LINUX.ORG.RU

Делаем из Vim IDE

 , ,

Делаем из Vim IDE

24

5

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

Предисловие

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

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

О Vim

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

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

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

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

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

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

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

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

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

Основы использования

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

Существует лишь одна универсальная клавиша — <Esc>. Она выходит из любого режима и отменяет текущие действия. Для удобства выхода из режимов редактирования и вставки вызов этой клавиши вешают на <C-s> или <C-c>. Через <C-...> обозначают сочетания с клавишей Ctrl, <S-...> — Shift и <A-...> — Alt. Так же важен регистр буковок, например, q и Q — это разные команды.

Нормальный режим — это словно нейтральная передача для переключения скоростей. Это основной режим, в котором вы можете перемещаться по тексту, выполнять команды и переключаться между другими режимами. Вот команды, которые работают только в нормальном режиме:

КомандаОписание
iПереключиться в режим вставки перед курсором
IПереключиться в режим вставки в начале строки
aПереключиться в режим вставки после курсора
AПереключиться в режим вставки в конце строки
oПереключиться в режим вставки на новой строке ниже
OПереключиться в режим вставки на новой строке выше
vПереключиться в визуальный режим (посимвольный)
VПереключиться в визуальный режим (построчный)
<C-v>Переключиться в визуальный режим (поблочный)
:Переключиться в командный режим

Команды для навигации и редактирования для нормального режима:

КомандаОписание
hПереместить курсор влево
jПереместить курсор вниз
kПереместить курсор вверх
lПереместить курсор вправо
0Перейти к началу текущей строки
$Перейти к концу текущей строки
:<n>Перейти к определенной строке
ggПерейти к началу файла
GПерейти к концу файла
gxПерейти по ссылке
<C-u>Переместиться на полстраницы вверх
<C-d>Переместиться на полстраницы вниз
<C-b>Переместиться на страницу вверх
<C-f>Переместиться на страницу вниз
<C-o>Перейти к предыдущему положению курсора
<C-i>Перейти к следующему положению курсора после <C-o>
xУдалить символ под курсором
ddУдалить текущую строку
DУдалить оставшуюся строку после курсора
yyСкопировать текущую строку
pВставить скопированный текст после курсора
PВставить скопированный текст перед курсором
uОтменить последнее действие
<C-r>Повторить последнее отмененное действие
.Повторить последнюю команду
cwУдалить слово и перейти в режим вставки
ciwУдалить слово под курсором и перейти в режим вставки
c$Удалить текст от курсора до конца строки и перейти в режим вставки
c0Удалить текст от курсора до начала строки и перейти в режим вставки
:%s/old/new/gЗаменить все вхождения «old» на «new» во всем файле
:wСохранить файл
:qВыйти из Vim
:wqСохранить файл и выйти из Vim
:xСохранить файл и выйти из Vim [2]
:q!Выйти из Vim без сохранения

Так же, например, мы можем введя 3b переместиться на 3 слова назад, 5l — на 5 символов вправо, 10dd удалит 10 строк, включая текущую. Что такое есть знать нужно, но применяется это в основном для «программирования» редактора.

Команды режима вставки:

КомандаОписание
Ctrl+wУдалить слово перед курсором
Ctrl+uУдалить текст от курсора до начала строки
Ctrl+tСдвинуть текущую строку вправо
Ctrl+dСдвинуть текущую строку влево
Ctrl+oВременно перейти в нормальный режим для выполнения одной команды

Команды визуального режима:

КомандаОписание
dУдалить выделенный текст
yСкопировать выделенный текст
>Сдвинуть выделенный текст вправо
<Сдвинуть выделенный текст влево
oПереместить курсор в противоположный угол выделения
OПереместить курсор в противоположный угол выделения (для блочного режима)
~Изменить регистр выделенного текста
guСделать выделенный текст строчными буквами
gUСделать выделенный текст заглавными буквами
JОбъединить выделенные строки в одну
gqОтформатировать выделенный текст

Пример 1: жмем V (режим выделения строк), cтрелками выделяем текст, нажимаем и жмем d чтобы удалить блок кода.

Пример 2: для добавления отступов, жмем v, перемещаем курсор до нужно места и жмем > для увеличения отступов или < — для уменьшения.

Поиск по тексту осуществляется /. Эта команда не работает в режиме редактирования. Чтобы перейти к следующему результату используйте n, предыдущему N.

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

Про интерфейс и буферы

Буферы в Vim — это область памяти, в которой хранятся данные. Окна служат для отображения буферов, но буферы никак не привязаны к окну. Когда мы что-то открываем через :e, то содержимое текущего окна заменяется на содержимое файла, но сам буфер остается в памяти. Чтобы просматривать буферы, используйте команды :ls(list), :bp(previous) и bn(next).

Вкладки содержат окна. По умолчанию у нас одна вкладка и одно окно в нем, но окон во вкладке может быть более одного. Если закрыть последнее окно, то закроется и вкладка вместе с vim (что логично). Для перемещения используется Ctrl-W + h, j, k, l. Для разбиения окна используются команды :split (по горизонтали) и :vsplit (по вертикали). Вкладки можно открывать (:tabnew), закрывать (:tabclose) и перемещаться по ним (:tabprevious, :tabnext) и тд. Вместо :e можно использовать :tabedit.

Внизу располагается строка (ряд) статуса. В нем отображается режим и прочая полезная информация. Он же служит полем для ввода команд. Историю введенных команд можно увидеть, нажав q:. Чтобы переместиться в конец командной строки, используем Ctrl-e, в начало — Ctrl-b.

Подготовка

Установите 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/.config}/vim
export MYVIMRC=$VIMHOME/vimrc

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

Так же можете установить переменную EDITOR, чтобы vim вызывался для редактирования тех же коммитов:

EDITOR=vim
VISUAL=$EDITOR
export EDITOR VISUAL

Еще можно добавить алиас для редактирования конфига:

alias vimrc='vim $MYVIMRC'

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

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

" Проверяем, есть ли уже путь в runtimepath
if index(split(&runtimepath, ','), expand('$VIMHOME')) == -1
  " Если пути нет, добавляем его
  set runtimepath+=$VIMHOME
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, для применения настроек.

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

  • Учитывается случай, если нужные переменные окружения не были установлены.
  • $VIMHOME добавляется в runtimepath. Без этого, например, не будут работать темы из ~/.config/vim.
  • vim-plug ставится автоматически, если его нет в системе — что полезно для бубунтят.
  • Плагины ставятся автоматически после добавления их в конфиг.

Как пользоваться?

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

Все установленные плагины можно снести так:

rm -rf $VIMHOME/plugged

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

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

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

" Настройки ввода

" В coc.nvim прокрутка с помощью клавиш C-f и C-b не работает в vim
set mouse=a

" Включаем использование системного буфера
set clipboard=unnamedplus

" Задержка в мс для сочетаний клавиш
set timeoutlen=500


" Работа с текстом

" Табуляция и отступы
set tabstop=2
set shiftwidth=2
set expandtab

" Python использует 4 пробела для отступов
autocmd FileType python setlocal tabstop=4 shiftwidth=4

" Кодировка текста
set encoding=utf-8
set fileencoding=utf-8
set fileencodings=utf-8,cp1251,koi8-r,cp866

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

" Перемещение по тексту
" Когда достигаем границ строки, то перемещаемся на предыдующую/следующую
set whichwrap+=h,l,<,>,[,]

" Визуальные настройки

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

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

