nvim: Refactor completion plugins
Begin a larger refactor with nvim-cmp, which separates out the different nvim-cmp modules to be loaded at different times and for different files (such as beancount completion on loaded for beancount files and so on). This is by no means complete but the start of a larger overhaul process.
This commit is contained in:
parent
7723f43a5b
commit
3e369ee31e
1 changed files with 143 additions and 70 deletions
|
@ -1,53 +1,29 @@
|
||||||
return {
|
local completion_engine = {
|
||||||
-- completion setup
|
|
||||||
{
|
{
|
||||||
"hrsh7th/nvim-cmp",
|
"hrsh7th/nvim-cmp",
|
||||||
branch = "main",
|
branch = "main",
|
||||||
version = false,
|
version = false, -- new releases (>2022) are sadly not versioned
|
||||||
dependencies = {
|
dependencies = {
|
||||||
"andersevenrud/cmp-tmux",
|
-- TODO: Move to lsp
|
||||||
"cbarrete/completion-vcard",
|
|
||||||
"f3fora/cmp-spell",
|
|
||||||
"hrsh7th/cmp-nvim-lsp",
|
"hrsh7th/cmp-nvim-lsp",
|
||||||
|
"hrsh7th/cmp-nvim-lsp-signature-help",
|
||||||
"hrsh7th/cmp-path",
|
"hrsh7th/cmp-path",
|
||||||
"hrsh7th/cmp-buffer",
|
"hrsh7th/cmp-buffer",
|
||||||
"hrsh7th/cmp-calc",
|
"hrsh7th/cmp-calc",
|
||||||
"hrsh7th/cmp-cmdline",
|
"hrsh7th/cmp-cmdline",
|
||||||
"hrsh7th/cmp-nvim-lsp-signature-help",
|
-- TODO: Move me into a separate load?
|
||||||
"dmitmel/cmp-digraphs",
|
"cbarrete/completion-vcard",
|
||||||
|
"f3fora/cmp-spell",
|
||||||
"jc-doyle/cmp-pandoc-references",
|
"jc-doyle/cmp-pandoc-references",
|
||||||
"kdheepak/cmp-latex-symbols",
|
-- TODO: Decide: get rid or just enable in very specific circumstances
|
||||||
"lukas-reineke/cmp-rg",
|
"lukas-reineke/cmp-rg",
|
||||||
"crispgm/cmp-beancount",
|
-- TODO: Move to treesitter
|
||||||
{ "ray-x/cmp-treesitter", dependencies = { "nvim-treesitter/nvim-treesitter" } },
|
{ "ray-x/cmp-treesitter", dependencies = { "nvim-treesitter/nvim-treesitter" } },
|
||||||
{
|
|
||||||
"saadparwaiz1/cmp_luasnip",
|
|
||||||
dependencies = {
|
|
||||||
|
|
||||||
{
|
|
||||||
"L3MON4D3/LuaSnip",
|
|
||||||
dependencies = {
|
|
||||||
"rafamadriz/friendly-snippets",
|
|
||||||
{
|
|
||||||
"benfowler/telescope-luasnip.nvim",
|
|
||||||
dependencies = { { "nvim-telescope/telescope.nvim", optional = true } },
|
|
||||||
config = function()
|
|
||||||
require("telescope").load_extension("luasnip")
|
|
||||||
end,
|
|
||||||
},
|
},
|
||||||
},
|
opts = function()
|
||||||
build = "make install_jsregexp",
|
|
||||||
config = function()
|
|
||||||
require("luasnip.loaders.from_vscode").lazy_load({ exclude = { "markdown", "quarto" } })
|
|
||||||
require("luasnip.loaders.from_snipmate").lazy_load()
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
config = function()
|
|
||||||
local luasnip = require("luasnip")
|
|
||||||
local cmp = require("cmp")
|
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()
|
local has_words_before = function()
|
||||||
---@diagnostic disable-next-line:deprecated
|
---@diagnostic disable-next-line:deprecated
|
||||||
|
@ -84,32 +60,42 @@ return {
|
||||||
TypeParameter = "",
|
TypeParameter = "",
|
||||||
}
|
}
|
||||||
|
|
||||||
cmp.setup({
|
-- `/` 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() },
|
window = { documentation = cmp.config.window.bordered() },
|
||||||
snippet = {
|
-- add noselect to not automatically select first item
|
||||||
expand = function(args)
|
completion = { completeopt = "menu,menuone,noinsert" },
|
||||||
require("luasnip").lsp_expand(args.body)
|
preselect = cmp.PreselectMode.Item, -- not sure what this changes diff than above?
|
||||||
end,
|
experimental = {
|
||||||
|
ghost_text = {
|
||||||
|
hl_group = "CmpGhostText",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
sources = {
|
sources = {
|
||||||
{
|
|
||||||
name = "beancount",
|
|
||||||
option = {
|
|
||||||
account = vim.env["HOME"] .. "/documents/records/budget/main.beancount", -- TODO implement dynamically
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{ name = "nvim_lsp" },
|
{ name = "nvim_lsp" },
|
||||||
{ name = "nvim_lsp_signature_help" },
|
{ name = "nvim_lsp_signature_help" },
|
||||||
{ name = "luasnip", keyword_length = 1 },
|
|
||||||
{ name = "pandoc_references" },
|
{ name = "pandoc_references" },
|
||||||
{ name = "calc" },
|
{ name = "calc" },
|
||||||
{ name = "path" },
|
{ name = "path" },
|
||||||
{ name = "buffer", keyword_length = 3 },
|
{ name = "buffer", keyword_length = 3 },
|
||||||
{ name = "latex_symbols" },
|
|
||||||
{ name = "spell", keyword_length = 3 },
|
{ name = "spell", keyword_length = 3 },
|
||||||
{ name = "tmux" }, -- { name = 'rg', keyword_length = 5 },
|
-- { name = 'rg', keyword_length = 5 },
|
||||||
{ name = "vCard" },
|
{ name = "vCard" },
|
||||||
{ name = "digraphs", keyword_length = 2 },
|
|
||||||
},
|
},
|
||||||
mapping = cmp.mapping.preset.insert({
|
mapping = cmp.mapping.preset.insert({
|
||||||
["<C-b>"] = cmp.mapping.scroll_docs(-4),
|
["<C-b>"] = cmp.mapping.scroll_docs(-4),
|
||||||
|
@ -134,9 +120,7 @@ return {
|
||||||
["<Tab>"] = cmp.mapping(function(fallback)
|
["<Tab>"] = cmp.mapping(function(fallback)
|
||||||
-- expand_or_jumpable() will always jump
|
-- expand_or_jumpable() will always jump
|
||||||
-- expand_or_locally_jumpable() only jumps when still inside snippet region
|
-- expand_or_locally_jumpable() only jumps when still inside snippet region
|
||||||
if luasnip.expand_or_locally_jumpable() then
|
if cmp.visible() then
|
||||||
luasnip.expand_or_jump()
|
|
||||||
elseif cmp.visible() then
|
|
||||||
cmp.select_next_item()
|
cmp.select_next_item()
|
||||||
elseif has_words_before() then
|
elseif has_words_before() then
|
||||||
cmp.complete()
|
cmp.complete()
|
||||||
|
@ -145,9 +129,7 @@ return {
|
||||||
end
|
end
|
||||||
end, { "i", "s" }),
|
end, { "i", "s" }),
|
||||||
["<S-Tab>"] = cmp.mapping(function(fallback)
|
["<S-Tab>"] = cmp.mapping(function(fallback)
|
||||||
if luasnip.jumpable(-1) then
|
if cmp.visible() then
|
||||||
luasnip.jump(-1)
|
|
||||||
elseif cmp.visible() then
|
|
||||||
cmp.select_prev_item()
|
cmp.select_prev_item()
|
||||||
else
|
else
|
||||||
fallback()
|
fallback()
|
||||||
|
@ -178,20 +160,111 @@ return {
|
||||||
return vim_item
|
return vim_item
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
})
|
}
|
||||||
-- `/` cmdline setup.
|
|
||||||
cmp.setup.cmdline("/", {
|
|
||||||
mapping = cmp.mapping.preset.cmdline(),
|
|
||||||
sources = { { name = "buffer" } },
|
|
||||||
})
|
|
||||||
-- `:` cmdline setup.
|
|
||||||
cmp.setup.cmdline(":", {
|
|
||||||
mapping = cmp.mapping.preset.cmdline(),
|
|
||||||
sources = cmp.config.sources({ { name = "path" } }, {
|
|
||||||
{ name = "cmdline", option = { ignore_cmds = { "Man", "!" } } },
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
end,
|
end,
|
||||||
event = { "InsertEnter", "CmdlineEnter" },
|
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 require("core.util").is_available("telescope") then
|
||||||
|
require("telescope").load_extension("luasnip")
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
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)
|
||||||
|
vim.g.python3_host_prog = "/home/marty/.local/pipx/venvs/beancount/bin/python"
|
||||||
|
table.insert(opts.sources, {
|
||||||
|
name = "beancount",
|
||||||
|
-- option = {
|
||||||
|
-- -- TODO: implement dynamically
|
||||||
|
-- -- I believe if we don't supply this it automatically takes
|
||||||
|
-- -- from the open file which would be good enough
|
||||||
|
-- account = "/home/marty/documents/records/budget/main.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,
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
completion_engine,
|
||||||
|
snippet_engine,
|
||||||
|
beancount_cmp,
|
||||||
|
latex_cmp
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue