Досвід переходу з Sublime на Vim



Дана стаття не розкриває всіх премудростей переміщення по тексту або його редагування. Основні рухи можна дізнатися в vimtutor, інші комбінації вивчаються в процесі роботи. Деякі з них, особливо важливі у процесі програмування, я висвітлю пізніше.

Я досить довгий час використовував sublime (близько 4 років) в якості основної середовища розробки, але останнім часом дещо змінилося: я освоїв сліпий 9-ти пальцевий метод друку. В той момент я почав розуміти людей, яким незручно тягнутися до мишки або стрілках. Прибирати пальці з «домашніх» позицій стало неприродно і непродуктивно. Тоді я включив vintage. Проблема, начебто, стала неактуальна, але чогось не вистачало. Не пам'ятаю, що змусило мене пересісти за vim, але мені завжди подобалося, як у ньому виділяються фігурні дужки (MatchParen) і як виглядає курсор :). Vim я пробував і до цього, коли правил конфіги на сервері, правда, вся «магія» обмежувалася переходом в режим вставки і успішним збереженням/виходом з редактора.

Перше, що необхідно зрозуміти — vim з коробки годиться хіба що для правки конфігів, для комфортної роботи з кодом необхідно встановити кілька плагінів. Мені вистачило 33. Я не ставив перед собою мету повністю копіювати поведінку sublime, швидше зробити роботу в vim'е такий ж простий і інтуїтивно зрозумілою. Цей посібник описує всі встановлені плагіни, а також установки, які, на мою думку, роблять роботу з плагінами і самим vim'ом більш зручною. Потрібні плагіни ви можете знайти на офіційному сайті, хоча мені більше подобається vimawesome. В якості оточення виступає Ubuntu 16.04 і консольний vim 7.4.

Всі плагіни знаходяться на github, де ви можете подивитися короткий посібник з встановлення або використання того чи іншого плагіна, за детальним описом варто йти в help. Якщо з опису плагіна не ясно, як його використовувати, то, напевно, потрібна комбінація биндится в розділі гарячих клавіш. Всі налаштування прописуємо в ~/.vimrc або ~/.vim/vimrc, якщо файл не існує — створюємо. Мабуть, почнемо.

vundleНемає нічого приємного в тому, щоб ставити плагіни вручну. Vundle виступає в ролі пакетного менеджера, серед яких є також pathogen, vim-plug та інші. Не можу сказати, що зручніше, так як користувався тільки Vundle. Вибирайте на свій розсуд.

Встановлені плагіни
// set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()

// let Vundle manage Vundle, required
Plugin 'VundleVim/Vundle.vim'

// common
Plugin 'scrooloose/nerdtree'
Plugin 'valloric/youcompleteme'
Plugin 'xolox/vim-easytags'
Plugin 'majutsushi/tagbar'
Plugin 'tpope/vim-fugitive'
Plugin 'easymotion/vim-easymotion'
Plugin 'ctrlpvim/ctrlp.vim'
Plugin 'terryma/vim-multiple-cursors'
Plugin 'vim-airline/vim-airline'
Plugin 'vim-airline/vim-airline-themes'
Plugin 'scrooloose/nerdcommenter'
Plugin 'matze/vim-move'
Plugin 'raimondi/delimitmate'
Plugin 'mattn/emmet-vim'
Plugin 'scrooloose/syntastic'
Plugin 'tpope/vim-surround'
Plugin 'sirver/ultisnips'
Plugin 'honza/vim-snippets'
Plugin 'xolox/vim-session'
Plugin 'xolox/vim-misc'
Plugin 'SyntaxAttr.vim'
Plugin 'dyng/ctrlsf.vim'
Plugin 'rking/ag.vim'
Plugin 'godlygeek/tabular'

// php
Plugin 'stanangeloff/php.vim'
Plugin 'sumpygump/php-documentor-vim'
Plugin 'arnaud-lb/vim-php-namespace'

// javascript
Plugin 'pangloss/vim-javascript

// html
Plugin 'othree/html5.vim'

// twig
Plugin 'evidens/vim-twig'

// css
Plugin 'mtscout6/vim-tagbar-css'

// colors
Plugin 'damage220/solas.vim'
Plugin 'nanotech/jellybeans.vim'
Plugin 'mhartington/oceanic-next'

call vundle#end()
Команди
// перегляд всіх встановлених плагінів
:PluginList

// встановлюємо плагіни
:PluginInstall

// видаляємо непотрібні плагіни
:PluginClean

// пошук необхідного плагіна
:PluginSearch foo
Установка
git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
Залежно
git і curl
solasЗ усіх колірних тим, що я пробував, найбільше сподобалася jellybeans, але через деякий час вирішив створити свою тему. На щастя, дізнатися назви всіх груп не склало праці, до нещастя, термінали дуже обмежені в колірній палітрі і підтримують, як правило, 256 кольорів. Solas заснована на стандартній темі в PhpStorm і на даний момент працює тільки в терміналі.
moveПлагін призначений для переміщення поточного рядка або виділених рядків вгору або вниз.

налаштування
// биндим команди переміщення на <C-j> <C-k>
let g:move_key_modifier = 'C'
nerdtreeнайпопулярніший плагін, призначений для роботи з файловою системою. Додає зручні гарячі клавіші для створення, переміщення і видалення файлів і директорій.

