LINUX.ORG.RU

Делаем из Vim IDE

 ,

Делаем из Vim IDE

5

2

В стародавние времена когда деревья были большими, трава зеленее, а мороженное стоило по 10 копеек, на Земле жили динозавры, и эти динозавры программировали в Vim.

Предисловие

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

Ну что ж, вспомним былое и настроим с нуля Vim.

О Vim

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

Существует три основных режима:

  • нормальный;
  • редактирования;
  • командный.

Из нормального режима в режим редактирования (вставки) можно перейти, нажав i. Чтобы выйти из режима вставки и вернуться в нормальный режим, надо нажать <Esc>.

Меметичность этих режимов связана с тем, что на Stack Overflow самым популярным вопросом является «Как выйти из Vim?». Правильный ответ: для этого нужно нажать <Esc> (перейти в нормальный режим), а потом набрать :q!.

Когда вы вводите : в нормальном режиме, то переходите в командный. Из него можно выйти, нажав <Enter>, тем самым выполнив команду (если та была введена) или <Esc>. К сведению, командный режим позволяет выполнять команды терминала, например, :! ls.

Есть так же дополнительные режимы, которые я не буду рассматривать. Есть еще режимы выделения, замены…

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

В Vim не нужна мышка совсем, что повышает скорость набора. Но слепой 10-пальцевый метод для программиста — вещь сомнительная, и Vim ценят не за быстрый набор текста, а во многом за его расширяемость через плагины. Для Vim для написания конфигураций и плагинов используется Vimscript, что является недостатком, ибо нужно учить дополнительный язык с нестандартным синтаксисом. Для Neovim, например, плагины пишутся на Lua, но тут последний рассматриваться не будет.

Далее немного пройдемся по основам, чтобы те кто не видел этого Vim мог хотя бы выйти.

Команды

Команды навешиваются на клавиши или сочетания (мæппинги). Базовые легко запомнить типа u (ndo), p (aste), d (delete), но в семье не без уродца y (ank), который служит для копирования…

Перемещение и форматирование

Перемещение в нормальном режиме:

  • h, j, k, l — переместить курсор влево, вниз, вверх, вправо
  • gg — в начало файла
  • G — в конец файла
  • Ctrl-u — на полстраницы вверх
  • Ctrl-d — на полстраницы вниз
  • Ctrl-b — на страницу вверх
  • Ctrl-f — на страницу вниз

Как выделить текст?

  • Перейдите в нормальный режим: Нажмите Esc, если вы не в нормальном режиме.
  • Нажмите v: Включает визуальный режим для выделения текста.
  • Выделите текст стрелками: Используйте клавиши со стрелками (h, j, k, l) для выделения текста.
  • Нажмите d для удаления: Удаляет выделенный текст.
  • Нажмите y (от yank) чтобы копировать: Копирует выделенный текст.
  • Нажмите p — вставить: Вставляет скопированный или удаленный текст.

Как добавить отступы к блоку?

  • Выделите блок текста:
    • Перейдите в визуальный режим блоков, нажав Ctrl-v.
    • Используйте клавиши со стрелками (h, j, k, l) для выделения блока текста.
  • Измените отступы:
    • Нажмите > для увеличения отступа выделенного блока.
    • Нажмите < для уменьшения отступа выделенного блока.

Как копировать строку?

  • Копирование текущей строки:
    • Перейдите в нормальный режим, нажмите Esc, если вы не в нем.
    • Нажмите yy (yank line), чтобы скопировать текущую строку

Адок? — В общем-то, да, но попоболь сглаживает то, что Vim — это программируемый редактор, где на сочетания клавиш можно повесить как бы ввод других сочетаний, что мы и сделаем.

Переключение между буферами и окнами

Буферы в Vim — это аналог «вкладок».

Чтобы перейти к предыдущему буферу вводим :bp, :bn — к следующему.

Окна — это области экрана на которые он разбивается. Для перемещения используется Ctrl-W + h, j, k, l.

Как выйти из сохраниться

:w — сохранить файл. :wa — сохранить все. :q — выйти или закрыть vim/окно/буфер. :q! — выйти без подтвержения.

Можно использовать wq, wqa! и т.п.

Подготовка

Установите vim любым доступным способом, но лучше через пакетный менеджер:

# этот пакет собран без unnamed, а значит текст копированный в vim нельзя будет вставить в браузере без костылей с xclip или расширений
yay -S vim

# можно поставить vim с фронтендом в виде gtk, он содержит все нужные флаги, но придется доставить мегабайты gtk-шного мусора 
yay -S gvim

