La riga dei due punti, e il comando :g
Sotto Vim c'è ancora ex, l'editor di riga da cui è nato. Da lì arrivano
gli intervalli, i filtri esterni e :g — il comando che fa in un
secondo le cose per cui altrove si scrive uno script.
:g — «su ogni riga che…, fai questo»
:[intervallo]g/pattern/comando # senza intervallo, l'impostazione è tutto il file # :g! oppure :v → agisce sulle righe che NON corrispondono
Funziona in due passate: prima Vim segna tutte le righe che corrispondono al pattern, poi esegue il comando su ciascuna. Questo doppio passaggio è ciò che lo rende sicuro anche quando il comando cancella o sposta righe: l'elenco è già stato deciso.
| Comando | Effetto |
|---|---|
| :g/TODO/d | cancella tutte le righe che contengono TODO |
| :g/^$/d | elimina le righe vuote |
| :g/^\s*$/d | elimina anche quelle con soli spazi |
| :v/errore/d | tiene solo le righe con «errore» — un grep dentro il file |
| :g/pattern/t$ | copia in fondo al file tutte le righe che corrispondono |
| :g/pattern/m0 | le sposta in cima, in ordine inverso |
| :g/pattern/-1j | unisce ogni riga trovata alla precedente |
| :g/<h2/ .+1,+3s/vecchio/nuovo/g | sostituisce solo nelle tre righe dopo ogni <h2 |
| :g/pattern/p | stampa le righe: anteprima innocua per verificare il pattern |
p prima. :g/pattern/p
elenca in fondo allo schermo le righe che verranno colpite. Se sono quelle
giuste, richiami il comando con : e ↑, cambi la p
finale in d e vai.
I comandi ex che si combinano con :g
| Comando | Significato |
|---|---|
| d | delete — cancella |
| t (o co) | copy — copia dopo la riga indicata |
| m | move — sposta |
| j | join — unisce |
| s | substitute — sostituisce |
| normal tasti | esegue quei tasti come se li premessi in NORMAL |
| > < | indenta / de-indenta |
Gli indirizzi si scrivono con . (riga corrente), $
(ultima), 0 (prima dell'inizio), un numero, o uno spostamento
relativo come +3 e -1.
Far lavorare i programmi esterni dentro Vim
Il punto esclamativo apre una porta verso la shell. Tre forme, tre usi diversi:
| Forma | Effetto |
|---|---|
| :!comando | esegue e mostra l'output, senza toccare il file |
| :r !comando | inserisce l'output nel file, sotto il cursore |
| :intervallo!comando | filtra quelle righe attraverso il comando e le sostituisce con il risultato |
| :w !comando | manda il buffer al comando senza salvare (vedi lezione 1) |
:%!sort # ordina tutto il file :%!sort -u # ordina ed elimina i duplicati :10,30!sort -t, -k2 # ordina solo quelle righe, per la 2ª colonna :%!column -t # incolonna una tabella di testo :%!python3 -m json.tool # riformatta un JSON illeggibile :'<,'>!tr a-z A-Z # la selezione visuale in maiuscolo :r !date +\%Y-\%m-\%d # inserisce la data di oggi :r !ls *.jpg # inserisce l'elenco dei file
In NORMAL, l'operatore ! accetta un movimento: !ip sort
ordina il paragrafo sotto il cursore, !}sort fino alla riga vuota
successiva. Se il risultato non ti piace, u lo annulla come qualsiasi
altra modifica.
% significa «nome del file corrente» e # «file
alternativo». Se ti servono letteralmente — per esempio in una stringa di
formato di date — vanno protetti con la barra rovescia, come
nell'esempio sopra.
Scorciatoie sulla riga di comando
| Tasto | Effetto dopo aver premuto : |
|---|---|
| ↑ ↓ | scorre lo storico dei comandi filtrato da ciò che hai già scritto |
| q: | apre lo storico come un buffer modificabile: correggi una riga e premi Invio |
| Ctrl-r Ctrl-w | inserisce la parola sotto il cursore nel comando |
| Ctrl-r " | inserisce il contenuto del registro innominato |
:g più macro: il moltiplicatore
Le macro della lezione 5 si eseguono dove sei, e con
999@q vanno avanti finché possono — ma passano anche sulle righe che
non c'entrano nulla. :g risolve esattamente questo: seleziona le
righe giuste, e su ognuna lancia la macro.
:g/pattern/normal @q
# file di partenza #max_connections = 100 max_connections = 100 #timeout = 30 timeout = 30 shared_buffers = 128MB # macro in "q: A ; # rivisto Esc # poi: :g/^[^#]/normal @q #max_connections = 100 max_connections = 100 ; # rivisto #timeout = 30 timeout = 30 ; # rivisto shared_buffers = 128MB ; # rivisto
Le righe commentate restano intatte, perché il pattern ^[^#] le
esclude. La stessa struttura risolve una quantità di problemi reali: applicare una
trasformazione complicata solo alle righe di una certa sezione, solo a quelle che
contengono un tag, solo a quelle senza un certo campo.
:g/pattern/normal ct,NUOVO usa direttamente i tasti senza registrare
una macro, comodo per modifiche brevi. E :g/pattern/normal! @q con il
punto esclamativo ignora le tue mappature personali — più prevedibile se hai un
.vimrc ricco.