Multiple commands on same line
Asked Answered
L

7

263

I've been trying to find something that will let me run multiple commands on the same line in Vim, akin to using semicolons to separate commands in *nix systems or & in Windows. Is there a way to do this?

Ludly answered 14/7, 2010 at 18:35 Comment(4)
Wow I was trying to learn about vim from your question (which I did) and found out I could use ; instead of && to separate Unix shell commands too!Goer
@ebyrob I feel it's important to note that && is 'boolean and' in shell commands so if you have command1 && command2, command2 will only execute if command1 executed successfully. with ; you're just manually specifying the end of that line and starting a new one. It's the same as writing each command on a different line in a shell script.Wire
...and command1 || command2, command2 will only execute if command1 fails. That's because in computer logic the || and && are bitwise, and even though "&&" implies that both command1 AND command2 are to be evaulated, command2 does NOT need to be evaluated if command1 fails because no matter what cmd2 returns, it will always fail since the first one returned false (0), and 0&&1 would still be zero.Similarly, if command1=true, theres no reason for command 2 in an OR evaluation because at that point it's already true (1), because 1||0 is 1, and only if it's 0, would need 0||1(which is still 1)Utimer
@Utimer that is known as short circuiting/ short circuit evaluation.Roundelay
D
314

A bar | will allow you to do this. From :help :bar

'|' can be used to separate commands, so you can give multiple commands in one line. If you want to use '|' in an argument, precede it with '\'.

Example:

:echo "hello" | echo "goodbye"

Output:

hello
goodbye

NB: You may find that your ~/.vimrc doesn't support mapping |, or \|. In these cases, try using <bar> instead.

Durkee answered 14/7, 2010 at 18:40 Comment(9)
Just watch out for the handful of commands that don't work with |!Syringa
When you find yourself wanting to use multiple commands in a map statement (and believe me, you will), check out :help map_bar.Ciceronian
That's true. I asked that very question on superuser a few months ago. My .vimrc doesn't support an escaped bar (\|) for mappings. I learned I have to actually type out <bar>.Durkee
Thanks for the working solution! :help bar shows motion.txt though and nothing about multiple commands.Polk
Is there a way to run all the commands even if some of the previous commands have failed? Asking because I've noticed that if I run :command1|command2 and command1 fails, the command2 won't be executed.Thunderstorm
@Thunderstorm Found the answer here: vim.wikia.com/wiki/Multiple_commands_at_once Just use :silent! cmd1|cmd2|...Thunderstorm
Special consideration needs to be taken for normal as this command cannot be followed by another command, since any '|' is considered part of the command.Yoshikoyoshio
@Polk should be :help <bar>Jennette
User-defined commands apparently need to be defined with -bar, for | to work as command separator - see :h command-bar.Brisesoleil
G
118

Put <CR> (Carriage Return/Enter) between and after commands. For example:

map <F5> :w<CR>:!make && ./run<CR>

Don't use | because:

  • Some commands have problems if you use | after them

  • | does not work consistently in configuration files, see :help map_bar

Giovannagiovanni answered 30/6, 2013 at 15:28 Comment(1)
From :h map_bar I got that it was ok to use <bar>. But you're right, it is complicated. Reading :h map_bar is the way to go here.Flashcube
U
49

You could define a function that executes your commands.

function Func()
     :command
     :command2 
endfunction

And place this in, for example, your vimrc. Run the function with

exec Func()
Unsought answered 16/7, 2010 at 16:5 Comment(4)
Clean solution. Would definitely be handy for more than two or just long commands.Modish
Very useful also for the ability to hand errors with try/catch.Loren
It's more conventional to use :call Func() because :execute Func() means something more. It means to perform the return value of the function as a command. The function described here will not usually have a command that starts with :return, so its return value will be the number zero. Performing that as a command will move the cursor to the first line of the current buffer, which is not always what you had in mind.Vanillic
@Vanillic thank you so much! I was debugging and turned out only call works; exec produces unexpected results. Thank you!Farrison
K
37

The command seperator in vim is |.

Katrinakatrine answered 14/7, 2010 at 18:39 Comment(0)
Y
21

Thought this might help someone trying to do substitutions in a chain and one fails

from a comment

%s/word/newword/ge | %s/word2/newword2/ge

You can use the e flag to ignore the error when the string is not found.

Yanina answered 26/1, 2018 at 22:35 Comment(1)
Very useful hint!Bolton
Z
20

I've always used ^J to separate multiple commands by pressing Ctrl+v, Ctrl+j.

Zingaro answered 14/7, 2010 at 18:41 Comment(5)
This seems to be the only solution that actually works. Who do I specify this if I want to use it in a string?Shumaker
You cannot use ^J as command separator in a string because it is inserting the NULL character terminating the string. however you can use <CR> = "\n".Literal
exe "echo 'foo' \n echo 'bar'"Literal
exe "echo 'foo'" . nr2char(0x0a) . "echo 'bar'"Literal
map aa :echo 'foo' <C-V><C-J> echo 'bar'<CR>Literal
L
3

You can create a new file, and write your commands on it. Then :so %, which means source current file.

Lysol answered 24/4, 2015 at 4:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.