sudo apt install -y vim

Чтобы не засирать мусором хомяка, перенес конфиги туда, где они должны находиться.

Добавьте переменные окружения в .bashrc или .zshrc, либо другое удобное вам место (~/.zshenv и т.п.):

# Это костыль который позволяет обойти захардкоженное поведение vim и разместить конфиг в любом месте
export VIMINIT='source $MYVIMRC'
export VIMHOME=${XDG_CONFIG_HOME:-$HOME}/vim
export MYVIMRC=$VIMHOME/vimrc

Если вы до сих пор не установили переменные окружения xdg, то почитайте эту статью.

Чтобы переменные применились, выполните:

exec -l "$SHELL"

Создайте каталог:

mkdir -p $VIMHOME

Теперь нам нужно поставить менеджер плагинов. Без менеджера плагиноов обойтись можно, но тогда конфиг разрастется до каких-то портянок на сотню экранов. Самым популярным является vim-plug.

Установка на примере Arch:

yay -S vim-plug

В конфиге добавлена автоматическая установка vim-plug, но он не будет обновляться в отличии от пакета из репозитория.

Приступим к редактированию конфига:

kate $MYVIMRC

Минимальный конфиг

Минимальный конфиг с использование vim-plug будет выглядеть так:

" Устанавливаем переменные окружения, если они не заданы
if empty($VIMHOME)
  let $VIMHOME = expand('~/.vim')
endif

if empty($MYVIMRC)
  let $MYVIMRC = expand('%:p')
endif

" Проверяем, установлен ли vim-plug, и устанавливаем его при необходимости
" filereadable не умеет работать с путями, начинающимися с '~', поэтому
" используется странная конструкция empty(glob('...'))
if empty(glob($VIMHOME . '/autoload/plug.vim')) && !filereadable('/usr/share/vim/vimfiles/autoload/plug.vim')
  silent !curl -fLo $VIMHOME/autoload/plug.vim --create-dirs
      \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
endif

" Автоматически ставим отсутствующие плагины
autocmd VimEnter *
  \  if len(filter(values(g:plugs), '!isdirectory(v:val.dir)'))
  \|   PlugInstall --sync | source $MYVIMRC
  \| endif

" Инициализируем vim-plug
call plug#begin('$VIMHOME/plugged')

" Добавляем плагины
Plug 'tpope/vim-sensible'  " Настройки по умолчанию для Vim

" Тут добавляем свои плагины

" Завершаем инициализацию vim-plug
call plug#end()

" А тут пользовательские настройки и настройки плагинов

vim-plug плагины по умолчанию ищет на хостинге исходного кода github.com. Т.е. плагин tpope/vim-sensible будет скачен с https://github.com/tpope/vim-sensible.

Используйте :source $MYVIMRC либо :so %, если текущий редактируемый файл vimrc, для применения настроек.

Чем хорош этот конфиг:

  • Учитывается случай, если нужные переменные окружения не были установлены.
  • vim-plug ставится автоматически, если его нет в системе — что полезно для бубунтят.
  • Плагины ставятся автоматически после добавления их в конфиг.

Базовые настройки

Допишем в конец файла любые нужные настройки, но учитывайте, что в vim-sensible тоже задаются настройки:

" Включаем использование системного буфера
set clipboard=unnamedplus
" Копирование по Ctrl-C
vnoremap <C-c> "+y

" Отключаем visual bell
set noerrorbells
set novisualbell
set t_vb=

" Включаем номера строк
set number

" Настройки для табуляции и отступов
set tabstop=2
set shiftwidth=2
set expandtab

" Для Python можно использовать другие настройки
autocmd FileType python setlocal tabstop=4 shiftwidth=4

" Настройки для подсветки результатов поиска
set hlsearch

" Настройки для ограничения ширины строки до 80 символов
set textwidth=80
set colorcolumn=+1

" Отображение скрытых символов
set list
set listchars=tab:»·,lead:·,trail:·,nbsp:␣,extends:>,precedes:<

" Настройки для кодировки
set encoding=utf-8
set fileencoding=utf-8
set fileencodings=utf-8,cp1251,koi8-r,cp866

" Настройки для клавиши Leader
let mapleader = " "

" Выделение всего текста
nnoremap <C-a> ggVG
inoremap <C-a> <Esc>ggVG

