aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/eval.txt9
-rw-r--r--runtime/doc/usr_41.txt1
-rw-r--r--src/nvim/eval.lua1
-rw-r--r--src/nvim/eval/funcs.c25
-rw-r--r--test/functional/legacy/expand_spec.lua39
5 files changed, 75 insertions, 0 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index ce0218f1dd..c687d15689 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2110,6 +2110,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
@@ -3733,6 +3734,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|.
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index 5f9253cbd0..234f7801ab 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -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
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 4654f8cef6..d3e769a7ef 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -102,6 +102,7 @@ return {
exists={args=1},
exp={args=1, func="float_op_wrapper", data="&exp"},
expand={args={1, 3}},
+ expandcmd={args=1},
extend={args={2, 3}},
feedkeys={args={1, 2}},
file_readable={args=1, func='f_filereadable'}, -- obsolete
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index be8e35b1de..c89c72c3de 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -2103,6 +2103,31 @@ static void f_menu_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
menu_get((char_u *)tv_get_string(&argvars[0]), modes, rettv->vval.v_list);
}
+// "expandcmd()" function
+// Expand all the special characters in a command string.
+static void f_expandcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ char_u *errormsg = NULL;
+
+ rettv->v_type = VAR_STRING;
+ char_u *cmdstr = (char_u *)xstrdup(tv_get_string(&argvars[0]));
+
+ exarg_T eap = {
+ .cmd = cmdstr,
+ .arg = cmdstr,
+ .usefilter = false,
+ .nextcmd = NULL,
+ .cmdidx = CMD_USER,
+ };
+ eap.argt |= NOSPC;
+
+ 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
diff --git a/test/functional/legacy/expand_spec.lua b/test/functional/legacy/expand_spec.lua
index 1b735080f4..f238128b31 100644
--- a/test/functional/legacy/expand_spec.lua
+++ b/test/functional/legacy/expand_spec.lua
@@ -70,6 +70,40 @@ describe('expand file name', function()
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
]])
end)
@@ -87,4 +121,9 @@ describe('expand file name', function()
call('Test_expand_tilde_filename')
expected_empty()
end)
+
+ it('works with expandcmd()', function()
+ call('Test_expandcmd')
+ expected_empty()
+ end)
end)