Préférences Tab Vs Space dans Vim

87

Vim est très accommodant en ce qui concerne l'onglet Vs. préférences d'espace. Si je comprends bien, le tabstopparamètre indique la largeur d'un caractère de tabulation. Le shiftwidthparamètre spécifie le nombre de colonnes à incrémenter / décrémenter lors de l'utilisation des commandes <<et >>, tandis que le softtabstopparamètre influence la quantité d'espaces à insérer lorsque vous appuyez sur la Tabtouche en mode insertion. Si expandtabest activé, la touche de tabulation insère le softtabstopnombre de caractères d'espacement. Alors qu'avec expandtabdésactivé, appuyer sur la Tabtouche insère le plus petit nombre possible de caractères tabulation + espace correspondant softtabstop. (Corrigez-moi si j'ai tort, s'il-vous plait.)

Ce dernier point me fait me demander: y a-t-il un cas pratique où vous ne voudriez pas shiftwidth == tabstop && tabstop == softtabstop? Je ne peux pas penser à un seul. En ce qui me concerne, ce serait plus pratique si je pouvais définir tous les 3 à la même valeur, en une seule affectation. par exemple appeler:

:set stab=4

ce qui équivaudrait à courir:

:set tabstop=4 softtabstop=4 shiftwidth=4 

Quelqu'un peut-il suggérer comment cela pourrait être fait?


MISE À JOUR

Merci pour les réponses si loin de trop de php , hobbs et kaiser.se . Plutôt que de répondre à chacun individuellement, je mets à jour la question ici.

Softtabstop avec expandtab désactivé

J'ai dit ci-dessus qu'avec expandtab désactivé, appuyez sur la touche Tab pour insérer le plus petit nombre possible de caractères tabulation + espace correspondant softtabstop. Je maintiens cela, mais je pense que je dois expliquer ce que je voulais dire. J'essaierai de le faire à l'aide de quelques exemples. Pour suivre, exécutez :set listpour voir les caractères de tabulation.

tabstop=4 softtabstop=2 shiftwidth=4 noexpandtab

En mode insertion, une pression sur la touche de tabulation insère 2 caractères d'espacement. Appuyez une deuxième fois sur la touche de tabulation et au lieu d'insérer deux autres caractères d'espace (pour un total de 4 caractères d'espace), il remplace les 2 espaces précédents par un seul caractère de tabulation. Tabstop est défini sur 4, donc un seul caractère de tabulation a la même largeur que 4 espaces.

tabstop=4 softtabstop=6 shiftwidth=4 noexpandtab

En mode insertion, appuyez sur la touche de tabulation pour insérer 1 caractère de tabulation plus 2 espaces. Le caractère de tabulation a une largeur de 4, donc la largeur totale est de 6, et ceci est réalisé en utilisant 3 caractères. Une seconde pression sur la touche de tabulation insère deux caractères de tabulation et supprime les deux espaces insérés précédemment. La largeur totale est de 12, et ceci est réalisé en utilisant 3 caractères.

Dans ces deux exemples, Vim insère le nombre minimum possible de caractères tabulation + espace correspondant à softtabstop.

Si je travaille avec expandtab désactivé, je ne me vois pas vouloir le contrôle supplémentaire granulaire qui peut être obtenu en définissant softtabstop sur une valeur différente de tabstop. Il me serait toujours utile de pouvoir régler tabstop, softtabstopet shiftwidthà la même valeur avec une seule commande.

Expandtab rend softtabstop redondant?

tabstop=4 softtabstop=0 shiftwidth=4 expandtab

En mode insertion, appuyer sur la touche de tabulation insère 4 espaces. Appuyer sur la touche de suppression supprime un seul espace - vous devez donc reculer 4 fois si vous appuyez sur la touche de tabulation par accident.

tabstop=4 softtabstop=4 shiftwidth=4 expandtab

En mode insertion, appuyer sur la touche de tabulation insère 4 espaces. Appuyez sur la touche de retour arrière pour supprimer 4 espaces.

Si je travaille avec expandtabactivé, je préférerais que la touche de suppression supprime la même quantité d'espaces que les inserts de touche de tabulation. Donc, dans ce cas aussi, je pense qu'il serait utile de pouvoir attribuer la même valeur à tabstop, softtabstopet shiftwidthsimultanément.

Un raccourci serait toujours utile