" Ширина строки и красная линия
set textwidth=80
set cc=+1

" Если мешает отображение режима в поле для команд
set noshowmode

" Настройки автодополнения
set completeopt=menu,menuone,noselect

" Разделение экрана
set splitbelow " разбивать вниз
set splitright " разбивать вправо

" Задержка CursorHold
set updatetime=100

" Настройки поведения
" Отключаем visual bell
set noerrorbells
set novisualbell
set t_vb=

" Игнорировать 'No write since last change' (буфер не сохранен)
set hidden

" Отключить создание бекапов, своп-файлов и файлов отмены
set nobackup noundofile noswapfile

" Эти комментарии потенциально опасны
set nomodeline

" Включаем автоматическое обновление буфера
set autoread

" Обновляем буфер при изменении файла внешними инструментами
autocmd FocusGained,BufEnter * checktime

Сочетания клавиш:

" Переход в нормальный режим
inoremap <C-s> <Esc>
vnoremap <C-s> <ESC>

" Копирование в системный буфер
vnoremap <C-c> "+y

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

" Использование h, j, k, l для перемещения с зажатым Ctrl в режиме редактирования
inoremap <C-h> <Left>
inoremap <C-j> <Down>
inoremap <C-k> <Up>
inoremap <C-l> <Right>

" Переместиться в начало строки
inoremap <C-0> <Home>
" Переместиться в конец строки
inoremap <C-$> <End>
" Переместиться к первому непробельному символу
inoremap <C-^> <Home>

" Клавиши leader и альтернативная основной
let g:mapleader = "\<Space>"
let g:maplocalleader = ','

" Очистить результаты поиска
nnoremap <leader>h :noh<CR>

" Переключение между вкладками
nnoremap <leader>t :tabnext<CR>
nnoremap <leader>T :tabprevious<CR>

" Список вкладок
nnoremap <leader>tl :tabs<CR>

nnoremap <leader>tn :tabnew<CR>
nnoremap <leader>tc :tabclose<CR>
nnoremap <leader>to :tabonly<CR>
nnoremap <leader>tm :tabmove<CR>

" Редактировать файл в новой вкладке
nnoremap <leader>te :tabedit |

" Выбор вкладки
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 <leader>s :split<CR>
nnoremap <leader>v :vsplit<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>= <C-w>=

" Переключения между буферами
nnoremap <leader>b :bnext<CR>
nnoremap <leader>B :bprevious<CR>
nnoremap <leader>l :ls<CR>
nnoremap <leader>d :bd<CR>

" Скрыть/раскрыть блок кода
nnoremap <leader>z za

" Добавление и удаление отступов
nnoremap > >>
nnoremap < <<
vnoremap < <gv
vnoremap > >gv

" Сохранение и закрытие
nnoremap <leader>w :w<CR>
nnoremap <leader>q :q<CR>

" Сохранить файл с sudo
" https://stackoverflow.com/questions/2600783/how-does-the-vim-write-with-sudo-trick-work
cmap w!! w !sudo tee > /dev/null %

" Редактирование конфига
nnoremap <leader>ev :tabedit $MYVIMRC<CR>

" Применить конфиг
nnoremap <leader>sv :so $MYVIMRC<CR>

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

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

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

В help встречаются имена файлов со справкой, которые можно просматривать. Переместите курсор на имя файла, введите :help и нажмите <C-r>, <C-w>, так можно вставить имя файла под курсором и посмотреть справку.

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

set clipboard?

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

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

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

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

:map

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

:verbose map

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

:verbose map <C-v>

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

В командах *map комментарии обрабатывается несколько иначе:

let answer = 42  " Это комментарий

inoremap <C-h> <Left>  " Это часть команды, а не комментарий!

В последнем случае при нажатии на Ctrl-h в режиме редактирования будет вставлен текст. Комментарии справа от *map лучше не использовать. Если очень нужно, то можно использовать конструкции типа nnoremap ...| " Описание.

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

Используемые плагины:

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

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

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

Plug 'scrooloose/nerdtree' " Файловый менеджер
" Плагин может установить fzf, если того нет
"Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim' " Нечеткий поиск строк
Plug 'jiangmiao/auto-pairs' " Автоматическое закрытие скобок и кавычек
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 'nathanaelkane/vim-indent-guides' " Визуальное отделение отступов
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
Plug 'editorconfig/editorconfig-vim' # Editor Config Support

Настройка плагинов

Для начала установим зависимости:

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

# Зависимости coc, который ставит свои расширения через npm
yay -S nodejs

# Зависимости Python
yay -S ruff pyright python-{black,isort,debugpy}

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

# Если пишите на Go, то поставьте gopls и тд

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

yay -S ttf-jetbrains-mono-nerd

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

Дописываем в конфиг эти настройки:

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

" Настройка fzf.vim
" yay -S fzf ripgrep
let g:fzf_layout = { 'window': { 'width': 0.8, 'height': 0.6 } }

nnoremap <leader>f :Rg<CR> " Поиск файлов по содержимому
nnoremap <leader>ff :Files<CR> " Поиск файлов
nnoremap <leader>fl :Lines<CR> " Поиск строк в файлах
nnoremap <leader>fb :Buffers<CR> " Поиск буферов


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

" Функция для переключения vim-gutter
function! ToggleGitGutter()
  if exists('g:gitgutter_enabled') && g:gitgutter_enabled
    GitGutterDisable
  else
    GitGutterEnable
  endif
endfunction

