changeset 23370:622e90acea5d v8.2.2228

patch 8.2.2228: Vim9: cannot use ":e #" because # starts a comment Commit: https://github.com/vim/vim/commit/4389f9cd00632adc0216d5ead13d859b186bcbf8 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Dec 27 16:55:11 2020 +0100 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 #.
author Bram Moolenaar <Bram@vim.org>
date Sun, 27 Dec 2020 17:00:04 +0100
parents a547793a18c1
children b0000757445c
files src/ex_docmd.c src/testdir/test_vim9_cmd.vim src/version.c
diffstat 3 files changed, 91 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -8535,18 +8535,19 @@ find_cmdline_var(char_u *src, int *usedl
 /*
  * Evaluate cmdline variables.
  *
- * change '%'	    to curbuf->b_ffname
- *	  '#'	    to curwin->w_alt_fnum
- *	  '<cword>' to word under the cursor
- *	  '<cWORD>' to WORD under the cursor
- *	  '<cexpr>' to C-expression under the cursor
- *	  '<cfile>' to path name under the cursor
- *	  '<sfile>' to sourced file name
- *	  '<stack>' to call stack
- *	  '<slnum>' to sourced file line number
- *	  '<afile>' to file name for autocommand
- *	  '<abuf>'  to buffer number for autocommand
- *	  '<amatch>' to matching name for autocommand
+ * change "%"	    to curbuf->b_ffname
+ *	  "#"	    to curwin->w_alt_fnum
+ *	  "%%"	    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
+ *	  "<cfile>" to path name under the cursor
+ *	  "<sfile>" to sourced file name
+ *	  "<stack>" to call stack
+ *	  "<slnum>" to sourced file line number
+ *	  "<afile>" to file 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
  * "" for error without a message) and NULL is returned.
@@ -8627,47 +8628,57 @@ eval_vars(
      */
     else
     {
+	int off = 0;
+
 	switch (spec_idx)
 	{
-	case SPEC_PERC:		// '%': current file
-		if (curbuf->b_fname == NULL)
+	case SPEC_PERC:
+		if (!in_vim9script() || src[1] != '%')
 		{
-		    result = (char_u *)"";
-		    valid = 0;	    // Must have ":p:h" to be valid
+		    // '%': current file
+		    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
-		{
-		    result = curbuf->b_fname;
-		    tilde_file = STRCMP(result, "~") == 0;
-		}
-		break;
+		// "%%" alternate file
+		off = 1;
+		// FALLTHROUGH
 
 	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();
 		    resultbuf = result;
-		    *usedlen = 2;
+		    *usedlen = off + 2;
 		    if (escaped != NULL)
 			*escaped = TRUE;
 		    skip_mod = TRUE;
 		    break;
 		}
-		s = src + 1;
+		s = src + off + 1;
 		if (*s == '<')		// "#<99" uses v:oldfiles
 		    ++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
 		    s--;
 		*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?
-			*usedlen = 1;
+			*usedlen = off + 1;
 			return NULL;
 		    }
 #ifdef FEAT_EVAL
@@ -8685,8 +8696,8 @@ eval_vars(
 		}
 		else
 		{
-		    if (i == 0 && src[1] == '<' && *usedlen > 1)
-			*usedlen = 1;
+		    if (i == 0 && src[off + 1] == '<' && *usedlen > off + 1)
+			*usedlen = off + 1;
 		    buf = buflist_findnr(i);
 		    if (buf == NULL)
 		    {
--- a/src/testdir/test_vim9_cmd.vim
+++ b/src/testdir/test_vim9_cmd.vim
@@ -25,6 +25,53 @@ def Test_edit_wildcards()
   CheckDefFailure(['edit `="foo"'], 'E1083:')
 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()
   new
   setline(1, 'xx')
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2228,
+/**/
     2227,
 /**/
     2226,