VIM Sostituisci la parola con il contenuto del buffer di incolla?


110

Devo fare un sacco di sostituzioni di parole in un file e voglio farlo con un comando vi, non un comando EX come :%s///g. So che questo è il modo tipico in cui si sostituisce la parola nella posizione corrente del cursore: cw<text><esc>ma c'è un modo per farlo con il contenuto del registro senza nome come testo sostitutivo e senza sovrascrivere il registro?


8
RISOLUZIONE: Per la mia necessità immediata, ho usato 12ylper strappare 12 caratteri e "_cw^r0per sostituire una parola. Sono stato quindi in grado di utilizzare il .comando per ripetere la sostituzione in tutto il file.
Plong

Risposte:


127

Penso che per "incolla" intendi il registro senza nome (yank / put / change / delete / substitute), giusto? (Poiché è quello che verrebbe sovrascritto dal comando di modifica.)

I registri sono generalmente specificati digitando "quindi il nome (singolo carattere) del registro, come "aypoi "apdare uno strattone nel registro a, poi mettere il contenuto del registro a. Lo stesso vale per un comando di modifica. In questo caso, se non si desidera che il testo si rimuove con il comando cambio per andare da nessuna parte, è possibile utilizzare il registro di buco nero "_: "_cw. Quindi, una volta in modalità di inserimento, puoi premere ctrl-R seguito dal registro che vuoi (probabilmente ") inserire nel contenuto di quel registro.

  • "* - registro di selezione (pulsante centrale incolla)
  • "+ - registro appunti (probabilmente accessibile anche con ctrl-shift-v tramite terminale)
  • "" - il registro predefinito (senza nome) di vim yank / put / change / delete / substitute register.

Risposta breve: "_cw^R"

Modifica: come altri suggeriscono, puoi ovviamente utilizzare un registro diverso per lo yank (o qualsiasi altra cosa) che ha portato il tuo testo nel registro predefinito. Non si pensa sempre a questo prima, quindi è bello eseguire un singolo comando di modifica senza soffiarlo via. Anche se non è completamente spazzato via. Ci sono i registri numerati "0attraverso "9:

Vim riempie questi registri con il testo dei comandi yank e delete.

