plugins/nvim-cmp: refactoring (init filetype and cmdline options)

This commit is contained in:
Gaetan Lepage 2024-02-03 23:22:06 +01:00 committed by Gaétan Lepage
parent 22b587f3dc
commit a61c8fbc3d
26 changed files with 1166 additions and 948 deletions

View file

@ -0,0 +1,125 @@
{
lib,
helpers,
config,
pkgs,
...
}:
with helpers.vim-plugin;
with lib; rec {
mkCmpSourcePlugin = {
name,
extraPlugins ? [],
useDefaultPackage ? true,
...
}:
mkVimPlugin config {
inherit name;
extraPlugins = extraPlugins ++ (lists.optional useDefaultPackage pkgs.vimPlugins.${name});
maintainers = [maintainers.GaetanLepage];
};
pluginAndSourceNames = {
"buffer" = "cmp-buffer";
"calc" = "cmp-calc";
"dap" = "cmp-dap";
"cmdline" = "cmp-cmdline";
"cmp-clippy" = "cmp-clippy";
"cmp-cmdline-history" = "cmp-cmdline-history";
"cmp_pandoc" = "cmp-pandoc-nvim";
"cmp_tabby" = "cmp-tabby";
"cmp_tabnine" = "cmp-tabnine";
"codeium" = "codeium-nvim";
"conventionalcommits" = "cmp-conventionalcommits";
"copilot" = "copilot-cmp";
"crates" = "crates-nvim";
"dictionary" = "cmp-dictionary";
"digraphs" = "cmp-digraphs";
"emoji" = "cmp-emoji";
"fish" = "cmp-fish";
"fuzzy_buffer" = "cmp-fuzzy-buffer";
"fuzzy_path" = "cmp-fuzzy-path";
"git" = "cmp-git";
"greek" = "cmp-greek";
"latex_symbols" = "cmp-latex-symbols";
"look" = "cmp-look";
"luasnip" = "cmp_luasnip";
"nvim_lsp" = "cmp-nvim-lsp";
"nvim_lsp_document_symbol" = "cmp-nvim-lsp-document-symbol";
"nvim_lsp_signature_help" = "cmp-nvim-lsp-signature-help";
"nvim_lua" = "cmp-nvim-lua";
"npm" = "cmp-npm";
"omni" = "cmp-omni";
"pandoc_references" = "cmp-pandoc-references";
"path" = "cmp-path";
"rg" = "cmp-rg";
"snippy" = "cmp-snippy";
"spell" = "cmp-spell";
"tmux" = "cmp-tmux";
"treesitter" = "cmp-treesitter";
"ultisnips" = "cmp-nvim-ultisnips";
"vim_lsp" = "cmp-vim-lsp";
"vimwiki-tags" = "cmp-vimwiki-tags";
"vsnip" = "cmp-vsnip";
"zsh" = "cmp-zsh";
};
extractSourcesFromOptionValue = sources:
if isList sources
then sources
else [];
autoInstallSourcePluginsModule = cfg: let
# cfg.setup.sources
setupSources = extractSourcesFromOptionValue cfg.settings.sources;
# cfg.filetype.<name>.sources
filetypeSources =
mapAttrsToList
(_: filetypeConfig:
extractSourcesFromOptionValue filetypeConfig.sources)
cfg.filetype;
# cfg.cmdline.<name>.sources
cmdlineSources =
mapAttrsToList
(_: cmdlineConfig:
extractSourcesFromOptionValue cmdlineConfig.sources)
cfg.cmdline;
# [{name = "foo";} {name = "bar"; x = 42;} ...]
allSources = flatten (setupSources ++ filetypeSources ++ cmdlineSources);
# Take only the names from the sources provided by the user
# ["foo" "bar"]
foundSources =
lists.unique
(
map
(source: source.name)
allSources
);
# A list of known source names
knownSourceNames = attrNames pluginAndSourceNames;
attrsEnabled = listToAttrs (map
(name: {
# Name of the corresponding plugin to enable
name = pluginAndSourceNames.${name};
# Whether or not we enable it
value.enable = mkIf (elem name foundSources) true;
})
knownSourceNames);
lspCapabilities =
mkIf
(elem "nvim_lsp" foundSources)
{
lsp.capabilities = ''
capabilities = vim.tbl_deep_extend("force", capabilities, require('cmp_nvim_lsp').default_capabilities())
'';
};
in
mkMerge [
(mkIf cfg.autoEnableSources attrsEnabled)
lspCapabilities
];
}

