Программист
0,1
рейтинг
12 декабря 2014 в 13:44

Разработка → Vim FileStyle: проверяем открытый файл на соответствие настройкам Vim из песочницы

VIM*

Зачем это нужно


При командной разработке важным является соблюдение определенного кодинг стандарта. Речь не всегда идет об именовании переменных, функций и т.д. Перечисленное выше во многом вопрос опыта и умения формулировать мысли в тексте. Кодинг стандарт часто начинается с определения следующих вещей:

  • Пробелы или табуляция
  • Длина строки

Несоблюдение приведенных выше параметров стиля разными людьми в пределах одного файла ведет с следующим проблемам:

  • Изрезанность кода
  • Необходимость горизонтального скроллинга

Часто такие проблемы возникают из-за того, что новый человек, вошедший в проект, не настроил редактор корректно, и это остается незамеченным вплоть до того момента, как становится нужно сравнить разные версии одного и того же файла.



Чтобы сразу при открытии файла видеть подобные проблемы, я написал небольшой плагин.

Почему именно плагин


На это было несколько причин:

  1. Я уже почти 2 года на постоянной основе пользуюсь Vim для редактирования кода, и мне давно хотелось написать какой-нибудь плагин
  2. Использование стандартных настроек вроде listchars не дает подсветки в случае использования пробелов для отступов при опции noexpandtab
  3. Задание зависимости от настроек в ftplugin

Функционал


  • Подсветка пробельных символов в соответствии с опцией expandtab: если опция включена, то символы табуляции подсвечиваются красным, в противном случае пробелы в начале строки подсвечиваются желтым
  • Подсветка пробельных символов в конце строки
  • Подсветка части строки превышающей длину, заданную опцией textwidth

Плагин изнутри


В основе плагина лежит функция matchadd(). Эта функция ищет в открытом буфере совпадения с заданным паттерном и подсвечивает его в соответствии с указанной схемой подсветки.

Например, мы хотим подсветить все пробелы в буфере желтым:

:highligh Spaces ctermbg=Yellow guibg=Yellow
:call matchadd('Spaces', '\s\+')

Общая функция подсветки выглядит следующим образом:

function FileStyleHighlightPattern(highlight)
  call matchadd(a:highlight['highlight'], a:highlight['pattern'])
endfunction

На вход принимается словарь с именем схемы подсветки и паттерном для сравнения.

Для того, чтобы плагин автоматически запускал проверку паттернов, необходимо было добавить автоматические команды при инициализации плагина:

augroup filestyle_auto_commands
  autocmd!
  autocmd BufReadPost,BufNewFile * call FileStyleActivate()
  autocmd FileType * call FileStyleCheckFiletype()
  autocmd WinEnter * call FileStyleCheck()
augroup end

Стоит отдельно оговорить, для чего нужен обработчик события FileType. Его пришлось добавить для того, чтобы плагин не отрабатывал на help файлах, так как их содержимое может быть произвольным и никак не согласовываться с текущими настройками, а так же не может быть отредактировано из окна помощи.

Обработчик WinEnter нужен для того, чтобы при делении окна (:split) в открытом окне так же была подсветка.

Так выглядит конечный результат:



Скачать можно по ссылкам: vim.org | GitHub

