tags:

views:

264

answers:

4

Hi,

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

+5  A: 

(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
toolkit
+1: NICE! Very very nice!
Al
Great answer. This is exactly what I was looking for. Thanks! -Gaurav
gveda
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.
mmrobins
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.
toolkit
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`.
Al
+1  A: 

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.

mmrobins
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 bufferAny idea? Thx a lot!
gveda
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).
gveda
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.
mmrobins
+1  A: 

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 %

Maxim Kim
A: 

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 :@".

intuited