View file

@ -0,0 +1,83 @@
{
lib,
helpers,
pkgs,
config,
...
} @ args: let
cmpOptions = import ./options {inherit lib helpers;};
in
with lib;
helpers.neovim-plugin.mkNeovimPlugin config {
name = "cmp";
originalName = "nvim-cmp";
defaultPackage = pkgs.vimPlugins.nvim-cmp;
maintainers = [maintainers.GaetanLepage];
# Introduced on 2024 February 21
# TODO: remove ~June 2024
imports = [
./deprecations.nix
./sources
];
deprecateExtraOptions = true;
extraOptions = {
autoEnableSources = mkOption {
type = types.bool;
default = true;
description = ''
Scans the sources array and installs the plugins if they are known to nixvim.
'';
};
inherit (cmpOptions) filetype cmdline;
};
inherit (cmpOptions) settingsOptions settingsExample;
callSetup = false;
extraConfig = cfg: {
warnings = optional (cfg.autoEnableSources && (helpers.nixvimTypes.isRawType cfg.settings.sources)) ''
Nixvim (plugins.cmp): You have enabled `autoEnableSources` that tells Nixvim to automatically
enable the source plugins with respect to the list of sources provided in `settings.sources`.
However, the latter is proveded as a raw lua string which is not parseable by Nixvim.
If you want to keep using raw lua for defining your sources:
- Ensure you enable the relevant plugins manually in your configuration;
- Dismiss this warning by explicitly setting `autoEnableSources` to `false`;
'';
extraConfigLua =
''
local cmp = require('cmp')
cmp.setup(${helpers.toLuaObject cfg.settings})
''
+ (
concatStringsSep "\n"
(
mapAttrsToList
(
filetype: settings: "cmp.setup.filetype('${filetype}', ${helpers.toLuaObject settings})\n"
)
cfg.filetype
)
)
+ (
concatStringsSep "\n"
(
mapAttrsToList
(
cmdtype: settings: "cmp.setup.cmdline('${cmdtype}', ${helpers.toLuaObject settings})\n"
)
cfg.cmdline
)
);
# If autoEnableSources is set to true, figure out which are provided by the user
# and enable the corresponding plugins.
plugins = (import ./cmp-helpers.nix args).autoInstallSourcePluginsModule cfg;
};
}

View file

