VIM Substituir palavra pelo conteúdo do buffer de colagem?

110

Eu preciso fazer várias substituições de palavras em um arquivo e quero fazê-lo com um comando vi, não um comando EX como :%s///g. Eu sei que esta é a maneira típica de substituir a palavra na posição atual do cursor: cw<text><esc>mas existe uma maneira de fazer isso com o conteúdo do registro não nomeado como o texto de substituição e sem sobrescrever o registro?

plong
fonte
8
RESOLUÇÃO: Para minha necessidade imediata, costumava 12ylarrancar 12 caracteres e "_cw^r0substituir uma palavra. Consegui então usar o .comando para repetir a substituição em todo o arquivo.
plong

Respostas:

127

Estou pensando que por "colar" você quer dizer o registro sem nome (arrancar / colocar / alterar / excluir / substituir), certo? (Uma vez que é o que seria substituído pelo comando de alteração.)

Registros são geralmente especificado digitando "então o nome (um único caractere) do registo, como "ay, em seguida, "appara arrancar em registo a, em seguida, colocar o conteúdo do registrador a. O mesmo vale para um comando de mudança. Neste caso, se você não quer que o texto que você remova com o comando de mudança de ir a qualquer lugar, você pode usar o registo buraco negro "_: "_cw. Então, uma vez no modo de inserção, você pode pressionar ctrl-R seguido pelo registro que você deseja (provavelmente ") colocar no conteúdo desse registro.

  • "* - registro de seleção (colar do botão do meio)
  • "+ - registro da área de transferência (provavelmente também acessível com ctrl-shift-v através do terminal)
  • "" - o registro de arrancar / colocar / alterar / excluir / substituir padrão (sem nome) do vim.

Resposta curta: "_cw^R"

Editar: como outros estão sugerindo, você pode usar um registro diferente para o yank (ou qualquer outro) que colocou seu texto no registro padrão. No entanto, nem sempre você pensa nisso primeiro, então é bom fazer um único comando de mudança sem ignorá-lo. Embora não seja totalmente estourado. Existem os registros numerados "0por meio de "9:

O Vim preenche esses registros com texto dos comandos arrancar e excluir.

