Merge #10737 from blueyed/vim-8.1.0911

vim-patch:8.1.0911: tag line with Ex command cannot have extra fields
This commit is contained in:
Justin M. Keyes 2019-08-10 18:35:00 +02:00 committed by GitHub
commit d8d3719941
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 29 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
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}

View File

@ -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) {

View File

@ -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
@ -65,20 +79,6 @@ func Test_tags_too_long()
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')
set tags&
endfunc
func Test_tagfiles()
call assert_equal([], tagfiles())
@ -102,3 +102,17 @@ func Test_tagfiles()
call delete('Xtags2')
bd
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')
set tags&
endfunc