" Настройки для навигации
nnoremap <Leader>1 1gt
nnoremap <Leader>2 2gt
nnoremap <Leader>3 3gt
nnoremap <Leader>4 4gt
nnoremap <Leader>5 5gt
nnoremap <Leader>6 6gt
nnoremap <Leader>7 7gt
nnoremap <Leader>8 8gt
nnoremap <Leader>9 9gt
nnoremap <Leader>0 :tablast<CR>
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l
nnoremap <Leader>z za

" Добавление/удаление отступов
" В нормальном режиме
nnoremap > >>
nnoremap < <<
" В визуальном режиме
vnoremap < <gv
vnoremap > >gv

" Настройки для переключения между буферами
nnoremap <Leader>n :bnext<CR>
nnoremap <Leader>p :bprevious<CR>

" Настройки для работы с окнами
nnoremap <Leader>s :split<CR>
nnoremap <Leader>v :vsplit<CR>

" Сохранение и закрытие
nnoremap <Leader>w :w<CR>
nnoremap <Leader>q :q<CR>
" Сохрание с sudo
noremap <Leader>W :w !sudo tee % > /dev/null

Справку по настройкам можно прочитать тут либо посмотреть ее прямо из Vim:

" Справка по всем настройкам
:help options

" Можно посмотреть конкретные
:help number

Чтобы узнать значение настройки, используйте:

set clipboard?

В данном конфиге в качестве leader был задан пробел. По умолчанию leader является \. leader используется в пользовательских сочетаниях клавиш (мэппингов).

" посмотреть значение
:echo mapleader

" задать альтернативное
let mapleader = ","

Чтобы посмотреть сочетания:

:map

Если хочется увидеть где заданы «мэппинги»:

:verbose map

Для конкретного сочетания клавиш:

:verbose map <C-v>

Для просмотра клавиш различных режимов используйте префиксы (:imap, :vmap и т.п.).

Добавим плагины

Список плагинов:

  1. scrooloose/nerdtree — Файловый менеджер для Vim, который позволяет просматривать структуру файлов и каталогов в виде дерева.
  2. junegunn/fzf.vim — Fuzzy finder для Vim, который позволяет быстро находить файлы, строки и другие элементы в проекте.
  3. tpope/vim-surround — Плагин для добавления, изменения и удаления скобок, кавычек и других символов вокруг текста.
  4. ervandew/supertab — Плагин для автодополнения с использованием клавиши <Tab>, упрощающий набор кода.
  5. tpope/vim-commentary — Плагин для быстрого комментирования и раскомментирования строк кода.
  6. airblade/vim-gitgutter — Плагин, который показывает изменения в Git в виде значков в сайдбаре.
  7. neoclide/coc.nvim — Плагин для автодополнения и языковой поддержки, основанный на LSP (Language Server Protocol).
  8. dense-analysis/ale — Плагин для линтинга и форматирования кода, поддерживающий множество языков программирования.
  9. puremourning/vimspector — Плагин для отладки кода, который поддерживает множество языков программирования и позволяет легко настраивать и использовать отладчик в Vim.
  10. ryanoasis/vim-devicons — Плагин, добавляющий иконки для файлов и папок в Vim, улучшая визуальное восприятие файловой структуры.
  11. Yggdroot/indentLine — Плагин для отделения отступов, делающий структуру кода более наглядной.
  12. luochen1990/rainbow — Плагин для разноцветной подсветки скобок, упрощающий понимание вложенности кода.
  13. vim-airline/vim-airline — Плагин для улучшения статус-бара Vim, добавляющий дополнительную информацию и улучшающий визуальный вид.
  14. vim-airline/vim-airline-themes — Коллекция тем для плагина vim-airline, позволяющая настроить внешний вид статус-бара.
  15. joshdick/onedark.vim — Тема для Vim, основанная на популярной теме One Dark для Visual Studio Code.

Для примера я добавлю настройки именно для Python, потому что я его использую. Как настроить ale, coc и viminspector для работы с другими языками нагуглите сами, на худой конец спросите у ChatGPT.

Установим зависимости:

# Fuzzy Search
# Если в вашем дистрибутиве нет такого пакета, он будет скачен
yay -S fzf

# Зависимости coc
yay -S nodejs

# Зависимости Python
yay -S ruff pyright python-debugpy

# бубунтята могут поставить пакеты так
pipx install ruff pyright debugpy

Для отображения значков и спецсимволов нужен какой-нибудь Nerd-шрифт:

yay -S ttf-jetbrains-mono-nerd

В настройках терминала сделайте его используемым.

А теперь добавим плагины:

