Tab Vs Space-Einstellungen in Vim

87

Vim ist sehr zuvorkommend, wenn es um Tab Vs. Raumpräferenzen. Soweit ich weiß, gibt die tabstopEinstellung die Breite eines Tabulatorzeichens an. Die shiftwidthEinstellung gibt an, wie viele Spalten bei Verwendung der Befehle <<und inkrementiert / dekrementiert >>werden sollen, während die softtabstopEinstellung die Anzahl der Leerzeichen beeinflusst, die beim Drücken der TabTaste im Einfügemodus eingefügt werden sollen. Wenn diese expandtabOption aktiviert ist, fügt die Tabulatortaste die softtabstopAnzahl der Leerzeichen ein. Während bei expandtabausgeschaltetem Gerät durch Drücken der TabTaste eine möglichst geringe Anzahl von Tabulatortasten + Leerzeichen eingefügt wird softtabstop. (Bitte korrigiere mich wenn ich falsch liege.)

Dieser letzte Punkt lässt mich fragen: Gibt es einen praktischen Fall, in dem Sie nicht wollen würden shiftwidth == tabstop && tabstop == softtabstop? Mir fällt keiner ein. Für mich wäre es am bequemsten, wenn ich alle drei in einer einzigen Aufgabe auf den gleichen Wert setzen könnte. zB anrufen:

:set stab=4

Das wäre gleichbedeutend mit Laufen:

:set tabstop=4 softtabstop=4 shiftwidth=4 

Kann jemand vorschlagen, wie dies getan werden könnte?


AKTUALISIEREN

Vielen Dank für die bisherigen Antworten von zu viel PHP , Hobbs und kaiser.se . Anstatt auf jede Frage einzeln zu antworten, aktualisiere ich die Frage hier.

Softtabstop bei ausgeschaltetem expandtab

Ich habe oben gesagt, dass bei ausgeschaltetem expandtab durch Drücken der Tabulatortaste die kleinstmögliche Anzahl von Tabulatortasten + Leerzeichen eingefügt wird, die übereinstimmen softtabstop. Ich stehe dazu, aber ich denke, ich muss erklären, was ich meinte. Ich werde dies anhand einiger Beispiele versuchen. Führen :set listSie den Vorgang aus , damit Sie Tabulatorzeichen sehen können.

tabstop=4 softtabstop=2 shiftwidth=4 noexpandtab

Im Einfügemodus werden durch Drücken der Tabulatortaste 2 Leerzeichen eingefügt. Drücken Sie die Tabulatortaste ein zweites Mal, und anstatt zwei weitere Leerzeichen (für insgesamt 4 Leerzeichen) einzufügen, werden die vorherigen 2 Leerzeichen durch ein einzelnes Tabulatorzeichen ersetzt. Tabstop ist auf 4 gesetzt, sodass ein einzelnes Tabulatorzeichen die gleiche Breite wie 4 Leerzeichen hat.

tabstop=4 softtabstop=6 shiftwidth=4 noexpandtab

Im Einfügemodus werden durch Drücken der Tabulatortaste 1 Tabulatorzeichen plus 2 Leerzeichen eingefügt. Das Tabulatorzeichen hat eine Breite von 4, die Gesamtbreite beträgt also 6, und dies wird mit 3 Zeichen erreicht. Durch ein zweites Drücken der Tabulatortaste werden zwei Tabulatorzeichen eingefügt und die beiden zuvor eingefügten Leerzeichen entfernt. Die Gesamtbreite beträgt 12, und dies wird mit 3 Zeichen erreicht.

In beiden Beispielen fügt Vim die minimal mögliche Anzahl von Tabulator- und Leerzeichen ein, die mit Softtabstop übereinstimmt.

Wenn ich mit ausgeschaltetem expandtab arbeite, kann ich mir nicht vorstellen, dass ich die zusätzliche granulare Steuerung möchte, die erreicht werden kann, indem softtabstop auf einen anderen Wert als tabstop gesetzt wird. Es wäre immer noch nützlich sein , für mich in der Lage sein zu setzen tabstop, softtabstopund shiftwidthauf den gleichen Wert mit einem einzigen Befehl.

