Полезные плагины для Vim. Часть 2

Немного рекламы

Введение

Когда-то давно я уже писал про некоторые полезные плагины для Vim, которые использовал в то время. С момента написания той статьи прошло уже несколько лет, и за это время появилось несколько новых интересных плагинов, которые успешно заменяют некоторые упомянутые в той статье. Кроме того, после того как некоторое время я использовал Sublime Text, а после опять вернулся к Vim, появилось желание некоторые возможности Sublime Text иметь и в Vim.

Цель этой статьи - не только рассказать о полезных плагинах, но и несколько углубиться в их настройку, рассказав заодно что-нибудь про работу самого Vim'а, чтобы работа самих плагинов стала более понятной.

В статье будет подразумеваться, что вы уже умеете устанавливать плагины и знаете, что такое файл .vimrc (или _vimrc под Windows). Если нет, то лучше сначала прочитайте статью Vim. Первая установка.

Итак, начнем.

Плагин Vundle. Автоматическая установка и обновление плагинов

В прошлой статье я писал про такой замечательный плагин как Pathogen, который позволяет упорядочивать плагины, храня каждый плагин в отдельной папке без необходимости разбрасывать файлы плагина по многим папкам вроде plugin, doc, syntax и т.п.

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

Для его установки нужно сделать несколько магических телодвижений с файлом .vimrc и папкой .vim (в дальнейшем тесте статьи я не буду упоминать о том, что под Windows файл .vimrc называется _vimrc). Алгоритм установки выглядит следующим образом.

0. Vundle для скачивания и обновления использует git и curl. Под Linux эти программы, как правило, уже установлены или устанавливаются без проблем. Git под Windows тоже устанавливается легко, а вот curl нужно еще поискать. Проще всего его скачать с сайта по адресу http://www.confusedbycode.com/curl/. После установки убедитесь, что в командной строке стала доступна команда curl. Это можно сделать, выполнив в консоли следующую команду:

curl --version

В результате вы должны увидеть что-то наподобие следующих строк:

curl 7.30.0 (i386-pc-win32) libcurl/7.30.0 OpenSSL/0.9.8x zlib/1.2.7
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smtp smtps telnet tftp
Features: AsynchDNS GSS-Negotiate IPv6 Largefile NTLM SPNEGO SSL SSPI libz

Если Windows не ругается, что команда curl не найдена, значит все нормально и можно двигаться дальше.

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

2. Затем в эту папку нужно склонировать репозиторий плагина с github:

git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim

Обратите внимание, что здесь также упоминается папка bundle, если вы ее назвали как-то по-другому, ее следует переименовать и здесь.

Если вы используете Vim под Windows, то вместо имени папки .vim нужно писать vimfiles:

git clone https://github.com/gmarik/Vundle.vim.git ~/vimfiles/bundle/Vundle.vim

А лучше для надежности перейти в папку bundle с помощью команды cd и склонировать репозиторий плагина непосредственно в эту папку (точнее, во вложенную папку Vundle.vim)

3. Теперь открываем файл .vimrc и в начало файла добавляем следующие строки (для Linux):

  1. set nocompatible             " be iMproved, required
  2. filetype off                 " required
  3.  
  4. set rtp+=~/.vim/bundle/Vundle.vim
  5. call vundle#begin()
  6.  
  7. Plugin 'gmarik/Vundle.vim'
  8.  
  9. call vundle#end()            " required
  10. filetype plugin indent on    " required

Под Windows эти строки должны выглядеть следующим образом:

  1. set nocompatible             " be iMproved, required
  2. filetype off                 " required
  3.  
  4. set rtp+=~/vimfiles/bundle/Vundle.vim
  5. let path = '~/vimfiles/bundle'
  6. call vundle#begin(path)
  7.  
  8. Plugin 'gmarik/Vundle.vim'
  9.  
  10. call vundle#end()            " required
  11. filetype plugin indent on    " required

По поводу первых двух и последней строк не стоит даже задумываться - они нужны из-за особенностей работы Vundle.

Четвертая строка добавляет новый путь до так называемого Пути runtime (runtimepath - rtp). Эта переменная хранит список путей, по которым ищутся плагины различных типов. По умолчанию этот параметр хранит путь только до папки .vim. Четвертая строка добавляет в список еще один путь, по которому Vim должен искать различные файлы плагинов, в данном случае - это папка плагина Vundle (в ту папку, куда мы его склонировали из репозитория. Обратите внимание, что здесь опять упоминается имя bundle). Таким образом, внутри папки ~/.vim/bundle/Vundle.vim могут быть (и они там действительно есть) такие папки как plugin, doc и т.п.

