Preferencje Tab Vs Space w Vimie

87

Vim jest bardzo przychylny, jeśli chodzi o kartę Vs. preferencje przestrzenne. Jak rozumiem, tabstopustawienie wskazuje szerokość znaku tabulacji. To shiftwidthustawienie określa, ile kolumn należy zwiększyć / zmniejszyć podczas używania poleceń <<i >>, podczas gdy softtabstopustawienie wpływa na ilość białych znaków, które mają być wstawione po naciśnięciu Tabklawisza w trybie wstawiania. Jeśli expandtabjest włączona, klawisz tabulacji wstawia softtabstopliczbę znaków spacji. Podczas gdy przy expandtabwyłączonym naciśnięciu Tabklawisza wstawia się najmniejszą możliwą liczbę pasujących znaków tabulacji + spacji softtabstop. (Proszę popraw mnie jeżeli się mylę.)

Ten ostatni punkt sprawia, że ​​zastanawiam się: czy istnieje praktyczny przypadek, w którym byś nie chciał shiftwidth == tabstop && tabstop == softtabstop? Nie mogę wymyślić żadnego. Jeśli o mnie chodzi, najwygodniej byłoby ustawić wszystkie 3 z nich na tę samą wartość w jednym przypisaniu. np. dzwoniąc:

:set stab=4

co byłoby równoznaczne z uruchomieniem:

:set tabstop=4 softtabstop=4 shiftwidth=4 

Czy ktoś może zasugerować, jak można to zrobić?


AKTUALIZACJA

Dzięki za odpowiedzi tak daleko od zbytniego php , Hobbs i kaiser.se . Zamiast odpowiadać każdemu indywidualnie, aktualizuję tutaj pytanie.

Softtabstop z wyłączoną kartą expandtab

Powiedziałem powyżej, że przy wyłączonej karcie expandtab, naciśnięcie klawisza Tab wstawia najmniejszą możliwą liczbę pasujących znaków tabulacji + spacji softtabstop. Trzymam się tego, ale myślę, że muszę wyjaśnić, co miałem na myśli. Spróbuję to zrobić na kilku przykładach. Aby kontynuować, biegnij :set list, aby zobaczyć znaki tabulacji.

tabstop=4 softtabstop=2 shiftwidth=4 noexpandtab

W trybie wstawiania naciśnięcie klawisza tabulacji powoduje wstawienie 2 znaków spacji. Naciśnij klawisz tabulatora po raz drugi i zamiast wstawiać dwa dodatkowe znaki spacji (łącznie 4 znaki spacji), zastępuje poprzednie 2 spacje pojedynczym znakiem tabulacji. Tabstop jest ustawiony na 4, więc pojedynczy znak tabulacji ma taką samą szerokość jak 4 spacje.

tabstop=4 softtabstop=6 shiftwidth=4 noexpandtab

W trybie wstawiania naciśnięcie klawisza tabulatora powoduje wstawienie 1 znaku tabulacji plus 2 spacje. Znak tabulatora ma szerokość 4, więc całkowita szerokość wynosi 6, a uzyskuje się to za pomocą 3 znaków. Naciśnięcie klawisza tabulatora po raz drugi wstawia dwa znaki tabulacji i usuwa dwie spacje, które zostały wcześniej wstawione. Całkowita szerokość wynosi 12 i można to osiągnąć za pomocą 3 znaków.

W obu tych przykładach Vim wstawia minimalną możliwą liczbę znaków tabulacji + spacji, które pasują do softtabstop.

Jeśli pracuję z wyłączoną kartą expandtab, nie wyobrażam sobie, że chcę dodatkowej kontroli szczegółowości, którą można osiągnąć, ustawiając softtabstop na inną wartość niż tabstop. Byłoby jeszcze być użyteczne dla mnie, aby móc ustawić tabstop, softtabstopi shiftwidthna tę samą wartość za pomocą jednego polecenia.

Czy expandtab sprawia, że ​​softtabstop jest zbędna?

tabstop=4 softtabstop=0 shiftwidth=4 expandtab

W trybie wstawiania naciśnięcie klawisza tabulatora powoduje wstawienie 4 spacji. Naciśnięcie klawisza Delete usuwa pojedynczą spację - więc musisz cofnąć się 4 razy, jeśli przypadkowo naciśniesz klawisz Tab.

tabstop=4 softtabstop=4 shiftwidth=4 expandtab

W trybie wstawiania naciśnięcie klawisza tabulatora powoduje wstawienie 4 spacji. Naciśnięcie klawisza Backspace usuwa 4 spacje.

Jeśli pracuję z expandtabwłączonym, wolałbym, aby klawisz delete usuwał taką samą ilość białych znaków, jak wstawiane klawisze tabulacji. Więc w tym przypadku, też czuję, że dobrze byłoby, aby móc przypisać tę samą wartość tabstop, softtabstopa shiftwidthrównocześnie.

