Skip to main content
  1. Comandi/

vim - Vi IMproved

·8 mins
Alessio Barnini
Author
Alessio Barnini
Table of Contents

Cosa fa
#

Editor di testo modale a riga di comando. A differenza degli editor grafici, vim ha modalita' distinte: in Normal mode i tasti sono comandi, in Insert mode si scrive testo. Presente su tutti i sistemi Unix anche minimali — conoscerlo e' requisito per lavorare su server remoti senza interfaccia grafica.

Sintassi
#

vim [system]

vi vs vim
#

vi e' l'editor originale scritto da Bill Joy nel 1976. vim (Vi IMproved) e' la versione moderna — aggiunge syntax highlighting, undo multiplo, split window, plugin e molto altro. Su quasi tutti i sistemi Linux moderni vi e' un alias o symlink a vim.

# Verifica cosa e' vi sul tuo sistema
ls -la $(which vi)     # se e' un symlink → punta a vim
vi --version           # se risponde VIM → e' vim

Le tre modalita'
#

  NORMAL MODE                INSERT MODE               VISUAL MODE
  (navigazione e comandi)    (scrittura testo)         (selezione)
                                                           
           i / a / o                 Esc                     Esc
         │─────────────────────────►│◄───────────────────────│
                                                             
           v / V / Ctrl+v                                    
         │───────────────────────────────────────────────────►│
         │◄───────────────────────────────────────────────────│
                        Esc

Quando apri vim sei sempre in Normal mode. Tutti i tasti sono comandi, non scrivono testo.

Entrare e uscire dalle modalita'
#

TastoDaASignificato
iNormalInsertinsert — inserisci prima del cursore
aNormalInsertappend — inserisci dopo il cursore
ANormalInsertAppend — inserisci a fine riga
oNormalInsertopen — apri nuova riga sotto e inserisci
ONormalInsertOpen — apri nuova riga sopra e inserisci
vNormalVisualvisual — selezione carattere per carattere
VNormalVisualVisual — selezione riga intera
Ctrl+vNormalVisualselezione blocco rettangolare
EscqualsiasiNormaltorna sempre a Normal mode

Navigazione — Normal mode#

TastoSignificato letteraCosa fa
hh = sinistra (Vim layout)Un carattere a sinistra
ll = destra (Vim layout)Un carattere a destra
jj = freccia giu' in VimUna riga in giu'
kk = freccia su in VimUna riga in su'
0zero = inizio assolutoInizio della riga corrente
^caret = primo non-spazioPrimo carattere non-whitespace della riga
$dollar = fine riga (regex)Fine della riga corrente
wwordInizio della parola successiva (include punteggiatura)
WWord (maiuscola)Inizio della parola successiva (ignora punteggiatura)
bbackInizio della parola precedente
BBack (maiuscola)Inizio della parola precedente (ignora punteggiatura)
Ctrl+fforwardUna pagina avanti
Ctrl+bbackwardUna pagina indietro
nGGo to line nVai alla riga n (es. 1G = prima riga, 20G = riga 20)
GGo (fine)Vai all'ultima riga del file
gggo goVai alla prima riga (alternativa a 1G)

Eliminare testo — Normal mode
#

Il pattern e': [numero] operatore [movimento]

