aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2019-04-03 00:30:24 +0200
committerGitHub <noreply@github.com>2019-04-03 00:30:24 +0200
commitc395cf018d48f919d0a6ad3c6747142f54f693b9 (patch)
treec5f2917772213b65c70a357a1d3db5a83450b0ab
parent5134b22ac5dbc7a56b580e4cee48d1cf41eb7ab6 (diff)
parenta79c0c8f7a8bb09a5d3eda9799851e271e986579 (diff)
downloadrneovim-c395cf018d48f919d0a6ad3c6747142f54f693b9.tar.gz
rneovim-c395cf018d48f919d0a6ad3c6747142f54f693b9.tar.bz2
rneovim-c395cf018d48f919d0a6ad3c6747142f54f693b9.zip
Merge #9823 from mhinz/vim-8.1.1093
vim-patch:8.1.{1093,1094,1100}
-rw-r--r--runtime/doc/tagsrch.txt39
-rw-r--r--src/nvim/tag.c116
-rw-r--r--src/nvim/testdir/test_tagjump.vim31
-rw-r--r--src/nvim/testdir/test_taglist.vim13
4 files changed, 103 insertions, 96 deletions
diff --git a/runtime/doc/tagsrch.txt b/runtime/doc/tagsrch.txt
index 367da7750e..08abcf2594 100644
--- a/runtime/doc/tagsrch.txt
+++ b/runtime/doc/tagsrch.txt
@@ -498,28 +498,21 @@ gnatxref For Ada. See http://www.gnuada.org/. gnatxref is
part of the gnat package.
-The lines in the tags file must have one of these three formats:
+The lines in the tags file must have one of these two formats:
1. {tagname} {TAB} {tagfile} {TAB} {tagaddress}
-2. {tagfile}:{tagname} {TAB} {tagfile} {TAB} {tagaddress}
-3. {tagname} {TAB} {tagfile} {TAB} {tagaddress} {term} {field} ..
+2. {tagname} {TAB} {tagfile} {TAB} {tagaddress} {term} {field} ..
-The first is a normal tag, which is completely compatible with Vi. It is the
-only format produced by traditional ctags implementations. This is often used
-for functions that are global, also referenced in other files.
+Previously an old format was supported, see |tag-old-static|.
+
+The first format is a normal tag, which is completely compatible with Vi. It
+is the only format produced by traditional ctags implementations. This is
+often used for functions that are global, also referenced in other files.
The lines in the tags file can end in <LF> or <CR><LF>. On the Macintosh <CR>
also works. The <CR> and <NL> characters can never appear inside a line.
- *tag-old-static*
-The second format is for a static tag only. It is obsolete now, replaced by
-the third format. It is only supported by Elvis 1.x and Vim and a few
-versions of ctags. A static tag is often used for functions that are local,
-only referenced in the file {tagfile}. Note that for the static tag, the two
-occurrences of {tagfile} must be exactly the same. Also see |tags-option|
-below, for how static tags are used.
-
-The third format is new. It includes additional information in optional
+The second format is new. It includes additional information in optional
fields at the end of each line. It is backwards compatible with Vi. It is
only supported by new versions of ctags (such as Exuberant ctags).
@@ -561,6 +554,7 @@ only supported by new versions of ctags (such as Exuberant ctags).
The only other field currently recognized by Vim is "file:"
(with an empty value). It is used for a static tag.
+
The first lines in the tags file can contain lines that start with
!_TAG_
These are sorted to the first lines, only rare tags that start with "!" can
@@ -613,6 +607,21 @@ If the command is a normal search command (it starts and ends with "/" or
followed by white space and a '('. This will find macro names and function
names with a type prepended.
+
+ *tag-old-static*
+Until March 2019 (patch 8.1.1092) an outdated format was supported:
+ {tagfile}:{tagname} {TAB} {tagfile} {TAB} {tagaddress}
+
+This format is for a static tag only. It is obsolete now, replaced by
+the second format. It is only supported by Elvis 1.x, older Vim versions and
+a few versions of ctags. A static tag is often used for functions that are
+local, only referenced in the file {tagfile}. Note that for the static tag,
+the two occurrences of {tagfile} must be exactly the same. Also see
+|tags-option| below, for how static tags are used.
+
+The support was removed, since when you can update to the new Vim version you
+should also be able to update ctags to one that supports the second format.
+
==============================================================================
6. Include file searches *include-search* *definition-search*
*E387* *E388* *E389*
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index c609af4751..861063ff62 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.c
@@ -1527,58 +1527,38 @@ line_read_in:
}
parse_line:
- /*
- * Figure out where the different strings are in this line.
- * For "normal" tags: Do a quick check if the tag matches.
- * This speeds up tag searching a lot!
- */
- if (orgpat.headlen
- ) {
+ // When the line is too long the NUL will not be in the
+ // last-but-one byte (see vim_fgets()).
+ // Has been reported for Mozilla JS with extremely long names.
+ // In that case we can't parse it and we ignore the line.
+ if (lbuf[LSIZE - 2] != NUL && !use_cscope) {
+ if (p_verbose >= 5) {
+ verbose_enter();
+ MSG(_("Ignoring long line in tags file"));
+ verbose_leave();
+ }
+ if (state != TS_LINEAR) {
+ // Avoid getting stuck.
+ linear = true;
+ state = TS_LINEAR;
+ vim_fseek(fp, search_info.low_offset, SEEK_SET);
+ }
+ continue;
+ }
+
+ // Figure out where the different strings are in this line.
+ // For "normal" tags: Do a quick check if the tag matches.
+ // This speeds up tag searching a lot!
+ if (orgpat.headlen) {
tagp.tagname = lbuf;
tagp.tagname_end = vim_strchr(lbuf, TAB);
- if (tagp.tagname_end == NULL)
- {
- if (vim_strchr(lbuf, NL) == NULL) {
- /* Truncated line, ignore it. Has been reported for
- * Mozilla JS with extremely long names. */
- if (p_verbose >= 5) {
- verbose_enter();
- MSG(_("Ignoring long line in tags file"));
- verbose_leave();
- }
- if (state != TS_LINEAR) {
- /* Avoid getting stuck. */
- linear = TRUE;
- state = TS_LINEAR;
- vim_fseek(fp, search_info.low_offset, SEEK_SET);
- }
- continue;
- }
-
- /* Corrupted tag line. */
- line_error = TRUE;
+ if (tagp.tagname_end == NULL) {
+ // Corrupted tag line.
+ line_error = true;
break;
}
/*
- * Check for old style static tag: "file:tag file .."
- */
- tagp.fname = NULL;
- for (p = lbuf; p < tagp.tagname_end; ++p) {
- if (*p == ':') {
- if (tagp.fname == NULL)
- tagp.fname = tagp.tagname_end + 1;
- if ( fnamencmp(lbuf, tagp.fname, p - lbuf) == 0
- && tagp.fname[p - lbuf] == TAB
- ) {
- /* found one */
- tagp.tagname = p + 1;
- break;
- }
- }
- }
-
- /*
* Skip this line if the length of the tag is different and
* there is no regexp, or the tag is too short.
*/
@@ -1677,11 +1657,8 @@ parse_line:
if (mb_strnicmp(tagp.tagname, orgpat.head, (size_t)cmplen) != 0)
continue;
- /*
- * Can be a matching tag, isolate the file name and command.
- */
- if (tagp.fname == NULL)
- tagp.fname = tagp.tagname_end + 1;
+ // Can be a matching tag, isolate the file name and command.
+ tagp.fname = tagp.tagname_end + 1;
tagp.fname_end = vim_strchr(tagp.fname, TAB);
tagp.command = tagp.fname_end + 1;
if (tagp.fname_end == NULL)
@@ -1748,19 +1725,12 @@ parse_line:
/* Don't change the ordering, always use the same table. */
mtt = MT_GL_OTH;
} else {
- /* Decide in which array to store this match. */
- is_current = test_for_current(
- tagp.fname, tagp.fname_end, tag_fname,
- buf_ffname);
- {
- if (tagp.tagname != lbuf)
- is_static = TRUE; /* detected static tag before */
- else
- is_static = test_for_static(&tagp);
- }
+ // Decide in which array to store this match.
+ is_current = test_for_current(tagp.fname, tagp.fname_end, tag_fname,
+ buf_ffname);
+ is_static = test_for_static(&tagp);
- /* decide in which of the sixteen tables to store this
- * match */
+ // Decide in which of the sixteen tables to store this match.
if (is_static) {
if (is_current)
mtt = MT_ST_CUR;
@@ -2192,25 +2162,9 @@ parse_tag_line (
*/
static bool test_for_static(tagptrs_T *tagp)
{
- char_u *p;
-
- int len;
-
- /*
- * Check for old style static tag: "file:tag file .."
- */
- len = (int)(tagp->fname_end - tagp->fname);
- p = tagp->tagname + len;
- if ( p < tagp->tagname_end
- && *p == ':'
- && fnamencmp(tagp->tagname, tagp->fname, len) == 0) {
- tagp->tagname = p + 1;
- return TRUE;
- }
+ char_u *p;
- /*
- * Check for new style static tag ":...<Tab>file:[<Tab>...]"
- */
+ // Check for new style static tag ":...<Tab>file:[<Tab>...]"
p = tagp->command;
while ((p = vim_strchr(p, '\t')) != NULL) {
++p;
diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim
index 180738a7c9..ad1f5fab73 100644
--- a/src/nvim/testdir/test_tagjump.vim
+++ b/src/nvim/testdir/test_tagjump.vim
@@ -331,4 +331,35 @@ func Test_tagnr_recall()
call delete('Xtest.c')
endfunc
+func Test_tag_line_toolong()
+ call writefile([
+ \ '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 django/contrib/admin/templates/admin/edit_inline/stacked.html 16;" j line:16 language:HTML'
+ \ ], 'Xtags')
+ set tags=Xtags
+ let old_vbs = &verbose
+ set verbose=5
+ " ":tjump" should give "tag not found" not "Format error in tags file"
+ call assert_fails('tj /foo', 'E426')
+ try
+ tj /foo
+ catch /^Vim\%((\a\+)\)\=:E431/
+ call assert_report(v:exception)
+ catch /.*/
+ endtry
+ call assert_equal('Ignoring long line in tags file', split(execute('messages'), '\n')[-1])
+ call writefile([
+ \ '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 django/contrib/admin/templates/admin/edit_inline/stacked.html 16;" j line:16 language:HTML'
+ \ ], 'Xtags')
+ call assert_fails('tj /foo', 'E426')
+ try
+ tj /foo
+ catch /^Vim\%((\a\+)\)\=:E431/
+ call assert_report(v:exception)
+ catch /.*/
+ endtry
+ call assert_equal('Ignoring long line in tags file', split(execute('messages'), '\n')[-1])
+ call delete('Xtags')
+ let &verbose = old_vbs
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_taglist.vim b/src/nvim/testdir/test_taglist.vim
index 3ad2025915..f4e939254a 100644
--- a/src/nvim/testdir/test_taglist.vim
+++ b/src/nvim/testdir/test_taglist.vim
@@ -61,3 +61,16 @@ func Test_tags_too_long()
call assert_fails('tag ' . repeat('x', 1020), 'E426')
tags
endfunc
+
+" For historical reasons we support a tags file where the last line is missing
+" the newline.
+func Test_tagsfile_without_trailing_newline()
+ call writefile(["Foo\tfoo\t1"], 'Xtags', 'b')
+ set tags=Xtags
+
+ let tl = taglist('.*')
+ call assert_equal(1, len(tl))
+ call assert_equal('Foo', tl[0].name)
+
+ call delete('Xtags')
+endfunc