Углубляясь в то, как работает плагин Vundle надо сказать, что при установке плагинов с помощью него, Vundle будет добавлять в переменную rtp (или полное название runtimepath) аналогичные пути до всех установленных плагинов, благодаря чему нет необходимости файлы каждого плагина раскидывать по множеству папок. В случае, если вам плагин больше не нужен, достаточно удалить его папку, и не надо искать, в каких других папках остались его файлы.

Чтобы увидеть, что хранится у вас в переменной rtp, достаточно выполнить команду:

:echo &rtp

или

:echo &runtimepath

Это будет особенно полезно сделать после установки каких-нибудь плагинов.

4. Добавляем интересующие нас плагины. В приведенном выше тексте, добавленном в .vimrc, есть строки:

call vundle#begin()
...
call vundle#end()

Между ними как раз и надо перечислить плагины, которые нужно установить. В тех строках, что мы уже добавили в vimrc, добавлена ссылка на сам плагин Vundle. Плагины добавляются с помощью команды Plugin. Осталось разобраться, откуда они будут скачиваться.

В стародавние времена плагины брали на сайте http://www.vim.org/, но плагин Vundle вместо него использует другие источники - это https://github.com и http://vim-scripts.org/. Последний сайт позволяет скачивать плагины через git (все через тот же github).

Чтобы добавить плагин для установки, нужно добавить команды Plugin с параметрами между вызовами call vundle#begin() и call vundle#end(). Параметры команды Plugin зависят от источника. Например:

call vundle#begin()
Plugin 'gmarik/Vundle.vim'

' Плагин ищется на сайте vim-scripts.org
Plugin '
vim-signature'

'
Ссылка на репозиторий github
Plugin 'scrooloose/nerdtree'
call vundle#end()

Если плагин упоминается на сайте http://vim-scripts.org/, а полный список этих плагинов можно посмотреть по ссылке http://vim-scripts.org/vim/scripts.html, то достаточно указать его имя. Если у плагина есть свой репозиторий на github, то нужно указать окончание ссылки на репозиторий, где содержится имя пользователя, который владеет репозиторием и собственно имя репозитория.

Плагин Vundle поддерживает и другие ссылки на плагины, например, через git, репозиторий который находится не на github, ссылки на локальный репозиторий и некоторые дополнительные настройки. Но мы их здесь рассматривать не будем, эти параметры можно посмореть в документации, вызвав команду

:h vundle

или на странице плагина.

5. Устанавливаем и обновляем плагины.

После того, как были добавлены ссылки на новые плагины в файле .vimrc, необходимо перезапустить Vim или заново прочитать .vimrc с помощью команды

:so $MYVIMRC

После этого выполнить команду:

:PluginInstall

Vundle пройдется по списку перечисленных плагинов и скачает новые плагины, которые до этого не были установлены. При этом установленные плагины на обновления не проверяются.

В результате откроется еще один буфер со списком плагинов. Вот, например, как выглядит этот буфер у меня после того как я добавил плагин tabman.vim (не важно, что это за плагин). Около установленных ранее плагинов (про некоторые из них мы еще поговорим) слева стоят точки, а новый плагин отмечен плюсиком.

vundle_01.png: 980x698, 182k (26.11.2014 09:25)

Если вы хотите проверить установленные плагины на наличие новых версий, достаточно выполнить команду

:PluginUpdate

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

Кроме того, с помощью команды :PluginSearch можно искать нужный плагин по ключевому слову.

:PluginSearch ключевое_слово

На следующем скриншоте показан результат выполнения команды :PluginSearch snippet:

vundle_02.png: 916x715, 158k (26.11.2014 09:25)

Найденные плагины можно устанавливать непосредственно из открывшегося буфера с помощью клавиши i. Выбранный плагин будет установлен. Правда, этот плагин не будет добавлен в файл .vimrc и, соответственно, в будущем Vundle не будет проверять его обновления, но в .vimrc упоминание этого плагина можно внести и позже.

Если вы хотите удалить плагин, то удалите или закомментируйте с помощью двойной кавычки его упоминание в .vimrc и вызовите команду

:PluginClean

Перед удалением каждого плагина Vundle будет спрашивать, действительно ли вы хотите удалить плагин. Если вы заранее согласны на все удаления и не хотите, чтобы вам задавали эти вопросы, то к предыдущей команде добавьте знак "!":

