modules/completion: rewrite

This commit is contained in:
diniamo 2024-10-06 12:42:35 +02:00
commit 130f64d1ee
20 changed files with 331 additions and 362 deletions

View file

@ -105,12 +105,10 @@ isMaximal: {
transparent = false; transparent = false;
}; };
autopairs.enable = true; autopairs.nvim-autopairs.enable = true;
autocomplete = { autocomplete.nvim-cmp.enable = true;
enable = true; snippets.vsnip.enable = true;
type = "nvim-cmp";
};
filetree = { filetree = {
nvimTree = { nvimTree = {

5
lib/attrsets.nix Normal file
View file

@ -0,0 +1,5 @@
{lib}: let
inherit (builtins) listToAttrs;
in {
mapListToAttrs = f: list: listToAttrs (map f list);
}

View file

@ -10,6 +10,7 @@
dag = import ./dag.nix {inherit lib;}; dag = import ./dag.nix {inherit lib;};
languages = import ./languages.nix {inherit lib;}; languages = import ./languages.nix {inherit lib;};
lists = import ./lists.nix {inherit lib;}; lists = import ./lists.nix {inherit lib;};
attrsets = import ./attrsets.nix {inherit lib;};
lua = import ./lua.nix {inherit lib;}; lua = import ./lua.nix {inherit lib;};
neovimConfiguration = import ../modules {inherit inputs lib;}; neovimConfiguration = import ../modules {inherit inputs lib;};
} }

View file

@ -2,8 +2,8 @@
{lib}: let {lib}: let
inherit (builtins) isString getAttr; inherit (builtins) isString getAttr;
inherit (lib.options) mkOption; inherit (lib.options) mkOption;
inherit (lib.attrsets) listToAttrs;
inherit (lib.types) bool; inherit (lib.types) bool;
inherit (lib.nvim.attrsets) mapListToAttrs;
in { in {
# Converts a boolean to a yes/no string. This is used in lots of # Converts a boolean to a yes/no string. This is used in lots of
# configuration formats. # configuration formats.
@ -12,21 +12,21 @@ in {
config, config,
diagnosticsProviders, diagnosticsProviders,
}: }:
listToAttrs mapListToAttrs
(map (v: let (v: let
type = type =
if isString v if isString v
then v then v
else getAttr v.type; else getAttr v.type;
package = package =
if isString v if isString v
then diagnosticsProviders.${type}.package then diagnosticsProviders.${type}.package
else v.package; else v.package;
in { in {
name = "${lang}-diagnostics-${type}"; name = "${lang}-diagnostics-${type}";
value = diagnosticsProviders.${type}.nullConfig package; value = diagnosticsProviders.${type}.nullConfig package;
}) })
config); config;
mkEnable = desc: mkEnable = desc:
mkOption { mkOption {

View file

@ -34,6 +34,8 @@ in {
"copilot-cmp" "copilot-cmp"
]; ];
vim.autocomplete.nvim-cmp.sources = {copilot = "[Copilot]";};
vim.pluginRC.copilot = entryAnywhere '' vim.pluginRC.copilot = entryAnywhere ''
require("copilot").setup(${toLuaObject cfg.setupOpts}) require("copilot").setup(${toLuaObject cfg.setupOpts})

View file

@ -4,16 +4,15 @@
... ...
}: let }: let
inherit (lib.modules) mkIf; inherit (lib.modules) mkIf;
inherit (lib.trivial) boolToString;
inherit (lib.nvim.dag) entryAnywhere; inherit (lib.nvim.dag) entryAnywhere;
inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.autopairs; cfg = config.vim.autopairs.nvim-autopairs;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim.startPlugins = ["nvim-autopairs"]; vim = {
startPlugins = ["nvim-autopairs"];
vim.pluginRC.autopairs = entryAnywhere '' pluginRC.autopairs = entryAnywhere "require('nvim-autopairs').setup(${toLuaObject cfg.setupOpts})";
require("nvim-autopairs").setup({ map_cr = ${boolToString (!config.vim.autocomplete.enable)} }) };
'';
}; };
} }

View file

