From fedd230111d216d47784ac50918ca7c14211f054 Mon Sep 17 00:00:00 2001 From: Fernando Schauenburg Date: Mon, 12 Feb 2024 00:35:44 +0100 Subject: [PATCH] vim: refactor completion to make it more maintainable --- .../nvim/lua/fschauen/plugins/completion.lua | 90 +++++++++---------- 1 file changed, 43 insertions(+), 47 deletions(-) diff --git a/config/nvim/lua/fschauen/plugins/completion.lua b/config/nvim/lua/fschauen/plugins/completion.lua index 5d04d92..85f853f 100644 --- a/config/nvim/lua/fschauen/plugins/completion.lua +++ b/config/nvim/lua/fschauen/plugins/completion.lua @@ -12,59 +12,59 @@ M.dependencies = { 'saadparwaiz1/cmp_luasnip', } -M.event = 'InsertEnter' +M.event = { + 'CmdlineEnter', + 'InsertEnter', +} -local repeat_mapping = function(value, keys) - local tbl = {} - for _, k in ipairs(keys) do tbl[k] = value end - return tbl -end +local make_keymap = function(cmp) + local select = { behavior = cmp.SelectBehavior.Select } -local transform_keymap = function(mappings, modes) - modes = modes or 'n' - modes = type(modes) == 'table' and modes or { modes } - local tbl = {} - for lhs, rhs in pairs(mappings) do - tbl[lhs] = repeat_mapping(rhs, modes) + local either = function(yes, no) + return function(fallback) + if cmp.visible() then yes(fallback) else no(fallback) end + end end - return tbl -end -local cond = function(condition, yes, no) - return function(fallback) - if condition() then yes(fallback) else no(fallback) end + -- Mappings that should work in both command line and Insert mode. + local common = { + [''] = either(cmp.mapping.select_next_item(select), cmp.mapping.complete()), + [''] = either(cmp.mapping.select_prev_item(select), cmp.mapping.complete()), + + [''] = cmp.mapping.select_next_item(select), + [''] = cmp.mapping.select_prev_item(select), + + [''] = cmp.mapping.scroll_docs( 3), + [''] = cmp.mapping.scroll_docs( 3), + [''] = cmp.mapping.scroll_docs(-3), + [''] = cmp.mapping.scroll_docs(-3), + + [''] = cmp.mapping.abort(), + [''] = cmp.mapping.confirm { select = true }, + } + + -- I want to start completion on the command line, but not in Insert. + local keymap = { + [''] = { + i = either(cmp.mapping.confirm { select = true }, function(fallback) fallback() end), + c = either(cmp.mapping.confirm { select = true }, cmp.mapping.complete()), + } + } + + -- Turn { lhs = rhs } into { lhs = { i = rhs, c = rhs } }. + for lhs, rhs in pairs(common) do + keymap[lhs] = { i = rhs, c = rhs } end + + return cmp.mapping.preset.insert(keymap) end M.config = function() local cmp = require 'cmp' - local map = cmp.mapping - - local keymap = { - [''] = cond(cmp.visible, - map.select_next_item { behavior = cmp.SelectBehavior.Select }, - map.complete()), - [''] = cond(cmp.visible, - map.select_prev_item { behavior = cmp.SelectBehavior.Select }, - map.complete()), - - [''] = map.select_next_item { behavior = cmp.SelectBehavior.Select }, - [''] = map.select_prev_item { behavior = cmp.SelectBehavior.Select }, - - [''] = map.scroll_docs( 3), - [''] = map.scroll_docs( 3), - [''] = map.scroll_docs(-3), - [''] = map.scroll_docs(-3), - - [''] = map.abort(), - [''] = map.confirm { select = true }, - [''] = cond(cmp.visible, - map.confirm { select = true }, - function(fallback) fallback() end), - } + local keymap = make_keymap(cmp) cmp.setup { - mapping = transform_keymap(keymap, 'i'), + mapping = keymap, enabled = function() local c = require 'cmp.config.context' @@ -113,11 +113,7 @@ M.config = function() } cmp.setup.cmdline(':', { - mapping = transform_keymap( - vim.tbl_extend('force', keymap, { - [''] = cond(cmp.visible, map.confirm {select = true }, map.complete()), - }), - 'c'), + mapping = keymap, completion = { autocomplete = false,