Plug 'scrooloose/nerdtree' " Файловый менеджер
" Плагин может установить fzf, если того нет
"Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim' " Нечеткий поиск строк
Plug 'tpope/vim-surround' " Добавляет, изменяет, удаляет закрывающие скобки, кавычки и тд
Plug 'ervandew/supertab' " Автодополнение с использованием <Tab>
Plug 'tpope/vim-commentary' " Комментирование строк кода
Plug 'airblade/vim-gitgutter' " Показываем изменения в Git
Plug 'neoclide/coc.nvim', {'branch': 'release'} " Автодополнение и языковая поддержка
Plug 'dense-analysis/ale' " Линтинг и форматирование
Plug 'puremourning/vimspector' " Дебаггер
Plug 'ryanoasis/vim-devicons' " Иконки для файлов и папок
Plug 'Yggdroot/indentLine' " Визуальное отделение отступов
Plug 'luochen1990/rainbow' " Разноцветная подсветка скобок
Plug 'vim-airline/vim-airline' " Airline status bar
Plug 'vim-airline/vim-airline-themes' " Airline themes
Plug 'joshdick/onedark.vim' " One Dark theme

И настроим их:

" Настройки для NERDTree
nnoremap <C-n> :NERDTreeToggle<CR>
nnoremap <Leader>f :NERDTreeFind<CR>

" Настройки для vim-gitgutter
set updatetime=100

" Настройки для coc.nvim
let g:coc_global_extensions = ['coc-pyright']
set completeopt=menu,menuone,noselect
inoremap <silent><expr> <C-n> coc#pum#next(1)
inoremap <silent><expr> <C-p> coc#pum#prev(1)
inoremap <silent><expr> <CR> coc#pum#confirm()
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)
nmap <silent> K :call CocAction('doHover')<CR>
inoremap <silent><expr> <C-Space> coc#refresh()

" Make <CR> to accept selected completion item or notify coc.nvim to format
" <C-g>u breaks current undo, please make your own choice
inoremap <silent><expr> <CR> coc#pum#visible() ? coc#pum#confirm()
                              \: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"

" yay -S ruff pyright python-debugpy
" Настройки для ale
let g:ale_linters = {
\   'python': ['ruff'],
\}
let g:ale_fixers = {
\   'python': ['ruff'],
\}
let g:ale_fix_on_save = 1

" Настройки для vimspector
" https://github.com/puremourning/vimspector?tab=readme-ov-file#human-mode
let g:vimspector_enable_mappings = 'HUMAN'

" Настройки для vim-devicons
let g:webdevicons_enable = 1
let g:webdevicons_enable_nerdtree = 1
let g:webdevicons_enable_airline_tabline = 1
let g:webdevicons_enable_airline_statusline = 1

" Настройки для разноцветной подсветки отступов
let g:indentLine_enabled = 1
let g:indentLine_char = '│'

" Настройки для разноцветной подсветки скобок
let g:rainbow_active = 1

" Настройки для vim-airline
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#tabline#formatter = 'unique_tail'
let g:airline_powerline_fonts = 1
let g:airline_theme = 'onedark'  " Устанавливаем тему One Dark для vim-airline

" Настройки для темы One Dark
colorscheme onedark

" Убедитесь, что терминал поддерживает 256 цветов
set t_Co=256
" Настройки для NERDTree
nnoremap <C-n> :NERDTreeToggle<CR>

" Поиск по файлам с помощью fzf
nnoremap <Leader>f :Files<CR>

" Настройки для vim-gitgutter
set updatetime=100

" Настройки для coc.nvim
" yay -S nodejs
let g:coc_global_extensions = ['coc-pyright']
set completeopt=menu,menuone,noselect
inoremap <silent><expr> <C-n> coc#pum#next(1)
inoremap <silent><expr> <C-p> coc#pum#prev(1)
inoremap <silent><expr> <CR> coc#pum#confirm()
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)
nmap <silent> K :call CocAction('doHover')<CR>
inoremap <silent><expr> <C-Space> coc#refresh()

" Make <CR> to accept selected completion item or notify coc.nvim to format
" <C-g>u breaks current undo, please make your own choice
inoremap <silent><expr> <CR> coc#pum#visible() ? coc#pum#confirm()
                              \: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"

" yay -S ruff pyright python-debugpy
" Настройки для ale
let g:ale_linters = {
\   'python': ['ruff'],
\}
let g:ale_fixers = {
\   'python': ['ruff'],
\}
let g:ale_fix_on_save = 1