Il registro numerato 0 contiene il testo dal comando yank più recente, a meno che il comando non abbia specificato un altro registro con ["x].

Il registro numerato 1 contiene il testo cancellato dal comando di cancellazione o modifica più recente, a meno che il comando non abbia specificato un altro registro o il testo sia inferiore a una riga (quindi viene utilizzato il registro di cancellazione piccolo). Si fa eccezione per l'operatore delete con questi comandi di movimento: %, (, ), `, /, ?, n, N, {e }. Viene sempre utilizzato il registro "1 (questo è compatibile con Vi). Anche il registro" - viene utilizzato se l'eliminazione è all'interno di una riga.

Ad ogni successiva cancellazione o modifica, Vim sposta il contenuto precedente del registro 1 nel registro 2, 2 in 3, e così via, perdendo il contenuto precedente del registro 9.


1
Va bene, pensi di aver già copiato abbastanza documenti sui registri nella mia risposta? È tutto lì sotto :help registers.
Cascabel

48

Usando le informazioni in questo post, ho creato questa utile mappatura. Ho scelto "cp" perché significa "cambia incolla"

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

MODIFICARE:

Inoltre ho fatto un ulteriore passo avanti e ho supportato qualsiasi movimento.

Per ottenere l'equivalente del comando sopra sarebbe cpwper "cambia parola incolla"

"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

Il <silenzioso> fa sì che non funzioni per me ... qualche idea del perché dovrebbe essere? Sono un n00b in mappature e funzioni.
Hollister

L'unico problema con questo è che non puoi scegliere un registro con cui incollare ... ma in quel caso suppongo che potresti semplicemente cw e usare CTRL + R
Steve Vermeulen

2
Potrebbe esserci un modo migliore per aggiungere nomi di registro, ma per me funziona: 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 funziona bene per sostituire le linee, come posso farlo funzionare per le parole invece che per le linee, sto ancora imparando vim. Grazie per l'aiuto.
Xavitoj Cheema

@XavitojCheema Non ricordo nemmeno di aver fatto quel commento, haha. Ma a quanto pare, da allora ho scritto un plugin per fornire questa funzionalità ( github.com/svermeulen/vim-easyclip )
Steve Vermeulen

27

Puoi usare la modalità visiva di vim per questo. es. copia una parola: yee poi sovrascrivi un'altra con la parola copiata:vep


9
Funziona, ma va anche notato che la pasta visiva sovrascrive il buffer di strappo per il testo appena eliminato.
ostler.c

24

Se il cursore si trova sulla parola che desideri sostituire con il contenuto del registro senza nome, puoi utilizzare viwp. vpassa alla modalità visuale, iwseleziona la parola interna e pinserisce il contenuto del registro al suo posto.

In pratica, quando devo sostituire una parola (nome della funzione, ecc.) Con un'altra, passo a quella da usare come sostituto, yiwper trascinare la parola interna nel registro senza nome, quindi passare alla parola I ' m sostituendolo, e viwpper sostituirlo. Un modo abbastanza rapido per sostituire una parola con un'altra. Se hai cercato ( /) la parola che stai sostituendo per arrivarci, puoi semplicemente premere nper arrivare all'occorrenza successiva che devi sostituire. Ovviamente non può sostituire l'uso :%s/find/replace/g, ma per un paio di sostituzioni rapide può essere utile, soprattutto se hai già la nuova parola in un registro.


4
Sono sorpreso che questa non sia la soluzione accettata: tutto quanto sopra, sebbene più flessibile in alcuni casi limite, è molto più prolisso per semplicemente 'scambiare l'attuale registro senza nome con una selezione da qualche parte', che è la situazione dell'originale asker è venuto qui per.
ELLIOTTCABLE

1
Questo è molto utile e intuitivo.
lacostenycoder

6

Se usi un registro con nome (es. Usa "ayo "ad, ecc. Per riempire il registro incolla), puoi fare qualcosa come

cw<CTRL-R>a<esc>

Che sostituirà la parola con il contenuto del registro a. Per quanto ne so, non puoi usare il registro predefinito perché quando verrai cwriempito con la parola che è stata tagliata da quel comando.


Puoi usare il registro predefinito! Controlla la mia risposta.
Cascabel

2

Intendi il buffer di pasta di sistema o il registro vi?

Se vuoi usare il buffer di incolla di sistema, allora stai bene e potresti farlo dw"+P- "sceglie un registro, ed "+è il buffer di incolla di sistema.

Altrimenti copia nel registro non predefinito dicendo "aydi copiare nel registro ae poi per sostituire qualcosa faidw"aP


Grazie, Hamish. L'ho provato, ma dwelimina gli spazi vuoti finali dopo quella che considererei la "parola", mentre cwcambia solo la parola. Per questo motivo, dwnon funzionerà per me.
Plong

In tal caso dedovrebbe funzionare per te: verrà eliminata fino alla fine di questa parola, mentre dwverrà eliminata all'inizio della parola successiva.
Hamish Downer

1

È possibile utilizzare ywper estrarre la parola, quindi è possibile modificare la parola con la parola strappata di vipwper estrarre la parola e incollare la parola precedentemente strappata.


0

Puoi usare i registri per questo:

primo posto testo sostitutivo nel registro <mark some text>"ay

dov'è il anome del registro

quindi puoi usare quel registro in sostituzione

ve"ap


Sfortunatamente, non potevo semplicemente ripetere l'ultima operazione di incolla tramite ., che è un'altra cosa che volevo fare. Grazie comunque. Molto apprezzato.
Plong

0

Oppure puoi fare Shift+ v- p(seleziona l'intera riga e incolla al suo posto)


1
o pdw ... Non ami vim? : P
elimirks
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.