Vim: Sostituire una linea con un'altra strappata prima


112

Almeno una volta al giorno ho la seguente situazione:

A: This line should also replace line X
...
X: This is line should be replaced

Credo di non svolgere questo compito in modo efficiente.

Quello che faccio:

  • Vai alla riga A: AG
  • Yank line A: yy
  • Vai alla riga X: XG
  • Incolla la riga A: P
  • Vai alla vecchia riga: j
  • Elimina la vecchia riga: dd

Questo ha l'ulteriore svantaggio che la linea X è ora nel registro di default, che è fastidioso se trovo un'altra linea che dovrebbe essere sostituito con A. Yanking da e incollare da un registro supplementare ( "ayy , " AP ) rende questo semplice compito ancora meno efficiente.

Le mie domande:

  • Mi sono perso un comando Vim integrato per sostituire una riga strappata prima?
  • In caso contrario, come posso associare il mio comando che lascia (o ripristina) la linea strappata nel registro predefinito?

2
Questo è il mio problema più grande con il modello di editing di Vim. Mi piacerebbe conoscere una soluzione. Un editor CUA distingue tra taglia ed elimina, quindi devi solo tagliare del testo, quindi puoi andare a eliminare e incollare tutto ciò che desideri. Con Vim, qualsiasi eliminazione apportata trasporta il testo tagliato. Finisci per usare molte più sequenze di tasti di quanto faresti con un altro editor.
Fango


@Mud impara a conoscere :movee il registro del buco nero ( _) (o in effetti, registra solo)
sehe

2
@sehe sono perfettamente a conoscenza dei registri, ma questo aggiunge 4 sequenze di tasti per operazione taglia / incolla e richiede più accortezza. Quando esegui molte modifiche, ciò si somma rapidamente.
Mud

Oltre a salvare pochi byte di memoria, c'è un vantaggio nell'usare il registro del buco nero rispetto a qualsiasi altro registro? Direi che qualsiasi registro può essere un registro di buco nero se non lo rileggi.
sleblanc

Risposte:


91

Cosa farei:

  1. aG
  2. Y
  3. xG
  4. Vp

Non è necessario per uscire dalla modalità normale, ma non strattone la linea. Puoi comunque usare V"0pche metterà sempre la linea strappata al punto 2.


11
@duddle: sì, Yè sinonimo diyy
icecrime

8
I passaggi 1 e 2 possono essere combinati usando: ay [Es: 20y] seguito da Vp dovrebbe fare il trucco. Non devi andare su una linea per strapparlo.
Bharad

2
Se sovrascrivi righe aggiuntive con ccCTRL + r0ESC invece di V "0p, tutte le righe seguenti possono essere sostituite con solo. (Il ripetitore)
Jordan Morris

Yè un sinonimo di yy, ma suggerisco di rimapparlo in modo che y$corrisponda a De C.
mgold

Controlla la risposta di Jordan Morris stackoverflow.com/users/970673/jordan-morris di seguito: utilizza davvero i comandi vim al massimo consentendoti di ripetere il comando più volte.
JESii

105

Vp: seleziona la riga, incolla ciò che è stato strappato


3
VPfunziona altrettanto bene, il che è utile perché puoi tenere premuto Shift per l'intera sequenza.
George Hilliard

24
trucco molto carino, anche se vale la pena notare un (forse) avvertimento significativo: questo fa sì che il registro di yank venga aggiornato con il contenuto della riga che viene sovrascritta, quindi potrebbe non funzionare bene con alcune attività, ad esempio se si desidera sovrascrivere la stessa linea su più destinazioni.
underscore_d

8
@underscore_d, suona bene se lo fai V"0p, che incolla dall'ultimo registro strappato.
timblaktu

@timblaktu Puoi spiegare cosa V"0pfa? V entra in modalità linea linea visiva ep è per incollare. A cosa servono "e 0? Grazie
programmatore

43

Questo ha lo svantaggio aggiuntivo che la riga X è ora nel registro predefinito, il che è fastidioso se trovo un'altra riga che dovrebbe essere sostituita con A.

Per eliminare il testo senza influire sui normali registri, è possibile utilizzare il registro Black hole "_:

"_dd

10
Ho aggiunto alcune mappature al mio .vimrc per creare de ddutilizzare sempre il buco nero xed xxeseguire quello che la maggior parte degli editor chiamerebbe un "taglio" (elimina e salva nel registro predefinito):noremap x d noremap xx dd noremap d "_d noremap dd "_dd
IMSoP

2
Sono cauto nel rimappare le cose in VIM, perché potrebbe non essere facile su altri computer o nei plugin in stile VIM per IDE. Anche i progettisti di VIM tendono ad aver risolto problemi con le mappature predefinite se si scava davvero.
Jordan Morris

15

Basandosi sulle risposte che suggeriscono di utilizzare Vpo VPdi incollare su una riga, per evitare di modificare il contenuto del registro di yank, trovo che il comando più ergonomico sia semplicemente:

VPY


Questa è la soluzione più semplice che lascia lo stesso contenuto di yank. Grazie molto!
heylookltsme

14
  1. aa
  2. j (spostarsi sulla riga che si desidera sostituire), quindi
  3. Vp (maiuscolo v e poi p, verrà sostituito con il contenuto estratto)

eccezionale! Davvero molto breve e rende facile selezionare più righe con modalità visiva. Inoltre mantiene intatto il tampone di pasta. È fastidioso quando dd sovrascrive quel buffer ...
Aktau

@ Aktau questo non lascia intatto il buffer.
Jordan Morris

9

Vorrei utilizzare la modalità a riga di comando (Ex) e fare i seguenti due comandi

:XmA
:Ad

