From b41af9dbf6be5d6d5164ce4c4f1e5b565186fce4 Mon Sep 17 00:00:00 2001 From: Ching Pei Yang Date: Sat, 11 Jan 2025 21:46:49 +0100 Subject: [PATCH] autocomplete: move shared code into common parent --- .../plugins/completion/blink-cmp/config.nix | 1 + modules/plugins/completion/config.nix | 34 +++ modules/plugins/completion/default.nix | 3 + modules/plugins/completion/module.nix | 7 + .../plugins/completion/nvim-cmp/config.nix | 201 +++++++++--------- 5 files changed, 140 insertions(+), 106 deletions(-) create mode 100644 modules/plugins/completion/config.nix create mode 100644 modules/plugins/completion/module.nix diff --git a/modules/plugins/completion/blink-cmp/config.nix b/modules/plugins/completion/blink-cmp/config.nix index 1141b7e9..914821f9 100644 --- a/modules/plugins/completion/blink-cmp/config.nix +++ b/modules/plugins/completion/blink-cmp/config.nix @@ -42,6 +42,7 @@ in { }; autocomplete = { + enableSharedCmpSources = true; blink-cmp.setupOpts = { sources = { default = ["lsp" "path" "snippets" "buffer"] ++ (attrNames cmpCfg.sources); diff --git a/modules/plugins/completion/config.nix b/modules/plugins/completion/config.nix new file mode 100644 index 00000000..8fc09201 --- /dev/null +++ b/modules/plugins/completion/config.nix @@ -0,0 +1,34 @@ +{ + lib, + config, + ... +}: let + inherit (lib.modules) mkIf; + inherit (lib.nvim.attrsets) mapListToAttrs; + inherit (builtins) typeOf tryEval; + + cfg = config.vim.autocomplete; + getPluginName = plugin: + if typeOf plugin == "string" + then plugin + else if (plugin ? pname && (tryEval plugin.pname).success) + then plugin.pname + else plugin.name; +in { + config.vim = mkIf cfg.enableSharedCmpSources { + startPlugins = ["rtp-nvim"]; + lazy.plugins = + mapListToAttrs (package: { + name = getPluginName package; + value = { + inherit package; + lazy = true; + after = '' + local path = vim.fn.globpath(vim.o.packpath, 'pack/*/opt/${getPluginName package}') + require("rtp_nvim").source_after_plugin_dir(path) + ''; + }; + }) + cfg.nvim-cmp.sourcePlugins; + }; +} diff --git a/modules/plugins/completion/default.nix b/modules/plugins/completion/default.nix index 0c0a61a0..bf737580 100644 --- a/modules/plugins/completion/default.nix +++ b/modules/plugins/completion/default.nix @@ -1,5 +1,8 @@ { imports = [ + ./module.nix + ./config.nix + ./nvim-cmp ./blink-cmp ]; diff --git a/modules/plugins/completion/module.nix b/modules/plugins/completion/module.nix new file mode 100644 index 00000000..eb2a32f1 --- /dev/null +++ b/modules/plugins/completion/module.nix @@ -0,0 +1,7 @@ +{lib, ...}: let + inherit (lib.options) mkEnableOption; +in { + options.vim.autocomplete = { + enableSharedCmpSources = mkEnableOption "sources shared by blink.cmp and nvim-cmp"; + }; +} diff --git a/modules/plugins/completion/nvim-cmp/config.nix b/modules/plugins/completion/nvim-cmp/config.nix index cfd3e53a..ce058876 100644 --- a/modules/plugins/completion/nvim-cmp/config.nix +++ b/modules/plugins/completion/nvim-cmp/config.nix @@ -24,114 +24,103 @@ in { config = mkIf cfg.enable { vim = { - startPlugins = ["rtp-nvim"]; - lazy.plugins = mkMerge [ - (mapListToAttrs (package: { - name = getPluginName package; - value = { - inherit package; - lazy = true; - after = '' - local path = vim.fn.globpath(vim.o.packpath, 'pack/*/opt/${getPluginName package}') - require("rtp_nvim").source_after_plugin_dir(path) + lazy.plugins = { + nvim-cmp = { + package = "nvim-cmp"; + after = '' + ${optionalString luasnipEnable "local luasnip = require('luasnip')"} + local cmp = require("cmp") + + local kinds = require("cmp.types").lsp.CompletionItemKind + local deprio = function(kind) + return function(e1, e2) + if e1:get_kind() == kind then + return false + end + if e2:get_kind() == kind then + return true + end + return nil + end + end + + cmp.setup(${toLuaObject cfg.setupOpts}) + + ${optionalString config.vim.lazy.enable + (concatStringsSep "\n" (map + (package: "require('lz.n').trigger_load(${toLuaObject (getPluginName package)})") + cfg.sourcePlugins))} + ''; + + event = ["InsertEnter" "CmdlineEnter"]; + }; + }; + + autocomplete = { + enableSharedCmpSources = true; + + nvim-cmp = { + sources = { + nvim-cmp = null; + buffer = "[Buffer]"; + path = "[Path]"; + }; + + sourcePlugins = ["cmp-buffer" "cmp-path"]; + + setupOpts = { + sources = map (s: {name = s;}) (attrNames cfg.sources); + + window = mkIf borders.enable { + completion.border = borders.style; + documentation.border = borders.style; + }; + + formatting.format = cfg.format; + + # `cmp` and `luasnip` are defined above, in the `nvim-cmp` section + mapping = { + ${mappings.complete} = mkLuaInline "cmp.mapping.complete()"; + ${mappings.close} = mkLuaInline "cmp.mapping.abort()"; + ${mappings.scrollDocsUp} = mkLuaInline "cmp.mapping.scroll_docs(-4)"; + ${mappings.scrollDocsDown} = mkLuaInline "cmp.mapping.scroll_docs(4)"; + ${mappings.confirm} = mkLuaInline "cmp.mapping.confirm({ select = true })"; + + ${mappings.next} = mkLuaInline '' + cmp.mapping(function(fallback) + 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 + + if cmp.visible() then + cmp.select_next_item() + ${optionalString luasnipEnable '' + elseif luasnip.locally_jumpable(1) then + luasnip.jump(1) + ''} + elseif has_words_before() then + cmp.complete() + else + fallback() + end + end) + ''; + + ${mappings.previous} = mkLuaInline '' + cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + ${optionalString luasnipEnable '' + elseif luasnip.locally_jumpable(-1) then + luasnip.jump(-1) + ''} + else + fallback() + end + end) ''; }; - }) - cfg.sourcePlugins) - { - nvim-cmp = { - package = "nvim-cmp"; - after = '' - ${optionalString luasnipEnable "local luasnip = require('luasnip')"} - local cmp = require("cmp") - - local kinds = require("cmp.types").lsp.CompletionItemKind - local deprio = function(kind) - return function(e1, e2) - if e1:get_kind() == kind then - return false - end - if e2:get_kind() == kind then - return true - end - return nil - end - end - - cmp.setup(${toLuaObject cfg.setupOpts}) - - ${optionalString config.vim.lazy.enable - (concatStringsSep "\n" (map - (package: "require('lz.n').trigger_load(${toLuaObject (getPluginName package)})") - cfg.sourcePlugins))} - ''; - - event = ["InsertEnter" "CmdlineEnter"]; - }; - } - ]; - - autocomplete.nvim-cmp = { - sources = { - nvim-cmp = null; - buffer = "[Buffer]"; - path = "[Path]"; - }; - - sourcePlugins = ["cmp-buffer" "cmp-path"]; - - setupOpts = { - sources = map (s: {name = s;}) (attrNames cfg.sources); - - window = mkIf borders.enable { - completion.border = borders.style; - documentation.border = borders.style; - }; - - formatting.format = cfg.format; - - # `cmp` and `luasnip` are defined above, in the `nvim-cmp` section - mapping = { - ${mappings.complete} = mkLuaInline "cmp.mapping.complete()"; - ${mappings.close} = mkLuaInline "cmp.mapping.abort()"; - ${mappings.scrollDocsUp} = mkLuaInline "cmp.mapping.scroll_docs(-4)"; - ${mappings.scrollDocsDown} = mkLuaInline "cmp.mapping.scroll_docs(4)"; - ${mappings.confirm} = mkLuaInline "cmp.mapping.confirm({ select = true })"; - - ${mappings.next} = mkLuaInline '' - cmp.mapping(function(fallback) - 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 - - if cmp.visible() then - cmp.select_next_item() - ${optionalString luasnipEnable '' - elseif luasnip.locally_jumpable(1) then - luasnip.jump(1) - ''} - elseif has_words_before() then - cmp.complete() - else - fallback() - end - end) - ''; - - ${mappings.previous} = mkLuaInline '' - cmp.mapping(function(fallback) - if cmp.visible() then - cmp.select_prev_item() - ${optionalString luasnipEnable '' - elseif luasnip.locally_jumpable(-1) then - luasnip.jump(-1) - ''} - else - fallback() - end - end) - ''; }; }; };