4

Is there a way in vim to give a list of editor commands? I want to execute a series of 'global' commands, and there is some pattern to the commands. So I would ideally like to generate the list of commands (using regex search & substitute), and then run them, instead of having to type in each command.

Thanks! Gaurav

1
  • Are you trying to generate the list on-the-fly inside of a function or script, or would a text file be sufficient? Commented Dec 2, 2009 at 6:00

4 Answers 4

8

(Update: s/buffer/register/g)

If you can yank all of the commands you want to run into a register, then execute the register ?

http://www.bo.infn.it/alice/alice-doc/mll-doc/linux/vi-ex/node24.html

For example, if you have a file like:

abc
def
ghi
dd
dd

Then do

:g/dd/y A

This yanks all lines with dd and appends into register a

Then if you are on the first line of the file, and type:

@a

Then 2 lines will now be deleted, and the file should look like:

ghi
dd
dd
Sign up to request clarification or add additional context in comments.

3 Comments

Good post. I don't want to seem critical, but I'm curious as to why you did some things. Wouldn't it be easier to record a macro? And for yanking into a register wouldn't it be easier to use visual mode and then yank instead of searching for the commands you want to yank? And why did you yank to register A instead of a (they end up being the same, just curious if you had a reason). Finally, when you yank text it goes into a register, not a buffer. The register is like the clipboard, the buffer is the text you're editing.
Thanks for the comments. 1. The specific requirement gveda has was to generate a list of commands using regex search and substitute. I took this to mean, look for commands based on a regex, and execute these commands in order. 2. Yes, you can use visual mode, and a macro, but see 1. 3. The post I linked to called it a buffer, not a register. Oops.
It might be worth adding that you need register 'a' to be clear before starting: either with something like :let @a = '' or with something like 0"ay0.
1

Sounds like a macro to me. Google vim macros for tons of useful information. Basically

  1. In command mode type q followed by some other letter which will be the register in which we store the macro. For example 'qw'.
  2. Run the commands you want to store for future use. This can be anything including regex substitutions, movements, inserts, deletes, etc.
  3. When you are done hit q again. You now have stored your actions for future use. To rerun what you just did type @w (or whatever letter you used for the register to save the macro in).

There's a lot of power in macros. Sometimes you want to save macros between sessions. When I want to do that, you can paste the macro into a buffer by pasting the register you just saved to. For example, if you saved your macro to register w, type "wp to paste register w (note that's the double quote, not two single quotes). You'll see some funny characters for when you pressed escape or enter. There are more readable ways of writing these like and , but ^[ and ^M will work too.

You can now yank those lines into a register (I see someone just posted an answer with this but somewhat differently than I'd do it) by selecting the text in visual mode and then typing "wy. This yanks the selected text into register w. Now to run the register as a macro, type @w as before.

If it's something you use often it might be worth mapping the macro to a shortcut command in your .vimrc. For example, here's a few maps I have in my vimrc to help me easily open and save my .vimrc

" For modifying the .vimrc
nmap ,e :e $HOME/.vimrc<cr>
nmap ,s :write!<cr>:source $HOME/.vimrc<cr>

Now when I'm editing any file and discover a new macro I'd like to save I type ,e to open my .vimrc. I paste the macro in, prepend a map statement (there's different maps depending on which mode you're in, plenty of documentation to explain this if you're interested), and save the .vimrc with ,s which also sources the .vimrc so that my new mapped command is available in other files without restarting vim.

3 Comments

As you anticipated, I now have a macro that I would want to use across files, and hence would like to save it in my .vimrc. So I opened my .vimrc, and pasted my macro there ("ay). Then I created the appropriate entry which looks like the following: nmap ,a :%s/ 0\./ || 0./^Mgg:%s/\(Topic [0-9]*\):/{|border="1" style="float:left;"\r! colspan="2" align="center" | '''\1'''b/^Mgg:%s/^\([a-z]\)/|-\r| \1/^Mgg:g/^$/ d^MGo|}^[:g/^{|/ s/^{|/|}\r{|/^Mggdd But now on opening any file, I get: Error detected while processing ~/.vimrc: line 17: E749: empty buffer Any idea? Thx a lot!
I figured out the problem with my map expression. I was using a pipe character without escaping it with a backslash. I don't need to escape it when I am typing the command manually, but when I set up a macro, apparently I need to escape it (since otherwise I think the editor interprets it as the end of one command and the beginning of another command - the usual interpretation for the pipe operator on the shell).
Glad you figured out about escaping characters. That happens sometimes and can be a pain to figure out. One thing I have yet to figure out is how to enter a macro like that on multiple lines so that it can be formatted nicely, and perhaps even commented to explain what is being done.
0

Here is mappings to run interactively vim commands:

" run selected vimscript
vmap <Leader>r "vy:@v<CR>
" run vimscript line
nmap <Leader>r "vyy:@v<CR>

Check vim help for:

:h :@

So in your case (silly example):

:g/line/
:g/for/
:g/endfor/

for line in getline(1, 3)
  let @a = line
  @a
endfor

save it as .vim and :so %

Comments

0

The word "command" is kind of ambiguous here. You can also execute Ex commands that have been yanked into a register using :@" eg for the default register. This is especially useful when you're writing vimscript code, eg in your .vimrc file, and you want to test out functions or mappings to make sure they work okay.

So if you have a buffer that contains

tabedit http://stackoverflow.com/questions/1830886/vim-executing-a-list-of-editor-commands
%s/intuited/The King Of Everything/g
w /tmp/superduperawesome.html
!/usr/bin/sensible-browser /tmp/superduperawesome.html

you can use the normal mode actions

ggyVG:@"

to bring up a slightly different version of this page.

It's also possible to execute the code that's stored in a register, or in a variable, using

:execute @"

but there seem to be some weird issues with this: it will stop executing when it hits a comment or the end of a block. I haven't had those problems using :@".

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.