C'est génial que Vim offre autant de flexibilité, mais je ne me vois pas en avoir besoin. Je veux juste pouvoir choisir la largeur d'un onglet, et s'il s'agit d'un onglet «dur» (en utilisant un caractère de tabulation) ou d'un onglet «souple» (composé d'espaces). Basculer entre les onglets durs et souples est assez facile ( :set expandtab!), mais j'aurais aimé qu'il soit plus simple de définir la largeur de l'onglet, sans avoir à jouer avec 3 paramètres différents.

Donc, ma proposition de suggestion pour quelque chose comme :set stab=4me semble toujours bonne.

Nelstrom
la source
Il semble que vous ayez deux questions différentes ici, peut-être devriez-vous diviser votre question en deux.
Greg Hewgill
Tu as raison! J'ai déplacé la deuxième question dans un sujet à part.
nelstrom
1
Cela ressemble plus à une RFE qu'à une question. En tant que tel, vous devriez probablement proposer à la communauté VIM: vim.org/community.php - ou simplement écrire un patch. En dehors de cela, VIM dispose d'une fonction macro étendue qui vous permet de définir de nouvelles opérations, il est donc très probable que vous puissiez simplement créer une macro qui fait ce que vous voulez.
kdgregory
@nelstrom En ce qui concerne votre question is there a practical case where you wouldn't want shiftwidth == tabstop && tabstop == softtabstop?, le propre code source de Vim utilise set shiftwidth=4 tabstop=8 noexpandtab. Oui, on veut généralement shiftwidth == softtabstop, mais c'est indépendant de la valeur tabstop.
jamessan

Réponses:

56

Créer une staboption dans Vim lui-même ne serait pas facile, mais j'ai mis au point cette commande / fonction que vous pouvez déposer dans votre .vimrc(ou dans un fichier de plugin si vous êtes super-organisé). Utilisez :Stabet vous serez invité à indiquer un niveau d'indentation et à utiliser ou non expandtab. Si vous appuyez sur Entrée sans lui donner un nouveau niveau de retrait, il imprimera simplement les paramètres actuels.

"mettez tout cela dans votre .vimrc ou dans un fichier plugin
commander! -nargs = * Stab appelle Stab ()
fonction! Poignarder()
  let l: tabstop = 1 * entrée ('set shiftwidth =')

  si l: tabstop> 0
    "voulons-nous aussi expandtab?
    let l: expandtab = confirm ('set expandtab?', "& Oui \ n & Non \ n & Annuler")
    si l: expandtab == 3
      " avorter?
      revenir
    fin si

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

    si l: expandtab == 1
      setlocal expandtab
    autre
      setlocal noexpandtab
    fin si
  fin si

  "afficher les options sélectionnées
  essayer
    Mode échoMsg
    echon 'set tabstop ='
    Question d'écho
    echon & l: ts
    Mode échoMsg
    echon 'shiftwidth ='
    Question d'écho
    echon & l: sw
    Mode échoMsg
    echon 'sts ='
    Question d'écho
    echon & l: sts. ''. (& l: et? '': 'non')
    Mode échoMsg
    echon 'expandtab'
  enfin
    echohl Aucun
  endtry
fonction finale
trop de php
la source
3
Merci pour le script! Il fait plus que ce que j'ai demandé - je pense que je préférerais ne pas utiliser expandtab - mais je peux facilement le personnaliser à mon goût. Vous m'avez donné un petit cours accéléré sur Vimscript, je vous en suis donc très reconnaissant. La prime de 100 points est à vous!
nelstrom
9

C'est ma première tentative d'écriture de VimScript, mais voici:

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

Si je mets cela dans mon fichier .vimrc, je peux l'appeler en exécutant :call Stab(X), où X est la largeur de tabulation souhaitée. C'est une solution adéquate pour le moment, mais si quelqu'un peut suggérer un moyen de faciliter l'appel, je vous en serais reconnaissant.

J'ai également créé une fonction qui résume rapidement les paramètres actuels, que j'ai mappés à ctrl-Tab:

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

Eh bien, j'ai mis une prime de 100 points pour cette réponse, et maintenant je l'ai à moitié résolue moi-même. Je ne sais pas si je peux accepter ma propre réponse ...

Nelstrom
la source
+1 ouais, mais si c'est ce que vous voulez vraiment, c'est toujours une bonne réponse.
DaveParillo
2
Vous voudrez probablement utiliser let & l: shiftwidth, etc. pour définir les versions locales.
SystemParadox
7

Vous pouvez en mode édition utiliser également Ctrl-Tà tiret et Ctrl-Dà deindent au niveau suivant d'indentation fixé par shiftwidth, quels que soient les tabstop, softtabstopou les expandtabparamètres. Vim ajoutera / supprimera automatiquement des espaces ou des onglets pour vous amener à la colonne de droite.

Si vous utilisez ces commandes pour contrôler l'indentation au lieu de Tab/, Backspacevous n'avez pas à vous soucier de l'adéquation de tous ces paramètres d'onglet et d'atteindre toujours le niveau d'indentation correct.

qc
la source
3

Si expandtabest défini, alors (comme trop de php le souligne), softtabstopdevient redondant. La seule raison pour laquelle vous pourriez définir shiftwidthdifféremment tabstopserait de répondre à une habitude étrange; par exemple, vous utilisez des retraits de quatre espaces, mais vous préférez tabinsérer huit espaces.

Si expandtabn'est pas défini, les choses deviennent plus floues. Si vous voulez que votre code ait la même apparence dans catles éditeurs with et non-vim que dans vim, il tabstopdoit toujours être défini sur 8; dans ce cas, vous définiriez softtabstopet les shiftwidthdeux à votre niveau de retrait préféré. Si vous préférez plutôt que chaque "onglet physique" dans le fichier représente un niveau de retrait, vous définiriez tabstopet shiftwidthà votre niveau de retrait préféré et le laisser softtabstopà zéro (le définir égal à tabstopest équivalent sauf que si vous le modifiez, tabstopil sera désynchronisé, tandis que zéro signifie simplement "ignorer ceci s'il vous plaît").

Hobbs
la source
3
Je pense que c'est faux car seulement avec softtabstopla bonne valeur, le retour arrière supprimera un retrait espacé comme s'il s'agissait d'un onglet. ce qui est un must pour une utilisation saine.
u0b34a0f6ae
2

Votre compréhension de softtabstopet expandtabest erronée - donc l' staboption que vous suggérez ne serait pas très utile.

expandtabest pour quand vous voulez utiliser des espaces au lieu des tabulations pour tout . Si vous définissez expandtab, Vim ignore l' softtabstopoption et utilise tabstopet shiftwidthpour calculer le nombre d'espaces à insérer.

softtabstopest uniquement pour lorsque vous souhaitez utiliser un mélange de tabulations et d'espaces, vous permettant de mettre en retrait avec un contrôle fin (2 ou 4 espaces), tout en gardant la largeur de tabulation à une valeur plus élevée (généralement 8) afin que le texte apparaisse dans les autres applications . La configuration softtabstop=tabstopn'accomplit rien car Vim utilisera toujours des onglets pour l'indentation.

Mise à jour: comme kaizer.se l' a souligné, si vous utilisez expandtab, vous devez toujours définir softtabstopsi vous voulez que Vim recule plusieurs espaces comme s'il s'agissait d' un onglet.

trop de php
la source
Bien que vous ayez raison tabstopet que vous softtabstopdeveniez une variable de trop quand elle extpandtabest définie, je pense que vous vous trompez sur la priorité. Essayez-le simplement: réglez ts=8 sts=4 etet appuyez sur l'onglet; le curseur sera dans la colonne cinq, et quatre espaces seront insérés, comme si vous aviez défini ts=4 sts=0 et.
hobbs
5
Je pense que c'est faux car seulement avec softtabstopla bonne valeur, le retour arrière supprimera un retrait espacé comme s'il s'agissait d'un onglet. ce qui est un must pour une utilisation saine.
u0b34a0f6ae
2

Modifiez-vous vos paramètres d'espace blanc si souvent que vous avez vraiment besoin d'une fonction pour gérer cela? Si vous jouez beaucoup avec tabstop et que vous définissez également expandtab, vous allez probablement avoir un désordre au fil du temps lorsque vous modifiez des fichiers avec des valeurs différentes transmises stab. Aujourd'hui j'utilise :call stab (4), demain c'est :call stab (2)et la semaine dernière c'était :call stab (8). On dirait que même si vous l'écrivez, vous cesserez bientôt de l'utiliser.

Si vous prévoyez de toujours transmettre la même valeur à stab, pourquoi ne pas simplement modifier vos paramètres globaux? Dans vim:

:e $MYVIMRC

et ajoutez ce qui suit:

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

C'est ainsi que mon .vimrc est configuré.

DaveParillo
la source
1

Une option utile est de softtabstop=-1le définir sur la valeur shiftwidth.
Vous pouvez également régler shiftwidthsur 0, auquel cas la tabstopvaleur sera utilisée.

pauloue
la source