@ -0,0 +1,154 @@
{lib, ...}:
with lib; let
oldPluginBasePath = ["plugins" "nvim-cmp"];
newPluginBasePath = ["plugins" "cmp"];
settingsPath = newPluginBasePath ++ ["settings"];
renamedOptions = [
{old = ["performance" "debounce"];}
{old = ["performance" "throttle"];}
{
old = ["performance" "fetchingTimeout"];
new = ["performance" "fetching_timeout"];
}
{
old = ["performance" "asyncBudget"];
new = ["performance" "async_budget"];
}
{
old = ["performance" "maxViewEntries"];
new = ["performance" "max_view_entries"];
}
{old = ["mapping"];}
{
old = ["completion" "keywordLength"];
new = ["completion" "keyword_length"];
}
{
old = ["completion" "keywordPattern"];
new = ["completion" "keyword_pattern"];
}
{old = ["completion" "autocomplete"];}
{old = ["completion" "completeopt"];}
{
old = ["confirmation" "getCommitCharacters"];
new = ["confirmation" "get_commit_characters"];
}
{
old = ["formatting" "expandableIndicator"];
new = ["formatting" "expandable_indicator"];
}
{old = ["formatting" "fields"];}
{old = ["formatting" "format"];}
{
old = ["matching" "disallowFuzzyMatching"];
new = ["matching" "disallow_fuzzy_matching"];
}
{
old = ["matching" "disallowFullfuzzyMatching"];
new = ["matching" "disallow_fullfuzzy_matching"];
}
{
old = ["matching" "disallowPartialFuzzyMatching"];
new = ["matching" "disallow_partial_fuzzy_matching"];
}
{
old = ["matching" "disallowPartialMatching"];
new = ["matching" "disallow_partial_matching"];
}
{
old = ["matching" "disallowPrefixUnmatching"];
new = ["matching" "disallow_prefix_unmatching"];
}
{
old = ["sorting" "priorityWeight"];
new = ["sorting" "priority_weight"];
}
{old = ["view" "entries"];}
{
old = ["view" "docs" "autoOpen"];
new = ["view" "docs" "auto_open"];
}
{old = ["window" "completion" "border"];}
{old = ["window" "completion" "winhighlight"];}
{old = ["window" "completion" "zindex"];}
{old = ["window" "completion" "scrolloff"];}
{
old = ["window" "completion" "colOffset"];
new = ["window" "completion" "col_offset"];
}
{
old = ["window" "completion" "sidePadding"];
new = ["window" "completion" "side_padding"];
}
{old = ["window" "completion" "scrollbar"];}
{old = ["window" "documentation" "border"];}
{old = ["window" "documentation" "winhighlight"];}
{old = ["window" "documentation" "zindex"];}
{
old = ["window" "documentation" "maxWidth"];
new = ["window" "documentation" "max_width"];
}
{
old = ["window" "documentation" "maxHeight"];
new = ["window" "documentation" "max_height"];
}
{old = ["experimental"];}
];
renameWarnings =
map
(
rename:
mkRenamedOptionModule
(oldPluginBasePath ++ rename.old)
(settingsPath ++ (rename.new or rename.old))
)
renamedOptions;
in {
imports =
renameWarnings
++ [
(
mkRemovedOptionModule
(oldPluginBasePath ++ ["preselect"])
''
Use `plugins.cmp.settings.preselect` option. But watch out, you now have to explicitly write `cmp.PreselectMode.<mode>`.
See the option documentation for more details.
''
)
(
mkRemovedOptionModule
(oldPluginBasePath ++ ["mappingPresets"])
"If you want to have a complex mapping logic, express it in raw lua within the `plugins.cmp.settings.mapping` option."
)
(
mkRemovedOptionModule
(oldPluginBasePath ++ ["snippet" "expand"])
''
Use `plugins.cmp.settings.snippet.expand` option. But watch out, you can no longer put only the name of the snippet engine.
If you use `luasnip` for instance, set:
```
plugins.cmp.settings.snippet.expand = "function(args) require('luasnip').lsp_expand(args.body) end";
```
''
)
(
mkRemovedOptionModule
(oldPluginBasePath ++ ["sorting" "comparators"])
''
Use `plugins.cmp.settings.sorting.comparators` option. But watch out, you can no longer put only the name of the comparators.
See the option documentation for more details.
''
)
(
mkRemovedOptionModule
(oldPluginBasePath ++ ["sources"])
''
Use `plugins.cmp.settings.sources` option. But watch out, you can no longer provide a list of lists of sources.
For this type of use, directly write lua.
See the option documentation for more details.
''
)
];
}

View file

