Neovim - современная замена vim
Для тех кто хочет просто что-то скопировать, вам сюда
Про neovim
:ID: neovim
Neovim - логическая замена другого, более древнего редактора - vim
Почему именно neovim? Все просто, vim/neovim это 1 из лучших редакторов кода, он сочитает в себе относительно большое количество преимуществ:
Скорость работы с текстом. Она просто на несколько порядков выше чем у аналогичных инструментов, таких как idea/vscode/sublime и т.д.
Сама по себе, скорость работы не столь важна, т.к. большинство времени разработчик тратит на аналитические процессы, однако, работа с кодом не отрываясь от клавиатуры, приводит к следующему эффекту
Минимизация дополнительных когнетивных нагрузок. Каждый раз, когда я отвлекался на перетягивания панелек мышкой, выделение куска текста для того чтобы скопировать его, установку каретки на нужную строку..я тратил свою концентрацию, я задумывался над этим. Это очень похоже на императивное и декларативное программирование. Вим позволяет не задумываться над тем как сделать, он позволяет переложить ответственность исполнения на мышечную память, которая не требует участия мозга. Это неплохо расслабляет, настолько, что когда я пытался вернуться в иде, я просто не осилил.
Производительность. Тут все просто, неовим ОЧЕНЬ быстрый редактор, сильно быстрее чем intellij idea, vscode и emacs. Оy открывает гигантские файлы за какие-то доли секунды. При этом потребление памяти весьма скромное. С полным обвесом оно не достигает даже 150мб (потребление памяти я не отношу к плюсу, т.к. на сегодняшний день, железо это не большая проблема)
Комьюнити. В виме прекрасное комьюнити, огромное количество хорошо реализованных плагинов на достаточном уровне качества.
Ты начнешь лучше понимать cli, unix, ast (abstract syntax tree), а также то, как работают языки программирования (насколько это полезные навыки? решать тебе)
Преимущества перед vim
- Lua. Lua это язык на котором конфигурируется neovim, при этом, для любителей vimscript, также нашлось место
непонятно правда зачем, vimscript ужасен. - Встроенный lsp (language server protocol), позволяющий взаимодействовть с большим количеством языков программирования и фреймворков.
Установка neovim
Посмотреть можно тут Для macos
brew install neovim
Пакетный менеджер Packer.nvim
Официальный репозиторий packer
Установка
git clone https://github.com/wbthomason/packer.nvim\
~/.local/share/nvim/site/pack/packer/start/packer.nvim
Перед всеми скриптами использовать следующее:
local execute = vim.api.nvim_command
local fn = vim.fn
local install_path = fn.stdpath('data')..'/site/pack/packer/opt/packer.nvim'
if fn.empty(fn.glob(install_path)) > 0 then
execute('!git clone https://github.com/wbthomason/packer.nvim '..install_path)
execute 'packadd packer.nvim'
end
plugins.lua
return require('packer').startup(function(use)
use 'wbthomason/packer.nvim'
...
end)
Основные настройки
Настройки
Настройка подсветки
cmd "hi clear CursorLine"
cmd "hi cursorlinenr guibg=NONE guifg=#abb2bf"
cmd "set nobackup"
cmd "set nowritebackup"
cmd "hi LineNr guifg=#42464e guibg=NONE"
cmd "hi Comment guifg=#42464e"
cmd "hi SignColumn guibg=NONE"
cmd "hi VertSplit guibg=NONE guifg=#2a2e36"
cmd "hi EndOfBuffer guifg=#1e222a"
cmd "hi PmenuSel guibg=#98c379"
cmd "hi Pmenu guibg=#282c34"
Навигация с разным выбранным языком (Ru/en)
cmd "set langmap=ФИСВУАПРШОЛДЬТЩЗЙКЫЕГМЦЧНЯ;ABCDEFGHIJKLMNOPQRSTUVWXYZ,фисвуапршолдьтщзйкыегмцчня;abcdefghijklmnopqrstuvwxyz"
Табуляция
vim.api.nvim_exec(
[[
set tabstop=2
set shiftwidth=2
set expandtab
set smartindent
]], false)
Persistent Undo между сессиями
vim.api.nvim_exec(
[[
set undodir=~/.vim/undodir
if !isdirectory("/tmp/.vim-undo-dir")
call mkdir("/tmp/.vim-undo-dir", "", 0700)
endif
set undodir=/tmp/.vim-undo-dir
set undofile
]], false)
Folding
vim.api.nvim_exec([[
set foldmethod=indent
set foldnestmax=10
set nofoldenable
set foldlevel=2
set foldcolumn=0
highlight foldcolumn guibg=none
]], false)
Сочитания клавиш
-- Quick window resize
vim.api.nvim_set_keymap(
"n",
"<S-l>",
":vertical resize -5<CR>",
{
noremap = true,
silent = true
}
)
vim.api.nvim_set_keymap(
"n",
"<S-h>",
":vertical resize +5<CR>",
{
noremap = true,
silent = true
}
)
vim.api.nvim_set_keymap(
"n",
"<S-j>",
":resize +5<CR>",
{
noremap = true,
silent = true
}
)
vim.api.nvim_set_keymap(
"n",
"<S-k>",
":resize -5<CR>",
{
noremap = true,
silent = true
}
)
-- Exit current buffer
vim.api.nvim_set_keymap(
"n",
"<Leader>q",
":bp<bar>sp<bar>bn<bar>bd<CR>",
{
noremap = true,
silent = true
}
)
-- Save/past clipboard
cmd 'noremap <Leader>y "+y'
cmd 'noremap <Leader>p "+p'
vim.api.nvim_exec([[
:nmap <c-s> :w<CR>
:imap <c-s> <Esc>:w<CR>a
]], false)
Множественная вставка без загрязнения текущего буфера
vim.api.nvim_exec([[
xnoremap <expr> p 'pgv"'.v:register.'y`>'
xnoremap <expr> P 'Pgv"'.v:register.'y`>'
]], false) -- multiple past without buffer trash
Плагины
Визуальная составляющая
- nvim-base16 - большинство популярных тем оформления
- Подборка ссылок на очень красивые и современные темы для neovim/vim
- Иконки для vim/neovim.
- Web dev icons для neovim
- Плагин для очень плавного скрола
- Indent blank line - neovim плагин для визуальной подсветки блоков кода на 1 уровне
- vim todo highlight - плагин для подсветки ключевых слов таких как TODO/NOTE/FIXME/DEPREICATED
- Vim startify - стартовая страница при открытии вим.
- Nvim dashboard. Еще 1 стартовая страница.
- nvim-ts-rainbow - плагин для подсветки парных скобок
- searchbox - визуальное окно поиска
- colorizer - подсветка hex цветов (полезно для css/sass)
- TrueZen - zen режим для программирование без отвлекающих факторов
Lualine - neovim status line
Lualine - Плагин для гибкой настройки статус бара
Отключение статус лайна для файлового менеджера
vim.api.nvim_exec([[
function! DisableST()
return " "
endfunction
au BufEnter NvimTree setlocal statusline=%!DisableST()
]], false)
Keybindings
Для работы с кейбиндами я использую whichkey - пакет для декларативной настройки сочетаний клавиш в neovim. Также, он позволяет напоминать о используемых сочетаниях клавиш, показывая их с небольшой задержкой. Данный пакет будет использоваться для настройки кейбиндов практически всех плагинов.
Я заранее создал 2 полезных сочитания клавиш, это SPC m e b
для перекомпиляции текущего открытого буфера настроек, а также SPC h r e
для перезагрузки конфигов и установки новых плагинов через packer. Остальные настройки можно посмотреть в моем репозитории.
Основные сочитания клавиш
local wk = require("which-key")
wk.register(
{
m = {
name = "Compile",
e = {
b = {':luafile %<CR>:echo "Compiled!"<CR>', "Compile current lua file"}
}
},
h = {
name = "Hot",
r = {
name = "Reload",
e = {
":source ~/.config/nvim/lua/plugins.lua<CR>:source $MYVIMRC<CR>:PackerSync<CR>:echo 'Reloaded!'<CR>",
"Reload neovim"
}
}
},
-- ...
},
{ prefix = "<space>" }
)
Программирование
Автодополнение с помощью nvim-cmp
- nvim-cmp - автокомплит для неовим
- nvm-cmp ветка с закругленными углами
- Tabnine для neovim. Искусственный интеллект для автодополнения.
Настройк автокомплита + tabnine + закругленных краев
Packer:
use "hrsh7th/cmp-nvim-lsp"
use "hrsh7th/cmp-buffer"
use "hrsh7th/cmp-path"
use "hrsh7th/cmp-cmdline"
-- use "hrsh7th/nvim-cmp"
use {"Iron-E/nvim-cmp", branch = "feat/completion-menu-borders"}
use {"tzachar/cmp-tabnine", run = "./install.sh", requires = "hrsh7th/nvim-cmp"}
local tabnine = require("cmp_tabnine.config")
local cmd = vim.cmd
tabnine:setup(
{
max_lines = 1000,
max_num_results = 20,
sort = true,
run_on_every_keystroke = true,
snippet_placeholder = "..",
ignored_file_types = {}
}
)
local cmp = require "cmp"
local lspkind = require("lspkind")
cmd "set completeopt=menu,menuone,noselect"
cmd "highlight! CmpItemKindMethod guibg=NONE guifg=LightYellow"
cmp.setup(
{
window = {
completion = {border = {"╭", "─", "╮", "│", "╯", "─", "╰", "│"}, scrollbar = "║"},
documentation = {
border = {"╭", "─", "╮", "│", "╯", "─", "╰", "│"},
scrollbar = "║"
},
},
-- win_mode = "rounded",
snippet = {
-- REQUIRED - you must specify a snippet engine
expand = function(args)
vim.fn["vsnip#anonymous"](args.body) -- For `vsnip` users.
-- require('luasnip').lsp_expand(args.body) -- For `luasnip` users.
-- vim.fn["UltiSnips#Anon"](args.body) -- For `ultisnips` users.
-- require'snippy'.expand_snippet(args.body) -- For `snippy` users.
end
},
mapping = {
["<C-b>"] = cmp.mapping(cmp.mapping.scroll_docs(-4), {"i", "c"}),
["<C-f>"] = cmp.mapping(cmp.mapping.scroll_docs(4), {"i", "c"}),
["<C-Space>"] = cmp.mapping(cmp.mapping.complete(), {"i", "c"}),
["<C-y>"] = cmp.config.disable, -- Specify `cmp.config.disable` if you want to remove the default `<C-y>` mapping.
["<C-e>"] = cmp.mapping(
{
i = cmp.mapping.abort(),
c = cmp.mapping.close()
}
),
-- Accept currently selected item. If none selected, `select` first item.
-- Set `select` to `false` to only confirm explicitly selected items.
-- ['<CR>'] = cmp.mapping.confirm({ select = true }),
["<C-j>"] = cmp.mapping.select_next_item({behavior = cmp.SelectBehavior.Insert}),
["<C-k>"] = cmp.mapping.select_prev_item({behavior = cmp.SelectBehavior.Insert}),
["<Tab>"] = cmp.mapping(cmp.mapping.select_next_item(), {"i", "s"}),
["<S-Tab>"] = cmp.mapping(cmp.mapping.select_prev_item(), {"i", "s"}),
["<CR>"] = cmp.mapping.confirm(
{
behavior = cmp.ConfirmBehavior.Replace,
select = true
}
)
},
sources = cmp.config.sources(
{
{name = "cmp_tabnine"},
{name = "nvim_lsp"},
{name = "orgmode"}
-- { name = 'vsnip' }, -- For vsnip users.
-- { name = 'luasnip' }, -- For luasnip users.
-- { name = 'ultisnips' }, -- For ultisnips users.
-- { name = 'snippy' }, -- For snippy users.
},
{
{name = "buffer"}
}
),
formatting = {
format = lspkind.cmp_format()
},
experimental = {native_menu = false}
}
)
-- Use buffer source for `/` (if you enabled `native_menu`, this won't work anymore).
cmp.setup.cmdline(
"/",
{
sources = {
{name = "buffer"}
}
}
)
-- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore).
cmp.setup.cmdline(
":",
{
sources = cmp.config.sources(
{
{name = "path"}
},
{
{name = "cmdline"}
}
)
}
)
LSP (language server protocol)
- LSP Репозиторий с примером настроек, а также информацией по поддержке вашего языка.
- Список доступных настроек для neovim lsp
- Плагин для автоматической установки языков серверов для lsp
- UI иконки и дополнительные действия для lsp с помощью SAGA
Настройка lua
Инструкция по установке lua lsp
local runtime_path = vim.split(package.path, ";")
table.insert(runtime_path, "lua/?.lua")
table.insert(runtime_path, "lua/?/init.lua")
nvim_lsp.sumneko_lua.setup {
apabilities = capabilities,
on_attach = on_attach,
settings = {
Lua = {
runtime = {
-- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim)
version = "LuaJIT",
-- Setup your lua path
path = runtime_path
},
diagnostics = {
-- Get the language server to recognize the `vim` global
globals = {"vim", "use", "bubbles_theme"}
},
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
}
}
}
}
LSP stylelint
require "lspconfig".stylelint_lsp.setup {
settings = {
stylelintplus = {}
}
}
Yaml
Перед настройкой: npm i -g yaml-language-server
require("lspconfig").yamlls.setup {
settings = {
yaml = {
schemas = {
["https://json.schemastore.org/github-workflow.json"] = "/.github/workflows/*",
["https://raw.githubusercontent.com/instrumenta/kubernetes-json-schema/master/v1.18.0-standalone-strict/all.json"] = "/*.k8s.yaml",
}
}
}
}
Angular
Перед настройкой необходимо установить Angular LSP
local project_library_path = "/usr/local/lib/node_modules"
local cmd = {
"ngserver",
"--stdio",
"--tsProbeLocations",
project_library_path,
"--ngProbeLocations",
project_library_path
}
require "lspconfig".angularls.setup {
cmd = cmd,
on_new_config = function(new_config, new_root_dir)
new_config.cmd = cmd
end
}
Улучшенная подсветка синтаксиса с помощью tree sitter.
- Tree sitter - плагин для составления абстрактного синтаксического дерева, с помощью которого выполняется более качественная подсветка синтаксиса, а также различные операции при работе с кодом.
- Tree-sitter context - отображение текущего метода/класса/неймспейса ввеху страницы
- logsitter - быстрое логирование выдленного участка кода с помощью tree-sitter
- Playground внутри neovim для tree-sitter Кстати, с помощью него я написал свой первый плагин на tree-sitter для емакс
Nvim autopair
Настройка, с учетом nvm-cmp
require("nvim-autopairs").setup(
{
disable_filetype = {"TelescopePrompt", "vim"}
}
)
-- If you want insert `(` after select function or method item
local cmp_autopairs = require("nvim-autopairs.completion.cmp")
local cmp = require("cmp")
cmp.event:on("confirm_done", cmp_autopairs.on_confirm_done({map_char = {tex = ""}}))
Автоформатирование
Настройка
g.neoformat_javascript_prettier = {
exe = "./node_modules/.bin/prettier",
args = {"--write", "--config .prettierrc"},
replace = 1
}
g.neoformat_typescript_prettier = {
exe = "./node_modules/.bin/prettier",
args = {"--write", "--config .prettierrc"},
replace = 1
}
vim.api.nvim_exec(
[[
let g:neoformat_javascript_prettier = {
\ 'exe': './node_modules/.bin/prettier',
\ 'args': ['--write', '--config .prettierrc'],
\ 'replace': 1
\ }
]],
false
)
Отладка
Html
Терминал
Поиск с помощью telescope.
- Telescope расширение для управления проектами.
- telescrop-vim-bookmarks - поиск по списку закладок
- telescope-project - добавление существующих проектов в telescope
GIT
- Neogit. Порт популчярного гит клиента Magit (топ 2 гит клиент по версии Slant) и топ 1 cli гит клиент
- Git signs - подсветка измененых участков кода
- Blamer - плагин для вывода информации о том кто последний изменил текущую строку кода
Файловые менеджеры
- Интеграция ranger с neovim. Пожалуй лучший файловый менеджер для cli
- nerdtree - боковой файловый менеджер с иерархией директорий
Работа с текстом
- Vim surround. Плагин для быстрого удаление и замены парных символов (скобки, кавычки и тд)
- Hop. Аналог easy motion. Быстрая навигация по тексту. Пожалуй 1 из самыих незаменимых плагинов.
- Быстрое комментаривание текста
Другие полезные утилиты
Плагин для более интуитивной работы с буферами vim. Как пример: предотвращает закрытие окна vim после того как буфер удалился.
Vim translator - плагин для перевода через google translate внутри vim
Wakatime плагин - мониторинг времени по проектам, файлам и другим метрикам
Для его настройки загляни на сайт wakatime
Vim rooter - плагин который помогает определить корень текущего проекта.
Vim bookmark. Продвинутые закладки, имееют интеграцию с telescope.
spelunker - плагин для подсветки синтакисческих ошибок (работает с camelCase)
Полные настройки можно посмотреть в моем репозитории