Skip to content

Commit 80dad48

Browse files
committed
patch 8.1.1510: a plugin cannot easily expand a command like done internally
Problem: A plugin cannot easily expand a command like done internally. Solution: Add the expandcmd() function. (Yegappan Lakshmanan, closes #4514)
1 parent 954bb06 commit 80dad48

5 files changed

Lines changed: 78 additions & 1 deletion

File tree

runtime/doc/eval.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2326,6 +2326,7 @@ extend({expr1}, {expr2} [, {expr3}])
23262326
exp({expr}) Float exponential of {expr}
23272327
expand({expr} [, {nosuf} [, {list}]])
23282328
any expand special keywords in {expr}
2329+
expandcmd({expr}) String expand {expr} like with `:edit`
23292330
feedkeys({string} [, {mode}]) Number add key sequence to typeahead buffer
23302331
filereadable({file}) Number |TRUE| if {file} is a readable file
23312332
filewritable({file}) Number |TRUE| if {file} is a writable file
@@ -4218,6 +4219,14 @@ expand({expr} [, {nosuf} [, {list}]]) *expand()*
42184219
See |glob()| for finding existing files. See |system()| for
42194220
getting the raw output of an external command.
42204221

4222+
expandcmd({expr}) *expandcmd()*
4223+
Expand special items in {expr} like what is done for an Ex
4224+
command such as `:edit`. This expands special keywords, like
4225+
with |expand()|, and environment variables, anywhere in
4226+
{expr}. Returns the expanded string.
4227+
Example: >
4228+
:echo expandcmd('make %<.o')
4229+
<
42214230
extend({expr1}, {expr2} [, {expr3}]) *extend()*
42224231
{expr1} and {expr2} must be both |Lists| or both
42234232
|Dictionaries|.

runtime/doc/usr_41.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*usr_41.txt* For Vim version 8.1. Last change: 2019 May 29
1+
*usr_41.txt* For Vim version 8.1. Last change: 2019 Jun 09
22

33
VIM USER MANUAL - by Bram Moolenaar
44

@@ -609,6 +609,7 @@ String manipulation: *string-functions*
609609
strcharpart() get part of a string using char index
610610
strgetchar() get character from a string using char index
611611
expand() expand special keywords
612+
expandcmd() expand a command like done for `:edit`
612613
iconv() convert text from one encoding to another
613614
byteidx() byte index of a character in a string
614615
byteidxcomp() like byteidx() but count composing characters

src/evalfunc.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ static void f_exists(typval_T *argvars, typval_T *rettv);
149149
static void f_exp(typval_T *argvars, typval_T *rettv);
150150
#endif
151151
static void f_expand(typval_T *argvars, typval_T *rettv);
152+
static void f_expandcmd(typval_T *argvars, typval_T *rettv);
152153
static void f_extend(typval_T *argvars, typval_T *rettv);
153154
static void f_feedkeys(typval_T *argvars, typval_T *rettv);
154155
static void f_filereadable(typval_T *argvars, typval_T *rettv);
@@ -646,6 +647,7 @@ static struct fst
646647
{"exp", 1, 1, f_exp},
647648
#endif
648649
{"expand", 1, 3, f_expand},
650+
{"expandcmd", 1, 1, f_expandcmd},
649651
{"extend", 2, 3, f_extend},
650652
{"feedkeys", 1, 2, f_feedkeys},
651653
{"file_readable", 1, 1, f_filereadable}, /* obsolete */
@@ -3790,6 +3792,35 @@ f_expand(typval_T *argvars, typval_T *rettv)
37903792
}
37913793
}
37923794

3795+
/*
3796+
* "expandcmd()" function
3797+
* Expand all the special characters in a command string.
3798+
*/
3799+
static void
3800+
f_expandcmd(typval_T *argvars, typval_T *rettv)
3801+
{
3802+
exarg_T eap;
3803+
char_u *cmdstr;
3804+
char *errormsg = NULL;
3805+
3806+
rettv->v_type = VAR_STRING;
3807+
cmdstr = vim_strsave(tv_get_string(&argvars[0]));
3808+
3809+
memset(&eap, 0, sizeof(eap));
3810+
eap.cmd = cmdstr;
3811+
eap.arg = cmdstr;
3812+
eap.argt |= NOSPC;
3813+
eap.usefilter = FALSE;
3814+
eap.nextcmd = NULL;
3815+
eap.cmdidx = CMD_USER;
3816+
3817+
expand_filename(&eap, &cmdstr, &errormsg);
3818+
if (errormsg != NULL && *errormsg != NUL)
3819+
emsg(errormsg);
3820+
3821+
rettv->vval.v_string = cmdstr;
3822+
}
3823+
37933824
/*
37943825
* "extend(list, list [, idx])" function
37953826
* "extend(dict, dict [, action])" function

src/testdir/test_expand.vim

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,37 @@ func Test_expand_tilde_filename()
4747
call assert_match('\~', expand('%:p'))
4848
bwipe!
4949
endfunc
50+
51+
func Test_expandcmd()
52+
let $FOO = 'Test'
53+
call assert_equal('e x/Test/y', expandcmd('e x/$FOO/y'))
54+
unlet $FOO
55+
56+
new
57+
edit Xfile1
58+
call assert_equal('e Xfile1', expandcmd('e %'))
59+
edit Xfile2
60+
edit Xfile1
61+
call assert_equal('e Xfile2', expandcmd('e #'))
62+
edit Xfile2
63+
edit Xfile3
64+
edit Xfile4
65+
let bnum = bufnr('Xfile2')
66+
call assert_equal('e Xfile2', expandcmd('e #' . bnum))
67+
call setline('.', 'Vim!@#')
68+
call assert_equal('e Vim', expandcmd('e <cword>'))
69+
call assert_equal('e Vim!@#', expandcmd('e <cWORD>'))
70+
enew!
71+
edit Xfile.java
72+
call assert_equal('e Xfile.py', expandcmd('e %:r.py'))
73+
call assert_equal('make abc.java', expandcmd('make abc.%:e'))
74+
call assert_equal('make Xabc.java', expandcmd('make %:s?file?abc?'))
75+
edit a1a2a3.rb
76+
call assert_equal('make b1b2b3.rb a1a2a3 Xfile.o', expandcmd('make %:gs?a?b? %< #<.o'))
77+
78+
call assert_fails('call expandcmd("make <afile>")', 'E495:')
79+
call assert_fails('call expandcmd("make <afile>")', 'E495:')
80+
enew
81+
call assert_fails('call expandcmd("make %")', 'E499:')
82+
close
83+
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,8 @@ static char *(features[]) =
777777

778778
static int included_patches[] =
779779
{ /* Add new patch number below this line */
780+
/**/
781+
1510,
780782
/**/
781783
1509,
782784
/**/

0 commit comments

Comments
 (0)