Курилка

Перевод с английского © Гиви Хакеридзе. Слайды VIM for (PHP) Programmers на zmievski.org.
См. также Vim-galore — по-русски, Ваша проблема с Vim заключается в том, что вы не въехали в vi.

Vim для (PHP-)программистов

Андрей Змиевский (Andrei Zmievski)

Open Source Fellow, Digg
Twitter: @a
http://gravitonic.com/

PHP Québec Conf ~ March 5, 2009


Справка

Научитесь эффективно использовать справку, :help — ваш друг. Используйте CTRL-V перед командами с CTRL. Используйте префиксы i_ и v_ для получения справки по последовательностям с CTRL в режиме вставки и визуальном режиме. В окне справки используйте CTRL-] (прыжок к тегу) и CTRL-T (перейти обратно).

Введение

Насколько хорошо вы знаете язык Vim-а? Какой у него алфавит? Посмотрите на вашу клавиатуру. Вы можете сказать, что делает каждая клавиша? Что такое режимы? Сколько вы их знаете? А сколько используете?

Если язык вам не нравится, измените его.

Пример: Что вы делаете, чтобы быстро выйти из Vim-а?

или

Совет: set showcmd позволяет видеть частично введённые команды.

Где я?

Как узнать, где вы находитесь?

Побалуйте себя и выполните set ruler, которая покажет в строке статуса номер строки, колонки и проценты. Или сконфигурируйте её так, как вам будет угодно, при помощи 'rulerformat'.

Перемещение

Вы используете для перемещения h/j/k/l? Или застряли в стрелках мира GUI? Если так, переучивайтесь. Спасите себя от бессчётных миль перемещений между домашним рядом клавиш и стрелками.

Как переместиться к:

Метки

Мы можем запоминать положение в буфере:

Метки очень полезны в изменении текста. Установите метку (допустим ma). Теперь можно:

Допустим, что вы куда-то перепрыгнули. Как вернуться обратно? ` ` переносит между двумя последними позициями. Можно явно установить ` (метку контекста): m` , перепрыгнуть куда-нибудь, а затем вернуться назад при помощи ` `.

Совет: CTRL-O и CTRL-I переносят между позициями во всей истории прыжков, но не могут быть использованы в качестве перемещений (как напр., w или Gпер.).

'. и `. — перепрыгнуть к строке или точному положению последнего изменения.

Вставка

gi — невероятно удобная комбинация. Переводит в режим вставки в том месте, где она производилась в последний раз. Сценарий: измените что-нибудь, выйдите из режима вставки, посмотрите что-то в другом месте, а затем при помощи gi вернитесь назад и возобновите редактирование.

Еще немного вкусностей:

Удаление

Освободите ваш <Backspace>:

:set backspace=start,indent,eol

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

Поиск

Поиск очень важен. Перемещение и информация. Как вы ищите? Чем-то вроде f/F/t/T? Что насчёт * и #?

Поиск в строке:

Часто бывает нужно посмотреть другие употребления слова под курсором:

Или найти строки с некоторым словом: [I и ]I покажут их список.

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

:map ,f [I:let nr = input("Which one: ")<Bar>exe "normal " . nr ."[\t"<CR>

И, конечно, есть поиск с использованием регулярных выражений:

Язык регулярных выражений Vim-а слишком сложен для изложения здесь.

Управляйте вашими настройками поиска:

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

Замена

:[диапазон]s/<шаблон>/<замена>/{флаги} — команда замены, используется обычно с диапазоном адресов, очень мощной вещью (читайте справку). Но кто захочет считать строки и делать что-то подобное :-23,’ts/foo/bar/? На самом деле вы будете использовать пару сокращений или просто визуальный режим.

Часто используемые диапазоны:

Текстовые объекты

Познакомьтесь с ними поближе, потому что их фантастически удобно использовать после оператора или в визуальном режиме. Встречайте два типа — «inner» (внутри) и «ambient» (вокруг). «Внутри» всегда выбирает меньше текста, чем «вокруг».

Есть ещё более крутые:

Заметьте, что эти объекты знают об экранированных кавычках внутри строки.

Примеры:

Копирование/удаление/вставка

Это вы уже должны знать:

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

:nnoremap <Esc>P  P'[v']=
:nnoremap <Esc>p  p'[v']=

Регистры

Регистры — ваш многоцелевой буфер обмена. Вы используете их, даже не зная о них. Каждая команда y или d копирует в регистр, не именованный или именованный. "<буква> перед командой копирования/удаления/вставки указывает регистр с именем <буква>.

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

В регистры можно записывать макрокоманды:

Для просмотра содержимого регистров используйте :reg.

Отмена

У оригинального vi был только один уровень отмены. Ха! А Vim имеет бесконечное количество (ограниченное только памятью). Установите 'undolevels' таким, какое вам нужно (по умолчанию — 1000).