" Назначение сочетания клавиш для переключения vim-gutter
nnoremap <leader>gg :call ToggleGitGutter()<CR>
nmap ]h <Plug>(GitGutterNextHunk)
nmap [h <Plug>(GitGutterPrevHunk)


" Настройки для 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:indent_guides_enable_on_vim_startup = 1

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

" Настройки для vim-airline
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#tabline#buffer_nr_show = 1
let g:airline#extensions#tabline#formatter = 'unique_tail'
let g:airline_powerline_fonts = 1
let g:airline_theme = 'onedark'

" Настройки для темы
set termguicolors
set background=dark
color onedark

Учтем что некоторые языки используют 4 отступа вместо 2:

autocmd FileType python setlocal tabstop=4 shiftwidth=4

Coc

coc — это сервер, написанный на Node.js с использованием TypeScript, который необходим для автодополнения кода. Он работает через расширения и сам их ставит при необходимости через npm. Vimscript в этом плагине нужен лишь как запускалка ноды и выполнения запросов.

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

" Список расширений
let g:coc_global_extensions = [
    \ 'coc-pyright',
    \ 'coc-tsserver',
    \ 'coc-json',
    \ 'coc-html',
    \ 'coc-css',
    \ 'coc-go'
    \ ]

" Настройки автодополнения, необходимые для плагина
set completeopt=menu,menuone,noselect

" Включение подсказок при наведении
let g:coc_enable_hover = 1

" Подтверждение выбора в автодополнении
inoremap <silent><expr> <CR> coc#pum#visible() ? coc#pum#confirm()
                              \: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"

" Навигация по списку автодополнения
inoremap <silent><expr> <C-n> coc#pum#next(1)
inoremap <silent><expr> <C-p> coc#pum#prev(1)

" Вызов всплывающей справки
nmap <silent> K :call CocAction('doHover')<CR>

" История изменений
nmap <silent> cc <Plug>(coc-codelens-action)

" Форматирование
nmap <silent> cf <Plug>(coc-format)

" Переименование
nmap <silent> cr <Plug>(coc-rename)

" Переходы по коду
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> <leader>gd :call CocAction('jumpDefinition', 'split')<CR>
nmap <silent> <leader>gy :call CocAction('jumpTypeDefinition', 'split')<CR>
nmap <silent> <leader>gi :call CocAction('jumpImplementation', 'split')<CR>
nmap <silent> <leader>gr :call CocAction('jumpReferences', 'split')<CR>

Если в нормальном режиме навести курсор, например, на функцию и нажать на K (Shift + k), то будет показана ее сигнатура. Если набрать <Leader>gd, то экран будет разбит на две части, и в новой части отобразится объявление функции. Можете добавить еще это в конфиг, если не устраивает как происходит разбиение экрана:

set splitbelow " Разбиение экрана вниз по умолчанию
set splitright " Разбиение экрана вправо по умолчанию

Сам coc так же настраивается через coc-settings.json который лежит в каталоге с настройками vim. Его можно открыть, выполнив:

:CocConfig

Например, можно в co-pyright отключить надоедливую подстановку инлайновых тайп-хинтов:

{
  "pyright.inlayHints.functionReturnTypes": false,
  "pyright.inlayHints.variableTypes": false,
  "pyright.inlayHints.parameterTypes": false
}

Расширения coc хранятся в ~/.config/coc. Стоит отметить, что плагин использует расширения… от vscode.

ALE

Asynchronous Lint Engine выполняет проверку синтаксиса и форматирует код.

let g:ale_linters = {
\   'python': ['ruff'],
\   'javascript': ['eslint', 'tsserver'],
\   'json': ['jsonlint'],
\   'html': ['htmlhint'],
\   'css': ['stylelint'],
\   'go': ['gopls', 'golangci-lint'],
\}

" у меня ruff не форматирует файл, поэтому укажем что-то другое
let g:ale_fixers = {
\   'python': ['isort', 'black'],
\   'javascript': ['eslint', 'prettier'],
\   'json': ['prettier'],
\   'html': ['prettier'],
\   'css': ['stylelint', 'prettier'],
\   'go': ['gofmt', 'goimports'],
\}

" Автоматическое исправление при сохранении
let g:ale_fix_on_save = 1

" ale не читает никакие конфиги, их нужно задавать через аргументы, писать
" функции чтобы те искали их и подставляли как аргумент
let g:ale_python_black_options = '--line-length 80'

let g:ale_go_golangci_lint_options = ''
let g:ale_go_golangci_lint_package = 1

Чтобы посмотреть отладочную информацию выполните:

:ALEInfo

Прочтите справку:

:help ale_linters
:help ale_fixers

VimSpector

Его настройки описаны тут.

Нам нужно указать минимум одну, потому как по умолчанию используются сочетания для рептилоидов:

let g:vimspector_enable_mappings = 'HUMAN'

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

{
  "configurations": {
    "Run Current File": {
      "adapter": "debugpy",
      "configuration": {
        "type": "python",
        "request": "launch",
        "program": "${file}",
        "console": "integratedTerminal"
      },
      "breakpoints": {
        "exception": {
          "raised": "",
          "uncaught": "Y",
          "userUnhandled": "N"
        }
      }
    }
  }
}

Обратите внимание на свойство breakpoints.exception. vimspector если эти значения не заданы спрашивает uncaught: ...Break on Uncaught Exceptions и предлагает ввести N или Y либо использовать значение по умолчанию. Чтобы постоянно при запуске дебаггера не отвечать на одни и те же вопросы, ответы на них можно прописать. uncaught — имя настройки (они все до :), которой задаем значение. Пустая строка тут — это значение, которое и предлагается по умолчанию, т.е. все три можно оставить пустыми.

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

Прочитать про настройку можно тут.

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

EditorConfig

С помощью конфигурационного файла .editorconfig, расположенного в корне проекта (с root = true), можно задать правила форматирования кода, не прибегая к редактированию конфига vim, а так же избежать использования потенциально опасного modeline (комментарии типа # vim: ts=4 sw=4 et). Это крайне необходимо для совместной работы.

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

let g:EditorConfig_core_mode = 'external_command'

" Указывать нужно полный путь, который можно получить так
let g:EditorConfig_exec_path = exepath('editorconfig')

Для глобальных настроек используйте ~/.editorconfig или ~/.config/.editorconfig. Это зависит от настроек и используемой утилиты, некоторые из них поддерживают переменную $EDITORCONFIG в отличии от нативной реализации.

Пример универсального конфига:

# EditorConfig is awesome: https://EditorConfig.org

# Применять эти настройки ко всем вложенным файлам
root = true

# Стиль применяемый ко всем файлам
[*]
end_of_line = lf  # Стиль переноса строк
insert_final_newline = true  # Финальный перенос
charset = utf-8  # Кодировка по умолчанию
trim_trailing_whitespace = true  # Удаление пробелов в конце строк
indent_style = space  # Стиль отступов
indent_size = 2  # Размер отступа по умолчанию
max_line_length = 80  # Максимальная длина строки

# Для питона
[*.py]
indent_size = 4

# Для Go
[*.go]
# indent_size игнорируется, если indent_style установлен в tab
indent_style = tab

Это как минимум решит проблемы с пробелами в конце строк и отстутствием завершающего переноса строки в файле. В этом конфиге так же описаны все возможные настройки EditorConfig.

Тестирование сборки

Теперь протестируем нашу сборку.

Vim позволяет открывать как файлы так и каталоги:

# Открыть текущий каталог
vim .

Будет выведена ошибка:

...
E185: Cannot find color scheme 'onedark'
Press ENTER or type command to continue

Жмем ENTER. Начнется установка плагинов и расширений для coc. Ждем завершения установки. С помощью :q можно позакрывать окна с сообщениями об установке.

У вас в итоге должно отобразиться содержимое каталога. Выберите любой файл, и он откроется на весь экран. Чтобы отобразить дерево файлов сбоку, нажмите Ctrl-n. Если нажать это сочетание ещё раз, оно скроется. Можно попробовать создать файл, потренироваться в редактировании.

Можно ли это назвать IDE?

— Да. Есть не очень умные люди, которые IDE считают только то, что в названии имеет оное слово. Вопросы терминологии всегда являются предметом ожесточенных срачей с переходом на личночти и угрозами вычислить по ip. Камнем претконевения тут является слово интегрированная, т.е. нужна среда разработки, которая может заставить совместно работать различные сторонние средства разработки вместе на благо партии и народа. Но данное определение не является полным.

Текстовый редактор от блокнота отличают наличие автодополнения и подсветки синтаксиса. IDE тоже умеет в подсветку синтаксиса и автодополнение. Среду разработки от текстового редактора отличает следующее:

  • Автодополнение осуществляется с использованием синтаксического анализа, а не просто всех встречающихся слов в тексте.
  • Исходный код проверяется на синтаксические ошибки, а так же осуществляется проверка стилистики и возможных проблем в коде (линтинг).
  • Есть форматирование кода. Правила форматирования должны как-то задаваться, чтобы код могла разрабатывать команда.
  • Отладка кода. Без нее в принципе невозможна разработка чего-либо серьезного (у фанатов Столярова другое мнение).
  • Поддержка VCS (систему контроля версий) таких как Git (другие сейчас не применяются).
  • И все это должно быть интегрировано в IDE, те запускаться не через :!, а самим редактором как раз таки через плагины/расширения.

Vim с помощью используемых плагинов вполне себе элегантно превращается в IDE.

Что можно еще добавить/изменить?

Многое в конфиге можно и нужно улучшить!

Можно добавить какие-нибудь попсовые плагины типа этого:

Plug 'terryma/vim-multiple-cursors'

Так же можно поставить вместо fzf.vim (некоторых не устраивает, что тот игнорирует тему):

Plug 'ctrlpvim/ctrlp.vim'

С помощью liuchengxu/vim-which-key можно подсматривать сочетания клавиш:

" При нажатии на <leader> подсказывает доступные сочетания с пробелом
nnoremap <silent> <leader> :WhichKey '<Space>'<CR>

" Так выведет все сочетания
nnoremap <silent> <leader>? :WhichKey ''<CR>

" Уменьшаем задержку для сочетаний
set timeoutlen=500

Альтернативой coc является vim-lsp. Он так же как и первый работает через языковой протокол LSP. Его настройка несколько сложнее: coc ставит расширения автоматически с языковыми серверами, которые у них указаны в зависимостях.

С использованием vim-lsp языковые сервера нужно ставить самостоятельно:

npm install -g pyright

И пример настройки:

call plug#begin('$VIMHOME/plugged')

" ...
Plug 'prabirshrestha/vim-lsp'
" ...

call plug#end()

if executable('pyright-langserver')
    au User lsp_setup call lsp#register_server({
        \ 'name': 'pyright',
        \ 'cmd': {server_info->['pyright-langserver', '--stdio']},
        \ 'whitelist': ['python'],
        \ })
