vim-patch:8.1.0911: tag line with Ex command cannot have extra fields

Problem:    Tag line with Ex command cannot have extra fields.
Solution:   Recognize |;" as the end of the command. (closes vim/vim#2402)
943e9639a9
This commit is contained in:
Daniel Hahler 2019-08-10 17:13:48 +02:00
parent 5f243fc68a
commit 4109ee8ef4
3 changed files with 50 additions and 15 deletions

View File

@ -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 {term} ;" The two characters semicolon and double quote. This is
interpreted by Vi as the start of a comment, which makes the interpreted by Vi as the start of a comment, which makes the
following be ignored. This is for backwards compatibility 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: {field} .. A list of optional fields. Each field has the form:
<Tab>{fieldname}:{value} <Tab>{fieldname}:{value}

View File

@ -2236,8 +2236,13 @@ parse_match (
p = tagp->command; p = tagp->command;
if (find_extra(&p) == OK) { if (find_extra(&p) == OK) {
tagp->command_end = p; tagp->command_end = p;
p += 2; /* skip ";\"" */ if (p > tagp->command && p[-1] == '|') {
if (*p++ == TAB) tagp->command_end = p - 1; // drop trailing bar
} else {
tagp->command_end = p;
}
p += 2; // skip ";\""
if (*p++ == TAB) {
while (ASCII_ISALPHA(*p)) { while (ASCII_ISALPHA(*p)) {
if (STRNCMP(p, "kind:", 5) == 0) { if (STRNCMP(p, "kind:", 5) == 0) {
tagp->tagkind = p + 5; tagp->tagkind = p + 5;
@ -2253,6 +2258,7 @@ parse_match (
break; break;
p = pt + 1; p = pt + 1;
} }
}
} }
if (tagp->tagkind != NULL) { if (tagp->tagkind != NULL) {
for (p = tagp->tagkind; for (p = tagp->tagkind;
@ -2677,22 +2683,30 @@ static int find_extra(char_u **pp)
{ {
char_u *str = *pp; char_u *str = *pp;
/* Repeat for addresses separated with ';' */ // Repeat for addresses separated with ';'
for (;; ) { for (;; ) {
if (ascii_isdigit(*str)) if (ascii_isdigit(*str)) {
str = skipdigits(str); str = skipdigits(str);
else if (*str == '/' || *str == '?') { } else if (*str == '/' || *str == '?') {
str = skip_regexp(str + 1, *str, FALSE, NULL); str = skip_regexp(str + 1, *str, false, NULL);
if (*str != **pp) if (*str != **pp) {
str = NULL; str = NULL;
else } else {
++str; str++;
} else }
str = NULL; } 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 != ';' if (str == NULL || *str != ';'
|| !(ascii_isdigit(str[1]) || str[1] == '/' || str[1] == '?')) || !(ascii_isdigit(str[1]) || str[1] == '/' || str[1] == '?')) {
break; break;
++str; /* skip ';' */ }
str++; // skip ';'
} }
if (str != NULL && STRNCMP(str, ";\"", 2) == 0) { if (str != NULL && STRNCMP(str, ";\"", 2) == 0) {

View File

@ -5,7 +5,9 @@ func Test_taglist()
\ "FFoo\tXfoo\t1", \ "FFoo\tXfoo\t1",
\ "FBar\tXfoo\t2", \ "FBar\tXfoo\t2",
\ "BFoo\tXbar\t1", \ "BFoo\tXbar\t1",
\ "BBar\tXbar\t2" \ "BBar\tXbar\t2",
\ "Kindly\tXbar\t3;\"\tv\tfile:",
\ "Command\tXbar\tcall cursor(3, 4)|;\"\td",
\ ], 'Xtags') \ ], 'Xtags')
set tags=Xtags set tags=Xtags
split Xtext 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(['FFoo', 'BFoo'], map(taglist("Foo", "Xfoo"), {i, v -> v.name}))
call assert_equal(['BFoo', 'FFoo'], map(taglist("Foo", "Xbar"), {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') call delete('Xtags')
set tags& set tags&
bwipe bwipe