]> granicus.if.org Git - vim/commitdiff
patch 8.1.1510: a plugin cannot easily expand a command like done internally v8.1.1510
authorBram Moolenaar <Bram@vim.org>
Sun, 9 Jun 2019 15:22:31 +0000 (17:22 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 9 Jun 2019 15:22:31 +0000 (17:22 +0200)
Problem:    A plugin cannot easily expand a command like done internally.
Solution:   Add the expandcmd() function. (Yegappan Lakshmanan, closes #4514)

runtime/doc/eval.txt
runtime/doc/usr_41.txt
src/evalfunc.c
src/testdir/test_expand.vim
src/version.c

index d1f6824b6d939569c03c03279614aca42a2193d1..b5df67cc602fe246dd1ebad8adf97776ff26ee11 100644 (file)
@@ -2326,6 +2326,7 @@ extend({expr1}, {expr2} [, {expr3}])
 exp({expr})                    Float   exponential of {expr}
 expand({expr} [, {nosuf} [, {list}]])
                                any     expand special keywords in {expr}
+expandcmd({expr})              String  expand {expr} like with `:edit`
 feedkeys({string} [, {mode}])  Number  add key sequence to typeahead buffer
 filereadable({file})           Number  |TRUE| if {file} is a readable file
 filewritable({file})           Number  |TRUE| if {file} is a writable file
@@ -4218,6 +4219,14 @@ expand({expr} [, {nosuf} [, {list}]])                            *expand()*
                See |glob()| for finding existing files.  See |system()| for
                getting the raw output of an external command.
 
+expandcmd({expr})                                      *expandcmd()*
+               Expand special items in {expr} like what is done for an Ex
+               command such as `:edit`.  This expands special keywords, like
+               with |expand()|, and environment variables, anywhere in
+               {expr}.  Returns the expanded string.
+               Example: >
+                       :echo expandcmd('make %<.o')
+<
 extend({expr1}, {expr2} [, {expr3}])                   *extend()*
                {expr1} and {expr2} must be both |Lists| or both
                |Dictionaries|.
index 719f015d79971d5fc7990c3051e039ff734b0fe4..ee3423cddf97153058ac1dee56cf76c92d4cb104 100644 (file)
@@ -1,4 +1,4 @@
-*usr_41.txt*   For Vim version 8.1.  Last change: 2019 May 29
+*usr_41.txt*   For Vim version 8.1.  Last change: 2019 Jun 09
 
                     VIM USER MANUAL - by Bram Moolenaar
 
@@ -609,6 +609,7 @@ String manipulation:                                        *string-functions*
        strcharpart()           get part of a string using char index
        strgetchar()            get character from a string using char index
        expand()                expand special keywords
+       expandcmd()             expand a command like done for `:edit`
        iconv()                 convert text from one encoding to another
        byteidx()               byte index of a character in a string
        byteidxcomp()           like byteidx() but count composing characters
index 42973797de0166ab555bf43c39f4caf7593c221c..2d8bf5275064a93339832232afa549211a74ca10 100644 (file)
@@ -149,6 +149,7 @@ static void f_exists(typval_T *argvars, typval_T *rettv);
 static void f_exp(typval_T *argvars, typval_T *rettv);
 #endif
 static void f_expand(typval_T *argvars, typval_T *rettv);
+static void f_expandcmd(typval_T *argvars, typval_T *rettv);
 static void f_extend(typval_T *argvars, typval_T *rettv);
 static void f_feedkeys(typval_T *argvars, typval_T *rettv);
 static void f_filereadable(typval_T *argvars, typval_T *rettv);
@@ -646,6 +647,7 @@ static struct fst
     {"exp",            1, 1, f_exp},
 #endif
     {"expand",         1, 3, f_expand},
+    {"expandcmd",      1, 1, f_expandcmd},
     {"extend",         2, 3, f_extend},
     {"feedkeys",       1, 2, f_feedkeys},
     {"file_readable",  1, 1, f_filereadable},  /* obsolete */
@@ -3790,6 +3792,35 @@ f_expand(typval_T *argvars, typval_T *rettv)
     }
 }
 
+/*
+ * "expandcmd()" function
+ * Expand all the special characters in a command string.
+ */
+    static void
+f_expandcmd(typval_T *argvars, typval_T *rettv)
+{
+    exarg_T    eap;
+    char_u     *cmdstr;
+    char       *errormsg = NULL;
+
+    rettv->v_type = VAR_STRING;
+    cmdstr = vim_strsave(tv_get_string(&argvars[0]));
+
+    memset(&eap, 0, sizeof(eap));
+    eap.cmd = cmdstr;
+    eap.arg = cmdstr;
+    eap.argt |= NOSPC;
+    eap.usefilter = FALSE;
+    eap.nextcmd = NULL;
+    eap.cmdidx = CMD_USER;
+
+    expand_filename(&eap, &cmdstr, &errormsg);
+    if (errormsg != NULL && *errormsg != NUL)
+       emsg(errormsg);
+
+    rettv->vval.v_string = cmdstr;
+}
+
 /*
  * "extend(list, list [, idx])" function
  * "extend(dict, dict [, action])" function
index b4f1363d12cfce4469d55c93f7f67f0705aff9de..bd8021f9fa4d2632bbbe8a15ecee5fff523c78aa 100644 (file)
@@ -47,3 +47,37 @@ func Test_expand_tilde_filename()
   call assert_match('\~', expand('%:p')) 
   bwipe!
 endfunc
+
+func Test_expandcmd()
+  let $FOO = 'Test'
+  call assert_equal('e x/Test/y', expandcmd('e x/$FOO/y'))
+  unlet $FOO
+
+  new
+  edit Xfile1
+  call assert_equal('e Xfile1', expandcmd('e %'))
+  edit Xfile2
+  edit Xfile1
+  call assert_equal('e Xfile2', expandcmd('e #'))
+  edit Xfile2
+  edit Xfile3
+  edit Xfile4
+  let bnum = bufnr('Xfile2')
+  call assert_equal('e Xfile2', expandcmd('e #' . bnum))
+  call setline('.', 'Vim!@#')
+  call assert_equal('e Vim', expandcmd('e <cword>'))
+  call assert_equal('e Vim!@#', expandcmd('e <cWORD>'))
+  enew!
+  edit Xfile.java
+  call assert_equal('e Xfile.py', expandcmd('e %:r.py'))
+  call assert_equal('make abc.java', expandcmd('make abc.%:e'))
+  call assert_equal('make Xabc.java', expandcmd('make %:s?file?abc?'))
+  edit a1a2a3.rb
+  call assert_equal('make b1b2b3.rb a1a2a3 Xfile.o', expandcmd('make %:gs?a?b? %< #<.o'))
+
+  call assert_fails('call expandcmd("make <afile>")', 'E495:')
+  call assert_fails('call expandcmd("make <afile>")', 'E495:')
+  enew
+  call assert_fails('call expandcmd("make %")', 'E499:')
+  close
+endfunc
index b392cfdc55fb1545572b862d0a4823664ada5057..79faf7b7d952456c1e5e46f91d1b7897e6adc356 100644 (file)
@@ -777,6 +777,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1510,
 /**/
     1509,
 /**/