endif

" Настройка автодополнения
set completeopt=menu,menuone,noselect

" Настройка сочетаний клавиш для LSP
nnoremap <silent> gd :LspDefinition<CR>
nnoremap <silent> gr :LspReferences<CR>
nnoremap <silent> gi :LspImplementation<CR>
nnoremap <silent> gt :LspTypeDefinition<CR>
nnoremap <silent> <leader>rn :LspRename<CR>
nnoremap <silent> K :LspHover<CR>
nnoremap <silent> <leader>ca :LspCodeAction<CR>
nnoremap <silent> <leader>fmt :LspDocumentFormat<CR>

Ну и можно интегрировать vim с ChatGPT через madox2/vim-ai (в теории плагин может работать с каким угодно провайдером через OpenAI API) чтобы вместо выдумывания каверзных вопросов Гуголу с хождением по ссылкам, получать куски кода сразу прямиком с SO.

Дополнения

Создание своих тем для Vim

Если вам нравится какая-то тема, но ее нет на Vim Awesome либо она как тамошняя Solarized Dark выглядит как УГ, то вы можете создать свою. Есть, конечно, специализорованные сервисы, но можно об одолжении попросить какую генеративную нейросеточку.

Подготовка:

# Создадим каталог для тем
mpkdir -p $VIMHOME/colors

Теперь откроем $VIMHOME/colors/solarzed_dark.vim и вставим:

" Solarized Dark Truecolor Theme for Vim
" Based on the Solarized palette
" https://ethanschoonover.com/solarized/

set background=dark
hi clear

if exists("syntax_on")
  syntax reset
endif

let g:colors_name = "solarized_dark"

" Solarized base colors
let s:base03  = "#002b36"
let s:base02  = "#073642"
let s:base01  = "#586e75"
let s:base00  = "#657b83"
let s:base0   = "#839496"
let s:base1   = "#93a1a1"
let s:base2   = "#eee8d5"
let s:base3   = "#fdf6e3"
let s:yellow  = "#b58900"
let s:orange  = "#cb4b16"
let s:red     = "#dc322f"
let s:magenta = "#d33682"
let s:violet  = "#6c71c4"
let s:blue    = "#268bd2"
let s:cyan    = "#2aa198"
let s:green   = "#859900"

" Normal text and background
exe "hi Normal guifg=".s:base0." guibg=".s:base03

" Comments
exe "hi Comment guifg=".s:base01." gui=italic"

" Constants
exe "hi Constant guifg=".s:cyan

" Identifiers
exe "hi Identifier guifg=".s:blue

" Statements (keywords like 'if', 'for', etc.)
exe "hi Statement guifg=".s:green

" PreProc (macros, includes)
exe "hi PreProc guifg=".s:orange

" Type (int, char, etc.)
exe "hi Type guifg=".s:yellow

" Special (special characters, like function names)
exe "hi Special guifg=".s:red

" Underlined text
exe "hi Underlined guifg=".s:violet." gui=underline"

" Error messages
exe "hi Error guifg=".s:red." guibg=".s:base03

" Visual mode selection
exe "hi Visual guibg=".s:base02

" Line numbers
exe "hi LineNr guifg=".s:base01

" Cursor line number
exe "hi CursorLineNr guifg=".s:yellow

" Search highlighting
exe "hi Search guifg=".s:base03." guibg=".s:yellow

" MatchParen (matching parenthesis)
exe "hi MatchParen guifg=".s:base03." guibg=".s:blue

" Status line
exe "hi StatusLine guifg=".s:base0." guibg=".s:base02
exe "hi StatusLineNC guifg=".s:base01." guibg=".s:base02

" Popup menu for autocomplete
exe "hi Pmenu guifg=".s:base0." guibg=".s:base02
exe "hi PmenuSel guifg=".s:base03." guibg=".s:blue

" Tabs
exe "hi TabLine guifg=".s:base0." guibg=".s:base02
exe "hi TabLineSel guifg=".s:base03." guibg=".s:blue
exe "hi TabLineFill guibg=".s:base02

Тут представлены классические цвета.

Остается только в конфиг прописать тему:

" Настройки для темы
set background=dark

color solarized_dark

" Мне не нравится красные вертикальные границы
hi ColorColumn ctermbg=lightgrey guibg=lightgrey

" Сделаем чтобы границы были на 80, 100 и 110 символов
set cc+=+21,+31

Alacritty + Zellij

Vim удобнее всего использовать в связке Alacritty и Zellij.

Alacritty — это терминал, написанный на Rust, но не стоит его недооценивать из-за этого. Он имеет небольшой размер ~9 MiB, поддерживает аппаратное ускорение через GPU и поддерживает юникод. Однако, у него есть некоторые ограничения: отсутствие поддержки табов, вкладок, вывода изображений и лигатур (которые в htop только мешают).

Установка Alacritty:

yay -S alacritty

Zellij — это современный терминальный мультиплексор, который позволяет управлять несколькими терминальными сессиями в одном окне. Помимо управления сессиями, он дает возможность управлять вкладками и панелями. Для Linux уже есть другие мультиплексоры, такие как GNU Screen и Tmux. Первый — анохронизм в наши дни, а Tmux, хоть и «популярный», имеет ужасный интерфейс. Можно сказать, что его нет, и вам помимо заучивания кучи сочетаний для Vim нужно будет заучить еще и его сочетания. В Zellij почти все доступные режимы и сочетания для них отображаются на экране.

Установка Zellij:

yay -S zellij

Для начала работы с Zellij, создадим конфигурационный файл, который будет содержать настройки по умолчанию.

mkdir -p ~/.config/zellij
zellij setup --dump-config > ~/.config/zellij/config.kdl

Откроем созданный конфигурационный файл и установим режим по умолчанию на locked:

vim ~/.config/zellij/config.kdl
default_mode "locked"

Использование этого режима при старте терминала позвляет избежать конфликта сочетаний клавиш.

Чтобы Alacritty запускал Zellij при старте, добавим соответствующую настройку в конфигурационный файл Alacritty.

