Como posso inserir texto no meio da linha para várias linhas no Vim?

91

Digamos que tenho dez linhas e desejo acrescentar texto a alguma palavra que ocorre nessas linhas. Não precisa estar no início da linha.

De:

sdfsd   foo sdfsd
sfsd    foo fsdf
sdfsdf  foo  sdfsdf

para:

sdfsd   bar(foo sdfsd
sfsd    bar(foo fsdf
sdfsdf  bar(foo  sdfsdf

Também é possível não apenas preceder, bar(mas realmente circundar foocom bar(foo)?

Também gostaria de uma maneira rápida de acrescentar //comentários a várias linhas (comentários de estilo C).

Eu uso o Vim / GVim 7.2.

Allen
fonte
1
Os comentários do estilo C são / * * / Os comentários do estilo BCPL são //
William Pursell

Respostas:

169

Vá para o primeiro foo, pressione Ctrl- vpara entrar no modo de bloqueio visual e pressione para baixo até que todas as linhas com foosejam marcadas. Em seguida, pressione Shift- ipara inserir no início (do bloco). Quando terminar e pressionar Esc, os caracteres inseridos serão adicionados a cada linha à esquerda do bloco marcado.

Para inserir no final, pressione novamente Ctrl- v, mova para cima / para baixo para marcar todas as linhas afetadas e pressione Endou $para estender a seleção até o final das linhas. Agora você pode pressionar Shift- apara acrescentar no final de todas as linhas, como anteriormente com Shift- i.

A seleção visual também pode ser feita com comandos de movimento normal. Portanto, para comentar um bloco inteiro em C, você pode mover para a chave de abertura e digitar Ctrl- v % Shift- i // Esc.

sth
fonte
5
Apenas um acréscimo: se Ctrl-V não iniciar o modo de bloqueio visual no Vim no Windows, deve-se usar Ctrl-Q.
Paul
3
Uma variação da resposta é marcar o bloco visual com shift + V e alterar o bloco no modo ex:: '<,'> s / ^ / prexix_text /: '<,'> s / $ / suffix_text / Note que "'< , '> "é impresso automaticamente pelo vim quando você pressiona": ".
dimba
1
Para descomentar use o bloqueio visual (marque com Ctrl + V). Uma das colunas com o sinal de comentário "//" é marcada, pressione "d" para remover os comentários. não se esqueça dos comentários em C ++ (/ ** /) também :)
dimba
9
É importante notar que no Linux eu tive que sair do modo Inserir antes do prefixo ser aplicado a todas as linhas, e é uma letra maiúscula que eu precisava para entrar no modo inserir no modo Visual - isto é, Shift + I, prefixo de tipo, Escape, Escape.
Joshua Enfield,
6
Isso não funciona em massa. Quando pressiono, inada acontece. Quando pressiono, shift+ia seleção desaparece mas consigo inserir texto (apenas no local atual onde está o cursor).
Jürgen Paul
44

Para responder à sua primeira pergunta, a seguir

:%s/foo/bar(&)/g

procurará fooe envolverá o padrão correspondente com bar(). O /gfará isso várias vezes em uma linha.

Já que você está apenas combinando foo, você poderia fazer uma coisa simples :s/foo/bar(foo)/g. O procedimento acima funcionará, no entanto, se você decidir fazer a correspondência com uma expressão regular em vez de uma palavra simples (por exemplo f[a-z][a-z]). O '&' acima representa o que você combinou.

Brian Agnew
fonte
Eu tive uma resposta longa e grande com macros. É muito mais fácil :-)
Brian Ramsay
Como você faz isso para várias linhas? Um caso prático é quando você tem um bloco de código composto por linhas semelhantes que requerem essa substituição.
Parece que funciona em todas as linhas ... observe:% s e / g.
ojrac
o que é interessante é que:% s / foo / bar (&) / gc não confirma - 'c' não tem efeito
1
O texto entre o :e o sdetermina em quais linhas ele opera. Nada significa apenas a linha atual. 1,30significa linhas 1 a 30 (inclusive). '<,'>significa as linhas na seleção visual atual.
rampion
17

Para prefixar um conjunto de linhas, uso uma das duas abordagens diferentes:

Uma abordagem é a seleção de bloco (mencionada por sth). Em geral, você pode selecionar uma região retangular com ctrl-Vmovimento do cursor seguido. Depois de realçar um retângulo, pressionar shift-Iirá inserir caracteres no lado esquerdo do retângulo ou shift-Airá anexá-los no lado direito do retângulo. Portanto, você pode usar essa técnica para fazer um retângulo que inclua a coluna mais à esquerda das linhas que deseja prefixar, pressione shift-I, digite o prefixo e, em seguida, pressione escape.

A outra abordagem é usar uma substituição (conforme mencionado por Brian Agnew). A substituição de Brian afetará todo o arquivo (o% no comando significa "todas as linhas"). Para afetar apenas algumas linhas, a abordagem mais fácil é acertar shift-V(o que ativa o modo de linha visual) na primeira / última linha e, em seguida, mover para a última / primeira linha. Em seguida, digite:

:s/^/YOUR PREFIX/

O ^ é um regex (neste caso, o início da linha). Ao digitar isso no modo de linha visual, você verá '<,'> inserido antes do s automaticamente. Isso significa que o alcance da substituição será a seleção visual.

Dica extra: se o seu prefixo contiver barras, você pode fazer o escape delas com uma barra invertida ou usar um caractere de pontuação diferente como separador no comando. Por exemplo, para adicionar comentários de linha C ++, geralmente escrevo:

:s:^:// :

Para adicionar um sufixo, a abordagem de substituição é geralmente mais fácil, a menos que todas as suas linhas tenham exatamente o mesmo comprimento. Apenas use $ para o padrão em vez de ^ e sua string será anexada em vez de pré-pendente.

Se você quiser adicionar um prefixo e um sufixo simultaneamente, pode fazer algo assim:

:s/.*/PREFIX & SUFFIX/

O. * Corresponde a toda a linha. O & na substituição coloca o texto correspondente (a linha inteira) de volta, mas agora terá seu prefixo e sufixo adicionados.

BTW: ao comentar o código, você provavelmente vai querer descomentar mais tarde. Você pode usar o visual-block ( ctrl-V) para selecionar as barras e então pressionar d para excluí-las, ou você pode usar uma substituição (provavelmente com uma seleção de linha visual, feita com shift-V) para remover as barras iniciais como esta:

:s:// ::
Laurence Gonsalves
fonte
6

: normal para o resgate!

:%norm Wibar(

:%norm WEa)

: norm (al) repete os comandos como se você os tivesse digitado:

W - vai para a próxima palavra

i - inicia o modo de inserção

bar (- digita a sequência 'bar ('

Ou em uma linha:

:%norm Wibar(ctrlvESCEa)

Se você estiver executando o Windows, digite em ctrlqvez de ctrlv.

Cyber ​​Oliveira
fonte
3

Ainda outra possibilidade (provavelmente não tão útil em seu caso de teste, mas útil em outras situações) é isolar a área que você deseja alterar com marcas.

  • Coloque o cursor em qualquer lugar na linha superior e pressione 'a
  • Coloque o cursor em qualquer lugar na última linha e pressione 'b
  • Emita o comando :'a,'b s/foo/bar(&)/

Normalmente gosto do modo de bloqueio visual se tudo estiver visível na tela e geralmente prefiro marcas se o início e a parada forem separados por várias telas.

Godfrey Parke
fonte
Deve ser em mvez de 'definir um novo marcador. 'é para saltar para a linha de um marcador existente. `salta para a linha e coluna desse marcador.
tiktak
1

Outra expressão regular simples é:

%s/^/<text you want to prepend>/
Artorias2718
fonte
0

Para os comentários de estilo C, use a resposta regexp de Brian, combine na terminação de linha $e insira imediatamente.

maxwellb
fonte