Come sostituire le schede con spazi?


85

È possibile convertire le schede in spazi, mantenendo l'allineamento del testo?

La semplice sostituzione funziona solo in modo utile quando non ci sono personaggi principali.


Se hai installato vim-faq , puoi ottenere una risposta offline lì: :h vim-faqe cerca /tab characters. Il tag difficile da memorizzare è :h faq-14.16.
Hotschke,

Risposte:


98

Puoi usare il :retabcomando A partire dal :help :retab

Sostituisci tutte le sequenze di spazi bianchi contenenti a <Tab>con nuove stringhe di spazi bianchi utilizzando il nuovo valore tabstop fornito. Se non si specifica una nuova dimensione tabstop o è zero, Vim utilizza il valore corrente di 'tabstop'. [...] Con 'expandtab'on, Vim sostituisce tutte le schede con il numero appropriato di spazi.

Si noti che il comando accetta un intervallo, quindi è possibile effettuare una selezione visiva e quindi solo :retable linee selezionate.


Freddo! Funziona veloce e semplice!
DenisKolodin,

2
che ne dici di fornire un esempio?
Petr,

23

Puoi usare :retab, come detto, tuttavia, questo cambierà tutte le schede in spazi, non solo le schede all'inizio della riga

Quindi questo (dove è un carattere di tabulazione):

if :; do
⇥echo "⇥hello"
end

viene modificato in (dov'è un personaggio spaziale):

if :; do
␣␣echo "␣␣hello"
end

Ciò può produrre effetti collaterali imprevisti in alcuni scenari ed è ancora più un problema quando si cambiano gli spazi in schede!

Quindi, ho scritto una piccola funzione per modificare solo le schede / spazi all'inizio della riga:

" :retab changes *everything*, not just start of lines
fun! Retab(expandtab)
    let l:spaces = repeat(' ', &tabstop)

    " Replace tabs with spaces
    if a:expandtab
        silent! execute '%substitute#^\%(' . l:spaces . '\)\+#\=repeat("\t", len(submatch(0)) / &tabstop)#e'
    " Replace spaces with tabs
    else
        silent! execute '%substitute#^\%(\t\)\+#\=repeat("' . l:spaces . '", len(submatch(0)))#e'
    endif
endfun

Con questa versione, è necessario specificare manualmente expandtabnella chiamata di funzione (es. :call Retab(1)Per cambiare le schede in spazi), ma è anche possibile modificarlo per assumere il valore corrente di &expandtab(come già fa con &tabstop) proprio come :retabfa. (Preferisco specificarlo manualmente).


6
C'è anche una risposta su SO che copre il retabbing solo all'inizio della linea. Vale la pena collegarlo a causa della chiarezza di tale spiegazione.
jalanb,

Qualcuno potrebbe spiegare cosa significa lettera ain if a:expandtab?
john cj,

Inoltre, sembra che le condizioni siano invertite (uno scherzo: D?). Se hai set expandtabnel tuo .vimrc e poi autocmd BufWritePre * :call Retab(&expandtab)- il rientro sarà cambiato in tabs, invece che in spazi.
john cj,

11

Vim fornisce un !retabcomando che sostituirà tutte le sequenze di <Tab>con nuove stringhe di spazi bianchi usando il nuovo valore tabstop (ad es. :set tabstop=2) Dato, ma tutte le schede all'interno delle stringhe possono essere modificate (ad es. In un programma C, dovresti usare \tper evitarlo)!

Quindi in alternativa puoi cambiare tutte le schede in spazi usando il seguente comando:

:%s/\t/  /g

o come suggerito da @Shahbaz :

:%s/^\t\+/ g

Quindi vengono convertite solo le schede utilizzate nel rientro.

Spiegazione:

  • %rappresenta l'intero buffer / file ( :help :%)
  • ssta per substitute ( :help sub-replace-special)
  • \to ^Ista per tab
  • - usa tutti gli spazi di cui hai bisogno per una scheda
  • g - sta per globale e convertirà più ricorrenze di schede nella stessa riga

Poi per correggere indentazione del tutto il file, si può provare: gg=G. Verifica: rientro del codice con rientro errato per ulteriori dettagli.

Per utilizzare gli spazi per impostazione predefinita anziché le schede, è necessario aggiungere le seguenti impostazioni al .vimrcfile:

set tabstop=2     " (ts) width (in spaces) that a <tab> is displayed as
set expandtab     " (et) expand tabs to spaces (use :retab to redo entire file)
set shiftwidth=2  " (sw) width (in spaces) used in each step of autoindent (aswell as << and >>)

La soluzione alternativa è usare tidy


Relazionato:


1
Almeno farei in %s/^\t\+/ gmodo che vengano convertite solo le schede utilizzate nel rientro. Inoltre, gg=Gpotrebbe essere catastrofico con linguaggi come Python.
Shahbaz

3

Prova a usare:

expand -t 4 input_filename output_filename

expandè uno strumento da riga di comando per convertire le schede in spazi, che è possibile eseguire da una shell o con :!expand.

È in POSIX quindi dovrebbe essere disponibile sulla maggior parte dei sistemi. unexpandfarà il contrario, a proposito.


2
Che cosa è expand?
muru,

Espandi è un comando terminale incorporato per copiare il carattere di tabulazione negli spazi. Puoi trovare una descrizione dettagliata nel seguente link. computerhope.com/unix/uexpand.htm
Ankit Shah

2
Se questi sono comandi esterni, dovresti menzionarlo.
muru,

Ulteriore descrizione aggiunta. Si prega di rivedere
Ankit Shah,

5
Potresti anche fare solo :%!expand -t 4all'interno di Vim. Meglio ancora, potresti anche usare l'attuale opzione di larghezza di spostamento: :exe '%!expand -t ' . &shiftwidth
EvergreenTree

1

Per completezza, =potrebbe anche essere utilizzato per correggere i rientri, dopo aver specificato che le schede vengono sostituite con spazi. In modalità normale, puoi farlo digitando :set expandtab. Quindi =potrebbe essere utilizzato in due modi:

  • In modalità Visual, un singolo =correggeva i rientri dei blocchi di codice selezionati.
  • In modalità normale, gg=Gaggiustava l'intero file, dove ggsposta il cursore all'inizio del file, quindi =viene applicato e Gsposta il cursore alla fine del file.

Riferimento: link


Ciò presuppone che vim possa ricalcolare correttamente il rientro corrente (potrebbe non essere il caso) , anche per file non strutturati o codice scritto in un editor diverso con regole di rientro leggermente diverse.
ideasman42

Grazie @ ideasman42; Ho aggiunto alla risposta per essere più completo.
Samuel Li,
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.