суббота, 26 июля 2008 г.

Очередной HowTo по Vim

Ранее я уже выкладывал небольшой HowTo по Vim. Тогда я только начинал свое знакомство с ним и решил, что на начальном этапе изучения лучше руководствоваться различными tutorial'ами и HowTo, а официальную документацию пока оставить в стороне. Почему? А потому, что если вы только начинаете изучать Vim, то вы еще не знаете, что вам от него нужно - необходим определенный опыт работы, чтобы при чтении документации вы смогли бы наиболее точно оценить, какие функции будут вам полезны, а о каких можно забыть. Все команды вы все равно не запомните - уж слишком их много, поэтому приходится отсеивать только те, которыми вы действительно будете пользоваться.

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

Подобные HowTo просто подарок судьбы для начинающих пользователей Vim'a, т. к., прочитав их и скопипастив строчки из чужих конфигов в свои, они уже смогут работать в нем, не испытывая при этом особого дискомфорта. Данный HowTo предполагает, что вы уже знаете Vim в объеме Vim Tutor. Опытные пользователи, которые не смогли найти время для прочтения документации, также, возможно, найдут что-то полезное для себя в этой статье - я, например, к своему стыду, о командах gj и gk узнал именно из документации, но сколько же я без них мучился... :)



Ввод команд при русской раскладке клавиатуры

С этой проблемой вы сталкиваетесь практически мгновенно, как только начинаете пользоваться Vim. Если у вас включена русская раскладка клавиатуры, то сразу же перестают работать все командные клавиши (т. е., например, при нажатии на dd в Normal режиме строка не удаляется, когда у вас включена русская раскладка клавиатуры). Переключаться на английскую раскладку только для того, чтобы ввести какую-нибудь команду - слишком большая трата времени, да и довольно утомительное занятие.

Я нашел два способа решения этой проблемы. Каждый из них имеет свои недостатки и преимущества, так что, какой из них использовать - выбирать вам.


Первый способ

