Введение
При каждом запуске редактора Vim, им выполняется процесс инициализации, обеспечивающий удобный интерфейс для пользователя. На первый взгляд модель инициализации может показаться простой и понятно, но это далеко не так.
В этой статье я предлагаю вам ознакомиться с процессом инициализации редактора Vim. Данную тему я считаю одной из наиболее сложных в ходе изучения редактора, от чего материал, изложенный мной, может быть очень полезен как новичкам, начинающим этот тернистый путь, так и опытным пользователям и разработчикам.
Сложность этой темы обусловлена нетривиальной моделью загрузки скриптов редактора, а так же количеством групп, на которые эти скрипты делятся. Запомнить порядок инициализации редактора достаточно сложно, но это очень важно для написания собственных плагинов для него.
Инициализация редактора
Кто?
Для начала рассмотрим, кто отвечает за загрузку скриптов и, с их помощью, инициализацию редактора. Таких точек загрузки в Vim всего две:
- Редактор — за поиск и загрузку скриптов отвечает логика, "вшитая" непосредственно в код редактора
- Скрипты — за поиск и загрузку скриптов отвечает логика других скриптов
Чтобы вам стало понятнее, взгляните на файл $VIM/vimrc
. Этот скрипт загружается (и выполняется) логикой самого редактора. С другой стороны сам скрипт $VIM/vimrc
, как правило, включает логику загрузки других скриптов.
Важным отличием скриптов, загружаемых редактором, от остальных является то, что первые могут быть отключены (или подключены) только с использованием опций запуска Vim, таких как -u
(указывает корневой пользовательский скрипт) или --noplugin
(запрещает загрузку плагинов). В свою очередь загруженные скрипты могут управлять инициализацией с помощью некоторой логики, программируемой разработчиком.
Когда?
Для удобства и повышения безопасности процесса инициализации редактора, механизм разбит на два основных этапа:
- Общесистемный — загружаемые на этом этапе скрипты влияют на работу всех пользователей компьютера
- Пользовательский — загружаемые на этом этапе скрипты влияют на работу только текущего пользователя компьютера
С помощью опции exrc
может быть подключен еще один этап:
- Проектный — загружаемые на этом этапе скрипты влияют на работу только текущего сеанса редактора
На самом деле вы можете добавить собственные этапы к уже имеющимся, важно лишь соблюдать порядок загрузки и область ответственности каждого этапа.
Порядок загрузки скриптов не строгий. Он определяется содержимым опции runtimepath
, в которой перечисляются адреса каталогов, хранящих файлы инициализации в том порядке, в котором они должны быть загружены.
К сожалению это наиболее непредсказуемая часть механизма инициализации редактора. Дело в том, что здесь применяется совсем не тот порядок загрузки, который мог бы показаться вам наиболее очевидным. В частности без должной настройки, сначала будет выполнятся инициализация пользовательских скриптов, а только затем общесистемных. В этом можно убедится взглянув на содержимое опции runtimepath
, у меня оно такое (без настройки): runtimepath=~/.vim,/usr/share/vim/vimfiles,/usr/share/vim/vim74,/usr/share/vim/vimfiles/after,~/.vim/after
.
Как видно, первыми в очереди инициализации стоят пользовательские скрипты, а это значит, что они будут переопределены общесистемными при старте редактора. Неожиданное, не правда ли? Я до сих пор ломаю голову над причиной, побудившей авторов применить именно такой порядок инициализации.
Что?
Скрипты инициализации редактора сгруппированы следующим образом, в зависимости от целей:
- Базовые (.vimrc) — скрипты, отвечающие за общую инциализацию редактора
- Контексто-определяющие (ftdetect/) — скрипты, отвечающие за выявление контекста (типа редактируемого файла)
- Контексто-зависимые (ftplugin/) — скрипты, инициализирующие редактор в зависимости от контекста
- Цветовые схемы (colors/) — правила подсветки интерфейса
- Скрипты поддержки компиляторов (compiler/) — скрипты для использования компиляторов
- Справочники (doc/) — документация
- Файлы раскладки клавиатуры (keymap/) — маппинг раскладки клавиатуры
- Конфигурация меню (menu.vim) — файл конфигурации меню
- Переводы меню (lang/) — файл локализации меню
- Подсветка синтаксиса (syntax/) — конфигурация подсветки синтаксиса языка
- Плагины (plugin/) — скрипты инициализации плагинов
- Сценарии создания отступов (indent/) — конфигурация отступов
- Вспомогательные сценарии для печати (print/) — конфигурация системы печати
- Файлы учебника (tutor/) — файлы учебника
Такое разнообразие используемых для инициализации скриптов обусловлено функциональными возможностями редактора. Конечно, никто не запрещает использовать единственный скрипт инициализации для конфигурирования всех механизмов редактора (на пример в файле ~/.vimrc
), но я так делать не рекомендую (файл быстро пухнет, знаете ли).
Контекстно-зависимые скрипты
О контексте скриптов следует поговорить отдельно. В отличии от некоторых редакторов, Vim не привязан к конкретному синтаксису или языку. С его помощью можно одинаково просто писать книгу, редактировать исходные коды программы или работать с двоичными (hex) файлами. Достигается это благодаря возможности локализовать конфигурацию конкретным буфером редактора. Другими словами, вы можете сконфигурировать одно окно редактора с использованием первого скрипта, а второе — с использованием второго, в зависимости от типа редактируемых в нем файлов. Тип файлов, в данном случае, я и называю — контекстом.
Как вам (возможно) известно, Vim имеет обратную совместимость с редактором Vi, который, в свою очередь, создавался с учетом особенностей Unix-подобных систем. С точки зрения контекста, это означает, что тип редактируемого файла не всегда можно определить по его имени (расширению), часто для этих целей редактору необходимо работать с содержимым редактируемого файла. Для этих целей применяются контексто-определяющие скрипты, которые располагаются в каталоге ftdetect/
, а так же скрипт filetype.vim
.
После того, как контекст определен, для редактируемого файла вызываются скрипты каталога ftplugin/
. Их конфигурации должны (но это никак не ограничивается) применяться только к текущему буферу.
Конфигурация механизма инициализации
Вы можете самостоятельно настроить механизм инициализации редактора, но делать это нужно крайне осторожно. Я не рекомендую вам изменять содержимое общесистемных скриптов инициализации, так как это может привести к неожиданному поведению редактора.
Перед тем, как приступить к конфигурации механизма инициализации, откройте ваш редактор Vim и выполните команду :scriptnames
, вы увидите список загруженных при старте редактора файлов. Это очень полезная информация, к которой вы будете обращаться постоянно, дабы узнать, почему тот или иной скрипт перестал работать. Так же с помощью этого списка легко проследить порядок инициализации редактора.
И так, как же можно сконфигурировать механизм инициализации? В первую очередь выполните команду set runtimepath?
и взгляните на содержимое опции runtimepath
. Вы можете изменить порядок загрузки ваших файлов инициализации или подключить новые каталоги с ее помощью. Для этого откройте файл ~/.vimrc
и добавьте в него следующую запись: set runtimepath=каталоги разделенные запятой
. При повторном старте редактора уже будет применен указанный вами порядок загрузки. Учтите лишь то, что до момента загрузки вашего файла ~/.vimrc
, редактором будет применяться заданный в общесистемных файлах конфигурации порядок инициализации.
Другим способом конфигурирования механизма инициализации является подключение дополнительного, проектного этапа инициализации. Для этого добавьте в ваш файл ~/.vimrc
следующую строку: exrc
. Теперь при старте редактора, будет выполняться не только пользовательский файл инициализации ~/.vimrc
, но файл с тем же именем в текущем каталоге (./.vimrc
). Он может применяться для конфигурирования редактора под каждый конкретный проект. Более того, ничего не мешает вам добавить в проекте каталог .vim
и запись в файл ./.vimrc
: set runtimepath+=./.vim
. После этого ваш проектный каталог .vim
станет аналогичен пользовательскому каталогу ~/.vim
, что облегчит структурирование ваших конфигурационных файлов проекта.
Пока все
Да, статья довольно сложная, не пестрит примерами и частично повторяет документацию. Дело в том, что это вступление к другой, более интересной теме, которую я постараюсь осветить в будущем, но сделать это без этих знаний будет слишком сложно.
Автор: Delphinum