@ -0,0 +1,82 @@
{
lib,
helpers,
}:
with lib; rec {
settingsOptions = import ./settings-options.nix {inherit lib helpers;};
settingsExample = {
snippet.expand = "luasnip";
mapping.__raw = ''
cmp.mapping.preset.insert({
['<C-b>'] = cmp.mapping.scroll_docs(-4),
['<C-f>'] = cmp.mapping.scroll_docs(4),
['<C-Space>'] = cmp.mapping.complete(),
['<C-e>'] = cmp.mapping.abort(),
['<CR>'] = cmp.mapping.confirm({ select = true }),
})
'';
sources.__raw = ''
cmp.config.sources({
{ name = 'nvim_lsp' },
{ name = 'vsnip' },
-- { name = 'luasnip' },
-- { name = 'ultisnips' },
-- { name = 'snippy' },
}, {
{ name = 'buffer' },
})
'';
};
attrsOfOptions = with types;
attrsOf (
submodule {
freeformType = attrsOf anything;
options = settingsOptions;
}
);
filetype = mkOption {
type = attrsOfOptions;
default = {};
description = "Options for `cmp.filetype()`.";
example = {
python = {
sources = [
{name = "nvim_lsp";}
];
};
};
};
cmdline = mkOption {
type = attrsOfOptions;
default = {};
description = "Options for `cmp.cmdline()`.";
example = {
"/" = {
mapping.__raw = "cmp.mapping.preset.cmdline()";
sources = [
{name = "buffer";}
];
};
":" = {
mapping.__raw = "cmp.mapping.preset.cmdline()";
sources = [
[
{name = "path";}
]
[
{
name = "cmdline";
option = {
ignore_cmds = ["Man" "!"];
};
}
]
];
};
};
};
}

View file

