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

Как я переписывал vim конфиг в init.lua

Время на прочтение19 мин
Количество просмотров30K

Статья рассказывает о том, как я с нуля переписывал свой nvim-конфиг (init.vim) в конфиг с поддержкой lua (init.lua).

Предисловие

Я тут сидел и прибывал в прокрастинации. Писать код было лень. И, листая старую тетрадь расстрелянного генерала, я увидел комментарии, в которых мне напомнили, что было бы круто переехать на lua. Я слежу за nvim&lua движением на редите, но все как-то руки не доходили, а тут, бах, и прокрастинацию как рукой сняло от таких мыслей:

  • Lua я не знаю, но решил, что это отличный способ немного познакомиться с новым для меня языком

  • Vim супер быстрый, но с помощью lua он станет ещё быстрее

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

  • Заменить кое-какие плагины на более современные, некоторые из которых уже написаны на lua

  • В мире vi* сейчас идет настоящая революция, связанная с использованием neovim с lua, и приобщиться к этому будет весело

Мой старый .vimrc (init.vim)

Мой init.vim представлял вот такой файл
call plug#begin('~/.local/share/nvim/plugged')
"-------------------------------------------------------------------------------
" ПЛАГИНЫ
"-------------------------------------------------------------------------------
" --- Python ---
Plug 'python-mode/python-mode', { 'for': 'python', 'branch': 'develop' }
Plug 'mitsuhiko/vim-jinja'
Plug 'fisadev/vim-isort', {'do': 'pip install isort'} " pip install isort Может сортировать импорты в шапке.
" --- Perl ---
Plug 'WolfgangMehner/perl-support'
" --- JavaScript ---
Plug 'pangloss/vim-javascript'
" --- JSON ---
Plug 'elzr/vim-json'
" --- Bash ---
Plug 'WolfgangMehner/bash-support'    " \rr - для запуска скрипта
" --- HTML ---
Plug 'othree/html5.vim'               " Поддержка microdata и прочей лабуды в html
Plug 'idanarye/breeze.vim'            " Подсвечивает закрывающий и откры. тэг. Если, где-то что-то не закрыто, то не подсвечивает.
Plug 'alvan/vim-closetag'             " Закрывает автоматом html и xml тэги. Пишешь <h1> и он автоматом закроется </h1>. Нажми >!
" --- CSS ---
Plug 'JulesWang/css.vim'              " CSS syntax file
Plug 'groenewege/vim-less'            " Vim syntax for LESS (dynamic CSS)
Plug 'hail2u/vim-css3-syntax'
Plug 'ap/vim-css-color'
" --- Оформление ---
Plug 'vim-airline/vim-airline'        " Крутая строка состояния внизу экрана
Plug 'vim-airline/vim-airline-themes'
Plug 'flazz/vim-colorschemes'        " Может менять цветовую схему. Список схем: https://github.com/flazz/vim-colorschemes/tree/prep
Plug 'joshdick/onedark.vim'          " Тема для вима
Plug 'challenger-deep-theme/vim'      " Тема вима
"Plug 'Yggdroot/indentLine'            " Точки для табов
" --- Автоформатирование кода для всех языков ---
Plug 'Chiel92/vim-autoformat'         " Форматирует все, но надо ставить модули, например для perl надо поставить perltidy.
" --- Автодополнялки ---
"  Здесь список всех поддерживаемых автодополнялкой языков:
"  https://github.com/Shougo/deoplete.nvim/wiki/Completion-Sources
"  Для PHP, GO, TypeScript - смотри там же
Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }     " Асинхронная автодополнялка, работает быстро в отличии от COC
Plug 'deoplete-plugins/deoplete-jedi'                             " Подплагин для автодополнения python
Plug 'carlitux/deoplete-ternjs'                                   " Подплагин для автодополнения javascript
Plug 'ternjs/tern_for_vim', {'do': 'cd ~/.local/share/nvim/plugged/tern_for_vim && npm install'}
" --- Навигация ---
Plug 'majutsushi/tagbar'              " Показывает дерево классов и функций, можно очень быстро перемещаться кнопка F8
Plug 'scrooloose/nerdtree'            " Дерево файлов. Для открытия файла в режиме таблицы юзай t, а для сплита s
Plug 'mileszs/ack.vim'                " Удобный grep по файлам
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
" --- Разное ---
Plug 'cohama/lexima.vim'              " Закрывает автоматом скобки
Plug 'scrooloose/nerdcommenter'       " Комментирует блок \cc, снимает комменты с блока \cu
Plug 'tpope/vim-surround'             " Обрамляет или снимает обрамление. Выдели слово, нажми S и набери <h1>
Plug 'powerman/vim-plugin-ruscmd'     " Русская раскладка в командом режиме
Plug 'chr4/nginx.vim'                 " nginx подсветка
Plug 'sheerun/vim-polyglot'           " Подсветка синтаксиса для тьмы языко, в т.ч. и конфиги nginx
Plug 'w0rp/ale'                       " Нужен, чтобы заработал eslint, как в атоме
Plug 'tpope/vim-unimpaired'           " ]p - вставить из буфера на строку выше, [p - ниже
Plug 'google/vim-searchindex'         " Считает кол-во совпадений при поиске
Plug 'tpope/vim-repeat'               " Может повторять через . vimsurround
Plug 'terryma/vim-multiple-cursors'   " Может изменять имя переменной одновременно в нескольких местах ctrl-n на имени и с
Plug 'mhinz/vim-startify'             " Стартовая страница, если просто набрать vim в консоле
Plug 'skanehira/translate.vim'        " Переводчик
Plug 'mattn/emmet-vim'                " Обрамляет строку в теги по ctrl- y
call plug#end()

