Vim: Substituir uma linha por outra puxada antes

112

Pelo menos uma vez por dia, tenho a seguinte situação:

A: This line should also replace line X
...
X: This is line should be replaced

Acredito que não desempenho essa tarefa de forma eficiente.

O que eu faço:

  • Vá para a linha A: AG
  • Yank line A: yy
  • Vá para a linha X: XG
  • Cole a linha A: P
  • Mover para a linha antiga: j
  • Excluir linha antiga: dd

Isso tem a desvantagem adicional de que a linha X está agora no registro padrão, o que é irritante se eu encontrar outra linha que deve ser substituída por A. Arrancar e colar de um registro adicional ( "ayy , " aP ) torna essa tarefa simples ainda menos eficiente.

Minhas perguntas:

  • Eu perdi um comando Vim embutido para substituir uma linha puxada antes?
  • Se não, como posso vincular meu próprio comando que deixa (ou restaura) a linha arrancada no registro padrão?
crocantes
fonte
2
Este é o meu maior problema com o modelo de edição do Vim. Adoraria saber uma solução. Um editor CUA distingue entre recortar e deletar, então você apenas recorta algum texto, então pode deletar e colar tudo o que quiser. Com o Vim, qualquer exclusão que você fizer trash seu texto cortado. Você acaba usando muito mais pressionamentos de tecla do que faria com outro editor.
Mud
3
YankRing
ajreal
@Mud aprenda sobre :movee o registro do buraco negro ( _) (ou, na verdade, apenas registra)
ver
2
@sehe Estou perfeitamente ciente dos registros, mas isso adiciona 4 pressionamentos de tecla por operação de recortar / colar e requer mais premeditação. Quando você está editando muito, isso aumenta rapidamente.
Mud
Além de economizar alguns bytes de memória, há alguma vantagem em usar o registro do buraco negro em oposição a qualquer outro registro? Eu diria que qualquer registro pode ser um registro de buraco negro se você não ler de volta a partir dele.
sleblanc,

Respostas:

91

O que eu faria :

  1. aG
  2. Y
  3. xG
  4. Vp

Você não tem que sair do modo normal, mas faz puxão na linha. No entanto, você pode usar o V"0pque sempre colocará a linha puxada na etapa 2.

crime de gelo
fonte
11
@duddle: sim, Yé sinônimo deyy
icecrime
8
As etapas 1 e 2 podem ser combinadas usando: ay [Ex: 20y] Seguido de Vp deve resolver o problema. Você não precisa ir a uma linha para puxá-lo.
Bharad
2
Se você sobrescrever linhas adicionais com ccCTRL + r0ESC em vez de V "0p, todas as linhas a seguir podem ser substituídas por apenas. (O repetidor)
Jordan Morris
Yé um sinônimo de yy, mas sugiro remapear para y$que corresponda a De C.
mgold
Confira a resposta de Jordan Morris stackoverflow.com/users/970673/jordan-morris abaixo - realmente usa os comandos do vim ao máximo, permitindo que você repita o comando várias vezes.
JESii
105

Vp: selecione a linha, cole o que foi puxado

Dorian
fonte
3
VPfunciona tão bem, o que é útil porque você pode manter a tecla Shift pressionada durante toda a sequência.
George Hilliard
24
truque muito bom, embora valha a pena observar uma advertência (talvez) significativa: isso faz com que o registro de arrancamento seja atualizado com o conteúdo da linha que está sendo sobrescrita, por isso pode não funcionar bem com algumas tarefas - por exemplo, se você quiser sobrescrever a mesma linha para vários destinos.
underscore_d
8
@underscore_d, funciona bem se você fizer isso V"0p, que cola do último registrador arrancado.
timblaktu
@timblaktu Você pode explicar o que V"0pfaz? V entra no modo de linha Visual e p é para colar. O que são "e 0 para? Obrigado
programador
43

Isso tem a desvantagem adicional de que a linha X agora está no registro padrão, o que é irritante se eu encontrar outra linha que deve ser substituída por A.

Para deletar texto sem afetar os registros normais, você pode usar o registro do buraco negro "_:

"_dd
Eugene Yarmash
fonte
10
Eu adicionei alguns mapeamentos ao meu .vimrc para fazer de ddsempre usar o buraco negro xe xxexecutar o que a maioria dos editores chamaria de "corte" (excluir e salvar no registro padrão):noremap x d noremap xx dd noremap d "_d noremap dd "_dd
IMSoP
2
Tenho receio de remapear coisas no VIM, porque isso pode não ser fácil em outros computadores ou em plug-ins no estilo VIM para IDE. Além disso, os designers do VIM tendem a resolver problemas com mapeamentos padrão se você realmente se interessar.
Jordan Morris
15

Com base nas respostas que sugerem usar Vpou VPcolar sobre uma linha - para evitar alterar o conteúdo do registro de puxão, acho que o comando mais ergonômico é simplesmente:

VPY

RichardW
fonte
Esta é a solução mais simples que mantém o mesmo conteúdo do puxão. Muito Obrigado!
heylookltsme
14
  1. yy
  2. j (mova para a linha que deseja substituir) e, em seguida
  3. Vp (v maiúsculo e depois p, será substituído pelo conteúdo arrancado)
Mariano Anaya
fonte
impressionante! Muito curto, de fato, e torna mais fácil selecionar várias linhas com modo visual. Ele também mantém o buffer de colagem intacto. É irritante quando o dd sobrescreve esse buffer ...
Aktau
@Aktau isso não deixa o buffer intacto.
Jordan Morris
9

Eu usaria o modo de linha de comando (Ex) e faria os dois comandos a seguir

:XmA
:Ad