@ -0,0 +1,350 @@
{
lib,
helpers,
}:
with lib; {
performance = {
debounce = helpers.defaultNullOpts.mkUnsignedInt 60 ''
Sets debounce time.
This is the interval used to group up completions from different sources for filtering and
displaying.
'';
throttle = helpers.defaultNullOpts.mkUnsignedInt 30 ''
Sets throttle time.
This is used to delay filtering and displaying completions.
'';
fetching_timeout = helpers.defaultNullOpts.mkUnsignedInt 500 ''
Sets the timeout of candidate fetching process.
The nvim-cmp will wait to display the most prioritized source.
'';
confirm_resolve_timeout = helpers.defaultNullOpts.mkUnsignedInt 80 ''
Sets the timeout for resolving item before confirmation.
'';
async_budget = helpers.defaultNullOpts.mkUnsignedInt 1 ''
Maximum time (in ms) an async function is allowed to run during one step of the event loop.
'';
max_view_entries = helpers.defaultNullOpts.mkUnsignedInt 200 ''
Maximum number of items to show in the entries list.
'';
};
preselect = helpers.defaultNullOpts.mkLua "cmp.PreselectMode.Item" ''
- "cmp.PreselectMode.Item": nvim-cmp will preselect the item that the source specified.
- "cmp.PreselectMode.None": nvim-cmp will not preselect any items.
'';
mapping = mkOption {
default = {};
type = with helpers.nixvimTypes;
maybeRaw
(attrsOf strLua);
apply = v:
# Handle the raw case first
if helpers.nixvimTypes.isRawType v
then v
# When v is an attrs **but not {__raw = ...}**
else mapAttrs (_: helpers.mkRaw) v;
example = {
"<C-d>" = "cmp.mapping.scroll_docs(-4)";
"<C-f>" = "cmp.mapping.scroll_docs(4)";
"<C-Space>" = "cmp.mapping.complete()";
"<C-e>" = "cmp.mapping.close()";
"<Tab>" = "cmp.mapping(cmp.mapping.select_next_item(), {'i', 's'})";
"<S-Tab>" = "cmp.mapping(cmp.mapping.select_prev_item(), {'i', 's'})";
"<CR>" = "cmp.mapping.confirm({ select = true })";
};
};
snippet = {
expand = mkOption {
type = with helpers.nixvimTypes; nullOr strLuaFn;
default = null;
description = ''
The snippet expansion function. That's how nvim-cmp interacts with a particular snippet
engine.
Common engines:
```lua
function(args)
# vsnip
vim.fn["vsnip#anonymous"](args.body)
# luasnip
require('luasnip').lsp_expand(args.body)
# snippy
require('snippy').expand_snippet(args.body)
# ultisnips
vim.fn["UltiSnips#Anon"](args.body)
end
```
You can also provide a custom function:
```lua
function(args)
vim.fn["vsnip#anonymous"](args.body) -- For `vsnip` users.
-- require('luasnip').lsp_expand(args.body) -- For `luasnip` users.
-- require('snippy').expand_snippet(args.body) -- For `snippy` users.
-- vim.fn["UltiSnips#Anon"](args.body) -- For `ultisnips` users.
end
```
'';
apply = helpers.mkRaw;
example = ''
function(args)
require('luasnip').lsp_expand(args.body)
end
'';
};
};
completion = {
keyword_length = helpers.defaultNullOpts.mkUnsignedInt 1 ''
The number of characters needed to trigger auto-completion.
'';
keyword_pattern =
helpers.defaultNullOpts.mkLua
''[[\%(-\?\d\+\%(\.\d\+\)\?\|\h\w*\%(-\w*\)*\)]]''
"The default keyword pattern.";
autocomplete =
helpers.defaultNullOpts.mkNullable
(
with helpers.nixvimTypes;
either
(enum [false])
(listOf strLua)
)
''["require('cmp.types').cmp.TriggerEvent.TextChanged"]''
''
The event to trigger autocompletion.
If set to `false`, then completion is only invoked manually (e.g. by calling `cmp.complete`).
'';
completeopt = helpers.defaultNullOpts.mkStr "menu,menuone,noselect" ''
Like vim's completeopt setting.
In general, you don't need to change this.
'';
};
confirmation = {
get_commit_characters =
helpers.defaultNullOpts.mkLuaFn
''
function(commit_characters)
return commit_characters
end
''
''
You can append or exclude `commitCharacters` via this configuration option function.
The `commitCharacters` are defined by the LSP spec.
'';
};
formatting = {
expandable_indicator = helpers.defaultNullOpts.mkBool true ''
Boolean to show the `~` expandable indicator in cmp's floating window.
'';
fields = helpers.defaultNullOpts.mkListOf types.str ''["abbr" "kind" "menu"]'' ''
An array of completion fields to specify their order.
'';
format =
helpers.defaultNullOpts.mkLuaFn
''
function(_, vim_item)
return vim_item
end
''
''
`fun(entry: cmp.Entry, vim_item: vim.CompletedItem): vim.CompletedItem`
The function used to customize the appearance of the completion menu.
See `|complete-items|`.
This value can also be used to modify the `dup` property.
NOTE: The `vim.CompletedItem` can contain the special properties `abbr_hl_group`,
`kind_hl_group` and `menu_hl_group`.
'';
};
matching = {
disallow_fuzzy_matching = helpers.defaultNullOpts.mkBool false ''
Whether to allow fuzzy matching.
'';
disallow_fullfuzzy_matching = helpers.defaultNullOpts.mkBool false ''
Whether to allow full-fuzzy matching.
'';
disallow_partial_fuzzy_matching = helpers.defaultNullOpts.mkBool true ''
Whether to allow fuzzy matching without prefix matching.
'';
disallow_partial_matching = helpers.defaultNullOpts.mkBool false ''
Whether to allow partial matching.
'';
disallow_prefix_unmatching = helpers.defaultNullOpts.mkBool false ''
Whether to allow prefix unmatching.
'';
};
sorting = {
priority_weight = helpers.defaultNullOpts.mkUnsignedInt 2 ''
Each item's original priority (given by its corresponding source) will be increased by
`#sources - (source_index - 1)` and multiplied by `priority_weight`.
That is, the final priority is calculated by the following formula:
`final_score = orig_score + ((#sources - (source_index - 1)) * sorting.priority_weight)`
'';
comparators = mkOption {
type = with helpers.nixvimTypes; nullOr (listOf strLuaFn);
apply = v:
helpers.ifNonNull' v (
map
helpers.mkRaw
v
);
default = null;
description = ''
The function to customize the sorting behavior.
You can use built-in comparators via `cmp.config.compare.*`.
Signature: `(fun(entry1: cmp.Entry, entry2: cmp.Entry): boolean | nil)[]`
Default:
```nix
[
"require('cmp.config.compare').offset"
"require('cmp.config.compare').exact"
"require('cmp.config.compare').score"
"require('cmp.config.compare').recently_used"
"require('cmp.config.compare').locality"
"require('cmp.config.compare').kind"
"require('cmp.config.compare').length"
"require('cmp.config.compare').order"
]
```
'';
};
};
sources = import ./sources-option.nix {inherit lib helpers;};
view = {
entries =
helpers.defaultNullOpts.mkNullable
(
with types;
either
str
(attrsOf anything)
)
''
{
name = "custom";
selection_order = "top_down";
}
''
''
The view class used to customize nvim-cmp's appearance.
'';
docs = {
auto_open = helpers.defaultNullOpts.mkBool true ''
Specify whether to show the docs_view when selecting an item.
'';
};
};
window = let
mkWinhighlightOption = default:
helpers.defaultNullOpts.mkStr
default
''
Specify the window's winhighlight option.
See `|nvim_open_win|`.
'';
zindex = helpers.mkNullOrOption types.ints.unsigned ''
The window's zindex.
See `|nvim_open_win|`.
'';
in {
completion = {
border =
helpers.defaultNullOpts.mkBorder
''[ "" "" "" "" "" "" "" "" ]''
"nvim-cmp completion popup menu"
"";
winhighlight =
mkWinhighlightOption
"Normal:Pmenu,FloatBorder:Pmenu,CursorLine:PmenuSel,Search:None";
inherit zindex;
scrolloff = helpers.defaultNullOpts.mkUnsignedInt 0 ''
Specify the window's scrolloff option.
See |'scrolloff'|.
'';
col_offset = helpers.defaultNullOpts.mkUnsignedInt 0 ''
Offsets the completion window relative to the cursor.
'';
side_padding = helpers.defaultNullOpts.mkUnsignedInt 1 ''
The amount of padding to add on the completion window's sides.
'';
scrollbar = helpers.defaultNullOpts.mkBool true ''
Whether the scrollbar should be enabled if there are more items that fit.
'';
};
documentation = {
border =
helpers.defaultNullOpts.mkBorder
''[ "" "" "" " " "" "" "" " " ]''
"nvim-cmp documentation popup menu"
"";
winhighlight = mkWinhighlightOption "FloatBorder:NormalFloat";
inherit zindex;
max_width =
helpers.mkNullOrStrLuaOr types.ints.unsigned
''
The documentation window's max width.
Default: "math.floor((40 * 2) * (vim.o.columns / (40 * 2 * 16 / 9)))"
'';
max_height =
helpers.mkNullOrStrLuaOr types.ints.unsigned
''
The documentation window's max height.
Default: "math.floor(40 * (40 / vim.o.lines))"
'';
};
};
# This can be kept as types.attrs since experimental features are often removed or completely
# changed after a while
experimental = helpers.mkNullOrOption (with types; attrsOf anything) ''
Experimental features.
'';
}

