Preferenze Tab Vs Space in Vim


87

Vim è molto accomodante quando si tratta di tab vs. preferenze di spazio. A quanto ho capito, l' tabstopimpostazione indica la larghezza di un carattere di tabulazione. L' shiftwidthimpostazione specifica quante colonne aumentare / diminuire quando si utilizzano i comandi <<e >>, mentre l' softtabstopimpostazione influenza la quantità di spazi bianchi da inserire quando si preme il Tabtasto in modalità di inserimento. Se expandtabè attivato, il tasto Tab inserisce il softtabstopnumero di caratteri di spazio. Mentre con expandtabspento, premendo il Tabtasto si inserisce il minor numero possibile di caratteri di tabulazione + spazio che corrispondono softtabstop. (Per favore correggimi se sbaglio.)

Quest'ultimo punto mi fa chiedere: c'è un caso pratico in cui non vorresti shiftwidth == tabstop && tabstop == softtabstop? Non riesco a pensare a uno. Per quanto mi riguarda, sarebbe più conveniente se potessi impostare tutti e 3 questi allo stesso valore, in una singola assegnazione. ad es. chiamando:

:set stab=4

che sarebbe equivalente a eseguire:

:set tabstop=4 softtabstop=4 shiftwidth=4 

Qualcuno può suggerire come questo potrebbe essere fatto?


AGGIORNARE

Grazie per le risposte finora da troppo php , hobbs e kaiser.se . Piuttosto che rispondere a ciascuno individualmente, aggiorno la domanda qui.

Softtabstop con expandtab disattivato

Ho detto sopra che con expandtab disattivato, premendo il tasto Tab si inserisce il minor numero possibile di caratteri di tabulazione + spazio che corrispondono softtabstop. Lo sostengo, ma penso di dover spiegare cosa intendevo. Cercherò di farlo attraverso alcuni esempi. Per proseguire, corri in :set listmodo da poter vedere i caratteri di tabulazione.

tabstop=4 softtabstop=2 shiftwidth=4 noexpandtab

In modalità di inserimento, premendo il tasto Tab si inseriscono 2 caratteri di spazio. Premere il tasto Tab una seconda volta e invece di inserire altri due caratteri di spazio (per un totale di 4 caratteri di spazio) sostituisce i 2 spazi precedenti con un singolo carattere di tabulazione. Tabstop è impostato su 4, quindi un singolo carattere di tabulazione ha la stessa larghezza di 4 spazi.

tabstop=4 softtabstop=6 shiftwidth=4 noexpandtab

In modalità di inserimento, premendo il tasto Tab si inserisce 1 carattere di tabulazione più 2 spazi. Il carattere di tabulazione ha una larghezza di 4, quindi la larghezza totale è 6 e ciò si ottiene utilizzando 3 caratteri. Premendo una seconda volta il tasto Tab vengono inseriti due caratteri di tabulazione e vengono rimossi i due spazi inseriti in precedenza. La larghezza totale è 12 e ciò si ottiene utilizzando 3 caratteri.

In entrambi questi esempi, Vim inserisce il numero minimo possibile di caratteri di tabulazione + spazio che corrispondono a softtabstop.

Se lavoro con expandtab disattivato, non riesco a immaginarmi a desiderare il controllo granulare extra che può essere ottenuto impostando softtabstop su un valore diverso da tabstop. Sarebbe comunque utile per me poter impostare tabstop, softtabstope shiftwidthallo stesso valore, con un solo comando.

Expandtab rende ridondante softtabstop?

tabstop=4 softtabstop=0 shiftwidth=4 expandtab

In modalità di inserimento, premendo il tasto Tab si inseriscono 4 spazi. Premendo il tasto Canc si elimina un singolo spazio, quindi è necessario tornare indietro 4 volte se si preme accidentalmente il tasto Tab.

tabstop=4 softtabstop=4 shiftwidth=4 expandtab

In modalità di inserimento, premendo il tasto Tab si inseriscono 4 spazi. Premendo il tasto backspace si cancellano 4 spazi.

Se sto lavorando con expandtabacceso, preferirei che il tasto Canc rimuovesse la stessa quantità di spazio bianco degli inserti del tasto Tab. Quindi, anche in questo caso, credo che sarebbe utile poter assegnare lo stesso valore a tabstop, softtabstope shiftwidthcontemporaneamente.

Una scorciatoia sarebbe comunque utile