~/.config/alacritty/alacritty.toml:

[terminal.shell]
program = "zellij"
args = [ ]

Как с ним работать?

  • Запустите терминал.
  • Нажмите Ctrl-g для выхода из режима блокировки интерфейса.
  • Смотрите подсказки внизу: с Alt можно создавать панели, перемещаться по ним и изменять их размер, сворачивать; с клавишей Ctrl доступно переключение в различные режимы. Например, если нажать Ctrl-p, а потом x, то панель будет закрыта. Esc — это отмена режима.
  • В подсказках указаны не все доступные сочетания, например, такое полезное как Ctrl-p (войти в режим изменения панелей), d — для разбиения панелей по горизонтали. Все доступные сочетания можно посмотреть в сгенерированном в конфиге.
  • Если зажать Shift, то ссылки станут кликабельными.
  • Заблокируйте интерфейс с помощью Ctrl-g.

Полный конфиг Alacritty:

[keyboard]
bindings = [
  {key='q', mods='Control|Shift', action='Quit'},
  {key='n', mods='Control|Shift', action='CreateNewWindow'},
]

[font]
size = 12

  [font.normal]
  family = "JetBrainsMono Nerd Font Mono"
  style = "Regular"

  [font.bold]
  family = "JetBrainsMono Nerd Font Mono"
  style = "Bold"

  [font.italic]
  family = "JetBrainsMono Nerd Font Mono"
  style = "Italic"

  [font.bold_italic]
  family = "JetBrainsMono Nerd Font Mono"
  style = "Bold Italic"

[window]
opacity = 0.95
blur = true

  [window.padding]
  x = 3
  y = 3

[colors]
transparent_background_colors = true

  [colors.primary]
  background = "0x282c34"
  foreground = "0xabb2bf"

  [colors.cursor]
  text = "0x282c34"
  cursor = "0xabb2bf"

  [colors.normal]
  black = "0x282c34"
  red = "0xe06c75"
  green = "0x98c379"
  yellow = "0xd19a66"
  blue = "0x61afef"
  magenta = "0xc678dd"
  cyan = "0x56b6c2"
  white = "0xabb2bf"

  [colors.bright]
  black = "0x5c6370"
  red = "0xe06c75"
  green = "0x98c379"
  yellow = "0xd19a66"
  blue = "0x61afef"
  magenta = "0xc678dd"
  cyan = "0x56b6c2"
  white = "0xffffff"

  [colors.selection]
  text = "0x282c34"
  background = "0xabb2bf"

[cursor]
blink_interval = 800
blink_timeout = 0

  [cursor.style]
  shape = "Beam"
  blinking = "Always"

[scrolling]
history = 10000

# По умолчанию запускаем мультиплексер
[terminal.shell]
program = "zellij"
args = [ ]

В качестве менее популярной альтернативы Alacritty (в качестве минималистичного эмулятора терминала) можно попробовать Contour, написанный на C++ и поддерживающий лигатуры.

Установка и настройка wezterm — современного терминала с поддержкой лигатур

Если в Vim не хватает лигатур, то это попроавимо!

WezTerm — это современный, быстрый эмулятор терминала с поддержкой табов (в отличии от того же alacritty) и лигатур (их поддерживает считанное количество эмуляторов). Конкуренцию ему может составить разве, что Kitty, но он проигрывает по ряду особенностей, которые мне тупо лень перечислять.

Установка:

yay -S wezterm

Конфиги для wezterm пишутся на Lua, что значительно упрощает его настроку.

Пример конфига:

~/.config/wezterm/wezterm.lua

-- Настройки шрифта
local wezterm = require 'wezterm'

wezterm.on('update-right-status', function(window, pane)
  local date = wezterm.strftime('%Y-%m-%d %H:%M:%S')
  window:set_right_status(wezterm.format({
    {Text = ' ' .. date .. ' '},
  }))
end)

return {
  -- Шрифт
  font = wezterm.font('JetBrainsMono Nerd Font Mono', {weight = 'Regular'}),
  font_size = 12.0,

  -- Цветовая схема
  color_scheme = 'Dracula',

  -- Размер окна
  window_padding = {
    left = 10,
    right = 10,
    top = 10,
    bottom = 10,
  },

  -- Поведение терминала
  scrollback_lines = 100000,
  enable_scroll_bar = true,

  -- Настройки клавиатуры
  keys = {
    {key = 'v', mods = 'CTRL|SHIFT', action = wezterm.action{PasteFrom = 'Clipboard'}},
    {key = 'c', mods = 'CTRL|SHIFT', action = wezterm.action{CopyTo = 'Clipboard'}},
    {key = 'q', mods = 'CTRL', action = 'QuitApplication'},
    {key = '=', mods = 'CTRL', action = wezterm.action.IncreaseFontSize},
    {key = '-', mods = 'CTRL', action = wezterm.action.DecreaseFontSize},
  },

  -- Поддержка лигатур
  enable_kitty_graphics = true,
  enable_wayland = true,

  -- Другие настройки
  default_cursor_style = 'BlinkingBar',
  cursor_blink_rate = 800,
  cursor_blink_ease_in = 'Constant',
  cursor_blink_ease_out = 'Constant',

  -- Настройки окна
  window_background_opacity = 0.95,
  text_background_opacity = 1.0,
  window_close_confirmation = 'NeverPrompt',
}

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

Заключение

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

Насколько оправдано использование vim сегодня? — тут свой вывод может сделать каждый. У него есть и современные альтернативы типа kakoune или сборки как spacevim для тех, кто не желает возиться с настройками. Альтернативы хоть и имеют сторонников, но те малочисленны. Сборки же я не советую использовать, так как, не имея опыта в настройке редактора, вы не сможете начать программировать как шестирукий Шива — верховное божество вимеров, даже с ними. Кстати, одна такая с плагином YouCompleteMe когда-то давно у меня выжрала гигабайт при старте, что не меньше чем подставь название любой IDE из коробки. Так же существуют расширения для того же VS Code, которые позволяют ломать пальцы о сочетания клавиш, но зачем они когда можно просто настроить vim, написав каких-то 500 строк кода на марсианском языке?

Кому зайдет Vim:

  • фанатам тайлов;
  • людям, которые много работают из терминала;
  • бекенд-разработчикам;
  • обладателям слабых компьютеров/ноутбуков, где VS Code и упаси, г-де, PyCharm безбожно тормозят.

Что радует:

  • мгновенный запуск;
  • отзывчивый интерфейс;
  • возможность все перенастроить под себя;
  • не надо вылазить из терминала. В VS Code, например, интегрированный терминал очень часто падает при долгой работе, хотя у меня есть на борту 32GB RAM (тупо утечки памяти в JS, которых сложно добиться, но для разрабов VS Code нет ничего невозможного).

Что может разочаровать:

  • На компьютерах уровня 2 ядра, 2 гига, игровая видеокарта vim с используемыми плагинами уже не взлетит. Я помню как в 2009 запускал Netbeans IDE на своем одноядерном Атлоне с 512 мегабайтами, и он ел меньше чем coc в связке с Ale, но, правда, и не обладал тем функционалом, что дают последнее. Годы летят, пухнут библиотеки, и из-за этого голый vim давно жрет больше чем гуишный Notepad++ конца нулевых.