UPD: Починена ошибка undefined variable filestyle_active. Изменения залиты на GitHub и Vim.org
@DrLivesey
карма
6,0
рейтинг 0,1
Программист
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (21)

  • 0
    На каком языке в основном пишете, если не секрет? Просто для статистики.
    • +1
      Сейчас в основном на С++ и Python.
      • 0
        И это очень логично. Кажется, что Vim наиболее пригоден как раз именно для этих языков. Для C++ потому что трудно написать хорошую IDE для такого сложного языка, а для Python — потому что для него написаны очень качественные и функциональные плагины.
        • +1
          Что меня прежде всего привлекает в Vim, так это отсутствие необходимости использовать мышь, скорость работы с текстом и его гибкость (одина возможность настроить Vim в зависимости от содержимого ftplugin чего стоит). Но скажу честно, что пользуюсь далеко не всеми его возможностями.
          • +2
            Vim – лучший текстовый редактор в мире. Но я ним не пользуюсь. Вернее, пользуюсь, но когда нужно отредактировать один файл.

            Мне кажется, глупо не пользоваться преимуществами графических интефейсов и мощью семантического анализа IDE, учитывая, что для большинства из них есть симуляция Vim в том или ином виде: Intellij IDEA, Eclipse, ST, Atom. Даже для Emacs. IdeaVIM, например, поддерживает macros, remapping (limited), marks, buffers и многое другое. То есть можно очень даже неплохо жить, и при этом не краснеть когда тебе на code review говорят, что эта переменная не используется, или что она при неких обстоятельствах может быть не инициализированна. И не мучиться с GitGutter, который обновляет состояние раз в вечность.

            В идеальном мире у Vim был бы API, который бы позволял подключать к нему внешние редакторы. Если я правильно понимаю, к этому стремятся ребята из NeoVIM.
  • 0
    А демонстрацию \r\n вместо простого \n в конце строки сложно добавить?
    • 0
      Технически сложности быть не должно, потому что нужно лишь добавить еще одно регулярное выражение. Только навскидку не могу сказать к какой опции это можно привязать, чтобы подсветка срабатывала корректно. Спасибо за идею.
      • 0
        Если в файле везде CRNL, то никаким регулярным выражением вы ничего не сделаете: файл будет открываться с setlocal fileformat=dos с преобразованием CRNL полностью в перенос строки. Если нет, то ^M в конце и без подсветки обычно заметить несложно, в регуляных выражениях можно использовать \r.
        • 0
          Хотя регулярное выражение $ будет подсвечивать часть строки за последним символом. Только без дополнительного условия «использовать только если &l:fileformat is# "dos"» подсвечиваться конец будет всегда.
          • 0
            Спасибо за информацию. Я как раз думал над этим вопросом.

            Получается, что подсветка в этом случае вообще не особенно нужна, если я правильно понял первый коментарий.
            • 0
              Подсветка — нет, скорее всего пользователь не поймёт, что подсвечивается и почему (если только это не смешанный CRNL/NL файл). Вот сообщение о том, что &l:fileformat is# 'dos' при открытии сделать можно, вместе с описанием «а что это такое» и «как исправить» (и «как отключить предупреждение»).

              Подсвечивать ^M в тексте всё же можно — «замечаемость» его сильно зависит от используемой цветовой схемы. С моим wombat256mod это особых проблем не доставляло, хотя там и нет кричащего фона. В стандартной схеме ^M похож на комментарий, что ещё заметнее. Проблем нету в основном потому, что ^M либо нет вообще, либо он есть везде (при вставке из старой Opera, к примеру). Так что мой комментарий всё же относится к моему опыту.

              Я бы рекомендовал подсвечивать все управляющие символы, а не \r. Во всех известных мне языках программирования их можно заменить на что‐то из печатных символов, а проблем при использовании VCS или cat они доставить могут (VCS может счесть, что файл является бинарным, а в терминале они не зря называются управляющими).
              • 0
                Спасибо за дельные предложения. Насчет предупреждения:
                Вот сообщение о том, что &l:fileformat is# 'dos' при открытии сделать можно, вместе с описанием «а что это такое» и «как исправить» (и «как отключить предупреждение»).

                я бы сделал это ненавязчивым echo со ссылками на соответствующий help.
  • 0
    Несколько плагинов по теме, которые могут пригодиться:
    sleuth — автоматическое определение tabstop, shiftwidth, softtabstop, expandtab
    better-whitespace — подсветка лишнего/неправильного whitespace, а так же функция для удаление такового
    indent-guides — подверстка отступов пробелами и табами
  • 0
    Подсветка пробельных символов в конце строки

    setlocal list listchars=eol:¬,trail:_
    • 0
      Я знаю про эту опцию и долго ей пользовался, но в плагине сделал универсальную функцию для всех паттернов.
  • 0
    Вышла версия 0.6.0. Доступна на GitHub и Vim.org.
    • 0
      А зачем в github releases помещать README? Обычно туда помещают часть CHANGELOG (что изменилось по сравнению с предыдущим выпуском) и/или какую‐нибудь производную от него (к примеру, где сломана совместимость и как это исправить).
      • 0
        Спасибо за совет. Учту на будущее.

        Если только CHANGELOG добавлять, то он у меня получается чересчур короткий от версии к версии, поэтому и вложил README.
        • 0
          Так это хорошо. Есть страничка github.com/aserebryakov/filestyle/releases, на которой сейчас много копий README. А в предложенном варианте там будет нормальный, полный CHANGELOG.

          Собственно поэтому в powerline я changelog не веду — достаточно того, что список изменений есть на Github и есть полностью его копия в описании изменений в master ветке.
  • 0
    Вышла версия 0.6.1. Доступна на GitHub и Vim.org.

    Починена проблема переопределения функций в случае если используется Vundle.
  • 0
    Вышла версия 0.7.0

    Доступна на GitHub и Vim.org.

    Новые возможности:

    • Исправление ошибок формата (экспериментальная фича)
    • Глобальное выключение плагина

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.