Skrót byłby nadal przydatny

To wspaniałe, że Vim zapewnia tak dużą elastyczność, ale nie widzę, żebym tego potrzebował. Chcę tylko mieć możliwość wyboru szerokości tabulatora i tego, czy jest to tabulator „twardy” (przy użyciu znaku tabulacji), czy „miękki” (składający się ze spacji). Przełączanie między twardymi i miękkimi zakładkami jest dość łatwe (:set expandtab! ), ale chciałbym, aby ustawienie szerokości karty było prostsze, bez konieczności majstrowania przy 3 różnych parametrach.

Tak więc moja propozycja czegoś takiego :set stab=4nadal brzmi dla mnie dobrze.

nelstrom
źródło
Wygląda na to, że masz tutaj dwa różne pytania, być może powinieneś podzielić je na dwie części.
Greg Hewgill
Masz rację! Drugie pytanie przeniosłem na osobny temat.
nelstrom
1
To wydaje się raczej RFE niż pytaniem. W związku z tym prawdopodobnie powinieneś zaproponować społeczności VIM: vim.org/community.php - lub po prostu napisać łatkę. Poza tym VIM ma rozbudowaną funkcję makr, która pozwala definiować nowe operacje, więc jest bardzo prawdopodobne, że możesz po prostu utworzyć makro, które robi to, co chcesz.
kdgregory
@nelstrom W odniesieniu do twojego pytania is there a practical case where you wouldn't want shiftwidth == tabstop && tabstop == softtabstop?, własny kod źródłowy Vima używa set shiftwidth=4 tabstop=8 noexpandtab. Tak, zazwyczaj chce się shiftwidth == softtabstop, ale to niezależne od wartości tabstop.
jamessan

Odpowiedzi:

56

Tworzenie stabopcji w samym Vimie nie byłoby łatwe, ale przygotowałem to polecenie / funkcję, które możesz upuścić w swoim .vimrc(lub pliku wtyczki, jeśli jesteś super zorganizowany). Użyj, :Staba zostaniesz zapytany o poziom wcięcia i czy chcesz użyćexpandtab . Jeśli naciśniesz Enter bez nadawania mu nowego poziomu wcięcia, po prostu wydrukuje bieżące ustawienia.

"umieść to wszystko w swoim .vimrc lub pliku wtyczki
Komenda! -nargs = * Stab call Stab ()
funkcjonować! Zasztyletować()
  niech l: tabstop = 1 * input ('set shiftwidth =')

  jeśli l: tabstop> 0
    „czy chcemy również expandtab?
    let l: expandtab = confirm ('set expandtab?', "& Yes \ n & No \ n & Cancel")
    jeśli l: expandtab == 3
      " anulować?
      powrót
    endif

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

    jeśli l: expandtab == 1
      setlocal expandtab
    jeszcze
      setlocal noexpandtab
    endif
  endif

  ”pokaż wybrane opcje
  próbować
    echohl ModeMsg
    echon 'set tabstop ='
    echohl Pytanie
    echon & l: ts
    echohl ModeMsg
    echon 'shiftwidth ='
    echohl Pytanie
    echon & l: sw
    echohl ModeMsg
    echon 'sts ='
    echohl Pytanie
    echon & l: sts. ''. (& l: et? '': 'nie')
    echohl ModeMsg
    echon 'expandtab'
  Wreszcie
    echohl Brak
  koniec
funkcja końcowa
za dużo php
źródło
3
Dzięki za scenariusz! Robi więcej, niż prosiłem - myślę, że wolałbym trzymać z daleka kartę rozwijania - ale mogę łatwo dostosować ją do własnych upodobań. Zapewniłeś mi krótki kurs obsługi Vimscript, więc jestem bardzo wdzięczny. Nagroda za 100 punktów jest Twoja!
nelstrom
9

To moja pierwsza próba napisania VimScript, ale oto:

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

Jeśli umieszczę to w swoim pliku .vimrc, mogę to wywołać, uruchamiając :call Stab(X), gdzie X jest żądaną szerokością karty. To na razie adekwatne rozwiązanie, ale jeśli ktoś może zasugerować sposób na ułatwienie rozmowy, byłbym wdzięczny.

Stworzyłem także funkcję, która szybko podsumowuje aktualne ustawienia, które zmapowałem na ctrl-Tab:

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

Cóż, postawiłem 100 punktów bounty za tę odpowiedź, a teraz w połowie rozwiązałem to sam. Nie jestem pewien, czy mogę zaakceptować własną odpowiedź ...

nelstrom
źródło
+1 tak, ale jeśli tego naprawdę chcesz, nadal jest to dobra odpowiedź.
DaveParillo
2
Prawdopodobnie będziesz chciał użyć let & l: shiftwidth itp., Aby ustawić wersje lokalne.
SystemParadox
7