:PluginClean!

В результате Vundle удалит все плагины из папки bundle, которые не упоминаются в вашем файле .vimrc.

В качестве альтернативы данного плагина есть еще NeoBundle - плагин, основанный на Vundle.

Плагин python-mode. Многофункциональных плагин для Python

Еще один плагин, который очень помогает при программировании на языке Python, является плагин python-mode. Он объединяет в себе сразу несколько полезных возможностей:

  • Проверку кода различными статическими анализаторами, включая pep8, pyflakes, pylint, pep257, mccabe.
  • Рефакторинг кода с помощью библиотеки rope.
  • Показ документации по функциям Python.
  • Запуск кода текущего буфера на выполнение.
  • Поддержку virtualenv.
  • Быструю установку точек останова (брейкпоинтов) в коде.
  • Горячие клавиши для удобной навигации по коду (перескок к предыдущему / следующему классу, выделение текста класса).
  • Более полную раскраску кода, включая слова self, None, стандартные исключения и т.д.
  • И другие полезные мелочи.

При желании все эти возможности можно добавить по отдельности с помощью различных плагинов, но когда это все устанавливается само, да еще и с помощью плагина Vundle, описанного выше, это замечательно. Потому что, например, для установки плагина ropevim - плагина для поддержки рефакторинга Python-кода - до этого приходилось делать достаточно большое количество телодвижений, связанных с установкой самого rope. Особенно приятно, что Pymode работает и под Linux, и под Windows (про Mac OS X ничего не скажу, не пробовал).

Установка плагина выполняется без каких-либо дополнительных шаманств, чтобы его установить с помощью Vundle, достаточно добавить в файл .vimrc между командами call vundle#begin() и call vundle#end() строку

Plugin 'klen/python-mode'

И после перезапуска Vim выполнить команду:

:PluginInstall

Python-mode имеет огромное количество настроек и возможностей, рассмотрим некоторые из них.

Начнем с проверки кода статическими анализаторами. Чтобы его включить, нужно добавить в файл .vimrc следующие строки:

let g:pymode_lint = 1
let g:pymode_lint_checker = "pyflakes,pep8"

Первая строка разрешает проверку кода, а вторая указывает инструменты, с помощью которых эта проверка должна осуществляться. На момент написания этих строк python-mode поддерживал следующие типы проверок:

  • pylint
  • pep8
  • pep257
  • mccabe
  • pyflakes

На следующем скриншоте показано, как python-mode отображает список ошибок и предупреждений после проверки.

pylint.png: 852x681, 149k (26.11.2014 09:25)

При выборе ошибки из списка в нижнем буфере курсор перемещается на проблемную строку. По умолчанию проверка осуществляется после каждого сохранения файла, но это поведение можно настроить с помощью параметров g:pymode_lint_on_write (включает / отключает проверку при каждом сохранении файла), g:pymode_lint_unmodified (указывает, нужно ли проверять код после сохранения, если он не изменился) и g:pymode_lint_on_fly (включает / выключает проверку кода "на лету", т.е. по мере набора текста программы).

Если вам позволяет совесть и коллеги, то вы можете подавить некоторые предупреждения и ошибки, обнаруженные в процессе проверки кода. Для этого служит параметр g:pymode_lint_ignore, значение которого - строка, содержащая номера ошибок или предупреждений, разделенных запятыми. Например:

let g:pymode_lint_ignore="E501,W601,C0110,E211,E303,E251"

Python-mode имеет еще и другие параметры, с помощью которых вы можете гибко настраивать проверку кода.

Python-mode включает в себя плагин для рефакторинга кода с помощью библиотеки rope. Рефакторинг динамических языков программирования наподобие Python - дело неблагодарное, не всегда автоматические инструменты находят все участки кода, которые нужно исправить, но все равно они бывают полезны.

Для того, чтобы активизировать поддержку rope, в файл .vimrc необходимо добавить строку:

let g:pymode_rope = 1

Для работы библиотека rope просматривает структуру кода и кэширует его в своем формате в папке .ropeproject, поэтому скорее всего вам надо будет добавить эту папку в список исключений вашей системы контроля версии. В принципе, построение кэша rope может занимать заметное время (секунды, хотя это все зависит от проекта). Плагин python-mode имеет несколько настроек, влияющих на создание папки .ropeproject, например, можно указать, искать ли подобную папку в родительских директориях, указать, где ее создавать и т.п. Все это можно найти в справке, вызвав ее с помощью команды

:help pymode-rope

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

  • Переименовывать классы, функции, методы и переменные.
  • Переименовывать текущий модуль или пакет.
  • Упорядочивать импорты. Эта команда удаляет неиспользуемые импорты, а остальные сортирует согласно требованию PEP8: сначала идут импорты стандартных библиотек, потом локальных модулей. При этом модули сортируются по алфавиту.
  • Преобразовывать текущий модуль в пакет.
  • Из выбранных строк извлекать метод или переменную.
  • Изменять сигнатуру функций.
  • Перемещать метод или поле.

Честно говоря, на момент написания этих строк многие типы рефакторинга у меня выдавали ошибку "[Pymode]: error: Unhandled exception in Pymode: get_changes() takes exactly 2 arguments (3 given)". Хочется верить, что это временные трудности, и скоро все будет исправлено. По крайней мере когда я ставил ropevim отдельно, эти типы рефакторинга работали.

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

Для того, чтобы использовать эту возможность, нужно в файл .vimrc добавить строку:

let g:pymode_rope_completion = 1

Включение / выключение подсказок после нажатия горячих клавиш устанавливается с помощью параметра g:pymode_rope_complete_on_dot. Например, добавив в файл .vimrc нижеприведенные строки, мы активизируем подсказки после ввода точки:

let g:pymode_rope_complete_on_dot = 1

С этими параметрами нужно обращаться осторожно, может так случиться, что при первом вызове подсказки начнет создаваться кэш .ropeproject или rope углубится в дебри большой сторонней библиотеки вроде wxPython и тогда Vim на некоторое время подвиснет.

Благодаря тому же rope мы можем искать в коде строку с объявлением метода, функции или переменной. Для этого надо в коде поставить курсор, например, на переменную, для которой ищем объявление, и нажать Комбинацию клавиш <Ctrl+C>g.

Плагин python-mode имеет еще множество возможностей для облегчения жизни Python-программиста, в заключени этого раздела упомянем еще одну - более продвинутую раскраску синтаксиса. Например, эта подсветка выделяет такие слова как self, None, True, False, имена стандартных исключений, docstrings.

Для того, чтобы разрешить или запретить раскраску кода плагину Python-mode, используется параметр g:pymode_syntax. Например, следующая стркоа в .vimrc разрешает продвинутую раскраску:

let g:pymode_syntax = 1

Есть возможность гибко настраивать раскраску - что подкрашивать, а что нет. Если вы хотите раскрашивать все элементы, достаточно установить параметр g:pymode_syntax_all в 1:

let g:pymode_syntax_all = 1

Строго говоря, параметры g:pymode_syntax и g:pymode_syntax_all по умолчанию и так установлены в 1, и они скорее нужны для того, чтобы отключать эти возможности (установив их в 0), но я предпочитаю как можно больше параметров задавать явно, чтобы в будущем, листая свой файл .vimrc, было сразу видно, что можно еще включить / отключить.

Плагины для сниппетов

Хотя термин "сниппет" уже прижился в жаргоне программистов, лучше лишний раз его уточнить, чтобы не было проблем с пониманием. Согласно Википедии, "сниппет" (англ. snippet — фрагмент, отрывок) в практике программирования — небольшой фрагмент исходного кода или текста, пригодный для повторного использования. Часто под сниппетами понимают не просто какой-то код, который можно использовать простым Copy-Paste, а целые макросы. Обычно они используются вместе с какими-то сокращениями, например, чтобы в Python не писать каждый раз код вроде

def myfunc (self, param):
    super (MyClass, self).myfunc(param)

можно создать сниппет, который будет создавать такой шаблон по ключевому слову. Например, вводим вы слово "def", нажимаем Tab или другую установленную горячую клавишу, и вместо "def" вы получаем шаблон функции, причем сниппеты, как правило, позволяют вводить шаблонные значения вроде "myfunc" в данном случае, и вводя "myfunc" один раз, оно будет подставлено и в место второго упоминания (в данном примере после оператора super).

Выбор плагинов для создания сниппетов под Vim достаточно широк, в качестве примера рассмотрим snipmate.

Для его работы требуются два дополнительных плагина - vim-addon-mw-utils и tlib_vim.

Будем считать, что этот плагин устанавливается с помощью Vundle. В этом случае нужно добавить следующие строки между call vundle#begin() и call vundle#end().

  1. Plugin "MarcWeber/vim-addon-mw-utils"
  2. Plugin "tomtom/tlib_vim"
  3. Plugin "garbas/vim-snipmate"

На странице плагина рекомендуют дополнительно установить плагин vim-snippets который добавляет множество сниппетов для многих языков программирования.

Сниппеты представляют собой текстовые файлы, расположенные в папке snippets внутри папки .vim и всех остальных папок, упомянутых в параметре runtimepath, о котором говорилось в разделе про Vundle.

Имена файлов сниппетов могут иметь разный формат (подробнее про синтаксис сниппетов можно прочитать, вызвав справку с помощью команды :help snippet-syntax), но обязательно в имени файла или пути до него (сниппеты можно располагать во вложенных папках) должен упоминаться язык (syntax в терминах Vim), для которого предназначен сниппет. Каждый файл со сниппетом имеет расширение .snippets. В простейшем случае файл со сниппетами может иметь вид: python.snippets, html.snippets и т.д. При необходимости после имени языка после подчеркивания можно добавлять произвольное имя (например, python_myfile.snippets), что позволяет иметь несколько файлов сниппетов в одной папке.

Также сниппеты для одного языка программирования можно объединять в папки. В этом случае имя папки - это название языка (syntax), а имя файла сниппета может быть произвольным.

На самом деле snipmate обладает еще некоторыми опциями, связанными с именами файлов, но мы их упоминать не будем, их можно найти в справке по вышеуказанной ссылке.

В одном файле .snippets может располагаться несколько сниппетов. Их формат выглядит следующим образом:

snippet триггер
        Код сниппета
        ...

Под триггером понимается то сокращение, которое нужно ввести в Vim, после чего нажать клавишу Tab (это по умолчанию, при желании клавиша настраивается), в результате триггер будет заменен на текст сниппета.

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

snippet #!
        #!/usr/bin/env python
        # -*- coding: utf-8 -*-

Этот сниппет просто добавляет заголовок скриптов Python при вводе #!<Tab>.

Сниппеты могут быть более умными. Вот, например, сниппет для ввода конструкции with Python. В этом случае мы можем перемещаться от одного поля ввода (${1:expr}, ${2:var}) к следующему с помощью клавиши Tab.

snippet with
        with ${1:expr} as ${2:var}:
                ${0}

Следующая анимированная gif-ка показывает работу этого плагина.

Если клавиша Tab у вас уже задействована другим плагином, то вы можете установить новую горячую клавишу для плагина snipmate, добавив в файл .vimrc следующие строки (в них показана привязка к горячей клавише Ctrl+J):

:imap <C-J> <Plug>snipMateNextOrTrigger
:smap <C-J> <Plug>snipMateNextOrTrigger

Хорошей альтернативой snipmate, возможно даже более более мощной, является плагин ultisnips, который использует сниппеты у том же формате, поэтому для него также подходит набор сниппетов из vim-snippets. У меня он даже лучше работает с клавишей Tab, если на ней висит еще и автодополнение.

Плагин The NERD Tree. Отображение дерева папок

В прошлой статье про настройку Vim я писал про плагин winmanager, выполняющую ту же задачу. С того времени я долго выбирал между winmanager и The NERD Tree. В winmanager подкупало наличие списка текущих буферов под деревом каталогов, но зато в The NERD Tree можно добавлять файлы в закладки, а также есть выбор - открывать файл в текущем окне или в новой вкладке.

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

nerdtree.png: 1180x970, 217k (26.11.2014 09:25)

Все действия с деревом папок по умолчанию осуществляются через командную строку Vim. Например, для отображения или скрытия дерева служит команда :NERDTreeToggle. Поскольку эта функция часто используется, есть смысл ее повесить на горячую клавишу, как это показано далее (в этом примере в качестве горячей клавиши используется сочетание <Ctrl+W><Ctrl+T>):

nmap <C-W><C-T> :NERDTreeToggle<CR>

В The NERD Tree удобно, что если в окне с деревом папок нажать клавишу "?", то отобразятся горячие клавиши, используемые в The NERD Tree.

nerdtree_keys.png: 1180x970, 241k (26.11.2014 09:25)

Файлы можно открывать как в текущем окне (выбрав файл, и нажав клавишу Enter), так и в новой вкладке (с помощью клавиши "t").

Среди полезных настроек плагина стоит упомянуть параметр NERDTreeIgnore, позволяющий скрывать некоторые файлы или каталоги в дереве. Например, следующая строка позволяет не видеть в дереве файлы *.pyc и папку репозитория .git:

let NERDTreeIgnore=['\.pyc$', '\.git$']

