Удобный Vim

С тех пор, как научился пользоваться Vim, при пользовании любым другим редактором кода возникает ощущение того, что что-то не так. В то же время, большое количество народу боится этот редактор и считает затраты времени на его изучение совершенно не оправданными. На самом деле это не так, изучить как пользоваться Vim очень просто и по первому времени, больше всего, не хватает нормальной конфигурации, так как Vim, по большому счету, это конструктор из которого можно собрать почти что угодно. Этот пост будет о том, что стоит прочитать про Vim и как его настроить. Каких-то рассказов о том, почему именно Vim я писать не собираюсь, так как цели убедить кого-то у меня нет.
Так как Vim сильно отличается от большинства редакторов и IDE, то вариант “сел и начал писать” не сработает. Поэтому, придется начать с руководства и тут возникает проблема – с какого именно руководства начинать, их же тысячи! В то же время:

  • Самая краткая и полезная справка по Vim – Best Vim Tips, по большому счету, это даже не справка а шпаргалка, которую в первое время стоит всегда иметь под рукой.
  • Самая лучшая книга посвященная Vim – Hacking Vim, с ней стоит ознакомится сразу после введения.

Сам редактор стоит слегка допилить под свои вкусы.

"  Показывать номера строк
set number
" Включить подсветку синтаксиса

syntax on
" Поиск в процессе набора

set incsearch
" Подсвечивание результатов поиска

set hlsearch
" умная зависимость от регистра. Детали `:h smartcase`

set ignorecase
set smartcase
" Кодировка текста по умолчанию utf8

set termencoding=utf8
" Включаем несовместимость настроек с Vi, так как Vi нам и не понадобится

set nocompatible
" Показывать положение курсора всё время.

set ruler
" Показывать незавершённые команды в статусбаре

set showcmd
" Фолдинг по отсупам

set foldenable
set foldlevel=100
set foldmethod=indent
" Выключаем звуковое оповещение о достижении конца буффера, невозможности действия и т.д.

set noerrorbells visualbell t_vb=
autocmd GUIEnter * set visualbell t_vb=
" Поддержка мыши

set mouse=a
set mousemodel=popup
" Не выгружать буфер, когда переключаемся на другой

" Это позволяет редактировать несколько файлов в один и тот же момент без необходимости сохранения каждый раз

" когда переключаешься между ними

set hidden
" Скрыть панель в gui версии

set guioptions-=T
" Сделать строку команд высотой в одну строку

set ch=1
" Скрывать указатель мыши, когда печатаем

set mousehide
" Включить автоотступы

set autoindent
" Не переносить строки

set nowrap
" Преобразование Таба в пробелы

set expandtab
" Размер табуляции по умолчанию

set shiftwidth=4
set softtabstop=4
set tabstop=4
" Формат строки состояния. Альтернативные варианты настройки `:h statusline`

set statusline=%<%f%h%m%r\ %b\ %{&encoding}\ 0x\ \ %l,%c%V\ %P
set laststatus=2
" Включаем "умные" отступы, например, авто отступ после `{`
set smartindent
" Отображение парных символов

set showmatch
" Указание размеров окна редактора по умолчанию

set lines=50
set columns=140
" Навигация с учетом русских символов, учитывается командами следующее/предыдущее слово и т.п.

set iskeyword=@,48-57,_,192-255
" Удаление символов бэкспэйсом в Windows

set backspace=indent,eol,start
" Подсвечивать линию текста, на которой находится курсор

set cursorline
highlight CursorLine guibg=lightblue ctermbg=lightgray
highlight CursorLine term=none cterm=none
" Увеличение размера истории

set history=200
" Дополнительная информация в строке состояния

set wildmenu
" Настройка отображения специальных символов

set list listchars=tab:→\ ,trail:·
" Включение сторонних плагинов

filetype plugin on

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

function! SuperCleverTab()
    if strpart( getline('.'), 0, col('.')-1 ) =~ '^\s*$'
        return "\<Tab>"
    else
        return "\<C-p>"
    endif
endfunction

inoremap <Tab> <C-R>=SuperCleverTab()<cr>

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

if filereadable(".vim_config")
    source .vim_config

Обычно я использую эту функцию для автоматического задания команды компиляции, например так:

set makeprg=rustc\ %

