Вкладка против настроек пространства в Vim

87

Vim очень любезен, когда дело касается вкладок Vs. космические предпочтения. Насколько я понимаю, tabstopнастройка указывает ширину символа табуляции. В shiftwidthпараметр определяет , сколько столбцов для увеличения / уменьшения при использовании <<и >>команды, в то время как softtabstopнастройка влияет на количество пробелов , которые будут вставлены при нажатии Tabклавиши в режиме вставки. Если expandtabон включен, клавиша табуляции вставляет softtabstopколичество пробелов. В то время как в expandtabвыключенном состоянии нажатие Tabклавиши вставляет минимально возможное количество совпадающих символов табуляции + пробела softtabstop. (Пожалуйста, поправьте меня, если я ошибаюсь.)

Этот последний момент заставляет меня задуматься: есть ли практический случай, в котором вы бы не хотели shiftwidth == tabstop && tabstop == softtabstop? Я не могу вспомнить ни одного. Насколько мне известно, было бы наиболее удобно, если бы я мог установить для всех трех из них одно и то же значение в одном назначении. например, звонок:

:set stab=4

что было бы эквивалентно запуску:

:set tabstop=4 softtabstop=4 shiftwidth=4 

Кто-нибудь может подсказать, как это можно сделать?


ОБНОВИТЬ

Спасибо за ответы от слишком большого количества php , hobbs и kaiser.se . Вместо того, чтобы отвечать каждому по отдельности, я обновляю вопрос здесь.

Softtabstop с выключенным expandtab

Выше я сказал, что при выключенном expandtab нажатие клавиши Tab вставляет минимально возможное количество совпадающих символов табуляции + пробела softtabstop. Я поддерживаю это, но думаю, мне нужно объяснить, что я имел в виду. Я попытаюсь сделать это на нескольких примерах. Чтобы продолжить, запустите :set listтак, чтобы вы могли видеть символы табуляции.

tabstop=4 softtabstop=2 shiftwidth=4 noexpandtab

В режиме вставки нажатие клавиши табуляции вставляет 2 символа пробела. Нажмите клавишу табуляции второй раз, и вместо того, чтобы вставить еще два символа пробела (всего 4 символа пробела), он заменяет предыдущие 2 пробела одним символом табуляции. Tabstop имеет значение 4, поэтому один символ табуляции имеет такую ​​же ширину, как 4 пробела.

tabstop=4 softtabstop=6 shiftwidth=4 noexpandtab

В режиме вставки нажатие клавиши табуляции вставляет 1 символ табуляции плюс 2 пробела. Символ табуляции имеет ширину 4, поэтому общая ширина равна 6, и это достигается с помощью 3 символов. Повторное нажатие клавиши табуляции вставляет два символа табуляции и удаляет два пробела, которые были вставлены ранее. Общая ширина составляет 12, и это достигается с помощью 3 символов.

В обоих этих примерах Vim вставляет минимально возможное количество символов табуляции + пробела, которое соответствует softtabstop.

Если я работаю с выключенным expandtab, я не вижу, что мне нужен дополнительный детальный контроль, которого можно достичь, установив для softtabstop значение, отличное от tabstop. Это все равно будет полезно для меня , чтобы быть в состоянии установить tabstop, softtabstopи shiftwidthк тому же значению с помощью одной команды.

Делает ли expandtab избыточным softtabstop?

tabstop=4 softtabstop=0 shiftwidth=4 expandtab

В режиме вставки нажатие клавиши табуляции вставляет 4 пробела. Нажатие клавиши удаления удаляет один пробел, поэтому вам придется вернуться назад 4 раза, если вы случайно нажмете клавишу табуляции.

tabstop=4 softtabstop=4 shiftwidth=4 expandtab

В режиме вставки нажатие клавиши табуляции вставляет 4 пробела. Нажатие клавиши Backspace удаляет 4 пробела.

Если я работаю с expandtabвключенным, я бы предпочел, чтобы клавиша удаления удаляла то же количество пробелов, что и вставка клавиши табуляции. Так что в этом случае тоже, я считаю , что было бы полезно , чтобы иметь возможность присвоить одинаковое значение tabstop, softtabstopи shiftwidthодновременно.

Ярлык все равно был бы полезен