W trybie edycji można również użyć Ctrl-Tdo Ctrl-Dwcinania i usuwania wcięć do następnego poziomu wcięcia, zgodnie z ustawieniami shiftwidth, niezależnie od ustawień tabstop, softtabstoplub expandtab. Vim automatycznie doda / usunie spacje lub tabulatory, aby przenieść cię do prawej kolumny.

Jeśli używasz tych poleceń do kontrolowania wcięć zamiast Tab/ Backspace, nie musisz się martwić, że wszystkie te ustawienia zakładek pasują do siebie i zawsze uzyskujesz właściwy poziom wcięcia.

sth
źródło
3

Jeśli expandtabjest ustawione (jak wskazuje zbyt wiele php), softtabstopstaje się zbędne. Jedynym powodem, dla którego mógłbyś ustawić shiftwidthinaczej, tabstopbyłoby zaspokojenie dziwnego nawyku; na przykład używasz wcięć czterech spacji, ale wolisz tabwstawić osiem spacji.

Jeśli nie expandtabjest ustawiony, sprawy stają się bardziej niejasne. Jeśli chcesz, aby Twój kod wyglądał tak samo w catedytorach zi non-vim, jak w vimie, to tabstopzawsze powinien być ustawiony na 8; w tym przypadku należy ustawić softtabstopi shiftwidthoba na preferowany poziom wcięcia. Jeśli zamiast tego wolisz, aby każda „fizyczna zakładka” w pliku reprezentowała jeden poziom wcięcia, możesz ustawić tabstopi shiftwidthna preferowany poziom wcięcia i pozostawić softtabstopzero (ustawienie równej wartości tabstopjest równoważne, z tą różnicą, że jeśli zmienisz tabstop, zostanie zsynchronizowany, podczas gdy zero oznacza po prostu „ignoruj ​​to, proszę”).

Hobbs
źródło
3
Myślę, że jest to błędne, ponieważ tylko przy softtabstopustawieniu na właściwą wartość, cofnięcie usunie wcięcie z odstępami, jakby to była tabulacja. co jest koniecznością dla rozsądnego użytku.
u0b34a0f6ae
2

Twoje zrozumienie softtabstopi expandtabjest błędne - więc stabopcja, którą sugerujesz, nie byłaby zbyt przydatna.

expandtabjest, gdy chcesz używać spacji zamiast zakładki do wszystkiego . Jeśli ustawisz expandtab, Vim ignoruje tę softtabstopopcję i używa tabstopi shiftwidthdo obliczenia, ile spacji ma wstawić.

softtabstopjest tylko wtedy, gdy chcesz użyć kombinacji tabulatorów i spacji, pozwalając ci na wcięcie z precyzyjną kontrolą (2 lub 4 spacje), przy jednoczesnym zachowaniu większej szerokości tabulatora (zwykle 8), aby tekst pojawił się w innych aplikacjach . Ustawienie softtabstop=tabstopnic nie daje, ponieważ Vim zawsze będzie używał tabulatorów do wcięć.

Aktualizacja: Jak wskazał kaizer.se , jeśli używasz expandtab, nadal musisz ustawić, softtabstopczy chcesz, aby Vim cofał wiele spacji, tak jakby były one tabulatorami.

za dużo php
źródło
Chociaż masz rację tabstopi softtabstopstajesz się o jedną zmienną za dużo, gdy extpandtabjest ustawiona, myślę, że mylisz się co do priorytetu. Po prostu spróbuj: ustaw ts=8 sts=4 eti naciśnij tab; kursor znajdzie się w piątej kolumnie i zostaną wstawione cztery spacje, tak jak w przypadku ustawienia ts=4 sts=0 et.
hobbs
5
Myślę, że jest to błędne, ponieważ tylko przy softtabstopustawieniu na właściwą wartość, cofnięcie usunie wcięcie z odstępami, jakby to była tabulacja. co jest koniecznością dla rozsądnego użytku.
u0b34a0f6ae
2

Czy tak często zmieniasz ustawienia białych znaków, że naprawdę potrzebujesz funkcji, aby tym zarządzać? Jeśli często bawisz się tabstopem, a także ustawiasz expandtab, prawdopodobnie z czasem będziesz mieć bałagan, gdy będziesz zmieniać pliki z różnymi wartościami przekazywanymi do stab. Dziś używam :call stab (4), jutro :call stab (2)i w zeszłym tygodniu :call stab (8). Wygląda na to, że nawet jeśli to napiszesz, wkrótce przestaniesz go używać.

Jeśli planujesz zawsze przekazywać tę samą wartość do dźgnięcia, dlaczego nie edytować po prostu ustawień globalnych? In vim:

:e $MYVIMRC

i dodaj:

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

Oto jak jest konfigurowany mój plik .vimrc.

DaveParillo
źródło
1

Jedną z przydatnych opcji jest softtabstop=-1ustawienie wartości shiftwidth.
Możesz również ustawić shiftwidthna 0, w którym to przypadku tabstopwartość zostanie użyta.

Pauloue
źródło