nvim: Switch nvim-cmp for blink.cmp completion
Switched completion engines. Blink is supposedly faster and so on but what I really love is the batteries-included style. I don't have to set up the basic lsp, path, buffer and cmdline completions, nor styling for basic kind displays and more. Hundreds of lines of config shrink down to 60, very nice.
This commit is contained in:
parent
2618eb55b8
commit
3a10d7a849
2 changed files with 73 additions and 296 deletions
nvim/.config/nvim/lua/plugins
|
@ -1,287 +1,63 @@
|
|||
local is_available = require("core.util").is_available
|
||||
|
||||
local completion_engine = {
|
||||
{
|
||||
"hrsh7th/nvim-cmp",
|
||||
branch = "main",
|
||||
version = false, -- new releases (>2022) are sadly not versioned
|
||||
dependencies = {
|
||||
-- TODO: Move to lsp
|
||||
"hrsh7th/cmp-nvim-lsp",
|
||||
"hrsh7th/cmp-nvim-lsp-signature-help",
|
||||
"hrsh7th/cmp-path",
|
||||
"hrsh7th/cmp-buffer",
|
||||
"hrsh7th/cmp-calc",
|
||||
"hrsh7th/cmp-cmdline",
|
||||
-- TODO: Move me into a separate load?
|
||||
"cbarrete/completion-vcard",
|
||||
"f3fora/cmp-spell",
|
||||
"jc-doyle/cmp-pandoc-references",
|
||||
-- TODO: Decide: get rid or just enable in very specific circumstances
|
||||
"lukas-reineke/cmp-rg",
|
||||
-- TODO: Move to treesitter
|
||||
{ "ray-x/cmp-treesitter", dependencies = { "nvim-treesitter/nvim-treesitter" } },
|
||||
},
|
||||
opts = function()
|
||||
local cmp = require("cmp")
|
||||
-- style 'ghosttext' which appears behind cursor, showing current completion
|
||||
vim.api.nvim_set_hl(0, "CmpGhostText", { link = "Comment", default = true })
|
||||
|
||||
local has_words_before = function()
|
||||
---@diagnostic disable-next-line:deprecated
|
||||
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
|
||||
return col ~= 0
|
||||
and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
|
||||
end
|
||||
|
||||
local kind_icons = {
|
||||
Text = "",
|
||||
Method = "",
|
||||
Function = "",
|
||||
Constructor = "",
|
||||
Field = "",
|
||||
Variable = "",
|
||||
Class = "",
|
||||
Interface = "",
|
||||
Module = "",
|
||||
Property = "",
|
||||
Unit = "",
|
||||
Value = "V",
|
||||
Enum = "",
|
||||
Keyword = "",
|
||||
Snippet = "",
|
||||
Color = "",
|
||||
File = "",
|
||||
Reference = "",
|
||||
Folder = "",
|
||||
EnumMember = "",
|
||||
Constant = "",
|
||||
Struct = "",
|
||||
Event = "",
|
||||
Operator = "",
|
||||
TypeParameter = "",
|
||||
}
|
||||
|
||||
-- `/` cmdline setup.
|
||||
cmp.setup.cmdline("/", {
|
||||
completion = { completeopt = "menu,menuone,noinsert,noselect" },
|
||||
preselect = cmp.PreselectMode.None,
|
||||
mapping = cmp.mapping.preset.cmdline(),
|
||||
sources = { { name = "buffer" } },
|
||||
})
|
||||
-- `:` cmdline setup.
|
||||
cmp.setup.cmdline(":", {
|
||||
completion = { completeopt = "menu,menuone,noinsert,noselect" },
|
||||
preselect = cmp.PreselectMode.None,
|
||||
mapping = cmp.mapping.preset.cmdline(),
|
||||
sources = cmp.config.sources({ { name = "path" } }, {
|
||||
{ name = "cmdline", option = { ignore_cmds = { "Man", "!" } } },
|
||||
}),
|
||||
})
|
||||
return {
|
||||
window = { documentation = cmp.config.window.bordered() },
|
||||
-- add noselect to not automatically select first item
|
||||
completion = { completeopt = "menu,menuone,noinsert" },
|
||||
preselect = cmp.PreselectMode.Item, -- not sure what this changes diff than above?
|
||||
experimental = {
|
||||
ghost_text = {
|
||||
hl_group = "CmpGhostText",
|
||||
},
|
||||
},
|
||||
sources = {
|
||||
{ name = "nvim_lsp" },
|
||||
{ name = "nvim_lsp_signature_help" },
|
||||
{ name = "pandoc_references" },
|
||||
{ name = "calc" },
|
||||
{ name = "path" },
|
||||
{ name = "buffer", keyword_length = 3 },
|
||||
{ name = "spell", keyword_length = 3 },
|
||||
-- { name = 'rg', keyword_length = 5 },
|
||||
{ name = "vCard" },
|
||||
},
|
||||
mapping = cmp.mapping.preset.insert({
|
||||
["<C-b>"] = cmp.mapping.scroll_docs(-4),
|
||||
["<C-f>"] = cmp.mapping.scroll_docs(4),
|
||||
["<CR>"] = cmp.mapping({
|
||||
i = function(fallback)
|
||||
if cmp.visible() and cmp.get_active_entry() then
|
||||
cmp.confirm({
|
||||
behavior = cmp.ConfirmBehavior.Replace,
|
||||
select = false,
|
||||
})
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end,
|
||||
s = cmp.mapping.confirm({ select = true }),
|
||||
c = cmp.mapping.confirm({
|
||||
behavior = cmp.ConfirmBehavior.Replace,
|
||||
select = false,
|
||||
}), -- disable selection in cmd mode
|
||||
}),
|
||||
["<Tab>"] = cmp.mapping(function(fallback)
|
||||
-- expand_or_jumpable() will always jump
|
||||
-- expand_or_locally_jumpable() only jumps when still inside snippet region
|
||||
if cmp.visible() then
|
||||
cmp.select_next_item()
|
||||
elseif has_words_before() then
|
||||
cmp.complete()
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end, { "i", "s" }),
|
||||
["<S-Tab>"] = cmp.mapping(function(fallback)
|
||||
if cmp.visible() then
|
||||
cmp.select_prev_item()
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end, { "i", "s" }),
|
||||
}),
|
||||
formatting = {
|
||||
expandable_indicator = true,
|
||||
fields = { "kind", "abbr", "menu" },
|
||||
format = function(entry, vim_item)
|
||||
-- Kind icons, removing kind text leaving only icon
|
||||
-- vim_item.kind = string.format('%s %s', kind_icons[vim_item.kind], vim_item.kind)
|
||||
vim_item.kind = string.format("%s", kind_icons[vim_item.kind])
|
||||
|
||||
-- Source
|
||||
vim_item.menu = ({
|
||||
buffer = "",
|
||||
calc = "",
|
||||
digraphs = "∬",
|
||||
latex_symbols = "𝓧",
|
||||
luasnip = "",
|
||||
nvim_lsp = "ℒ",
|
||||
nvim_lua = "",
|
||||
pandoc_references = "",
|
||||
spell = "",
|
||||
vCard = "",
|
||||
})[entry.source.name]
|
||||
return vim_item
|
||||
end,
|
||||
},
|
||||
}
|
||||
end,
|
||||
event = { "InsertEnter", "CmdlineEnter" },
|
||||
},
|
||||
}
|
||||
--
|
||||
-- TODO: Enable more lazy loaded startup? And integrate into
|
||||
-- cmp as insert source instead of in its setup config below.
|
||||
local snippet_engine = {
|
||||
"nvim-cmp",
|
||||
dependencies = {
|
||||
"L3MON4D3/LuaSnip",
|
||||
"rafamadriz/friendly-snippets",
|
||||
"saadparwaiz1/cmp_luasnip",
|
||||
{
|
||||
"benfowler/telescope-luasnip.nvim",
|
||||
dependencies = { { "nvim-telescope/telescope.nvim", optional = true } },
|
||||
config = function()
|
||||
if is_available("telescope") then
|
||||
require("telescope").load_extension("luasnip")
|
||||
end
|
||||
end,
|
||||
},
|
||||
{ "hrsh7th/nvim-cmp", optional = true },
|
||||
},
|
||||
event = { "InsertEnter" },
|
||||
build = "make install_jsregexp",
|
||||
opts = function(_, opts)
|
||||
local cmp = require("cmp")
|
||||
local luasnip = require("luasnip")
|
||||
|
||||
require("luasnip.loaders.from_vscode").lazy_load({ exclude = { "markdown", "quarto" } })
|
||||
require("luasnip.loaders.from_snipmate").lazy_load()
|
||||
|
||||
opts.snippet = {
|
||||
expand = function(item)
|
||||
require("luasnip").lsp_expand(item.body)
|
||||
end,
|
||||
}
|
||||
local has_words_before = function()
|
||||
---@diagnostic disable-next-line:deprecated
|
||||
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
|
||||
return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
|
||||
end
|
||||
|
||||
table.insert(opts.sources, { name = "luasnip", keyword_length = 1 })
|
||||
|
||||
opts.mapping["<Tab>"] = cmp.mapping(function(fallback) -- expand_or_jumpable() will always jump
|
||||
-- expand_or_locally_jumpable() only jumps when still inside snippet region
|
||||
if luasnip.expand_or_locally_jumpable() then
|
||||
luasnip.expand_or_jump()
|
||||
elseif cmp.visible() then
|
||||
cmp.select_next_item()
|
||||
elseif has_words_before() then
|
||||
cmp.complete()
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end, { "i", "s" })
|
||||
opts.mapping["<S-Tab>"] = cmp.mapping(function(fallback)
|
||||
if luasnip.locally_jumpable(-1) then
|
||||
luasnip.jump(-1)
|
||||
elseif cmp.visible() then
|
||||
cmp.select_prev_item()
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end, { "i", "s" })
|
||||
end,
|
||||
}
|
||||
|
||||
local beancount_cmp = {
|
||||
"nvim-cmp",
|
||||
dependencies = {
|
||||
"crispgm/cmp-beancount",
|
||||
},
|
||||
ft = "beancount",
|
||||
opts = function(_, opts)
|
||||
-- FIXME: Find a way to dynamically derive environment
|
||||
vim.g.python3_host_prog = os.getenv("HOME") .. "/.local/pipx/venvs/beancount/bin/python"
|
||||
table.insert(opts.sources, {
|
||||
name = "beancount",
|
||||
})
|
||||
end,
|
||||
}
|
||||
|
||||
local latex_cmp = {
|
||||
"nvim-cmp",
|
||||
dependencies = {
|
||||
-- TODO: Needs better lazy loading
|
||||
"kdheepak/cmp-latex-symbols",
|
||||
},
|
||||
event = "CursorHold",
|
||||
opts = function(_, opts)
|
||||
table.insert(opts.sources, { name = "latex_symbols" })
|
||||
end,
|
||||
}
|
||||
|
||||
local markdown_cmp = {}
|
||||
-- FIXME: Currently always set to true but should ideally
|
||||
-- recognize if we have render-markdown available or not
|
||||
if is_available("render-markdown") or true then
|
||||
markdown_cmp = {
|
||||
"nvim-cmp",
|
||||
dependencies = {
|
||||
{ "MeanderingProgrammer/render-markdown.nvim", main = "render-markdown", optional = true },
|
||||
},
|
||||
ft = "markdown",
|
||||
opts = function(_, opts)
|
||||
table.insert(opts.sources, {
|
||||
name = "render-markdown",
|
||||
})
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
return {
|
||||
completion_engine,
|
||||
snippet_engine,
|
||||
beancount_cmp,
|
||||
latex_cmp,
|
||||
markdown_cmp,
|
||||
-- full documentation here: https://cmp.saghen.dev/
|
||||
"saghen/blink.cmp",
|
||||
dependencies = {
|
||||
"saghen/blink.compat",
|
||||
"rafamadriz/friendly-snippets",
|
||||
"hrsh7th/cmp-calc",
|
||||
"f3fora/cmp-spell",
|
||||
{ "aspeddro/cmp-pandoc.nvim", opts = {
|
||||
filetypes = { "pandoc", "markdown", "quarto", "rmd" },
|
||||
} },
|
||||
},
|
||||
lazy = false,
|
||||
opts = {
|
||||
keymap = { preset = "default" },
|
||||
|
||||
appearance = {
|
||||
-- Sets the fallback highlight groups to nvim-cmp's highlight groups
|
||||
-- Useful for when your theme doesn't support blink.cmp
|
||||
-- Will be removed in a future release
|
||||
use_nvim_cmp_as_default = true,
|
||||
-- Set to 'mono' for 'Nerd Font Mono' or 'normal' for 'Nerd Font'
|
||||
-- Adjusts spacing to ensure icons are aligned
|
||||
nerd_font_variant = "mono",
|
||||
},
|
||||
completion = {
|
||||
documentation = { auto_show = true, auto_show_delay_ms = 500 },
|
||||
-- ghost_text = { enabled = true },
|
||||
},
|
||||
signature = {
|
||||
enabled = true,
|
||||
},
|
||||
|
||||
-- Default list of enabled providers defined so that you can extend it
|
||||
-- elsewhere in your config, without redefining it, due to `opts_extend`
|
||||
sources = {
|
||||
default = {
|
||||
"pandoc",
|
||||
"calc",
|
||||
"lsp",
|
||||
"path",
|
||||
"snippets",
|
||||
"buffer",
|
||||
"spell",
|
||||
},
|
||||
providers = {
|
||||
calc = {
|
||||
name = "calc",
|
||||
module = "blink.compat.source",
|
||||
},
|
||||
spell = {
|
||||
name = "spell",
|
||||
module = "blink.compat.source",
|
||||
},
|
||||
pandoc = {
|
||||
name = "cmp_pandoc",
|
||||
module = "blink.compat.source",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
opts_extend = { "sources.default" },
|
||||
}
|
||||
|
|
|
@ -12,17 +12,18 @@ return {
|
|||
},
|
||||
dependencies = {
|
||||
{ "Bilal2453/luvit-meta" }, -- optional `vim.uv` typings
|
||||
{ -- optional completion source for require statements and module annotations
|
||||
"hrsh7th/nvim-cmp",
|
||||
opts = function(_, opts)
|
||||
opts.sources = opts.sources or {}
|
||||
table.insert(opts.sources, {
|
||||
name = "lazydev",
|
||||
group_index = 0, -- set group index to 0 to skip loading LuaLS completions
|
||||
})
|
||||
end,
|
||||
optional = true,
|
||||
},
|
||||
-- FIXME: Set up to work with blink.cmp
|
||||
-- { -- optional completion source for require statements and module annotations
|
||||
-- "hrsh7th/nvim-cmp",
|
||||
-- opts = function(_, opts)
|
||||
-- opts.sources = opts.sources or {}
|
||||
-- table.insert(opts.sources, {
|
||||
-- name = "lazydev",
|
||||
-- group_index = 0, -- set group index to 0 to skip loading LuaLS completions
|
||||
-- })
|
||||
-- end,
|
||||
-- optional = true,
|
||||
-- },
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue