Vim по полной: Менеджер плагинов без фатальных недостатков

Введение (vim_lib) Менеджер плагинов без фатальных недостатков (vim_lib, vim_plugmanager) Уровень проекта и файловая система (vim_prj, nerdtree) Snippets и шаблоны файлов (UltiSnips, vim_template) Компиляция и выполнение чего угодно (vim_start) Работа с Git (vim_git) Деплой (vim_deploy) Тестирование с помощью xUnit (vim_unittest) Библиотека, на которой все держится (vim_lib) Другие полезные плагины Я пользовался, наверно, всеми популярными менеджерами плагинов для Vim и у меня не было ни малейшего желания писать свой собственный, так как эти меня вполне устраивали, но было небольшое но, о котором я расскажу в этой статье. Как работает менеджер плагинов для Vim? Все тривиально. Во время старта редактора считывается .vimrc в котором объявляются все используемые в данный момент плагины. Эти имена конкатенируются с адресом каталога, который должен хранить плагины и полученные строки добавляются в runtimepath — переменная Vim, которая определяет, откуда редактору брать стартовые скрипты, плагины и все остальное.Основной проблемой большинства популярных менеджеров плагинов для Vim является то, что они заполняют переменную runtimepath как попало. К чему это ведет? Плагины загружаются беспорядочно, нет возможности переопределить настройки плагина для конкретного проекта, плагины переопределяют ваши собственные настройки Vim и т.д. Все еще больше усугубляется невозможностью контролировать порядок загрузки плагинов, когда нужно сначала загрузить плагин A, а только затем зависимый от него благин B. Одним словом — боль.

Я уже говорил раньше и подробнее остановлюсь на этом вопросе в следующей статье, а сейчас только немного коснусь его. Предлагаемая мной структура добавляет еще один уровень инициализации редактора Vim. Это означает, что ваши Vim-конфигурации и плагины будут существовать на трех уровнях: Системном ($VIMRUNTIME/) — конфигурации и плагины, которые распространяются на всех пользователей системы Пользовательские (~/.vim/) — конфигурации и плагины конкретного пользователя Проектные (./.vim/) — конфигурации и плагины, доступные только в данном проекте. Именно этого уровня нет в Vim, точнее он есть, но реализован довольно слабо Это позволит, на пример, настроить шаблоны для Java классов, а затем переопределить их для конкретного проекта. Можно так же установить некоторый плагин только для определенного проекта, и этот плагин не будет подгружаться Vim в других проектах, что сэкономит память и увеличит производительность редактора (на пример вы решили начать работать с Lua и не хотите ставить плагины в ~/.vim/). Только представьте, один редактор на все случаи жизни и никаких лагов. Библиотека vim_lib определяет как структуру плагинов Vim (но не ограничивает вас только этой структурой, может использоваться любой плагин), так и порядок их подключения и загрузки, для этого реализованы классы sys/Plugin и sys/Autoload соответственно.Если реализовать плагин в строгом соответствии с требованиями класса sys/Plugin, то мы получим следующую структуру:

myPlugin/ plugin/ myPlugin.vim autoload/ … myPlugin.vim doc/ myPlugin.rux Файл plugin/myPlugin.vim содержит логику инициализации и подключения плагина.Пример » Date Create: 2015–02–23 22:45:56 » Last Change: 2015–06–07 11:45:51 » Author: Artur Sh. Mamedbekov (Artur-Mamedbekov@yandex.ru) » License: GNU GPL v3 (http://www.gnu.org/copyleft/gpl.html)

» Аналог use в VimLanguage let s: Plugin = vim_lib#sys#Plugin# let s: System = vim_lib#sys#System#.new ()

let s: p = s: Plugin.new ('vim_write', '1') » Создание объекта плагина с указанием его имени и версии

» Опции плагина » {{{ » @var bool Следует ли выполнять замену ключевых значений в файле перед сохранением. » }}} let s: p.preplace = 1 » {{{ » @var bool Включен ли механизм автосохранения изменений. » }}} let s: p.aw = 0 » {{{ » @var string|array Массив, содержащий имена типов файлов, для которых задействован механизм автосохранения изменений. Если опция установлена в значение 'all', механизм задействован для всех типов файлов. » }}} let s: p.awTypes = 'all' if! exists ('g: vim_write#replacement') » {{{ » @var hash Словарь замен, используемый перед записью буфера для замены ключевых слов. Словарь имеет следующую структуру: {типФайла: [regexp, …]}. Тип 'all' используется для всех файлов. » }}} let g: vim_write#replacement = {} endif

» Функция инициализации плагина, в ней можно писать любую логику function! s: p.run () » {{{ call s: System.au ('BufWritePre, FileWritePre', function ('vim_write#_writePre')) call s: System.au ('CursorHold', function ('vim_write#_autowrite')) endfunction » }}}

» Объявление пунктов меню плагина. Они попадут в Plugins.имяПлагина.пунктМеню call s: p.menu ('Aw_start', 'awstart', '1') call s: p.menu ('Aw_stop', 'awstop', '2')

» Объявление команд плагина call s: p.comm ('VimWriteAwStart', 'awstart ()') call s: p.comm ('VimWriteAwStop', 'awstop ()')

call s: p.reg () » Регистрация плагина, которая делает его доступным в редакторе Файл autoload/myPlugin.vim содержит методы плагина. Опытные пользователи Vim сразу заметят, что основной код плагина будет подгружаться при первом его использовании, а не во время запуска редактора. Делается это через глобальный вызов методов плагина. На пример, при выполнении команды VimWriteAwStart из предыдущего примера, будет вызван метод имяПлагина#awstart ().Пример » Date Create: 2015–02–23 22:48:37 » Last Change: 2015–06–07 11:45:51 » Author: Artur Sh. Mamedbekov (Artur-Mamedbekov@yandex.ru) » License: GNU GPL v3 (http://www.gnu.org/copyleft/gpl.html)

» Аналог use в VimLanguage let s: Publisher = vim_lib#sys#Publisher#.new () let s: Content = vim_lib#sys#Content#.new ()

» {{{ » Метод активирует механизм автосохранение. » }}} function! vim_write#awstart () » {{{ let g: vim_write#.autowrite = 1 endfunction » }}}

… Файл doc/myPlugin.rux содержит документацию к плагину.Зачем все это нужно? Во-первых стандартизация. Писать, изменять и разбираться в плагинах становится легче. Во-вторых их проще отключить.

Подробнее можно почитать здесь.

Класс sys/Authoload библиотеки определяет порядок инициализации как самого редактора Vim, так и его плагинов. Инициализация выполняется в несколько этапов: Подключение основных файлов конфигурации редактора ($VIMRUNTIME) Подключение общесистемных плагинов ($VIMRUNTIME/plugin/) Подключение файло-зависимых конфигураций ($VIMRUNTIME/ftplugin/) Подключение основных файлов конфигурации пользователя (~/.vimrc) Подключение пользовательских плагинов (~/.vim/plugin/) Подключение файло-зависимых плагинов пользователя (~/.vim/ftplugin/) Подключение основных файлов конфигурации проекта (./.vimrc) Подключение проектных плагинов (./.vim/plugin/) Подключение файло-зависимых плагинов проекта (./.vim/ftplugin) Выполняется это с помощью уже знакомой нам переменной runtimepath, но учитывается порядок загрузки плагинов, их локализация (системные, пользовательские или проектные), а так же поддерживается механизм переопределения конфигураций как редактора, так и любых плагинов на каждом из уровней (проектный уровень самый приоритетный).Вообще класс sys/Authoload позволяет реализовать любую иерархию вложенности и приоритет конфигураций, а не только трехступенчатую, но я не увидел необходимости добавлять новые уровни.

Для использования автозагрузки, предлагаемой классом sys/Authoload, достаточно добавить в ваш файл .vimrc следующие строки:

filetype off set rtp=~/.vim/bundle/vim_lib call vim_lib#sys#Autoload#init ('~/.vim', 'bundle') » Адрес до вашего ~/.vim/bundle

Plugin 'vim_lib' » Другие плагины

filetype indent plugin on Сделать это можно не только на пользовательском уровне (~/.vimrc), но и на системном ($VIMRUNTIME/.vimrc) или проектном (./.vimrc), при этом логика автозагрузки будет распространятся только от данного уровня и «ниже». На всех низлежайших уровнях достаточно просто подключать новые плагины, доступные только этому уровню: Plugin 'myPlugin' Для отключения плагина, достаточно просто закоментировать строку Plugin 'имя'.Сконфигурировать плагин можно прямо во время его подключения:

Plugin 'vim_deploy', { \ 'options': {'adapter': 'shipit'},» Переопределение опций плагина \ 'map': {'deploy': 'd'},» Переопределение горячих клавиш \} На более низких уровнях можно переопределить эти конфигурации: let g: vim_deploy#options = {'adapter': 'gradle'} Все очень гибко и удобно. Казалось бы, что мешает заставить другие менеджеры плагинов устанавливать плагины в нужные нам каталоги (системный, пользовательский или проектный)? Проблема здесь в том, что другие менеджеры не просто устанавливают сторонние плагины, но и определяют порядок из инициализации, а нам это не нужно (уже реализовано классом sys/Authoload библиотеки). Та самая проблема несовместимости Vim плагинов, о которой я говорил в предыдущей статье. Пришлось писать свое решение.vim_plugmanager имеет довольно простой интерфейс и позволяет устанавливать плагины из GitHub в системный каталог, каталог пользователя или проектный каталог, в зависимости от того, где вы сейчас находитесь.

Окно со списком плагинов 663157f84eb844ba899daf9288057925.png Как видно на рисунке, vim_plugmanager реализован в виде окна, в котором он отображает список установленных на данный момент плагинов (именно установленных, а не подключенных) с группировкой по уровням. Для добавления нового плагина достаточно нажать клавишу a, а для удаления навести курсор на плагин и нажать dd (очень привычно, не так ли?).После установки нового плагина его необходимо подключить. Для этого, как уже было сказано выше, достаточно добавить в текущий .vimrc (текущего уровня) запись Plugin 'имяПлагина'. Нужно это потому, что установка плагина представляет собой копирование его в каталог с плагинами, а подключение добавляет его в vimruntime, после чего он может быть загружен редактором.

Подробнее можно почитать здесь.

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

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

© Habrahabr.ru