"-------------------------------------------------------------------------------
" GLOBAL
"-------------------------------------------------------------------------------
syntax on
set autoindent
filetype on
filetype plugin on
filetype plugin indent on
" Цветовая тема и палитра 256 или 24бит цветов
if ($MYCOLOR=='24bit')
        set termguicolors
endif
"Use 24-bit (true-color) mode in Vim/Neovim when outside tmux.
"If you're using tmux version 2.2 or later, you can remove the outermost $TMUX check and use tmux's 24-bit color support
"(see < http://sunaku.github.io/tmux-24bit-color.html#usage > for more information.)
if (empty($TMUX))
        if (has("nvim"))
                "For Neovim 0.1.3 and 0.1.4 < https://github.com/neovim/neovim/pull/2198 >
                let $NVIM_TUI_ENABLE_TRUE_COLOR=1
        endif
        "For Neovim > 0.1.5 and Vim > patch 7.4.1799 < https://github.com/vim/vim/commit/61be73bb0f965a895bfb064ea3e55476ac175162 >
        "Based on Vim patch 7.4.1770 (guicolors option) < https://github.com/vim/vim/commit/8a633e3427b47286869aa4b96f2bfc1fe65b25cd >
        " < https://github.com/neovim/neovim/wiki/Following-HEAD#20160511 >
        if (has("termguicolors"))
                set termguicolors
        endif
