1
0
forked from aniani/vim

patch 8.2.2228: Vim9: cannot use ":e #" because # starts a comment

Problem:    Vim9: cannot use ":e #" because # starts a comment.
Solution:   Support using %% instead of #.
This commit is contained in:
Bram Moolenaar
2020-12-27 16:55:11 +01:00
parent e462f52db3
commit 4389f9cd00
3 changed files with 91 additions and 31 deletions

View File

@@ -8535,18 +8535,19 @@ find_cmdline_var(char_u *src, int *usedlen)
/* /*
* Evaluate cmdline variables. * Evaluate cmdline variables.
* *
* change '%' to curbuf->b_ffname * change "%" to curbuf->b_ffname
* '#' to curwin->w_alt_fnum * "#" to curwin->w_alt_fnum
* '<cword>' to word under the cursor * "%%" to curwin->w_alt_fnum in Vim9 script
* '<cWORD>' to WORD under the cursor * "<cword>" to word under the cursor
* '<cexpr>' to C-expression under the cursor * "<cWORD>" to WORD under the cursor
* '<cfile>' to path name under the cursor * "<cexpr>" to C-expression under the cursor
* '<sfile>' to sourced file name * "<cfile>" to path name under the cursor
* '<stack>' to call stack * "<sfile>" to sourced file name
* '<slnum>' to sourced file line number * "<stack>" to call stack
* '<afile>' to file name for autocommand * "<slnum>" to sourced file line number
* '<abuf>' to buffer number for autocommand * "<afile>" to file name for autocommand
* '<amatch>' to matching name for autocommand * "<abuf>" to buffer number for autocommand
* "<amatch>" to matching name for autocommand
* *
* When an error is detected, "errormsg" is set to a non-NULL pointer (may be * When an error is detected, "errormsg" is set to a non-NULL pointer (may be
* "" for error without a message) and NULL is returned. * "" for error without a message) and NULL is returned.
@@ -8627,47 +8628,57 @@ eval_vars(
*/ */
else else
{ {
int off = 0;
switch (spec_idx) switch (spec_idx)
{ {
case SPEC_PERC: // '%': current file case SPEC_PERC:
if (curbuf->b_fname == NULL) if (!in_vim9script() || src[1] != '%')
{ {
result = (char_u *)""; // '%': current file
valid = 0; // Must have ":p:h" to be valid if (curbuf->b_fname == NULL)
{
result = (char_u *)"";
valid = 0; // Must have ":p:h" to be valid
}
else
{
result = curbuf->b_fname;
tilde_file = STRCMP(result, "~") == 0;
}
break;
} }
else // "%%" alternate file
{ off = 1;
result = curbuf->b_fname; // FALLTHROUGH
tilde_file = STRCMP(result, "~") == 0;
}
break;
case SPEC_HASH: // '#' or "#99": alternate file case SPEC_HASH: // '#' or "#99": alternate file
if (src[1] == '#') // "##": the argument list if (off == 0 ? src[1] == '#' : src[2] == '%')
{ {
// "##" or "%%%": the argument list
result = arg_all(); result = arg_all();
resultbuf = result; resultbuf = result;
*usedlen = 2; *usedlen = off + 2;
if (escaped != NULL) if (escaped != NULL)
*escaped = TRUE; *escaped = TRUE;
skip_mod = TRUE; skip_mod = TRUE;
break; break;
} }
s = src + 1; s = src + off + 1;
if (*s == '<') // "#<99" uses v:oldfiles if (*s == '<') // "#<99" uses v:oldfiles
++s; ++s;
i = (int)getdigits(&s); i = (int)getdigits(&s);
if (s == src + 2 && src[1] == '-') if (s == src + off + 2 && src[off + 1] == '-')
// just a minus sign, don't skip over it // just a minus sign, don't skip over it
s--; s--;
*usedlen = (int)(s - src); // length of what we expand *usedlen = (int)(s - src); // length of what we expand
if (src[1] == '<' && i != 0) if (src[off + 1] == '<' && i != 0)
{ {
if (*usedlen < 2) if (*usedlen < off + 2)
{ {
// Should we give an error message for #<text? // Should we give an error message for #<text?
*usedlen = 1; *usedlen = off + 1;
return NULL; return NULL;
} }
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
@@ -8685,8 +8696,8 @@ eval_vars(
} }
else else
{ {
if (i == 0 && src[1] == '<' && *usedlen > 1) if (i == 0 && src[off + 1] == '<' && *usedlen > off + 1)
*usedlen = 1; *usedlen = off + 1;
buf = buflist_findnr(i); buf = buflist_findnr(i);
if (buf == NULL) if (buf == NULL)
{ {

View File

@@ -25,6 +25,53 @@ def Test_edit_wildcards()
CheckDefFailure(['edit `="foo"'], 'E1083:') CheckDefFailure(['edit `="foo"'], 'E1083:')
enddef enddef
def Test_expand_alternate_file()
var lines =<< trim END
edit Xfileone
var bone = bufnr()
edit Xfiletwo
var btwo = bufnr()
edit Xfilethree
var bthree = bufnr()
edit #
assert_equal(bthree, bufnr())
edit %%
assert_equal(btwo, bufnr())
edit %% # comment
assert_equal(bthree, bufnr())
edit %%yy
assert_equal('Xfiletwoyy', bufname())
exe "edit %%" .. bone
assert_equal(bone, bufnr())
exe "edit %%" .. btwo .. "xx"
assert_equal('Xfiletwoxx', bufname())
next Xfileone Xfiletwo Xfilethree
assert_equal('Xfileone', argv(0))
assert_equal('Xfiletwo', argv(1))
assert_equal('Xfilethree', argv(2))
next %%%zz
assert_equal('Xfileone', argv(0))
assert_equal('Xfiletwo', argv(1))
assert_equal('Xfilethreezz', argv(2))
v:oldfiles = ['Xonefile', 'Xtwofile']
edit %%<1
assert_equal('Xonefile', bufname())
edit %%<2
assert_equal('Xtwofile', bufname())
assert_fails('edit %%<3', 'E684:')
edit Xfileone.vim
edit Xfiletwo
edit %%:r
assert_equal('Xfileone', bufname())
END
CheckDefAndScriptSuccess(lines)
enddef
def Test_global_backtick_expansion() def Test_global_backtick_expansion()
new new
setline(1, 'xx') setline(1, 'xx')

View File

@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
2228,
/**/ /**/
2227, 2227,
/**/ /**/