No Vim, existe uma maneira de excluir sem colocar texto no registro?

470

Usando o Vim, geralmente desejo substituir um bloco de código por outro que acabei de puxar.

Mas quando eu excluo o bloco de código que será substituído, o próprio bloco entra no registro que apaga o bloco que acabei de puxar. Então, eu tenho o hábito de puxar, inserir e excluir o que não queria, mas com grandes blocos de código, fica complicado tentar manter o bloco inserido e o bloco a ser excluído separados.

Então, qual é a maneira mais rápida e rápida de substituir o texto no Vim?

  • existe uma maneira de excluir texto sem colocá-lo no registro?
  • existe uma maneira de dizer, por exemplo, "substituir a próxima palavra" ou "substituir até o próximo parágrafo"
  • ou é a melhor maneira de usar o recurso de registro múltiplo?
Edward Tanguay
fonte
1
vim-EasyClip ( github.com/svermeulen/vim-easyclip ) é projetado para resolver este problema exato
Steve Vermeulen
1
Fiz uma pergunta, sem saber (na época), uma duplicata do seu problema real , mas não muito da pergunta do título. TL; DR - substitua pelo que você puxou usando viwp(para word).
OJFord

Respostas:

429

Para excluir algo sem salvá-lo em um registro, você pode usar o "registro do buraco negro":

"_d

Claro que você também pode usar qualquer um dos outros registradores que não contêm nada do seu interesse.

Christian Berg
fonte
4
No começo, pensei que este comando não estava funcionando corretamente. Então percebi que estava usando uma versão de "teclas mortas" do teclado americano. Com esse layout de teclado, tenho que digitar "<space>_d. O espaço é necessário para realmente digite o".
Sebastián Grignoli
4
Alguma idéia de fazer isso seletivamente apenas em linhas vazias? (Se eu estiver ddem uma linha vazia, ela entra no buraco negro, caso contrário, ddé normal).
Jonathan Dumaine 5/03
6
Para remover um caractere, tente:"_x
kenorb 6/13
54
Essa é uma área em que um editor de texto padrão vence. Você simplesmente pressiona a tecla Delete.
Vince Panuccio
22
Você também pode puxar algo com yyou '3yy' (ou o que seja), o que o coloca no registro sem nome, mas também em 0. Você pode continuar colando "0p, apesar de ter usado ddepois disso.
Halfgaar 7/08/15
102

Sim. É um pouco mais complicado do que excluir o texto "antigo" primeiro, mas:

Eu começo com ..

line1
line2
line3
line4

old1
old2
old3
old4

I shift+ vseleciono as linhas 1, 2, 3 e 4 e as excluo com o dcomando

Em seguida, apago as linhas 1-4 antigas da mesma maneira.

Então faça

"2p

Isso colará as segundas últimas linhas arrancadas (linha 1-4). "3pfará o terceiro do último, e assim por diante ..

Então eu acabo com

line1
line2
line3
line4

Referência: documentação do Vim no registro numerado

dbr
fonte
Se você selecionar linhas com <Shift-v> de excluí-los com apenas d, não dd
Heikki Naski
31
1 a 9 funciona para exclusões. Para colar a última coisa realmente arrancada (com 'y'), é necessário usar "0p. Isso é útil nos casos em que você arranca algo que pretende substituir outra coisa, mas depois a outra coisa substitui o registro de colagem padrão.
Rafael de F. Ferreira
Para mais sofisticação, desfaça o script Gundo (desfazer gráfico) .
Lumi
@ RafaeldeF.Ferreira: Seu comentário não é uma resposta a esta pergunta, mas na verdade resolve provavelmente o problema real que levou o OP a fazer a pergunta em primeiro lugar. Para mim, esse era o verdadeiro problema.
0xc0de
76

