In Vim c'è un modo per eliminare senza mettere il testo nel registro?


470

Usando Vim spesso voglio sostituire un blocco di codice con un blocco che ho appena strappato.

Ma quando cancello il blocco di codice che deve essere sostituito, quel blocco stesso va nel registro che cancella il blocco che ho appena strappato. Quindi ho l'abitudine di strappare, quindi inserire, quindi eliminare ciò che non volevo, ma con grandi blocchi di codice questo diventa disordinato nel tentativo di mantenere separati il ​​blocco inserito e il blocco.

Qual è il modo più semplice e veloce per sostituire il testo in Vim?

  • c'è un modo per eliminare il testo senza inserirlo nel registro?
  • c'è un modo per dire, ad esempio "sostituisci la parola successiva" o "sostituisci al paragrafo successivo"
  • o è il modo migliore per utilizzare in qualche modo la funzione di registrazione multipla?

1
vim-easyclip ( github.com/svermeulen/vim-easyclip ) è progettato per risolvere questo problema esatto
Steve Vermeulen,

1
Ho fatto una domanda, inconsapevolmente (all'epoca) duplicata del tuo vero problema , ma non tanto della domanda sul titolo. TL; DR: sostituisci con ciò che hai strappato usando viwp(per word).
OJFord,

Risposte:


429

Per eliminare qualcosa senza salvarlo in un registro, è possibile utilizzare il "registro buco nero":

"_d

Ovviamente potresti anche usare uno degli altri registri che non contengono nulla di tuo interesse.


4
All'inizio ho pensato che questo comando non funzionasse correttamente. Poi mi sono reso conto che stavo usando una versione "dead keys" della tastiera americana. Con questo layout di tastiera devo digitare "<space>_d. Lo spazio è necessario per digitare effettivamente ".
Sebastián Grignoli

4
Qualche idea su come farlo in modo selettivo solo su righe vuote? (Se io ddsu una linea vuota va nel buco nero, altrimenti è ddnormale).
Jonathan Dumaine,

6
Per rimuovere un personaggio, prova:"_x
kenorb,

54
Questa è un'area in cui vince un editor di testo standard. Basta premere il tasto Canc.
Vince Panuccio,

22
Puoi anche strappare qualcosa con yyo "3yy" (o qualsiasi altra cosa), che lo inserisce nel registro senza nome, ma anche in 0. Puoi quindi continuare a incollarlo con "0p, nonostante abbia usato ddopo.
Halfgaar,

102

Sì. È leggermente più contorto che eliminare prima il "vecchio" testo, ma:

Comincio con ..

line1
line2
line3
line4

old1
old2
old3
old4

I shift+ vseleziona la riga 1, la riga 2, 3 e 4, e li elimino con il dcomando

Quindi cancello le vecchie 1-4 righe allo stesso modo.

Quindi fa

"2p

In questo modo verranno incollate le penultimo righe strappate (riga 1-4). "3pfarà il terzo dall'ultimo, e così via ..

Quindi finisco con

line1
line2
line3
line4

Riferimento: documentazione Vim su registro numerato


Se selezioni le righe con <Maiusc-v> le elimini con solo d, non dd
Heikki Naski

31
1 a 9 funziona per le eliminazioni. Per incollare l'ultima cosa veramente strappata (con 'y') devi usare "0p. È utile nei casi in cui prima strattoni qualcosa con l'intenzione di sostituire qualcos'altro, ma poi qualcos'altro sovrascrive il registro incolla predefinito.
Rafael de F. Ferreira,

Per una maggiore sofisticazione, controlla lo script Gundo (annullamento grafico) .
Lumi,

@ RafaeldeF.Ferreira: il tuo commento non è una risposta a questa domanda, ma in realtà risolve probabilmente il problema reale che ha portato l'OP a porre la domanda in primo luogo. Per me, quello era il vero problema.
0xc0de,

76

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

Ad esempio, strappiamo "pippo" ed eliminiamo "bar" - il registro 0 contiene ancora "pippo"! Quindi "foo" può essere incollato usando"0p


53

È utile disporre di una mappatura semplice che consente di sostituire la selezione corrente con buffer.

Ad esempio quando lo metti nel tuo .vimrc

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

quindi, dopo aver copiato qualcosa nel registro (cioè con 'y'), puoi semplicemente selezionare il testo che vuoi sostituire e semplicemente premere 'r' sulla tastiera. La selezione verrà sostituita con il tuo attuale registro.

Spiegazione:

vmap - mapping for visual mode
"_d - delete current selection into "black hole register"
P - paste

1
Per una versione più avanzata, verificare: stackoverflow.com/questions/290465/...
Luc Hermitte

Mi piacerebbe usarevmap <C-P> "_dP
Harry Lee il

7
Puoi semplicemente inserire il testo senza eliminare la selezione. Ad esempio, Vpsostituisce immediatamente la linea corrente con quella strappata.
Bobby Marinoff,

Questa soluzione non risolve il problema dche viene spesso utilizzato per l'eliminazione.
Victor Yarema,

35

Ho inserito quanto segue nel mio 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

Ora scrivo e inserisco il registro degli appunti e non devo preoccuparmi di cosa succede con il registro predefinito. Un ulteriore vantaggio è che posso incollare da altre app con una seccatura minima. Sto perdendo alcune funzionalità, lo so, ma non riesco comunque a tenere traccia di più di un registro / appunti.


6
Invece di tutti quei rimappaggi, puoi anche set clipboard=unnamedo set clipboard=unnamedplus, che cambia gli appunti predefiniti in *o +, rispettivamente.
Steve,

5
@Steve Se lo fai, allora d sovrascriverà anche l'ultimo yank nel registro degli appunti, che è ciò che la domanda sta cercando di evitare.
79E09796,

1
@ 79E09796, non intendevo insinuare che lo avrebbe fatto; Stavo commentando questa risposta e non la domanda originale.
Steve

1
Ho messo questi nel mio .vimrc e ora lo strappo non funziona. Qualche idea sul perché?
martedì

2
@tba sostituisce noremap con nnoremap (due n) e dovrebbe funzionare correttamente.
Meáin

24

Per l'esempio specifico che hai fornito, se capisco la domanda, potrebbe funzionare:

*Highlight what you want to put somewhere else
*delete (d)
*Highlight the code that you want it to replace
*paste (p)

6
Funziona bene tranne quando si desidera incollare più selezioni.

23

Tutte le operazioni di strappo ed eliminazione scrivono nel registro senza nome per impostazione predefinita. Tuttavia, lo yank più recente e l'eliminazione più recente vengono sempre memorizzati (separatamente) nei registri numerati. Il registro 0contiene lo yank più recente. I registri 1-9contengono le 9 eliminazioni più recenti (con 1la più recente).

In altre parole, un'eliminazione sovrascrive lo yank più recente nel registro senza nome, ma è ancora presente nel 0registro. Il trucco blackhole-register ( "_dd) menzionato nelle altre risposte funziona perché impedisce di sovrascrivere il registro senza nome, ma non è necessario.

Fai riferimento a un registro usando le doppie virgolette, quindi puoi incollare il testo strappato più di recente in questo modo:

"0p

Questo è un riferimento eccellente:


16

Per sottolineare ciò che ha detto EBGreen :

Se si incolla durante la selezione del testo, il testo selezionato viene sostituito con il testo incollato.

Se vuoi copiare del testo e incollarlo in più posizioni, usa "0pper incollare. Il registro numerato 0 contiene il testo del comando yank più recente.


Inoltre, puoi elencare i contenuti di tutti i tuoi registri:

:registers

Questo comando rende più facile capire quale registro vuoi quando fai qualcosa come la risposta di dbr . Vedrai anche i registri /,%, #. (Vedi anche :help registers)


E infine, controlla cWe cWper cambiare una parola includendo e non includendo uno spazio finale. (L'uso del capitale Winclude la punteggiatura.)


10

Se stai usando Vim, avrai la modalità visiva, che è come selezionare, ma con la modalità di separazione che è la base di vi / vim.

Quello che vuoi fare è usare la modalità visiva per selezionare l'origine, quindi yank, quindi utilizzare di nuovo la modalità visiva per selezionare l'ambito della destinazione, quindi incollare nel testo dal buffer predefinito.

Esempio:

In un file di testo con:

1 | qwer
2 | asdf
3 | zxcv
4 | poiu

con la seguente sequenza: ggVjyGVkpfinirai con:

1 | qwer
2 | asdf
3 | qewr
4 | asdf

Ha spiegato:

  • gg: vai alla prima riga
  • V: avvia la modalità visiva con linee intere
  • j: scendi di una riga (con la selezione avviata sulle righe precedenti, la selezione aumenta di una riga in basso)
  • y: yank al buffer predefinito (le due linee selezionate, e ti esce automaticamente dalla modalità visiva)
  • G: vai all'ultima riga
  • V: avvia la modalità visiva (come prima)
  • k: passa di una riga (come in precedenza, con la modalità visiva abilitata, la selezione aumenta di una riga)
  • p: incolla (con la selezione sulle ultime due righe, sostituirà quelle righe con qualsiasi cosa ci sia nel buffer - le 2 prime righe in questo caso)

Questo ha il piccolo inconveniente che mette l'ultimo blocco sul buffer, quindi in qualche modo non è desiderato per gli incollaggi ripetuti della stessa cosa, quindi ti consigliamo di salvare l'origine in un buffer con un nome simile a "ay(in un buffer chiamato "a ") e incollalo con qualcosa del genere "ap(ma se stai programmando, probabilmente non vuoi incollare più volte ma creare una funzione e chiamarla, giusto? DESTRA ?).

Se stai usando solo vi, allora dovrai usare segni invisibili invece della modalità visiva, :he markper di più su questo, mi dispiace ma non sono molto bravo con questa cosa dei segni invisibili, sono piuttosto contaminato con la modalità visiva.



9

Una soluzione minimamente invasiva per i più pigri:

Register 0contiene sempre l'ultimo yank (come già menzionato Rafael , alex2k8 e idbrii ). Sfortunatamente, selezionare il registro in 0qualsiasi momento può essere piuttosto fastidioso, quindi sarebbe bello se lo putilizzi "0per impostazione predefinita. Ciò può essere ottenuto inserendo le seguenti righe nel tuo .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

La prima riga mappa ogni ptratto su "0p. Tuttavia, ciò impedisce l' paccesso a qualsiasi altro registro. Pertanto, tutti i ptratti con un registro selezionato in modo esplicito vengono associati all'espressione della riga di comando equivalente all'interno del for-loop. Lo stesso è fatto per P.

In questo modo viene preservato il comportamento standard, ad eccezione dell'implicito pe dei Ptratti, che ora utilizzano il registro0 per impostazione predefinita.

Suggerimento 1: il comando di taglio è ora "0danziché solo d. Ma dato che sono pigro, questo è troppo lungo per me;) Quindi sto usando il seguente mapping:

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

La chiave principale è \di default, quindi puoi tagliare facilmente il testo digitando \do \D.

Suggerimento 2: il timeout predefinito per i mapping multi-chiave è piuttosto breve. Potresti volerlo aumentare per avere più tempo quando selezioni un registro. Vedi :help timeoutlenper i dettagli, sto usando:

set timeout timeoutlen=3000 ttimeoutlen=100

7

Bene, prima esegui questo comando:

:h d

Quindi ti renderai conto che puoi eliminare in un registro specifico. In questo modo non modificherai ciò che è nel tuo registro predefinito.


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

5

La mia situazione: in Normalmodalità, quando elimino i caratteri usando il xtasto premuto, quelle eliminazioni sovrascrivono il mio ultimo registro - complicando le modifiche in cui desidero eliminare i caratteri usando xe incollando qualcosa che ho nel mio registro più recente (ad esempio incollando lo stesso testo in due o più posti).

Ho provato il suggerimento nella risposta accettata ( "_d), ma non ha funzionato.

Tuttavia, dalla risposta / commenti accettati su /vi/122/performing-certain-operations-without-clearing-register , ho aggiunto questo al mio ~/.vimrc, che funziona (potrebbe essere necessario riavviare Vim ):

nnoremap x "_x

Cioè, ora posso eseguire i miei normali comandi yank ( y), delete ( d) e paste ( p) - e i caratteri che elimino usando xnon popolano più i registri più recenti.


4

Il testo eliminato, mentre è in modalità inserimento, non va nel registro predefinito.


2
ma l'eliminazione di qualsiasi quantità significativa di testo in modalità predefinita è LENTO
Hamish Downer,

3

Le due soluzioni che utilizzo nei contesti giusti sono;

  • evidenziare ciò che si desidera sostituire utilizzando la VISUALmodalità Vims , quindi incollare il registro.

Lo uso principalmente per abitudine poiché ho trovato la seconda soluzione molto più tardi, ad es

yiw   " yank the whole word
viwp  " replace any word with the default register
  • YankRing . Con questo plugin puoi usare il keybinding <ctrl>+<p>per sostituire il registro numerato precedente con quello appena incollato.

Fondamentalmente si procede per incollare come si farebbe, ma quando ti rendi conto che da allora hai sovrascritto il registro predefinito perdendo così ciò che volevi effettivamente incollare puoi <C-P>trovare e sostituire dalla storia di YankRing!

Uno di questi deve avere plugin ...



2

Nella versione di Windows (probabilmente anche in Linux), è possibile eseguire lo yanking nel buffer di copia / incolla del sistema utilizzando "*y(ovvero precedendo il comando yank con virgolette doppie e asterisco).

È quindi possibile eliminare normalmente le righe sostituibili e incollare il testo copiato utilizzando "*p.


2

Faccio spesso un errore quando seguo i comandi di 'y'ank quindi' "_d'elete in un buco nero quindi 'p'aste. Preferisco' y'ank, quindi elimina come preferisco, quindi '" 0p "da il registro 0, dove viene inviato l'ultimo testo copiato.


2

Per gli utenti di emacs-evil, la funzione (evil-paste-pop)può essere attivata dopo aver incollato e scorrere ciclicamente le voci precedenti nel kill-ring. Supponendo che lo vincolassi <C-p>(impostazione predefinita in Spacemacs), colpiresti pseguito da quanti ne hai <C-p>bisogno.


1

Per gli utenti di Dvorak, un metodo molto conveniente è quello di eliminare il testo non necessario nel "1 registro invece del" _ registro buco nero, se non altro perché è possibile premere "+ 1 con lo stesso tasto Maiusc e un rapido mignolo poiché 1 è la chiave immediatamente sopra "in Dvorak (PLUS d è invece, il che rende l'intero comando veloce come l'inferno).

Quindi, naturalmente, il "1 registro potrebbe essere usato per altre cose per la sua praticità, ma a meno che tu non abbia uno scopo più comune della sostituzione del testo, direi che è un buon uso del registro.


1

Per quelli di voi che sono principalmente interessati a non sovrascrivere il registro senza nome quando si sostituisce un testo tramite selezione virtuale e incolla.

È possibile utilizzare la seguente soluzione che è facile e funziona meglio per me:

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

Viene dalle risposte (e dai commenti) qui: Come incollare senza sovrascrivere il registro

Passa prima la selezione, quindi la selezione con il nuovo testo viene nuovamente selezionata (gv). Ora il registro che è stato utilizzato l'ultima volta in modalità visiva (normalmente il registro senza nome ma funziona anche senza effetti collaterali se si utilizza un altro registro per incollare). E quindi trascinare nuovamente il nuovo valore nel registro.

PS: Se hai bisogno di una variante più semplice che funzioni anche con la simulazione vim-plug-in di intellj idea puoi prendere questa (svantaggio: sovrascrivi un registro senza nome anche se è stato dato un altro registro per incollare):

vnoremap p pgvy



0

L'occasionale preferenza di Vim per la complessità rispetto alla praticità grava sull'applicazione dei registri per copiare / cancellare azioni - quando più spesso si vuole semplicemente incollare ciò che è stato copiato e "dimenticare" ciò che è stato eliminato.

Tuttavia, invece di combattere i complicati registri di Vim, rendili più comodi: scegli un registro "predefinito" per memorizzare l'ultima cancellazione. Ad esempio, invia le cancellazioni al registro d (lasciando ac aperto per l'uso ad-hoc; d è un bel mnemonico):

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

Questo approccio evita che le cancellazioni possano ostruire gli yanks MA non perde la registrazione dell'eliminazione: si può incollare (indietro) ciò che è stato eliminato invece di perderlo in un buco nero (come nella risposta accettata). Nell'esempio sopra, questo richiamo viene eseguito con due mappature p leader. Un vantaggio di questo approccio è che ti dà la possibilità di scegliere cosa incollare: (a) cosa è stato appena strappato, o (b) cosa è stato appena eliminato.


0

il registro da 0 a 9 sono le ultime cose che strappate o tagliate ecc., e NON includete cose cancellate ecc. Quindi se strappate / tagliate qualcosa, è anche nel registro 0, anche se dite cose cancellate tutto il giorno successivo, registrate 0 è ancora l'ultima cosa che hai strappato / tagliato.

yiw # passa al registro predefinito e al registro 0

strappa la parola in cui si trova il cursore

cose cancellate ecc andranno al registro predefinito, ma NON registrano 0

in modalità standard:

"0p #put il contenuto del registro 0

in modalità inserimento:

ctrl-r 0 # immette il contenuto del registro 0

Ho anche avuto un amico che ha sempre tirato / tagliato per registrare x lol.

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.