View file

@ -0,0 +1,107 @@
{
lib,
helpers,
}:
with lib; let
sourceType = types.submodule {
freeformType = with types; attrsOf anything;
options = {
name = mkOption {
type = types.str;
description = "The name of the source.";
example = "buffer";
};
option = helpers.mkNullOrOption (with types; attrsOf anything) ''
Any specific options defined by the source itself.
If direct lua code is needed use `helpers.mkRaw`.
'';
keyword_length = helpers.mkNullOrOption types.ints.unsigned ''
The source-specific keyword length to trigger auto completion.
'';
keyword_pattern = helpers.mkNullOrLua ''
The source-specific keyword pattern.
'';
trigger_characters = helpers.mkNullOrOption (with types; listOf str) ''
Trigger characters.
'';
priority = helpers.mkNullOrOption types.ints.unsigned ''
The source-specific priority value.
'';
group_index = helpers.mkNullOrOption types.ints.unsigned ''
The source group index.
For instance, you can set the `buffer`'s source `group_index` to a larger number
if you don't want to see `buffer` source items while `nvim-lsp` source is available:
```nix
sources = [
{
name = "nvim_lsp";
group_index = 1;
}
{
name = "buffer";
group_index = 2;
}
];
```
'';
entry_filter = helpers.mkNullOrLuaFn ''
A source-specific entry filter, with the following function signature:
`function(entry: cmp.Entry, ctx: cmp.Context): boolean`
Returning `true` will keep the entry, while returning `false` will remove it.
This can be used to hide certain entries from a given source. For instance, you
could hide all entries with kind `Text` from the `nvim_lsp` filter using the
following source definition:
```nix
{
name = "nvim_lsp";
entry_filter = \'\'
function(entry, ctx)
return require('cmp.types').lsp.CompletionItemKind[entry:get_kind()] ~= 'Text'
end
\'\';
}
```
Using the `ctx` parameter, you can further customize the behaviour of the source.
'';
};
};
in
mkOption {
default = [];
type = with helpers.nixvimTypes;
maybeRaw (listOf sourceType);
description = ''
The sources to use.
Can either be a list of `sourceConfigs` which will be made directly to a Lua object.
Or it can be a raw lua string which might be necessary for more advanced use cases.
WARNING:
If `plugins.cmp.autoEnableSources` Nixivm will automatically enable the corresponding source
plugins. This will work only when this option is set to a list.
If you use a raw lua string, you will need to explicitly enable the relevant source plugins in
your nixvim configuration.
Default: `[]`
'';
example = [
{name = "nvim_lsp";}
{name = "luasnip";}
{name = "path";}
{name = "buffer";}
];
}