O registro numerado 0 contém o texto do comando de arrancar mais recente, a menos que o comando tenha especificado outro registro com ["x].

O registro numerado 1 contém o texto excluído pelo comando de exclusão ou alteração mais recente, a menos que o comando especifique outro registro ou o texto seja menor que uma linha (o pequeno registro de exclusão é usado então). Uma exceção é feita para o operador de exclusão com estes comandos de movimento: %, (, ), `, /, ?, n, N, {e }. O registrador "1 é sempre usado então (este é compatível com Vi). O" - registrador é usado também se a exclusão estiver dentro de uma linha.

Com cada exclusão ou alteração sucessiva, o Vim muda o conteúdo anterior do registro 1 para o registro 2, 2 para 3 e assim por diante, perdendo o conteúdo anterior do registro 9.

Cascabel
fonte
1
Certo, acho que já copiei o suficiente dos documentos nos registros para minha resposta? Está tudo lá embaixo :help registers.
Cascabel
48

Usando as informações desta postagem, formulei esse mapeamento útil. Escolhi 'cp' porque significa "alterar colar"

nmap <silent> cp "_cw<C-R>"<Esc>

EDITAR:

Também dei um passo adiante e apoiei qualquer movimento.

Para obter o equivalente ao comando acima, seria cpwpara "alterar colar palavra"

"This allows for change paste motion cp{motion}
nmap <silent> cp :set opfunc=ChangePaste<CR>g@
function! ChangePaste(type, ...)
    silent exe "normal! `[v`]\"_c"
    silent exe "normal! p"
endfunction
ostler.c
fonte
O <silent> faz com que não funcione para mim ... alguma ideia de por que isso seria? Sou um n00b em mapeamentos e funções.
Hollister
O único problema com isso é que você não pode escolher um registro para colar ... mas, nesse caso, suponho que você poderia simplesmente cw e usar CTRL + R
Steve Vermeulen
2
Pode haver uma maneira melhor de adicionar nomes de registro, mas o seguinte funciona para mim: nmap <silent> cp :let g:currentRegister=v:register<cr>:set opfunc=ChangePaste<CR>g@ function! ChangePaste(type, ...) silent exe "normal! `[v`]\"_c".getreg(g:currentRegister) endfunction
Steve Vermeulen
@eventualEntropy isso funciona bem para substituir linhas, como posso fazer isso funcionar para palavras em vez de linhas, ainda estou aprendendo vim. Obrigado pela ajuda.
Xavitoj Cheema
@XavitojCheema Eu nem me lembro de ter feito esse comentário, haha. Mas, na verdade, escrevi um plugin para fornecer essa funcionalidade ( github.com/svermeulen/vim-easyclip )
Steve Vermeulen
27

Você pode usar o modo visual do vim para isso. por exemplo, copie uma palavra: yee então sobrescreva outra com a palavra copiada:vep

Ste
fonte
9
Isso funciona, mas também deve ser observado que a colagem visual sobrescreve o buffer de arrancamento do texto recém-excluído.
ostler.c
24

Se o cursor estiver sobre a palavra que deseja substituir pelo conteúdo do registro sem nome, você pode usar viwp. vmuda para o modo visual, iwseleciona a palavra interna e pcoloca o conteúdo do registro em seu lugar.

Na prática, quando preciso substituir uma palavra (nome da função, etc.) por outra, passarei para aquela para usar como uma substituição, yiwpara puxar a palavra interna para o registro sem nome e, em seguida, mover para a palavra I ' m substituindo, e viwppara substituí-lo. Maneira muito rápida de substituir uma palavra por outra. Se você pesquisou ( /) pela palavra que está substituindo para chegar a ela, pode simplesmente clicar em npara ir para a próxima ocorrência que precisa ser substituída. Obviamente, não substitui o uso :%s/find/replace/g, mas para algumas substituições rápidas pode ser útil, especialmente se você já tiver a nova palavra em um registro.

Travis Northcutt
fonte
4
Estou surpreso que esta não seja a solução aceita: todos os itens acima, embora mais flexíveis em alguns casos extremos, são muito mais prolixos para simplesmente 'trocar o registro não nomeado atual por uma seleção em algum lugar', que é a situação do original solicitante veio aqui para.
ELLIOTTCABLE
1
Isso é muito útil e intuitivo.
lacostenycoder
6

Se você fizer uso de um registro nomeado (ou seja, use "ayou "ad, etc., para preencher o registro de colagem), você pode fazer algo como

cw<CTRL-R>a<esc>

Que substituirá a palavra pelo conteúdo do registro a. Pelo que eu posso dizer, você não pode usar o registrador padrão porque quando você cwfor preenchido com a palavra que foi cortada por aquele comando.

Daniel Vandersluis
fonte
Você pode usar o registro padrão! Confira minha resposta.
Cascabel
2

Você quer dizer o buffer de pasta do sistema ou o registro vi?

Se você quiser usar o buffer de colagem do sistema, tudo bem e pode dw"+P- "escolhe um registro e "+é o buffer de colagem do sistema.

Caso contrário, copie para o registro não padrão com a palavra "aypara copiar para o registro ae, em seguida, para substituir algo, façadw"aP

Hamish Downer
fonte
Obrigado, Hamish. Eu tentei fazer isso, mas dwexclui o espaço em branco depois do que eu consideraria a "palavra", enquanto cwapenas altera a palavra. Por esse motivo, dwnão vai funcionar para mim.
plong
Nesse caso, dedeve funcionar para você - excluirá no final desta palavra, enquanto dwexcluirá no início da próxima palavra.
Hamish Downer,
1

Você pode usar ywpara puxar a palavra e, em seguida, alterar a palavra com palavra puxada por vipwpara palavra puxada e colar a palavra previamente puxada.

YevgenyYork
fonte
0

Você pode usar registros para isso:

texto de substituição de primeiro lugar no registro <mark some text>"ay

onde aestá o nome de registro

então você pode usar esse registro em substituição

ve"ap

lollinus
fonte
Infelizmente, não pude simplesmente repetir a última operação de colar via ., que é outra coisa que eu queria fazer. Obrigado, entretanto. Muito apreciado.
plong de
0

Ou você pode fazer Shift+ v- p(selecionar a linha inteira e colar em seu 'lugar)

Elimirks
fonte
1
ou pdw ... Você não ama o vim? : P
elimirks