Reputation: 2254
I'm trying to define a new command in Vim that calls an external script with the name of the current file, but slightly modified. Here's how I defined the command:
:command MyNewCommand !/tmp/myscript.sh substitute(expand("%:p"), "-debug", "", 'g')
In other words, myscript.sh
takes one parameter, which is the full pathname of the file being edited, with the string -debug
in the pathname removed. My command definition doesn't work because rather than passing the pathname, Vim seems to pass to myscript.sh
the entire string itself, beginning with the word substitute
. How do I define the command to do what I want? Thanks :).
Upvotes: 2
Views: 1922
Reputation: 28944
You can use the system()
function to execute the script.
Change the command definition as follows:
:command! MyNewCommand call system('/tmp/myscript.sh ' .
\ shellescape(substitute(expand('%:p'), '-debug', '', 'g')))
To see the output of the command, replace call
with echo
.
Upvotes: 3
Reputation: 24686
The generic approach is to build a string and then execute
it. The problem in your command is that substitute(expand(...
is not being evaluated and it's passed as is.
So in a generic example
command MyNewCommand OldCommand expand("%:p")
should be converted to
command MyNewCommand execute 'OldCommand '.expand("%:p")
That way MyNewCommand
will just invoke execute
with the expression 'OldCommand '.expand("%:p")
. execute
will evaluate the expression and therefore expand()
will get evaluated to the filename and concatenated to 'OldCommand '
resulting in a string of the form 'OldCommand myfilename'
. That string then gets executed as an Ex
command by the same execute
.
Upvotes: 1
Reputation: 53614
You can use solution similar to @ib's one, but with !
which will show you the output of the shell command (and will also handle case when expand('%:p')
contains newlines (it can if FS is fully POSIX-compliant)):
command MyNewCommand execute '!/tmp/myscript.sh' shellescape(substitute(expand('%:p'), '-debug', '', 'g'))
Upvotes: 2