endif
colorscheme challenger_deep
"colorscheme onedark
" Орфография для английского и русского языка
set spelllang=en,ru
" Два пробела при табуляции в качестве отступа для js/html/xml файлов, для
" остальных 4
set shiftwidth=4
set tabstop=4
set softtabstop=4
" Как vim сплитит экран
set splitright
set splitbelow
" Даже, если ща русская раскладка, все равно можно вводить любые команды типа
" Ctrl + r и т.д.
set keymap=russian-jcukenwin
set iminsert=0  " Чтобы при старте ввод был на английском, а не русском (start > i)
set imsearch=0  " Чтобы при старте поиск был на английском, а не русском (start > /)
" Включаем номерацию строк
set number
" Вкл. относительную нумерацию строк, напр. 10j или 5k
set relativenumber
" Курсор всегда в центре экрана
set so=999
" Подсветка строки, на которой находится курсор
set cursorline
set nostartofline
hi CursorLine cterm=underline
" Возможность отката назад в файле
set undofile
"-------------------------------------------------------------------------------
" LET'S
"-------------------------------------------------------------------------------
" python-mode
let g:pymode_python = 'python3'                           " По умолчанию python-mode использует проверку синтаксиса python 2. Чтобы включить python 3
" Здесь правильнее писать путь к виртуальному окружению, а не общему. На рокки
" не работало без этого
let g:python3_host_prog='/usr/bin/python3'
let g:pymode_lint_ignore=["E722", "C901"]                 " Игнорировать определенные линты
" Тема для айрлайна и все остальное настройка tabline
let g:airline_theme='papercolor'
"let g:airline_theme='onedark'
let g:airline#extensions#tabline#formatter = 'unique_tail'
let g:airline#extensions#tabline#enabled = 1           " enable airline tabline
let g:airline#extensions#tabline#tabs_label = ''       " can put text here like BUFFERS to denote buffers (I clear it so nothing is shown)
let g:airline#extensions#tabline#buffers_label = ''    " can put text here like TABS to denote tabs (I clear it so nothing is shown)
let g:airline#extensions#tabline#fnamemod = ':t'       " disable file paths in the tab
let g:airline#extensions#tabline#show_tab_count = 0    " dont show tab numbers on the right
let g:airline#extensions#tabline#show_buffers = 1      " dont show buffers in the tabline
let g:airline#extensions#tabline#tab_min_count = 1     " minimum of 2 tabs needed to display the tabline
let g:airline#extensions#tabline#show_splits = 0       " disables the buffer name that displays on the right of the tabline
let g:airline#extensions#tabline#show_tab_nr = 0       " disable tab numbers
let g:airline#extensions#tabline#show_tab_type = 0     " disables the weird ornage arrow on the tabline
let g:airline#extensions#tabline#left_sep = ''
let g:airline#extensions#tabline#left_alt_sep = '|'
" fzf
let g:fzf_buffers_jump = 1
"let g:fzf_action = {  'enter': 'tab drop',  'ctrl-t': 'tab drop'}
" Включаем автодополнялку при старте
let g:deoplete#enable_at_startup = 1
call deoplete#custom#option('num_processes', 4)
" Чтобы работало по <F8> навигация по перловому файлу
let g:tagbar_type_perl = {
                        \ 'ctagstype' : 'perl',
                        \ 'kinds'     : [
                        \ 'p:package:0:0',
                        \ 'w:roles:0:0',
                        \ 'e:extends:0:0',
                        \ 'u:uses:0:0',
                        \ 'r:requires:0:0',
                        \ 'o:ours:0:0',
                        \ 'a:properties:0:0',
                        \ 'b:aliases:0:0',
                        \ 'h:helpers:0:0',
                        \ 's:subroutines:0:0',
                        \ 'd:POD:1:0'
                        \ ]
                        \ }
" Компактный вид у тагбара
let g:tagbar_compact = 1
" Отк. сортировка по имени у тагбара
let g:tagbar_sort = 0
" Конфиг ale + eslint
let g:ale_fixers = { 'javascript': ['eslint'] }
let g:ale_sign_error = '❌'
let g:ale_sign_warning = '⚠️'
let g:ale_fix_on_save = 1
" Запуск линтера, только при сохранении
let g:ale_lint_on_text_changed = 'never'
let g:ale_lint_on_insert_leave = 0
" Используем ag вместо grep. Он будет игнорить папки помеченные .gitignore
if executable('ag')
        let g:ackprg = 'ag --vimgrep'
