How can I join two commands together in vim? - vim

I am trying to combine two commands for Bundle plugin in vim. Because BundleUpdate pulls all plugins and installs them and it is slow. I have the following below. The first two works fine, but the third one does not. It stops after the BundleClean operation. How can I make vim to run second command?
command! -bang BI BundleInstall<bang>
command! -bang BC BundleClean<bang>
;not working below
command! -bang BU BundleClean<bang> | BundleInstall<bang>

You should use -bar as an argument to :command in addition to -bang, otherwise chaining commands and adding comments is not possible for user-defined commands.
You will have to use
command! -bar -bang BU BC<bang> | BI<bang>
in place of what you have currently because Bundle* commands do not have -bar argument.
There is another alternative: use execute:
command! -bang BU execute 'BundleClean<bang>' | execute 'BundleInstall<bang>'
. Beware of using execute '…<some-arg>', it is not going to work properly for some arguments’ values. It works fine for both possible expansions of <bang>.

You cannot do BundleClean | BundleInstall.
Because BundleClean is a user-defined command, it is defined by Vundle plugin:
com! -nargs=? -bang BundleClean call vundle#installer#clean('!' == '<bang>')
Note that, there is no -bar in this command definition.
If you :h command-bar you will see:
-bar The command can be followed by a "|" and another command.
A "|" inside the command argument is not allowed then.
Also checks for a " to start a comment.
that is, the BundleClean cannot be followed by another command by |.
You could however write a function, in the function you execute the two commands. And let your BU command call your function.

Related

How to pass Vim function argument to a command?

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.

Vi multiple command in one line

I want to achieve the following things in vi :
Remove first few columns
Remove lines starting with specific words
Remove everything after first word.
I have the following command with respect to above requirements
:%s/new page //g to remove first two columns.
:g/abc/d , :g/xyz/d , :g/ddd/d to remove lines starting with specific words.
:%s/ .*//g to remove everything after first word.
Overall I want to run the following commands :
:%s/new page //g
:g/abc/d
:g/xyz/d
:g/ddd/d
:%s/ .*//g
How can I execute all the above commands in one single command.
I have tried | but it did not worked.
:g/abc/d|:g/xyz/d|:g/ddd/d
I am getting the following error :
E147: Cannot do :global recursive
How can I achieve this. I want to execute all commands in one single command.
Thanks
You can put all those commands in a function:
function! AllMyCommands()
%s/new page //g
g/abc/d
g/xyz/d
g/ddd/d
%s/ .*//g
endfunction
and call it either directly:
:call AllMyCommands()
or via a custom command:
command! Foo call AllMyCommands()
:Foo
or via a custom mapping:
nnoremap <key> :<C-u>call AllMyCommands()<CR>
<key>
I have tried | but it did not worked.
:g/abc/d|:g/xyz/d|:g/ddd/d
In general, commands can be executed sequentially, separated by |, but there are exceptions, as :help :bar tells:
These commands see the '|' as their argument, and can therefore not be
followed by another Vim command:
[...]
:global
[...]
As a workaround, you can wrap them in :execute:
:exe 'g/abc/d'|exe 'g/xyz/d'|g/ddd/d
But putting them into a :function, as per #romainl's answer, is probably better.

:edit in function does not opens path given in argument

I have in .vimrc:
function! s:Edit(path)
vsplit a:path
endfunction
command! -nargs=1 -complete=file E call s:Edit(<q-args>)
Problem is that in new window i have file named "a:path" not file passed as argument to :E command.
Although my function starts to work when i do:
exec "vsplit".a:path
Why?
Can it be done better?
Build up your command and execute it with :execute. e.g.
function! s:Edit(path)
execute 'vsplit ' . a:path
endfunction
command! -nargs=1 -complete=file E call s:Edit(<q-args>)
For more help see :h :exe
Is there a better way?
Really depends on your goals. I would need more information about what this is supposed to do. However it seem like you want to create an alias for :vsplit. I would suggest you using cmdalias.vim or a the very least the following:
command! -nargs=? -complete=file -bang E vsplit<bang> <args>
If all you are doing is trying to optimize key strokes then the following mapping would also be sufficient:
nnoremap <leader>v :vsp<space>
Personally I would just get used to using :vsplit and stop worrying.

Calling "set" command within vim custom command

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.

Extend a vim command

How can I extend a command in vim?
I want to do it in two situations,
After a :diffget or :diffput I always want to run a :diffupdate
After a :NERDTreeToggle I want to run a <C-w>=
I am unaware of any autocmd events that would be triggered for your scenarios. However a few custom mappings might be helpful.
You can change the default dp and do mappings to also do a :diffupdate
nnoremap dp dp:diffupdate<cr>
nnoremap do do:diffupdate<cr>
Note there are times where you cannot use dp and/or do and must use :diffput/:diffget. In these cases I would suggest you create a commands like so:
command! -nargs=? -range=1 -bar Diffput <line1>,<line2>diffput <args>|diffupdate
command! -nargs=? -range=1 -bar Diffget <line1>,<line2>diffget <args>|diffupdate
Or you can just map :diffupdate
nnoremap <f8> :diffupdate<cr>
NERDTree
nnoremap <leader>N :NERDTreeToggle<cr><c-w>=
Maybe you can have a look to the vim macro. It is probably suitable for what you want to do :).
Create your own custom function in VimScript in your .vimrc that wraps several commands.
Here's one I use to launch a Clojure Repl in a buffer using several plugins:
fun! LeinCMD()
execute 'ConqueTerm lein repl'
execute 'set syntax=clojure'
execute 'normal! i'
endf
command! Repl call LeinCMD()
I then call this command with :Repl (note that your custom commands must always start with an uppercase letter).
Source: Automate running several vim commands and keystrokes

Resources