По умолчанию поведение плагина удобное, но я у себя в .vimrc установил следующий параметр:

let NERDTreeQuitOnOpen=1

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

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

Плагин session. Более удобная работа с сессиями

Под сессией в Vim понимается текущее состояние программы - в первую очередь это список открытых файлов (в том числе и во вкладках), а также множество более мелких настроек вроде текущего положения курсора, текущего искомого слова (с помощью команды /) и т.п. Даже без всяких плагинов работа с сессиями в Vim довольно удобная, для сохранения сессии предназначена команда mksession (или в сокращенном виде - mks).

Введя команду наподобие

mks ~/mysession.vim

мы сохраним текущее состояние программы в файл mysession.vim в домашней директории. Этот файл содержит скрипт на встроенном в Vim языке (отсюда и расширение .vim, хотя это и не обязательно), выполнив который с помощью команды source (или в сокращенном виде so), вернемся к тому состоянию Vim, в котором были.

Это полезно, если использовать Vim как полноценную среду разработки, особенно если работать одновременно над несколькими проектами, тогда для каждого проекта будет свой файл сессии. И вот тут начинаются не то, чтобы проблемы, но некоторые неудобства.

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

Во-вторых, каждый раз при открытии сессии вы должны помнить путь до файла *.vim вместе с именем файла. Можно приучить себя сохранять все сессии в одном и том же месте (лучше, конечно, не в корень домашней папки), но все-равно при вводе команды so приходится весь этот путь набирать вручную, хотя автодополнение здесь заметно помогает.

И, в третьих, хотелось бы, чтобы при последующем запуске Vim последняя открытая сессии сама восстанавливалась.

Именно эти задачи решает плагин session, представляющий собой удобную оболочку поверх mksession.

После установки плагина будет создана папка sessions внутри папки .vim, куда будут сохраняться все сессии. При желании путь до папки с сессиями можно изменить с помощью параметра g:session_directory в файле .vimrc.

На мой взгляд, есть смысл сразу после установки плагина установить следующие параметры файле .vimrc:

let g:session_autosave = 'yes'
let g:session_default_to_last = 1
let g:session_autoload = 'yes'

Параметр g:session_autosave указывает плагину, что сессию нужно молча сохранять при выходе из Vim, а также когда открывается другая сессия. Если этот параметр не установить, то при указанных действиях будет выводиться диалог, спрашивающий, нужно ли сохранять сессию. Если этот параметр установить в no, то сессии автоматически никогда ну будут обновляться.

Параметр g:session_default_to_last говорит, что при запуске Vim нужно открывать последнюю используемую сессию. При этом плагин работает умно, если вы открываете Vim, передав ему в качестве параметра командной строки имя файла, т.е. vim abyrvalg.txt, то это не повлияет на сессии, они использоваться не будут.

Параметр g:session_autoload позволяет отключить еще один диалог с вопросом, на этот раз о том, действительно ли вы хотите открыть последнюю используемую сессию при запуске программы. Если этот параметр уснановлен в yes, то это равносильно тому, что мы всегда всегда нажимаем кнопку "Да".

А теперь о том, как с этим плагином работать. Этот плагин добавляет несколько команд, наиболее важные из которых - это :SaveSession и :OpenSession.

Если ввести команду :SaveSession без параметров, то сессия будет сохранена в папку session с именем по умолчанию - default. При желании это имя можно поменять с помощью параметра g:session_default_name. Если же ввести команду наподобие следующей:

:SaveSession test

то сессия будет сохранена под именем "test". При желании вы можете найти файлы default.vim, test.vim и другие ваши сессии в папке sessions, о которой говорилось выше.

Если теперь ввести команду

:OpenSession

То будет выведен список сохраненных сессий. На данный момент у меня это выглядит так:

Также после установки плагина появятся команды :DeleteSession и :CloseSession. Их назначение понятно из названия.

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

Плагин tComment. Удобное комментирование кода

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

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

:help tcomment

Этот плагин имеет огромное количество настроек и возможностей, но я его устанавливаю из-за одной команды, которая по умолчанию вызывается с помощью горячей клавиши <Ctrl+_><Ctrl+_>. Эта комбинация закомментаривает текущую или выделенные строка, а если они уже были закомментарены, то снимает комментирование.

Редактирование текста сразу в нескольких местах

На поиск этого и описанных далее в этой статье плагинов меня сподвигло использование в течение некоторого времени другого замечательного текстового редактора - Sublime Text. Возможно, некоторые из этих возможностей есть и в других текстовых редакторах, но обратил внимание на них я благодаря ему.