налаштування
// автоматично оновлювати буфер після перейменування файлу
let NERDTreeAutoDeleteBuffer = 1
php-documentorПлагін створює doc-блоки для класів, властивостей класу, функцій.
phpПлагін надає поліпшену підтримку синтаксису. Оновлений список констант, класів і функцій до версії 5.6.
html5Плагін надає поліпшену підтримку синтаксису і відступів.
javascriptПлагін надає поліпшену підтримку синтаксису і відступів.
twigПлагін додає підтримку шаблонів twig.
fugitiveЗручна обгортка над git, надає безліч команд.
ultisnipsПлагін додає підтримку фрагментів в vim.

Корисні комбінації
<Tab> - вставити фрагмент
snippetsНабір фрагментів для більшості мов програмування.

Залежно
snipmate або ultisnips
SyntaxAttrПлагін показує групу синтаксису, посилання (hi link) і колір групи. Зручний плагін для створення власних колірних схем.
ctrlpЗа 3 роки я так сильно звик до нечіткого пошуку, що насилу уявляю розробку без цієї можливості. Наскільки я пам'ятаю, це був перший плагін, який я встановив. Ctrlp виробляє пошук по тегам, файлів, буферам і останнім активним файлів.

Команди
// пошук тега в поточному файлі (аналог Ctrl + R в sublime)
:CtrlPBufTag
Корисні комбінації
<C-j> <C-k> - для переміщення курсору вниз і вгору відповідно
<Enter> - відкрити в поточному вікні
<C-t> - відкрити в новій вкладці
<C-v> - відкрити файл ліворуч/праворуч (залежить від налаштувань)
<C-x> - відкрити файл зверху/знизу (залежить від налаштувань)
<C-d> - перемикання режиму пошуку по імені файлу або повного шляху
налаштування
// За замовчуванням, CtrlP шукає файли за їх повного шляху, що мені здалося дивним, оскільки на запит "repo", маючи таку структуру файлів:
// project/src/Repository/Repository.php
// project/src/Repository/Foo.php
// CtrlP може надати більшу вагу файлу Foo.php. На щастя, CtrlP, як і багато інші плагіни для vim'a, має гнучку настройку. Для вирішення проблеми потрібно прописати
let g:ctrlp_by_filename = 1

// звідки починати пошук. w - найближча директорія, яка містить ознаки наявності CVS (.git .svn). r - поточна директорія (pwd).
let g:ctrlp_working_path_mode = 'wr'

// за замовчуванням, як не складно здогадатися, пошук активується натисканням <C-p>, але оскільки у мене стоїть інша комбінація (далі по тексту), я вирішив скинути стандартна поведінка.
let g:ctrlp_map = "

// прибираємо змінні зі списку тегів
let g:ctrlp_buftag_types = {
\'php': '--php-kinds=icdf'
\}
Залежно
Для пошуку по тегам потрібен ctags
tagbarМені подобається міні в sublime, глянувши на неї можна відразу зрозуміти структуру файлу. Природно, я хотів таку ж і в vim, і, треба ж, плагін так і називається — vim-minimap. На жаль, плагін мені абсолютно не сподобався. Потрібна була альтернатива, і вона знайшлася — tagbar. Плагін показує список тегів в поточному файлі, групуючи їх і сортуючи в потрібному порядку.

налаштування
// сортувати в тому порядку, в якому тег з'являється в коді, а не по імені
let g:tagbar_sort = 0

// заміна стандартних стрілок розкриття/згортання групи тегів
let g:tagbar_iconchars = ['+', '-']

// забезпечуємо перемикач
let g:tagbar_map_close = '<C-m>'

