Neovim
大纲#
- option
- plugin manager
- splash
- theme
- FileExpolre
- lsp
- cmp
- comment
- autopair,indent_blankline
- lualine
- bufferline
- fuzzy-find
- nvim-treesitter
LSP: lspconfig & mason-lspconfig.nvim
DAP: nvim-dap
Linters: null-ls.nvim or nvim-lint
Formatters: null-ls.nvim or formatter.nvim
runtimepath#
:h rtp 或者
:h runtimepath
resource#
:luafile %
:so
:checkhealth
vim.options#
https://neovim.io/doc/user/options.html#set-option
:help option-list
plug manager#
git clone --depth 1 https://github.com/wbthomason/packer.nvim\
~/.local/share/nvim/site/pack/packer/start/packer.nvim
sudo vim ~/.config/nvim/lua/basic/packer.lua
---------------------------------
vim.cmd [[packadd packer.nvim]]
return require('packer').startup(function(use)
-- Packer can manage itself
use 'wbthomason/packer.nvim'
end)
---------------------------------
:so in nvim this packer.lua
nvim-tree#
nvim-tree和telescope的区别在于,nvim-tree更能从整体上了解文件结构,telescope更加有针对性,在已了解工程结构的前提下更加便捷
Features
- Automatic updates
- File type icons
- Git integration
- Diagnostics integration: LSP and COC
- (Live) filtering
- Cut, copy, paste, rename, delete, create
- Highly customisable
map | aciton |
---|---|
E | expand_all |
W | collapse_all |
tab | preview |
a | create |
R | refresh |
f | live_filter |
r | rename |
d | remove |
x | cut |
D | trash |
y | copy_name |
gy | copy_absolute_name |
Y | copy_path |
c | copy file |
p | paste |
fuzzy finder#
comment#
- gcc 按行注释
- gbc 按块注释
- gc 按行注释选中
- gc2j 往下按注释两行
- gb 按块注释选中
- gcO 在当前行之上添加注释
- gco 在当前行之下添加注释
- gcA 在当前行尾添加注释
nvim-treesitter#
可以理解为更加理解代码结构和意图的自动档,让nvim更具备相关语言的特色功能
- 代码高亮模块
- 增量选择模块(代替wildfire.vim)
- 格式化功能
- Folding 模块
:TsInstallInfo #查看已安装的language parser
:TSInstall javascript #手工安装某个language parser
:TSModuleInfo #查看parser的安装情况
:TSBufToggle highlight #toggle当前语言的高亮
lsp_zero#
this is the integration between the LSP client and the autocompletion plugin.
---
-- LSP Support
---
local function lsp_keymaps(bufnr)
local map = function(m, lhs, rhs)
local opts = {remap = false, silent = true, buffer = bufnr}
vim.keymap.set(m, lhs, rhs, opts)
end
-- LSP actions
map('n', 'K', '<cmd>lua vim.lsp.buf.hover()<cr>')
map('n', 'gd', '<cmd>lua vim.lsp.buf.definition()<cr>')
map('n', 'gD', '<cmd>lua vim.lsp.buf.declaration()<cr>')
map('n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<cr>')
map('n', 'go', '<cmd>lua vim.lsp.buf.type_definition()<cr>')
map('n', 'gr', '<cmd>lua vim.lsp.buf.references()<cr>')
map('n', '<C-k>', '<cmd>lua vim.lsp.buf.signature_help()<cr>')
map('n', '<F2>', '<cmd>lua vim.lsp.buf.rename()<cr>')
map('n', '<F4>', '<cmd>lua vim.lsp.buf.code_action()<cr>')
map('x', '<F4>', '<cmd>lua vim.lsp.buf.range_code_action()<cr>')
-- Diagnostics
map('n', 'gl', '<cmd>lua vim.diagnostic.open_float()<cr>')
map('n', '[d', '<cmd>lua vim.diagnostic.goto_prev()<cr>')
map('n', ']d', '<cmd>lua vim.diagnostic.goto_next()<cr>')
end
local function lsp_settings()
local sign = function(opts)
vim.fn.sign_define(opts.name, {
texthl = opts.name,
text = opts.text,
numhl = ''
})
end
sign({name = 'DiagnosticSignError', text = '✘'})
sign({name = 'DiagnosticSignWarn', text = '▲'})
sign({name = 'DiagnosticSignHint', text = '⚑'})
sign({name = 'DiagnosticSignInfo', text = ''})
vim.diagnostic.config({
virtual_text = false,
signs = true,
update_in_insert = false,
underline = true,
severity_sort = true,
float = {
focusable = false,
style = 'minimal',
border = 'rounded',
source = 'always',
header = '',
prefix = '',
},
})
vim.lsp.handlers['textDocument/hover'] = vim.lsp.with(
vim.lsp.handlers.hover,
{border = 'rounded'}
)
vim.lsp.handlers['textDocument/signatureHelp'] = vim.lsp.with(
vim.lsp.handlers.signature_help,
{border = 'rounded'}
)
local command = vim.api.nvim_create_user_command
command('LspWorkspaceAdd', function()
vim.lsp.buf.add_workspace_folder()
end, {desc = 'Add folder to workspace'})
command('LspWorkspaceList', function()
vim.notify(vim.inspect(vim.lsp.buf.list_workspace_folders()))
end, {desc = 'List workspace folders'})
command('LspWorkspaceRemove', function()
vim.lsp.buf.remove_workspace_folder()
end, {desc = 'Remove folder from workspace'})
end
local function lsp_attach(client, bufnr)
local buf_command = vim.api.nvim_buf_create_user_command
lsp_keymaps(bufnr)
buf_command(bufnr, 'LspFormat', function()
vim.lsp.buf.format()
end, {desc = 'Format buffer with language server'})
end
lsp_settings()
require('mason').setup({})
require('mason-lspconfig').setup({})
local get_servers = require('mason-lspconfig').get_installed_servers
for _, server_name in ipairs(get_servers()) do
require('lspconfig')[server_name].setup({
on_attach = lsp_attach,
capabilities = require('cmp_nvim_lsp').default_capabilities(),
})
end
---
-- Snippet engine setup
---
local luasnip = require('luasnip')
luasnip.config.set_config({
region_check_events = 'InsertEnter',
delete_check_events = 'InsertLeave'
})
require('luasnip.loaders.from_vscode').lazy_load()
---
-- Autocompletion
---
local cmp = require('cmp')
vim.opt.completeopt = {'menu', 'menuone', 'noselect'}
local cmp_select_opts = {behavior = cmp.SelectBehavior.Select}
local cmp_config = {
completion = {
completeopt = 'menu,menuone,noinsert'
},
snippet = {
expand = function(args)
luasnip.lsp_expand(args.body)
end,
},
sources = {
{name = 'path'},
{name = 'nvim_lsp', keyword_length = 3},
{name = 'buffer', keyword_length = 3},
{name = 'luasnip', keyword_length = 2},
},
window = {
documentation = vim.tbl_deep_extend(
'force',
cmp.config.window.bordered(),
{
max_height = 15,
max_width = 60,
}
)
},
formatting = {
fields = {'abbr', 'menu', 'kind'},
format = function(entry, item)
local short_name = {
nvim_lsp = 'LSP',
nvim_lua = 'nvim'
}
local menu_name = short_name[entry.source.name] or entry.source.name
item.menu = string.format('[%s]', menu_name)
return item
end,
},
mapping = {
-- confirm selection
['<CR>'] = cmp.mapping.confirm({select = false}),
['<C-y>'] = cmp.mapping.confirm({select = false}),
-- navigate items on the list
['<Up>'] = cmp.mapping.select_prev_item(select_opts),
['<Down>'] = cmp.mapping.select_next_item(select_opts),
['<C-p>'] = cmp.mapping.select_prev_item(select_opts),
['<C-n>'] = cmp.mapping.select_next_item(select_opts),
-- scroll up and down in the completion documentation
['<C-f>'] = cmp.mapping.scroll_docs(5),
['<C-u>'] = cmp.mapping.scroll_docs(-5),
-- toggle completion
['<C-e>'] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.abort()
fallback()
else
cmp.complete()
end
end),
-- go to next placeholder in the snippet
['<C-d>'] = cmp.mapping(function(fallback)
if luasnip.jumpable(1) then
luasnip.jump(1)
else
fallback()
end
end, {'i', 's'}),
-- go to previous placeholder in the snippet
['<C-b>'] = cmp.mapping(function(fallback)
if luasnip.jumpable(-1) then
luasnip.jump(-1)
else
fallback()
end
end, {'i', 's'}),
-- when menu is visible, navigate to next item
-- when line is empty, insert a tab character
-- else, activate completion
['<Tab>'] = cmp.mapping(function(fallback)
local col = vim.fn.col('.') - 1
if cmp.visible() then
cmp.select_next_item(cmp_select_opts)
elseif col == 0 or vim.fn.getline('.'):sub(col, col):match('%s') then
fallback()
else
cmp.complete()
end
end, {'i', 's'}),
-- when menu is visible, navigate to previous item on list
-- else, revert to default behavior
['<S-Tab>'] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_prev_item(cmp_select_opts)
else
fallback()
end
end, {'i', 's'}),
}
}
cmp.setup(cmp_config)
lsp config plugin#
mason-config-lsp
代码Nav#
- 函数引用
- 调用图
- 函数签名
- 错误提示
- Code Action
- Format
keyshort#
key | description | mode |
---|---|---|
K | hover information | normal |
gd | go to definition | normal |
gD | go to declaration | normal |
gr | go to references | normal |
gI | go to implementation | normal |
gs | show signature help | normal |
gl | show line diagnostics | normal |
mason-null-ls.nvim#
与VS Code和coc.nvim生态系统不同,Neovim没有为非LSP源提供连接到其LSP客户端的方法。null-ls试图弥合这一差距,并简化使用纯Lua创建、共享和设置LSP源的过程。
nullls还试图减少设置通用语言服务器所需的样板,并通过消除对外部进程的需要来提高性能。
null-ls.nvim#
Features#
- null-ls sources are able to hook into the following LSP features:
- Code actions
- Diagnostics (file- and project-level)
- Formatting (including range formatting)
- Hover
- Completion
:NullLsInstall
auto completion#
keymap | action |
---|---|
tr | toggle trouble.nvim |
leader+t | telescope find_files |
### LSP | |
https://blog.codeminer42.com/configuring-language-server-protocol-in-neovim/ |
vim-sursound#
keymap | action |
---|---|
ysiw' | 用单括号包围选区 |
dsiw | 删除包裹 |
visual模式下, |
先用野火包围选区,再用大S加符号包裹之 |
vim-sandwich#
keymap | action | |
---|---|---|
saiw | 包裹word | |
sriw | 替换word的包裹 | |
srb | 替换cursor所在的包裹 | |
sdiw | 删除word包裹 | |
sdb | 删除cursor所在的包裹 | |
saiwf+函数名字 | 包裹文字并作为要创建的方法的参数 | > |
参考#
https://github.com/BurntSushi/ripgrep
https://github.com/nvim-telescope/telescope.nvim
https://github.com/wbthomason/packer.nvim
https://www.youtube.com/watch?v=SpexCBrZ1pQ
https://github.com/nvim-tree/nvim-tree.lua/blob/master/doc/nvim-tree-lua.txt
https://www.lunarvim.org/
https://devhints.io/vim
https://www.youtube.com/watch?v=-InmtHhk2qM
https://joereynoldsaudio.com/2020/01/22/vim-sandwich-is-better-than-surround.html
https://github.com/machakann/vim-sandwich/blob/master/doc/sandwich.txt
https://neovim.io/doc/user/lua.html#lua-highlight
https://raw.githubusercontent.com/nvim-lua/kickstart.nvim/master/init.lua
https://microsoft.github.io/language-server-protocol/implementors/servers/
https://github.com/VonHeikemen/lsp-zero.nvim
https://www.youtube.com/watch?v=vdn_pKJUda8&t=117s
https://user-images.githubusercontent.com/17254073/195207023-7b709e35-7f10-416b-aafb-5bb61268c7d3.png
https://github.com/VonHeikemen/lsp-zero.nvim/wiki/Under-the-hood
https://github.com/jose-elias-alvarez/null-ls.nvim/blob/main/doc/BUILTINS.md(null-ls的一些内置源)
https://til.hashrocket.com/posts/619fdc96ed-running-same-vim-command-into-multiple-lines(在comnand模式执行 映射命令)
https://programmingpercy.tech/blog/learn-how-to-use-neovim-as-ide/
https://github.com/andymass/vim-matchup(eshaced %)
https://linuxize.com/post/vim-find-replace/#basic-find-and-replace(nvim replace)