Существует несколько плагинов, которые, на мой взгляд, просто необходимо установить:

  • UltiSnips – поддержка шаблонов кода.
  • manpageview – простой и удобный просмотр man-страниц.
  • bufexplorer – список открытых буффуров с возможностью переключиться на нужный.
  • fswitch – переключение между заголовком/реализацией, например, между .cpp/.h
  • NERD_commenter – как ни странно, у Vim нет встроенной поддержки комментариев кода, так что если хочется закоментировать/раскоментировать код быстро, то нужно устанавливать плагин.
  • tagbar – список тэгов присутсвующих в текущем буффере.
  • grep – расширенные возможности grep.

Настройки UltiSnips и tagbar желательно изменить следующим образом:

" по умолчанию, UltiSnips вешается на TAB, что не желательно т.к. на этой клавише
" уже "висит" функция SuperCleverTab
let g:UltiSnipsExpandTrigger = "<c-j>"
" по умолчанию, окно с тэгами отображается справа, что не привычно.

let g:tagbar_left = 1

Отдельно бы хотелось сказать о биндингах. Существует много вариаций биндингов, аналогичных VS, Eclipse, Xcode и прочим, пользоваться которыми я бы крайне не рекомендовал. Дело в том, что пусть я и вношу небольшие коррективы в конфигурацию редактора, в целом его поведение остается стандартным и любой другой Vim, доступ к которому был получен, к примеру, по SSH, не ошарашит непонятными комбинациями клавиш. Да и надо отдать должно создателям редактора – комбинации продуманные и легко запоминающиеся. А вот расширить биндинги для упрощения работы со сторонними плагинами очень даже стоит.

" просмотр списка буферов
nmap <C-b> <Esc>:BufExplorer<cr>
vmap <C-b> <esc>:BufExplorer<cr>
imap <C-b> <esc><esc>:BufExplorer<cr>
" Панель с тэгами текущего файла

nmap <C-\> :TagbarToggle<CR>
" Символ `@` в командном буфере разворачивается в путь до текущего файла.

" Крайне удобно использовать для открытия файла из той же директории,

" где находится текущий редактируемый файл

cnoremap @ <c-r>=expand("%:h")<cr>/
" Переключение между файлом с прототипами <-> реализацией (например: .h <-> .cpp)

nmap <silent> <Leader>of :FSHere<cr>
" Быстрый вызов Grep

nmap fd :Rgrep<cr>
nmap fb :GrepBuffer<cr>

И на всякий случай, моя конфигурация vimrc.

5 Comments Удобный Vim

  1. Dmitriy T.

    Местами интересно. Удивляет правда отсутствие NERDTree – обычно его всегда втыкают “чтоб было”.

    Я правда за минимализм, но на UltiSnips пожалуй гляну.

    Reply
    1. Alexander Stavonin

      У меня когда-то давно был установлен NERDTree, но он по факту совершенно бесполезен. Поэтому, я его больше не ставлю

      Reply
  2. Dmitriy T.

    Покопипастил тут с конфига немного и нашёл опечатку в настройках status line. Там видимо задуман был показ hex кода но куда-то делся:
    вместо 0x\ должно быть 0x%B\

    Да и я ширину полей по возможности фиксирую обычно (ну например %-4.6B и тп, для русско-английского это точно с запасом), иначе скачет туда-сюда всё – неприятно. Но это дело вкуса наверное.

    Reply
    1. Alexander Stavonin

      Задумку уже не помню, но, скорей всего, это было значение символа в HEX, спасибо за замечание!

      А вот про ширину полей я не понял. Каких полей?

      Reply
      1. Dmitriy T.

        Ну я под полем подразумевал например отображение в статусной строке hex-кода символа, ну и отображение номера строки и тп – тоже поля. Вобщем практически всё что в statusline со знаком % – я назвал полем. Технически правильно их называть “status line item”, как подсказывает помощь, а field это один из элементов из которых состоит каждый item так что тут я конечно неудачно назвал item полем.

        И если я двигаю курсор с символа на символ то десятиричный код символа (%b) и hex-код (%B) очень часто меняют длину от 1 до 4 в случае англо-язычного текста в UTF-8. И соответственно всё что после них в строке постоянно меняет горизонтальную координату.

        И если написать например %4.6b вместо просто %b то мы устанавливаем минимальную ширину 4 и максимальную 6. Понятно что максимальную можно не задавать в данном случае – бесконечного уникода не бывает :), но просто для примера я задал. Тогда под этот элемент минимум 4 позиции выделено всегда и пока значение в них помещается не будет постоянных “подергиваний” позиций последующих элементов статусной строки. Надеюсь понятно объяснил. Проще наверное скриншотов наклепать – но сейчас сильно занят…

        Reply

Leave a Reply to Dmitriy T. Cancel reply