endif
" Показывать скрытые файлы и папки в NERDTree
let NERDTreeShowHidden = 1
" Направление перевода с русского на английский
let g:translate_source = "ru"
let g:translate_target = "en"
let g:translate_popup_window = 0
"-------------------------------------------------------------------------------
" AUTOCMD
"-------------------------------------------------------------------------------
" Для питоновский скрипов автоматом вызывает Дерево функций и классов
autocmd VimEnter .py,.pl,.js,.php TagbarToggle
autocmd FileType javascript setlocal expandtab shiftwidth=2 tabstop=2 softtabstop=2
autocmd BufRead,BufNewFile .htm,.html,.xml,.json,.php,.css,*.rss setlocal tabstop=2 shiftwidth=2 softtabstop=2
" Автоматический перенос текста для текстовых файлов
autocmd BufRead,BufNewFile *.txt  setlocal textwidth=80
" С этой строкой отлично форматирует html файл, который содержит jinja2
au BufNewFile,BufRead *.html set filetype=htmldjango
autocmd BufRead,BufNewFile *.conf let b:autoformat_autoindent=0
" Запоминает где nvim последний раз редактировал файл
au BufReadPost * if line("'"") > 1 && line("'"") <= line("$") | exe "normal! g'"" | endif
" Запуск php скриптов с помощью \rr
autocmd FileType php noremap \rr :w!<CR>:!/bin/php %<CR>
"-------------------------------------------------------------------------------
" ГОРЯЧИЕ КНОПКИ
"-------------------------------------------------------------------------------
" Типа 'Нажимает' на ESC при быстром нажатии jj, чтобы не тянутся
imap jj <Esc>
" Отключаем стрелочки
nnoremap <Left> :echoe "Use h"<CR>
nnoremap <Right> :echoe "Use l"<CR>
nnoremap <Up> :echoe "Use k"<CR>
nnoremap <Down> :echoe "Use j"<CR>
" Системный буфер обмена shift - Y / P
noremap <S-Y> "+y
" По F1 очищаем последний поиск с подсветкой
nnoremap <silent><F1> :noh<CR>
" shift + F1 = удалить пустые строки
nnoremap <S-F1> :g/^$/d<CR>
" Используй F2 для временной вставки из буфера, чтобы отключить авто идент
set pastetoggle=<F2>
" Перечитать .vimrc / init
noremap <F3> :source ~/.config/nvim/init.vim<CR>
" Открыть .config/nvim/init.vim через Shift + <F3>
" Может не работать, если echo $TERM  xterm-256color
noremap <S-F3> :edit ~/.config/nvim/init.vim<CR>
" Поиск слова под курсором, воскл. знак, чтобы не было автооткрытия файла
noremap <F4> :Ack! <cword> --ignore-dir={static,logs,files}<cr>
noremap <S-F4> :Ack! --ignore-dir={static,logs,files}
" Тогле включение и отклю. показа строк и обычных и релативных
nnoremap  <silent> <F5> :exec &nu==&rnu? "se nu!" : "se rnu!"<cr>
" Дерево файлов. Используй для открытия файлов t  и s  чтобы открывать в режиме таблицы или сплита
noremap <F6> :NERDTreeRefreshRoot<CR> :NERDTreeToggle<CR>
" Показ дерева классов и функций, плагин majutsushi/tagbar
nnoremap <F8> :TagbarToggle<CR>
" Проверка орфографии <F11> для русского и английского языка
nnoremap <silent> <F11> :set spell!<cr>
inoremap <silent> <F11> <C-O>:set spell!<cr>
" CTRL-s сохранялка и автоформат
inoremap <C-s> <esc>:Autoformat<CR>:w<CR>
noremap <C-s> <esc>:Autoformat<CR>:w<CR>
" Пролистнуть на страницу вниз (как в браузерах)
nnoremap <Space> <PageDown> zz
" Пролистнуть на страницу вверх
nnoremap <C-Space> <PageUp> zz
" fzf
noremap <C-a> :Files<CR>
noremap <C-p> :Buffers<CR>
" Переводчик
vmap t <Plug>(VTranslate)
" Переключение между буферов с помощью TAB
function! BSkipQuickFix(command)
        let start_buffer = bufnr('%')
        execute a:command
        while &buftype ==# 'quickfix' && bufnr('%') != start_buffer
                execute a:command
        endwhile
endfunction
nnoremap <Tab> :call BSkipQuickFix("bn")<CR>
nnoremap <S-Tab> :call BSkipQuickFix("bp")<CR>

Писать я его начал ещё тогда, когда neovim не существовал. Что-то добавлялось, удалялось и накопилось всякого разного. Все это я и буду конвертировать в lua, за одно и причешу и избавлюсь от лишнего.

Стартовые условия

(Можно пропустить, если у вас из пакетного менеджера сразу ставится neovim 0.5.х и выше)

Я решил взять старенькую машину с Centos 7, исходя из принципа, что если я смогу на ней все настроить, то на современных и подавно все запущу. Ещё мне надо было убедиться, что на старых машинах так же работает, ибо много легаси болтается на Centos 7, которое надо поддерживать.

Естественно, по умолчанию через yum ставилась старая версия nvim. Но после таких манипуляций версия была уже последняя.

curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim.appimage
chmod u+x nvim.appimage
mkdir .local/bin
mv nvim.appimage .local/bin/nvim

И в файле .bash_profile поменял PATH на локальный в первую очередь.

PATH=$HOME/.local/bin:$HOME/bin:$PATH

AppImage - универсальный пакет для всех, вне зависимости от дистрибутива (Ubuntu, Redhat и т.д.) просто скачиваете файл, запускаете и все сразу работает.

Старенький git обновил таким образом. Без современного git плагин менеджер Packman не работал.

Больше никаких проблем с Centos 7 не было.

С нуля

В ~/.config/nvim создал 4 пустых файла и одну папку. Вот такая получилась структура файлов:

.
├── init.lua
├── lua
│   ├── keymaps.lua
│   ├── plugins.lua
│   └── settings.lua

И начал эти файлы заполнять...

Файл init.lua

Он только считывает файлы с плагинами, настройками и моими хоткеями из директории ~/.config/nvim/lua

-----------------------------------------------------------
-- Импорт модулей lua
-----------------------------------------------------------
require('plugins')
require('settings') 
require('keymaps')

Файл keymaps.lua

Сконвертировать мои хоткеи на lua не составило труда.

keymaps.lua
local map = vim.api.nvim_set_keymap
local default_opts = {noremap = true, silent = true}

-- Системный буфер обмена shift - Y
map('v', 'S-Y', '"+y', {})
-- Типа 'Нажимает' на ESC при быстром нажатии jj, чтобы не тянутся
map('i', 'jj', '<Esc>', {noremap = true})
-- Стрелочки откл. Использовать hjkl
map('', '<up>', ':echoe "Use k"<CR>', {noremap = true, silent = false})
map('', '<down>', ':echoe "Use j"<CR>', {noremap = true, silent = false})
map('', '<left>', ':echoe "Use h"<CR>', {noremap = true, silent = false})
map('', '<right>', ':echoe "Use l"<CR>', {noremap = true, silent = false})
-- Автоформат + сохранение по CTRL-s , как в нормальном, так и в insert режиме
map('n', '<C-s>', ':Autoformat<CR>:w<CR>',  default_opts)
map('i', '<C-s>', '<esc>:Autoformat<CR>:w<CR>', default_opts)
-- Переключение вкладок с помощью TAB или shift-tab (akinsho/bufferline.nvim)
map('n', '<Tab>', ':BufferLineCycleNext<CR>', default_opts)
map('n', '<S-Tab>', ':BufferLineCyclePrev<CR>', default_opts)
-- Пролистнуть на страницу вниз / вверх (как в браузерах)
map('n', '<Space>', '<PageDown> zz', default_opts)
map('n', '<C-Space>', '<PageUp> zz', default_opts)
-- " Переводчик рус -> eng
map('v', 't', '<Plug>(VTranslate)', {})
-- fzf
map('n', '<C-a>', [[ <cmd>lua require('telescope.builtin').find_files()<cr> ]], default_opts)
map('n', '<C-p>', [[ <cmd>lua require('telescope.builtin').buffers()<cr> ]], default_opts)

-----------------------------------------------------------
-- Фн. клавиши по F1 .. F12
-----------------------------------------------------------
-- По F1 очищаем последний поиск с подсветкой
map('n', '<F1>', ':nohl<CR>', default_opts)
-- shift + F1 = удалить пустые строки
map('n', '<S-F1>', ':g/^$/d<CR>', default_opts)
-- <F2> для временной вставки из буфера, чтобы отключить авто идент
vim.o.pastetoggle='<F2>'
-- <F3> перечитать конфигурацию nvim Может не работать, если echo $TERM  xterm-256color
map('n', '<F3>', ':so ~/.config/nvim/init.lua<CR>:so ~/.config/nvim/lua/plugins.lua<CR>:so ~/.config/nvim/lua/settings.lua<CR>:so ~/.config/nvim/lua/keymaps.lua<CR>', { noremap = true })
-- <S-F3> Открыть всю nvim конфигурацию для редактирования
map('n', '<S-F3>', ':e ~/.config/nvim/init.lua<CR>:e ~/.config/nvim/lua/plugins.lua<CR>:e ~/.config/nvim/lua/settings.lua<CR>:e ~/.config/nvim/lua/keymaps.lua<CR>', { noremap = true })
-- <F4> Поиск слова под курсором
map('n', '<F4>', [[<cmd>lua require('telescope.builtin').grep_string()<cr>]], default_opts)
-- <S-F4> Поиск слова в модальном окошке
map('n', '<S-F4>', [[<cmd>lua require('telescope.builtin').live_grep()<cr>]], default_opts)
-- <F5> разные вариации нумераций строк, можно переключаться
map('n', '<F5>', ':exec &nu==&rnu? "se nu!" : "se rnu!"<CR>', default_opts)
-- <F6> дерево файлов.
map('n', '<F6>', ':NvimTreeRefresh<CR>:NvimTreeToggle<CR>', default_opts)
-- <F8>  Показ дерева классов и функций, плагин majutsushi/tagbar
map('n', '<F8>', ':TagbarToggle<CR>', default_opts)
-- <F11> Проверка орфографии  для русского и английского языка
map('n', '<F11>', ':set spell!<CR>', default_opts)
map('i', '<F11>', '<C-O>:set spell!<CR>', default_opts)

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

noremap <F3> :source ~/.config/nvim/init.vim<CR>

А тут файлов уже больше получается. Полез в инет, начал гуглить. Нашел вот такое обсуждение, но у меня не взлетело ничего из того, что там предлагается. Очередной показатель, что lua за 15 минут - это цирк. Надо разбираться. И короче, я просто захардкодил в итоге релоад этих 4-х файлов, но сдаваться не буду, попробую найти адекватное решение.

Файл settings.lua

Файл с настройками получился таким:

settings.lua
local cmd = vim.cmd             -- execute Vim commands
local exec = vim.api.nvim_exec  -- execute Vimscript
local g = vim.g                 -- global variables
local opt = vim.opt             -- global/buffer/windows-scoped options
-- Направление перевода с русского на английский
g.translate_source = 'ru'
g.translate_target = 'en'
-- Компактный вид у тагбара и Отк. сортировка по имени у тагбара
g.tagbar_compact = 1
g.tagbar_sort = 0

-- Конфиг ale + eslint
g.ale_fixers = { javascript= { 'eslint' } }
g.ale_sign_error = '❌'
g.ale_sign_warning = '⚠️'
g.ale_fix_on_save = 1
-- Запуск линтера, только при сохранении
g.ale_lint_on_text_changed = 'never'
g.ale_lint_on_insert_leave = 0

-----------------------------------------------------------
-- Главные
-----------------------------------------------------------
opt.colorcolumn = '80'              -- Разделитель на 80 символов
opt.cursorline = true               -- Подсветка строки с курсором
opt.spelllang= { 'en_us', 'ru' }    -- Словари рус eng
opt.number = true                   -- Включаем нумерацию строк
opt.relativenumber = true           -- Вкл. относительную нумерацию строк
opt.so=999                          -- Курсор всегда в центре экрана
opt.undofile = true                 -- Возможность отката назад
opt.splitright = true               -- vertical split вправо
opt.splitbelow = true               -- horizontal split вниз
-----------------------------------------------------------
-- Цветовая схема
-----------------------------------------------------------
opt.termguicolors = true      --  24-bit RGB colors
cmd'colorscheme onedark'
-----------------------------------------------------------
-- Табы и отступы
-----------------------------------------------------------
cmd([[
filetype indent plugin on
syntax enable
]])
opt.expandtab = true      -- use spaces instead of tabs
opt.shiftwidth = 4        -- shift 4 spaces when tab
opt.tabstop = 4           -- 1 tab == 4 spaces
opt.smartindent = true    -- autoindent new lines
-- don't auto commenting new lines
cmd [[au BufEnter * set fo-=c fo-=r fo-=o]]
-- remove line lenght marker for selected filetypes
cmd [[autocmd FileType text,markdown,html,xhtml,javascript setlocal cc=0]]
-- 2 spaces for selected filetypes
cmd [[
autocmd FileType xml,html,xhtml,css,scss,javascript,lua,yaml,htmljinja setlocal shiftwidth=2 tabstop=2
]]
-- С этой строкой отлично форматирует html файл, который содержит jinja2
cmd[[ autocmd BufNewFile,BufRead *.html set filetype=htmldjango ]]
-----------------------------------------------------------
-- Полезные фишки
-----------------------------------------------------------
-- Запоминает где nvim последний раз редактировал файл
cmd [[
autocmd BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
]]
-- Подсвечивает на доли секунды скопированную часть текста
exec([[
augroup YankHighlight
autocmd!
autocmd TextYankPost * silent! lua vim.highlight.on_yank{higroup="IncSearch", timeout=700}
augroup end
]], false)

-----------------------------------------------------------
-- Установки для плагинов
-----------------------------------------------------------
-- LSP settings
local lsp_installer = require("nvim-lsp-installer")
lsp_installer.on_server_ready(function(server)
    local opts = {}
    if server.name == "sumneko_lua" then
        -- only apply these settings for the "sumneko_lua" server
        opts.settings = {
            Lua = {
                diagnostics = {
                    -- Get the language server to recognize the 'vim', 'use' global
                    globals = {'vim', 'use'},
                },
                workspace = {
                    -- Make the server aware of Neovim runtime files
                    library = vim.api.nvim_get_runtime_file("", true),
                },
                -- Do not send telemetry data containing a randomized but unique identifier
                telemetry = {
                    enable = false,
                },
            },
        }
    end
    server:setup(opts)
end)


-- nvim-cmp supports additional completion capabilities
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities = require('cmp_nvim_lsp').update_capabilities(capabilities)
vim.o.completeopt = 'menuone,noselect'
-- luasnip setup
local luasnip = require 'luasnip'
-- nvim-cmp setup
local cmp = require 'cmp'
cmp.setup {
    snippet = {
        expand = function(args)
            luasnip.lsp_expand(args.body)
        end,
    },
    sources = {
        { name = 'nvim_lsp' },
        { name = 'luasnip' },
        { name = 'path' },
        { name = 'buffer', opts = {
            get_bufnrs = function()
                return vim.api.nvim_list_bufs()
            end
        },
    },
},
}

С файлом никаких проблем не возникло, все легко переписалось. Добавились настройки для плагинов: LSP и nvim-cmp, но о плагинах дальше...

Файл plugins.lua

Мой файл с плагинами после "ревизии" получился таким:

plugins.lua

vim.cmd [[packadd packer.nvim]]

return require('packer').startup(function()
    -- Packer сам себя
    use 'wbthomason/packer.nvim'

    -----------------------------------------------------------
    -- ПЛАГИНЫ ВНЕШНЕГО ВИДА
    -----------------------------------------------------------

    -- Цветовая схема
    use 'joshdick/onedark.vim'
    --- Информационная строка внизу
    use { 'nvim-lualine/lualine.nvim',
    requires = {'kyazdani42/nvim-web-devicons', opt = true},
    config = function()
        require('lualine').setup()
    end, }
    -- Табы вверху
    use {'akinsho/bufferline.nvim', requires = 'kyazdani42/nvim-web-devicons',
    config = function()
        require("bufferline").setup{}
    end, }


    -----------------------------------------------------------
    -- НАВИГАЦИЯ
    -----------------------------------------------------------
    -- Файловый менеджер
    use { 'kyazdani42/nvim-tree.lua',
    requires = 'kyazdani42/nvim-web-devicons',
    config = function() require'nvim-tree'.setup {} end, }
    -- Навигация внутри файла по классам и функциям
    use 'majutsushi/tagbar'
    -- Замена fzf и ack
    use { 'nvim-telescope/telescope.nvim',
    requires = { {'nvim-lua/plenary.nvim'} },
    config = function() require'telescope'.setup {} end, }


    -----------------------------------------------------------
    -- LSP и автодополнялка
    -----------------------------------------------------------


    -- Highlight, edit, and navigate code using a fast incremental parsing library
    use 'nvim-treesitter/nvim-treesitter'
    -- Collection of configurations for built-in LSP client
    use 'neovim/nvim-lspconfig'
    use 'williamboman/nvim-lsp-installer'
    -- Автодополнялка
    use 'hrsh7th/nvim-cmp'
    use 'hrsh7th/cmp-nvim-lsp'
    use 'hrsh7th/cmp-buffer'
    use 'saadparwaiz1/cmp_luasnip'
    --- Автодополнлялка к файловой системе
    use 'hrsh7th/cmp-path'
    -- Snippets plugin
    use 'L3MON4D3/LuaSnip'



    -----------------------------------------------------------
    -- PYTHON
    -----------------------------------------------------------
    --- Шапка с импортами приводим в порядок
    use 'fisadev/vim-isort'
    -- Поддержка темплейтом jinja2
    use 'mitsuhiko/vim-jinja'


    -----------------------------------------------------------
    -- HTML и CSS
    -----------------------------------------------------------
    -- Подсвечивает закрывающий и откры. тэг. Если, где-то что-то не закрыто, то не подсвечивает.
    use 'idanarye/breeze.vim'
    -- Закрывает автоматом html и xml тэги. Пишешь <h1> и он автоматом закроется </h1>
    use 'alvan/vim-closetag'
    -- Подсвечивает #ffffff
    use 'ap/vim-css-color'

    -----------------------------------------------------------
    -- РАЗНОЕ
    -----------------------------------------------------------
    -- Даже если включена русская раскладка vim команды будут работать
    use 'powerman/vim-plugin-ruscmd'
    -- 'Автоформатирование' кода для всех языков
    use 'Chiel92/vim-autoformat'
    -- ]p - вставить на строку выше, [p - ниже
    use 'tpope/vim-unimpaired'
    -- Переводчик рус - англ
    use 'skanehira/translate.vim'
    --- popup окошки
    use 'nvim-lua/popup.nvim'
    -- Обрамляет или снимает обрамление. Выдели слово, нажми S и набери <h1>
    use 'tpope/vim-surround'
    -- Считает кол-во совпадений при поиске
    use 'google/vim-searchindex'
    -- Может повторять через . vimsurround
    use 'tpope/vim-repeat'
    -- Стартовая страница, если просто набрать vim в консоле
    use 'mhinz/vim-startify'
    -- Комментирует по gc все, вне зависимости от языка программирования
    use { 'numToStr/Comment.nvim',
    config = function() require('Comment').setup() end }
    -- Обрамляет строку в теги по ctrl- y + ,
    use 'mattn/emmet-vim'
    -- Закрывает автоматом скобки
    use 'cohama/lexima.vim'
    -- Линтер, работает для всех языков
    use 'dense-analysis/ale'

end)

За установку плагинов для lua отвечает менеджер packer.nvim. Принцип работы такой же, как и у обычных менеджеров.

О плагинах

Некоторые плагины я удалил, которые были в init.vim, некоторые добавил или заменил. Об этом и пойдет дальше речь.

nvim-lspconfig и nvim-lsp-installer

Работа плагина nvim-lsp-installer
Работа плагина nvim-lsp-installer

Из названий плагинов понятно, что они занимаются взаимодействием с lsp. И на основе lsp строится уже все остальное: автодополнялки, линтеры и т.д.

Допустим, вы открыли два файла, один написан на Rust, а другой на Typescript. На гиф-ке сверху видно, как плагин nvim-lsp-installer устанавливает сервера для этих языков, а как только сервера были установлены, мгновенно заработали линтеры с критикой кода. Для работы nvim-lsp-installer требуется плагин nvim-lspconfig. Если ввести команду :LspInstallInfo , то можно увидеть список поддерживаемых на данный момент языков (сейчас, когда я это пишу, их 57).

nvim-cmp

Nvim-cmp - это движок, на котором строятся любые автодополнения. Движок написан на lua. Можно посмотреть в моем файле plugins.lua, какие я еще использую встроенные исходники. Например, чтобы работал автокомплит по путям в файловой системе, используется cmp-path, для lsp - cmp-nvim-lsp и т.д.

telescope.nvim

telescope.nvim
telescope.nvim

Telescope.nvim - модная по нынешним временам штуковина. В своей прошлой статье, я писал о плагинах fzf и ack.vim. Плагин fzf отвечал за нечеткий поиск по файлам, а ack - когда нужно грепнуть какое-нибудь слово. Так вот Телескоп делает обе эти вещи в одном флаконе. Умеет делать нечеткий поиск по файлам и умеет искать слово внутри файлов. И делает это все в модальном всплывающем окошке.

Comment.nvim

Comment.nvim
Comment.nvim

Я на гиф-ке выше выделяю код, нажимаю gc , и он закоменчен. Прелесть Comment.nvim в том, что не надо думать, с каким на данный момент я имею дело языком, будь то php, perl или js и т.д. Плагин может закомментарить любой язык по gc. До этого использовал плагин nerdcommenter, но вот перешел на новый, который, как вы уже поняли, написан на lua.

lualine.nvim

lualine.nvim
lualine.nvim

Многим людям в nvim нравилась строчка внизу экрана со всякой там информацией, называлась она airline (в старом init.vim она у меня была). Переписали ее на lua и назвали lualine.nvim. Автор даже не поленился и выложил что-то вроде бечмарка, на сколько у него быстрее эта строчка работает.

bufferline.nvim

bufferline.nvim
bufferline.nvim
Скрин кликабельный (работа плагина bufferline.nvim)
Скрин кликабельный (работа плагина bufferline.nvim)

Плагин bufferline.nvim отвечает за работу с табами (буферами) открытых файлов. Я повесил следующие настройки в горячие клавиши, чтобы переключать вкладочки с помощью tab и shift-tab

-- Переключение вкладок с помщью TAB или shift-tab (akinsho/bufferline.nvim)
map('n', '<Tab>', ':BufferLineCycleNext<CR>', default_opts)
map('n', '<S-Tab>', ':BufferLineCyclePrev<CR>', default_opts)

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

Для работы плагина нужны специальные шрифты. Если заходите по ssh с windows, например, используя securecrt или putty, то на винде надо поставить терминальный шрифт nerd, чтобы работали иконки на вкладках.

Теги:
Хабы:
+18
Комментарии38

Публикации