View file

@ -0,0 +1,44 @@
{
lib,
helpers,
config,
...
}:
with lib; let
cfg = config.plugins.cmp-tabby;
in {
meta.maintainers = [maintainers.GaetanLepage];
options.plugins.cmp-tabby =
helpers.neovim-plugin.extraOptionsOptions
// {
host = helpers.defaultNullOpts.mkStr "http://localhost:5000" ''
The adress of the tabby host server.
'';
maxLines = helpers.defaultNullOpts.mkUnsignedInt 100 ''
The max number of lines to complete.
'';
runOnEveryKeyStroke = helpers.defaultNullOpts.mkBool true ''
Whether to run the completion on every keystroke.
'';
stop = helpers.defaultNullOpts.mkListOf types.str ''["\n"]'' "";
};
config = mkIf cfg.enable {
extraConfigLua = let
setupOptions = with cfg;
{
inherit host;
max_lines = maxLines;
run_on_every_keystroke = runOnEveryKeyStroke;
inherit stop;
}
// cfg.extraOptions;
in ''
require('cmp_tabby.config'):setup(${helpers.toLuaObject setupOptions})
'';
};
}

View file

@ -0,0 +1,17 @@
{
lib,
helpers,
config,
...
}:
with lib; let
cfg = config.plugins.cmp-tabnine;
in {
options.plugins.cmp-tabnine = helpers.neovim-plugin.extraOptionsOptions;
config = mkIf cfg.enable {
extraConfigLua = ''
require('cmp_tabnine.config'):setup(${helpers.toLuaObject cfg.extraOptions})
'';
};
}

View file