Macht expandtab softtabstop überflüssig?

tabstop=4 softtabstop=0 shiftwidth=4 expandtab

Im Einfügemodus werden durch Drücken der Tabulatortaste 4 Leerzeichen eingefügt. Durch Drücken der Löschtaste wird ein einzelnes Leerzeichen gelöscht. Sie müssen also viermal die Rücktaste drücken, wenn Sie versehentlich die Tabulatortaste drücken.

tabstop=4 softtabstop=4 shiftwidth=4 expandtab

Im Einfügemodus werden durch Drücken der Tabulatortaste 4 Leerzeichen eingefügt. Durch Drücken der Rücktaste werden 4 Leerzeichen gelöscht.

Wenn ich mit expandtabeingeschaltet arbeite , würde ich es vorziehen, wenn die Löschtaste die gleiche Menge an Leerzeichen entfernt, die die Tabulatortaste einfügt. Also in diesem Fall, auch, ich glaube , dass es nützlich wäre , in der Lage sein den gleichen Wert zuweisen tabstop, softtabstopund shiftwidthgleichzeitig.

Eine Verknüpfung wäre immer noch nützlich

Es ist großartig, dass Vim so viel Flexibilität bietet, aber ich kann mir nicht vorstellen, dass ich es brauche. Ich möchte nur die Breite einer Registerkarte auswählen können und ob es sich um eine "harte" Registerkarte (mit einem Tabulatorzeichen) oder eine "weiche" Registerkarte (bestehend aus Leerzeichen) handelt. Das Umschalten zwischen harten und weichen Registerkarten ist einfach genug ( :set expandtab!), aber ich wünschte, es wäre einfacher, die Breite der Registerkarten festzulegen, ohne mit 3 verschiedenen Parametern herumspielen zu müssen.

Mein vorgeschlagener Vorschlag für so etwas :set stab=4klingt für mich immer noch gut.

Nelstrom
quelle
Es scheint, als hätten Sie hier zwei verschiedene Fragen. Vielleicht sollten Sie Ihre Frage in zwei Teile teilen.
Greg Hewgill
Du hast recht! Ich habe die zweite Frage in ein eigenes Thema verschoben.
Nelstrom
1
Dies scheint eher eine RFE als eine Frage zu sein. Als solches sollten Sie wahrscheinlich der VIM-Community vorschlagen: vim.org/community.php - oder einfach einen Patch schreiben. Abgesehen davon verfügt VIM über eine umfangreiche Makrofunktion, mit der Sie neue Vorgänge definieren können. Daher ist es sehr wahrscheinlich, dass Sie einfach ein Makro erstellen können, das die gewünschten Funktionen ausführt.
kdgregory
@nelstrom In Bezug auf Ihre Frage verwendet Vims is there a practical case where you wouldn't want shiftwidth == tabstop && tabstop == softtabstop?eigener Quellcode set shiftwidth=4 tabstop=8 noexpandtab. Ja, man möchte normalerweise shiftwidth == softtabstop, aber das ist unabhängig davon, welchen Wert es tabstophat.
Jamessan

Antworten:

56

Das Erstellen einer stabOption in Vim selbst wäre nicht einfach, aber ich habe diesen Befehl / diese Funktion entwickelt, die Sie in Ihre .vimrc(oder eine Plugin-Datei, wenn Sie sehr gut organisiert sind) einfügen können. Verwenden :StabSie und Sie werden aufgefordert, eine Einrückungsstufe einzugeben und zu entscheiden, ob diese verwendet werden soll oder nicht expandtab. Wenn Sie die Eingabetaste drücken, ohne eine neue Einrückungsstufe zu erhalten, werden nur die aktuellen Einstellungen gedruckt.