È fantastico che Vim offra così tanta flessibilità, ma non riesco a immaginarmi di averne bisogno. Voglio solo essere in grado di scegliere la larghezza di una scheda e se si tratta di una scheda "dura" (utilizzando un carattere di tabulazione) o una scheda "morbida" (composta da spazi). Passare :set expandtab!da una scheda dura a una scheda morbida è abbastanza facile ( ), ma vorrei che fosse più semplice impostare la larghezza della scheda, senza dover armeggiare con 3 diversi parametri.

Quindi il mio suggerimento proposto per qualcosa di simile :set stab=4suona ancora bene per me.


Sembra che tu abbia due domande diverse qui, forse dovresti dividere la tua domanda in due.
Greg Hewgill

Hai ragione! Ho spostato la seconda domanda in un argomento a sé stante.
nelstrom

1
Sembra una RFE piuttosto che una domanda. Come tale, probabilmente dovresti proporre alla comunità VIM: vim.org/community.php - o semplicemente scrivere una patch. Oltre a questo, VIM ha una vasta funzionalità di macro che ti consente di definire nuove operazioni, quindi è molto probabile che tu possa semplicemente creare una macro che fa quello che vuoi.
kdgregory

@nelstrom Per quanto riguarda la tua domanda is there a practical case where you wouldn't want shiftwidth == tabstop && tabstop == softtabstop?, il codice sorgente di Vim usa set shiftwidth=4 tabstop=8 noexpandtab. Sì, in genere si vuole shiftwidth == softtabstop, ma questo è indipendente dal valore tabstop.
jamessan

Risposte:


56

Creare stabun'opzione in Vim stesso non sarebbe facile, ma ho creato questo comando / funzione che puoi inserire nel tuo .vimrc(o in un file plugin se sei super organizzato). Usa :Stabe ti verrà richiesto un livello di rientro e se usarlo o meno expandtab. Se premi Invio senza dargli un nuovo livello di rientro, stamperà solo le impostazioni correnti.

"metti tutto questo nel tuo .vimrc o in un file plugin
comando! -nargs = * Stab chiama Stab ()
funzione! Pugnale ()
  let l: tabstop = 1 * input ('set shiftwidth =')

  se l: tabstop> 0
    "vogliamo anche expandtab?
    let l: expandtab = confirm ('set expandtab?', "& Yes \ n & No \ n & Cancel")
    se l: expandtab == 3
      "abortire?
      ritorno
    finisci se

    let & l: sts = l: tabstop
    let & l: ts = l: tabstop
    let & l: sw = l: tabstop

    se l: expandtab == 1
      setlocal expandtab
    altro
      setlocal noexpandtab
    finisci se
  finisci se

  "mostra le opzioni selezionate
  provare
    echohl ModeMsg
    echon 'set tabstop ='
    echohl Question
    echon & l: ts
    echohl ModeMsg
    echon 'shiftwidth ='
    echohl Question
    echon & l: sw
    echohl ModeMsg
    echon "sts ="
    echohl Question
    echon & l: sts. ''. (& l: et? '': 'no')
    echohl ModeMsg
    echon 'expandtab'
  infine
    echohl Nessuno
  endtry
funzione finale

3
Grazie per la sceneggiatura! Fa più di quanto ho chiesto - penso che preferirei mantenere expandtab fuori da esso - ma posso facilmente personalizzarlo a mio piacimento. Mi hai fornito un piccolo corso accelerato in Vimscript, quindi ti sono molto grato. La taglia da 100 punti è tua!
nelstrom

9

Questo è il mio primo tentativo di scrivere VimScript, ma ecco qui:

function! Stab(value)
    let &shiftwidth  = a:value
    let &softtabstop = a:value
    let &tabstop     = a:value
endfunc

Se lo metto nel mio file .vimrc, posso chiamarlo eseguendolo :call Stab(X), dove X è la larghezza di tabulazione desiderata. Questa è una soluzione adeguata per ora, ma se qualcuno può suggerire un modo per rendere più facile la chiamata ne sarei grato.

Ho anche creato una funzione che riassume rapidamente le impostazioni correnti, che ho mappato in ctrl-Tab:

nmap <C-Tab> :call TabParams()<CR>
function! TabParams()
    echo "tabstop:     ".&tabstop
    echo "shiftwidth:  ".&shiftwidth
    echo "softtabstop: ".&softtabstop
endfunc

Bene, ho messo una taglia di 100 punti per questa risposta, e ora l'ho risolto a metà da solo. Non sono sicuro di poter accettare la mia risposta ...


+1 sì, ma se questo è ciò che vuoi veramente, è comunque una risposta ok.
DaveParillo