Наиболее известная возможность Sublime Text - это так называемая многокурсорность, когда курсор устанавливается сразу в нескольких участках кода, и редактирование происходит сразу в нескольких местах. Это удобно для рефакторинга, чтобы не использовать "тяжелую артиллерию" наподобие :%s/... или rope, описанный выше.

Благодаря разработчикам плагинов, Vim не отстает от этой новой моды и тоже имеет может иметь несколько курсоров, для этого достаточно установить плагин vim-multiple-cursors.

Этот плагин работает следующим образом. Сначала устанавливаем курсор на слово, которое надо изменить в некоторых местах программы, как правило, это имя переменной или функции. Затем в нормальном режиме нажимаем горячую клавишу Ctrl+n (при желании эту клавишу можно изменить с помощью параметра g:multi_cursor_next_key), после чего слово останется выделенным, а также выделится следующее такое же слово, и курсор перескочит на него. Нажимая Ctrl+n несколько раз, можно выделить все вхождения слова, которое нужно изменить, после чего получаем, что у нас сразу несколько виртуальных курсоров установлены на этих словах. Затем мы можем перейти в визуальный режим или режим вставки и редактировать это слово сразу в нескольких местах. Если в каком-то месте слово изменять не нужно, то при попадании курсора на него нажимаем горячую клавишу Ctrl+x (эта клавиша настраивается с помощью параметра g:multi_cursor_skip_key), и курсор на этот слове установлен не будет.

Честно говоря, работает этот плагин с некоторыми проблемами. Например, если мы хотим изменить название переменной arg в следующем коде:

  1. class MyClass (object):
  2.     """docstring for MyClass """
  3.     def __init__(self, arg):
  4.         super(MyClass, self).__init__(arg)
  5.         self.arg = arg
  6.         print arg

Если сначала установить курсор на переменную arg на 5-й строке, то последующие выделения этой переменной пройдут как положено, а если первое выделение будет на третьей строке, то плагин почему-то начинает искать не слово arg, а arg) со скобкой, и, разумеется, большую часть нужных переменных не находит. Да и во время самой работы плагина иногда возникают ошибки.

К счастью, в плагине есть возможность выделения участков кода с помощью регулярных выражений, но в этом случае иногда проще использовать команду :s.

Для еще более гибкой расстановки точек замены можно использовать плагин vim-multiedit. Он позволяет расставлять ключевые точки вручную с помощью комбинации клавиш <leader>mi, а потом разом изменять текст в отмеченных точках. К сожалению, этот плагин тоже работает не безупречно.

В целом, пока Sublime Text по данной возможности опережает Vim, будем надеяться, что со временем плагины для Vim станут более стабильными.

Быстрое перемещение строк вверх / вниз

Другая возможность, подсмотренная в Sublime Text, - это удобное перемещение строк вверх / вниз. Часто это нужно, чтобы во время рефакторинга перенести какой-то участок кода из одной функции в другую, внести его в цикл или вынести из цикла. При этом желательно автоматически корректировать отступы (а в Python это делать нужно в любом случае).

Для того, чтобы сэкономить несколько нажатий клавиш на это действие, пригодится плагин vim-move.

После его установки с помощью клавиш Alt+J / Alt+K можно будет перемещать текущую строку или выбранные строки вниз и вверх соответственно, как это показано на следующей анимации:

Если вы хотите использовать клавишу Ctrl вместо Alt, то в файл .vimrc нужно добавить следующую строку:

let g:move_key_modifier = 'C'

Если вам проще использовать стрелки, а не "классическое" перемещение по тексту с помощью клавиш J и K, то можете добавить в файл .vimrc следующие строки:

vmap <C-Down> <Plug>MoveBlockDown
vmap <C-Up> <Plug>MoveBlockUp
nmap <C-Down> <Plug>MoveLineDown
nmap <C-Up> <Plug>MoveLineUp

Этот плагин достаточно простой и каких-либо проблем с его работой замечено не было.

Выделение измененных строк

Во многих средах разработки есть возможность выделять строки, которые были изменены или с момента последнего коммита в систему контроля версий, или с момента открытия файла. Обе эти возможности поддерживает плагин changesPlugin, но в данном разделе я все-таки хочу рассказать о другом, более ограниченном по возможностям плагине, но который чисто субъективно мне нравится больше - это плагин vim-gitgutter.

