No Vim, como aplico uma macro a um conjunto de linhas?

222

Eu tenho um arquivo com várias linhas. Gravei uma macro que executa uma operação em uma única linha. Quero repetir essa macro em todas as linhas restantes no arquivo. Existe uma maneira rápida de fazer isso?

Tentei Ctrl + Q, destaquei um conjunto de linhas e pressionei @@, mas isso não pareceu funcionar.

Jordan Parmer
fonte
Pergunta offtopic: eu não conhecia as macros do VIM (ou não queria saber: P) Você tem algum link orientado para o "leitor lento" nas macros do VIM?
OscarRyz
Claro, isto: oreillynet.com/mac/blog/2006/07/… resume muito bem.
Jordan Parmer
Você também pode verificar: ele complexa-repeat a partir vim dentro
Sam

Respostas:

354

Use o normal comando no modo Ex para executar a macro em várias / todas as linhas:

Execute a macro armazenada no registro a nas linhas 5 a 10.

:5,10norm! @a

Execute a macro armazenada no registro a nas linhas 5 até o final do arquivo.

:5,$norm! @a

Execute a macro armazenada no registro a em todas as linhas.

:%norm! @a

Execute o armazenamento de macro no registro a em todas as linhas que correspondem ao padrão .

:g/pattern/norm! @a

Para executar a macro em linhas visualmente seleccionados, prima V e o j ou k até a região desejada é seleccionada. Em seguida, digite :norm! @ae observe a seguinte linha de entrada é mostrada.

:'<,'>norm! @a

Digite : ajude o normal no vim para ler mais.

Juiz Maygarden
fonte
1
Sim: ajuda normal no vim ou no link que acabei de adicionar.
Maygarden do juiz
1
Qualquer coisa para ajudar um usuário não-emacs!
Julgador Maygarden
48
Agradável!! Beginner dica: use V, em seguida, j / k para destacar as linhas que você deseja, em seguida, digite apenas:norm! @a
Kevin Bourrillion
7
Para adicionar uma dica muito útil de @KevinBourrillion, ao pressionar :após destacar as linhas, a linha de entrada Ex lerá :'<,'>na qual você adicionará o restante do que Kevin sugeriu. Isso fará com que o comando final ler: :'<,'>norm! @a.
Deiwin
3
@GabeMoothart !Evita o remapeamento de chaves pelo usuário. Você pode não precisar, mas uma resposta que funcione para todos exige isso.
Maygarden do juiz
60

Use global para executar a macro 'a' em todas as linhas que contêm 'padrão'

:g/pattern/normal! @a

Para obter ajuda, consulte: :help global.

SergioAraujo
fonte
4
Apenas para esclarecimentos para futuros usuários: este é um comando Ex global.
atp
39

Você também pode fazer isso:

No modo normal:

[number of times to apply the macro] @ [register]

Por exemplo:

1000@q

Apaga a macro no registro q para as próximas 1000 linhas.

Atualização: a resposta aceita é muito melhor

Atualização: como apontou @kevinliu, é provável que você queira finalizar a macro com a jpara ir para a próxima linha.

Max Heiber
fonte
4
Isso para na última linha e não executa várias vezes na última linha, o que eu temia.
Hubro 02/08/2015
@Hubro, estas respostas de outros usuários funcionou para mim: :%norm! @aevGG :norm! @a
Max Heiber
2
Por alguma razão, isso funcionou muito bem, e a resposta aceita não. Minha macro envolvia inserir uma nova linha, fazer coisas e passar para a próxima linha.
jasonszhao
@jasonszhao sim mesmo aqui. mas existe mesmo assim para não dizer 1000, mas todas as linhas até o final .. e ainda cuidar da nova linha, fazendo coisas etc.
ihightower
2
Eu acho que deve ser destacado que sua macro deve terminar com um jcomando para ir para a próxima linha, caso contrário, tentará aplicá-la à mesma linha.
Kevin Liu
2

Há também um plugin chamado RangeMacro, faz exatamente o que você deseja! Para todos que não conseguem adivinhar pelo nome, o que faz: repete uma macro gravada para cada linha em um determinado intervalo, independentemente da seleção visual ou de: 40,50 /: +10

Consulte http://www.vim.org/scripts/script.php?script_id=3271

phux
fonte