2
Probabilmente vorrai usare let & l: shiftwidth, ecc. Per impostare le versioni locali.
SystemParadox

7

In modalità di modifica puoi anche utilizzare Ctrl-Tper rientrare e Ctrl-Ddeindentare al livello di rientro successivo come impostato da shiftwidth, indipendentemente dalle impostazioni tabstop, softtabstopo expandtab. Vim aggiungerà / rimuoverà automaticamente spazi o tabulazioni per portarti alla colonna di destra.

Se usi questi comandi per controllare il rientro invece di Tab/ Backspacenon devi preoccuparti che tutte queste impostazioni della scheda si adattino insieme e arrivi sempre al livello di rientro corretto.


3

Se expandtabè impostato allora (come sottolinea troppo php), softtabstopdiventa ridondante. L'unico motivo per cui potresti impostare shiftwidthdiversamente tabstopsarebbe quello di soddisfare una strana abitudine; ad esempio, usi i rientri di quattro spazi ma preferisci tabinserire otto spazi.

Se expandtabnon è impostato, le cose si fanno più confuse. Se vuoi che il tuo codice abbia lo stesso aspetto negli cateditor e non vim come in vim, allora tabstopdovrebbe sempre essere impostato su 8; in questo caso si dovrebbe impostare softtabstope shiftwidthsia per il vostro livello di rientro preferito. Se invece preferisci che ogni "scheda fisica" nel file rappresenti un livello di rientro, dovresti impostare tabstope shiftwidthal tuo livello di rientro preferito e lasciarlo softtabstopa zero (impostarlo uguale a tabstopequivale a tranne che se lo modifichi tabstopnon sarà più sincronizzato, mentre zero significa semplicemente "ignoralo per favore").


3
Penso che questo sia sbagliato perché solo con softtabstopil valore corretto, il backspace cancellerà un rientro spaziato come se fosse una tabulazione. che è un must per un uso sano.
u0b34a0f6ae

2

La tua comprensione di softtabstoped expandtabè sbagliata, quindi l' stabopzione che suggerisci non sarebbe molto utile.

expandtabè per quando vuoi usare gli spazi invece delle tabulazioni per tutto . Se imposti expandtab, Vim ignora l' softtabstopopzione e usa tabstope shiftwidthper calcolare quanti spazi inserire.

softtabstopserve solo quando desideri utilizzare una combinazione di tabulazioni e spazi, permettendoti di rientrare con un controllo preciso (2 o 4 spazi), mantenendo la larghezza della tabulazione a un valore più alto (di solito 8) in modo che il testo appaia nelle altre applicazioni . L'impostazione softtabstop=tabstopnon realizza nulla perché Vim userà sempre le tabulazioni per il rientro.

Aggiornamento: come ha sottolineato kaizer.se , se stai usando expandtab, devi ancora impostare softtabstopse vuoi che Vim esegua il backspace di più spazi come se fossero una scheda.


Anche se hai ragione tabstope softtabstopdiventi una variabile di troppo quando extpandtabè impostata, penso che tu abbia torto sulla priorità. Provalo: imposta ts=8 sts=4 ete premi tab; il cursore si troverà nella colonna cinque e verranno inseriti quattro spazi, proprio come se avessi impostato ts=4 sts=0 et.
hobbs

5
Penso che questo sia sbagliato perché solo con softtabstopil valore corretto, il backspace eliminerà un rientro spaziato come se fosse una tabulazione. che è un must per un uso sano.
u0b34a0f6ae

2

Stai cambiando le impostazioni dello spazio bianco così spesso che hai davvero bisogno di una funzione per gestirlo? Se stai scherzando molto con tabstop e anche impostando expandtab, probabilmente avrai un pasticcio nel tempo mentre cambi file con valori diversi passati a stab. Oggi lo uso :call stab (4), domani è :call stab (2)e la scorsa settimana è stato :call stab (8). Sembra che anche se lo scrivi, presto smetterai di usarlo.

Se prevedi di passare sempre lo stesso valore per pugnalare, perché non modificare semplicemente le tue impostazioni globali? In vim:

:e $MYVIMRC

e aggiungi quanto segue:

set tabstop=4
set shiftwidth=4  "tabs are 4 spaces wide (default = 8)
set expandtab     "Convert tabs to spaces

Ecco come è configurato il mio .vimrc.


1

Un'opzione utile è softtabstop=-1che lo imposterà sul valore di shiftwidth.
È inoltre possibile impostare shiftwidtha 0, nel qual caso tabstopverrà utilizzato il valore.

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.