I'm using the following function + command to invoke the debugger in Vim:
function! TermDebugArm(executable)
packadd termdebug
let g:termdebugger="arm-none-eabi-gdb"
Termdebug a:executable
endfunction
command! -complete=file -nargs=1 TermDebugArm :call TermDebugArm(<f-args>)
Unfortunately, the Termdebug command gets the literal argument "a:executable" and not the actual value it should represent (i.e. the filename passed to the command that called the function).
What am I doing wrong?
You need to use the :execute command to build a command from strings, which will allow you to use the value of a:executable as a literal:
execute "Termdebug ".a:executable
Or you can use the feature of :execute that will join multiple arguments with a space, so you don't need an explicit concatenation:
execute "Termdebug" a:executable
See :help :execute.
Related
I am trying execute a nested execute command within a vimscript. I know that this command works in ex mode:
g/\(^\n\|\%1l\).\_.\{-}\n$/execute "normal! vap:call MCformat()\<cr>"
I want to be able to run that command from within a script. I have tried a number of permutations of the following code but can't get it to work.
function! RunMCformat()
silent! execute "normal! g/\(^\n\|\%1l\).\_.\{-}\n$/execute \"normal! vap:call MCformat\(\)\<cr>\""
endfunction
Probably I am not escaping the string properly but I don't know where I am going wrong.
Because of the double quotes, you'd have to escape (i.e. double) the backslashes inside the /.../ pattern definition. However, the biggest problem is the first :normal!; :g[lobal] is an Ex command. So, you're lucky, you can just prepend :silent! (which invokes Ex commands like :global), are you should be done; no nested :execute is necessary:
function! RunMCformat()
silent! global/\(^\n\|\%1l\).\_.\{-}\n$/execute "normal! vap:call MCformat()\<cr>"
endfunction
In general, I would avoid nesting of :execute; that's not readable in any case. Rather, extract parts of your code into a function / custom command (in which you can use :execute), and invoke that.
I am trying to generate a filename using a shell function and pass it to tabnew.
How might I get a working equivalent of the following, where echo foo might be replaced by any arbitrary external command?
tabnew $(!echo foo)
To be clear, the desired result is for the shell command to be evaluated, and its output passed to tabnew. In the above example, the command should evaluate to tabnew foo.
You can accomplish this using execute and system to craft a tabnew command.
Here is a function you can modify and perhaps stick in your .vimrc:
function! TabNewFoo()
execute "tabnew ".system('echo "foo"')
endfunction
Invoke with:
:call TabNewFoo()
Or, a more generalized form:
function! TabNewFoo(command)
execute "tabnew ".system(a:command)
endfunction
Invoke with:
:call TabNewFoo("echo 'foo'")
I have a small operator mapping for use with the Pydoc plugin. The code for it is below:
nnoremap <buffer> <localleader>d :set operatorfunc=<SID>PydocOperator<cr>g#
vnoremap <buffer> <localleader>d :<c-u>call <SID>PydocOperator(visualmode())<cr>
function! s:PydocOperator(type)
let l:orig_register = ##
if a:type ==# 'v'
normal! `<v`>y
elseif a:type ==# 'char'
normal! `[v`]y
else
return
endif
execute 'Pydoc ' . shellescape(##)
let ## = l:orig_register
endfunction
However, vim throws an error:
E116: Invalid arguments for function <SNR>117_ShowPyDoc
The same error happens if I copy some text manually and run this command:
execute 'Pydoc ' . shellescape(##)
This is very odd, considering that the :Pydoc should work as a normal command, taking one argument as its input. I looked at the code where the :Pydoc command is defined, (that line of code is here) and discovered that passing an argument to the :Pydoc command that is in quotes might be causing an issue. So I ran :Pydoc 'sys' to see if it would throw the same error as the operator mapping, which it did. So if it is having an issue with the quotes around the argument, how do I format the execute command so that it doesn't give an invalid argument?
The shellescape() function is not necessary for the :Pydoc command. shellescape includes quotes in the returned string, which causes :Pydoc to self destruct. However, if the command were :grep, for instance, shellescape would need to be used.
Relevant help topics:
:help shellescape()
:help 'operatorfunc'
:help :map-operator
I'm trying to write a custom command in Vim to make setting the makeprg variable for an out-of-source build easier. Having read the command manual, so far I've got as far as this
command! -complete=file -nargs=1 Cmakeprg call set makeprg=cmake --build <args><CR>
but it isn't working. How do I call "set" within the command?
You :call functions, :set is an Ex command just like :call (as it's invoked with the : prefix).
A complication with :set is that whitespace must be escaped with \, but that can be avoided by using :let with the &option, and <q-args> automatically quotes the passed command arguments.
You also don't need <CR>; this isn't a mapping. Taken all together:
command! -complete=file -nargs=1 Cmakeprg let &makeprg = 'cmake --build ' . <q-args>
Add a colon in front of "set" and use a <CR> to execute it: :set … <CR>
Do not use call.
I wrote a function to get the full path of the current file under the cursor
nmap <F12> :echo GetFullPath()<cr>
function! GetFullPath()
let currentFile=expand("<cfile>")
let afterChangeSlash=substitute(currentFile,"/","\\","g")
let fullPath="e:\\Test\\".afterChangeSlash
return fullPath
endfunction
When I call the function after the :echo command, I get the expected result,like:
:echo GetFullPath()
e:\Test\test.h
However,When I call it after the :e(edit) command:
:e GetFullPath()
Vim just create a new file named GetFullPath()
Why the command :e will treat a function call literally while the command :echo won't?
You can use :execute to build your ex command string and execute it:
:exe "e ".GetFullPath()
Or use the `=` syntax to expand a Vim expression:
:e `=GetFullPath()`
If you check the help for :edit and :echo, you'll notice that the former expects its argument to be the file name (literally), while :echo expects an expression which will be evaluated.
Some ex commands expect to be given an expression, while some others expect to be given a string. For your case to make it work use exec:
nmap <F12> :exec 'e ' . GetFullPath()