Простой пример: u — отмена, CTRL-R — повторение.

В Vim 7-й версии добавлена отмена с ветвлениями. Если отменить что-то, а затем сделать изменения, то создаётся новая ветка. g-, g+ — переход к более старому/новому состоянию текста (по всем веткам).

Можно путешествовать во времени:

:earlier 10m — вернуться на 10 минут назад до того, как я выпил банку Red Bull и сделал эти дурацкие изменения. Уфф.

Визуальный режим

Используйте его, потому что это проще, чем запоминать непонятные диапазоны или команды перемещения.

Начните выделение с:

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

Блочный визуальный режим это — вообще что-то. Особенно для текста в виде таблиц.

Совет: o переносит курсор на другой конец выделения, где можно продолжить выделение.

Как только вы оказались в блочном режиме:

Аббревиатуры

Замена строк в реальном времени. Подстановка выполняется, когда набран символ не ключевого слова:

:ab tempalte template — исправление опечатки

Расширение посложнее:

:iab techo <?php echo ?><Left><Left><Left>

Окна

Научитесь работать с окнами. Как перемещаться между ними. :new, :sp должны быть на кончиках ваших пальцев. Очень важно изучить команды с CTRL-W для изменения размеров окон и перемещения между ними.

Страницы с табами

Начиная с 7-й версии, Vim поддерживает вкладки.

Возможно, вы захотите замапить это для более удобной навигации, (если gt, gT для вас слишком сложно).

Дополнение

Vim очень дружественен в дополнении. В командной строке просто используйте <Tab>:

Нажимайте <Tab> повторно для прохода в цикле, CTRL-N для следующего совпадения, CTRL-P — для предыдущего.

CTRL-X, за которым следуют комбинации с CTRL-, включает режим дополнения в режиме вставки. Я в основном использую дополнение имён файлов, идентификаторов и омни-дополнение. Когда имеется несколько совпадений, появляется окошечко с вариантами.

У меня есть отличный ремапинг для <Tab>:

“ Вставить <Tab> или дополнить идентификатор,
“ если курсор находится после символа ключевого слова
function MyTabOrComplete()
    let col = col('.') - 1
    if !col || getline('.')[col-1] !~ '\k'
        return "\<tab>"
    else
        return "\<C-N>"
    endif
endfunction

inoremap <Tab> <C-R>=MyTabOrComplete()<CR>

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

Мапинги

Сделали мапинги для каждого режима режимов и утомились менять текст в кавычках?

:nmap X ci"

Сделать Vim похожим на браузер?

:nmap <Space> <PageDown>

Быстро вставить ваш e-mail?

:imap ;EM me@mydomain.com

Пусть <Backspase> в визуальном режиме работает как <Delete>?

:vmap <BS> x

Опции

У Vim-а — сотни опций. Изучите их, чтобы управлять ими так, как вам нужно.

Сессии

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

Разное

Настройки

Настройте Vim, разместив файлы в каталоге ~/.vim (в этом каталоге vimrc д.б. без точки — пер.)

.vimrc - глобальные настройки
.vim/
    after/ - файлы, которые загружаются в последнюю очередь
    ftplugin/
    plugin/
    syntax/
    ...
    autoload/ - автоматически загружаемые скрипты
    colors/ - пользовательские цветовые схемы
    doc/ - документация к плагинам
    ftdetect/ - скрипты для определения типа файла
    ftplugin/ - плагины для типов файла
    indent/ - скрипты для отступов
    plugin/ - плагины
    syntax/ - скрипты для подсветки синтаксиса

PHP: линтинг

Vim поддерживает произвольные команды сборки/линтинга, если настроить 'makeprg' и 'errorformat' правильно:

:set makeprg=php\ -l\ %
:set errorformat=%m\ in\ %f\ on\ line\ %l

Теперь достаточно набрать :make (и пару раз <Enter>), и курсор будет помещён на строку с синтаксической ошибкой.

PHP: парные скобки

Вы уже должны быть знакомы с командой % (переместить курсор к паре), которая используется для (), {}, [] и т.д. Но такое можно использовать и для прыжков между тегами PHP и HTML. Используйте плагин matchit.vim. Но syntax/php.vim содержит ошибки и опечатки в правиле поиска соответствия. Я предлагаю своё.

PHP: блочные объекты

Схожие с Vim-овскими встроенными объектами:

Примеры:

Всё это — в моём файле .vim/ftplugin/php.vim.

PHP: опции синтаксиса

У Vim-а есть очень полезные плагины для синтаксиса PHP, которые имеют несколько опций:

PHP: свёртки

Научитесь управлять свёртками:

PHP: теги

Для Vim теги это — идентификаторы PHP (классы, функции, константы). Если у вас файл с тегами, то можно быстро переходить к определению любого тега. Установите Exuberant Ctags. Он умеет сканировать ваши скрипты и выводить файл с тегами, содержащий информацию об идентификаторах. В данный момент он не поддерживает информацию о членах класса (выводит методы как функции). Для исправления этого приходится применять сторонний патч.