Documentos do VIM: O registro numerado 0 contém o texto do comando yank mais recente, a menos que o comando especifique outro registro com ["x].

Por exemplo, puxamos "foo" e excluímos "bar" - o registro 0 ainda contém "foo"! Portanto, "foo" pode ser colado usando"0p

alex2k8
fonte
53

É útil ter um mapeamento fácil, que permite substituir a seleção atual por buffer.

Por exemplo, quando você coloca isso em seu arquivo .vimrc

vmap r "_dP       // it's a capital 'p' on the end

depois, depois de copiar algo no registro (ou seja, com 'y'), você pode simplesmente selecionar o texto que deseja substituir e simplesmente pressionar 'r' no teclado. A seleção será substituída pelo seu registro atual.

Explicação:

vmap - mapping for visual mode
"_d - delete current selection into "black hole register"
P - paste
João Portela
fonte
1
Para uma versão mais avançada, verifique: stackoverflow.com/questions/290465/…
Luc Hermitte
Eu gostaria de usarvmap <C-P> "_dP
Harry Lee
7
Você pode simplesmente colocar o texto sem excluir a seleção. Por exemplo, Vpsubstitui sua linha atual pela arrancada imediatamente.
Bobby Marinoff
Esta solução não resolve o problema dque está sendo frequentemente usado para exclusão.
Victor Yarema 06/06/19
35

Coloquei o seguinte no meu vimrc:

noremap  y "*y
noremap  Y "*Y
noremap  p "*p
noremap  P "*P
vnoremap y "*y
vnoremap Y "*Y
vnoremap p "*p
vnoremap P "*P

Agora eu puxo e pego do registro da área de transferência e não preciso me importar com o que acontece com o registro padrão. Um benefício adicional é que eu posso colar de outros aplicativos com o mínimo de problemas. Estou perdendo algumas funcionalidades, eu sei, mas simplesmente não consigo acompanhar mais de um registro / área de transferência de qualquer maneira.

Magnus
fonte
6
Em vez de todos os remaps, você também pode set clipboard=unnamedou set clipboard=unnamedplus, que altera a área de transferência padrão para *ou +, respectivamente.
8133 Steve Steve
5
@Steve Se você fizer isso, d também sobrescreverá o último puxão no registro da área de transferência, que é o que a pergunta está tentando evitar.
79E09796
1
@ 79E09796, não pretendia sugerir que sim; Eu estava comentando sobre esta resposta e não a pergunta original.
Steve
1
Coloquei-os no meu .vimrc e agora puxar não funciona. Alguma idéia do porquê?
TBA
2
@ tba substitua noremap por nnoremap (dois n) e deve funcionar bem.
meain
24

Para o exemplo específico que você deu, se eu entender a pergunta, isso pode funcionar:

*Highlight what you want to put somewhere else
*delete (d)
*Highlight the code that you want it to replace
*paste (p)
EBGreen
fonte
6
Isso funciona bem, exceto quando você deseja colar sobre várias seleções.
23

Todas as operações de arrancar e excluir gravam no registro sem nome por padrão. No entanto, o arranque mais recente e a exclusão mais recente são sempre armazenados (separadamente) nos registros numerados. O registro 0contém o puxão mais recente. Os registros 1-9contêm as 9 exclusões mais recentes ( 1sendo a mais recente).

Em outras palavras, uma exclusão substitui o arranque mais recente no registro sem nome, mas ainda está lá no 0registro. O truque do registro de buraco negro ("_dd ) mencionado nas outras respostas funciona porque impede a substituição do registro sem nome, mas não é necessário.

Você faz referência a um registro usando aspas duplas, portanto, colar o texto arrancado mais recentemente pode ser feito assim:

"0p

Esta é uma excelente referência:

Wayne
fonte
16

Para enfatizar o que a EBGreen disse :

Se você colar ao selecionar o texto, o texto selecionado será substituído pelo texto colado.

Se você deseja copiar algum texto e colá-lo em vários locais, use "0ppara colar. O registro numerado 0 contém o texto do comando yank mais recente.


Além disso, você pode listar o conteúdo de todos os seus registros:

:registers

Esse comando torna mais fácil descobrir qual registro você deseja ao executar algo como a resposta do dbr . Você também verá os registros /,%, #. (Veja também :help registers)


E, finalmente, confira cWe cWaltere uma palavra, incluindo e não um espaço à direita. (Usar capital Winclui pontuação.)

idbrii
fonte
10

Se você estiver usando o Vim, terá o modo visual, que é como selecionar, mas com os modos de separação que são a base do vi / vim.

O que você deseja fazer é usar o modo visual para selecionar a fonte e, em seguida, puxar, em seguida, usar o modo visual novamente para selecionar o escopo do destino e colar no texto a partir do buffer padrão.

Exemplo:

Em um arquivo de texto com:

1 | qwer
2 asdf
3 zxcv
4 poiu

com a seguinte sequência: ggVjyGVkpvocê terminará com:

1 | qwer
2 asdf
3 qewr
4 asdf

Explicado:

  • gg: ir para a primeira linha
  • V: inicia o modo visual com linhas inteiras
  • j: desce uma linha (com a seleção iniciada nas linhas anteriores, aumenta a seleção uma linha abaixo)
  • y: puxa para o buffer padrão (as duas linhas selecionadas e sai automaticamente do modo visual)
  • G: ir para a última linha
  • V: inicia o modo visual (o mesmo de antes)
  • k: sobe uma linha (como antes, com o modo visual ativado, aumenta a seleção de uma linha)
  • p: paste (com a seleção nas duas últimas linhas, ele substituirá essas linhas pelo que houver no buffer - as 2 primeiras linhas nesse caso)

Isso tem o pouco inconveniente de colocar o último bloco no buffer, então, de alguma forma, não é desejado para pastos repetidos da mesma coisa; portanto, você deseja salvar a fonte em um buffer nomeado com algo como "ay(em um buffer chamado "a ") e cole com algo como "ap(mas, em seguida, se você estiver programação, você provavelmente não quer colar várias vezes, mas para criar uma função e chamá-lo, certo? dIREITO ?).

Se você estiver usando apenas o vi, precisará usar marcas invisíveis no modo visual. :he markPara mais informações, desculpe, mas não sou muito bom com essa coisa de marcas invisíveis, estou bastante contaminado com o modo visual.

maeghith
fonte
10

Para 'substituir palavra', tente cwno modo normal.

Para 'substituir parágrafo', tente capno modo normal.

Swaroop CH
fonte
1
Para 'substituir até o próximo parágrafo', tente c}no modo normal.
jabirali
Por que "cap" faz isso? "A" e "p" não significam "anexar" e "colar"?
WiSaGaN
2
@WiSaGaN "ap" significa "um parágrafo": vimhelp.appspot.com/motion.txt.html#object-select
Swaroop CH
9

Uma solução invasiva mínima para os preguiçosos:

O registro 0sempre contém o último puxão (como Rafael , alex2k8 e idbrii já mencionaram). Infelizmente, selecionar o registro 0o tempo todo pode ser bastante irritante, por isso seria bom se o pusar "0por padrão. Isso pode ser alcançado colocando as seguintes linhas no seu .vimrc:

noremap p "0p
noremap P "0P
for s:i in ['"','*','+','-','.',':','%','/','=','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
    execute 'noremap "'.s:i.'p "'.s:i.'p'
    execute 'noremap "'.s:i.'P "'.s:i.'P'
endfor

A primeira linha mapeia cada pcurso para "0p. No entanto, isso impede o pacesso a outros registros. Portanto, todos os ptraços com um registro selecionado explicitamente são mapeados para a expressão de linha de comando equivalente no loop for. O mesmo é feito para P.

Dessa forma, o comportamento padrão é preservado, exceto os implícitos pe os Ptraços, que agora usam o registro 0por padrão.

Dica 1: O comando recortar é agora, e "0dnão apenas d. Mas como sou preguiçoso, isso é muito longo para mim;) Portanto, estou usando o seguinte mapeamento:

noremap <LEADER>d "0d
noremap <LEADER>D "0D

A tecla líder é \por padrão, para que você possa cortar o texto facilmente digitando \dou \D.

Dica 2: o tempo limite padrão para mapeamentos de várias chaves é bastante curto. Você pode aumentá-lo para ter mais tempo ao selecionar um registro. Veja :help timeoutlenpara detalhes, estou usando:

set timeout timeoutlen=3000 ttimeoutlen=100
Torben
fonte
7

Bem, primeiro faça este comando:

:h d

Então você perceberá que pode excluir em um registro específico. Dessa forma, você não alterará o que está no seu registro padrão.

EBGreen
fonte
1
["x]d{motion} Delete text that {motion} moves over [into register x]- Vim:h d
Wes Turner
5

Minha situação: no Normalmodo, quando excluo caracteres usando a xtecla, essas exclusões substituem meu registro mais recente - complicando as edições em que desejo excluir caracteres usando xe colando algo que tenho no meu registro mais recente (por exemplo, colando o mesmo texto em dois ou mais lugares).

Tentei a sugestão na resposta aceita ( "_d), mas não funcionou.

No entanto, das respostas / comentários aceitos em /vi/122/performing-fficient-operations-without-clearing-register , eu adicionei isso ao meu ~/.vimrc, que funciona (talvez seja necessário reiniciar o Vim ):

nnoremap x "_x

Ou seja, agora eu posso executar meus comandos yank ( y), delete ( d) e paste ( p) normais - e os caracteres que eu excluo usando xnão preenchem mais os registros mais recentes.

Victoria Stuart
fonte
4

O texto excluído, no modo de inserção, não entra no registro padrão.


fonte
2
mas excluindo qualquer quantidade significativa de texto no modo padrão é LENTO
Hamish Downer
3

As duas soluções que eu uso nos contextos certos são;

  • destaque o que você deseja substituir usando o VISUALmodo Vims e cole o registro.

Eu uso isso principalmente por hábito, pois só encontrei a segunda solução mais tarde, por exemplo

yiw   " yank the whole word
viwp  " replace any word with the default register
  • YankRing . Com este plugin, você pode usar a combinação <ctrl>+<p>de teclas para substituir o registro numerado anterior pelo que você acabou de colar.

Basicamente, você colará como faria, mas, quando perceber que substituiu o registro padrão, perdendo o que realmente queria colar, poderá <C-P> encontrar e substituir o histórico do YankRing!

Um deles deve ter plugins ...

expelledboyboy
fonte
2

Na versão do Windows (provavelmente também no Linux), você pode puxar o buffer de copiar / colar do sistema usando "*y(ou seja, preceder o seu comando puxar com aspas duplas e asterisco).

Você pode excluir as linhas substituíveis normalmente e colar o texto copiado usando "*p.

JayG
fonte
2

Costumo cometer um erro ao seguir os comandos para 'y'ank then' "_d'elete em um buraco negro e depois 'p'aste. Prefiro' y'ank, depois excluo como eu quiser e depois" "0p" de o registro 0, que é para onde o último texto copiado é enviado.

Sem noção
fonte
2

Para usuários do emacs-evil, a função (evil-paste-pop)pode ser acionada após colar, e percorre as entradas anteriores no ringue. Supondo que você o <C-p>vinculasse (padrão no Spacemacs), você pressionaria pseguido de quantos fossem <C-p>necessários.

Adrien Vakili
fonte
1

Para os usuários do Dvorak, um método muito conveniente é excluir o texto desnecessário no registro "1 em vez do" _ _ black hole register, apenas porque você pode pressionar "+ 1 com a mesma tecla Shift e um rápido movimento mindinho, já que 1 é a chave imediatamente acima "em Dvorak (PLUS d está na outra mão, o que torna todo o comando rápido como o inferno).

Então, é claro, o registro "1 pode ser usado para outras coisas por sua conveniência, mas, a menos que você tenha um propósito mais comum do que substituir o texto, eu diria que é um uso muito bom do registro.

Vic Goldfeld
fonte
1

Para aqueles que são os principais interessados ​​em não substituir o registro sem nome ao substituir um texto por seleção virtual e colar.

Você pode usar a seguinte solução que é fácil e funciona melhor para mim:

xnoremap <expr> p 'pgv"'.v:register.'y'

É das respostas (e comentários) aqui: Como colar sem substituir o registro

Após a seleção primeiro, a seleção com o novo texto é selecionada novamente (gv). Agora, o registro que foi usado pela última vez no modo visual (normalmente o registro sem nome, mas também funciona sem efeitos colaterais se você usar outro registro para colar). E, em seguida, puxe o novo valor para o registro novamente.

PS: Se você precisar de uma variante mais simples que funcione também com a simulação de vim do plugin intellj idea, você pode usar esta (desvantagem: substituir o registro sem nome, mesmo que outro registro tenha sido fornecido para colar):

vnoremap p pgvy

estalar
fonte
0

A preferência ocasional do Vim pela complexidade e não pela praticidade sobrecarrega o usuário com a aplicação de registros para copiar / excluir ações - quando, na maioria das vezes, apenas se deseja colar o que foi copiado e "esquecer" o que foi excluído.

No entanto, em vez de combater os complicados registros do vim, torne-os mais convenientes: escolha um registro "padrão" para armazenar sua exclusão mais recente. Por exemplo, envie exclusões para o registro d (deixando um AC aberto para uso ad-hoc; d é um mnemônico interessante):

nnoremap d "dd           "send latest delete to d register
nnoremap D "dD           "send latest delete to d register 
nnoremap dd "ddd         "send latest delete to d register
nnoremap x "_x           "send char deletes to black hole, not worth saving
nnoremap <leader>p "dp   "paste what was deleted
nnoremap <leader>P "dP   "paste what was deleted

Essa abordagem evita que as exclusões ocultas puxem, mas não perde o registro da exclusão - é possível colar (voltar) o que foi excluído em vez de perdê-lo em um buraco negro (como na resposta aceita). No exemplo acima, essa recuperação é feita com dois mapeamentos líderes p. Um benefício dessa abordagem é que ela permite escolher o que colar: (a) o que acabou de ser arrancado ou (b) o que acabou de ser excluído.

Gregory
fonte
0

registre de 0 a 9 são as coisas mais recentes que você puxa ou corta etc., e NÃO inclui itens excluídos etc. Portanto, se você puxa / corta algo, também está no registro 0, mesmo que você diga coisas excluídas o dia todo depois disso, registre 0 ainda é a última coisa que você arrancou / cortou.

yiw # passa para o registro padrão e registra 0

ele puxa a palavra em que o cursor está

coisas excluídas etc irão para o registro padrão, mas NÃO registram 0

no modo padrão:

"0p #puta o conteúdo do registro 0

no modo de inserção:

ctrl-r 0 #putar o conteúdo do registro 0

Eu também tive um amigo que sempre puxou / cortou para registrar x lol.

prumo
fonte