Замечательно, что Vim обеспечивает такую ​​гибкость, но я не думаю, что мне это нужно. Я просто хочу иметь возможность выбирать ширину вкладки и то, является ли она «жесткой» вкладкой (с использованием символа табуляции) или «мягкой» вкладкой (состоящей из пробелов). Переключение между жесткой и мягкой вкладками достаточно просто ( :set expandtab!), но мне хотелось бы, чтобы было проще установить ширину вкладки, без необходимости возиться с 3 различными параметрами.

Так что предложенное мной предложение по поводу чего-то вроде :set stab=4меня все еще звучит хорошо.

Nelstrom
источник
Похоже, что у вас здесь два разных вопроса, возможно, вам следует разделить свой вопрос на два.
Грег Хьюгилл,
Ты прав! Я переместил второй вопрос в отдельную тему.
nelstrom
1
Это похоже на RFE, а не на вопрос. Таким образом, вам, вероятно, следует предложить сообществу VIM: vim.org/community.php или просто написать патч. Помимо этого, VIM имеет обширную возможность макроса, которая позволяет вам определять новые операции, поэтому весьма вероятно, что вы могли бы просто создать макрос, который делает то, что вы хотите.
kdgregory
@nelstrom Что касается вашего вопроса is there a practical case where you wouldn't want shiftwidth == tabstop && tabstop == softtabstop?, собственный исходный код Vim использует set shiftwidth=4 tabstop=8 noexpandtab. Да, обычно хочется shiftwidth == softtabstop, но это не зависит от ценности tabstop.
jamessan

Ответы:

56

Создать stabпараметр в самом Vim будет непросто, но я разработал эту команду / функцию, которую вы можете .vimrcдобавить в свой (или в файл плагина, если вы суперорганизованы). Используйте, :Stabи вам будет предложено указать уровень отступа и указать, следует ли его использовать expandtab. Если вы нажмете Enter, не задав новый уровень отступа, он просто распечатает текущие настройки.

"поместите все это в свой .vimrc или файл плагина
команда! -nargs = * Колющий вызов Stab ()
функция! Удар ()
  пусть l: tabstop = 1 * input ('set shiftwidth =')

  если l: tabstop> 0
    "мы тоже хотим expandtab?
    let l: expandtab = confirm ('set expandtab?', «& Да \ n & Нет \ n & Отменить»)
    если l: expandtab == 3
      "прервать?
      возвращение
    endif

    пусть & l: sts = l: tabstop
    пусть & l: ts = l: tabstop
    пусть & l: sw = l: tabstop

    если l: expandtab == 1
      setlocal expandtab
    еще
      setlocal noexpandtab
    endif
  endif

  "показать выбранные параметры
  пытаться
    echohl ModeMsg
    echon 'установить tabstop ='
    echohl Вопрос
    echon & l: ts
    echohl ModeMsg
    echon 'shiftwidth ='
    echohl Вопрос
    echon & l: sw
    echohl ModeMsg
    echon 'sts ='
    echohl Вопрос
    эхон и л: ст. ''. (& l: et? '': 'нет')
    echohl ModeMsg
    echon 'expandtab'
  наконец-то
    echohl Нет
  Endtry
конечная функция
слишком много php
источник
3
Спасибо за сценарий! Он делает больше, чем я просил - думаю, я бы предпочел не включать в него expandtab - но я могу легко настроить его по своему вкусу. Вы предоставили мне небольшой ускоренный курс по Vimscript, за что я очень благодарен. Награда в 100 баллов за вами!
nelstrom
9

Это моя первая попытка написать VimScript, но вот что:

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

Если я помещу это в свой файл .vimrc, я могу вызвать его, запустив :call Stab(X), где X - желаемая ширина табуляции. На данный момент это адекватное решение, но если кто-нибудь может предложить способ облегчить вызов, я был бы признателен.

Я также создал функцию, которая быстро суммирует текущие настройки, которые я сопоставил ctrl-Tab:

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

Что ж, я назначил награду в 100 баллов за этот ответ, и теперь я сам решил половину. Не уверен, что могу принять свой ответ ...

Nelstrom
источник
+1 да, но если это то, чего вы действительно хотите, это все равно хороший ответ.
DaveParillo
2
Вы, вероятно, захотите использовать let & l: shiftwidth и т. Д. Для установки локальных версий.
SystemParadox
7