"Fügen Sie all dies in Ihre .vimrc- oder Plugin-Datei ein
Befehl! -nargs = * Stab call Stab ()
Funktion! Stechen()
  l: tabstop = 1 * Eingabe ('set shiftwidth =')

  wenn l: tabstop> 0
    "wollen wir auch expandtab?
    Lassen Sie l: expandtab = bestätigen ('expandtab setzen?', "& Ja \ n & Nein \ n & Abbrechen")
    if l: expandtab == 3
      "abbrechen?
      Rückkehr
    endif

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

    if l: expandtab == 1
      setlocal expandtab
    sonst
      setlocal noexpandtab
    endif
  endif

  "Zeigen Sie die ausgewählten Optionen an
  Versuchen
    echohl ModeMsg
    echon 'set tabstop ='
    echohl Frage
    echon & l: ts
    echohl ModeMsg
    echon 'shiftwidth ='
    echohl Frage
    echon & l: sw
    echohl ModeMsg
    echon 'sts ='
    echohl Frage
    echon & l: sts. ''. (& l: et? '': 'no')
    echohl ModeMsg
    echon 'expandtab'
  endlich
    echohl Keine
  endtry
Endfunktion
zu viel php
quelle
3
Danke für das Skript! Es macht mehr als ich verlangt habe - ich denke, ich würde es vorziehen, expandtab nicht zu verwenden -, aber ich kann es leicht nach meinen Wünschen anpassen. Sie haben mir einen kleinen Crashkurs in Vimscript zur Verfügung gestellt, deshalb bin ich sehr dankbar. Das 100-Punkte-Kopfgeld gehört dir!
Nelstrom
9

Dies ist mein erster Versuch, VimScript zu schreiben, aber hier ist:

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

Wenn ich dies in meine .vimrc-Datei einfüge, kann ich es durch Ausführen aufrufen :call Stab(X), wobei X die gewünschte Registerkartenbreite ist. Dies ist vorerst eine adäquate Lösung, aber wenn jemand einen Weg vorschlagen kann, um das Anrufen zu vereinfachen, wäre ich dankbar.

Ich habe auch eine Funktion erstellt, die die aktuellen Einstellungen, die ich Strg-Tab zugeordnet habe, schnell zusammenfasst:

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

Nun, ich habe für diese Antwort ein Kopfgeld von 100 Punkten gezahlt, und jetzt habe ich es zur Hälfte selbst gelöst. Ich bin mir nicht sicher, ob ich meine eigene Antwort akzeptieren kann ...

Nelstrom
quelle
+1 ja, aber wenn es das ist, was du wirklich willst, ist es immer noch eine gute Antwort.
DaveParillo
2
Sie sollten wahrscheinlich let & l: shiftwidth usw. verwenden, um die lokalen Versionen festzulegen.
SystemParadox
7

Sie können im Bearbeitungsmodus auch verwenden Ctrl-Teinrücken und Ctrl-Dzu deindent auf die nächste Einzugsebene als Satz durch shiftwidth, unabhängig von den tabstop, softtabstopoder expandtabEinstellungen. Vim fügt automatisch Leerzeichen oder Tabulatoren hinzu / entfernt diese, um Sie zur rechten Spalte zu bringen.

Wenn Sie diese Befehle verwenden, um die Einrückung zu steuern, anstatt Tab/ müssen BackspaceSie sich nicht darum kümmern, dass alle diese Registerkarteneinstellungen zusammenpassen, und immer die richtige Einrückungsstufe erreichen.

etw
quelle
3

Wenn expandtabdann eingestellt ist (wie zu viel PHP hervorhebt), softtabstopwird redundant. Der einzige Grund, warum Sie sich shiftwidthanders einstellen könnten, tabstopwäre, auf eine seltsame Angewohnheit einzugehen. Zum Beispiel verwenden Sie Einrückungen mit vier Leerzeichen, aber Sie bevorzugentab acht Leerzeichen einfügen.