Можно еще кинуть камень в огород вимеров. Не даром сей текст с первых абзацев начинался со стеба над их пафосом. Я часто от них вижу какую-то критику самокатчиков и смузихлебов за то, что те пишут хипсторские приложения из 100 строчек. Но я захожу на гитхаб, смотрю исходники любого популярного плагина для vim, и вижу там все те же 100 строчек… За 20 с лишним лет вимеры не смогли родить никаких средств для разработки, единственное что они осилили сделать — это прикрутить ноду и поставить расширения от VS Code. Я не вижу в этом ничего плохого, но хейт-спич в сторону JavaScript и любителей соевого молока от них не одобряю. Да, и такую кодовую базу сложно реализовать силами одного человека и даже небольшой команды, а непризнанные гении как правило работают в одиночку, что не дает надежды на замену «ненужно-скрипта» быстрым как гепард, обожравшийся стероидов, кодом на C++ или на Rust (эти пока все стандартные утилиты на крабе не перепишут, таким «нужным делом» не займутся).

Что можно сказать точно, так это то, что vim жив и продолжает развиваться. Для меня vim примечателен как явление, и я им иногда пользуюсь, потому что на нем «удобно редактировать» конфиги на серверах в осутствии альтернатив кроме убогого nano, хотя и без этих настроек, которые из него делают что-то большее, чем необычный текстовый редактор для терминала. А настроить его я решил, только чтобы написать статью, главным образом для тех, кто никогда не заморачивался с его настройкой.

Ссылки

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

★★

Проверено: hobbit ()
Последнее исправление: rtxtxtrx (всего исправлений: 96)
Ответ на: комментарий от Eulenspiegel

Так ты ж свою не написал про ctags и наколеночное автодополнение с дебагом через :!. И вообще в этом мире существует лишь два мнения по любому вопросу: мое и неправильное. Я не буду отказываться от технологии X (Node.js), лишь потому что она не нравится религиозному фанатику. JavaScript прекрасен.

rtxtxtrx ★★
() автор топика
Последнее исправление: rtxtxtrx (всего исправлений: 1)
Ответ на: комментарий от rtxtxtrx

я пользуюсь Emacs.

Emacs не нуждается в статьях такого уровня.

Есть 2 варианта использования - «я пока тупой, но очень хочется» и «я умею в Elisp». Для первых лучше видео, чтобы могли увидеть поведение и объяснение (есть повод учить eng). Вторые смотрят решения и сравнивают со своими, опять же не читая статьи на таком уровне, где учат кнопки жать.

Не в обиду, но если «Делаем из Vim IDE», то мог бы или глубоко в теорию или в глубокий разбор дополнений или для новичков copy/paste с результатом для, например, web (это непросто) или C. А это - это печально… Тема и modeline - это не инструмент.

Eulenspiegel
()
Ответ на: комментарий от Eulenspiegel

Ты даже статьи не удосужился нормально вставить. «Учим vimscript»… Какой? 9й? А зачем? А создатель R.I.P.? А кто-то развивает 9 версию, которая быстрее в N раз?

Eulenspiegel
()
Ответ на: комментарий от Eulenspiegel

я пользуюсь Emacs.

Java Script лучше твоего Emacs… Да и вообще ржачно читать какую-то критику оного от любителя смайликов с его тормознутым интерпретатором без JIT))))))))))))

в глубокий разбор дополнений

Кому захочется — разберется.

Тема и modeline - это не инструмент.

Инстрмент. Докажи обратное

rtxtxtrx ★★
() автор топика
Последнее исправление: rtxtxtrx (всего исправлений: 1)
Ответ на: комментарий от Eulenspiegel

Насколько оправдано использование vim сегодня? — Оно на самом деле имеет мало смысла, но любителям тайлов зайдет, либо тем, кто постоянно работает из терминала.

А это вывод кого? Школьника?

Ему годков в 2-3 раза больше тебя. Теперь статистика (тырил с reddit-emacs), относительно не поправленная корпами

Для true

4.2% is actually very high usage! If you were to for example look at the languages used section and see languages that are at about 4% of respondents you’d find Ruby, R, and Swift, all of which are highly respectable languages comfortably sitting in their niches.

What if instead take a different metric: the amount of respective subreddit members. This would show a community who cares about the success of the editor and interest in using it. In order the list is:

vim: 177k
vscode: 139.9k
neovim: 103k
emacs: 73k
Visual Studio: 21K
intellijidea: 20k
sublime text: 11k
android studio: 9.6k
xcode: 9.2k
pycharm: 8k
phpstorm: 6.2k
Jupyter: 1.8k
webstorm: 1.1k
notepad++: 786
goland: 333
Eulenspiegel
()
Последнее исправление: Eulenspiegel (всего исправлений: 1)
Ответ на: комментарий от rtxtxtrx

Инстрмент. Докажи обратное

Я же объективно, а не смехуёчки. Может ты и дурак, да вырастешь, детей учить будешь. А вдруг? Так учи! И начни понимать, что хорошие статьи и нужны и популярны. Твои не хорошие.

Eulenspiegel
()
Последнее исправление: Eulenspiegel (всего исправлений: 1)
Ответ на: комментарий от Eulenspiegel

Вызываю тебя на баттл. Сделай мне обзор на дендиевскую игрушку мари… пиши свою статью ё-макс лучше вима или vscode (и Java Script). Или слив засчитан. Критиканов много, но тех кто не лев простой на деле мало.

rtxtxtrx ★★
() автор топика
Ответ на: комментарий от th3m3

В Арче так переехать можно:

$ code --list-extensions > extensions.txt

$ yay -S code                  
Sync Explicit (1): code-1.94.2-1
resolving dependencies...
looking for conflicting packages...
:: code-1.94.2-1 and visual-studio-code-bin-1.94.2-1 are in conflict. Remove visual-studio-code-bin? [y/N] y

$ xargs -n1 code --install-extension < extensions.txt

$ cp -f ~/.config/Code/User/settings.json ~/.config/Code\ -\ OSS/User 
cp: overwrite '/home/sergey/.config/Code - OSS/User/settings.json'? y
rtxtxtrx ★★
() автор топика

Основы использования

Стоило бы добавить { и }. Это основы многих идиом vi.

Отсутствуют многие идиоматичные практики, такие как g (global), ! и адресы.

Отсутствует упоминание макросов, которые позволяют уменьшить недостатки vi, не прибегая к использованию плагинов.

Файловый менеджер для Vim

:r !ls
:r !find . -type f |sort

Для открытия файла:

добавить e! в начало строки
"a:@a

Fuzzy finder для Vim

!}grep pattern

Плагин для добавления, изменения и удаления скобок, кавычек и других символов вокруг текста

Переусложнение и без того сложного языка команд vi. f F t T.

Плагин для автодополнения с использованием клавиши , упрощающий набор кода

Традиционный способ — оставить метку на текущем месте (mm), найти символ (/sym), скопировать что нужно, вернуться назад (``), вставить.

Да, неудобно (вопреки обещаниям про эффективное управление в vi), зато заставляет привыкнуть к стандартному управлению, которое уже используется в других задачах.

Плагин для быстрого комментирования и раскомментирования строк кода

!}sed 's|^|//|'
!}sed 's|^//||'

Плагин, который показывает изменения в Git в виде значков в сайдбаре

:!git status

Плагин для линтинга и форматирования кода

:!go vet %
:%!gofmt %

Плагин для отладки кода

:!sh
gdb

Плагин, добавляющий иконки для файлов и папок в Vim

https://microsoft.com

Плагин для отделения отступов

https://jspaint.app

Плагин для разноцветной подсветки скобок

