Мой vim

Заметка написана в 2017 году и успела устареть. Сейчас у меня установлен neovim, а набор плагинов стал минималистичнее. Актуальная версия vimrc всегда доступна на гитхабе

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

Установка плагинов

В качестве пакетного менеджера для плагинов vim я использую vundle. Для установки надо просто склонировать репозиторий в директорию ~/.vim/bundle, создать .vimrc по шаблону и выполнить :PluginInstall.

set nocompatible
filetype off

let $PATH = $PATH . ':' . expand("~/.local/bin")

set rtp+=~/.vim/bundle/Vundle.vim

call vundle#begin()

Plugin 'VundleVim/Vundle.vim'
" Тут место для плагинов
call vundle#end()
" Тут место для команд конфигурации

Теперь для добавления нового плагина достаточно прописать строчку со ссылкой на него в конфиг и выполнить :PluginInstall.

Полезные шорткаты

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

По умолчанию кнопка <leader> привязана к \, но мне удобнее переназначить её на запятую let mapleader=",".

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

vmap <F2> "+y
nmap <F3> "+p

vmap <leader>y :w! ~/.vbuf<CR>
nmap <leader>y :.w! ~/.vbuf<CR>
nmap <leader>p :r ~/.vbuf<CR>

На заметку: vmap означает привязку сокращения к команде в режиме визуального выделения, а nmap ―вне этого режима.

nmap <silent> // :nohlsearch<CR> ― выключение подсветки результатов поиска.

Изменение регистра всего слова:

nmap <leader>u mQviwU`Q
nmap <leader>l mQviwu`Q

Переключение между режимами переноса строк:

nmap <silent> <leader>tw :set invwrap<CR>:set wrap?<CR>

Ввод пароля суперпользователя для сохранения файла с рут-правами:

cmap w!! %!sudo tee > /dev/null %

Хранение истории undo после закрытия файла:

if has('persistent_undo')
  silent !mkdir ~/.vim/backups > /dev/null 2>&1
  set undodir=~/.vim/backups
  set undofile
endif

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

nmap <silent> <F4> :set invpaste<CR>:set paste?<CR>
imap <silent> <F4> <ESC>:set invpaste<CR>:set paste?<CR>

А этот шорткат найдёт метки мердж-конфликтов при работе с гитом:

nmap <silent> <leader>fc <ESC>/\v^[<=>]{7}( .*\|$)<CR>

Визуальное оформление

Плагин для темы jellybeans Plugin 'nanotech/jellybeans.vim'. Включаем цветовое оформление:

set t_Co=256
colorscheme jellybeans
syntax on

Теперь надо сделать редактор более удобным для работы с исходниками. Для этого мне понадобится отображение номеров строк, выделение текущей строки, подсветка результатов поиска и ещё несколько опций:

set number
set cursorline
set hlsearch
set incsearch " перемещение курсора уже во время набора строки поиска
set wildmenu

Последняя опция добавляет удобное автодополнение команд редактора в командной строке.

Ещё одна важная настройка ― это активация скролла и выделения мышью:

if has('mouse')
  set mouse=a
endif

Стандартная строка состояния отображает мало информации, поэтому я подключил сторонний плагин:

Plugin 'vim-airline/vim-airline'
Plugin 'vim-airline/vim-airline-themes'

Активация командной строки и установка темы:

set laststatus=2
let g:airline_theme='minimalist'
let g:airline_section_warning=airline#section#create(['ycm_warning_count']) " отключение предупреждений о пробелах в конце строк

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

let g:airline_powerline_fonts = 1

if !exists('g:airline_symbols')
    let g:airline_symbols = {}
endif

let g:airline_left_sep = '»'
let g:airline_left_sep = '▶'
let g:airline_right_sep = '«'
let g:airline_right_sep = '◀'
let g:airline_symbols.branch = '⎇'
let g:airline_symbols.paste = 'ρ'
let g:airline_symbols.paste = 'Þ'
let g:airline_symbols.paste = '∥'
let g:airline_symbols.whitespace = 'Ξ'

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

То, без чего нельзя представить современные текстовые редакторы ― это дерево файлов. Есть плагин и для этого. Заодно добавил плагин для быстрого поиска по файлам проекта:

Plugin 'scrooloose/nerdtree'
Plugin 'kien/ctrlp.vim'
nmap <silent> <leader><leader> :NERDTreeToggle<CR> " раскрытие и скрытие дерева по двойному нажатию на запятую

Теперь можно искать файлы по нажатию .

Настройка редактора

Теперь к конфигурации непосредственно редактирования текста:

set nowrap
set ignorecase " игнорирование регистра при поиске
set smartcase " но только если сама строка поиска в нижнем регистре

" для повышения производительности
set lazyredraw " не перерисовывать буферы после макросов
set hidden " скрывать буферы вместо закрытия
" выключение вимовских бэкапов
set nobackup 
set noswapfile

" бэкспэйс в режиме вставки должен работать, как и в других редакторах
set backspace=eol,start,indent
set history=500
set undolevels=500
set autoindent
set expandtab " замена табов пробелами
set tabstop=4
set shiftwidth=4 " на сколько пробелов заменяем
autocmd Filetype scala setlocal ts=2 sw=2 autoindent " для файлов .scala свой конфиг табуляции

" включение плагинов по типу файла
filetype plugin indent on 
" закрытие дополнительных буфером (например, с документацией к функции) после сдвига курсора
autocmd CursorMovedI * if pumvisible() == 0|pclose|endif
autocmd InsertLeave * if pumvisible() == 0|pclose|endif

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

Plugin 'Shougo/neocomplete.vim'
Plugin 'ervandew/supertab'

и настроить автодополнение:

let g:neocomplete#enable_at_startup = 1
let g:neocomplete#enable_smart_case = 1

let g:neocomplete#sources#syntax#min_keyword_length = 3

Для того, чтобы иметь возможность заменять строки сразу во всех файлах проекта по команде :Replace abc cba, надо поставить ещё один плагин:

Plugin 'dkprice/vim-easygrep'

Этот плагин, кстати, поддерживает регулярки по умолчанию и предоставляет более подробный поиск по :Grep abc.

При помощи Plugin 'mbbill/undotree' можно получить удобный доступ к истории изменения файла. Только надо сделать удобный шорткат для этого: nmap <silent> <leader>z :UndotreeToggle<CR>.

Ещё можно добавить подсветку опечаток и грамматически неверных слов в файлах некоторых форматов:

Plugin 'reedes/vim-lexical'

let g:lexical#spell = 1
augroup lexical
  autocmd!
  autocmd FileType markdown,mkd call lexical#init()
  autocmd FileType textile call lexical#init()
  autocmd FileType text call lexical#init({ 'spell': 0 })
augroup END
let g:lexical#spelllang = ['en_us', 'ru_ru',]

Окружение для разработки

Чтобы редактор мог находить определение функций или переменных в разных языках программирования, понадобится плагин, применяющий утилиту ctags. Устанавливаем exuberant-ctags в своей операционной системе и прописываем в .vimrc:

Plugin 'xolox/vim-easytags'
Plugin 'xolox/vim-misc'
Plugin 'majutsushi/tagbar'

let g:easytags_async = 1
nmap <F8> :TagbarToggle<CR>

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

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

Plugin 'Shougo/vimproc.vim'
Plugin 'Shougo/vimshell.vim'

let g:vimshell_user_prompt = 'fnamemodify(getcwd(), ":~")'
let g:vimshell_prompt =  '$ '

Но сейчас недостаточно просто поставить плагины через пакетный менеджер. Надо ещё выполнить

cd ~/.vim/bundle/vimproc.vim
make

Теперь можно запускать командную строку командой :VimShell.

Естественно, для нормальной разработки необходим git. Плагин fugitive даёт возможность работать с гитом прямо из вима. Можно использовать спецальные команды плагина, например, :Gstatus, а можно писать обычные комманды гита :Git status.

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

Plugin 'w0rp/ale'

function! LinterStatus() abort
    let l:counts = ale#statusline#Count(bufnr(''))

    let l:all_errors = l:counts.error + l:counts.style_error
    let l:all_non_errors = l:counts.total - l:all_errors

    return l:counts.total == 0 ? 'OK' : printf(
    \   '%dW %dE',
    \   all_non_errors,
    \   all_errors
    \)
endfunction

set statusline=%{LinterStatus()}

" перемещение между ошибками
nmap <silent> <C-k> <Plug>(ale_previous_wrap)
nmap <silent> <C-j> <Plug>(ale_next_wrap)

Плагин ale будет на лету прогонять код через линтеры. Соответственно, утилиты для проверки кода, например, flake8 для Python, должны быть установлены в системе. Для использования утилиты, проверяющей код, не по умолчанию, используется следующая запись:

let g:ale_linters = {
\   'javascript': ['eslint'],
\}

Информацию по доступным утилитам можно посмотреть при помощи :help syntastic-checkers.

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

Plugin 'scrooloose/nerdcommenter'
nnoremap <C-_> :call NERDComment(0,"toggle")<CR>
vnoremap <C-_> :call NERDComment(0,"toggle")<CR>

На заметку: в конфигах вима сочетания Control и слэша записывается как <C-_>.

Результат

Полный конфиг на данном этапе можно посмотреть здесь. А на гитхабе лежат мои текущие дотфайлы.