Wenn expandtabnicht festgelegt, werden die Dinge unschärfer. Wenn Sie möchten, dass Ihr Code in catund mit Nicht-Vim-Editoren genauso aussieht wie in Vim, tabstopsollten Sie immer auf 8 setzen. in diesem Fall würden Sie gesetzt softtabstopund shiftwidthbeide auf Ihre bevorzugte Einzugsebene. Wenn Sie stattdessen bevorzugen, dass jede "physische Registerkarte" in der Datei eine Einrückungsstufe darstellt, würden Sie tabstopund shiftwidthauf Ihre bevorzugte Einrückungsstufe setzen und softtabstopbei Null belassen (die Einstellung gleich tabstopist äquivalent, außer dass tabstopsie nicht mehr synchron ist, wenn Sie sie ändern). während Null nur "bitte ignorieren" bedeutet).

Hobbs
quelle
3
Ich denke, das ist falsch, weil nur mit softtabstopdem richtigen Wert die Rücktaste einen beabstandeten Einzug löscht, als wäre es ein Tabulator. Das ist ein Muss für den gesunden Gebrauch.
u0b34a0f6ae
2

Ihr Verständnis von softtabstopund expandtabist falsch - daher wäre die von stabIhnen vorgeschlagene Option nicht sehr nützlich.

expandtabist für den Fall gedacht, dass Sie für alles Leerzeichen anstelle von Tabulatoren verwenden möchten . Wenn Sie festlegen expandtab, ignoriert Vim die softtabstopOption und verwendet tabstopund shiftwidthberechnet, wie viele Leerzeichen eingefügt werden sollen.

softtabstopDies ist nur dann der Fall, wenn Sie eine Mischung aus Tabulatoren und Leerzeichen verwenden möchten , sodass Sie mit der Feinsteuerung (2 oder 4 Leerzeichen) einrücken können, während die Registerkartenbreite auf einem höheren Wert (normalerweise 8) bleibt, sodass Text in den anderen Anwendungen angezeigt wird . Mit der Einstellung softtabstop=tabstopwird nichts erreicht, da Vim zum Einrücken immer Registerkarten verwendet.

Update: Wie kaizer.se hervorgehoben hat, müssen Sie bei Verwendung expandtabimmer noch festlegen, softtabstopob Vim mehrere Leerzeichen zurücksetzen soll , als wären sie eine Registerkarte.

zu viel php
quelle
Während Sie Recht haben tabstopund softtabstopeine Variable zu viele werden, wenn sie extpandtabgesetzt ist, denke ich, dass Sie in der Priorität falsch liegen. Probieren Sie es einfach aus: Setzen Sie ts=8 sts=4 etund drücken Sie die Tabulatortaste. Der Cursor befindet sich in Spalte fünf, und es werden vier Leerzeichen eingefügt, als hätten Sie gesetzt ts=4 sts=0 et.
Hobbs
5
Ich denke, das ist falsch, weil nur mit softtabstopdem richtigen Wert die Rücktaste einen beabstandeten Einzug löscht, als wäre es ein Tabulator. Das ist ein Muss für den gesunden Gebrauch.
u0b34a0f6ae
2

Ändern Sie Ihre Leerraumeinstellungen so oft, dass Sie wirklich eine Funktion benötigen, um dies zu verwalten? Wenn Sie viel mit Tabstop herumspielen und auch expandtab einstellen, werden Sie wahrscheinlich im Laufe der Zeit ein Durcheinander haben, wenn Sie Dateien mit unterschiedlichen Werten ändern, die an übergeben werden stab. Heute benutze ich :call stab (4), morgen ist es :call stab (2)und letzte Woche war es :call stab (8). Klingt so, als würden Sie es bald nicht mehr verwenden, selbst wenn Sie es schreiben.

Wenn Sie immer den gleichen Wert zum Stechen übergeben möchten, bearbeiten Sie doch einfach Ihre globalen Einstellungen. In vim:

:e $MYVIMRC

und fügen Sie Folgendes hinzu:

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

So wird meine .vimrc eingerichtet.

DaveParillo
quelle
1

Eine nützliche Option ist softtabstop=-1, den Wert auf zu setzen shiftwidth.
Sie können auch shiftwidth0 setzen. In diesem Fall wird der tabstopWert verwendet.

Pauloue
quelle