% на скобке

Любители обмазаться vim шарят свои конфиги, делают скрины и показывают их друг другу.

Более преданные пользователи предпочитают узнать базовые методы, предлагаемые vi для решения проблем. Документы, написанные Биллом Джоем хорошо помогают в этом (1, 2).

Вопреки переусложнениям, ограничениям и банальной неудобности (моё мнение может отличаться от вашего), vi стремится к универсальности. Несмотря на все свои недостатки, vi позволяет переиспользовать одни и те же принципы и практики для решения разных задач, что было продемонстрировано выше.

Другими словами, vi предлагает подход «many problems, one approach». Плагины, напротив, «many problems, many approaches».

Возможно, людям больше нравится последний подход. Но в таком случае им не нужен vi.

kaldeon
()
Ответ на: комментарий от ox55ff

Использовать временный макрос.

:map #p anewval^[

Делаешь что хочешь с текстом. Как только нужно вставить значение - жмёшь #p в визуальном режиме.

Если текст слишком большой, то сохраняешь его во временный файл (w !cat >/tmp/newval) и делаешь такой макрос:

:map #p :r !cat /tmp/newval^M
kaldeon
()

Эта статья с ее 4000 слов не дотягивает даже до размера моего резюме на 15 страницах, от которого бомбит херок. Это печально

rtxtxtrx ★★
() автор топика
Ответ на: комментарий от special-k

А кто его напишет? Его нет… Решил я значит выпотрошить расширение аля blackbox ai. Ну думаю ну где кроме тестов смотреть какие он запросы шлет… Смотрю:

import { isCodeValid } from '../src/utils/extractors/utils';

require('jest');

test("AI Code Validation - Valid", () => {
    expect(isCodeValid("function test() { return 1; }")).toBe(true);
    expect(isCodeValid("function test() { return 1; }\nfunction test2() { return 1; }")).toBe(true);
});

test("AI Code Validation - Invalid", () => {
    expect(isCodeValid("thisisnotcode")).toBe(false);
});

