Vim editing multilinea come in sublimetext?


133

Ho iniziato a usare gvim e non riesco a capire come funzioni la modifica multilinea in gvim.

Per esempio:

Testo originale:

asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;

ctrl + q, jjjjjj, $ tutto è selezionato, quindi premo I per eseguire un inserimento multilinea.

La mia intenzione è quella di inserire le virgolette come nella prima riga, quindi premere Esc:

asd "asd asd" asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;

Quello che è successo? Mi aspettavo un comportamento simile a quello di sublimetext:

inserisci qui la descrizione dell'immagine

Se non sai come funziona, ripete semplicemente le azioni per ogni riga. Come può farlo? E cosa ci fa Vim qui?


Basta registrare una macro di tastiera per cambiare la prima riga e quindi riprodurre la macro per tutte le altre righe.
— high5

Risposte:


215

Fatti un favore lasciando cadere il livello di compatibilità di Windows.

La normale scorciatoia per accedere alla modalità Visual-Block è <C-v>.

Altri si sono occupati della registrazione di macro, ecco alcune altre idee:

Utilizzando solo la modalità blocco visivo .

  1. Posiziona il cursore sulla seconda parola:

    asd |a|sd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    
  2. Premi <C-v>per accedere alla modalità blocco visivo ed espandere la selezione verso il basso:

    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    
  3. Premi I"<Esc>per ottenere:

    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    
  4. Posiziona il cursore sull'ultimo carattere della terza parola:

    asd "asd as|d| asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    
  5. Premi <C-v>per accedere alla modalità blocco visivo ed espandere la selezione verso il basso:

    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    
  6. Premi A"<Esc>per ottenere:

    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    

Con modalità blocco visivo e Surround.vim .

  1. Posiziona il cursore sulla seconda parola:

    asd |a|sd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    
  2. Premi <C-v>per accedere alla modalità blocco visivo ed espandere la selezione verso il basso e verso destra:

    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    
  3. Premi S"per circondare la tua selezione con ":

    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    

Con modalità visuale e :normal.

  1. Premi Vper selezionare l'intera linea ed espanderla verso il basso:

    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    
  2. Eseguire questo comando: :'<,'>norm ^wi"<C-v><Esc>eea"<CR>per ottenere:

    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    
    • :norm[al]consente di eseguire i comandi in modalità normale su un intervallo di righe (la '<,'>parte viene aggiunta automaticamente da Vim e significa "agire sull'area selezionata")

    • ^ posiziona il cursore sul primo carattere della riga

    • w passa alla parola successiva

    • i"inserisce una "prima del cursore

    • <C-v><Esc>è il modo di Vim di inserire un carattere di controllo in questo contesto, qui è <Esc>usato per uscire dalla modalità di inserimento

    • ee si sposta alla fine della parola successiva

    • a"aggiunge un "dopo il cursore

    • <CR> esegue il comando

    Usando Surround.vim, il comando sopra diventa

    :'<,'>norm ^wvees"<CR>
    

7
Per i passaggi 4 e 5, consiglierei di premere gvper ripristinare la selezione visiva precedente, quindi spostarsi in orizzontale, magari con 2e. (Più righe, più prezioso gvè!)
— joeytwiddle,

4
surround.vim usa un piccolo sin modalità normale ma uno grande Sin modalità visiva, quindi nel passaggio 3 del metodo surround.vim, i tasti dovrebbero essereS"
— joeytwiddle

1
Il punto 3 di visual-block + Surround.vim dovrebbe essere S", nons"
— zool

1
Invece dei passaggi 5 e 6 in modalità blocco visivo, puoi semplicemente posizionare il cursore dopo la terza parola e premere ..
— Jonas,

2
Questo è interessante, ma funziona solo in alcuni casi in cui i caratteri che si desidera modificare su linee diverse si trovano esattamente nella stessa posizione orizzontale su ciascuna linea e le linee modificate si trovano una dopo l'altra. Non possiamo scegliere dove entrare in modalità modifica su quale linea in Vim? Possiamo in Sublim ... EDIT: In realtà la seconda risposta è quello che stavo cercando
— Alexandre Bourlier,

30

Queste sono alcune buone soluzioni pronte all'uso sopra indicate, ma possiamo anche provare alcuni plugin che forniscono più cursori come Sublime.

Penso che questo appaia promettente:

Sembrava abbandonato da un po ', ma ha avuto alcuni contributi nel 2014.

È abbastanza potente, anche se mi ci è voluto un po 'di tempo per abituarmi al flusso (che è abbastanza simile al Sublime ma ancora modale come Vim).

Nella mia esperienza, se hai installato molti altri plugin, potresti incontrare alcuni conflitti!

Ci sono altri tentativi di questa funzione:

Non esitare a modificare se noti uno di questi in fase di miglioramento.


Sembra che github.com/osyo-manga/vim-over sia il più attivo del gruppo al momento.
— Wernight,

Eccellente, questo è quello che stavo cercando
— Alexandre Bourlier,

1
Dopo averne testato la maggior parte, hlissner / vim-multiedit sembra il migliore AFAIAC
— Alexandre Bourlier,

1
Controlla mg979 / vim-visual-multi come un buon sostituto per i cursori multi-vim
— Mushex Antaranian

29

Ci sono molti modi per farlo in Vim. Non so quali siano i più simili a quelli di Sublime Text.