Questo sposta semplicemente la linea X appena sotto A, quindi l'eliminazione di A sposta quella linea verso l'alto

Per esempio

:7m3
:3d

Puoi fare un esempio? Quando premo, ad esempio, 50Gm30G Vim va alla riga 50 e poi in fondo e il gioco è fatto. Inoltre: l'annuncio non fa nulla per A = 50 o A = 50G
croccante

7
  1. Spostati all'inizio della prima riga.

  2. y, $- copia la riga senza l'interruzione di riga alla fine

  3. Spostarsi all'inizio della linea di destinazione.

    1. V, p- sostituire solo una linea di destinazione

    2. c, c, Ctrlr, 0, Esc- sostituire la linea di destinazione con lo strattone originale

  4. Spostarsi all'inizio della successiva linea di destinazione.

  5. . - ripete il comando impartito al 4.2.

Appunti:

  • 4.1 è y, $perché se lo fai y, yo Ysi copia il linebreak, e Ctrlr0in realtà aggiunge l'interruzione di riga sotto la linea di destinazione.

  • 4.2 sostituisce V p, che non funziona con la ripetizione perché tecnicamente l'ultima azione è eliminare, quindi .eliminerebbe solo una riga.

  • Se qualcuno sa come emettere 'sostituire la riga corrente con il registro' dalla modalità EX (riga di comando), mi piacerebbe sentirti (e sapere dove hai trovato la documentazione). Potrebbe esserci un comando EX ripetibile che è più veloce di 4.2 e / o non ha l'avvertenza di interruzione di riga.


1
Il passaggio 4.2 è il killer qui, poiché ora puoi ripetere l'intero processo con il comando punto come in 4.3 - questo è ciò di cui si occupa vim!
JESii

1
Non ho capito. "AG" mette il mio creatore alla fine della riga, entra in modalità di inserimento e immette una "G". Cos'è che non ricevo?
gustafbstrom

@gustafbstrom fair criticism - mi dispiace che la A avrebbe dovuto rappresentare il numero di riga, ma non l'ho fatto notare. Modificato.
Jordan Morris

5

Ecco cosa farei

  • Spostare l'inizio della riga A, AG(dove A è ovviamente un numero di riga)
  • Yank line a qualche registro, ad esempio a (senza nuova riga). genere"ay$
  • Sposta per inserire la riga, XG
  • Linea sostitutiva, S
  • Inserisci dal registro a, Ctrl-Ra

4

Puoi usarlo con la modalità visiva.

  • Vai alla riga A: AG
  • Seleziona la riga con modalità visuale: VESC
  • vai alla riga X: XG
  • Accedere alla modalità sostitutiva per la linea: S
  • Incolla la riga che hai copiato: shift+ insert(o qualsiasi altra mappatura che hai per incollare dagli appunti).

Ah. Non sapere di V e S . Tuttavia, i tuoi passaggi non funzionano per me poiché non trascino negli appunti del mio sistema operativo, che è l'unico a cui posso accedere in modalità di inserimento. Quindi dovrei prima lasciare la modalità di inserimento.
croccante

3

Puoi anche fare:

Vy (in normal mode at the line you want to copy)
Vp (in normal mode at the line you want to replace)
  • Non crea spazi o estremità di linea.
  • Il cursore viene posizionato all'inizio del testo copiato.

Gli stessi tasti possono essere utilizzati per estrarre / incollare più di una riga.

V (in normal mode at what you want to yank)
(use jk to move the selection)
y (to yank the selection)
V (in normal mode at where you want to paste)
(use jk to move the selection)
p (to replace the selection with the yanked lines)

2

Puoi usare questi comandi in modalità normale:

:AmX | Xd

il mcomando è per m[ove], che sposta il numero di riga A dopo il numero di riga X, se si desidera copiare invece di spostare la riga, utilizzare co[py]. il dcomando è per d[elete].

È possibile spostare (copiare utilizzando co) un intervallo di linee utilizzando

:start,end m X

2

Alla luce del recente commento di cicld (grazie!), Vedo che non ho colto appieno il problema originale. Spostare la linea non è appropriato, ma la copia lo è (poiché la linea è strappata). Quindi lo rivederei in:

:1t20:20d_
  1. Copia la prima riga (il :tcomando è un alias per :copy) dopo la riga 20 (la posizionerà sulla riga 21)

  2. Elimina la riga 20, inserendo la riga eliminata nel registro 'blackhole' ( _) (cioè non influisce sul buffer di yank corrente)

Come accennato nel recente commento, ciò non influirà sulla posizione corrente del cursore.


1
  1. : ay (dove a è il numero di riga. Esempio: 20y). Questo strappa una linea (gioco di parole).
  2. Vp

1

Trovo più facile usare il comando Ex per questo; ex. per spostare la linea da 9 a 46:

 :46|9m.|-1d

Questo sposterà il cursore sulla riga 46, sposterà la riga 9 sotto l'attuale, quindi cancellerà la riga precedente (poiché la riga spostata è quella corrente).

O usando i segni, usando il segno 'a':

:46ma a|9m'a|'ad

La bellezza dei comandi EX è che puoi eseguirli ovunque si trovi il cursore (in modalità normale). Preferisco :1m20|.+1d(sposta la riga 1 alla riga 20 ed elimina la riga successiva, ovvero il testo che era alla riga 20 in precedenza). Stessa idea però!
Circld

1

Spesso devo Y una riga e sostituirla in più punti, ognuno dei quali ha un valore diverso (il che significa che non posso fare una regex).

Y per strappare la linea originale desiderata

e poi su ogni riga che desideri sostituire, VpzeroY


0

Vorrei semplicemente usare il registro "Black hole":

dato:

nnoremap <Cd> "_dd

la soluzione sarebbe:

<Cd> yy

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.