diff --git a/config/nvim/lua/fschauen/completion.lua b/config/nvim/lua/fschauen/completion.lua new file mode 100644 index 0000000..8012dbf --- /dev/null +++ b/config/nvim/lua/fschauen/completion.lua @@ -0,0 +1,44 @@ +local M = {} + +local cmp = function() + return require 'cmp' +end + +M.select_next_or_complete = function(fallback) + local func = cmp().visible() + and cmp().mapping.select_next_item { behavior = cmp().SelectBehavior.Select } + or cmp().mapping.complete() + func(fallback) +end + +M.select_prev_or_complete = function(fallback) + local func = cmp().visible() + and cmp().mapping.select_prev_item { behavior = cmp().SelectBehavior.Select } + or cmp().mapping.complete() + func(fallback) +end + +M.select_next_item = function(fallback) + cmp().mapping.select_next_item({ behavior = cmp().SelectBehavior.Select })(fallback) +end + +M.select_prev_item = function(fallback) + cmp().mapping.select_prev_item({ behavior = cmp().SelectBehavior.Select })(fallback) +end + +M.scroll_docs = function(delta) + return function(fallback) + cmp().mapping.scroll_docs(delta)(fallback) + end +end + +M.abort = function(fallback) + cmp().mapping.abort()(fallback) +end + +M.confirm = function(fallback) + cmp().mapping.confirm({ select = true })(fallback) +end + +return M + diff --git a/config/nvim/lua/fschauen/keymap.lua b/config/nvim/lua/fschauen/keymap.lua index aff0aeb..999680a 100644 --- a/config/nvim/lua/fschauen/keymap.lua +++ b/config/nvim/lua/fschauen/keymap.lua @@ -3,6 +3,7 @@ local M = {} local diagnostic = require 'fschauen.diagnostic' local window = require 'fschauen.window' local pick = require('fschauen.telescope').pickers +local completion = require 'fschauen.completion' local toggle_number = function() vim.wo.number = not vim.wo.number @@ -82,6 +83,21 @@ local keymap = { { '', '', mode = 'c' }, { '', '', mode = 'c' }, + completion = { + {'' , completion.select_next_or_complete, mode = { 'i', 'c' }, desc = '󰁨 Complete: select next'}, + {'' , completion.select_prev_or_complete, mode = { 'i', 'c' }, desc = '󰁨 Complete: select previous'}, + {'' , completion.select_next_item, mode = { 'i', 'c' }, desc = '󰁨 Complete: select next'}, + {'' , completion.select_prev_item, mode = { 'i', 'c' }, desc = '󰁨 Complete: select previous'}, + + {'' , completion.scroll_docs(-3), mode = { 'i', 'c' }, desc = '󰁨 Complete: scroll docs down'}, + {'' , completion.scroll_docs(-3), mode = { 'i', 'c' }, desc = '󰁨 Complete: scroll docs down'}, + {'' , completion.scroll_docs( 3), mode = { 'i', 'c' }, desc = '󰁨 Complete: scroll docs up'}, + {'' , completion.scroll_docs( 3), mode = { 'i', 'c' }, desc = '󰁨 Complete: scroll docs up'}, + + {'' , completion.abort, mode = { 'i', 'c' }, desc = '󰁨 Complete: abort'}, + {'' , completion.confirm, mode = { 'i', 'c' }, desc = '󰁨 Complete: confirm'}, + }, + -- quickly change background { 'bg', [[let &background = &background ==? 'light' ? 'dark' : 'light']] }, diff --git a/config/nvim/lua/fschauen/plugins/completion.lua b/config/nvim/lua/fschauen/plugins/completion.lua index 65e244b..225fbfd 100644 --- a/config/nvim/lua/fschauen/plugins/completion.lua +++ b/config/nvim/lua/fschauen/plugins/completion.lua @@ -1,164 +1,5 @@ -local repeat_mapping = function(value, keys) - local tbl = {} - for _, k in ipairs(keys) do tbl[k] = value end - return tbl -end - -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) - end - return tbl -end - -local cond = function(condition, yes, no) - return function(fallback) - if condition() then yes(fallback) else no(fallback) end - end -end - -local 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), - } - - cmp.setup { - mapping = transform_keymap(keymap, 'i'), - - enabled = function() - local c = require 'cmp.config.context' - return not c.in_treesitter_capture('comment') and - not c.in_syntax_group('Comment') - end, - - snippet = { - expand = function(args) - require('luasnip').lsp_expand(args.body) - end, - }, - - formatting = { - format = require('lspkind').cmp_format { - mode = 'symbol_text', - - menu = { - buffer = 'buf', - nvim_lsp = 'LSP', - nvim_lua = 'lua', - path = '', - }, - - -- Custom mix of lspkind defaults and VS Code codicons :) - symbol_map = { - Array = '', - Boolean = '', - Class = '', - Color = '', - Constant = '󰏿', - Constructor = '', - Copilot = '', - Enum = '', - EnumMember = '', - Event = '', - Field = '', - File = '', - Folder = '', - Function = '󰊕', - Interface = '', - Key = '', - Keyword = '', - Method = '', - Module = '', - Namespace = '', - Null = '', - Number = '', - Object = '', - Operator = '', - Package = '', - Property = '', - Reference = '', - Snippet = '', - String = '', - Struct = '', - Text = '', - TypeParameter = '', - Unit = '', - Value = '󰎠', - Variable = '󰀫', - }, - }, - }, - - sources = cmp.config.sources({ - { name = 'nvim_lua' }, - { name = 'nvim_lsp' }, - { name = 'luasnip' }, - }, { - { name = 'path' }, - { name = 'buffer', keyword_length = 5 }, - }), - - window = { - completion = cmp.config.window.bordered(), - documentation = cmp.config.window.bordered(), - }, - - experimental = { - ghost_text = true, - }, - } - - cmp.setup.cmdline(':', { - mapping = transform_keymap( - vim.tbl_extend('force', keymap, { - [''] = cond(cmp.visible, map.confirm {select = true }, map.complete()), - }), - 'c'), - - completion = { - autocomplete = false, - }, - - sources = cmp.config.sources({ - { name = 'path' } - }, { - { name = 'cmdline' } - }), - }) - - cmp.setup.filetype('TelescopePrompt', { enabled = false }) -end - return { 'hrsh7th/nvim-cmp', - - config = config, - dependencies = { 'hrsh7th/cmp-nvim-lsp', 'hrsh7th/cmp-nvim-lua', @@ -166,9 +7,101 @@ return { 'hrsh7th/cmp-buffer', 'hrsh7th/cmp-cmdline', 'onsails/lspkind-nvim', - 'L3MON4D3/LuaSnip', 'saadparwaiz1/cmp_luasnip', }, + keys = require('fschauen.keymap').completion, + config = function() + local cmp = require('cmp') + + cmp.setup { + enabled = function() + local c = require 'cmp.config.context' + return not c.in_treesitter_capture('comment') and + not c.in_syntax_group('Comment') + end, + snippet = { + expand = function(args) + require('luasnip').lsp_expand(args.body) + end, + }, + formatting = { + format = require('lspkind').cmp_format { + mode = 'symbol_text', + menu = { + buffer = 'buf', + nvim_lsp = 'LSP', + nvim_lua = 'lua', + path = '', + }, + symbol_map = { + Array = '', + Boolean = '', + Class = '', + Color = '', + Constant = '󰏿', + Constructor = '', + Copilot = '', + Enum = '', + EnumMember = '', + Event = '', + Field = '', + File = '', + Folder = '', + Function = '󰊕', + Interface = '', + Key = '', + Keyword = '', + Method = '', + Module = '', + Namespace = '', + Null = '', + Number = '', + Object = '', + Operator = '', + Package = '', + Property = '', + Reference = '', + Snippet = '', + String = '', + Struct = '', + Text = '', + TypeParameter = '', + Unit = '', + Value = '󰎠', + Variable = '󰀫', + }, + }, + }, + sources = cmp.config.sources({ + { name = 'nvim_lua' }, + { name = 'nvim_lsp' }, + { name = 'luasnip' }, + }, { + { name = 'path' }, + { name = 'buffer', keyword_length = 5 }, + }), + window = { + completion = cmp.config.window.bordered(), + documentation = cmp.config.window.bordered(), + }, + experimental = { + ghost_text = true, + }, + } + + cmp.setup.cmdline(':', { + completion = { + autocomplete = false, + }, + sources = cmp.config.sources({ + { name = 'path' } + }, { + { name = 'cmdline' } + }), + }) + + cmp.setup.filetype('TelescopePrompt', { enabled = false }) + end, }