No Vim existe uma maneira de deletar sem colocar texto no cadastro?
-
09-06-2019 - |
Pergunta
Usando o Vim, muitas vezes quero substituir um bloco de código por um bloco que acabei de arrancar.
Mas quando eu excluo o bloco de código que será substituído, esse bloco vai para o registro que apaga o bloco que acabei de arrancar.Então, adquiri o hábito de arrancar, inserir e excluir o que não queria, mas com grandes blocos de código isso fica confuso ao tentar manter o bloco inserido e o bloco a ser excluído separados.
Então, qual é a maneira mais fácil e rápida de substituir texto no Vim?
- existe uma maneira de excluir texto sem colocá-lo no registro?
- existe uma maneira de dizer, por ex."substituir a próxima palavra" ou "substituir até o próximo parágrafo"
- ou é a melhor maneira de usar de alguma forma o recurso multi-registro?
Solução
Para deletar algo sem salvá-lo em um cadastro, você pode usar o “registro buraco negro”:
"_d
É claro que você também pode usar qualquer um dos outros registros que não contenham nada de seu interesse.
Outras dicas
Sim.É um pouco mais complicado do que excluir primeiro o texto "antigo", mas:
Eu começo com..
line1
line2
line3
line4
old1
old2
old3
old4
EU mudança+v selecione a linha 1, linha 2, 3 e 4 e exclua-as com o d comando
Em seguida, excluo as 1-4 linhas antigas da mesma maneira.
Então faça
"2p
Isso colará as penúltimas linhas arrancadas (linhas 1-4). "3p
fará o antepenúltimo e assim por diante.
Então eu acabo com
line1
line2
line3
line4
Referência: Documentação do Vim no registro numerado
Documentos 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.arrancamos "foo" e excluímos "bar" - o registro 0 ainda contém "foo"!Portanto, "foo" pode ser colado usando "0p
É útil ter um mapeamento fácil que permite substituir a seleção atual por buffer.
Por exemplo, quando você coloca isso no seu .vimrc
vmap r "_dP // it's a capital 'p' on the end
então, 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
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 coloco no 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 posso colar de outros aplicativos com o mínimo de complicações.Estou perdendo algumas funcionalidades, eu sei, mas simplesmente não consigo controlar mais de um registro/área de transferência.
Para o exemplo específico que você deu, se entendi 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)
Todas as operações de arrancar e excluir são gravadas no registro sem nome por padrão.No entanto, o puxão e a exclusão mais recentes são sempre armazenados (separadamente) nos registros numerados.O registro 0
detém o puxão mais recente.Os registros 1-9
mantenha as 9 exclusões mais recentes (com 1
sendo o mais recente).
Em outras palavras, uma exclusão substitui o puxão mais recente no registro sem nome, mas ainda está lá no 0
registro. O truque do registro do buraco negro ("_dd
) mencionado nas outras respostas funciona porque evita 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 extraído mais recentemente pode ser feito assim:
"0p
Esta é uma excelente referência:
Para enfatizar o que EBGreen disse:
Se você colar enquanto seleciona o texto, o texto selecionado será substituído com o texto colado.
Se você quiser copiar algum texto e colá-lo em vários locais, use "0p
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 fazer algo como resposta do dbr.Você também verá os registros /,%,#.(Veja também :help registers
)
E finalmente, confira cW
e cW
para alterar uma palavra incluindo e não incluindo um espaço à direita.(Usando capital W
inclui pontuação.)
Se você estiver usando o Vim, você 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 origem, puxar e usar o modo visual novamente para selecionar o escopo do destino e colar no texto do buffer padrão.
Exemplo:
Em um arquivo de texto com:
1| qwer 2| asdf 3| zxcv 4| poiu
com a seguinte sequência: ggVjyGVkp
você terminará com:
1| qwer 2| asdf 3| qewr 4| asdf
Explicado:
gg
:vá para a primeira linhaV
:inicie o modo visual com linhas inteirasj
:descer uma linha (com a seleção iniciada nas linhas anteriores isso aumenta a seleção uma linha abaixo)y
:puxe para o buffer padrão (as duas linhas selecionadas e você sai automaticamente do modo visual)G
:vá para a última linhaV
:iniciar o modo visual (o mesmo de antes)k
:subir uma linha (como antes, com o modo visual ativado, isso aumenta a seleção uma linha acima)p
:colar (com a seleção nas duas últimas linhas, ele substituirá essas linhas pelo que houver no buffer - as 2 primeiras linhas neste caso)
Isso tem o pequeno inconveniente de colocar o último bloco no buffer, então de alguma forma não é desejado colar repetidamente a mesma coisa, então você vai querer salvar a fonte em um buffer nomeado com algo como "ay
(para um buffer chamado "a") e cole com algo como "ap
(mas então se você estiver programando, provavelmente não vai querer colar várias vezes e sim criar uma função e chamá-la, certo? CERTO?).
Se você estiver usando apenas o vi, terá que usar marcas invisíveis em vez do modo visual, :he mark
para saber mais sobre isso, me desculpe, mas não sou muito bom com essa coisa de marcas invisíveis, estou bastante contaminado com o modo visual.
Para 'substituir palavra', tente cw
no modo normal.
Para 'substituir parágrafo', tente cap
no modo normal.
Uma solução minimamente invasiva para os preguiçosos:
Registro 0
sempre contém o último puxão (como Rafael, alex2k8 e idbrii já mencionei).Infelizmente selecionando registro 0
o tempo todo pode ser muito chato, então seria bom se p
usa "0
por padrão.Isso pode ser conseguido colocando as seguintes linhas em 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 p
acidente vascular cerebral para "0p
.No entanto, isso impede p
de acessar quaisquer outros registros.Portanto, todos p
traços com um registro explicitamente selecionado são mapeados para a expressão de linha de comando equivalente dentro do loop for.O mesmo é feito para P
.
Desta forma o comportamento padrão é preservado, exceto pelo implícito p
e P
traços, que agora usam registro 0
por padrão.
Dica 1: O comando cortar agora é "0d
em vez de 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 chave do líder é \
por padrão, para que você possa cortar texto facilmente digitando \d
ou \D
.
Dica 2: O tempo limite padrão para mapeamentos de múltiplas teclas é bastante curto.Você pode querer aumentá-lo para ter mais tempo ao selecionar um registro.Ver :help timeoutlen
para detalhes, estou usando:
set timeout timeoutlen=3000 ttimeoutlen=100
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á em seu registro padrão.
O texto excluído, enquanto estiver no modo de inserção, não entra no registro padrão.
As duas soluções que utilizo nos contextos certos são;
- destaque o que você deseja substituir usando Vims
VISUAL
modo e cole o registro.
Eu uso isso principalmente por hábito, pois só encontrei a segunda solução muito mais tarde, por exemplo
yiw " yank the whole word
viwp " replace any word with the default register
- Yank Ring.Com este plugin você pode usar o atalho de teclado
<ctrl>+<p>
para substituir o registro numerado anterior pelo que você acabou de colar.
Basicamente você cola como faria, mas quando você percebe que você sobrescreveu o registro padrão, perdendo assim o que você realmente queria colar, você pode <C-P>
para encontrar e substituir na história do YankRing!
Um deles deve ter plugins ...
Encontrei um mapeamento muito útil para o seu propósito:
xnoremap p "_dP
O texto excluído é colocado no "registro do buraco negro" e o texto arrancado permanece.
Fonte: http://vim.wikia.com/wiki/Replace_a_word_with_yanked_text
Na versão Windows (provavelmente também no Linux), você pode acessar o buffer de copiar/colar do sistema usando "*y
(ou seja,precedendo seu comando yank com aspas duplas e asterisco).
Você pode então excluir as linhas substituíveis normalmente e colar o texto copiado usando "*p
.
Muitas vezes cometo um erro ao seguir os comandos para 'arrancar e depois ''_d'elete em um buraco negro e depois 'colar'.Prefiro 'y'ank, depois excluir como quiser e depois '"0p' do registro 0, que é para onde o último texto copiado é enviado.
Minha situação:em Normal
modo, quando eu excluo caracteres usando o x
pressionamento de tecla, essas exclusões substituem meu registro mais recente - complicando as edições onde desejo excluir caracteres usando x
e cole algo que tenho em meu registro mais recente (por exemplocolando o mesmo texto em dois ou mais lugares).
Tentei a sugestão na resposta aceita ("_d
), mas não funcionou.
No entanto, a partir das respostas/comentários aceitos em https://vi.stackexchange.com/questions/122/performing-certain-operations-without-clearing-register, adicionei isso ao meu ~/.vimrc
, que funciona (talvez seja necessário reiniciar o Vim):
nnoremap x "_x
Ou seja, agora posso fazer meu puxão normal (y
), excluir (d
) e cole (p
) comandos - e caracteres que excluo usando x
não preenche mais os registros mais recentes.
Para usuários do Dvorak, um método muito conveniente é simplesmente excluir o texto desnecessário no registro "1 em vez do registro "_ buraco negro, até porque você pode pressionar " + 1 com o mesmo pressionamento de shift e um movimento rápido do dedo mindinho, já que 1 é a chave imediatamente acima de " em Dvorak (Mais d está por outro lado, o que torna todo o comando rápido como o inferno).
Então, é claro, o registro "1 poderia ser usado para outras coisas por causa de sua conveniência, mas a menos que você tenha um propósito mais comum do que substituir texto, eu diria que é um uso muito bom do registro.
Para aqueles que estão principalmente interessados em não sobrescrever o registro sem nome ao substituir um texto por meio de seleção e colagem virtual.
Você poderia 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 sobrescrever o registro
Ele passa primeiro pela seleção, depois 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 então coloque o novo valor no registro novamente.
PS:Se você precisar de uma variante mais simples que funcione também com o plugin intelj idea vim-simulation, você pode escolher esta (desvantagem:sobrescrever o registro sem nome mesmo que outro registro tenha sido fornecido para colar):
vnoremap p pgvy
Para usuários malvados do emacs, a função (evil-paste-pop)
pode ser acionado após colar e percorrer as entradas anteriores no kill-ring.Supondo que você o vinculou <C-p>
(padrão no Spacemacs), você acertaria p
seguido por tantos <C-p>
como necessário.