@ -0,0 +1,89 @@
{
lib,
helpers,
config,
pkgs,
...
}:
with lib; let
cfg = config.plugins.codeium-nvim;
in {
meta.maintainers = [maintainers.GaetanLepage];
options.plugins.codeium-nvim =
helpers.neovim-plugin.extraOptionsOptions
// {
package = helpers.mkPackageOption "codeium.nvim" pkgs.vimPlugins.codeium-nvim;
configPath =
helpers.defaultNullOpts.mkStr
''{__raw = "vim.fn.stdpath('cache') .. '/codeium/config.json'";}''
"The path to the config file, used to store the API key.";
binPath =
helpers.defaultNullOpts.mkStr
''{__raw = "vim.fn.stdpath('cache') .. '/codeium/bin'";}''
"The path to the directory where the Codeium server will be downloaded to.";
api = {
host = helpers.defaultNullOpts.mkStr "server.codeium.com" ''
The hostname of the API server to use.
'';
port = helpers.defaultNullOpts.mkPositiveInt 443 ''
The port of the API server to use.
'';
};
tools = {
uname = helpers.mkNullOrOption types.str "The path to the `uname` binary.";
uuidgen = helpers.mkNullOrOption types.str "The path to the `uuidgen` binary.";
curl = helpers.mkNullOrOption types.str "The path to the `curl` binary.";
gzip = helpers.mkNullOrOption types.str "The path to the `gzip` binary.";
languageServer = helpers.mkNullOrOption types.str ''
The path to the language server downloaded from the official source.
'';
};
wrapper = helpers.mkNullOrOption types.str ''
The path to a wrapper script/binary that is used to execute any binaries not listed under
tools.
This is primarily useful for NixOS, where a FHS wrapper can be used for the downloaded
codeium server.
'';
};
config = mkIf cfg.enable {
extraConfigLua = let
setupOptions = with cfg;
{
config_path = configPath;
bin_path = binPath;
api = with api; {
inherit host;
port =
if isInt port
then toString port
else port;
};
tools = with tools; {
inherit
uname
uuidgen
curl
gzip
;
language_server = languageServer;
};
inherit wrapper;
}
// cfg.extraOptions;
in ''
require('codeium').setup(${helpers.toLuaObject setupOptions})
'';
};
}

View file

@ -0,0 +1,66 @@
{
lib,
helpers,
config,
...
}:
with lib; let
copilot-lua-cfg = config.plugins.copilot-lua;
cfg = config.plugins.copilot-cmp;
in {
options.plugins.copilot-cmp =
helpers.neovim-plugin.extraOptionsOptions
// {
event =
helpers.defaultNullOpts.mkNullable
(with types; listOf str)
''["InsertEnter" "LspAttach"]''
''
Configures when the source is registered.
Unless you have a unique problem for your particular configuration you probably don't want
to touch this.
'';
fixPairs = helpers.defaultNullOpts.mkBool true ''
Suppose you have the following code: `print('h')`.
Copilot might try to account for the `'` and `)` and complete it with this: `print('hello`.
This is not good behavior for consistency reasons and will just end up deleting the two ending
characters.
This option fixes that.
Don't turn this off unless you are having problems with pairs and believe this might be
causing them.
'';
};
config = mkIf cfg.enable {
warnings =
optional
((!isBool copilot-lua-cfg.suggestion.enabled) || copilot-lua-cfg.suggestion.enabled)
''
It is recommended to disable copilot's `suggestion` module, as it can interfere with
completions properly appearing in copilot-cmp.
''
++ optional
(
(!isBool copilot-lua-cfg.panel.enabled) || copilot-lua-cfg.panel.enabled
)
''
It is recommended to disable copilot's `panel` module, as it can interfere with completions
properly appearing in copilot-cmp.
'';
plugins.copilot-lua.enable = true;
extraConfigLua = let
setupOptions = with cfg;
{
inherit event;
fix_pairs = fixPairs;
}
// cfg.extraOptions;
in ''
require('copilot_cmp').setup(${helpers.toLuaObject setupOptions})
'';
};
}

View file

@ -0,0 +1,17 @@
{
lib,
helpers,
config,
...
}:
with lib; let
cfg = config.plugins.crates-nvim;
in {
options.plugins.crates-nvim = helpers.neovim-plugin.extraOptionsOptions;
config = mkIf cfg.enable {
extraConfigLua = ''
require('crates').setup(${helpers.toLuaObject cfg.extraOptions})
'';
};
}

View file

@ -0,0 +1,29 @@
{
lib,
config,
helpers,
pkgs,
...
}:
with lib; let
cmpLib = import ../cmp-helpers.nix {inherit lib config helpers pkgs;};
cmpSourcesPluginNames = attrValues cmpLib.pluginAndSourceNames;
pluginModules =
map
(
name:
cmpLib.mkCmpSourcePlugin {inherit name;}
)
cmpSourcesPluginNames;
in {
# For extra cmp plugins
imports =
[
./codeium-nvim.nix
./copilot-cmp.nix
./cmp-tabby.nix
./cmp-tabnine.nix
./crates-nvim.nix
]
++ pluginModules;
}