Первый способ заключается в том, что вы вставляете в свой ~/.vimrc следующие строки:
map ё `
map й q
map ц w
map у e
map к r
map е t
map н y
map г u
map ш i
map щ o
map з p
map х [
map ъ ]
map ф a
map ы s
map в d
map а f
map п g
map р h
map о j
map л k
map д l
map ж ;
map э '
map я z
map ч x
map с c
map м v
map и b
map т n
map ь m
map б ,
map ю .
map . /

map Ё ~
map Й Q
map Ц W
map У E
map К R
map Е T
map Н Y
map Г U
map Ш I
map Щ O
map З P
map Х {
map Ъ }
map Ф A
map Ы S
map В D
map А F
map П G
map Р H
map О J
map Л K
map Д L
map Ж :
map Э "
map Я Z
map Ч X
map С C
map М V
map И B
map Т N
map Ь M
map Б <
map Ю >
map , ?

map ; $
Эти команды просто создают привязки русских клавиш к английским. Недостаток данного метода в том, что после вставки этих строк работают не все команды. Например, команды фолдинга (za, zM и т. п.) не работают. Это можно исправить, добавив привязки яф -> za и яЬ -> zM, но не будете же вы делать так для каждой команды, которую вы используете... К тому же это - костыль. Причем костыль довольно плохой - в данных командах я привязываю не только русские символы к английским, но и такие символы как, например, ; -> $, что уже очень не хорошо.


Второй способ

Данный способ более естественный для Vim. Вы добавляете в ~/.vimrc строки
" Настраиваем переключение раскладок клавиатуры по <C-^>
set keymap=russian-jcukenwin

" Раскладка по умолчанию - английская
set iminsert=0
и теперь можете переключаться между раскладками комбинацией клавиш <C-^>. При таком способе все команды работают идеально. Недостаток очевиден - необходимо использовать комбинацию клавиш для переключения раскладки, отличную от используемой в остальных приложениях.

Я довольно долго использовал первый способ, но как только узнал о втором, стал использовать его. Я переназначил переключение раскладок на комбинацию <C-F> и добавил индикацию выбранной в данный момент раскладки путем изменения цвета статусной строки текущего окна (см. мой ~/.vimrc далее) - на мой взгляд, получилось очень даже не плохо. К <C-F> я привык на удивление быстро и теперь никак не нарадуюсь. :)



Использование различных настроек для разных типов файлов

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

Настройки для каждого файла хранятся в директории ~/.vim/ftplugin. Vim определяет абсолютное большинство всевозможных форматов файлов, но если вдруг ему это не удалось, то можно задать собственное правило для определения нужного вам формата.

Посмотреть тип, который Vim назначил открытому в данный момент файлу, можно командой :set filetype. К примеру, если вы откроете *.c файл, то Vim выдаст filetype=c.

Когда вы открываете в Vim, например, файл *.py, содержащий программу, написанную на Python, он ищет в ~/.vim/ftplugin файл python.vim и директорию python. Если они присутствуют, то Vim загружает файл ~/.vim/ftplugin/python.vim и все *.vim файлы в директории ~/.vim/ftplugin/python.

У меня директория ~/.vim/ftplugin имеет следующий вид:
~/.vim/ftplugin
|-- awk.vim -> ../develop.vim
|-- c.vim -> ../develop.vim
|-- cpp.vim -> ../develop.vim
|-- js.vim -> ../develop.vim
|-- make.vim -> ../develop.vim
|-- php.vim -> ../develop.vim
|-- python
| |-- custom_settings.vim
| `-- python_folding.vim
|-- python.vim -> ../develop.vim
|-- sed.vim -> ../develop.vim
|-- sh.vim -> ../develop.vim
|-- sql.vim -> ../develop.vim
`-- vim.vim -> ../develop.vim


Как вы видите, у меня для всех форматов файлов, имеющих какое-либо отношение к программированию, есть свой конфигурационный файл в ~/.vim/ftplugin, причем в качестве этого файла выступает символическая ссылка на ~/.vim/develop.vim, который содержит настройки, общие для файлов, содержащих какой-либо код.

Для Python'овских файлов у меня также предусмотрены дополнительные настройки в виде конфигурационных файлов ~/.vim/ftplugin/python/custom_settings.vim и ~/.vim/ftplugin/python/python_folding.vim.

~/.vim/ftplugin/python/python_folding.vim - это плагин, обеспечивающий свертку блоков кода. Содержимое файлов ~/.vim/develop.vim и ~/.vim/ftplugin/python/custom_settings.vim я приведу ниже в разделе "Конфигурационные файлы".



Использование Vim в качестве IDE (среды разработки)

Для этого у меня написан небольшой скрипт:
#!/bin/bash
#
# Скрипт запуска среды разработки Vim
#

if [[ $# != 1 ]]
then
    zenity --title "Vim IDE usage error" --error --text "Usage: vim_ide /path/to/project/dir."
    exit 1
fi

if [[ ! -e "$1/.vim/ide.vim" ]]
then
    zenity --title "Vim IDE usage error" --error --text "'$1' is not a Vim IDE project directory."
    exit 1
fi

cd "$1" || { zenity --title "Vim IDE usage error" --error --text "Can't change current directory to Vim IDE project directory '$1'."; exit 1; }

gvim --class=IDE -S .vim/ide.vim

Данному скрипту в качестве аргумента я передаю путь к каталогу с проектом. Вся работа скрипта сводится к переходу в каталог проекта и запуску в нем Vim'а с классом окна 'IDE' и подгруженным дополнительным конфигурационным файлом ${путь к каталогу с проектом}/.vim/ide.vim.

Класс окна нужен для того, чтобы оконный менеджер в соответствии с заданными мной настройками развернул окно Vim'а на весь экран (никаких панелей инструментов, заголовков окон, меню и т. п. - только код программы и больше ничего :) ). Как отключить панель инструментов и меню, вы можете посмотреть в моем ~/.gvimrc (будет приведен в разделе "Конфигурационные файлы").

В директории каждого моего проекта лежит файл .vim/ide.vim, который задает все специфические настройки для данного проекта, такие как правила сборки или правила генерации ctags. В ~/.vimrc у меня назначена горячая клавиша для обновления ctags. Каждый проект задает собственную функцию для их обновления. Например, для C проекта у меня в make файле есть специальная цель vim, которая с помощью gcc получает все зависимости исходных текстов от заголовочных файлов и генерирует ctags только для файлов с исходным кодом проекта и подключаемых ими заголовочных файлов (а не для всего /usr/include :) ). Также эта цель просматривает только что сгенерированные тэги и при помощи awk и sed вытаскивает из них все typedef'ы, формируя из полученной информации файл с правилами подсветки синтаксиса для текущего проекта, который подгружается в .vim/ide.vim при запуске vim_ide.

Кроме того .vim/ide.vim при закрытии Vim сохраняет текущую сессию, а при запуске восстанавливает сохраненную. Таким образом, придя утром на работу, я открываю свой Vim IDE, а он устанавливает все буферы, табы, окна и их размеры такими, какими они были вчера при закрытии Vim'а.

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

Так, к примеру, выглядят мои ide.vim:

Для Python проекта:
" Конфигурационный файл Vim IDE

" Запрещаем восстановление настроек из сессии,
" т. к. тогда при изменении ~/.vimrc даже после
" перезагрузки IDE новые настройки не будут
" вступать в силу.
set sessionoptions-=options

" Настраиваем работу с ctags -->
    set tags+=.vim/ctags

    function! MyUpdateIdeCtags()
        silent !ctags --languages=Python -f .vim/ctags -.
    endfunction

    let MyUpdateCtagsFunction = "MyUpdateIdeCtags"
" Настраиваем работу с ctags <--

" Обновляем базу ctags при старте IDE
call {MyUpdateCtagsFunction}()

" При сохранении любого *.py файла обновляем базу ctags
au BufWritePost *.py :call {MyUpdateCtagsFunction}()

" При закрытии Vim'а сохраняем информацию о текущей сессии
au VimLeave * :mksession! .vim/ide.session

" Загружаем ранее сохраненную сессию -->
    if getfsize(".vim/ide.session") >= 0
        source .vim/ide.session
    endif
" Загружаем ранее сохраненную сессию <--


Для C проекта:
" Конфигурационный файл Vim IDE

" Запрещаем восстановление настроек из сессии,
" т. к. тогда при изменении ~/.vimrc даже после
" перезагрузки IDE новые настройки не будут
" вступать в силу.
set sessionoptions-=options

" Добавляем пути к библиотекам
set path+=/usr/include/gtk-2.0
set path+=./netlog

" Устанавливает правила синтаксиса, специфичные для данного проекта.
" -->
    function! MySetIdeSyntax()
        if getfsize(".vim/syntax.vim") >= 0
            source .vim/syntax.vim
        endif
    endfunction
" <--

" Настраиваем работу с ctags -->
    set tags=.vim/ctags

    function! MyUpdateIdeCtags()
        !make vim
    endfunction

    let MyUpdateCtagsFunction = "MyUpdateIdeCtags"
" Настраиваем работу с ctags <--

" Обновляем базу ctags при старте IDE
call {MyUpdateCtagsFunction}()

" При открытии нового буфера устанавливаем для него
" правила синтаксиса, специфичные для данного проекта.
au BufReadPost * :call MySetIdeSyntax()

" При закрытии Vim'а сохраняем информацию о текущей сессии
au VimLeave * :mksession! .vim/ide.session

" Загружаем ранее сохраненную сессию -->
    if getfsize(".vim/ide.session") >= 0
        source .vim/ide.session
    endif
" Загружаем ранее сохраненную сессию <--



Конфигурационные файлы

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

~/.vimrc:
" Включаем мышку даже в текстовом режиме
" (очень удобно при копировании из терминала, т. к. без этой опции,
" например, символы табуляции раскладываются в кучу пробелов).
set mouse=a

" Минимальная высота окна
set winminheight=0
" Минимальная ширина окна
set winminwidth=0
" Всегда отображать статусную строку для каждого окна
set laststatus=2

" Опции автодополнения - включаем только меню с доступными вариантами
" автодополнения (также, например, для omni completion может быть
" окно предварительного просмотра).
set completeopt=menu

" Размер табуляции
set tabstop=4
" Размер сдвига при нажатии на клавиши << и >>
set shiftwidth=4
" Копирует отступ от предыдущей строки
set autoindent
" Включаем 'умную' автоматическую расстановку отступов
set smartindent
" Включаем подсветку синтаксиса
syntax on

" Включаем перенос строк
set wrap
" Перенос строк по словам, а не по буквам
set linebreak

" Включаем отображение выполняемой в данный момент команды в правом нижнем углу экрана.
" К примеру, если вы наберете 2d, то в правом нижнем углу экрана Vim отобразит строку 2d.
set showcmd
" Включаем отображение дополнительной информации в статусной строке
set statusline=%<%f%h%m%r%=format=%{&fileformat}\ file=%{&fileencoding}\ enc=%{&encoding}\ %b\ 0x%B\ %l,%c%V\ %P

" Включаем подсветку выражения, которое ищется в тексте
set hlsearch
" При поиске перескакивать на найденный текст в процессе набора строки
set incsearch
" Останавливать поиск при достижении конца файла
set nowrapscan
" Игнорировать регистр букв при поиске
set ignorecase

" Отключаем создание бэкапов
set nobackup
" Отключаем создание swap файлов
set noswapfile
"" Все swap файлы будут помещаться в эту папку
"set dir=~/.vim/swp

"" Размер истории для отмены
"set undolevels=1000

" Список кодировок файлов для автоопределения
set fileencodings=utf-8,cp1251,koi8-r,cp866

" Включает виртуальный звонок (моргает, а не бибикает при ошибках)
set visualbell

" Перемещать курсор на следующую строку при нажатии на клавиши вправо-влево и пр.
set whichwrap=b,s,<,>,[,],l,h

" Метод фолдинга - вручную (для обычных файлов)
set foldmethod=manual

" Настраиваем переключение раскладок клавиатуры по <C-^>
set keymap=russian-jcukenwin
" Раскладка по умолчанию - английская
set iminsert=0

" Необходимо установить для того, чтобы *.h файлам
" присваивался тип c, а не cpp.
let c_syntax_for_h=""

" Просмотр нетекстовых файлов в Vim -->
    au BufReadPost *.pdf silent %!pdftotext -nopgbrk "%" - |fmt -csw78
    au BufReadPost *.doc silent %!antiword "%"
    au BufReadPost *.odt silent %!odt2txt "%"
" Просмотр нетекстовых файлов в Vim <--

" Горячие клавиши -->
    " Ускоренное передвижение по тексту
    nmap <C-H> 5h
    nmap <C-J> 5j
    nmap <C-K> 5k
    nmap <C-L> 5l

    " Клавиши быстрого редактирования строки в режиме вставки
    " и в режиме редактирования командной строки.
    " -->
        "imap <C-H> <BS>
        imap <C-J> <Left>
        imap <C-K> <Right>
        imap <C-L> <Del>

        "cmap <C-H> <BS>
        cmap <C-J> <Left>
        cmap <C-K> <Right>
        cmap <C-L> <Del>
    " <--

    " Стрелки для комментариев
    map - $a --><Esc>
    map = $a <--<Esc>

    " Запуск/сокрытие плагина Winmanager
    map <F1> :WMToggle<CR>
    imap <F1> <Esc>:WMToggle<CR>
    vmap <F1> <Esc>:WMToggle<CR>

    " Запуск/сокрытие плагина Tag List
    map <F2> :TlistToggle<CR>
    imap <F2> <Esc>:TlistToggle<CR>
    vmap <F2> <Esc>:TlistToggle<CR>

    " Очистить подсветку последнего найденного выражения
    nmap <F3> :nohlsearch<CR>
    imap <F3> <Esc>:nohlsearch<CR>
    vmap <F3> <Esc>:nohlsearch<CR>gv

    " Сохранить файл
    nmap <F4> :w!<CR>
    imap <F4> <Esc>:w!<CR>
    vmap <F4> <Esc>:w!<CR>

    " Закрыть VIM
    nmap <F5> :q<CR>
    imap <F5> <Esc>:q<CR>
    vmap <F5> <Esc>:q<CR>

    " Более привычные Page Up/Down, когда курсор остаётся в той же строке,
    " а не переносится вверх/вниз экрана, как при стандартном PgUp/PgDown.
    " Поскольку по умолчанию прокрутка по C-U/D происходит на полэкрана,
    " привязка делается к двойному нажатию этих комбинаций.
    nmap <PageUp> <C-U><C-U>
    imap <PageUp> <C-O><C-U><C-O><C-U>
    nmap <PageDown> <C-D><C-D>
    imap <PageDown> <C-O><C-D><C-O><C-D>

    " Переключение раскладок и индикация выбранной
    " в данный момент раскладки.
    " -->
        " Переключение раскладок будет производиться по <C-F>
        "
        " При английской раскладке статусная строка текущего окна будет синего
        " цвета, а при русской - зеленого.

        function MyKeyMapHighlight()
            if &iminsert == 0
                hi StatusLine ctermfg=DarkBlue guifg=DarkBlue
            else
                hi StatusLine ctermfg=DarkGreen guifg=DarkGreen
            endif
        endfunction

        " Вызываем функцию, чтобы она установила цвета при запуске Vim'a
        call MyKeyMapHighlight()

        " При изменении активного окна будет выполняться обновление
        " индикации текущей раскладки
        au WinEnter * :call MyKeyMapHighlight()

        cmap <silent> <C-F> <C-^>
        imap <silent> <C-F> <C-^>X<Esc>:call MyKeyMapHighlight()<CR>a<C-H>
        nmap <silent> <C-F> a<C-^><Esc>:call MyKeyMapHighlight()<CR>
        vmap <silent> <C-F> <Esc>a<C-^><Esc>:call MyKeyMapHighlight()<CR>gv
    " <--

    " Omni completion
    inoremap <C-B> <C-X><C-O>
" Горячие клавиши <--

" Меню -->
    " Включение автоматического разбиения строки на несколько
    " строк фиксированной длины
    menu Textwidth.off :set textwidth=0<CR>
    menu Textwidth.on :set textwidth=75<CR>


    " Проверка орфографии -->
        if version >= 700
            " По умолчанию проверка орфографии выключена.
            set spell spelllang=
            set nospell

            menu Spell.off :setlocal spell spelllang=<CR>:setlocal nospell<CR>
            menu Spell.Russian+English :setlocal spell spelllang=ru,en<CR>
            menu Spell.Russian :setlocal spell spelllang=ru<CR>
            menu Spell.English :setlocal spell spelllang=en<CR>
            menu Spell.-SpellControl- :
            menu Spell.Word\ Suggest<Tab>z= z=
            menu Spell.Add\ To\ Dictionary<Tab>zg zg
            menu Spell.Add\ To\ TemporaryDictionary<Tab>zG zG
            menu Spell.Remove\ From\ Dictionary<Tab>zw zw
            menu Spell.Remove\ From\ Temporary\ Dictionary<Tab>zW zW
            menu Spell.Previous\ Wrong\ Word<Tab>[s [s
            menu Spell.Next\ Wrong\ Word<Tab>]s ]s
        endif
    " Проверка орфографии <--


    " Обертка для :make -->
        function! MyMake()
            " Для *.py файлов не открываем новые вкладки,
            " а просто компилируем текущий файл.
            if &filetype == "python"
                write
                make
                return
            endif

            let old_tab_num = tabpagenr()

            " Создаем новую вкладку
            tabe

            " Помещаем ее в конец
            tabm

            let old_buflist = tabpagebuflist(tabpagenr())
            make
            let buflist = tabpagebuflist(tabpagenr())

            " Если список буферов не изменился, значит, компиляция прошла
            " успешно и можно закрыть только что созданную вкладку - она нам
            " не понадобилась.
            if old_buflist == buflist
                tabc
                execute 'tabn '.old_tab_num
            " Иначе файл с ошибкой откроется в этой вкладке.
            else
                " Раскрываем все складки
                setlocal foldlevel=9999
            endif
        endfunction

        nmap ,m :call MyMake()<CR>
        nmap ,w :cwindow<CR>
        nmap ,n :cnext<CR>
        nmap ,p :cprevious<CR>
        nmap ,l :clist<CR>

        menu Make.Make<Tab>,m ,m
        menu Make.Make\ Window<Tab>,w ,w
        menu Make.Next\ Error<Tab>,n ,n
        menu Make.Previous\ Error<Tab>,p ,p
        menu Make.Errors\ List<Tab>,l ,l
    " Обертка для :make <--


    " Обновление ctags -->
        function! MyUpdateCtags()
            echo "Update ctags function is not setted."
        endfunction

        let MyUpdateCtagsFunction = "MyUpdateCtags"
        nmap <F11> :call {MyUpdateCtagsFunction}()<CR>

        menu ctags.Update<Tab><F11> <F11>
    " Обновление ctags <--


    " Блог -->
        " Преобразование открытого в данный момент файла в HTML код для
        " последующей вставки в блог.

        function! MyConvertFileToHtmlForBlog()
            runtime syntax/2html.vim
            %s/<br>$//
            %s/\_^\_.*<body[^>]*><font[^>]*>\_\s*/<pre class="my_code_box"><font color="#000000">/
            %s/\_\s*<\/font><\/body>\_.*/<\/font><\/pre>/
        endfunction

        menu Blog.Convert\ file\ to\ HTML\ for\ blog :silent call MyConvertFileToHtmlForBlog()<CR>
    " Блог <--


    " Меню Encoding -->
        " Выбор кодировки, в которой читать файл -->
            set wildmenu
            set wcm=<Tab>
            menu Encoding.Read.utf-8<Tab><F7> :e ++enc=utf8 <CR>
            menu Encoding.Read.windows-1251<Tab><F7> :e ++enc=cp1251<CR>
            menu Encoding.Read.koi8-r<Tab><F7> :e ++enc=koi8-r<CR>
            menu Encoding.Read.cp866<Tab><F7> :e ++enc=cp866<CR>
            map <F7> :emenu Encoding.Read.<TAB>
        " Выбор кодировки, в которой читать файл <--

        " Выбор кодировки, в которой сохранять файл -->
            set wildmenu
            set wcm=<Tab>
            menu Encoding.Write.utf-8<Tab><S-F7> :set fenc=utf8 <CR>
            menu Encoding.Write.windows-1251<Tab><S-F7> :set fenc=cp1251<CR>
            menu Encoding.Write.koi8-r<Tab><S-F7> :set fenc=koi8-r<CR>
            menu Encoding.Write.cp866<Tab><S-F7> :set fenc=cp866<CR>
            map <S-F7> :emenu Encoding.Write.<TAB>
        " Выбор кодировки, в которой сохранять файл <--

        " Выбор формата концов строк (dos - <CR><NL>, unix - <NL>, mac - <CR>) -->
            set wildmenu
            set wcm=<Tab>
            menu Encoding.End_line_format.unix<Tab><C-F7> :set fileformat=unix<CR>
            menu Encoding.End_line_format.dos<Tab><C-F7> :set fileformat=dos<CR>
            menu Encoding.End_line_format.mac<Tab><C-F7> :set fileformat=mac<CR>
            map <C-F7> :emenu Encoding.End_line_format.<TAB>
        " Выбор формата концов строк (dos - <CR><NL>, unix - <NL>, mac - <CR>) <--
    " Меню Encoding <--


    " Перевод слов при помощи консольной версии StarDict -->
        function! TranslateWord()
            let s:dict    = "sdcv"
            let s:phrase  = expand("<cword>")
            let s:tmpfile = tempname()

            silent execute "!" . s:dict . " " . s:phrase . " > " . s:tmpfile

            let s:lines = system("wc -l " . s:tmpfile . "| awk '{print $1}'")

            if s:lines == 0
                echo s:phrase . ": Not found."
            else
                execute "botright sp " . s:tmpfile
            end
        endfun

        map <F9> :call TranslateWord()<CR>
        menu Translate.Translate_word<Tab><F9> :call TranslateWord()<CR>
    " Перевод слов при помощи консольной версии StarDict <--
" Меню <--


" Задаем собственные функции для назначения имен заголовкам табов -->
    function! MyTabLine()
        let tabline = ''

        " Формируем tabline для каждой вкладки -->
            for i in range(tabpagenr('$'))
                " Подсвечиваем заголовок выбранной в данный момент вкладки.
                if i + 1 == tabpagenr()
                    let tabline .= '%#TabLineSel#'
                else
                    let tabline .= '%#TabLine#'
                endif

                " Устанавливаем номер вкладки
                let tabline .= '%' . (i + 1) . 'T'

                " Получаем имя вкладки
                let tabline .= ' %{MyTabLabel(' . (i + 1) . ')} |'
            endfor
        " Формируем tabline для каждой вкладки <--

        " Заполняем лишнее пространство
        let tabline .= '%#TabLineFill#%T'

        " Выровненная по правому краю кнопка закрытия вкладки
        if tabpagenr('$') > 1
            let tabline .= '%=%#TabLine#%999XX'
        endif

        return tabline
    endfunction

    function! MyTabLabel(n)
        let label = ''
        let buflist = tabpagebuflist(a:n)

        " Имя файла и номер вкладки -->
            let label = substitute(bufname(buflist[tabpagewinnr(a:n) - 1]), '.*/', '', '')

            if label == ''
                let label = '[No Name]'
            endif

            let label .= ' (' . a:n . ')'
        " Имя файла и номер вкладки <--

        " Определяем, есть ли во вкладке хотя бы один
        " модифицированный буфер.
        " -->
            for i in range(len(buflist))
                if getbufvar(buflist[i], "&modified")
                    let label = '[+] ' . label
                    break
                endif
            endfor
        " <--

        return label
    endfunction

    function! MyGuiTabLabel()
        return '%{MyTabLabel(' . tabpagenr() . ')}'
    endfunction

    set tabline=%!MyTabLine()
    set guitablabel=%!MyGuiTabLabel()
" Задаем собственные функции для назначения имен заголовкам табов <--


" Переключение между заголовочными файлами и
" файлами с исходным кодом.
" -->
    "   Соответственно:
    "   ,s - переключение на исходный код
    "   ,S - тоже самое, только открыть в новом окне
    "   ,h - переключение на заголовочный файл
    "   ,H - тоже самое, только открыть в новом окне

    nmap ,h :call MySwitchToHeader()<CR>
    nmap ,H :call MySwitchToHeaderInNewWindow()<CR>
    nmap ,s :call MySwitchToSource()<CR>
    nmap ,S :call MySwitchToSourceInNewWindow()<CR>

    function! MySwitchToHeader()
        if &filetype == "c"
            find %:t:r.h
            return
        end

        if &filetype == "cpp"
            find %:t:r.hpp
            return
        end
    endfunction

    function! MySwitchToHeaderInNewWindow()
        if &filetype == "c"
            sf %:t:r.h
            return
        end

        if &filetype == "cpp"
            sf %:t:r.hpp
            return
        end
    endfunction

    function! MySwitchToSource()
        if &filetype == "c"
            find %:t:r.c
            return
        end

        if &filetype == "cpp"
            find %:t:r.cpp
            return
        end
    endfunction

    function! MySwitchToSourceInNewWindow()
        if &filetype == "c"
            sf %:t:r.c<CR>
            return
        end

        if &filetype == "cpp"
            sf %:t:r.cpp<CR>
            return
        end
    endfunction
" <--

~/.gvimrc:
" Подсветка строки, в которой находится в данный момент курсор
set cursorline

" Отключаем панель инструментов
set guioptions-=T
" Отключаем графические диалоги
set guioptions+=c
" Отключаем графические табы (текстовые занимают меньше места)
set guioptions-=e

" Устанавливаем шрифт
set guifont=Monospace\ 9

" Меню -->
    " По умолчанию меню скрыто
    set guioptions-=m

    " Горячие клавиши скрытия/отображения меню -->
        function MyToggleMenu()
            let old_guioptions = &guioptions

            " Если меню в данный момент видимо
            if stridx(old_guioptions, 'm') != -1
                set guioptions-=m
            else
                set guioptions+=m
            endif
        endfunction

        cmap <F12> <ESC>:call MyToggleMenu()<CR>
        imap <F12> <ESC>:call MyToggleMenu()<CR>
        nmap <F12> :call MyToggleMenu()<CR>
        vmap <F12> <ESC>:call MyToggleMenu()<CR>
    " Горячие клавиши скрытия/отображения меню <--
" Меню <--

~/.vim/develop.vim:
" Общий конфигурационный файл для всех файлов,
" которые имеют какое-либо отношение к программированию.

" Отключаем перенос строк
setlocal nowrap

" Уровень сокрытия по умолчанию для вновь открытых файлов
setlocal foldlevelstart=0
" Метод фолдинга - по синтаксису
setlocal foldmethod=syntax

" Включаем отображение номеров строк
setlocal number

" Учитывать регистр букв при поиске
setlocal noignorecase

" Включить подсветку невидимых символов
setlocal list
" Настройка подсветки невидимых символов
setlocal listchars=tab:·\ ,trail:·

~/.vim/ftplugin/python/custom_settings.vim:
" Ключевые слова, по которым smartindent будет расставлять отступы
setlocal cinwords=if,elif,else,for,while,try,except,finally,def,class
" Чтобы из-за smartindent'а при написании комментария в пустой
" строке курсор не переносился в начало строки
inoremap # X<C-H>#

" Настройка работы :make
" Теперь по команде :make будет производиться 'компиляция' открытого в данный
" момент файла. Это помогает выявить самые простейшие ошибки синтаксиса, такие
" как, например, пропуск двоеточия после if.
setlocal makeprg=python\ -c\ \"import\ py_compile,sys;\ sys.stderr=sys.stdout;\ py_compile.compile(\'%\')\"
setlocal efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m

" Ctags для всей библиотеки Python'a
setlocal tags+=~/.vim/tags/python.ctags



Список команд


Соглашения

Чтобы сократить размеры данного HowTo, я ввел следующее обозначение: строка
<C-W>{h, j, k, l} - перемещает курсор в окно, которое находится {слева, внизу, вверху, справа}.
эквивалентна следующим 4 строкам:
<C-W>h - перемещает курсор в окно, которое находится слева.
<C-W>j - перемещает курсор в окно, которое находится внизу.
<C-W>k - перемещает курсор в окно, которое находится вверху.
<C-W>l - перемещает курсор в окно, которое находится справа.



Команды редактирования

c - полностью аналогична d, но после своего выполнения переводит редактор в режим вставки.
X - аналогична x, но "стирает текст влево, а не вправо". Если проводить аналогии, то x - это клавиша Del, а X - клавиша Backspace.
D - аналогична d$.
C - аналогична c$.
s - аналогична xi.
S - аналогична cc.
. - повторяет предыдущую команду.
I - аналогична ^i.
A - аналогична $a.

<C-A> - перемещает курсор на ближайшее число и увеличивает его на единицу.
<C-X> - перемещает курсор на ближайшее число и уменьшает его на единицу.



Работа с текстом в режиме вставки

<C-W> - удаляет слово перед курсором.
<C-U> - удаляет все символы от начала строки до курсора.
<C-Y> - вставляет символ, который находится над курсором (в предыдущей строке).
<C-E> - вставляет символ, который находится под курсором (в следующей строке).
<C-O>cmd - выполняет команду cmd и возвращается обратно в режим вставки.



Изменение регистра

{g~, gu, gU} - меняют регистр букв на {противоположный, нижний, верхний}.
{g~~, guu, gUU} - меняют регистр букв во всей строке на {противоположный, нижний, верхний}.



Перемещение в тексте

w - переместиться вперед на первую букву слова.
e - переместиться вперед на последнюю букву слова.
b - переместиться назад на первую букву слова.
ge - переместиться назад на последнюю букву слова.
gE, B, W и E - тоже самое, что и ge, b, w, и e, но только в этом случае словом будет считаться любая последовательность букв, разделенных пробельными символами.

( - На одно предложение назад (до точки).
) - На одно предложение вперед (до точки).
{ - На абзац назад (до пустой строки).
} - На абзац вперед (до пустой строки).

$ - перемещает курсор в конец строки.
^ - перемещает курсор на первый непробельный символ в строке.
0 - перемещает курсор на первый символ строки.

g{j, k} - перемещает курсор на одну экранную строку {вниз, вверх}. Когда длинная строка не умещается в одной экранной строке, она разбивается на несколько экранных строк. j и k перемещают по реальным строкам, а gj и gk - по экранным.

fn - перемещает курсор вперед на символ n в текущей строке.
Fn - перемещает курсор назад на символ n в текущей строке.
t, T - аналогичны f и F, но перемещают курсор не на сам символ, а на символ, находящийся перед ним.
; - повторяет поиск, производимый последней командой f, F, t или T.
, - повторяет поиск, производимый последней командой f, F, t или T, но в обратном порядке.

% - перемещает курсор на парную круглую, фигурную или квадратную скобку. Пары можно задать командой :set matchpairs.

:5 или 5G - перемещает курсор на 5 строку.
gg - перемещает курсор на первую строку.
G - перемещает курсор на последнюю строку.
50% - перемещает курсор в середину текста.
H, M, L - перемещают курсор в начало, середину и конец видимой части текста.

{<C-U>, <C-D>} - прокручивает текст на половину высоты окна {вниз, вверх}.
{<C-Y>, <C-E>} - прокручивает текст на одну строку {вниз, вверх}, но при этом не перемещает курсор.
{<C-F>, <C-B>} - прокручивает текст {вниз, вверх} на количество строк, равное высоте окна минус 2 строки.
{zs, ze, zt, zz, zb} - прокручивает текст так, чтобы курсор оказался {на левом крае, на правом крае, вверху, в центре, внизу} экрана.

Стоит заметить, что все эти команды можно использовать не только для перемещения курсора или поиска символа, но и комбинировать их с командами копирования и удаления. Например, если у вас есть строка
void foo(int val_1, int val_2);
то поставив курсор за первую круглую скобку и нажав dt), вы очистите все содержимое внутри скобок, т. е. получите строку
void foo();



Режим выделения

v - войти в режим выделения символов.
V - войти в режим выделения строк.
<C-V> - войти в режим выделения блока текста.
gv - выделяет текст, который был выделен прошлой командой выделения.
o, O - перемещают в режиме выделения курсор в другой конец, чтобы можно было изменить размеры области выделения с разных концов. Команда O необходима при блочном выделении.
J - если у вас выделен блок текста и вы нажмете J, то все строки, содержащиеся в этом блоке сольются в одну.



Редактирование текста в блочном выделении

Все описанные ниже команды необходимо выполнять, когда вы находитесь в режиме блочного выделения (вызывается по комбинации клавиш <C-V>).

I - переключает в режим вставки символов в блочное выделение. После того, как вы нажмете I, наберете несколько символов и нажмете клавишу <Esc>, набранные символы вставятся во все выделенные строки. Например, с помощью этой операции строки
#include <header_1.h>
#include <header_2.h>
#include <header_3.h>
можно преобразовать в
#include <my_headers_dir/header_1.h>
#include <my_headers_dir/header_2.h>
#include <my_headers_dir/header_3.h>

c - аналогична I, но только перед переключением в режим вставки удаляет символы, выделенные в данный момен блоком.
C - аналогична I, но только перед переключением в режим вставки удаляет все символы от левого края выделения, до конца строки.
{~, u, U} - меняют регистр букв на {противоположный, нижний, верхний}
r - если сначала выделить блок текста, а потом нажать r*, то весь блок заполнится символами *.
< и > - сдвигают выделенный текст влево или вправо так, как это делают команды << и >> в обычном режиме.



Использование буфера обмена и регистров

"*yy - скопировать строку в буфер обмена текущего выделения, которую потом можно будет вставить в других приложениях по нажатию на колесико мыши.
"+yy - скопировать строку в буфер обмена, которую потом можно будет вставить в других приложениях по нажатию на Ctrl+V.
"ayy - скопировать строку в регистр a.
"ap - вставить текст из регистра a.

Важно отметить одну особенность при работе с регистрами: имена регистров лежат в диапазоне a-z. Если "ayy копирует строку в регистр a, то "Ayy добавляет строку в регистр a. Это очень важная особенность. Ее очень удобно использовать, когда вы копируете строки из разных частей файла и хотите потом вставить их в одном месте. Но вся ее мощь проявляется при записи и воспроизведении макросов Vim (через клавиши q и @) - если у вас уже существует работающий макрос, который вы хотите расширить, то вам не обязательно записывать все действия заново - достаточно выполнить, например, qA, и набранные вами команды добавятся к уже существующим.



Метки

Каждый раз, когда вы осуществляете поиск или выполняете команды G, gg и т. п, курсор перемещается по тексту. Vim каждый раз запоминает положение курсора и позволяет вам вернуться в предыдущую позицию. Также существует возможность создавать собственные метки.

ma - создает метку с именем a.
`a - перемещает курсор на метку a.
'a - перемещает курсор на начало строки, содержащей метку a.
:marks - показывает все существующие в данный момент метки.
<C-O> и <C-I> - перемещение к ранее посещенным меткам назад и вперед.
`` и '' - перейти на предыдущую позицию (разница между `` и '' такая же как и между `a и 'a).



Поиск

/ - включает режим поиска. Символы .*[]^%/\?~$ являются специальными, поэтому при поиске слова, содержащего такие символы, их необходимо предварять символом \. Строка поиска - это обычное регулярное выражение, так что вы можете использовать символы *, ^, $ и т. д. также, как и при записи обычного регулярного выражения. Подробнее о регулярных выражениях Vim можно прочитать в документации.
? - то же, что и /, но только поиск будет производиться в обратном направлении.
n - повторить поиск.
N - повторить поиск в обратном направлении.
* - при нажатии на * будет произведен поиск слова, на котором находится в данный момент курсор.
# - тоже самое, что и *, но в обратном направлении.
g*, g# - тоже самое, что * и #, но со следующей разницей: при поиске 'the' команда * найдет в тексте только слово the, тогда как g* найдет the, there и т. п.

Игнорирование регистра символов при поиске можно задать опцией :set (no)ignorecase.
Также действуют следующие правила:
/слово\c - ищет "слово", игнорируя регистр независимо от настроек.
/слово\C - ищет "слово", учитывая регистр независимо от настроек.

\< и \> означают начало и конец слова. Т. е. при поиске /\<the\> будет найдено только слово the, тогда как при поиске /the будет найдено the, there и т. д.

/word/b+1 - ищет слово word и устанавливает курсор на второй символ (o).
/word/e-1 - ищет слово word и устанавливает курсор второй символ с конца (r).
?word?e - аналогично /word/e, но ищет назад, а не вперед.

Ввод двух поисковых команд
/word
//e
аналогичен одной команде
/word/e

Если в режиме поиска нажимать на клавиши <Up> и <Down>, то можно перемещаться по истории поиска. Стоит отметить, что если вы ранее искали слова "слово", "словарь" и "слог", то если вы наберете в режиме поиска "слов" и нажмете на клавишу <Up>, то Vim предложит вам из истории поиска только "слово" и "словарь".

Командный режим, вызываемый по клавише : также имеет свою историю.



Автозамена

:[address]s/[search]/[repl]/[gcie] - Поиск [search] и замена на [repl] (в режиме VISUAL - без адреса и в выделенной области):
[gcie]:
[без опций] - первого вхождения (в строке).
g - все вхождения (в строке).
c - с запросом подтверждения.
i - игнорируя регистр.
e - подавляет сообщение об ошибке, которое возникает, если найденный шаблон не встречается ни одного раза.
[address]:
% - весь текст.
1 - первая строка.
. - текущая строка.
$ - последняя строка.
1,3 - между строками 1-3.
.,$ - от текущей до последней.


Примеры:

:s/text/new_text/ - Заменяет первый встреченный образец text в текущей строке на new_text.
:s/text/new_text/g - Заменяет все образцы text в текущей строке на new_text.
:1,$s/the/THE/g - Начиная с первой строки до последней (строки $), заместить все встреченные the на THE.
:'a,.s/.*/ha ha/ - От строки, помеченной меткой a, до текущей строки, заменить любой текст на строку "ha ha".
:%s/\s\+$// - удаляет пробельные символы в конце строк во всем файле.

:%s/\([^,]*\), \(.*\)/\2 \1/ - преобразовывает
Doe, John
Smith, Peter
в
John Doe
Peter Smith

Ограничение диапазона строк, в которых необходимо произвести автозамену:
:g/search/s/text/new_text/ - заменяет строку text на new_text в строках, содержащих подстроку search. Команда состоит из двух команд: :g/search/ и :s/text/new_text/. Первая выбирает только строки, содержащие подстроку search, а вторая производит в них обычную автозамену.



Автодополнение

<C-P> и <C-N> - поиск слова для автодополнения назад и вперед.

Опция ignorecase влияет на работу автодополнения. Если же установлены опции ignorecase и infercase, то если вы наберете "For" и Vim найдет соответствие "fortunately", то результатом будет "Fortunately".

Автодополнение из определенной области поиска:
<C-X><C-F> - имена файлов.
<C-X><C-L> - целые строки.
<C-X><C-D> - макроопределения.
<C-X><C-I> - текущий и включенные (included) файлы.
<C-X><C-K> - слова из словаря.
<C-X><C-T> - слова из тезауруса.
<C-X><C-]> - теги.
<C-X><C-V> - командная строка Vim.
<C-X><C-O> - имена функций и переменных в исходном коде программ с использованием ctags.
<C-X><C-S> - слова из spell словаря.

Перемещение по предлагаемым в меню словам можно осуществлять теми же <C-P> и <C-N>.
<C-Y> - Принять выделенное в данный момент в меню слово.
<C-E> - Возвращается к тому состоянию, которое было до нажатия горячих клавиш автодополнения.



Выравнивание текста

:{center, right} [width] - выравнивает текст по {центру, правому краю}. width - максимальная ширина строки.



Форматирование строк до фиксированной ширины

:set textwidth=72 - задает автоматическое форматирование строк таким, чтобы их длина не превышала 72 символа. Во время набора текста Vim будет сам вставлять необходимые переносы строк. Правда, если вы впоследствии удалите какие-либо символы из уже набранного текста или просто склеите несколько строк, то Vim не станет их переформатировать автоматически.
gqap - заставляет Vim переформатировать текущий параграф.
gggqG - заставляет Vim переформатировать весь текст.

Также, если необходимо переформатировать только часть текста, то достаточно выделить нужные строки и нажать gq.



Преобразование параграфов, разбитых на строки фиксированной ширины, в строки

:g/./,/^$/join
или
:g/\S/,/^\s*$/join
если пустые строки между параграфами содержат пробельные символы.



Редактирование таблиц

При редактировании таблиц или составлении каких-либо блоксхем удобно иметь возможность свободно перемещаться по всему экрану, не обращая внимания на отсутствующие символы в строке. :set virtualedit=all позволяет сделать это. После выполнения данной команды вы можете перемещать курсор, далее по строке, даже если она не содержит ни одного символа. Как только вы вставите в нее хотя бы один символ, все пространство от начало строки до вставленного символа автоматически заполнится пробелами.



Работа с буферами

:ls - отображает список буферов.
:b file_name - переключается на буфер файла file_name. Полное имя файла писать не обязательно - главное ввести такую последовательность символов, которая присутствует только в имени искомого буфера и не присутствует в именах других буферов.
:b{f,n,p,l} - открывает {первый, следующий, предыдущий, последний} буфер.



Работа с окнами

<C-W>n или :new [file] - создает новое пустое окно и помещает его над текущим окном. Если указано имя файла, то создается окно, в которое загружается указанный файл.
:vnew [file] - аналогична :new, но помещает окно слева относительно текущего.
<C-W>s или :sp[lit] [file] - создает копию текущего окна и помещает ее над текущим окном. Если указано имя файла, то создается окно, в которое загружается указанный файл.
<C-W>v или :vs[plit] - аналогична :split, но помещает окно слева относительно текущего.
<C-W>c или :clo[se] - закрывает окно.
<C-W>o или :only - закрывает все окна кроме текущего.
<C-W>W - перескакивает с одного окна на другое.
<C-W>- или :res[ize] -N - уменьшает высоту окна на одну строку.
<C-W>+ или :res[ize] +N - увеличивает высоту окна на одну строку.
<C-W>< или :vertical res[ize] -N - уменьшает ширину окна на одну колонку.
<C-W>> или :vertical res[ize] +N - увеличивает ширину окна на одну колонку.
:res[ize] [N] - Задает высоту окна.
:vertical res[ize] [N] - Задает ширину окна.
[height]<C-W>_ - если указано значение height, то делает размер окна равным height, в противном случае увеличивает высоту окна до максимального размера.
[width]<C-W>| - если указано значение width, то делает ширину окна равной width, в противном случае увеличивает ширину окна до максимального размера.
<C-W>{h, j, k, l, t, b} - перемещает курсор в окно, которое находится {слева, внизу, вверху, справа, в самом верху, в самом низу}
<C-W>{H, J, K, L} - перемещает окно так, чтобы оно было {самым левым, самым нижним, самым верхним, самым правым}
<C-W>= - Делает все окна одинакового размера.
:wa, :qa, :wqa - аналогичны :w, :q и :wq, но производят действия со всеми окнами.



Табы (вкладки)

:tabe[dit] [file] - создает новую вкладку.
gt - переключается между вкладками.
Ngt - Переходит на вкладку с номером N.
:tab split - создает новую вкладку, в которой будет открыт буфер, редактируемый в данный момент.
:tabn[ext][N] или :tabn[ext][N] - Переходит на вкладку с номером N. Если аргумент N опущен, то переходит на следующую вкладку.
:tabm[ove][N] или :tabm[ove][N] - Перемещает текущую вкладку так, чтобы она стояла после вкладки N.
:tabc[lose] [tab_num] - Закрывает вкладку.
:tabo[nly] - Закрывает все вкладки кроме текущей.
:tabr[ewind] или :tabfir[st] - Открывает первую вкладку.
:tabl[ast] - Открывает последнюю вкладку.
:tabp[revious] - Переходит на предыдущую вкладку.
:tabs - Отображает список вкладок с открытыми в них окнами.



Макросы

qa - начать запись в регистр a.
q - окончить запись.
@a - воспроизвести запись из регистра a.



Редактирование командной строки и строки поиска

<S-Left> или <C-Left> - смещает курсор на одно слово влево.
<S-Right> или <C-Right> - смещает курсор на одно слово вправо.
<C-B> или <Home> - в начало строки.
<C-E> или <End> - в конец строки.
<C-W> - удаляет слово, стоящее перед курсором.
<C-U> - удаляет все символы перед курсором.



Сохранение информации о текущей сессии между запусками Vim

Vim запоминает файл и место в файле, в котором находился курсор в момент его закрытия. Если запустить Vim снова и нажать '0, то он откроет этот файл и установит курсор в то же место. При закрытии '0 запишется в '1, '1 в '2 и т. д. до '9. В '0 запишется новое значение.

Сохранение viminfo файла позволяет впоследствии восстановить текущее содержимое регистров, метки, историю поиска и историю команд.
:wviminfo! ~/.vim/my_viminfo - записывает текущую информацию в файл ~/.vim/my_viminfo.
:rviminfo! ~/.vim/my_viminfo - восстанавливает записанную информацию из файла ~/.vim/my_viminfo.

Сохранение текущей сессии позволяет впоследствии восстановить открытые в данный момент окна, их размеры, табы, текущие привязки горячих клавиш, значения переменных и т. п.
:mksession! ~/.vim/my_session - сохраняет информацию о текущей сессии в файл ~/.vim/my_session.
Восстановить сохраненную ранее сессию можно командой
:source ~/.vim/my_session
или запустив Vim с переданной ему опцией -S:
vim -S ~/.vim/my_session



Просмотр бинарных файлов

Запустите Vim командой
vim -b -c '%!xxd' binary_file
Если вам необходимо изменить файл - то поменяйте hex значения (не printable часть) и выполните команду :%!xxd -r - она преобразует обратно hex представление в бинарный файл, который затем можно сохранить.



Внесение изменений во множество файлов

Допустим, что у вас есть много *.c файлов, в которых вы хотите поменять переменную
"x_cnt" на "x_counter".

Для этого вам необходимо произвести следующие действия:
:args *.c
:argdo %s/\<x_cnt\>/x_counter/gce | update
| - это разделитель команд. Команда update сохраняет файл, если он был изменен.

Также существуют команды :windo и :bufdo, которые действуют соответственно, для всех окон и всех буферов.



Подсветка синтаксиса

Иногда из-за подсветки синтаксиса Vim очень сильно тормозит. :syntax clear позволяет временно отключить подсветку.
После выполнения :syntax manual, все новые файлы, которые вы будете открывать, будут отображаться без подсветки. Чтобы включить подсветку для конкретного файла, нужно будет выполнить команду :set syntax=ON.



Складки

zf - создает новую складку (актуально при foldmethod=manual).
zd - удаляет складку, на которой в данный момент находится курсор.
zD - рекурсивно удаляет все складки под курсором.
zE - удаляет все складки в окне.
zo - открыть текущую складку.
zO - открыть текущую складку и все складки внутри нее.
zc - скрыть текущую складку.
- скрыть текущую складку и все складки внутри нее.
za - скрыть/открыть текущую складку.
zA - скрыть/открыть текущую складку и все складки внутри нее.
{zr, zm} - {увеличивает, уменьшает} на 1 уровень сокрытия складок.
{zR, zM} - {открыть, скрыть} все складки.

Метод, по которому будут создаваться складки можно задать через опцию foldmethod:
:set foldmethod=indent
:set foldmethod=manual
:set foldmethod=syntax

Команды zr и zm на самом деле просто увеличивают и уменьшают опцию foldlevel, поэтому вы можете также задать ее самостоятельно:
:set foldlevel=3
zM задает foldlevel=0, а zR - максимальное значение, для текущего файла.



Сборка C/C++ программ средствами make

:cc [line] - показать ошибку. Если указан параметр line, то отображается строка line.
:cn[ext] - отображает следующую ошибку.
:cN[ext] или :cp[revious] - отображает предыдущую ошибку.
:cr[ewind] или :cfir[st] - отображает первую строку вывода make.
:cla[st] - отображает последнюю строку вывода make.
:cl[ist] [from][,[to]] - отображает список ошибок.
:cl[ist]! [from][,[to]] - отображает список всех ошибок, а не только тех, которые подходят под шаблон.
:cw[indow] [height] или :cope[n] [height] - открывает окно с выводом make'a.
:ccl[ose] - закрывает окно, открытое командой :copen.
:make - запускает процесс компиляции. Если запущена не как :make!, то при возникновении ошибок компиляции переходит на эти ошибки в тексте.
:set makeprg=make - задает команду, которую будет запускать :make.

Опция switchbuf задает поведение команд :cn, :make и т. п. относительно того, где они будут открывать требуемый файл (к примеру, значение split заставляет сначала открывать новое окно, и уже в него загружать файл с ошибкой, а не использовать текущее).



Редактирование C/C++ программ

= - вставляет необходимые отступы в выделенных строках C программы.
[i - пытается найти в заголовочных файлах определение идентификатора, на котором в данный момент находится курсор и выводит это определение в статусную строку.
[<C-I> - аналогична [i, но только не отображает строку с определением, а открывает файл с исходным кодом на той строке, из которой команда [i взяла бы определение.
[I - отображает список строк из текущего и подключенных к нему заголовочных файлов, в которых находится идентификатор, на котором в данный момент находится курсор.
<C-]> - перемещает на определение функции C, имя которой находится под курсором (используя ctags).
<C-W>] - то же самое, что и <C-]>, но открывает в новом окне.
<C-T> - перемещает обратно на файл, который был открыт в буфере до выполнения команды <C-]>.
gd - перемещает к определению переменной внутри текущей функции.
gD - перемещает к определению глобальной переменной, если она определена в этом файле.
% - перемещает к парной (), {}, [], /* */, #if, #else, #endif.
[<C-D> - перемещает на первый найденный в текущем и в подключенных файлах #define для идентификатора, на котором в данный момент находится курсор.
[<C-I> - перемещает на первое найденное в текущем и в подключенных файлах определение идентификатора, на котором в данный момент находится курсор.
[D - отображает список #define'ов, найденных в текущем и подключенных файлах для идентификатора, на котором в данный момент находится курсор.
[I - отображает список определений, найденных в текущем и подключенных файлах для идентификатора, на котором в данный момент находится курсор.
{]<C-D>, ]<C-I>, ]D, ]I} - аналогична {[<C-D>, [<C-I>, [D, [I}, но поиск будет производиться от текущего положения курсора.
[( - производит поиск вверх по тексту и устанавливает курсор на круглой скобке '(', у которой нет парной закрывающей скобки (если такая существует).

Список файлов, в которых будут искаться ctag'и задаются опцией :set tags=./tags,./../tags,./*/tags.

При нажатии на CTRL-] Vim находит метку в ctag'ах и открывает эту метку в буфере. Если одному имени тэга соответствует несколько меток, то переключаться между ними можно командами :tfirst, :[count]tprevious, :[count]tnext и :tlast. :tselect tagname выведет список меток с тегом tagname.



Перемещение по блокам кода

             function(int a)
+->       {
|             if (a)
|     +->     {
[[ |     |         for (;;)          --+
|     |     +-> {                   |
|  [{ |     |     foo(32);          |    --+
|     |  [{ |     if(bar(a)) --+    | ]}   |
+--   |     +--     break;     | ]} |      |
|         }            <-+    |      | ][
+--       foobar(a)           |      |
}                   <-+      |
}                              <-+


int func1(void)
{
return 1;
+---------->  }
|
[]  |             int func2(void)
|        +->  {
|    [[  |       if (flag)
start     +--      +--       return flag;
|    ][  |       return 2;
|        +->  }
]]  |
|             int func3(void)
+---------->  {
return 3;
}


[(
<--------------------------------
<--------
if (a == b && (c == d || (e > f)) && x > y)
-------------->
-------------------------------->
])

Также не стоит забывать про команду %, которая перемещает на парные (), [] и {}.



Остальные команды

:options - выдает список всех доступных опций, причем опции можно менять прямо в этом списке - изменения сразу же будут вступать в силу. Опции с булевыми значениями меняются клавишей Enter. Чтобы поменять опции, содержащие строковые или числовые значения, необходимо просто отредактировать это значение и нажать клавишу Enter.
:r[ead] filename - вставляет содержимое другого файла в текущий.
:w[rite] [>>]filename - записывает содержимое текущего файла в файл filename. Если указан оператор >>, то информация добавляется в файл, не стирая его содержимого. Команда write также поддерживает диапазоны, например, :.write filename записывает в файл только текущую строку. Если выполнить команду :write в режиме выделения, то в файл запишется выделенный фрагмент текста.
:!cmd - запускает внешнюю команду cmd. Например, :!date выведет текущую дату. Если выделить какой-нибудь текст и в режиме выделения набрать :!sort, то выделенный текст будет отсортирован. :read !ls -1 вставляет список файлов текущей директории в место под курсором. :write !wc -l подсчитывает количество строк в редактируемом тексте.
:cd - меняет текущую директорию Vim'a.
:pwd - выводит текущую директорию Vim'a.
:lcd - меняет текущую директорию окна. По умолчанию все окна имеют одинаковую текущую директорию, которая меняется командой :cd. После выполнения :lcd выполнение :cd в других окнах не влияет на текущую директорию этого окна, пока в нем не будет выполнена :cd.
gf - открывает файл, на имя которого в данный момент указывает курсор. Если загружен плагин netrw, то можно открывать файлы по протоколам ftp, http, scp и rcp.
<C-W>f - аналогично gf, но открывает файл в новом окне.
:map - показывает список привязок горячих клавиш.
:set lazyredraw - отключает перерисовку экрана на время выполнения макроса (существенно ускоряет работу).



Аналоги стандартных клавиш

При десятипальцевом слепом методе набора текста гораздо удобнее нажимать <C-[> нежели <Esc>, т. к. для нажатия <C-[> не требуется убирать руки с клавиатуры, что влечет за собой увеличение скорости работы.

<C-[> - <Esc>
<C-I> - <Tab>
<C-H> - <BS>
<C-M> - <Enter>



Самый главный совет :)

Напоследок дам, на мой взгляд, самый главный совет. Все эти команды, конечно, позволяют ускорить работу и значительно повысить ее качество, но действительно высокой скорости работы (и получения максимального удовольствия от нее :) ) вы сможете достигнуть только в том случае, если овладеете десятипальцевым слепым методом набора текста. Все команды в Vim специально сделаны так, чтобы минимизировать перемещения рук по клавиатуре. Даже клавиши перемещения курсора вынесены в h, j, k и l. При слепом методе набора вам не нужно отвлекаться на клавиатуру и тратить драгоценное время на перемещение рук - все ваше внимание будет сконцентрировано на том, что вы пишете. Если человек может печатать вслепую, то он не задумывается, на какую клавишу нажать - эта информация у него находится в "мышечной памяти". Вы же не ищете каждый раз кнопку мыши, на какую вам нужно нажать. Да, на мыши всего 3 кнопки, на клавиатуре их больше - это значит, что вам просто потребуется чуть больше времени, чтобы ваши руки запомнили все клавиши. Причем как раз вам их помнить не надо - это необходимо только на начальном этапе обучения. Я вот сейчас, например, сразу и не скажу, каким пальцем и как надо нажимать на какую букву - я этого не знаю, но мои руки знают. Так что, можно сказать, печатаю силой мысли. :) Разве вам этого не хочется?

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

На следующем рисунке представлена схема того, какими пальцами и какие клавиши необходимо нажимать:


Поверьте, это не так сложно, как кажется. Конечно, сначала придется потрудиться, но вы ведь сейчас читаете этот HowTo как раз потому, что хотите потратить какое-то время на изучение Vim, чтобы потом это время окупилось стократно. Обещаю, если вы освоите слепой метод набора текста, то тогда затраченное вами время окупится уже тысячекратно.

За сим раскланиваюсь и желаю успехов в освоении. Оно того стоит. :)

50 комментариев:

urbanserj комментирует...

>Первый способ заключается в том, что вы вставляете в свой ~/.vimrc следующие строки:

:help russian.txt
:set langmap=....
(хотя сам предпочитаю russian-jcukenwin)

хорошая статья, узнал еще пару любопытных shortcut'ов :)

Конищев Дмитрий комментирует...

urbanserj, у меня этот метод не заработал, когда я пытался его использовать - если не ошибаюсь, с UTF-8 он не работает.

Анонимный комментирует...

Спасибо большое за статью, узнал все чего мне не хватало в Vim.

Анонимный комментирует...

Разбираюсь с vim. Немогу заставить разварачиваться его на весь экран. В руководстве сказано - вставить следующую команду:

au GUIEnter * simalt ~x

Но она работает если интерфейс Windows английский. Как сделать под русский нитерфейс?

Конищев Дмитрий комментирует...

Тут я вам вряд ли смогу помочь, т. к. вообще не использую Windows.

kevit комментирует...

большое спасибо, очень полезный howto

dekar-j комментирует...

Большое спасибо за статью. У себя использую аналогичный подход с опцией exrc, чтобы загружать конфиг проекта.

Не могли бы вы побробнее рассказать/написать про парсинг зависимостей исходников, чтобы использовать тэги только от нужный файлов?

Конищев Дмитрий комментирует...

dekar-j, а в чем именно для вас заключается проблема? Зависимости для исходного файла можно получить при помощи команды gcc -M filename.c. Далее этот список файлов нужно передать программе ctags. У меня в makefile'e в одной из целей содержатся следующие строки:
@echo Generating Vim ctags...
tags=''; \
for file in $(SRC_PREFIX)*.c; \
do \
tags+=$$(gcc -M $(CFLAGS) $$file | sed -r 's/.+?://'); \
done; \
tags=$$(echo $$tags | sed 's/\\//g' | sed 's/ /\n/g' | sort -u); \
ctags -f $(VIM_PREFIX)ctags $$tags

Если содержимое данных строк для вас не понятно, обращайтесь - объясню, что они делают.

Анонимный комментирует...

Спасибо, за отличный howto, Дмитрий!

AQUAGNU: комментирует...

Использую GNU GLOBAL и другим советую (минус: небольшое число поддерживаемых языков, плюсов слишком много...:)

Георгий Виноградов комментирует...

А как пользоваться Вашим преобразованием в HTML? Больно не пинайте, я с вимом работать почти не умею =)

Конищев Дмитрий комментирует...

Георгий Виноградов, в конфиге создается меню Blog - его вы можете увидеть там же, где находятся меню File, Edit и т. д. В этом меню есть пункт "Convert file to HTML for blog". Нажимаете на него - открывается новое окно, в котором находится HTML код, заключенный в тэги <pre class="my_code_box">...</pre>. Эти теги у меня используются для визуального выделения блоков кода. Подробнее о них можно прочитать тут. После этого остается только скопировать текст в буфер обмена и вставить в блог.

Георгий Виноградов комментирует...

Во-первых, вот:

Обнаружена ошибка при обработке function MyConvertFileToHtmlForBlog:
строка 2:
E486: шаблон не найден <br>$
строка 3:
E486: шаблон не найден \_^\_.*<body[^>]*><font[^>]*>\_\s*
строка 4:
E486: шаблон не найден \_\s*<\/font><\/body>\_.*

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

Конищев Дмитрий комментирует...

Георгий Виноградов, скорее всего, у вас установлена не полная версия Vim, и команда "runtime syntax/2html.vim" просто не выполняется, т. к. нет скрипта 2html.vim. У меня в Ubuntu 8.10 этот файл находится в /usr/share/vim/vim71/syntax/2html.vim, а устанавливает его пакет vim-runtime.

Меню можете пользоваться следующим образом: набираете ":emenu", пробел и нажимаете на Tab. Отобразится список доступных меню, по которым вы можете перемещаться и активировать их нажатием на Enter.

Георгий Виноградов комментирует...

Спасибо за объяснение работы с меню, разобрался.
Честно говоря, уже несколько неудобно Вас отрывать, но все-же... Скрипт syntax/2html.vim лежит там, где ему и положено. В HTML код конвертируется, но ошибки напрягают, тем более что на более-менее больших файлах я его еще не проверял.
И образовалась еще одна проблема, где грабли понять не могу... Добавил imap <C-Space> <C-N>. В gvim работает на ура, а вот в консоли творится черт-знает что. Парой проверок убедился, что на <C-Space> в консоли мапы не вешаются. В чем может быть проблема, как думаете?

Георгий Виноградов комментирует...

Проблема с автодополнением решена. Вместо <C-Space> надо было ставить <C-@>

Конищев Дмитрий комментирует...

Ну а какой HTML код у вас генерируется? Ведь данные команды - это всего лишь автозамена <html>...<body>$text</body>...</html> на <pre class="my_code_box">$text</pre>. То, что они у вас выдают ошибки, означает, что у вас 2html.vim генерирует HTML код с другим форматированием, под которое мои regex'пы не подходят.

Георгий Виноградов комментирует...

Вот такое вот генерится:
<html>
<head>
<title>~/tp/hw.c.html</title>
<meta name="Generator" content="Vim/7.0">
<meta http-equiv="content-type" content="text/html; charset=windows-1251">
</head>
<body bgcolor="#ffffff" text="#000000">
<pre>
<font color="#ffff00">1 </font><font color="#ff40ff">#include </font><font color="#ff6060"><stdio.h></font>
<font color="#ffff00">2 </font>
<font color="#ffff00">3 </font><font color="#00ff00">int</font> main(<font color="#00ff00">void</font>){
<font color="#ffff00">4 </font> printf(<font color="#ff6060">"hello, world!</font><font color="#ff40ff">\n</font><font color="#ff6060">"</font>);
<font color="#ffff00">5 </font> <font color="#ffff00">return</font> <font color="#ff6060">0</font>;
<font color="#ffff00">6 </font>}
</pre>
</body>
</html>

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

Конищев Дмитрий комментирует...

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

В вашем случае просто замените строки
%s/<br>$//
%s/\_^\_.*<body[^>]*><font[^>]*>\_\s*/<pre class="my_code_box"><font color="#000000">/
%s/\_\s*<\/font><\/body>\_.*/<\/font><\/pre>/
на
%s/\_^\_.*<body[^>]*>\_\s*<pre>\_\s*/<pre class="my_code_box"><font color="#000000">/
%s/\_\s*<\/pre>\_\s*<\/body>\_.*/<\/font><\/pre>/

Георгий Виноградов комментирует...

Огромное спасибо! Все работает.

Георгий Виноградов комментирует...

Появился еще один вопрос, но он, надеюсь,последний. Как выглядит Ваша Make цель для получения ctags?

Конищев Дмитрий комментирует...

Примерно так:

vim:
    make # Чтобы, если в программе есть ошибки, генерация тэгов не выполнялась
    @echo Creating Vim directory...
    mkdir -p $(VIM_PREFIX)
    @echo Generating Vim ctags...
    tags=''; \
    for file in $(SRC_PREFIX)*.c; \
    do \
     tags+=$$(gcc -M $(CFLAGS) $(SRC_PREFIX)$$(basename $$file) | sed -r 's/.+?://'); \
    done; \
    tags=$$(echo $$tags | sed 's/\\//g' | sed 's/ /\n/g' | sort -u); \
    ctags -f $(VIM_PREFIX)ctags $$tags
    @echo "Vim ctags successfully gotten."
    @echo Generating Vim syntax...
    sed -r '/\tt(\ttyperef:struct:[a-zA-Z0-9_]+){0,1}$$/!d' $(VIM_PREFIX)ctags | awk '{print "syn keyword cType", $$1}' | sort -u > $(VIM_PREFIX)syntax.vim
    @echo Vim files has been created...

Анонимный комментирует...

для того, чтобы langmap работал с utf-8 существует патч к vim-у - vim71-langmapmb-4.patch.

По этому имени его можно найти в сети

Александр Вольф комментирует...

А нет ли всего этого в виде pdf/odf - чтобы можно было распечатать?

Конищев Дмитрий комментирует...

Александр Вольф, как-то об этом не задумывался. Хотя бы потому, что blogspot не позволяет прикладывать файлы. К тому же Ctrl+C + Ctrl+V дают вполне приличный результат. =)

brutaler комментирует...

огромное спасибо за gk и gj!!

Dzmitry комментирует...

А не поможете ли бедным виндузятникам?.. Хотя может система тут не важна... В общем я столкнулся с тем, что способ с keymap не работает при поиске... т.е. при запуске везде раскладка английская (нормал, комманд и инсерт), но при поиске "вдруг" появляются русские буквы... приходится ещё раз нажимать C-F, что ну очень неприятно

Конищев Дмитрий комментирует...

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

Дмитрий Павленко комментирует...

Ну я вроде нашёл решение для проблемы:

" Чтобы дефолтная раскладка была и в режиме поиска
set imsearch=-1
" Чтобы менялся цвет при переключении раскладки в поиске
cmap <C-F> <C-^><C-R>=MyKeyMapHighlight()<CR><Left><Del>

Конищев Дмитрий комментирует...

Дмитрий Павленко, спасибо! Работает.

Анонимный комментирует...

Вообще-то на <C-F> стандартно висит прокрутка буфера на страницу вниз и мапить на <C-F> переключение раскладки, а потом изголяться с PgUp PgDown как-то нелогично. <C-F> и <C-B> отлично справляются с прокруткой буфера и запоминаются легко (от forward и backward соответственно). Кроме того они гораздо удобнее PgUp и PgDown так как руки из основной позиции убирать ненужно. И чем собственно не угодила <C-^> для переключения раскладки?
Вообще есть мнение, причём не только моё, что перепиливание стандартных шорткатов в виме, при обработке оного напильником - дело неблагодарное, а уж таких фундаментальных как шорткаты для навигации по тексту - Абсолютное Зло! Большинство из них совершенно логичны, а те что нелогичны - таковыми кажутся с непривычки. ;-) Неужели не хватает незадействованных комбинаций? Теперь большинство использующих Ваш .vimrc никогда не узнают, что для прокрутки буфера необязательно использовать такие неудобные PgUp и PgDown.)))
С уважением, Александр.

Конищев Дмитрий комментирует...

Анонимный, сейчас уже не помню. Возможно, потому, что когда я писал данную статью, мои руки не настолько хорошо были разработаны для слепого набора, как сейчас, и нажатие C-^ мне казалось не таким удобным, тем более что раскладки я переключаю довольно часто, а C-F и C-B я никогда не пользовался, т. к. по файлам бегаю при помощи других команд.

Незадействованных комбинаций действительно не хватает! :) Куда не плюнь, все, которые наиболее удобно использовать, уже заняты. Кстати, сейчас посмотрел - на C-^ в Normal-режиме повешена какая-то совсем другая команда, так что можно считать, что она тоже занята. :)

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

pirks комментирует...

Вы пишете:
" Настраиваем работу с ctags -->
set tags+=.vim/ctags

Тобишь tags файл лежит в директории
(каталог проекта).vim/
При таком раскладе у меня команда tag ищет проиндексированные файлы не в директории проекта, а в .vim/ ((

Что я не так сделал ?

P.S.
Кстати по вашей цели vim: в make файле не видно, что tags файл лежит в .vim/

pirks комментирует...

Сори,неправ- в make файле то как раз и прописано, но ищет tag именно в .vim/

В результате ошибки примерно такие:
E429: Файл ".vim/modbusrtu.c" не существует

Файл modbusrtu.c находится на директорию выше ...

Конищев Дмитрий комментирует...

В главе "Использование Vim в качестве IDE (среды разработки)" написано, что я вызываю скрипт для запуска "VimIDE". Этот скрипт перед запуском Vim переходит в каталог с проектом, где я и продолжаю работу - так гораздо удобнее, т. к. при открытии файлов проекта достаточно ввести их путь относительно корня проекта.

pirks комментирует...

Скрипт я запускаю ..
И при наборе :tag имя_функции функции находит ?

Конищев Дмитрий комментирует...

Не знаю, т. к. давно уже не использую ctags. :) Как-то и без них неплохо.

pirks комментирует...

Ясно.
Спасибо за статью, очень полезный и практичный пример настройки vim.

И последний вопросик, вот если в проекте под 50 файлов, и куча классов..., есть сопряжение нескольких языков. Как в этом случае найти нужную функцию без использования ctags ?

Анонимный комментирует...

Лучшее описание, которое я читал по vim. Спасибо!

Николай Фоминых комментирует...

Спасибо за толковую статью. Будем-с разбираться. :)

Георгий Виноградов комментирует...

Создал такую структуру:
ftplugin
|
|_ haml.vim
|_ haml
|_ haml_tabs.vim

в haml_tabs.vim прописано setlocal tabstop=2. haml.vim -- то же самое, что и у вас. Однако tabstop не переустанавливается...

Конищев Дмитрий комментирует...

Ну так со стороны сложно сказать - может быть, у вас просто в директории haml какой-нибудь файл оверрайдит tabstop, или в вашем дистрибутиве по умолчанию отключен ftplugin...

sarbash.s комментирует...

Большое спасибо за сообщение, очень познавательно. Набрёл на Ваш блок в поисках решения проблемы с использованием русских символов в шаблонах регекспов. Может, Вы подскажете, почему такие классы, как, например [:alpha:] не воспринимают русские буквы? Единственное, что на ум приходит, это использовать классы [а-яА-Я], однако это я не проверял, так как мысль пришла во время поиска ответа на вопрос. Я так понимаю, классы и спецсимволы в паттернах заточены только под аски-кодировку в Vim'е?

Конищев Дмитрий комментирует...

Да, любая regex-библиотека по умолчанию воспринимает текст как ASCII. Для поддержки юникода обычно приходится указывать дополнительную опцию парсеру. Посмотрите в документацию - может быть, Vim позволяет это сделать, хотя я бы на это особо не расчитывал. :)

sarbash.s комментирует...

Благодарю за ответ, Дмитрий.
В самом деле, я тоже в доках при беглом просмотре не нашёл возможности указать национальные символы, чтобы буквы воспринимались, как буквы, тем не менее класс [а-яА-Я] прекрасно работает. И на том спасибо. :)
Тут же мысль родилась - а нельзя ли назначить метасимвол на свой класс?.. Чтобы так же коротко можно было запись делать. :)
Посмотрю по-возможности.

raggi комментирует...

Спасибо большое за HowTo, подчерпнул много нового

Artur Davletov комментирует...

Здравствуйте, у меня тормозит ctags, запускаю проект по этому мануалу, но для ruby языка.

Жудекс Казарян комментирует...

Спасибо

Анонимный комментирует...

большое спасибо за статью!

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

Анонимный комментирует...

короче, что бы .vimrc заработал, его оказывается нужно разместить в директории /home, а не в /.../vim/vim74

здесь нашел http://vimdoc.sourceforge.net/htmldoc/starting.html#vimrc