nvim/lua/plugs/nvim-cmp.lua

153 lines
4.9 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

return {
{
-- lsp补全
"hrsh7th/nvim-cmp",
dependencies = {
'hrsh7th/cmp-nvim-lsp',
'hrsh7th/cmp-buffer',
'hrsh7th/cmp-path',
'hrsh7th/cmp-cmdline',
{
'hrsh7th/vim-vsnip',
config = function()
G.g.vsnip_snippet_dir = G.fn.stdpath("config") .. "/snippets"
end
},
'hrsh7th/cmp-vsnip',
'onsails/lspkind-nvim',
},
config = function()
local has_words_before = function()
local cursor = G.api.nvim_win_get_cursor(0)
local line, col = cursor[1], cursor[2]
return col ~= 0 and G.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match('%s') == nil
end
local feedkey = function(key, mode)
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true)
end
local cmp = require('cmp')
local cmp_opt = {
snippet = {
expand = function(args)
vim.fn["vsnip#anonymous"](args.body)
end,
},
-- 补全来源优先级LSP > 片段 > buffer > 路径
sources = cmp.config.sources({
{ name = 'nvim_lsp' },
{ name = 'vsnip' },
},
{ name = 'buffer' },
{ name = 'path' }
),
-- 插入模式映射C-n/C-p 选择CR 未选时换行(避免冲突 Copilot 的 Tab
mapping = cmp.mapping.preset.insert({
-- 回车:手动选择后确认,未选时 fallback 到换行
["<CR>"] = cmp.mapping({
i = cmp.mapping.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = false }),
c = function(fallback)
if cmp.visible() then
cmp.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = false })
else
fallback()
end
end,
}),
-- C-n选下一个补全项 / 展开 vsnip 占位 / 手动触发补全
["<C-n>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item()
elseif vim.fn["vsnip#available"](1) == 1 then
feedkey("<Plug>(vsnip-expand-or-jump)", "")
elseif has_words_before() then
cmp.complete()
else
fallback()
end
end, { "i", "s" }),
["<C-p>"] = cmp.mapping(function()
if cmp.visible() then
cmp.select_prev_item()
elseif vim.fn["vsnip#jumpable"](-1) == 1 then
feedkey("<Plug>(vsnip-jump-prev)", "")
end
end, { "i", "s" }),
}),
window = {
completion = {
winhighlight = "Normal:Pmenu,FloatBorder:Pmenu,Search:None",
col_offset = -3,
side_padding = 0,
border = "rounded",
scrollbar = false,
},
documentation = {
winhighlight = "Normal:Pmenu,FloatBorder:Pmenu,Search:None",
border = "rounded",
scrollbar = false,
},
},
formatting = {
fields = { "kind", "abbr", "menu" },
format = function(entry, vim_item)
local kind = require("lspkind").cmp_format({ mode = "symbol_text", maxwidth = 50, })(entry, vim_item)
local strings = vim.split(kind.kind, "%s", { trimempty = true })
kind.kind = " " .. (strings[1] or "") .. " "
kind.menu = " (" .. (strings[2] or "") .. ")"
return kind
end,
},
}
require('cmp').setup(cmp_opt)
-- 命令栏补全Tab 导航,回车时若有手动选择则确认,否则直接执行命令(不卡住)
require('cmp').setup.cmdline(':', {
mapping = {
['<Tab>'] = cmp.mapping(cmp.mapping.select_next_item(), { 'c' }),
['<S-Tab>'] = cmp.mapping(cmp.mapping.select_prev_item(), { 'c' }),
['<CR>'] = cmp.mapping({
c = function(fallback)
if cmp.visible() and cmp.get_active_entry() then
cmp.confirm({ select = false })
else
fallback() -- 没选的时候 fallback = 直接执行命令
end
end,
}),
},
sources = {
{ name = 'cmdline' },
{ name = 'path' },
}
})
-- 搜索栏补全
require('cmp').setup.cmdline('/', {
mapping = {
['<Tab>'] = cmp.mapping(cmp.mapping.select_next_item(), { 'c' }),
['<S-Tab>'] = cmp.mapping(cmp.mapping.select_prev_item(), { 'c' }),
['<CR>'] = cmp.mapping({
c = function(fallback)
if cmp.visible() and cmp.get_active_entry() then
cmp.confirm({ select = false })
else
fallback()
end
end,
}),
},
sources = {
{ name = 'buffer' },
}
})
end,
},
}