Этот плагин работает только с системой контроля версий Git, но свою задачу выполняет отлично, а также имеет множество настроек. Сразу после его установки можно даже ничего не настраивать. Если открыть какой-нибудь файл, находящийся в репозитории git, как-то его изменить (добавить, удалить или исправить некоторые строки), то рядом с кодом появится еще один столбец, в которых будут отмечены плюсиками новые строки, минусами - места, где строки были удалены, а тильдами - измененные строки. Например:

Поведение плагина по умолчанию на мой взгляд очень удачное - он не пытается искать изменения при каждом введенном символе (в отличие от changesPlugin, хотя там тоже есть простор для настроек и оптимизации), благодаря чему работу редактора совсем не тормозит. Проверка на изменение происходит в момент сохранения файла, после окончания ввода текста (когда в течение некоторого количества секунд не происходило никаких изменений) и в момент некоторых других событий вроде переключения буфера или вкладок. Реакцию на каждое это событие можно настраивать (нужно в этот момент проверять изменения или нет). Лично я все оставил по умолчанию и тормозов не наблюдаю.

В плагине есть настройки для изменения символов, обозначающих новые / исправленные / удаленные строки. Можно, например, для наглядности сделать так, чтобы строки отмечались не одним символом, а двумя:

let g:gitgutter_sign_added = '++'
let g:gitgutter_sign_modified = '~~'
let g:gitgutter_sign_removed = '--'
let g:gitgutter_sign_removed_first_line = '^^'
let g:gitgutter_sign_modified_removed = '~_'

Выглядеть это будет так:

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

let g:gitgutter_sign_added = '➕'
let g:gitgutter_sign_modified = '✔'
let g:gitgutter_sign_removed = '➖'
let g:gitgutter_sign_removed_first_line = '^'
let g:gitgutter_sign_modified_removed = '~_'

Выглядит это все следующим образом:

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

let g:gitgutter_highlight_lines = 1

Результат будет выглядеть примерно так:
align="center"

Наверное, внешний вид этой подсветки настраивается, но что-то по умолчанию она меня не впечатлила, и я от нее сразу же отказался.

Тема в стиле Sublime Text

Я всю свою сознательную жизнь был сторонником светлых тем оформления кода, пока не попробовал использовать Sublime Text, в котором мне очень понравилась раскраска по умолчанию, которая называется Monokai. Вернувшись на Vim, я начал искать ее аналоги, коих оказалось не так мало. Но мне больше всего понравилась тема, не копирующая Monokai один в один, а та, где автор подошел к задаче творчески - эта тема называется molokai.

Устанавливается эта тема, как и любая другая, либо копированием файла molokai.vim в папку .vim/colors, либо с помощью Vundle добавлением следующей строки между командами call vundle#begin() и call vundle#end().

Plugin 'tomasr/molokai'

с последующим вызовом команды :PluginInstall.

Затем в файл .vimrc нужно добавить строку

color molokai

Эта тема может работать в "совсем темном" стиле (значение по умолчанию), или может установить цвет фона в точности как у Sublime Text. Если вам нужен второй вариант, то строки установки темы должны выглядеть следующим образом:

let g:molokai_original = 1
color molokai

Строка let g:molokai_original = 1 должна обязательно идти до команды color molokai.

Выглядят эти темы следующим образом:

molokai.png: 1231x1000, 138k (26.11.2014 09:25)
let g:molokai_original = 0
molokai_original.png: 1231x1000, 140k (26.11.2014 09:25)
let g:molokai_original = 1

Заключение

На этом статья заканчивается, я очень надеюсь, что она окажется вам полезна, и использование Vim станет еще более приятным. Надеюсь, что в будущем будут появляться еще подобные статьи. Тем, кто дочитал до этих строк, спасибо за внимание. :)

Немного рекламы

Вы можете подписаться на новости сайта через RSS, Группу Вконтакте или Канал в Telegram.
5 stars

Рейтинг 4.9/5. Всего 18 голос(а, ов)



Sanitatier 26.11.2014 - 14:49

Спасибо.

ulole 27.11.2014 - 11:52

Отлично, спасибо!

Vladimir 05.12.2014 - 04:26

Хорошая цветовая схема Solarized:
https://github.com/altercation/vim-colors-solarized
И ее можно подключить через Vundle тоже.

 02.04.2015 - 22:47

Я очень благодарен Вам за эту статью!
У Вас не плохо получается, приятно и понятно такое читать.
(делаю только первые шаги в VIM)


Подписаться на комментарии
Автор:
Тема:
 Ваш комментарий
 
 
Введите код 505