vim: Continuar macro após erro no submacro?

11

Estou no processo de embelezar alguns códigos-fonte usando o vim. {1}

Eu criei algumas macros vim que executam as etapas individuais: removendo espaços em branco, removendo linhas vazias após { , removendo linhas vazias antes de { , esse tipo de coisa.

Agora, quero criar uma macro que execute todas as macros individuais em sequência. No entanto, uma vez que a primeira macro recursiva termina (porque ela não consegue mais encontrar nenhuma correspondência - > erro de correspondência), minha macro "wrapper" também termina.

Existe uma maneira de fazer com que uma macro vim continue depois que um submacro gerou um erro?

{1} Eu conheço sobre reformatadores automáticos. Eu posso até usá-los no meu problema atual. Mencionei apenas a reformatação de fontes pelo exemplo. Não publique nenhuma resposta sobre esse embelezador de fontes ou algo assim. A questão não é sobre reformatação de código per se , mas sobre macros vim.

Exemplo:

  • Macro 1 - aparando espaços em branco finais - qw/\s\+$d$@wq
  • Macro 2 - excluindo linhas vazias antes de} - qe/\n\n *}dd@eq
  • Macro de invólucro - retabbing, Macro 1, Macro 2 - qr:retab@w@eq

Quando eu executar o wrapper - @r - ele será retablado, depois executará a Macro 1 até que nenhum outro espaço em branco seja encontrado, então termine ( sem executando a Macro 2).

Esclarecimento:

O que estou procurando é como chamar um submacro para que, quando essa submacro terminar, a macro de chamada continue?

    
por DevSolar 04.08.2011 / 16:54

3 respostas

11

Eu sugiro que você use :try para "absorver" o erro da submacro.

Aqui está um exemplo bobo:

:let @a='f|dt|@a'
:let @q=':try|exe "norm! @a"|endtry^Mj0@q'
@q

Sua macro de wrapper seria algo como isto:

let @r=':retab^M:try|exe "norm! @w"|endtry|try|exe "norm! @e"|endtry^M'
    
por 20.09.2011 / 17:22
19

Se o comando com falha for uma substituição que não esteja encontrando seu padrão, por exemplo,

:%s/foo/bar/

quando foo não existe no buffer, você pode adicionar o sinal e para ignorar esse erro, por exemplo,

:%s/foo/bar/e

Veja

:help :s_flags

Você pode dizer ao Vim para ignorar os erros de alguns comandos: ex, precedendo-os com :silent! . Veja

:help :silent

Editar após a adição do exemplo à pergunta

A macro 1 e a macro 2 são recursivas e não possuem nenhum mecanismo explícito para encerrar a recursão. Meu palpite é que um dos testes internos do Vim para recursão ilimitada está sendo acionado, o que gera um erro. Se a Macro 1 estiver gerando tal erro, esse erro encerrará a execução da Macro do Wrapper logo após @w .

Minha sugestão seria limitar o número de vezes que suas macros estão sendo executadas, reescrevendo-as como: ex-comandos e limitando o intervalo de linhas sobre as quais elas são executadas. Por exemplo:

qw:%s/\s\+$//^Mq
qe:%s/\n\n *}/\r}/^Mq

onde ^M significa digitar sua tecla Enter ou Return. Eu não testei os juntos na sua Macro de Wrapper, mas acho que você poderá corrigir quaisquer erros que eu possa ter cometido.

    
por 04.08.2011 / 17:48
1

Eu costumo criar macros on-the-fly quando eu preciso fazer uma tarefa repetitiva entre muitos arquivos. No meu caso, eu tenho NERDtree ( link ) instalado no VIM, que cria um vsplit janela, e à esquerda, eu tenho uma lista de todos os arquivos no diretório atual. Em um exemplo, eu preciso encontrar a primeira instância da seqüência de caracteres MY_TEST no arquivo e, em seguida, excluir, se presente, um prefixo rotulado como CUSTOM_PREFIX- dessa linha, salve o arquivo e, em seguida, mova para o próximo. / p>

Veja como eu tenho essa macro trabalhando em cerca de 2000 arquivos no diretório atual. Eu poderia escrever um script bash para fazer isso, mas é mais rápido no VIM, no meu caso. O + indica que as teclas estão sendo pressionadas simul

# Start recording a macro sequence to register 'A'

q , a

# Search silently for the string "MY_TEST"; DO NOT report an error
# if the string could not be found.
:silent! /MY_TEST


# Replace, on just the current line, the string "CUSTOM_PREFIX-", with
# nothing (ie: delete it), and suppress any warning messages if the
# string could not be found on the current line.
:s/CUSTOM_PREFIX-//e


# Now issue some UI commands. CTRL-W then and arrow key lets you hope
# between tabs/splits/windows within vim.

CTRL + W ,

# Scroll down to the next file in the list in NERDtree



# Open the next file

ENTER

# End the macro

q

# Run the macro a thousand times in VIM

1000, @ , a

Espero que isso ajude!

    
por 24.05.2013 / 18:43

Tags