В режиме редактирования вы также можете использовать Ctrl-Tдля отступа и Ctrl-Dдля перехода к следующему уровню отступа, установленному с помощью shiftwidth, независимо от настроек tabstop, softtabstopили expandtab. Vim автоматически добавит / удалит пробелы или табуляции, чтобы перейти в правый столбец.

Если вы используете эти команды для управления отступом вместо Tab/, Backspaceвам не нужно беспокоиться о том, что все эти настройки вкладки подходят друг другу, и всегда добираетесь до правильного уровня отступа.

что-то
источник
3

Если expandtabустановлено, то (как указывает слишком много php) softtabstopстановится избыточным. Единственная причина, по которой вы могли бы установить shiftwidthиное, - tabstopэто удовлетворить странную привычку; например, вы используете отступы из четырех пробелов, но предпочитаете tabвставлять восемь пробелов.

Если expandtabне установлено, то все становится нечетко. Если вы хотите, чтобы ваш код в catредакторах и без редакторов vim выглядел так же, как в vim, то tabstopвсегда следует устанавливать значение 8; в этом случае вы должны установить softtabstopи shiftwidthоба на желаемый уровень отступа. Если вместо этого вы предпочитаете, чтобы каждая «физическая вкладка» в файле представляла один уровень отступа, вы должны установить tabstopи shiftwidthна свой предпочтительный уровень отступа и оставить softtabstopравным нулю (установка этого значения tabstopэквивалентна, за исключением того, что если вы измените, tabstopон выйдет из синхронизации в то время как ноль просто означает «игнорируйте это, пожалуйста»).

Hobbs
источник
3
Я думаю, что это неправильно, потому что только при softtabstopустановке правильного значения Backspace удалит отступ, как если бы это была вкладка. что необходимо для разумного использования.
u0b34a0f6ae
2

Ваше понимание softtabstopи expandtabневерно, поэтому stabвариант, который вы предлагаете, не будет очень полезным.

expandtabпредназначен для случаев, когда вы хотите использовать пробелы вместо табуляции для всего . Если вы установили expandtab, Vim игнорирует эту softtabstopопцию и использует tabstopи, shiftwidthчтобы определить, сколько пробелов нужно вставить.

softtabstopпредназначен только для случаев, когда вы хотите использовать сочетание вкладок и пробелов, позволяя делать отступ с точным контролем (2 или 4 пробела), сохраняя при этом ширину табуляции на более высоком значении (обычно 8), чтобы текст отображался в других приложениях . Установка softtabstop=tabstopничего не дает, потому что Vim всегда будет использовать табуляцию для отступов.

Обновление: как указал kaizer.se , если вы используете expandtab, вам все равно нужно установить softtabstop, хотите ли вы, чтобы Vim возвращал несколько пробелов, как если бы они были вкладкой.

слишком много php
источник
Хотя вы правы tabstopи softtabstopстановитесь одной переменной слишком много, когда extpandtabона установлена, я думаю, что вы ошибаетесь в отношении приоритета. Просто попробуйте: установите ts=8 sts=4 etи нажмите вкладку; курсор будет в пятом столбце, и будут вставлены четыре пробела, как если бы вы установили ts=4 sts=0 et.
hobbs
5
Я думаю, что это неправильно, потому что только при softtabstopустановке правильного значения Backspace удалит отступ, как если бы это была вкладка. что необходимо для разумного использования.
u0b34a0f6ae
2

Вы так часто меняете настройки пустого пространства, что вам действительно нужна функция для управления этим? Если вы много возитесь с tabstop, а также устанавливаете expandtab, у вас, вероятно, со временем будет беспорядок, когда вы меняете файлы с разными значениями, переданными в stab. Сегодня пользуюсь :call stab (4), завтра уже :call stab (2)и на прошлой неделе было :call stab (8). Похоже, даже если вы напишете это, вы скоро перестанете им пользоваться.

Если вы планируете всегда передавать одно и то же значение в stab, почему бы просто не отредактировать глобальные настройки? В vim:

:e $MYVIMRC

и добавьте следующее:

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

Вот как настраивается мой .vimrc.

ДэйвПарилло
источник
1

Одна полезная опция - softtabstop=-1установить для него значение shiftwidth.
Вы также можете установить shiftwidthзначение 0, и в этом случае tabstopбудет использоваться значение.

Pauloue
источник