diff --git a/modules/completion/nvim-cmp/config.nix b/modules/completion/nvim-cmp/config.nix index 36aee08..7bdda3d 100644 --- a/modules/completion/nvim-cmp/config.nix +++ b/modules/completion/nvim-cmp/config.nix @@ -1,5 +1,4 @@ { - pkgs, lib, config, ... @@ -8,6 +7,12 @@ with lib; with builtins; let cfg = config.vim.autocomplete; lspkindEnabled = config.vim.lsp.enable && config.vim.lsp.lspkind.enable; + + self = import ./nvim-cmp.nix {inherit lib;}; + mappingDefinitions = self.options.vim.autocomplete.mappings; + + mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions; + builtSources = concatMapStringsSep "\n" @@ -46,6 +51,133 @@ in { "path" = "[Path]"; }; + vim.maps.insert = mkMerge [ + (mkSetLuaBinding mappings.complete '' + require('cmp').complete + '') + (mkSetLuaBinding mappings.confirm '' + function() + if not require('cmp').confirm({ select = true }) then + local termcode = vim.api.nvim_replace_termcodes(${builtins.toJSON mappings.confirm.value}, true, false, true) + + vim.fn.feedkeys(termcode, 'n') + end + end + '') + (mkSetLuaBinding mappings.next '' + function() + local has_words_before = function() + 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 cmp = require('cmp') + + local feedkey = function(key, mode) + vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true) + end + + if cmp.visible() then + cmp.select_next_item() + elseif vim.fn['vsnip#available'](1) == 1 then + feedkey("(vsnip-expand-or-jump)", "") + elseif has_words_before() then + cmp.complete() + else + fallback() + end + end + '') + (mkSetLuaBinding mappings.previous '' + function() + local cmp = require('cmp') + + local feedkey = function(key, mode) + vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true) + end + + if cmp.visible() then + cmp.select_prev_item() + elseif vim.fn['vsnip#available'](-1) == 1 then + feedkeys("(vsnip-jump-prev)", "") + end + end + '') + (mkSetLuaBinding mappings.close '' + require('cmp').mapping.abort + '') + (mkSetLuaBinding mappings.scrollDocsUp '' + function() + require('cmp').mapping.scroll_docs(-4) + end + '') + (mkSetLuaBinding mappings.scrollDocsDown '' + function() + require('cmp').mapping.scroll_docs(4) + end + '') + ]; + + vim.maps.command = mkMerge [ + (mkSetLuaBinding mappings.complete '' + require('cmp').complete + '') + (mkSetLuaBinding mappings.close '' + require('cmp').mapping.close + '') + (mkSetLuaBinding mappings.scrollDocsUp '' + function() + require('cmp').mapping.scroll_docs(-4) + end + '') + (mkSetLuaBinding mappings.scrollDocsDown '' + function() + require('cmp').mapping.scroll_docs(4) + end + '') + ]; + + vim.maps.select = mkMerge [ + (mkSetLuaBinding mappings.next '' + function() + local cmp = require('cmp') + local has_words_before = function() + 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 feedkey = function(key, mode) + vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true) + end + + if cmp.visible() then + cmp.select_next_item() + elseif vim.fn['vsnip#available'](1) == 1 then + feedkey("(vsnip-expand-or-jump)", "") + elseif has_words_before() then + cmp.complete() + else + fallback() + end + end + '') + (mkSetLuaBinding mappings.previous '' + function() + local cmp = require('cmp') + + local feedkey = function(key, mode) + vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true) + end + + if cmp.visible() then + cmp.select_prev_item() + elseif vim.fn['vsnip#available'](-1) == 1 then + feedkeys("(vsnip-jump-prev)", "") + end + end + '') + ]; + vim.luaConfigRC.completion = mkIf (cfg.type == "nvim-cmp") (dagPlacement '' local nvim_cmp_menu_map = function(entry, vim_item) -- name for each source @@ -59,16 +191,6 @@ in { ${optionalString lspkindEnabled '' lspkind_opts.before = ${cfg.formatting.format} ''} - - local has_words_before = function() - 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 feedkey = function(key, mode) - vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true) - end - local cmp = require'cmp' cmp.setup({ snippet = { @@ -79,37 +201,6 @@ in { sources = { ${builtSources} }, - mapping = { - [''] = cmp.mapping(cmp.mapping.scroll_docs(-4), { 'i', 'c' }), - [''] = cmp.mapping(cmp.mapping.scroll_docs(4), { 'i', 'c'}), - [''] = cmp.mapping(cmp.mapping.complete(), { 'i', 'c'}), - [''] = cmp.config.disable, - [''] = cmp.mapping({ - i = cmp.mapping.abort(), - c = cmp.mapping.close(), - }), - [''] = cmp.mapping.confirm({ - select = true, - }), - [''] = cmp.mapping(function (fallback) - if cmp.visible() then - cmp.select_next_item() - elseif vim.fn['vsnip#available'](1) == 1 then - feedkey("(vsnip-expand-or-jump)", "") - elseif has_words_before() then - cmp.complete() - else - fallback() - end - end, { 'i', 's' }), - [''] = cmp.mapping(function (fallback) - if cmp.visible() then - cmp.select_prev_item() - elseif vim.fn['vsnip#available'](-1) == 1 then - feedkeys("(vsnip-jump-prev)", "") - end - end, { 'i', 's' }) - }, completion = { completeopt = 'menu,menuone,noinsert', }, diff --git a/modules/completion/nvim-cmp/nvim-cmp.nix b/modules/completion/nvim-cmp/nvim-cmp.nix index 9010a99..8011feb 100644 --- a/modules/completion/nvim-cmp/nvim-cmp.nix +++ b/modules/completion/nvim-cmp/nvim-cmp.nix @@ -1,34 +1,6 @@ -{ - pkgs, - lib, - config, - ... -}: +{lib, ...}: with lib; -with builtins; let - cfg = config.vim.autocomplete; - lspkindEnabled = config.vim.lsp.enable && config.vim.lsp.lspkind.enable; - builtSources = - concatMapStringsSep - "\n" - (n: "{ name = '${n}'},") - (attrNames cfg.sources); - - builtMaps = - concatStringsSep - "\n" - (mapAttrsToList - (n: v: - if v == null - then "" - else "${n} = '${v}',") - cfg.sources); - - dagPlacement = - if lspkindEnabled - then nvim.dag.entryAfter ["lspkind"] - else nvim.dag.entryAnywhere; -in { +with builtins; { options.vim = { autocomplete = { enable = mkOption { @@ -37,6 +9,16 @@ in { description = "enable autocomplete"; }; + mappings = { + complete = mkMappingOption "Complete [nvim-cmp]" ""; + confirm = mkMappingOption "Confirm [nvim-cmp]" ""; + next = mkMappingOption "Next item [nvim-cmp]" ""; + previous = mkMappingOption "Previous item [nvim-cmp]" ""; + close = mkMappingOption "Close [nvim-cmp]" ""; + scrollDocsUp = mkMappingOption "Scroll docs up [nvim-cmp]" ""; + scrollDocsDown = mkMappingOption "Scroll docs down [nvim-cmp]" ""; + }; + type = mkOption { type = types.enum ["nvim-cmp"]; default = "nvim-cmp";