@ -1,21 +1,14 @@
{lib, ...}: let {lib, ...}: let
inherit (lib) mkRemovedOptionModule; inherit (lib) mkRemovedOptionModule;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption;
inherit (lib.types) enum; inherit (lib.nvim.types) mkPluginSetupOption;
in { in {
imports = [ imports = [
(mkRemovedOptionModule ["vim" "autopairs" "nvim-compe"] "nvim-compe is deprecated and no longer suported.") (mkRemovedOptionModule ["vim" "autopairs" "nvim-compe"] "nvim-compe is deprecated and no longer suported.")
]; ];
options.vim = { options.vim.autopairs.nvim-autopairs = {
autopairs = { enable = mkEnableOption "autopairs" // {default = false;};
enable = mkEnableOption "autopairs" // {default = false;}; setupOpts = mkPluginSetupOption "nvim-autopairs" {};
type = mkOption {
type = enum ["nvim-autopairs"];
default = "nvim-autopairs";
description = "Set the autopairs type. Options: nvim-autopairs [nvim-autopairs]";
};
};
}; };
} }

View file

@ -3,246 +3,176 @@
config, config,
... ...
}: let }: let
inherit (builtins) toJSON; inherit (lib.modules) mkIf;
inherit (lib.modules) mkIf mkMerge; inherit (lib.strings) optionalString;
inherit (lib.attrsets) attrNames mapAttrsToList; inherit (lib.generators) mkLuaInline;
inherit (lib.strings) concatMapStringsSep concatStringsSep optionalString; inherit (lib.nvim.binds) addDescriptionsToMappings;
inherit (lib.nvim.binds) addDescriptionsToMappings mkSetLuaBinding; inherit (lib.nvim.dag) entryAnywhere;
inherit (lib.nvim.dag) entryAnywhere entryAfter; inherit (lib.nvim.lua) toLuaObject;
inherit (builtins) attrNames;
cfg = config.vim.autocomplete; cfg = config.vim.autocomplete.nvim-cmp;
lspkindEnabled = config.vim.lsp.enable && config.vim.lsp.lspkind.enable; vsnipEnable = config.vim.snippets.vsnip.enable;
self = import ./nvim-cmp.nix {inherit lib;};
mappingDefinitions = self.options.vim.autocomplete.mappings;
self = import ./nvim-cmp.nix {inherit lib config;};
mappingDefinitions = self.options.vim.autocomplete.nvim-cmp.mappings;
mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions; mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions;
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 entryAfter ["lspkind"]
else entryAnywhere;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim.startPlugins = [ vim = {
"nvim-cmp" startPlugins = [
"cmp-buffer" "nvim-cmp"
"cmp-vsnip" "cmp-buffer"
"cmp-path" "cmp-path"
"vim-vsnip" ];
];
vim.autocomplete.sources = { autocomplete.nvim-cmp.sources = {
"nvim-cmp" = null; nvim-cmp = null;
"vsnip" = "[VSnip]"; buffer = "[Buffer]";
"buffer" = "[Buffer]"; path = "[Path]";
"crates" = "[Crates]"; };
"path" = "[Path]";
"copilot" = "[Copilot]";
};
vim.maps.insert = mkMerge [ autopairs.nvim-autopairs.setupOpts.map_cr = false;
(mkSetLuaBinding mappings.complete ''
require('cmp').complete
'')
(let
defaultKeys =
if config.vim.autopairs.enable
then "require('nvim-autopairs').autopairs_cr()"
else "vim.api.nvim_replace_termcodes(${toJSON mappings.confirm.value}, true, false, true)";
in
mkSetLuaBinding mappings.confirm ''
function()
if not require('cmp').confirm({ select = true }) then
vim.fn.feedkeys(${defaultKeys}, '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') autocomplete.nvim-cmp.setupOpts = {
sources = map (s: {name = s;}) (attrNames cfg.sources);
local feedkey = function(key, mode) # TODO: try to get nvim-cmp to follow global border style
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true) window = mkIf config.vim.ui.borders.enable {
end completion = mkLuaInline "cmp.config.window.bordered()";
documentation = mkLuaInline "cmp.config.window.bordered()";
};
if cmp.visible() then formatting.format = cfg.format;
cmp.select_next_item() };
elseif vim.fn['vsnip#available'](1) == 1 then
feedkey("<Plug>(vsnip-expand-or-jump)", "")
elseif has_words_before() then
cmp.complete()
else
local termcode = vim.api.nvim_replace_termcodes(${toJSON mappings.next.value}, true, false, true)
vim.fn.feedkeys(termcode, 'n') pluginRC.nvim-cmp = mkIf cfg.enable (entryAnywhere ''
end local cmp = require("cmp")
end cmp.setup(${toLuaObject cfg.setupOpts})
'')
(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) optionalString config.vim.autopairs.nvim-autopairs.enable
end ''
cmp.event:on('confirm_done', require("nvim-autopairs.completion.cmp").on_confirm_done({ map_char = { text = "" } }))
if cmp.visible() then ''
cmp.select_prev_item()
elseif vim.fn['vsnip#available'](-1) == 1 then
feedkeys("<Plug>(vsnip-jump-prev)", "")
end
end
'')
(mkSetLuaBinding mappings.close ''
require('cmp').mapping.abort()
'')
(mkSetLuaBinding mappings.scrollDocsUp ''
require('cmp').mapping.scroll_docs(-4)
'')
(mkSetLuaBinding mappings.scrollDocsDown ''
require('cmp').mapping.scroll_docs(4)
'')
];
vim.maps.command = mkMerge [
(mkSetLuaBinding mappings.complete ''
require('cmp').complete
'')
(mkSetLuaBinding mappings.close ''
require('cmp').mapping.close()
'')
(mkSetLuaBinding mappings.scrollDocsUp ''
require('cmp').mapping.scroll_docs(-4)
'')
(mkSetLuaBinding mappings.scrollDocsDown ''
require('cmp').mapping.scroll_docs(4)
'')
];
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("<Plug>(vsnip-expand-or-jump)", "")
elseif has_words_before() then
cmp.complete()
else
local termcode = vim.api.nvim_replace_termcodes(${toJSON mappings.next.value}, true, false, true)
vim.fn.feedkeys(termcode, 'n')
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("<Plug>(vsnip-jump-prev)", "")
end
end
'')
];
# TODO: alternative snippet engines to vsnip
# https://github.com/hrsh7th/nvim-cmp/blob/main/doc/cmp.txt#L82
vim.pluginRC.completion = mkIf (cfg.type == "nvim-cmp") (dagPlacement ''
local nvim_cmp_menu_map = function(entry, vim_item)
-- name for each source
vim_item.menu = ({
${builtMaps}
})[entry.source.name]
return vim_item
end
${optionalString lspkindEnabled ''
lspkind_opts.before = ${cfg.formatting.format}
''}
local cmp = require'cmp'
cmp.setup({
${optionalString config.vim.ui.borders.enable ''
-- explicitly enabled by setting ui.borders.enable = true
-- TODO: try to get nvim-cmp to follow global border style
window = {
completion = cmp.config.window.bordered(),
documentation = cmp.config.window.bordered(),
},
''}
snippet = {
expand = function(args)
vim.fn["vsnip#anonymous"](args.body)
end,
},
sources = {
${builtSources}
},
completion = {
completeopt = 'menu,menuone,noinsert',
${optionalString (!cfg.alwaysComplete) "autocomplete = false"}
},
formatting = {
format =
${
if lspkindEnabled
then "lspkind.cmp_format(lspkind_opts)"
else cfg.formatting.format
},
} }
}) '');
${optionalString (config.vim.autopairs.enable && config.vim.autopairs.type == "nvim-autopairs") ''
local cmp_autopairs = require('nvim-autopairs.completion.cmp')
cmp.event:on('confirm_done', cmp_autopairs.on_confirm_done({ map_char = { text = ""} }))
''}
'');
vim.snippets.vsnip.enable = keymaps = [
if (cfg.type == "nvim-cmp") {
then true mode = ["i" "c"];
else config.vim.snippets.vsnip.enable; key = mappings.complete.value;
lua = true;
action = "require('cmp').complete";
desc = mappings.complete.description;
}
{
mode = "i";
key = mappings.confirm.value;
lua = true;
action = let
defaultKeys =
if config.vim.autopairs.nvim-autopairs.enable
then "require('nvim-autopairs').autopairs_cr()"
else "vim.api.nvim_replace_termcodes(${toLuaObject mappings.confirm.value}, true, false, true)";
in ''
function()
if not require('cmp').confirm({ select = true }) then
vim.fn.feedkeys(${defaultKeys}, 'n')
end
end
'';
desc = mappings.confirm.description;
}
{
mode = ["i" "s"];
key = mappings.next.value;
lua = true;
action = ''
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()
${
optionalString vsnipEnable
''
elseif vim.fn['vsnip#available'](1) == 1 then
feedkey("<Plug>(vsnip-expand-or-jump)", "")
''
}
elseif has_words_before() then
cmp.complete()
else
vim.fn.feedkeys(vim.api.nvim_replace_termcodes(${toLuaObject mappings.next.value}, true, false, true), 'n')
end
end
'';
desc = mappings.next.description;
}
{
mode = ["i" "s"];
key = mappings.previous.value;
lua = true;
action = ''
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()
${
optionalString vsnipEnable
''
elseif vim.fn['vsnip#available'](-1) == 1 then
feedkeys("<Plug>(vsnip-jump-prev)", "")
''
}
end
end
'';
desc = mappings.previous.description;
}
{
mode = ["i" "c"];
key = mappings.close.value;
lua = true;
action = "require('cmp').mapping.abort()";
desc = mappings.close.description;
}
{
mode = ["i" "c"];
key = mappings.scrollDocsUp.value;
lua = true;
action = "require('cmp').mapping.scroll_docs(-4)";
desc = mappings.scrollDocsUp.description;
}
{
mode = ["i" "c"];
key = mappings.scrollDocsDown.value;
lua = true;
action = "require('cmp').mapping.scroll_docs(4)";
desc = mappings.scrollDocsDown.description;
}
];
};
}; };
} }

