Настройка отступов в VIM

    Процесс смены Komodo IDE на VIM я начал с изучения всевозможных туториалов и хау ту, однако, что удивительно, ни в одном из них мне не удалось встретить человеческого описания процесса настройки отступов. В одних предлагали регулировать ширину отступа с помощью опции tabstop, в других — с помощью softtabstop, в третьих — выставлять и то и другое и shiftwidth в придачу. После нескольких часов экспериментов с настройками я понял, что единственный способ не только заставить все работать, но и понять, почему оно работает — читать документацию. Своими «открытиями» я и хочу с вами поделиться.

    Начну с описания опций, которые могут использоваться при настройке отступов.

    tabstop (по умолчанию 8) — количество пробелов, которыми символ табуляции отображается в тексте. Оказывает влияние как на уже существующие табуляции, так и на новые. В случае изменения значения, «на лету» применяется к тексту.

    softtabstop (0) — количество пробелов, которыми символ табуляции отображается при добавлении. Несмотря на то, что при нажатии на Tab вы получите ожидаемый результат (добавляется новый символ табуляции), фактически в отступе могут использоваться как табуляция так и пробелы. Например, при установленных tabstop равной 8 и softtabstop равной 4, троекратное нажатие Tab приведет к добавлению отступа шириной 12 пробелов, однако сформирован он будет из одного символа табуляции и 4 пробелов.

    shiftwidth (8) — по умолчанию используется для регулирование ширины отступов в пробелах, добавляемых командами >> и <<. Если значение опции не равно tabstop, как и в случае с softtabstop, отступ может состоять как из символов табуляций так и из пробелов. При включении опции — smarttab, оказывает дополнительное влияние.

    smarttab (выключена) — в случае включения этой опции, нажатие Tab в начале строки (если быть точнее, до первого непробельного символа в строке) приведет к добавлению отступа, ширина которого соответствует shiftwidth (независимо от значений в tabstop и softtabstop). Нажатие на Backspace удалит отступ, а не только один символ, что очень полезно при включенной expandtab. Напомню: опция оказывает влияние только на отступы в начале строки, в остальных местах используются значения из tabstop и softtabstop.

    expandtab (выключена) — в режиме вставки заменяет символ табуляции на соответствующее количество пробелов. Так же влияет на отступы, добавляемые командами >> и <<.

    Вооружившись полученными знаниями, очень просто настроить требуемое поведение отступов. Популярная практика у разработчиков: пробелы вместо табуляции, ширина отступа — 4 пробела. Настройка в данном случае будет выглядеть следующим образом:
    set tabstop=4
    set shiftwidth=4
    set smarttab
    set expandtab

    На десерт я оставил описание двух life changing опций для тех, кто использует VIM в качестве редактора для разработки:

    autoindent (выключена) — копирует отступы с текущей строки при добавлении новой.

    smartindent (выключена) — делает то же, что и autoindent плюс автоматически выставляет отступы в «нужных» местах. В частности, отступ ставится после строки, которая заканчивается символом {, перед строкой, которая заканчивается символом }, удаляется перед символом #, если он следует первым в строке и т.д. (подробнее help 'smartindent').

    Вот, собственно, и все.

    Мой конфигурационный файл в части отступов выглядит следующим образом:
    set tabstop=4
    set shiftwidth=4
    set smarttab
    set expandtab
    set smartindent

    Буду благодарен за любые уточнения или дополнения.

    Similar posts

    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 39

      +1
      Конечно всегда можно настраивать самому, но иногда требуется просто конфиг для удобной работы на чужом компьютере. (например попросили настроить сервер) Свои конфиги тянуть лень, по этому есть замечательное месте где их взять :)
        0
        З.Ы. забыл линк указать

        wget -O $HOME/.vimrc www.cynapses.org/tmp/setup/.vimrc
          +1
          проще сделать тоже самое, только с урлом на свой конфиг =)
            0
            Это если у домашнего компа есть внешний IP :) В любом случае данный конфиг очень удобен (для меня) И отступы я люблю по 2 пробела.
              +1
              А у меня mercurial-репозитарий для ~/.vimrc и ~/.vim c плагинами, файлами синтаксиса. Лежит на битбакете и личном redmine.
              Очень удобно — везде и всегда своя IDE :) Если кому-то нужно, могу дать урл для импорта(средства для разработки RoR-приложений, безумно удобные снипеты а-ля textmate в .rb, .erb, штатные средства для подсветки php, c++ и прочих современных языков)
                +1
                конечно давай, посмотреть всем хочется я думаю :)
                  +1
                    +1
                    Подсветка синтаксися для RoR лучше всего смотрится в Konsole тема «Тёмная пастель» с немного высветленным «Цвет 1» в её настройках для нормального отображения комментариев.
                    В репе также лежат плагины для html-сниппетов.
        +2
        Отличная статья, спасибо! На днях тоже решил научится пользоватся vim'ом, так что вы мне очень помогли.
          +1
          Про smarttab не знал, спасибо
            +5
            Еще полезная команда — retab. Заменяет табы на пробелы и обратно(в зависимости от значения expandtab)
              +2
              Еще более life-changing будет cindent, автоматически применяющий выбранный с помощью cinoptions стиль кодирования, как при вводе, так и при переформатировании командой =
                0
                И вобще самой-самой life-changing будет indentexpr, которая позволяет задать собственную функцию для формирования отступов на новой строке.
                  0
                  Удобство cinoptions в том, что там есть по управляющей конструкции практически на любой элемент форматирования, упоминаемый в большинстве стандартов кодирования. И подправить это выражение достаточно просто. А кроме того, indentexpr для С и С++ выполняется с помощью cindent, согласно $VIMRUNTIME/indent/{c,cpp}.vim
                    +1
                    indentexpr полезен когда нужно написать скрипт индента для какого нибудь языка, у которого синтаксис отличен от си. А так да — cindent наиболее простой и при этом наиболее гибкий вариант.
                      0
                      а возможно с их помощью организовать следующий стиль форматирования:
                      * при отступе от начала блока табуляция остаётся собой;
                      * при выравнивании текста относительно текста предыдущей строки табуляция заменяется пробелами;
                      * при нажатии '=' происходило форматирование выделенного текста в соотсветствии с этими правилами.

                      пример 1:

                      class C
                      {
                      void foo();
                      double boo();
                      };

                      в этом примере нужно, чтобы при нажатии одного или более табов в строке с boo после double курсор останавливался на позиции foo из предыдущей строки, т.е. достигалось автоматическое выравнивание имён функций. сейчас я это делаю вручную, нажимая пробел нужно число раз.

                      пример 2:

                      void foo()
                      {
                      for(int i = 0;
                      i < 10;
                      ++i)
                      {
                      cout
                        0
                        'умный' хабраредактор ликвидировал фрагменты текста, содержащие угловые скобки. в первом примере отступы функций от начала класса должны быть реализованы табами, а выравнивание имён этих функций относительно друг друга — пробелами. во втором примере отступ от начала функции — табами, далее 'i < 10' & '++i' должны быть выровнены пробелами относительно слова 'int'. т.е. хочется всегда нажимать таб, но во всех случаях, кроме отступов от начала блока, табы чтобы заменялись заданным в настройках числом пробелов.
                  +1
                  спасибо за '='.
                  От себя добавлю комбинацию '1G=G' — форматирует ('=') с 1ой строчки ('1G') до последней ('G')
                    +2
                    Вместо 1G ещё можно gg
                  0
                  а как можно сделать форматирование кода?
                    0
                    Хм, если я правильно вас понял, то нужно выделить форматируемый участок кода и нажать =
                      0
                      очень благодарен
                    0
                    Как-то пытался настроить подобное. Появился досадный «артефакт» — при копировании из веб-страницы в вим линии «съезжают» вправо. Кто-нибудь пытался побороть?

                    Вот пример:
                    1. Так выглядит скопированный в vim текст (.vimrc с конфигом из статьи):
                    import unittest

                    class TestStatisticalFunctions(unittest.TestCase):

                    def test_average(self):
                    self.assertEqual(average([20, 30, 70]), 40.0)
                    self.assertEqual(round(average([1, 5, 7]), 1), 4.3)
                    self.assertRaises(ZeroDivisionError, average, [])
                    self.assertRaises(TypeError, average, 20, 30, 70)

                    2. Вот так выглядит этот текст в оригинале:
                    import unittest

                    class TestStatisticalFunctions(unittest.TestCase):

                    def test_average(self):
                    self.assertEqual(average([20, 30, 70]), 40.0)
                    self.assertEqual(round(average([1, 5, 7]), 1), 4.3)
                    self.assertRaises(ZeroDivisionError, average, [])
                    self.assertRaises(TypeError, average, 20, 30, 70)
                      +4
                      set paste
                      Вставляем
                      set nopaste

                      Можно забиндить на комбинацию клавиш
                        0
                        не знал. большое спасибо
                      0
                      sorry, хабр съел пробелы
                          0
                          Сталкивался пару раз с подобным при копировании снаружи. Решал следующим образом: визуальное выделение блока, затем команда =. Думаю, при желании можно настроить автоматическое форматирование фрагмента после вставки.
                        0
                        Материала набралось на вторую часть. Впрочем, кто бы сомневался :)
                          +1
                          Небольшой оффтоп, но часто в редакторах, сразу после отступов, я настраиваю ту самую вертикальную полоску, на 80ой колонке. Хоть в vi, на сколько мне известно, нет подобной фичи, зато можно подкрашивать часть строк, вышедших за предел 80ой колонки.

                          match ErrorMsg '\%>80v.\+'
                            0
                            А может быть кто-нибудь знает если в vim что-нибудь похожее на ctrl+r в терминале? только с поиском не в истории а в файлах rails проета
                              0
                              скажите, а как отключить вот это:
                              # комментарий, нажимаем enter
                              # < — это вим сам добавляет, в конфигах, некоторых скриптах. в 7.0 не было, в 7.2, кажется, стало по-умолчанию.

                              и ещё, как временно отключить отступы и форматировани, например на время копипаста?
                                0
                                Отключение автоматического комментирования:
                                :set formatoptions-=ro

                                Про отступы при вставке написано выше.
                                  0
                                  ":set formatoptions=-ro" в консоли помогает, а вот в .vimrc — нет. как его правильно туда вставить? добавление в конец «set formatoptions=-ro» не помогает. содержимое .vimrc тут.
                                    0
                                    Потому что нужно не =-, а -=
                                      0
                                      тоже не помогает.
                                        0
                                        Это, мягко говоря, очень странно. Возможно у вас какой-то плагин это делает, не знаю.
                                0
                                Вместо smarttab'a с backspace'ом можно использовать Ctrl-d, Ctrl-t в режиме вставки (сдвигает строку под курсором на shiftwidth).
                                  0
                                  Накину пару ссылок для истории:

                                  Vim Wiki:
                                  vim.wikia.com/wiki/Indenting_source_code

                                  Vimcasts:
                                  vimcasts.org/episodes/tabs-and-spaces/
                                  vimcasts.org/episodes/indentation-commands/

                                  Only users with full accounts can post comments. Log in, please.