// Прибираємо змінні зі списку
let g:tagbar_type_php = {
\'ctagstype': 'php',
\'kinds': [
\'i:interfaces',
\'c:classes',
\'d:constants',
\'f:functions'
\]
\}
Залежно
ctags
tagbar-cssПлагін додає підтримку css, less і scss для tagbar. Крім установки самого плагіна, пропишіть наступні рядки в ваш ~/.ctags
--langdef=css
--langmap=css:.css.less.scss
--regex-css=/^[ \t]*@([A-Za-z0-9_-]+)/@\1/v,var,variables/
--regex-css=/^[ \t]*\.([A-Za-z0-9_-]+)/.\1/c,class,classes/
--regex-css=/^[ \t]*#([A-Za-z0-9_-]+)/#\1/i,id ids/
--regex-css=/^[ \t]*(([A-Za-z0-9_-]+[ \t\n,]+)+)\{/\1/t,tag,tags/
--regex-css=/^[ \t]*@media\s+([A-Za-z0-9_-]+)/\1/m,media,medias/
Залежно
tagbar
easymotionОдин з кращих плагінів, на мій погляд. Дозволяє миттєво переміщатися з кодом, ввівши всього кілька символів.

налаштування
// відключаємо залежність від регістра
let g:EasyMotion_smartcase = 1

// відключаємо тінь (в момент вибору мети весь текст позначається як коментар)
let g:EasyMotion_do_shade = 0

// якою групою підсвічувати цілі
hi link EasyMotionTarget Search
Примітка
Оскільки easymotion працює з буфером безпосередньо, постійно змінюючи його, місцями може з'являтися неприємний баг, коли ви спробуєте скасувати всі зміни. Vim повідомить, що ви відновили первісний стан, але при спробі вийти з редактора, з'явиться попередження про несохраненном буфері.
sessionПлагін робить роботу з сесіями більш зручною, надаючи обгортку над стандартною командою :mksession.

Команди
// відкрити сесію. Якщо ви закрили термінал або випадково натиснули <C-z>, необхідно додати "!" в кінці команди, наприклад, "OpenSession! name"
:OpenSession name

// зберегти сесію
:SaveSession name
налаштування
// відкривати сесію при старті. Опція ігнорується, якщо ми передаємо vim якісь файли
let g:session_autoload = 'yes'

// включити автозбереження
let g:session_autosave = 'yes'

// зберігати стан кожні 5 хвилин
let g:session_autosave_periodic = 5

// не повідомляти нічого при автосохранении
let g:session_autosave_silent = 1

// відкривати останню робочу сесію замість стандартної
let g:session_default_to_last = 1
Залежно
misc
miscПлагін, необхідний для роботи session.emmetПро emmet'e було сказано занадто багато, щоб писати про нього тут.

налаштування
// розгортати абревіатуру по натисненню на <C-e>
let g:user_emmet_expandabbr_key = '<C-e>'
delimitmateПлагін ставить відступи між будь-якими дужками або лапками.

налаштування
// включити відступи після натискання на enter
let delimitMate_expand_cr = 1

// включити відступи за допомогою натискання на пробіл. " |" перетворюється в " | "
let delimitMate_expand_space = 1

// для html, необхідно дописати >:<, щоб виставлялися правильні відступи
au FileType vim,html let b:delimitMate_matchpairs = "(:),[:],{:},<:>>:<"
syntasticПлагін для перевірки синтаксису. В readme радять ставити такі параметри, не сперечаємося.

налаштування
let g:syntastic_always_populate_loc_list = 1
let g:syntastic_auto_loc_list = 1
let g:syntastic_check_on_open = 1
let g:syntastic_check_on_wq = 0
NERDCommenterплагіна для коментування коду я хотів домогтися наступного поведінки: для коментування ділянки коду використовуємо <C-?> для коментування рядка, раскомментирования рядка/фрагмента коду служить <C-/>. Наскільки я пам'ятаю, з усіх встановлених мною плагінів (близько 4-х), ні один в точності не впорався з цим завданням. Щоб розкоментувати фрагмент коду доводиться використовувати стандартну комбінацію — \<Leader\>cu, де \<Leader\> — ",". Це не стандартна клавіша, за замовчуванням використовується "\". В іншому таку ж поведінку, як і в sublime.

налаштування
// кількість пробілів після символу(ів) коментаря
let g:NERDSpaceDelims = 1
airlineПлагін відображає зручну рядок статусу, яку легко кастомизировать під свої потреби. Також можна дозволити плагіну управляти зовнішнім виглядом вкладок. Для коректної роботи потрібні пропатчені шрифти, які ви можете взяти звідси.

налаштування
// solarized не входить у стандартну поставку, необхідно завантажити набір тем
let g:airline_theme='solarized'

// використовувати шрифти пропатчені
let g:airline_powerline_fonts = 1

// включити управління табами
let g:airline#extensions#tabline#enabled = 1

// завжди показувати tabline
let g:airline#extensions#tabline#tab_min_count = 0

// таку ж поведінку, як і в sublime: якщо файл з унікальною назвою - показується лише ім'я, якщо зустрічається файл з таким же ім'ям, відображається також і директорія
let g:airline#extensions#tabline#formatter = 'unique_tail'

// приховати буфери
let g:airline#extensions#tabline#show_buffers = 0

// ім'я файлу + розширення :help filename-modifiers
let g:airline#extensions#tabline#fnamemod = ':t'

// прибираємо дратівливі непотрібні червоні панелі з попередженнями чи помилками. Попередження, як на мене, не потрібні, оскільки лаються навіть на trailing-spaces і різні відступи: наприклад таби і прогалини (привіт від phpDoc). Для помилок і так відкривається додаткове вікно. Втім, вам вирішувати.
let g:airline_section_warning = "
let g:airline_section_error = "

// прибираємо "X" для закриття вкладки мишею (мишею!?)
let g:airline#extensions#tabline#show_close_button = 0

// прибираємо роздільник для вкладок
let g:airline#extensions#tabline#left_alt_sep = "

// відключаємо tagbar
let g:airline#extensions#tagbar#enabled = 0

// показувати номер вкладки
let g:airline#extensions#tabline#show_tab_nr = 1

// показувати тільки номер вкладки
let g:airline#extensions#tabline#tab_nr_type = 1
airline-themesНабір тем для airline.

Залежно
airline
youcompletemeYCM надає швидке автодоповнення коду з нечітким пошуком. «Найважчий» плагін з усіх і найнеприємніший в установці. Важить 275.9 mb і помітно сповільнює запуск редактора. Для порівняння, всі інші плагіни разом узяті займають 15.1 mb. Для роботи плагіну потрібне vim, скомпільований з підтримкою python. Для перевірки виконайте команду vim --version | grep "+python" у вашому терміналі. Я не люблю компілювати з джерел та, на щастя, в моєму репозиторії є пакет «vim-nox» з підтримкою скриптових мов.

налаштування
// ycm сам визначає відповідну версію інтерпретатора, але, чомусь, з 3 версією доповнення не показуються - ставимо другу.
let g:ycm_server_python_interpreter='python'

// закрити превью після введення, наприклад, при натисканні на закриваючу дужку ")"
let g:ycm_autoclose_preview_window_after_completion = 1

// дозволяємо ultisnips використовувати tab для розкриття сніппетів
let g:ycm_key_list_select_completion = ['<Down>']
Установка
Крім установки самого плагіна, необхідно запустити "install.py" з необхідними прапорами, детальніше в help.
multiple-cursorsНазва говорить сама за себе — плагін дозволяє працювати з декількома вказівники одночасно.

Команди
// виділити все входження
:MultipleCursorsFind pattern
Корисні комбінації
<C-n> - виділення наступного слова під курсором
<C-p> - виділення попереднього слова під курсором
<C-x> - пропустити поточне слово і перейти до наступного

// Після того, як ви виділили всі слова, можна приступити до редагування:
c - видалити і перейти в режим редагування
I - вставити в початок
A - вставити в кінець
ctrlsfДовгий час мене лякала думка, як я буду реалізовувати заміну рядки по всьому проекту, та ще з попереднім переглядом і… підтвердженням. І дарма — для vim'a знайшовся (причому майже відразу) чудовий плагін, який надає необхідний функціонал. Досить набрати команду :CtrlSF pattern [filemask] і відкриється вікно з усіма вхождениями. Редагуємо як звичайний файл зберігаємо (w). Після чого, плагін запросить підтвердження і вкаже скільки файлів зазнають змін. Будьте обережні, якщо натиснути на \<Esc\>, то дані все одно закоммитятся. Втім, завжди можна скасувати зміни (u) і зберегти буфер заново. Добре поєднується з множинними вказівники, особливо з командою :MultipleCursorsFind. CtrlSF — це абстракція над ack/ag, так що один з цих плагінів доведеться встановити. Про встановлення ag читати нижче.

Команди
:CtrlSF foo *.php
Корисні комбінації
<C-j> <З k> - перейти до наступного і попереднього входження
налаштування
// переміщаємо вікно праворуч
let g:ctrlsf_position = 'right'
Залежно
ack або ag
agОбгортка над системним ag. За заявою автора, за рахунок розпаралелювання, ag працює в 34 рази швидше ack, докладніше. Для роботи плагіну потрібно встановити сам ag. В ubuntu пакет називається silversearcher-ag.
php-namespaceПлагін для більш зручної роботи з оператором «use». Підключає необхідний клас, використовуючи тег-файл.

Залежно
ctags, згенерований тег-файл.
surroundПлагін дозволяє додавати, змінювати або видаляти навколишні текст лапки, дужки або xml-теги. ys, cs, ds — служать для вставки, заміни та видалення обрамляють символів відповідно.

Корисні комбінації
ds' - видалити одинарні лапки
dst - видалити тег обрамляє
cs'" - замінити одинарні лапки на подвійні
ysiw" - помістити слово в лапки
ysiw<a> - помістити текст в тег <a>
tabularПлагін вирівнює текст за певним шаблоном, наприклад "=" або "|". Я не любитель «б'юті» коду, але нещодавно, коли я робив шпаргалку за часів в англійській мові, плагін виявився вельми корисним.

Команди
// вирівнює текст по символу "|"
:Tabularize /|
ctagsДля роботи таких плагінів, як CtrlP, TagBar і php-namespace вам знадобиться ctags — потужна утиліта для аналізу вихідного коду програм. Ctags створює тег-файл, у якому містяться назви класів, функцій, змінних, ..., а також їх позиції. Ctags 5.9 підтримує 43 мови з коробки, але може бути розширений за допомогою регулярних виразів (дивитися tagbar-css).

Корисні ключі
// список підтримуваних мов
--list-languages

// список тегів для конкретної мови
--list-kinds=lang
Установка
Шукайте у своїх репозиторіях пакет зі схожим ім'ям. Наприклад, в ubuntu - це процвітаючими-ctags
Примітка
Для великих проектів має сенс створити який-небудь "tags.vendor" і додати цей файл в змінну "tags"
easytagsТег-файл надає багато інформації, але створювати його вручну — справа не з приємних. Easytags позбавить вас від рутини, достатньо один раз прописати :UpdateTags -R у новому проекті, а всі подальші зміни плагін проіндексує сам.

налаштування
// записуємо теги локально для кожного проекту, замість ~/.vimtags
let g:easytags_file = './tags'

// відключаємо підсвічування тегів
let g:easytags_auto_highlight = 0

// події:help autocmd-events), які слухає easytags
let g:easytags_events = ['BufWritePost']

// не блокувати vim під час оновлення тег-файлу
let g:easytags_async = 1
Залежно
ctags

Досить складно описати кожен плагін докладно, та і немає чого, напевно. Немає ніякого сенсу перераховувати всі команди, я лише описав ті, які сам використовував, але і без того стаття вийшла досить об'ємною. Тепер давайте розглянемо можливості самого редактора.

НалаштуванняЗа подробицями йдемо у :help setting
// Для роботи з табами, замість пробілів, надайте tabstop і shiftwidth однакові значення
set tabstop=4
set shiftwidth=4
set softtabstop=4

// автоматично оновлювати файл при його зміні
set autoread

// налаштовуємо відступи
set autoindent
set smartindent

// показувати відносні номери рядків. Зручно тим, що можна легко переходити до потрібної рядку командою 10j, наприклад
set rnu

// завжди показувати рядок статусу
set laststatus=2

// Час, який vim чекає для введення наступного символу комбінації клавіш.
// Наприклад, якщо в vim'e існує комбінація "df", то після введення символу "d" у вас є пів секунди,
// щоб ввести "f", інакше в буфер вставитися символ "d".
set timeoutlen=500

// цю команду я погано розумію. В документації написано, що це час очікування для введення послідовностей клавіш,
// у такому випадку, я не знаю в чому відмінність від попередньої команди. Тим не менш, коли очікування дорівнює нулю, то при натисканні <Esc>
// для виходу з візуального режиму або закриття спливаючого меню, немає жодної заминки, що дуже приємно.
set ttimeoutlen=0

// більш зручна робота з кирилицею. При натисканні <C-6> у режимі вставки, vim змінить режим з "Insert" на "Insert (lang)",
// після чого будуть вводитися російські символи. Якщо повернутися в нормальний режим, то всі команди будуть працювати.
set keymap=russian-jcukenwin
set iminsert=0
set imsearch=0

// Виставляємо кодування
set encoding=utf-8
set termencoding=utf-8

// Відключаємо swap-файли. Ставте на свій розсуд, мені ця можливість частіше заважала
set noswapfile

// Якщо протягом цього часу, ви не будете переміщати курсор або друкувати, vim оновить swap-файл,
// а також активує подія CursorHold. Деякі плагіни, начебто tagbar, слухають це подія для оновлення стану.
// Так як swap-файли я не використовую, вирішив зробити значення менші (за замовчуванням - 4000).
set updatetime=500

// :vsplit відкриває вікна праворуч
set splitright

// :split відкриває вікна знизу
set splitbelow

// прибираємо сумісність з vi
set nocompatible

// шукаємо тег-файл поточної директорії
set tags=./tags;

// Ігнорувати регістр при пошуку. Набагато зручніше вводити команди без урахування регістру, наприклад ctrlsf, замість CtrlSF.
// Для пошуку з урахуванням регістру, потрібно помістити \C в будь-яке місце шуканого рядка
set ignorecase

// наприклад, при переході до тегу, vim може лаятися, що поточний буфер не збережений, hidden вирішує цю проблему
set hidden

// підсвічувати всі збіги при пошуку
set hlsearch

// підсвічувати збіг під час пошуку на льоту
set incsearch

// виділяти рядок, на якій знаходиться курсор
set cursorline

// кількість рядків у спливаючому вікні
set pumheight=10

// використовувати пробіли для розділення вікон. Не забудьте поставити в кінці рядка символ пробілу
set fillchars+=vert:\ 

// змінюємо mapleader на ",", за замовчуванням - "\"
let mapleader=","

// рекомендовані налаштування для Vundle
filetype off
filetype on plugin
filetype plugin indent on

// включити підсвічування синтаксису
syntax enable

// обираємо темний фон
background set=dark

// обираємо схему кольорів
colorscheme solas
Комбінації клавішСинтаксис створення комбінації, як не складно здогадатися, наступний:
[[mode]nore]map command keys
де mode — режим або оточення, де працює комбінація
nore (non-recursive) — не «розкривати» комбінацію, а використовувати значення за замовчуванням
:map j gg // j = gg
:map Q j // Q = gg
:noremap W j // W = j

<CR> - enter
<> - Ctrl
Детальніше про призначення комбінацій
// виходимо в "нормальний" режим за df. "d" використовується набагато частіше, ніж "j"
// напевно, забиндить "jj" було б куди краще, але я вже звик, до того ж так швидше
imap df <Esc>l

// часто потрібно відокремлювати блоки коду пустим рядком, наприклад, перед return
nnoremap 2o o<CR>

// теж саме, що і попередня команда, тільки в іншому напрямку
nnoremap 2O O<Esc>O

// пересунути поточну вкладку праворуч
nnoremap tm :tabm +1<CR>

// пересунути поточну вкладку ліворуч
nnoremap tM :tabm -1<CR>

// прибрати підсвітку знайдених збігів
nnoremap <C-h> :noh<CR>

// коментуємо фрагмент коду
map <C-?> <plug>NERDCommenterComment

// коментуємо рядок, повторне натискання прибирає коментар
map <C-_> <plug>NERDCommenterToggle

// створюємо phpDoc для функцій, класів, властивостей
nnoremap <C-d> :call PhpDoc()<CR>

// показати вікно з тегами
nnoremap <C-m> :TagbarToggle<CR>

// показати дерево проекту
nnoremap <C-p> :NERDTreeToggle<CR>

// показати syntax group для ділянки коду, а також колір цієї групи. Зручно при створенні своєї колірної схеми
nnoremap <C-g> :call SyntaxAttr()<CR>

// мені набагато зручніше натиснути <C-j> <C-k> для вибору наступного і попереднього значення, ніж <C-n> <C-p>
inoremap <C-j> <C-n>
inoremap <C-k> <C-p>
cnoremap <C-j> <C-n>
cnoremap <C-k> <C-p>

// прописуємо use
autocmd FileType php noremap <C-u> :call PhpInsertUse()<CR>

// відкрити ~/.vimrc
nnoremap <F4> :tabe ~/.vimrc<CR>:tabm 0<CR>

// зберегти ~/.vimrc і застосувати зміни
nnoremap <F5> :w<CR>:so $MYVIMRC<CR>
Мені не подобається ідея змінювати поведінку клавіш, але такі комбінації я знайшов досить зручними для себе. Я рідко користуюся пошуком символу в рядку (f і F), а такі команди, як J і K, я жодного разу так і не використав.
// переміститися в початок видимій області
nnoremap K H

// переміститися в кінець видимій області
nnoremap J L

// відкрити попереднє вікно
nnoremap H gT

// відкрити наступне вікно
nnoremap L gt

// вікно пошуку файлів
nnoremap F :CtrlP<CR>
nnoremap ff :CtrlP<CR>

// find tag - нечіткий пошук тегів у файлі
nnoremap ft :CtrlPBufTag<CR>

// find buffer - нечіткий пошук буфера
nnoremap fb :CtrlPBuffer<CR>

// find symbol - переміститися до будь-якого символу в файлі
nmap fs <Plug>(easymotion-s)

// find line - переміститися до будь-якого символу в рядку
nmap fl <Plug>(easymotion-sl)

// find current - знайти поточний файл в дереві проекту
nnoremap fc :NERDTreeFind<CR>

// find pattern - пошук слова в проекті
nnoremap fp :CtrlSF 
найскладнішим завданням для мене виявилася установка youcompleteme налаштування перемикання вкладок <Alt-n>, на яку я витратив годин 5 (5, Карл!). Як я тільки не писав: <Alt-1> <A-1> <M-1>, ^[1 — escape-послідовність (<C-v>, потім Alt + 1). Читав :help :map-alt-keys, створював файл ~/.inputrc з вмістом set convert-meta on. Забавно, але в xterm все працювало. Gnome-terminal підніс мені безліч незабутніх відчуттів, поки я не натрапив на цей відповідь SO. Повинен зізнатися, я майже відразу знайшов цю відповідь, але мені здалося, що програмувати комбінацію клавіш, хм, занадто. Трохи змінивши приклад, отримуємо:
for c in range(1, 9)
exec "set <A-".c.">=\e".c
exec "map \e".c." <A-".c.">"

let n = c - '0'
exec "map <M-". n ."> ". n ."gt"
endfor
Це якийсь мазохізм, і я вірю, що є щось більш адекватне (напишіть в коментарях, якщо це так, будь ласка), просто в той момент я був радий будь-якого рішення.
Деякі стандартні комбінації
// вставка з системного буфера. Потрібен vim, скомпільований з прапором "clipboard". Щоб перевірити, наберіть vim --version | grep "+clipboard" у вашому терміналі
<C-r> *

// центру екрана на поточному рядку
zz

// перейти до визначення тега (необхідний тег-файл)
<C-]>

// повернутися на рівень вище по стеку викликів команди <C-]>
<C-t>

// вставка останнього віддаленого(d) або скопійованого(y) тексту. Зручно використовувати в режимі вставки або в режимі командного рядка
<C-r> "
АбревіатуриVim дозволяє створювати корисні скорочення команд, просто пропишіть в вашому .vimrc наступне «abbr help tab help» і після введення «help», і натискання пробілу, vim розкриє її до «tab help». Щоб уникнути «розкриття», перед пропуском натисніть <C-v>.
Висновок: vim дає свободу, незрівнянну ні з чим. Можливо, emacs може скласти конкуренцію, але з ним поки не працював. Перехід від sublime'a до vim'у нагадує мені перенавчання з 4-х пальцевої (наскільки я пам'ятаю) друку на 9-ти пальцеву. Не зрозумійте мене неправильно, sublime чудовий редактор, мова про те, що спочатку ви втрачаєте звичну швидкість; проходить час, продуктивність повертається до колишнього рівня і починаючи з цього моменту ви нарощуєте швидкість. Всі основні функції, якими я користувався в sublime, перекочували в vim в тому чи іншому вигляді. Саме час відпрацьовувати комбінації і розширювати стандартні можливості редактора з допомогою viml. Є ще одна особливість, яка нагадує мені зміну основної ОС Windows на Ubuntu. У Windows я користувався терміналом, напевно, разів 10 за весь час. Я не можу сказати, що мені чогось не вистачало, все цілком влаштовувало. Але коли переходиш на linux, то волею-неволею починаєш використовувати консольні команди. Не усвідомлено (і це важливо) ви отримуєте інструмент (bash) для вирішення визначених завдань. У vim'e доводиться постійно щось гуглити в пошуках вирішення тих чи інших проблем. Дуже часто я бачу рішення, які відрізняються від звичної налаштування sublime або схожих редакторів в стилі key, value. Ви в буквальному сенсі програмуєте свій редактор. Майже відразу ви бачите, як ініціалізувати змінну, трохи пізніше — як застосувати ту чи іншу налаштування для певного типу файлів, ще пізніше — як слухати події або створювати цикли. По крупицях інформації ви отримуєте уявлення про viml і, можливо, скоро напишіть свій перший плагін. Звичайно, все це можна дізнатися просто відкривши документацію до мови, але, повинен сказати, бажання освоїти python або api sublime у мене так і не з'явилося. Особисто я впевнений, що vim приберіг для мене ще чимало приємних сюрпризів, а мій .vimrc, схоже, буде змінюватися весь час, поки я працюю з цим редактором.

Кілька запитань1. Якщо буфер змінився, airline виділить таб іншим кольором, тим не менше, коли ми перемикаємося на іншу вкладку, змінена вкладка забарвлюється в звичайний колір. З-за цього, при виході з редактора, часто отримую попередження, що буфер не збережено. Можна підсвічувати всі змінені вкладки, незалежно від того, активні вони чи ні?
2. В readme nerdtree сказано, що можна змінити символ відкриття/закриття директорії прописавши g:NERDTreeDirArrowExpandable і g:NERDTreeDirArrowCollapsible. Однак, при спробі виставити "+" і "-", nerdtree падає. Хто-небудь пробував полагодити?
3. Як подружити youcompleteme і omnicompletion? Доводиться йти прямо, натискаючи <C-x><C-o>.
4. На початку кожного php-скрипта стоїть "<?php", коли курсор знаходиться над "<", то vim шукає найближчий ">". Як відключити підсвічування цього символу для php-файлів? Щось на подобі:
au FileType php set matchparen-=<
.vimrc цілком" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()

" let Vundle manage Vundle, required
Plugin 'VundleVim/Vundle.vim'

" common
Plugin 'scrooloose/nerdtree'
Plugin 'valloric/youcompleteme'
Plugin 'xolox/vim-easytags'
Plugin 'majutsushi/tagbar'
Plugin 'tpope/vim-fugitive'
Plugin 'easymotion/vim-easymotion'
Plugin 'ctrlpvim/ctrlp.vim'
Plugin 'terryma/vim-multiple-cursors'
Plugin 'vim-airline/vim-airline'
Plugin 'vim-airline/vim-airline-themes'
Plugin 'scrooloose/nerdcommenter'
Plugin 'matze/vim-move'
Plugin 'raimondi/delimitmate'
Plugin 'mattn/emmet-vim'
Plugin 'scrooloose/syntastic'
Plugin 'tpope/vim-surround'
Plugin 'sirver/ultisnips'
Plugin 'honza/vim-snippets'
Plugin 'xolox/vim-session'
Plugin 'xolox/vim-misc'
Plugin 'SyntaxAttr.vim'
Plugin 'dyng/ctrlsf.vim'
Plugin 'rking/ag.vim'
Plugin 'godlygeek/tabular'

" php
Plugin 'stanangeloff/php.vim'
Plugin 'sumpygump/php-documentor-vim'
Plugin 'arnaud-lb/vim-php-namespace'

" javascript
Plugin 'pangloss/vim-javascript

" html
Plugin 'othree/html5.vim'

" twig
Plugin 'evidens/vim-twig'

" css
Plugin 'mtscout6/vim-tagbar-css'

" colors
Plugin 'damage220/solas.vim'
Plugin 'nanotech/jellybeans.vim'
Plugin 'mhartington/oceanic-next'

call vundle#end()

" settings
set tabstop=4
set softtabstop=4
set shiftwidth=4
set autoread
set autoindent
set smartindent
set rnu
set laststatus=2
set timeoutlen=500
set ttimeoutlen=0
set keymap=russian-jcukenwin
set iminsert=0
set imsearch=0
set encoding=utf-8
set termencoding=utf-8
set updatetime=500
set noswapfile
set splitright
set splitbelow
set nocompatible
set tags=./tags;
set ignorecase
set hidden
set hlsearch
set incsearch
set cursorline
set pumheight=10
set fillchars+=vert:\
let mapleader=","
filetype off
filetype on plugin
filetype plugin indent on
" autocmd CompleteDone * pclose

" color
syntax enable
background set=dark
colorscheme solas

" abbreviations
abbr help help tab

" mappings
imap df <Esc>l
nnoremap 2o o<CR>
nnoremap 2O O<Esc>O
nnoremap tm :tabm +1<CR>
nnoremap tM :tabm -1<CR>
nnoremap K H
nnoremap J L
nnoremap H gT
nnoremap L gt
nnoremap F :CtrlP<CR>
nnoremap ff :CtrlP<CR>
nnoremap ft :CtrlPBufTag<CR>
nnoremap fb :CtrlPBuffer<CR>
nmap fs <Plug>(easymotion-s)
nmap fl <Plug>(easymotion-sl)
nnoremap fc :NERDTreeFind<CR>
nnoremap fp :CtrlSF
nnoremap <C-h> :noh<CR>
map <C-?> <plug>NERDCommenterComment
map <C-_> <plug>NERDCommenterToggle
nnoremap <C-d> :call PhpDoc()<CR>
nnoremap <C-m> :TagbarToggle<CR>
nnoremap <C-p> :NERDTreeToggle<CR>
nnoremap <C-g> :call SyntaxAttr()<CR>
inoremap <C-j> <C-n>
inoremap <C-k> <C-p>
cnoremap <C-j> <C-n>
cnoremap <C-k> <C-p>
autocmd FileType php noremap <C-u> :call PhpInsertUse()<CR>
nnoremap <F4> :tabe ~/.vimrc<CR>:tabm 0<CR>
nnoremap <F5> :w<CR>:so $MYVIMRC<CR>

" map <alt+n> to navigate through tabs
for c in range(1, 9)
exec "set <A-".c.">=\e".c
exec "map \e".c." <A-".c.">"

let n = c — '0'
exec "map <M-". n ."> ". n ."gt"
endfor

" nerdtree
let NERDTreeAutoDeleteBuffer = 1

" move
let g:move_key_modifier = 'C'

" youcompleteme
let g:ycm_server_python_interpreter='python'
let g:ycm_autoclose_preview_window_after_completion = 1
let g:ycm_key_list_select_completion = ['<Down>']

" emmet
let g:user_emmet_expandabbr_key = '<C-e>'

" airline
let g:airline_theme='solarized'
let g:airline_powerline_fonts = 1
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#tabline#tab_min_count = 0
let g:airline#extensions#tabline#formatter = 'unique_tail'
let g:airline#extensions#tabline#show_buffers = 0
let g:airline#extensions#tabline#fnamemod = 't'
let g:airline_section_warning = "
let g:airline_section_error = "
let g:airline#extensions#tabline#show_close_button = 0
let g:airline#extensions#tabline#left_alt_sep = "
let g:airline#extensions#tagbar#enabled = 0
let g:airline#extensions#tabline#show_tab_nr = 1
let g:airline#extensions#tabline#tab_nr_type = 1

" easymotion
let g:EasyMotion_smartcase = 1
let g:EasyMotion_do_shade = 0
hi link EasyMotionTarget Search
hi EasyMotionTarget2First ctermfg=202 ctermbg=None cterm=None
hi EasyMotionTarget2Second ctermfg=202 ctermbg=None cterm=None

" session
let g:session_autoload = 'yes'
let g:session_autosave = 'yes'
let g:session_autosave_periodic = 5
let g:session_autosave_silent = 1
let g:session_default_to_last = 1

" NERDCommenter
let g:NERDSpaceDelims = 1

" html
au BufNewFile,BufRead *.tpl set filetype=html syntax=php

" syntastic
let g:syntastic_always_populate_loc_list = 1
let g:syntastic_auto_loc_list = 1
let g:syntastic_check_on_open = 1
let g:syntastic_check_on_wq = 0

" tagbar
let g:tagbar_sort = 0
let g:tagbar_width = 35
let g:tagbar_iconchars = ['+', '-']
let g:tagbar_map_close = '<C-m>'
let g:tagbar_type_php = {
\'ctagstype': 'php',
\'kinds': [
\'i:interfaces',
\'c:classes',
\'d:constants',
\'f:functions'
\]
\}
let g:tagbar_type_javascript = {
\'ctagstype':'JavaScript',
\'kinds': [
\'f:functions',
\'c:classes',
\'m:methods',
\'p:properties'
\]
\}

" delimitmate
let delimitMate_expand_cr = 1
let delimitMate_expand_space = 1
au FileType vim,html let b:delimitMate_matchpairs = "(:),[:],{:},<:>>:<"

" NERDTree
" let g:NERDTreeDirArrowExpandable = '+'
" let g:NERDTreeDirArrowCollapsible = '-'

" ctrlp
let g:ctrlp_by_filename = 1
let g:ctrlp_working_path_mode = 'wr'
let g:ctrlp_map = "
let g:ctrlp_buftag_types = {
\'php': '--php-kinds=icdf'
\}

" ctrlsf
let g:ctrlsf_position = 'right'

" easytags
let g:easytags_file = './tags'
let g:easytags_auto_highlight = 0
let g:easytags_events = ['BufWritePost']
let g:easytags_async = 1vim як ideПередбачаючи деякі питання в стилі: «як у vim'e рефакторіть код також зручно, як і в моїй улюбленій ide?» мабуть, відповім одразу.

Якщо ви завзятий vim'ер, то вам можуть сподобатися наступні розширення для chrome:

vimiumРозширення додає комбінації для навігації по сторінці і зручного переміщення по посиланнях, докладніше.
wasaviДодає основні можливості vim'a для роботи з текстовими полями. Розширення можна активувати, натиснувши \<Insert\> <C-enter> або ж при фокусі текстового поля (настроюється).

PS: замість рідного символу коментаря viml (подвійні лапки), я вирішив використовувати "//", оскільки viml на хабре немає, і я не знаю, чи є мова зі схожим коментуванням коду.
PS2: деякі комбінації екрановані символом "\", щоб парсер не вважав їх за html-теги. Тег «pre» — блочний, вирішив, що краще вже так.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.