const testCases: [string, boolean][] = [['public int counter = 0;', true],
    ['Toast msg;', true],
    ['public int counter = 0;', true],
    /// ...
     VALUE()`, true],
    ['SELECT COUNT(CompanyID) FROM email_archive WHERE attachment = \'\'', true],
    ['SELECT COUNT(CompanyID) FROM email_archive', true],
    ['I have joined two tables via CompanyID to get the count of those attachment that have null and those that are not null. I have then calculated the percentage and to the result I have concatenated \'%\' string.', false]
];

test("Testing for 95% of tests to be valid", () => {
    let succeeded = 0;
    let failed = 0;
    for (let i = 0; i < testCases.length; i++) {
        const testCase = testCases[i];
        const result = isCodeValid(testCase[0]);
        result == testCase[1] ? succeeded++ : failed++;
    }
    expect(succeeded).toBeGreaterThan(testCases.length * 0.95);
});

Там тесты - это просто проверка содержат ли строки волшебные слова… Сам запрос не сложен:

 http POST https://www.blackbox.ai/api/chat \
    messages:='[{"id": "6cdrFCv", "content": "Привет, мир!", "role": "user"}]' \
    id='6clrFCv' \
    previewToken:=null \
    userId='0d264665-73ae-498f-aa3f-4b7b65997963' \
    codeModelMode:=true \
    agentMode:='[]' \
    trendingAgentMode:='[]' \
    isMicMode:=false \
    isChromeExt:=false \
    githubToken:=null \
    webSearchMode:=false \
    maxTokens:=10240
HTTP/2 200 
date: Sun, 20 Oct 2024 02:58:58 GMT
content-type: text/plain; charset=utf-8
cf-ray: <cut>-HEL
cf-cache-status: DYNAMIC
set-cookie: sessionId=<cut>; Path=/; Expires=Fri, 19 Oct 2029 02:58:58 GMT
vary: RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url, Accept-Encoding
rndr-id: <cut>
x-experimental-stream-data: false
x-render-origin-server: Render
server: cloudflare
alt-svc: h3=":443"; ma=86400

$@$v=undefined-rv1$@$Привет! Как я могу помочь тебе сегодня?

Автоподстановка не работает:

http https://www.useblackbox.io/autocomplete userId='0d264665-73ae-498f-aa3f-4b7b65997963' textInput="document.getE" source="visual studio"
{
    "status": "success",
    "response": ""
}

Но то старое расширение было…

Из нового я ключи какие-то выдрал:

~/workspace/hacking   
(.venv) ❯ vim blackbox.py

{'error': {'code': 'unsupported_country_region_territory', 'message': 'Country, region, or territory not supported', 'param': None, 'type': 'request_forbidden'}}

Press ENTER or type command to continue

~/workspace/hacking
(.venv) ❯ proxychains python blackbox.py
[proxychains] config file found: /home/sergey/workspace/hacking/proxychains.conf
[proxychains] preloading /usr/lib/libproxychains4.so
[proxychains] DLL init: proxychains-ng 4.17
[proxychains] Strict chain  ...  127.0.0.1:1080  ...  api.openai.com:443  ...  OK
{'error': {'message': 'Incorrect API key provided: sk-o7gz6***************************************DoxJ. You can find your API key at https://platform.openai.com/account/api-keys.', 'type': 'invalid_request_error', 'param': None, 'code': 'invalid_api_key'}}
                                                                                                               
~/workspace/hacking   
(.venv) ❯ cat blackbox.py 
import requests

OPENAI_API_KEY = "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"


def describe_code(code):
    url = "https://api.openai.com/v1/engines/davinci-codex/completions"
    prompt = f'{code}\n"""\ndescribe the above code:'

    headers = {
        "Authorization": f"Bearer {OPENAI_API_KEY}",
        "Content-Type": "application/json",
    }

    data = {
        "prompt": prompt,
        "temperature": 0,
        "max_tokens": 170,
        "top_p": 1.0,
        "frequency_penalty": 0.0,
        "presence_penalty": 0.0,
        "stop": ['"""'],
    }

    response = requests.post(url, headers=headers, json=data)
    return response.json()


# Пример использования
code_to_describe = """
def add(a, b):
    return a + b
"""

description = describe_code(code_to_describe)
print(description)
rtxtxtrx ★★
() автор топика
Последнее исправление: rtxtxtrx (всего исправлений: 2)
Ответ на: комментарий от rtxtxtrx

Короче нужен дегенеративный ai, предоставляющий доступ любым желающим к своему API, основанному на OpenAI API, тогда можно родить расширение

rtxtxtrx ★★
() автор топика
Ответ на: комментарий от ox55ff

Да вручную никто ничего не делает, все вешают на сочетания. Тут в основном хейтерки вима - это ё-максо-бои типа шпигуля либо просто те, кто меня ненавидит, те это мои персонально хейтеры. Я не вижу причин ненавидеть вим, ведь он теперь придаток вскоде. А вскоде я люблю и ноду с электроном. А ты просто фишку не сечешь, что движение мышкой больше энергии расходует чем нажатие сочетаний.

rtxtxtrx ★★
() автор топика
Ответ на: комментарий от rtxtxtrx

Да вручную никто ничего не делает, все вешают на сочетания.

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

bread
()
Ответ на: комментарий от braboar

Sexplore

Звучит как название фильма на отцовской кассете

rtxtxtrx ★★
() автор топика
Ответ на: комментарий от bread

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

rtxtxtrx ★★
() автор топика

" Поиск файлов по содержимому
" yay -S ripgrep
nnoremap f :Rg

:Rg из плагина vim-ripgrep который не установлен.
Чтобы ripgrep искал в скрытых директорияx нужно ещё добавить:

g:rg_command = 'rg --vimgrep --hidden'

Искать оно будет в current directory, нужно отдельно ввести :cd, и после поиска наверное восстановить прежнюю cd.

В Emacs это просто встроенная команда rgrep, которая использует путь файла в буферe, можно подняться вверх удаляя целые слова из пути, предлагает выбрать расширение файлов или all. Всё с минимальным нажатием клавиш за 3 секунды.

Для Vim сделать rgrep как в Emacs это одна функция vimscript с использование input() для запросов пути и расширения файлов.
Но очень мало тех кто понимает в чём эргономика vimscript, почему он именно такой. Даже плагин не надо оформлять потому что одна функция будет. Большинство жаваскриптеров такое не понимают. Neovim вообще скручен скотчем.

tp_for_my_bunghole
()
Последнее исправление: tp_for_my_bunghole (всего исправлений: 1)
Ответ на: комментарий от tp_for_my_bunghole

Сам ты копипаст. Сейчас еще примеров добавлю

rtxtxtrx ★★
() автор топика
Ответ на: комментарий от kaldeon

Есть, без «:» вводить.
Есть :{range}![!]{filter} [!][arg], сохраняет в файл и открывает в буфере.

tp_for_my_bunghole
()

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

rtxtxtrx ★★
() автор топика
Ответ на: комментарий от rtxtxtrx

Ты мой герой! Слушай а ты случаем не подскажешь как в расширении CoC настроить, что бы он при поиске определения нужной функции если окно не отрыто, то открывал его, а если открыто, то переходил к нужному определению в уже открытом окне. Я искал но нашёл лишь такое:

nmap <silent> gs :call CocAction('jumpDefinition', 'split')<CR>
nmap <silent> gd :call CocAction('jumpDefinition', 'vsplit')<CR>
nmap <silent> gt :call CocAction('jumpDefinition', 'tabe')<CR>

Тут он всё время начинает открывать окна, что в прочем понятно. Просто я не знаю как в vimscript писать условие и главное как узнать есть ли нужная функция в уже открытом окне.

keeper_b ★★★★
()
Ответ на: комментарий от keeper_b

Я тоже Vimcript не знаю и просто по аналогии делаю. Там не в условиях дело, а в том что плюгин для vim просто шлет запросы на нодовский сервер, запущенный локально. — Форкнуть проект и отредактировать серверный код на TypeScript.

rtxtxtrx ★★
() автор топика
Ответ на: комментарий от rtxtxtrx

И создать пулл-реквест, если это кому-то полезно, то его примут…

rtxtxtrx ★★
() автор топика
Ответ на: комментарий от keeper_b

issue создай, описав свое проблему, и тогда автор, возможно, ее решит, и наче о ней никогда не узнает

rtxtxtrx ★★
() автор топика

Это же сколько свободного времени должно быть у програмиста / девопса, что ВОТ ТАК настраивать редактор. РЕДАКТОР, КАРЛ. Не кластер поднять, не продукт пилить, а НАСТРАИВАТЬ РЕДАКТОР.

her_s_gory
()
Ответ на: комментарий от her_s_gory

Кластер поднять

С этим любой идиот справится (я же справлялся). Если погроммист YAML не могёт, то пусть честно признается, что он обычный недоадмин, который в отличии от полноценного хорошо знает лишь пару утилит

rtxtxtrx ★★
() автор топика
Последнее исправление: rtxtxtrx (всего исправлений: 1)
Ответ на: комментарий от Gentooshnik

Извините, но я не могу помочь с этим запросом. Если у вас есть другие вопросы или вам нужна помощь с чем-то другим, пожалуйста, дайте знать.

Жаль такое зеленым текстом нельзя писать. Ты с фурфагом из одной секты, покусанных чатомгпт (а это в виде спойлера)

rtxtxtrx ★★
() автор топика
Последнее исправление: rtxtxtrx (всего исправлений: 1)
Ответ на: комментарий от rtxtxtrx

Какой секты? Каким фурфагом?

EDIT: Да нет, никто меня недавно не кусал. Вообще не понимаю о чём ваш комментарий.

Gentooshnik ★★★★★
()
Последнее исправление: Gentooshnik (всего исправлений: 1)
Ответ на: комментарий от rtxtxtrx

С этим любой идиот справится

И всё, задачи кончились? Айда РЕДАКТОР НАСТРАИВАТЬ.

her_s_gory
()

А из ed слабо? Я-то делал (при помощи rlwrap + .inputrc можно облагородить любой REPL, а ed таковым и является), но хипстота не оценит.

А вообще IDE — понятие относительное. Где заканчивается редактор и начинается IDE, особенно применимо к форто-, лиспо- и реболообразным ЯП? Я к тому, что хорошие ЯП не требуют ни подсветки, ни автодополнения, ни других свистоперделок, и без них всё должно быть понятно и просто.

rebforce
()
Ответ на: комментарий от rebforce

А из ed слабо?

Ну в отличии от вим он никому не нужен.

Я к тому, что хорошие ЯП не требуют ни подсветки

Русский — хороший язык, да. Ему подсветка не нужна. В древнем иврите, где писали стеной, используя только согласные, она бы даже не помогла (из-за него насчет библии куча споров в связи с ошибками перевода на греческий). Для языков программирования — нужна, потому как между скобочками и кавычками пробелов нет, что затрудняет чтение + мозг не может на автопилоте скобки распознавать, так как при чтении воспримаются первая и последняя буквы, остальные мозг автоподставляет.

Брос не удался.

rtxtxtrx ★★
() автор топика
Ответ на: комментарий от rtxtxtrx

Ну в отличии от вим он никому не нужен.

Мимо.

Русский — хороший язык, да.

Ага, «в отличии от», заметно. Запятых тоже не завезли в процитированное.

Для языков программирования — нужна, потому как между скобочками и кавычками пробелов нет, что затрудняет чтение + мозг не может на автопилоте скобки распознавать

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

Подсветка нужна только новичкам и только в тех ЯП, где есть чётко обозначенный набор ключевых слов. В гомоиконных она скорее мешает. Там и понятия-то такого, как ключевое слово, нет.

rebforce
()
Ответ на: комментарий от rebforce

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

rtxtxtrx ★★
() автор топика
Ответ на: комментарий от rtxtxtrx

Опять не угадал, да что ж такое-то… Хотя мне подсветка даже в питоне с го не нужна, но пишу я на них и на Tcl сейчас. В виме. Было дело, что и в эде. И в виме везде подсветку отключаю. Мешает ибо.

rebforce
()
Ответ на: комментарий от rebforce

Ладно. А ed зачем рекламировать, если его не используешь, но утвердаешь, что кому-то нужен, но таких ты людей не знаешь. Вим так то очень распространен. Может 1 из 10 на нем постоянно программирует.

rtxtxtrx ★★
() автор топика
Ответ на: комментарий от rtxtxtrx

Ну прикинь, есть такие системные окружения, в которых даже вима нет, ага. Максимум busybox vi и оттуда же ed. И когда заходишь удалённо на такую систему и надо поправить пару строчек в длиннофайле, ed-ом справиться можно порой быстрее, чем курсоровозить в vi. А если сразу чётко знаешь, что на что менять, то и (бизибоксовский же) sed поможет.

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