" Настройки для vimspector
" https://github.com/puremourning/vimspector?tab=readme-ov-file#human-mode
let g:vimspector_enable_mappings = 'HUMAN'

" Настройки для vim-devicons
let g:webdevicons_enable = 1
let g:webdevicons_enable_nerdtree = 1
let g:webdevicons_enable_airline_tabline = 1
let g:webdevicons_enable_airline_statusline = 1

" Настройки для разноцветной подсветки отступов
let g:indentLine_enabled = 1
let g:indentLine_char = '│'

" Настройки для разноцветной подсветки скобок
let g:rainbow_active = 1

" Настройки для vim-airline
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#tabline#formatter = 'unique_tail'
let g:airline_powerline_fonts = 1
let g:airline_theme = 'onedark'  " Устанавливаем тему One Dark для vim-airline

" Настройки для темы One Dark
colorscheme onedark

" Убедитесь, что терминал поддерживает 256 цветов
set t_Co=256
  • Установить плагины можно, выполнив :PlugInstall.
  • Для обновления используйте :PlugUpdate. Так же можно указать конкретный плагин для обновления.
  • :PlugClean позволяет удалить неиспользуемсые плагины.
  • :PlugStatus показывает плагины, которые можно обновить.

Настройка Coc

coc как и все хорошее требует Node.js. Он автоматически ставит расширения, которые указаны в конфигурации:

let g:coc_global_extensions = [
  \ 'coc-pyright',
  \ 'coc-json',
  \ 'coc-tsserver',
  \ 'coc-eslint',
  \ 'coc-prettier',
  \ ]

Выполните:

:CocConfig

Будет открыт файл coc-settings.json в $VIMHOME.

Например, можно сделать pyright менее строгим (но не нужно):

{
  "pyright.typeCheckingMode": "basic",
  "pyright.diagnosticSeverityOverrides": {
    "reportMissingTypeArgument": "none",
    "reportMissingParameterType": "none",
    "reportMissingReturnType": "none",
    "reportGeneralTypeIssues": "none"
  }
}

VimSpector

Чтобы запустить код, нужно создать конфиг .vimspector.json в корне проекта типа этого:

{
  "configurations": {
    "Launch": {
      "adapter": "debugpy",
      "configuration": {
        "name": "Python: Launch",
        "type": "python",
        "request": "launch",
        "program": "${workspaceFolder}/foo.py",
        "console": "integratedTerminal"
      }
    }
  }
}

Далее на строке, отладка которой требуется, нажимаем <F9> и ставим breakpoint, потом нажимаем <F5> для старта отладки, если клавишу нажать еще раз, то отладчик перейдет к следующему шагу, и <F3> можно использовать для ее завершения.

Многие, наверное, заметили, что конфиг что-то подозрительно напоминает… — Да, это подарок ненужноэлектронщикам от разработчиков VS Code (там в основе дебаггер от него). Посетите сайт проекта чтобы почитать про поддержку других языков.

>>> Конфиг полностью <<<

Заключение

Как видим, настройка Vim довольно таки сложна и представляет собой особый вид специальной олимпиады. Любители обмазаться vim шарят свои конфиги, делают скрины и показывают их друг другу. Насколько оправдано использование vim сегодня? — Оно на самом деле имеет мало смысла, но любителям тайлов зайдет, либо тем, кто постоянно работает из терминала. У vim есть и современные альтернативы типа kakoune или сборки как spacevim для тех, кто не желает возиться с настройками. Есть расширения для того же VS Code, которые позволяют ломать пальцы о сочетания. Для меня Vim примечателен как явление, и я им иногда пользуюсь, потому что на нем «удобно редактировать» конфиги на серверах в осутствии альтернатив кроме убогого nano, хотя и без этих настроек, которые из него делают что-то большее, чем необычный текстовый редактор для терминала.

Ссылки

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

★★

Проверено: hobbit ()
Последнее исправление: rtxtxtrx (всего исправлений: 18)

За статью спасибо. Самое полезное здесь - описание плагинов. Часть «Перемещение и форматирование» я бы убрал. Если человек не умеет работать в vim, то эта информация ему не поможет. Даже сделает еще хуже: он просто получит неудобный редактор. Главная фишка vim в том, что он позволяет легко делать то, что не умеют другие редакторы. Например, манипулировать блоками текста (такими как слово, то что в скобках или кавычках, до какого-то символа и т. п.) макросы, разные типы автодополнения, и др. Это вообще заслуживает отдельной статьи.

Kroz ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.