Isso simplesmente move a linha X para logo abaixo de A, em seguida, a exclusão de A move essa linha para cima

Por exemplo

:7m3
:3d
Ericgamliel
fonte
Você pode dar um exemplo? Quando pressiono, por exemplo, 50Gm30G, o Vim vai para a linha 50 e depois para a parte inferior e é isso. Além disso: o anúncio não faz nada para A = 50 ou A = 50G
crocante de
7
  1. Vá para o início da primeira linha.

  2. y, $- copia a linha sem a quebra de linha no final

  3. Mova para o início da linha de destino.

    1. V, p- substituir apenas uma linha de destino

    2. c, c, Ctrlr, 0, Esc- substituir a linha de meta com o puxão originais

  4. Mova para o início da próxima linha de destino.

  5. . - repete o comando emitido em 4.2.

Notas:

  • 4.1 é y, $porque se você fizer isso y, you Yirá copiar a quebra de linha e Ctrlr, 0na verdade ,  adiciona a quebra de linha abaixo de sua linha de destino.

  • 4.2 substitui V p, que não funciona com repetir porque tecnicamente a última ação é excluir, então .apenas excluiria uma linha.

  • Se alguém souber como emitir 'substituir linha atual por registro' no modo EX (linha de comando), gostaria de ouvir de você (e saber onde você encontrou a documentação). Pode haver um comando EX repetível que é mais rápido do que 4.2 e / ou não tem a ressalva de quebra de linha.

Jordan Morris
fonte
1
O passo 4.2 é o assassino aqui, já que agora você pode repetir todo o processo com o comando ponto como em 4.3 - é disso que se trata o vim!
JESii
1
Eu não entendo. 'AG' coloca meu criador no final da linha, entra no modo de inserção e insere um 'G'. O que é que eu não entendo?
gustafbstrom
@gustafbstrom crítica justa - desculpe, o A deveria representar o número da linha, mas não consegui apontar isso. Editado.
Jordan Morris
5

Aqui está o que eu faria

  • Mova o início da linha A, AG(onde A é um número de linha obviamente)
  • Arranca a linha para algum registro, por exemplo, a (sem nova linha). Tipo"ay$
  • Mova para inserir linha, XG
  • Linha substituta, S
  • Insira do registro a, Ctrl-Ra
Brian Rasmussen
fonte
4

Você pode usar isso com o modo visual.

  • Vá para a linha A: AG
  • Selecione a linha com modo visual: VESC
  • vá para a linha X: XG
  • Entre no modo substituto para a linha: S
  • Cole a linha que você copiou: shift+ insert(ou qualquer outro mapeamento que você tenha para colar da área de transferência).
Nathan Fellman
fonte
Ah. Não sabia sobre V e S . No entanto, seus passos não funcionam para mim, pois não puxo para a área de transferência do sistema operacional, que é a única que posso acessar no modo de inserção. Então, eu teria que sair do modo de inserção primeiro.
crocante de
3

Você também pode fazer:

Vy (in normal mode at the line you want to copy)
Vp (in normal mode at the line you want to replace)
  • Não cria espaços ou extremidades de linha.
  • O cursor é colocado no início do texto copiado.

As mesmas teclas podem ser usadas para puxar / colar mais de uma linha.

V (in normal mode at what you want to yank)
(use jk to move the selection)
y (to yank the selection)
V (in normal mode at where you want to paste)
(use jk to move the selection)
p (to replace the selection with the yanked lines)
Kozmonaut
fonte
2

Você pode usar estes comandos no modo normal:

:AmX | Xd

o mcomando é para m[ove], que move o número da linha A após o número da linha X, se você quiser copiar em vez de mover a linha, use co[py]. o dcomando é para d[elete].

Você pode mover (copiar usando co) um intervalo de linhas usando

:start,end m X
Nafaa Boutefer
fonte
2

À luz do comentário recente de cicld (obrigado!), Vejo que não compreendi totalmente o problema original. Mover a linha não é apropriado, mas copiar é (já que a linha está puxada). Então, eu revisaria para:

:1t20:20d_
  1. Copie a 1ª linha (o :tcomando é um alias para :copy) após a linha 20 (irá colocá-lo na linha 21)

  2. Exclua a linha 20, colocando a linha excluída no registro do 'buraco negro' _(ou seja, não afetando o buffer de yank atual)

Conforme mencionado no comentário recente, isso não afetará a posição atual do cursor.

nkalvi
fonte
1
  1. : ay (onde a é o número da linha. Exemplo: 20y). Isso puxa uma linha (trocadilho intencional).
  2. Vp
Bharad
fonte
1

Acho mais fácil usar o comando Ex para isso; ex. para mover a linha 9 para 46:

 :46|9m.|-1d

Isso moverá o cursor para a linha 46, moverá a linha 9 abaixo da atual e, em seguida, excluirá a linha anterior (uma vez que a linha movida é a atual).

Ou usando marca (s), usando a marca 'a':

:46ma a|9m'a|'ad
nk3181544
fonte
A beleza dos comandos EX é que você pode executá-los onde quer que esteja o cursor (no modo normal). Eu prefiro :1m20|.+1d(mova a linha 1 para a linha 20 e exclua a próxima linha, ou seja, o texto que estava na linha 20 anteriormente). A mesma ideia!
circld
1

Freqüentemente, preciso usar uma linha em Y e substituí-la em vários lugares, cada um com um valor diferente (o que significa que não posso fazer uma regex).

Y arrancar a linha original desejada

e em cada linha que você deseja substituir, VpzeroY

Ron
fonte
0

Eu simplesmente usaria o registro "Buraco negro":

dado:

nnoremap <Cd> "_dd

a solução seria:

<Cd> yy

j5shi
fonte