ComandoSignificatoCosa fa
xx = taglia un carattereElimina il carattere sotto il cursore
3x3x = taglia 3 caratteriElimina il carattere corrente e i 2 successivi
dddelete delete = delete lineElimina la riga corrente (finisce nel registro — e' un taglia)
5dd5 delete deleteElimina 5 righe a partire da quella corrente
dwdelete wordElimina dalla posizione corrente all'inizio della parola successiva
dWdelete WordCome dw ma ignora la punteggiatura
d$delete to endElimina dalla posizione corrente alla fine della riga
d0delete to zeroElimina dalla posizione corrente all'inizio della riga
d^delete to first charElimina fino al primo carattere non-whitespace
dGdelete to end of fileElimina dalla riga corrente alla fine del file
d20Gdelete to line 20Elimina dalla riga corrente alla riga 20
Note

dd non e' un vero "delete" — e' un taglia. Il contenuto va nel registro e puo' essere incollato con p. Se vuoi eliminare senza salvare nel registro usa "_dd (registro blackhole).

Copiare e incollare — Normal mode
#

In vim "yank" significa copiare. La y sta per yank — tirare/strappare.

ComandoSignificatoCosa fa
yyyank yank = yank lineCopia la riga corrente nel registro
5yy5 yank yankCopia 5 righe a partire da quella corrente
ywyank wordCopia dalla posizione corrente all'inizio della parola successiva
y$yank to endCopia dalla posizione corrente alla fine della riga
y0yank to zeroCopia dalla posizione corrente all'inizio della riga
y^yank to first charCopia fino al primo carattere non-whitespace
yGyank to end of fileCopia dalla riga corrente alla fine del file
y20Gyank to line 20Copia dalla riga corrente alla riga 20
ppasteIncolla dopo il cursore (o sotto la riga per dd/yy)
PPaste (maiuscola)Incolla prima del cursore (o sopra la riga)

Undo e redo
#

ComandoSignificatoCosa fa
uundoAnnulla l'ultima modifica
UUndo lineAnnulla tutte le modifiche alla riga corrente
Ctrl+rredoRifai l'ultima modifica annullata

Unire righe
#

ComandoSignificatoCosa fa
JJoinUnisce la riga corrente con quella successiva (aggiunge uno spazio)

Cerca e sostituisci
#

# Cerca in avanti
/parola       # cerca "parola" verso il basso
?parola       # cerca "parola" verso l'alto
n             # prossima occorrenza (next)
N             # occorrenza precedente

# Sostituisci — sintassi: :[range]s/vecchio/nuovo/[flag]
:s/vecchio/nuovo/       # sostituisce prima occorrenza nella riga corrente
:s/vecchio/nuovo/g      # sostituisce tutte le occorrenze nella riga corrente
                        # g = global (tutte le occorrenze della riga)
:%s/vecchio/nuovo/g     # sostituisce in tutto il file
                        # % = shortcut per "dalla prima all'ultima riga"
:%s/vecchio/nuovo/gc    # chiede conferma per ogni sostituzione
                        # c = confirm
:1,5s/vecchio/nuovo/g   # sostituisce solo nelle righe 1-5
:1,$s/vecchio/nuovo/g   # equivalente a :%s ($ = ultima riga)

Salvare e uscire — Command mode (:)
#

ComandoSignificatoCosa fa
:wwriteSalva il file
:w nomefilewrite to fileSalva con nuovo nome
:qquitEsci (solo se non ci sono modifiche non salvate)
:q!quit forceEsci senza salvare — forza l'uscita
:wqwrite quitSalva ed esci
:wq!write quit forceSalva ed esci forzatamente
ZZshortcut per :wqSalva ed esci (solo se il file e' stato modificato)
ZQshortcut per :q!Esci senza salvare

Lavorare con piu' file
#

# Aprire piu' file dalla riga di comando
vim file1.txt file2.txt

# Vedere i buffer aperti
:buffers
# o equivalente:
:ls

# Passare al buffer successivo/precedente
:bn         # buffer next
:bp         # buffer previous
:b2         # vai al buffer numero 2

# Aprire un file aggiuntivo mentre sei in vim
:e nomefile.txt     # e = edit

# Copiare contenuto da un buffer all'altro
:buffer 1           # vai al buffer 1
yy                  # copia la riga
:buffer 2           # vai al buffer 2
p                   # incolla

Configurazione — ~/.vimrc
#

Il file ~/.vimrc e' il dotfile di configurazione di vim. Viene letto all'avvio.

# Contenuto minimo consigliato per ~/.vimrc

set number          " mostra i numeri di riga
set relativenumber  " numeri relativi alla riga corrente (utile per 5dd, 3j)
set syntax on       " syntax highlighting
set tabstop=4       " tab = 4 spazi
set expandtab       " converte tab in spazi
set autoindent      " indentazione automatica
set hlsearch        " evidenzia i risultati della ricerca
set incsearch       " cerca mentre digiti
set ignorecase      " ricerca case-insensitive
set smartcase       " case-sensitive se la query ha maiuscole
set cursorline      " evidenzia la riga corrente
colorscheme desert  " schema colori (usa :colorscheme <Tab> per vedere le opzioni)
# Aprire e modificare il vimrc da dentro vim
:e ~/.vimrc

# Ricaricare il vimrc senza uscire
:source ~/.vimrc
" oppure il shortcut:
:so %
Tip

set relativenumber e' una delle impostazioni piu' utili per chi usa vim seriamente. Mostra la distanza relativa di ogni riga dal cursore — cosi' 5dd (elimina 5 righe) o 3j (scendi 3 righe) diventano visivamente immediati senza dover contare.

Combinazioni utili
#

# Escape da shell ristretta via vim (vedi more.md e bandit-25)
:set shell=/bin/bash
:shell
# oppure direttamente:
:!/bin/bash

# Eseguire un comando shell senza uscire da vim
:!ls -la
:!python3 script.py

# Inserire l'output di un comando nel file
:r !date       # inserisce la data corrente nella posizione del cursore
:r !ls         # inserisce la lista dei file

# Vai alla riga N rapidamente
:42            # vai alla riga 42
42G            # equivalente

Scenario Reale
#

Un analista deve modificare /etc/ssh/sshd_config su un server remoto senza interfaccia grafica per disabilitare il login con password. Apre il file con sudo vim /etc/ssh/sshd_config, usa /PasswordAuthentication per trovare la riga, preme n per navigare alle occorrenze, poi i per entrare in Insert mode e modifica il valore. Salva con :wq e ricarica il servizio. Conoscere vim e' l'unica opzione quando non c'e' nano installato o quando il file e' troppo grande per editor grafici.

Dove l'ho usato
#

  • bandit-25 — escape da shell ristretta via morev → vim

Note personali
#

Important

La prima cosa da imparare e' sempre :q! — come uscire senza fare danni. Poi i per scrivere e Esc + :wq per salvare. Con questi tre comandi sopravvivi su qualsiasi server.

Tip

Esegui vimtutor nel terminale — e' un tutorial interattivo incluso in vim che insegna le basi in circa 30 minuti direttamente nell'editor.

Collegato a
#

  • system — categoria
  • file — categoria
  • more — vim e' raggiungibile da more con il tasto v
  • less — less usa la stessa logica di navigazione h/j/k/l
  • shell-interattiva~/.vimrc e' un dotfile letto all'avvio

Related