Il primo sarebbe tramite la modalità di inserimento multilinea . Posiziona il cursore sulla seconda "a" nella prima riga, premi Ctrl-V, seleziona tutte le righe, quindi premi Ie inserisci una doppia virgoletta. Premendo <esc>si ripeterà l'operazione su ogni riga.


Il secondo è tramite macro. Posiziona il cursore sul primo carattere e inizia a registrare una macro con qa. Vai a destra con llll, inserisci la modalità di inserimento con a, metti una doppia virgoletta, esci dalla modalità di inserimento e torna all'inizio della riga con <home>(o equivalente). Premere jper spostarsi verso il basso di una riga. Interrompere la registrazione con q. E quindi riprodurre nuovamente la macro @a. Parecchie volte.


Qualcuno dei suddetti approcci funziona per te?


15

se si utilizza il comando "globale", è possibile ripetere ciò che è possibile fare in linea su un numero qualsiasi di righe.

:g/<search>/.<your ex command>

esempio:

:g/foo/.s/bar/baz/g

Il comando sopra trova tutte le linee che hanno pippo e sostituisce tutte le occorrenze di barra su quella linea con baz.

:g/.*/

farà su ogni linea


1
È così utile, non lo sapevo. Sembra una combinazione di comandi così potente e intelligente.
— 0xc0de,

Per comodità, ho scritto una piccola funzione che prende la parola sotto il cursore (o la parola visivamente selezionata), richiede una sostituzione e quindi esegue il :gcomando descritto qui. Mi piace usare /gcper chiedere "conferme" in modo da poter premere yo nper ogni sostituzione, o aper cambiarle tutte.
— joeytwiddle,

11
Ctrl-v ................ start visual block selection
6j .................... go down 6 lines
I" .................... inserts " at the beginning
<Esc><Esc> ............ finishes start
2fdl. ................. second 'd' l (goes right) . (repeats insertion)

Nel passaggio 3, Inon è possibile accedere alla modalità di inserimento, sai perché questo accade?
— Ninja

Prova a caricare vim senza plug-in: vim -u NONEe prova a eseguire di nuovo l'azione desiderata, potrebbe essere una mappa o un plug-in a cambiare il comportamento del tuo vim.
— SergioAraujo,

6

Non sono sicuro di cosa vimstia facendo, ma è un effetto interessante. Il modo in cui stai descrivendo ciò che desideri sembra più simile al modo in cui funzionano le macro ( :help macro). Qualcosa del genere farebbe quello che vuoi con le macro (partendo dalla modalità normale):

  1. qa: Registra la macro da aregistrare.
  2. 0w: 0vai all'inizio della riga, wsalta una parola.
  3. i"<Esc>: Consente di accedere alla modalità di inserimento, inserire a "e tornare alla modalità normale.
  4. 2e: Passa alla fine della seconda parola.
  5. a"<Esc>: Aggiungi a ".
  6. jq Passa alla riga successiva e termina la registrazione macro.

Presi insieme: qa0wi"<Esc>2ea"<Esc>

Ora puoi eseguire la macro con @a, ripeti l'ultima macro con @@. Per applicare al resto del file, fare qualcosa del genere 99@ache presuppone che non ci siano più di 99 righe, l'esecuzione della macro termina quando raggiunge la fine del file.

Ecco come ottenere ciò che vuoi visual-block-mode(partendo dalla modalità normale):

  1. Vai dove vuoi che sia la prima citazione.
  2. Invio visual-block-mode, selezionare le linee che si desidera influenzare, Gper andare in fondo al file.
  3. Hit I"<Esc>.
  4. Passa al punto successivo che desideri inserire a ".
  5. Vuoi ripetere quello che hai appena fatto, quindi .sarà sufficiente una semplice .

4
Non è necessario per 99 @ a. Se si desidera eseguire una macro su ogni riga di un file, provare:% norm! @un.
— Rook

Senza i punti (sono solo le estremità delle frasi, non fanno parte dei comandi)
— Arriva il

9999@apuò essere brutto ma è molto più facile da scrivere rispetto a :%norm! @ae non viene eseguito nuovamente sulla riga appena modificata. Comunque buono conoscerlo comunque. :)
— joeytwiddle,

0

La mia soluzione è utilizzare questi 2 mapping:

map <leader>n <Esc><Esc>0qq
map <leader>m q:'<,'>-1normal!@q<CR><Down>

Come usarli:

  1. Seleziona le tue linee. Se voglio selezionare le successive 12 righe premoV12j
  2. stampa <leader>n
  3. Apporta le modifiche alla linea
  4. Assicurati di essere in modalità normale, quindi premi <leader>m

Per effettuare un'altra modifica non è necessario ripetere la selezione. Basta premere <leader>n, apportare la modifica e premere <leader>mper applicare.


Come funziona:

  • <Esc><Esc>0qq Esci dalla selezione visiva, vai all'inizio della riga e inizia a registrare una macro.

  • q Interrompere la registrazione della macro.

  • :'<,'>-1normal!@q<CR> Dall'inizio della selezione visiva alla riga prima della fine, riprodurre la macro su ciascuna riga.

  • <Down> Torna all'ultima riga.


Puoi anche mappare la stessa chiave ma per diverse modalità:

vmap <leader>m <Esc><Esc>0qq
nmap <leader>m q:'<,'>-1normal!@q<CR><Down>

Anche se questo confonde la tua capacità di fare un'altra modifica. Dovrai riselezionare le tue linee.

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.