View file

@ -1,4 +1,4 @@
_: { {
imports = [ imports = [
./config.nix ./config.nix
./nvim-cmp.nix ./nvim-cmp.nix

View file

@ -1,72 +1,75 @@
{lib, ...}: let {
inherit (lib.options) mkEnableOption mkOption literalMD; lib,
config,
...
}: let
inherit (lib.options) mkEnableOption mkOption literalExpression literalMD;
inherit (lib.types) str attrsOf nullOr;
inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.binds) mkMappingOption; inherit (lib.nvim.binds) mkMappingOption;
inherit (lib.types) enum attrsOf nullOr str bool; inherit (lib.nvim.types) mkPluginSetupOption luaInline;
inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.autocomplete.nvim-cmp;
in { in {
options.vim = { options.vim.autocomplete.nvim-cmp = {
autocomplete = { enable = mkEnableOption "nvim-cmp" // {default = false;};
enable = mkEnableOption "autocomplete" // {default = false;}; setupOpts = mkPluginSetupOption "the autocomplete plugin" {
completion.completeopt = mkOption {
alwaysComplete = mkOption { type = str;
type = bool; default = "menu,menuone,noinsert";
description = "Automatically show completion.";
default = true;
};
mappings = {
complete = mkMappingOption "Complete [nvim-cmp]" "<C-Space>";
confirm = mkMappingOption "Confirm [nvim-cmp]" "<CR>";
next = mkMappingOption "Next item [nvim-cmp]" "<Tab>";
previous = mkMappingOption "Previous item [nvim-cmp]" "<S-Tab>";
close = mkMappingOption "Close [nvim-cmp]" "<C-e>";
scrollDocsUp = mkMappingOption "Scroll docs up [nvim-cmp]" "<C-d>";
scrollDocsDown = mkMappingOption "Scroll docs down [nvim-cmp]" "<C-f>";
};
type = mkOption {
type = enum ["nvim-cmp"];
default = "nvim-cmp";
description = "Set the autocomplete plugin. Options: [nvim-cmp]";
};
sources = mkOption {
description = '' description = ''
Attribute set of source names for nvim-cmp. A comma-separated list of options for completion.
If an attribute set is provided, then the menu value of See `:help completeopt` for the complete list.
`vim_item` in the format will be set to the value (if
utilizing the `nvim_cmp_menu_map` function).
Note: only use a single attribute name per attribute set
'';
type = attrsOf (nullOr str);
default = {};
example = ''
{nvim-cmp = null; buffer = "[Buffer]";}
''; '';
}; };
};
formatting = { mappings = {
format = mkOption { complete = mkMappingOption "Complete [nvim-cmp]" "<C-Space>";
description = '' confirm = mkMappingOption "Confirm [nvim-cmp]" "<CR>";
The function used to customize the appearance of the completion menu. next = mkMappingOption "Next item [nvim-cmp]" "<Tab>";
previous = mkMappingOption "Previous item [nvim-cmp]" "<S-Tab>";
close = mkMappingOption "Close [nvim-cmp]" "<C-e>";
scrollDocsUp = mkMappingOption "Scroll docs up [nvim-cmp]" "<C-d>";
scrollDocsDown = mkMappingOption "Scroll docs down [nvim-cmp]" "<C-f>";
};
If [](#opt-vim.lsp.lspkind.enable) is true, then the function format = mkOption {
will be called before modifications from lspkind. type = luaInline;
default = mkLuaInline ''
function(entry, vim_item)
vim_item.menu = (${toLuaObject cfg.sources})[entry.source.name]
return vim_item
end
'';
defaultText = literalMD ''
```lua
function(entry, vim_item)
vim_item.menu = (''${toLuaObject config.vim.autocomplete.nvim-cmp.sources})[entry.source.name]
return vim_item
end
```
'';
description = ''
The function used to customize the completion menu entires.
This is outside of `setupOpts` because of internal reasons.
Default is to call the menu mapping function. See `:help cmp-config.formatting.format`.
''; '';
type = str; };
default = "nvim_cmp_menu_map";
example = literalMD '' sources = mkOption {
```lua type = attrsOf (nullOr str);
function(entry, vim_item) default = {};
return vim_item description = "The list of sources used by nvim-cmp";
end example = literalExpression ''
``` {
''; nvim-cmp = null;
}; buffer = "[Buffer]";
}; }
'';
}; };
}; };
} }

View file

@ -3,13 +3,12 @@
pkgs, pkgs,
lib, lib,
... ...
}: let }: let inherit (builtins) attrNames;
inherit (builtins) attrNames;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.options) mkOption mkEnableOption; inherit (lib.options) mkOption mkEnableOption;
inherit (lib.strings) optionalString; inherit (lib.strings) optionalString;
inherit (lib.trivial) boolToString; inherit (lib.trivial) boolToString;
inherit (lib.lists) isList optionals; inherit (lib.lists) isList;
inherit (lib.types) bool package str listOf either enum; inherit (lib.types) bool package str listOf either enum;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.lua) expToLua;
@ -101,7 +100,7 @@ in {
vim = { vim = {
startPlugins = ["crates-nvim"]; startPlugins = ["crates-nvim"];
lsp.null-ls.enable = mkIf cfg.crates.codeActions true; lsp.null-ls.enable = mkIf cfg.crates.codeActions true;
autocomplete.sources = {"crates" = "[Crates]";}; autocomplete.nvim-cmp.sources = {crates = "[Crates]";};
pluginRC.rust-crates = entryAnywhere '' pluginRC.rust-crates = entryAnywhere ''
require('crates').setup { require('crates').setup {
null_ls = { null_ls = {

View file

@ -11,7 +11,7 @@
inherit (lib.nvim.binds) addDescriptionsToMappings; inherit (lib.nvim.binds) addDescriptionsToMappings;
cfg = config.vim.lsp; cfg = config.vim.lsp;
usingNvimCmp = config.vim.autocomplete.enable && config.vim.autocomplete.type == "nvim-cmp"; usingNvimCmp = config.vim.autocomplete.nvim-cmp.enable;
self = import ./module.nix {inherit config lib pkgs;}; self = import ./module.nix {inherit config lib pkgs;};
mappingDefinitions = self.options.vim.lsp.mappings; mappingDefinitions = self.options.vim.lsp.mappings;
@ -25,7 +25,7 @@ in {
vim = { vim = {
startPlugins = optional usingNvimCmp "cmp-nvim-lsp"; startPlugins = optional usingNvimCmp "cmp-nvim-lsp";
autocomplete.sources = {"nvim_lsp" = "[LSP]";}; autocomplete.nvim-cmp.sources = {nvim_lsp = "[LSP]";};
pluginRC.lsp-setup = '' pluginRC.lsp-setup = ''
vim.g.formatsave = ${boolToString cfg.formatOnSave}; vim.g.formatsave = ${boolToString cfg.formatOnSave};

View file

@ -3,18 +3,32 @@
lib, lib,
... ...
}: let }: let
inherit (lib.modules) mkIf; inherit (lib.modules) mkIf mkForce;
inherit (lib.nvim.dag) entryAnywhere; inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.lsp; cfg = config.vim.lsp.lspkind;
in { in {
config = mkIf (cfg.enable && cfg.lspkind.enable) { config = mkIf cfg.enable {
vim.startPlugins = ["lspkind"]; assertions = [
vim.pluginRC.lspkind = entryAnywhere '' {
local lspkind = require'lspkind' assertion = config.vim.autocomplete.nvim-cmp.enable;
local lspkind_opts = { message = ''
mode = '${cfg.lspkind.mode}' While lspkind supports Neovim's native lsp upstream, using that over
nvim-cmp isn't recommended, nor supported by nvf.
Please migrate to nvim-cmp if you want to use lspkind.
'';
} }
''; ];
vim = {
startPlugins = ["lspkind"];
lsp.lspkind.setupOpts.before = config.vim.autocomplete.nvim-cmp.format;
autocomplete.nvim-cmp.setupOpts.formatting.format = mkForce (mkLuaInline ''
require("lspkind").cmp_format(${toLuaObject cfg.setupOpts})
'');
};
}; };
} }

View file

@ -1,16 +1,22 @@
{lib, ...}: let {lib, ...}: let
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) enum; inherit (lib.types) enum nullOr;
inherit (lib.nvim.types) mkPluginSetupOption luaInline;
in { in {
options.vim.lsp = { options.vim.lsp.lspkind = {
lspkind = { enable = mkEnableOption "vscode-like pictograms for lsp [lspkind]";
enable = mkEnableOption "vscode-like pictograms for lsp [lspkind]"; setupOpts = mkPluginSetupOption "lspkind.nvim" {
mode = mkOption { mode = mkOption {
description = "Defines how annotations are shown"; description = "Defines how annotations are shown";
type = enum ["text" "text_symbol" "symbol_text" "symbol"]; type = enum ["text" "text_symbol" "symbol_text" "symbol"];
default = "symbol_text"; default = "symbol_text";
}; };
before = mkOption {
description = "The function that will be called before lspkind's modifications are applied";
type = nullOr luaInline;
default = null;
};
}; };
}; };
} }

View file

@ -45,10 +45,10 @@ in {
completion = { completion = {
nvim_cmp = mkOption { nvim_cmp = mkOption {
# if using nvim-cmp, otherwise set to false # If using nvim-cmp, otherwise set to false
type = bool; type = bool;
description = "If using nvim-cmp, otherwise set to false"; description = "If using nvim-cmp, otherwise set to false";
default = config.vim.autocomplete.type == "nvim-cmp"; default = config.vim.autocomplete.nvim-cmp.enable;
}; };
}; };
}; };

View file

@ -3,11 +3,28 @@
lib, lib,
... ...
}: let }: let
inherit (lib.modules) mkIf; inherit (lib.modules) mkIf mkMerge;
inherit (lib.generators) mkLuaInline;
cfg = config.vim.snippets.vsnip; cfg = config.vim.snippets.vsnip;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable (mkMerge [
vim.startPlugins = ["vim-vsnip"]; {
}; vim.startPlugins = ["vim-vsnip"];
}
(mkIf config.vim.autocomplete.nvim-cmp.enable {
vim = {
startPlugins = ["cmp-vsnip"];
autocomplete.nvim-cmp = {
sources = {"vsnip" = "[VSnip]";};
setupOpts.snippet.expand = mkLuaInline ''
function(args)
vim.fn["vsnip#anonymous"](args.body)
end
'';
};
};
})
]);
} }

View file

@ -4,10 +4,11 @@
... ...
}: let }: let
inherit (lib.options) mkOption; inherit (lib.options) mkOption;
inherit (lib.attrsets) attrNames listToAttrs; inherit (lib.attrsets) attrNames;
inherit (lib.strings) hasPrefix; inherit (lib.strings) hasPrefix;
inherit (lib.types) bool lines enum; inherit (lib.types) bool lines enum;
inherit (lib.modules) mkIf; inherit (lib.modules) mkIf;
inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.dag) entryBefore; inherit (lib.nvim.dag) entryBefore;
inherit (lib.nvim.types) hexColor; inherit (lib.nvim.types) hexColor;
@ -17,7 +18,8 @@
}; };
numbers = ["0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F"]; numbers = ["0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F"];
base16Options = listToAttrs (map (n: { base16Options =
mapListToAttrs (n: {
name = "base0${n}"; name = "base0${n}";
value = mkOption { value = mkOption {
description = "The base0${n} color to use"; description = "The base0${n} color to use";
@ -28,7 +30,7 @@
else "#${v}"; else "#${v}";
}; };
}) })
numbers); numbers;
in { in {
options.vim.theme = { options.vim.theme = {
enable = mkOption { enable = mkOption {

View file

@ -11,7 +11,7 @@
inherit (lib.nvim.dag) entryBefore entryAfter; inherit (lib.nvim.dag) entryBefore entryAfter;
cfg = config.vim.treesitter; cfg = config.vim.treesitter;
usingNvimCmp = config.vim.autocomplete.enable && config.vim.autocomplete.type == "nvim-cmp"; usingNvimCmp = config.vim.autocomplete.nvim-cmp.enable;
self = import ./treesitter.nix {inherit pkgs lib;}; self = import ./treesitter.nix {inherit pkgs lib;};
mappingDefinitions = self.options.vim.treesitter.mappings; mappingDefinitions = self.options.vim.treesitter.mappings;
@ -21,7 +21,7 @@ in {
vim = { vim = {
startPlugins = ["nvim-treesitter"] ++ optional usingNvimCmp "cmp-treesitter"; startPlugins = ["nvim-treesitter"] ++ optional usingNvimCmp "cmp-treesitter";
autocomplete.sources = {"treesitter" = "[Treesitter]";}; autocomplete.nvim-cmp.sources = {treesitter = "[Treesitter]";};
treesitter.grammars = optionals cfg.addDefaultGrammars cfg.defaultGrammars; treesitter.grammars = optionals cfg.addDefaultGrammars cfg.defaultGrammars;
maps = { maps = {

View file

@ -21,7 +21,7 @@ in {
mkBool true "override the lsp markdown formatter with Noice"; mkBool true "override the lsp markdown formatter with Noice";
"cmp.entry.get_documentation" = "cmp.entry.get_documentation" =
mkBool (config.vim.autocomplete.type == "nvim-cmp") "override cmp documentation with Noice"; mkBool config.vim.autocomplete.nvim-cmp.enable "override cmp documentation with Noice";
}; };
signature = { signature = {

View file

@ -4,7 +4,7 @@
... ...
}: let }: let
inherit (builtins) map mapAttrs filter; inherit (builtins) map mapAttrs filter;
inherit (lib.attrsets) mapAttrsToList filterAttrs; inherit (lib.attrsets) mapAttrsToList;
inherit (lib.strings) concatLines concatMapStringsSep; inherit (lib.strings) concatLines concatMapStringsSep;
inherit (lib.trivial) showWarnings; inherit (lib.trivial) showWarnings;
inherit (lib.generators) mkLuaInline; inherit (lib.generators) mkLuaInline;