diff options
-rw-r--r-- | runtime/doc/tagsrch.txt | 9 | ||||
-rw-r--r-- | src/nvim/tag.c | 40 | ||||
-rw-r--r-- | src/nvim/testdir/test_taglist.vim | 16 |
3 files changed, 50 insertions, 15 deletions
diff --git a/runtime/doc/tagsrch.txt b/runtime/doc/tagsrch.txt index 58dd3259fd..bb3134feb6 100644 --- a/runtime/doc/tagsrch.txt +++ b/runtime/doc/tagsrch.txt @@ -537,7 +537,14 @@ only supported by new versions of ctags (such as Exuberant ctags). {term} ;" The two characters semicolon and double quote. This is interpreted by Vi as the start of a comment, which makes the following be ignored. This is for backwards compatibility - with Vi, it ignores the following fields. + with Vi, it ignores the following fields. Example: + APP file /^static int APP;$/;" v + When {tagaddress} is not a line number or search pattern, then + {term} must be |;". Here the bar ends the command (excluding + the bar) and ;" is used to have Vi ignore the rest of the + line. Example: + APP file.c call cursor(3, 4)|;" v + {field} .. A list of optional fields. Each field has the form: <Tab>{fieldname}:{value} diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 504a099df2..88676abc2e 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -2236,8 +2236,13 @@ parse_match ( p = tagp->command; if (find_extra(&p) == OK) { tagp->command_end = p; - p += 2; /* skip ";\"" */ - if (*p++ == TAB) + if (p > tagp->command && p[-1] == '|') { + tagp->command_end = p - 1; // drop trailing bar + } else { + tagp->command_end = p; + } + p += 2; // skip ";\"" + if (*p++ == TAB) { while (ASCII_ISALPHA(*p)) { if (STRNCMP(p, "kind:", 5) == 0) { tagp->tagkind = p + 5; @@ -2253,6 +2258,7 @@ parse_match ( break; p = pt + 1; } + } } if (tagp->tagkind != NULL) { for (p = tagp->tagkind; @@ -2677,22 +2683,30 @@ static int find_extra(char_u **pp) { char_u *str = *pp; - /* Repeat for addresses separated with ';' */ + // Repeat for addresses separated with ';' for (;; ) { - if (ascii_isdigit(*str)) + if (ascii_isdigit(*str)) { str = skipdigits(str); - else if (*str == '/' || *str == '?') { - str = skip_regexp(str + 1, *str, FALSE, NULL); - if (*str != **pp) + } else if (*str == '/' || *str == '?') { + str = skip_regexp(str + 1, *str, false, NULL); + if (*str != **pp) { str = NULL; - else - ++str; - } else - str = NULL; + } else { + str++; + } + } else { + // not a line number or search string, look for terminator. + str = (char_u *)strstr((char *)str, "|;\""); + if (str != NULL) { + str++; + break; + } + } if (str == NULL || *str != ';' - || !(ascii_isdigit(str[1]) || str[1] == '/' || str[1] == '?')) + || !(ascii_isdigit(str[1]) || str[1] == '/' || str[1] == '?')) { break; - ++str; /* skip ';' */ + } + str++; // skip ';' } if (str != NULL && STRNCMP(str, ";\"", 2) == 0) { diff --git a/src/nvim/testdir/test_taglist.vim b/src/nvim/testdir/test_taglist.vim index fb8c6c85cd..39bd5dcf04 100644 --- a/src/nvim/testdir/test_taglist.vim +++ b/src/nvim/testdir/test_taglist.vim @@ -5,7 +5,9 @@ func Test_taglist() \ "FFoo\tXfoo\t1", \ "FBar\tXfoo\t2", \ "BFoo\tXbar\t1", - \ "BBar\tXbar\t2" + \ "BBar\tXbar\t2", + \ "Kindly\tXbar\t3;\"\tv\tfile:", + \ "Command\tXbar\tcall cursor(3, 4)|;\"\td", \ ], 'Xtags') set tags=Xtags split Xtext @@ -15,6 +17,18 @@ func Test_taglist() call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo", "Xfoo"), {i, v -> v.name})) call assert_equal(['BFoo', 'FFoo'], map(taglist("Foo", "Xbar"), {i, v -> v.name})) + let kind = taglist("Kindly") + call assert_equal(1, len(kind)) + call assert_equal('v', kind[0]['kind']) + call assert_equal('3', kind[0]['cmd']) + call assert_equal(1, kind[0]['static']) + call assert_equal('Xbar', kind[0]['filename']) + + let cmd = taglist("Command") + call assert_equal(1, len(cmd)) + call assert_equal('d', cmd[0]['kind']) + call assert_equal('call cursor(3, 4)', cmd[0]['cmd']) + call delete('Xtags') set tags& bwipe |