Для пересборки файла с тегами после редактирования используйте мапинг:

nmap <silent> <F4>
    \ :!ctags -f ./tags
    \ --langmap="php:+.inc"
    \ -h ".php.inc" -R --totals=yes
    \ --tag-relative=yes --PHP-kinds=+cf-v .<CR>

set tags=./tags,tags

Будут рекурсивно просканированы все PHP-файлы в текущем каталоге и подкаталогах.

См. также плагин taglist.vim.

PHP: дополнение

В Vim 7 появилось мощное омни-дополнение основанное на эвристике. CTRL-X CTRL-O начинает дополнение (я замапил это на CTRL-F). На основании контекста умно дополняет классы, переменные, методы. Встроенные функции дополняет тоже. Дополнение функции показывает прототип. array_<CTRL-X><CTRL-O> покажет список функции для работы с массивами. Выберите одну из списка, и в окне предварительного просмотра будет показан прототип. CTRL-W CTRL-Z — чтобы закрыть окно предварительного просмотра. Вне блоков PHP переключается на дополнение HTML/CSS/JavaScript.

Дополнительно см.:

:help ins-completion
:help popupmenu-completion
:help popupmenu-keys
:help ft-php-omni

Плагины

Vim можно бесконечно настраивать и расширять при помощи плагинов. Их написано уже тысячи. Установка очень проста, просто бросьте их в каталог .vim/plugin. Однако сначала прочтите инструкции.

netrw

Позволяет читать, записывать и просматривать удалённые каталоги и файлы. Обычно я использую его по ssh-соединению при помощи протокола scp. Чтобы избежать постоянных запросов пароля, нужно запустить ssh-агента. Не используйте беспарольные ключи! Когда настроите, используйте:

vim scp://hostname/path/to/file
:new scp://hostname/path/to/dir/

NERDTree

Похож на браузер netrw, но больше похож на проводник по иерархии каталогов. Не поддерживает удалённые файловые операции.

:nmap <silent> <F7> :NERDTreeToggle<CR>

taglist

Обеспечивает обзор исходного кода. Предоставляет быстрый доступ к классам, функциям и константам. Автоматически обновляет окно при переключении буферов. Может показывать прототип и область видимости тега. Требует наличия Exuberant Ctags.

Сохраните это в ~/.vim/after/plugin/general.vim:

let Tlist_Ctags_Cmd = "/usr/local/bin/ctags-ex"
let Tlist_Inc_Winwidth = 1
let Tlist_Exit_OnlyWindow = 1
let Tlist_File_Fold_Auto_Close = 1
let Tlist_Process_File_Always = 1
let Tlist_Enable_Fold_Column = 0
let tlist_php_settings = 'php;c:class;d:constant;f:function'
if exists('loaded_taglist')
    nmap <silent> <F8> :TlistToggle<CR>
endif

snippetsEmu

Реализует некоторую функциональность снипетов TextMate. Поддерживает многие языки, включая PHP/HTML/CSS/JavaScript. По умолчанию привязывается к <Tab>, но это раздражает, приходится переназначать клавишу после его загрузки.

Поместите это в ~/.vim/after/plugin/general.vim:

if exists('loaded_snippet')
    imap <C-B> <Plug>Jumper
endif
inoremap <Tab> <C-R>=MyTabOrComplete()<CR>

php documentor

Автоматически вставляет блоки PHP Documentor. Работает в одно- и много-строчном режиме. По умолчанию не предоставляет мапинги. Прочитайте документацию, чтобы настроить переменные по умолчанию для копирайта, пакета и т.д.

Добавьте это в ~/.vim/ftplugin/php.vim:

inoremap <buffer> <C-P> <Esc>:call PhpDocSingle()<CR>i
nnoremap <buffer> <C-P> :call PhpDocSingle()<CR>
vnoremap <buffer> <C-P> :call PhpDocRange()<CR>
let g:pdv_cfg_Uses = 1

project

Предоставляет управление файлами проекта как в IDE. Позволяет группировать файлы и быстрый доступ к ним. Может искать и выполнять произвольные команды.

0scan

Поиск различной информации, основанный на тегах. Быстрый доступ к:

xdebug-ger

Позволяет отладку при помощи xdebug по протоколу DBGp. Достаточно прост, но работу делает. Нужно, чтобы Vim был скомпилирован с опцией +python. См. раздел ресурсов для ссылок на документацию.

vcscommand

Предоставляет интерфейс с CVS/SVN/git. Установите его, затем выполните :help vcscommand.

Заключение

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

Ресурсы


«Как и во всем остальном, лучше не заглядывать в это слишком глубоко»

Спасибо!

http://joind.in/121
http://digg.com/
http://gravitonic.com/talks/