mirror of
https://github.com/nix-community/nixvim.git
synced 2025-06-24 09:48:42 +02:00
plugins/nvim-cmp: refactoring (init filetype and cmdline options)
This commit is contained in:
parent
22b587f3dc
commit
a61c8fbc3d
26 changed files with 1166 additions and 948 deletions
|
@ -173,7 +173,7 @@ in {
|
||||||
# }
|
# }
|
||||||
# bufferline = helpers.defaultNullOpts.mkBool false "";
|
# bufferline = helpers.defaultNullOpts.mkBool false "";
|
||||||
|
|
||||||
cmp = helpers.defaultNullOpts.mkBool config.plugins.nvim-cmp.enable "";
|
cmp = helpers.defaultNullOpts.mkBool config.plugins.cmp.enable "";
|
||||||
|
|
||||||
coc_nvim = helpers.defaultNullOpts.mkBool false "";
|
coc_nvim = helpers.defaultNullOpts.mkBool false "";
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
with helpers.vim-plugin;
|
with helpers.vim-plugin;
|
||||||
with lib; {
|
with lib; rec {
|
||||||
mkCmpSourcePlugin = {
|
mkCmpSourcePlugin = {
|
||||||
name,
|
name,
|
||||||
extraPlugins ? [],
|
extraPlugins ? [],
|
||||||
|
@ -16,6 +16,7 @@ with lib; {
|
||||||
mkVimPlugin config {
|
mkVimPlugin config {
|
||||||
inherit name;
|
inherit name;
|
||||||
extraPlugins = extraPlugins ++ (lists.optional useDefaultPackage pkgs.vimPlugins.${name});
|
extraPlugins = extraPlugins ++ (lists.optional useDefaultPackage pkgs.vimPlugins.${name});
|
||||||
|
|
||||||
maintainers = [maintainers.GaetanLepage];
|
maintainers = [maintainers.GaetanLepage];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -63,4 +64,62 @@ with lib; {
|
||||||
"vsnip" = "cmp-vsnip";
|
"vsnip" = "cmp-vsnip";
|
||||||
"zsh" = "cmp-zsh";
|
"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
|
||||||
|
];
|
||||||
}
|
}
|
83
plugins/completion/cmp/default.nix
Normal file
83
plugins/completion/cmp/default.nix
Normal 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;
|
||||||
|
};
|
||||||
|
}
|
154
plugins/completion/cmp/deprecations.nix
Normal file
154
plugins/completion/cmp/deprecations.nix
Normal 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.
|
||||||
|
''
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
82
plugins/completion/cmp/options/default.nix
Normal file
82
plugins/completion/cmp/options/default.nix
Normal 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" "!"];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
]
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
350
plugins/completion/cmp/options/settings-options.nix
Normal file
350
plugins/completion/cmp/options/settings-options.nix
Normal 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.
|
||||||
|
'';
|
||||||
|
}
|
107
plugins/completion/cmp/options/sources-option.nix
Normal file
107
plugins/completion/cmp/options/sources-option.nix
Normal 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";}
|
||||||
|
];
|
||||||
|
}
|
|
@ -8,7 +8,13 @@
|
||||||
with lib; let
|
with lib; let
|
||||||
cmpLib = import ../cmp-helpers.nix {inherit lib config helpers pkgs;};
|
cmpLib = import ../cmp-helpers.nix {inherit lib config helpers pkgs;};
|
||||||
cmpSourcesPluginNames = attrValues cmpLib.pluginAndSourceNames;
|
cmpSourcesPluginNames = attrValues cmpLib.pluginAndSourceNames;
|
||||||
pluginModules = lists.map (name: cmpLib.mkCmpSourcePlugin {inherit name;}) cmpSourcesPluginNames;
|
pluginModules =
|
||||||
|
map
|
||||||
|
(
|
||||||
|
name:
|
||||||
|
cmpLib.mkCmpSourcePlugin {inherit name;}
|
||||||
|
)
|
||||||
|
cmpSourcesPluginNames;
|
||||||
in {
|
in {
|
||||||
# For extra cmp plugins
|
# For extra cmp plugins
|
||||||
imports =
|
imports =
|
|
@ -49,7 +49,7 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
config = let
|
config = let
|
||||||
doCmp = cfg.cmp.enable && config.plugins.nvim-cmp.enable;
|
doCmp = cfg.cmp.enable && config.plugins.cmp.enable;
|
||||||
options =
|
options =
|
||||||
{
|
{
|
||||||
inherit (cfg) mode preset;
|
inherit (cfg) mode preset;
|
||||||
|
@ -73,7 +73,7 @@ in {
|
||||||
require('lspkind').init(${helpers.toLuaObject options})
|
require('lspkind').init(${helpers.toLuaObject options})
|
||||||
'';
|
'';
|
||||||
|
|
||||||
plugins.nvim-cmp.formatting.format =
|
plugins.cmp.settings.formatting.format =
|
||||||
if cfg.cmp.after != null
|
if cfg.cmp.after != null
|
||||||
then ''
|
then ''
|
||||||
function(entry, vim_item)
|
function(entry, vim_item)
|
||||||
|
|
|
@ -1,578 +0,0 @@
|
||||||
{
|
|
||||||
lib,
|
|
||||||
helpers,
|
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
} @ args:
|
|
||||||
with lib; let
|
|
||||||
cfg = config.plugins.nvim-cmp;
|
|
||||||
cmpLib = import ./cmp-helpers.nix args;
|
|
||||||
in {
|
|
||||||
options.plugins.nvim-cmp =
|
|
||||||
helpers.neovim-plugin.extraOptionsOptions
|
|
||||||
// {
|
|
||||||
enable = mkEnableOption "nvim-cmp";
|
|
||||||
|
|
||||||
package = helpers.mkPackageOption "nvim-cmp" pkgs.vimPlugins.nvim-cmp;
|
|
||||||
|
|
||||||
performance = {
|
|
||||||
debounce = helpers.defaultNullOpts.mkInt 60 ''
|
|
||||||
Sets debounce time
|
|
||||||
This is the interval used to group up completions from different sources
|
|
||||||
for filtering and displaying.
|
|
||||||
'';
|
|
||||||
|
|
||||||
throttle = helpers.defaultNullOpts.mkInt 30 ''
|
|
||||||
Sets throttle time.
|
|
||||||
This is used to delay filtering and displaying completions.
|
|
||||||
'';
|
|
||||||
|
|
||||||
fetchingTimeout = helpers.defaultNullOpts.mkInt 500 ''
|
|
||||||
Sets the timeout of candidate fetching process.
|
|
||||||
The nvim-cmp will wait to display the most prioritized source.
|
|
||||||
'';
|
|
||||||
|
|
||||||
asyncBudget = helpers.defaultNullOpts.mkInt 1 ''
|
|
||||||
Maximum time (in ms) an async function is allowed to run during one step of the event loop.
|
|
||||||
'';
|
|
||||||
|
|
||||||
maxViewEntries = helpers.defaultNullOpts.mkInt 200 ''
|
|
||||||
Maximum number of items to show in the entries list.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
preselect = mkOption {
|
|
||||||
type = with types; nullOr (enum ["Item" "None"]);
|
|
||||||
apply = v:
|
|
||||||
helpers.ifNonNull' v
|
|
||||||
(helpers.mkRaw "cmp.PreselectMode.${v}");
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
- "Item": nvim-cmp will preselect the item that the source specified.
|
|
||||||
- "None": nvim-cmp will not preselect any items.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
mapping = mkOption {
|
|
||||||
default = {};
|
|
||||||
type = with types;
|
|
||||||
attrsOf
|
|
||||||
(
|
|
||||||
either
|
|
||||||
str
|
|
||||||
(
|
|
||||||
submodule {
|
|
||||||
options = {
|
|
||||||
action = mkOption {
|
|
||||||
type = nonEmptyStr;
|
|
||||||
description = "The function the mapping should call";
|
|
||||||
example = ''"cmp.mapping.scroll_docs(-4)"'';
|
|
||||||
};
|
|
||||||
modes = mkOption {
|
|
||||||
default = null;
|
|
||||||
type = nullOr (listOf str);
|
|
||||||
example = ''[ "i" "s" ]'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
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>" = {
|
|
||||||
modes = ["i" "s"];
|
|
||||||
action = "cmp.mapping.select_next_item()";
|
|
||||||
};
|
|
||||||
"<S-Tab>" = {
|
|
||||||
modes = ["i" "s"];
|
|
||||||
action = "cmp.mapping.select_prev_item()";
|
|
||||||
};
|
|
||||||
"<CR>" = "cmp.mapping.confirm({ select = true })";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
mappingPresets = mkOption {
|
|
||||||
default = [];
|
|
||||||
type = with types;
|
|
||||||
listOf (enum ["insert" "cmdline"]);
|
|
||||||
description = ''
|
|
||||||
Mapping presets to use; cmp.mapping.preset.
|
|
||||||
\$\{mappingPreset} will be called with the configured mappings.
|
|
||||||
'';
|
|
||||||
example = ''[ "insert" "cmdline" ]'';
|
|
||||||
};
|
|
||||||
|
|
||||||
snippet = {
|
|
||||||
expand = let
|
|
||||||
snippetEngines = {
|
|
||||||
"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)'';
|
|
||||||
};
|
|
||||||
in
|
|
||||||
mkOption {
|
|
||||||
default = null;
|
|
||||||
type = with types;
|
|
||||||
nullOr
|
|
||||||
(
|
|
||||||
either
|
|
||||||
helpers.nixvimTypes.rawLua
|
|
||||||
(enum (attrNames snippetEngines))
|
|
||||||
);
|
|
||||||
apply = v:
|
|
||||||
if isString v
|
|
||||||
then
|
|
||||||
helpers.mkRaw ''
|
|
||||||
function(args)
|
|
||||||
${snippetEngines.${v}}
|
|
||||||
end
|
|
||||||
''
|
|
||||||
else v;
|
|
||||||
description = ''
|
|
||||||
The snippet expansion function. That's how nvim-cmp interacts with a
|
|
||||||
particular snippet engine.
|
|
||||||
|
|
||||||
You may directly provide one of those four supported engines:
|
|
||||||
- vsnip
|
|
||||||
- luasnip
|
|
||||||
- snippy
|
|
||||||
- ultisnips
|
|
||||||
|
|
||||||
You can also provide a custom function:
|
|
||||||
```nix
|
|
||||||
{
|
|
||||||
__raw = \'\'
|
|
||||||
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
|
|
||||||
\'\';
|
|
||||||
};
|
|
||||||
```
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
completion = {
|
|
||||||
keywordLength = helpers.defaultNullOpts.mkInt 1 ''
|
|
||||||
The number of characters needed to trigger auto-completion.
|
|
||||||
'';
|
|
||||||
|
|
||||||
keywordPattern = mkOption {
|
|
||||||
type = with types; nullOr str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
The default keyword pattern.
|
|
||||||
|
|
||||||
Note: the provided pattern will be embedded as such: `[[PATTERN]]`.
|
|
||||||
|
|
||||||
Default: "\%(-\?\d\+\%(\.\d\+\)\?\|\h\w*\%(-\w*\)*\)"
|
|
||||||
'';
|
|
||||||
apply = v:
|
|
||||||
helpers.ifNonNull'
|
|
||||||
v
|
|
||||||
(helpers.mkRaw "[[${v}]]");
|
|
||||||
};
|
|
||||||
|
|
||||||
autocomplete = mkOption {
|
|
||||||
type = with types;
|
|
||||||
nullOr
|
|
||||||
(
|
|
||||||
either
|
|
||||||
(listOf str)
|
|
||||||
(types.enum [false])
|
|
||||||
);
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
The event to trigger autocompletion.
|
|
||||||
If set to `"false"`, then completion is only invoked manually
|
|
||||||
(e.g. by calling `cmp.complete`).
|
|
||||||
|
|
||||||
Default: ["TextChanged"]
|
|
||||||
'';
|
|
||||||
apply = v:
|
|
||||||
if isList v
|
|
||||||
then
|
|
||||||
map
|
|
||||||
(triggerEvent:
|
|
||||||
helpers.mkRaw "require('cmp.types').cmp.TriggerEvent.${triggerEvent}")
|
|
||||||
v
|
|
||||||
# either null or false
|
|
||||||
else v;
|
|
||||||
};
|
|
||||||
|
|
||||||
completeopt = helpers.defaultNullOpts.mkStr "menu,menuone,noselect" ''
|
|
||||||
Like vim's completeopt setting. In general, you don't need to change this.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
confirmation = {
|
|
||||||
getCommitCharacters =
|
|
||||||
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 = {
|
|
||||||
expandableIndicator = helpers.defaultNullOpts.mkBool true ''
|
|
||||||
Boolean to show the `~` expandable indicator in cmp's floating window.
|
|
||||||
'';
|
|
||||||
|
|
||||||
fields =
|
|
||||||
helpers.defaultNullOpts.mkNullable
|
|
||||||
(with types; listOf str)
|
|
||||||
''[ "kind" "abbr" "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 = {
|
|
||||||
disallowFuzzyMatching = helpers.defaultNullOpts.mkBool false ''
|
|
||||||
Whether to allow fuzzy matching.
|
|
||||||
'';
|
|
||||||
|
|
||||||
disallowFullfuzzyMatching = helpers.defaultNullOpts.mkBool false ''
|
|
||||||
Whether to allow full-fuzzy matching.
|
|
||||||
'';
|
|
||||||
|
|
||||||
disallowPartialFuzzyMatching = helpers.defaultNullOpts.mkBool true ''
|
|
||||||
Whether to allow fuzzy matching without prefix matching.
|
|
||||||
'';
|
|
||||||
|
|
||||||
disallowPartialMatching = helpers.defaultNullOpts.mkBool false ''
|
|
||||||
Whether to allow partial matching.
|
|
||||||
'';
|
|
||||||
|
|
||||||
disallowPrefixUnmatching = helpers.defaultNullOpts.mkBool false ''
|
|
||||||
Whether to allow prefix unmatching.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
sorting = {
|
|
||||||
priorityWeight = helpers.defaultNullOpts.mkInt 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
|
|
||||||
(
|
|
||||||
funcName:
|
|
||||||
helpers.mkRaw "require('cmp.config.compare').${funcName}"
|
|
||||||
)
|
|
||||||
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: ["offset" "exact" "score" "recently_used" "locality" "kind" "length" "order"]
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
autoEnableSources = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = ''
|
|
||||||
Scans the sources array and installs the plugins if they are known to nixvim.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
sources = let
|
|
||||||
source_config = types.submodule {
|
|
||||||
options = {
|
|
||||||
name = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "The name of the source.";
|
|
||||||
example = "buffer";
|
|
||||||
};
|
|
||||||
|
|
||||||
option = helpers.mkNullOrOption types.attrs ''
|
|
||||||
Any specific options defined by the source itself.
|
|
||||||
|
|
||||||
If direct lua code is needed use `helpers.mkRaw`.
|
|
||||||
'';
|
|
||||||
|
|
||||||
keywordLength = helpers.mkNullOrOption types.int ''
|
|
||||||
The source-specific keyword length to trigger auto completion.
|
|
||||||
'';
|
|
||||||
|
|
||||||
keywordPattern = helpers.mkNullOrOption types.str ''
|
|
||||||
The source-specific keyword pattern.
|
|
||||||
|
|
||||||
Note: the provided pattern will be embedded as such: `[[PATTERN]]`.
|
|
||||||
'';
|
|
||||||
|
|
||||||
triggerCharacters = helpers.mkNullOrOption (with types; listOf str) ''
|
|
||||||
A source-specific keyword pattern.
|
|
||||||
'';
|
|
||||||
|
|
||||||
priority = helpers.mkNullOrOption types.int "The source-specific priority value.";
|
|
||||||
|
|
||||||
groupIndex = helpers.mkNullOrOption types.int ''
|
|
||||||
The source group index.
|
|
||||||
|
|
||||||
For instance, you can set the `buffer`'s source `groupIndex` 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";
|
|
||||||
groupIndex = 1;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "buffer";
|
|
||||||
groupIndex = 2;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
```
|
|
||||||
'';
|
|
||||||
|
|
||||||
entryFilter = helpers.mkNullOrOption types.str ''
|
|
||||||
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:
|
|
||||||
|
|
||||||
```
|
|
||||||
{
|
|
||||||
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 = null;
|
|
||||||
type = with types;
|
|
||||||
nullOr
|
|
||||||
(
|
|
||||||
listOf
|
|
||||||
(
|
|
||||||
either
|
|
||||||
source_config
|
|
||||||
(listOf source_config)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
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 list of lists, which will use the cmp built-in helper function
|
|
||||||
`cmp.config.sources`.
|
|
||||||
|
|
||||||
Default: `[]`
|
|
||||||
'';
|
|
||||||
example = ''
|
|
||||||
[
|
|
||||||
{ name = "nvim_lsp"; }
|
|
||||||
{ name = "luasnip"; } #For luasnip users.
|
|
||||||
{ name = "path"; }
|
|
||||||
{ name = "buffer"; }
|
|
||||||
]
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
view = {
|
|
||||||
entries =
|
|
||||||
helpers.defaultNullOpts.mkNullable (with types; either str attrs)
|
|
||||||
''
|
|
||||||
{
|
|
||||||
name = "custom";
|
|
||||||
selection_order = "top_down";
|
|
||||||
}
|
|
||||||
''
|
|
||||||
''
|
|
||||||
The view class used to customize nvim-cmp's appearance.
|
|
||||||
'';
|
|
||||||
|
|
||||||
docs = {
|
|
||||||
autoOpen = helpers.defaultNullOpts.mkBool true ''
|
|
||||||
Specify whether to show the docs_view when selecting an item.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
window = let
|
|
||||||
# Reusable options
|
|
||||||
mkWinhighlightOption = default:
|
|
||||||
helpers.defaultNullOpts.mkStr
|
|
||||||
default
|
|
||||||
''
|
|
||||||
Specify the window's winhighlight option.
|
|
||||||
See |nvim_open_win|.
|
|
||||||
'';
|
|
||||||
|
|
||||||
zindex = helpers.mkNullOrOption types.int ''
|
|
||||||
The completion window's zindex.
|
|
||||||
See |nvim_open_win|.
|
|
||||||
'';
|
|
||||||
in {
|
|
||||||
completion = {
|
|
||||||
border =
|
|
||||||
helpers.defaultNullOpts.mkBorder
|
|
||||||
''[ "" "" "" "" "" "" "" "" ]''
|
|
||||||
"nvim-cmp window"
|
|
||||||
"";
|
|
||||||
|
|
||||||
winhighlight =
|
|
||||||
mkWinhighlightOption
|
|
||||||
"Normal:Pmenu,FloatBorder:Pmenu,CursorLine:PmenuSel,Search:None";
|
|
||||||
|
|
||||||
inherit zindex;
|
|
||||||
|
|
||||||
scrolloff = helpers.defaultNullOpts.mkInt 0 ''
|
|
||||||
Specify the window's scrolloff option.
|
|
||||||
See |'scrolloff'|.
|
|
||||||
'';
|
|
||||||
|
|
||||||
colOffset = helpers.defaultNullOpts.mkInt 0 ''
|
|
||||||
Offsets the completion window relative to the cursor.
|
|
||||||
'';
|
|
||||||
|
|
||||||
sidePadding = helpers.defaultNullOpts.mkInt 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 window"
|
|
||||||
"";
|
|
||||||
|
|
||||||
winhighlight = mkWinhighlightOption "FloatBorder:NormalFloat";
|
|
||||||
|
|
||||||
inherit zindex;
|
|
||||||
|
|
||||||
maxWidth =
|
|
||||||
helpers.mkNullOrStrLuaOr types.ints.unsigned
|
|
||||||
''
|
|
||||||
The documentation window's max width.
|
|
||||||
|
|
||||||
Default: "math.floor((40 * 2) * (vim.o.columns / (40 * 2 * 16 / 9)))"
|
|
||||||
'';
|
|
||||||
|
|
||||||
maxHeight =
|
|
||||||
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 types.attrs "Experimental features";
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
extraPlugins = [cfg.package];
|
|
||||||
|
|
||||||
extraConfigLua = let
|
|
||||||
setupOptions = import ./setup-options.nix {
|
|
||||||
inherit cfg lib helpers;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
helpers.wrapDo ''
|
|
||||||
local cmp = require('cmp')
|
|
||||||
cmp.setup(${helpers.toLuaObject setupOptions})
|
|
||||||
'';
|
|
||||||
|
|
||||||
# If autoEnableSources is set to true, figure out which are provided by the user
|
|
||||||
# and enable the corresponding plugins.
|
|
||||||
plugins = let
|
|
||||||
sourcesFlattenedList =
|
|
||||||
if cfg.sources == null
|
|
||||||
then []
|
|
||||||
else flatten cfg.sources;
|
|
||||||
|
|
||||||
# Take only the names from the sources provided by the user
|
|
||||||
foundSources =
|
|
||||||
lists.unique
|
|
||||||
(
|
|
||||||
map
|
|
||||||
(source: source.name)
|
|
||||||
sourcesFlattenedList
|
|
||||||
);
|
|
||||||
|
|
||||||
# A list of known source names
|
|
||||||
knownSourceNames = attrNames cmpLib.pluginAndSourceNames;
|
|
||||||
|
|
||||||
attrsEnabled = listToAttrs (map
|
|
||||||
(name: {
|
|
||||||
# Name of the corresponding plugin to enable
|
|
||||||
name = cmpLib.pluginAndSourceNames.${name};
|
|
||||||
|
|
||||||
# Whether or not we enable it
|
|
||||||
value.enable = mkIf (elem name foundSources) true;
|
|
||||||
})
|
|
||||||
knownSourceNames);
|
|
||||||
in
|
|
||||||
mkMerge [
|
|
||||||
(mkIf cfg.autoEnableSources attrsEnabled)
|
|
||||||
(mkIf (elem "nvim_lsp" foundSources)
|
|
||||||
{
|
|
||||||
lsp.capabilities = ''
|
|
||||||
capabilities = vim.tbl_deep_extend("force", capabilities, require('cmp_nvim_lsp').default_capabilities())
|
|
||||||
'';
|
|
||||||
})
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,148 +0,0 @@
|
||||||
{
|
|
||||||
cfg,
|
|
||||||
lib,
|
|
||||||
helpers,
|
|
||||||
}:
|
|
||||||
with lib; let
|
|
||||||
# Not very readable sorry
|
|
||||||
# If null then null
|
|
||||||
# If an attribute is a string, just treat it as lua code for that mapping
|
|
||||||
# If an attribute is a module, create a mapping with cmp.mapping() using the action as the first input and the modes as the second.
|
|
||||||
mapping' = let
|
|
||||||
mappings =
|
|
||||||
mapAttrs
|
|
||||||
(
|
|
||||||
key: action:
|
|
||||||
helpers.mkRaw (
|
|
||||||
if isString action
|
|
||||||
then action
|
|
||||||
else let
|
|
||||||
inherit (action) modes;
|
|
||||||
modesString =
|
|
||||||
optionalString
|
|
||||||
(
|
|
||||||
(modes != null)
|
|
||||||
&& ((length modes) >= 1)
|
|
||||||
)
|
|
||||||
("," + (helpers.toLuaObject modes));
|
|
||||||
in "cmp.mapping(${action.action}${modesString})"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
cfg.mapping;
|
|
||||||
|
|
||||||
luaMappings = helpers.toLuaObject mappings;
|
|
||||||
|
|
||||||
wrapped =
|
|
||||||
lists.fold
|
|
||||||
(
|
|
||||||
presetName: prevString: ''cmp.mapping.preset.${presetName}(${prevString})''
|
|
||||||
)
|
|
||||||
luaMappings
|
|
||||||
cfg.mappingPresets;
|
|
||||||
in
|
|
||||||
helpers.mkRaw wrapped;
|
|
||||||
|
|
||||||
sources' = let
|
|
||||||
convertSourceAttrs = source:
|
|
||||||
with source; {
|
|
||||||
inherit
|
|
||||||
name
|
|
||||||
option
|
|
||||||
;
|
|
||||||
keyword_length = keywordLength;
|
|
||||||
keywordPattern =
|
|
||||||
helpers.ifNonNull' keywordPattern (helpers.mkRaw "[[${keywordPattern}]]");
|
|
||||||
trigger_characters = triggerCharacters;
|
|
||||||
inherit priority;
|
|
||||||
group_index = groupIndex;
|
|
||||||
entry_filter = entryFilter;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
if cfg.sources == null || cfg.sources == []
|
|
||||||
then null
|
|
||||||
# List of lists of sources -> we use the `cmp.config.sources` helper
|
|
||||||
else if isList (head cfg.sources)
|
|
||||||
then let
|
|
||||||
sourcesListofLists =
|
|
||||||
map
|
|
||||||
(map convertSourceAttrs)
|
|
||||||
cfg.sources;
|
|
||||||
in
|
|
||||||
helpers.mkRaw "cmp.config.sources(${helpers.toLuaObject sourcesListofLists})"
|
|
||||||
# List of sources
|
|
||||||
else map convertSourceAttrs cfg.sources;
|
|
||||||
in
|
|
||||||
with cfg;
|
|
||||||
{
|
|
||||||
performance = with performance; {
|
|
||||||
inherit
|
|
||||||
debounce
|
|
||||||
throttle
|
|
||||||
;
|
|
||||||
fetching_timeout = fetchingTimeout;
|
|
||||||
async_budget = asyncBudget;
|
|
||||||
max_view_entries = maxViewEntries;
|
|
||||||
};
|
|
||||||
inherit preselect;
|
|
||||||
mapping = mapping';
|
|
||||||
snippet = with snippet; {
|
|
||||||
inherit expand;
|
|
||||||
};
|
|
||||||
completion = with completion; {
|
|
||||||
keyword_length = keywordLength;
|
|
||||||
keyword_pattern = keywordPattern;
|
|
||||||
inherit
|
|
||||||
autocomplete
|
|
||||||
completeopt
|
|
||||||
;
|
|
||||||
};
|
|
||||||
confirmation = with confirmation; {
|
|
||||||
get_commit_characters = getCommitCharacters;
|
|
||||||
};
|
|
||||||
formatting = with formatting; {
|
|
||||||
expandable_indicator = expandableIndicator;
|
|
||||||
inherit fields format;
|
|
||||||
};
|
|
||||||
matching = with matching; {
|
|
||||||
disallow_fuzzy_matching = disallowFuzzyMatching;
|
|
||||||
disallow_fullfuzzy_matching = disallowFullfuzzyMatching;
|
|
||||||
disallow_partial_fuzzy_matching = disallowPartialFuzzyMatching;
|
|
||||||
disallow_partial_matching = disallowPartialMatching;
|
|
||||||
disallow_prefix_unmatching = disallowPrefixUnmatching;
|
|
||||||
};
|
|
||||||
sorting = with sorting; {
|
|
||||||
priority_weight = priorityWeight;
|
|
||||||
inherit comparators;
|
|
||||||
};
|
|
||||||
sources = sources';
|
|
||||||
view = with view; {
|
|
||||||
inherit entries;
|
|
||||||
docs = with docs; {
|
|
||||||
auto_open = autoOpen;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
window = with window; {
|
|
||||||
completion = with completion; {
|
|
||||||
inherit
|
|
||||||
border
|
|
||||||
winhighlight
|
|
||||||
zindex
|
|
||||||
scrolloff
|
|
||||||
;
|
|
||||||
col_offset = colOffset;
|
|
||||||
side_padding = sidePadding;
|
|
||||||
inherit scrollbar;
|
|
||||||
};
|
|
||||||
documentation = with documentation; {
|
|
||||||
inherit
|
|
||||||
border
|
|
||||||
winhighlight
|
|
||||||
zindex
|
|
||||||
;
|
|
||||||
max_width = maxWidth;
|
|
||||||
max_height = maxHeight;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
inherit experimental;
|
|
||||||
}
|
|
||||||
// cfg.extraOptions
|
|
|
@ -27,8 +27,7 @@
|
||||||
./completion/coq.nix
|
./completion/coq.nix
|
||||||
./completion/coq-thirdparty.nix
|
./completion/coq-thirdparty.nix
|
||||||
./completion/lspkind.nix
|
./completion/lspkind.nix
|
||||||
./completion/nvim-cmp
|
./completion/cmp
|
||||||
./completion/nvim-cmp/sources
|
|
||||||
|
|
||||||
./filetrees/chadtree.nix
|
./filetrees/chadtree.nix
|
||||||
./filetrees/neo-tree.nix
|
./filetrees/neo-tree.nix
|
||||||
|
|
|
@ -122,7 +122,7 @@ with lib; let
|
||||||
nvimCmp = helpers.mkNullOrOption types.bool ''
|
nvimCmp = helpers.mkNullOrOption types.bool ''
|
||||||
Set to false to disable completion.
|
Set to false to disable completion.
|
||||||
|
|
||||||
Default: `true` if `nvim-cmp` is enabled.
|
Default: `true` if `cmp` is enabled.
|
||||||
'';
|
'';
|
||||||
|
|
||||||
minChars = helpers.defaultNullOpts.mkUnsignedInt 2 ''
|
minChars = helpers.defaultNullOpts.mkUnsignedInt 2 ''
|
||||||
|
@ -500,10 +500,10 @@ in {
|
||||||
assertion = let
|
assertion = let
|
||||||
nvimCmpEnabled = isBool cfg.completion.nvimCmp && cfg.completion.nvimCmp;
|
nvimCmpEnabled = isBool cfg.completion.nvimCmp && cfg.completion.nvimCmp;
|
||||||
in
|
in
|
||||||
nvimCmpEnabled -> config.plugins.nvim-cmp.enable;
|
nvimCmpEnabled -> config.plugins.cmp.enable;
|
||||||
message = ''
|
message = ''
|
||||||
Nixvim (plugins.obsidian): You have enabled `completion.nvimCmp` but `plugins.nvim-cmp.enable` is `false`.
|
Nixvim (plugins.obsidian): You have enabled `completion.nvimCmp` but `plugins.cmp.enable` is `false`.
|
||||||
You need to enable `nvim-cmp` to use this setting.
|
You need to enable `cmp` to use this setting.
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
|
@ -100,37 +100,40 @@
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
nvim-cmp = {
|
cmp = {
|
||||||
formatting = {
|
|
||||||
format = ''
|
|
||||||
require("lspkind").cmp_format({
|
|
||||||
mode="symbol",
|
|
||||||
maxwidth = 50,
|
|
||||||
ellipsis_char = "..."
|
|
||||||
})
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
autoEnableSources = true;
|
|
||||||
snippet = {
|
|
||||||
expand.__raw = ''
|
|
||||||
function(args)
|
|
||||||
require("luasnip").lsp_expand(args.body)
|
|
||||||
end
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
enable = true;
|
enable = true;
|
||||||
sources = [
|
autoEnableSources = true;
|
||||||
{name = "nvim_lsp";}
|
|
||||||
{
|
settings = {
|
||||||
name = "luasnip";
|
formatting = {
|
||||||
option = {
|
format = ''
|
||||||
show_autosnippets = true;
|
require("lspkind").cmp_format({
|
||||||
};
|
mode="symbol",
|
||||||
}
|
maxwidth = 50,
|
||||||
{name = "path";}
|
ellipsis_char = "..."
|
||||||
{name = "buffer";}
|
})
|
||||||
];
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
snippet = {
|
||||||
|
expand = ''
|
||||||
|
function(args)
|
||||||
|
require("luasnip").lsp_expand(args.body)
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
sources = [
|
||||||
|
{name = "nvim_lsp";}
|
||||||
|
{
|
||||||
|
name = "luasnip";
|
||||||
|
option = {
|
||||||
|
show_autosnippets = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{name = "path";}
|
||||||
|
{name = "buffer";}
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
barbar.enable = true;
|
barbar.enable = true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
empty = {
|
empty = {
|
||||||
plugins.nvim-cmp = {
|
plugins.cmp = {
|
||||||
enable = true;
|
enable = true;
|
||||||
sources = [
|
settings.sources = [
|
||||||
{name = "cmp_tabby";}
|
{name = "cmp_tabby";}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@ -10,9 +10,9 @@
|
||||||
|
|
||||||
defaults = {
|
defaults = {
|
||||||
plugins = {
|
plugins = {
|
||||||
nvim-cmp = {
|
cmp = {
|
||||||
enable = true;
|
enable = true;
|
||||||
sources = [
|
settings.sources = [
|
||||||
{name = "cmp_tabby";}
|
{name = "cmp_tabby";}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
272
tests/test-sources/plugins/completion/cmp.nix
Normal file
272
tests/test-sources/plugins/completion/cmp.nix
Normal file
|
@ -0,0 +1,272 @@
|
||||||
|
{
|
||||||
|
empty = {
|
||||||
|
plugins.cmp.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
snippet-engine = {
|
||||||
|
plugins.cmp = {
|
||||||
|
enable = true;
|
||||||
|
settings.snippet.expand = "luasnip";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Issue #536
|
||||||
|
mappings = {
|
||||||
|
plugins.cmp = {
|
||||||
|
enable = true;
|
||||||
|
settings.mapping = {
|
||||||
|
"<CR>" = "cmp.mapping.confirm({ select = false })";
|
||||||
|
"<Tab>" = ''
|
||||||
|
cmp.mapping(
|
||||||
|
function(fallback)
|
||||||
|
if cmp.visible() then
|
||||||
|
cmp.select_next_item()
|
||||||
|
elseif luasnip.expandable() then
|
||||||
|
luasnip.expand()
|
||||||
|
elseif luasnip.expand_or_jumpable() then
|
||||||
|
luasnip.expand_or_jump()
|
||||||
|
elseif check_backspace() then
|
||||||
|
fallback()
|
||||||
|
else
|
||||||
|
fallback()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
{ "i", "s" }
|
||||||
|
)
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# All the upstream default options of nvim-cmp
|
||||||
|
defaults = {
|
||||||
|
plugins.cmp = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
performance = {
|
||||||
|
debounce = 60;
|
||||||
|
throttle = 30;
|
||||||
|
fetchingTimeout = 500;
|
||||||
|
asyncBudget = 1;
|
||||||
|
maxViewEntries = 200;
|
||||||
|
};
|
||||||
|
preselect = "Item";
|
||||||
|
snippet = {
|
||||||
|
expand = ''
|
||||||
|
function(_)
|
||||||
|
error('snippet engine is not configured.')
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
completion = {
|
||||||
|
keywordLength = 1;
|
||||||
|
keywordPattern = ''[[\%(-\?\d\+\%(\.\d\+\)\?\|\h\w*\%(-\w*\)*\)]]'';
|
||||||
|
autocomplete = ["TextChanged"];
|
||||||
|
completeopt = "menu,menuone,noselect";
|
||||||
|
};
|
||||||
|
confirmation = {
|
||||||
|
getCommitCharacters = ''
|
||||||
|
function(commit_characters)
|
||||||
|
return commit_characters
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
formatting = {
|
||||||
|
expandableIndicator = true;
|
||||||
|
fields = ["abbr" "kind" "menu"];
|
||||||
|
format = ''
|
||||||
|
function(_, vim_item)
|
||||||
|
return vim_item
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
matching = {
|
||||||
|
disallowFuzzyMatching = false;
|
||||||
|
disallowFullfuzzyMatching = false;
|
||||||
|
disallowPartialFuzzyMatching = true;
|
||||||
|
disallowPartialMatching = false;
|
||||||
|
disallowPrefixUnmatching = false;
|
||||||
|
};
|
||||||
|
sorting = {
|
||||||
|
priorityWeight = 2;
|
||||||
|
comparators = [
|
||||||
|
"offset"
|
||||||
|
"exact"
|
||||||
|
"score"
|
||||||
|
"recently_used"
|
||||||
|
"locality"
|
||||||
|
"kind"
|
||||||
|
"length"
|
||||||
|
"order"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
sources = [];
|
||||||
|
experimental = {
|
||||||
|
ghost_text = false;
|
||||||
|
};
|
||||||
|
view = {
|
||||||
|
entries = {
|
||||||
|
name = "custom";
|
||||||
|
selection_order = "top_down";
|
||||||
|
};
|
||||||
|
docs = {
|
||||||
|
autoOpen = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
window = {
|
||||||
|
completion = {
|
||||||
|
border = ["" "" "" "" "" "" "" ""];
|
||||||
|
winhighlight = "Normal:Pmenu,FloatBorder:Pmenu,CursorLine:PmenuSel,Search:None";
|
||||||
|
scrolloff = 0;
|
||||||
|
colOffset = 0;
|
||||||
|
sidePadding = 1;
|
||||||
|
scrollbar = true;
|
||||||
|
};
|
||||||
|
documentation = {
|
||||||
|
maxHeight = "math.floor(40 * (40 / vim.o.lines))";
|
||||||
|
maxWidth = "math.floor((40 * 2) * (vim.o.columns / (40 * 2 * 16 / 9)))";
|
||||||
|
border.__raw = "cmp.config.window.bordered()";
|
||||||
|
winhighlight = "FloatBorder:NormalFloat";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
list-of-sources = {
|
||||||
|
plugins.cmp = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
settings.sources = [
|
||||||
|
{name = "path";}
|
||||||
|
{name = "nvim_lsp";}
|
||||||
|
{name = "luasnip";}
|
||||||
|
{
|
||||||
|
name = "buffer";
|
||||||
|
option.get_bufnrs.__raw = "vim.api.nvim_list_bufs";
|
||||||
|
}
|
||||||
|
{name = "neorg";}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
list-of-lists-of-sources = {
|
||||||
|
plugins.cmp = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
# Here we are setting sources with raw lua. This cannot be parsed by Nixvim.
|
||||||
|
autoEnableSources = false;
|
||||||
|
|
||||||
|
settings.sources.__raw = ''
|
||||||
|
cmp.config.sources({
|
||||||
|
{
|
||||||
|
{name = "path"},
|
||||||
|
{name = "nvim_lsp"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{
|
||||||
|
name = "buffer",
|
||||||
|
option = {
|
||||||
|
get_bufnrs = vim.api.nvim_list_bufs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
example = {
|
||||||
|
plugins.cmp = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
snippet.expand = "luasnip";
|
||||||
|
window = {
|
||||||
|
completion.__raw = "cmp.config.window.bordered";
|
||||||
|
documentation.__raw = "cmp.config.window.bordered";
|
||||||
|
};
|
||||||
|
|
||||||
|
mapping = {
|
||||||
|
"<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 })";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
readme-example = {
|
||||||
|
plugins.cmp = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
# Here we are setting sources with raw lua. This cannot be parsed by Nixvim.
|
||||||
|
autoEnableSources = false;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
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' },
|
||||||
|
})
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
filetype.gitcommit.sources.__raw = ''
|
||||||
|
cmp.config.sources({
|
||||||
|
{ name = 'git' },
|
||||||
|
}, {
|
||||||
|
{ name = 'buffer' },
|
||||||
|
})
|
||||||
|
'';
|
||||||
|
|
||||||
|
cmdline = {
|
||||||
|
"/" = {
|
||||||
|
mapping.__raw = "cmp.mapping.preset.cmdline()";
|
||||||
|
# Need to use a raw lua string as we only accept **flat** lists (not nested).
|
||||||
|
sources.__raw = ''
|
||||||
|
{
|
||||||
|
{ name = 'buffer' }
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"?" = {
|
||||||
|
mapping.__raw = "cmp.mapping.preset.cmdline()";
|
||||||
|
# Need to use a raw lua string as we only accept **flat** lists (not nested).
|
||||||
|
sources.__raw = ''
|
||||||
|
{
|
||||||
|
{ name = 'buffer' }
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
":" = {
|
||||||
|
mapping.__raw = "cmp.mapping.preset.cmdline()";
|
||||||
|
sources.__raw = ''
|
||||||
|
cmp.config.sources({
|
||||||
|
{ name = 'path' }
|
||||||
|
}, {
|
||||||
|
{ name = 'cmdline' }
|
||||||
|
})
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -4,10 +4,10 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
enabled-by-cmp = {
|
enabled-by-cmp = {
|
||||||
plugins.nvim-cmp = {
|
plugins.cmp = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
sources = [
|
settings.sources = [
|
||||||
{name = "codeium";}
|
{name = "codeium";}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
fixPairs = true;
|
fixPairs = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
nvim-cmp = {
|
cmp = {
|
||||||
enable = true;
|
enable = true;
|
||||||
sources = [
|
settings.sources = [
|
||||||
{name = "copilot";}
|
{name = "copilot";}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
enable = true;
|
enable = true;
|
||||||
servers.clangd.enable = true;
|
servers.clangd.enable = true;
|
||||||
};
|
};
|
||||||
nvim-cmp.enable = true;
|
cmp.enable = true;
|
||||||
lspkind.enable = true;
|
lspkind.enable = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,171 +0,0 @@
|
||||||
{
|
|
||||||
# Empty configuration
|
|
||||||
empty = {
|
|
||||||
plugins.nvim-cmp.enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
snippetEngine = {
|
|
||||||
plugins.nvim-cmp = {
|
|
||||||
enable = true;
|
|
||||||
snippet.expand = "luasnip";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Issue #536
|
|
||||||
mappings = {
|
|
||||||
plugins.nvim-cmp = {
|
|
||||||
enable = true;
|
|
||||||
mapping = {
|
|
||||||
"<CR>" = "cmp.mapping.confirm({ select = false })";
|
|
||||||
"<Tab>" = {
|
|
||||||
modes = ["i" "s"];
|
|
||||||
action = ''
|
|
||||||
function(fallback)
|
|
||||||
if cmp.visible() then
|
|
||||||
cmp.select_next_item()
|
|
||||||
elseif luasnip.expandable() then
|
|
||||||
luasnip.expand()
|
|
||||||
elseif luasnip.expand_or_jumpable() then
|
|
||||||
luasnip.expand_or_jump()
|
|
||||||
elseif check_backspace() then
|
|
||||||
fallback()
|
|
||||||
else
|
|
||||||
fallback()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# All the upstream default options of nvim-cmp
|
|
||||||
defaults = {
|
|
||||||
plugins.nvim-cmp = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
performance = {
|
|
||||||
debounce = 60;
|
|
||||||
throttle = 30;
|
|
||||||
fetchingTimeout = 500;
|
|
||||||
asyncBudget = 1;
|
|
||||||
maxViewEntries = 200;
|
|
||||||
};
|
|
||||||
preselect = "Item";
|
|
||||||
snippet = {
|
|
||||||
expand.__raw = ''
|
|
||||||
function(_)
|
|
||||||
error('snippet engine is not configured.')
|
|
||||||
end
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
completion = {
|
|
||||||
keywordLength = 1;
|
|
||||||
keywordPattern = ''\%(-\?\d\+\%(\.\d\+\)\?\|\h\w*\%(-\w*\)*\)'';
|
|
||||||
autocomplete = ["TextChanged"];
|
|
||||||
completeopt = "menu,menuone,noselect";
|
|
||||||
};
|
|
||||||
confirmation = {
|
|
||||||
getCommitCharacters = ''
|
|
||||||
function(commit_characters)
|
|
||||||
return commit_characters
|
|
||||||
end
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
formatting = {
|
|
||||||
expandableIndicator = true;
|
|
||||||
fields = ["abbr" "kind" "menu"];
|
|
||||||
format = ''
|
|
||||||
function(_, vim_item)
|
|
||||||
return vim_item
|
|
||||||
end
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
matching = {
|
|
||||||
disallowFuzzyMatching = false;
|
|
||||||
disallowFullfuzzyMatching = false;
|
|
||||||
disallowPartialFuzzyMatching = true;
|
|
||||||
disallowPartialMatching = false;
|
|
||||||
disallowPrefixUnmatching = false;
|
|
||||||
};
|
|
||||||
sorting = {
|
|
||||||
priorityWeight = 2;
|
|
||||||
comparators = [
|
|
||||||
"offset"
|
|
||||||
"exact"
|
|
||||||
"score"
|
|
||||||
"recently_used"
|
|
||||||
"locality"
|
|
||||||
"kind"
|
|
||||||
"length"
|
|
||||||
"order"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
sources = [];
|
|
||||||
experimental = {
|
|
||||||
ghost_text = false;
|
|
||||||
};
|
|
||||||
view = {
|
|
||||||
entries = {
|
|
||||||
name = "custom";
|
|
||||||
selection_order = "top_down";
|
|
||||||
};
|
|
||||||
docs = {
|
|
||||||
autoOpen = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
window = {
|
|
||||||
completion = {
|
|
||||||
border = ["" "" "" "" "" "" "" ""];
|
|
||||||
winhighlight = "Normal:Pmenu,FloatBorder:Pmenu,CursorLine:PmenuSel,Search:None";
|
|
||||||
scrolloff = 0;
|
|
||||||
colOffset = 0;
|
|
||||||
sidePadding = 1;
|
|
||||||
scrollbar = true;
|
|
||||||
};
|
|
||||||
documentation = {
|
|
||||||
maxHeight = "math.floor(40 * (40 / vim.o.lines))";
|
|
||||||
maxWidth = "math.floor((40 * 2) * (vim.o.columns / (40 * 2 * 16 / 9)))";
|
|
||||||
border.__raw = "cmp.config.window.bordered()";
|
|
||||||
winhighlight = "FloatBorder:NormalFloat";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
list-of-sources = {
|
|
||||||
plugins.nvim-cmp = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
sources = [
|
|
||||||
{name = "path";}
|
|
||||||
{name = "nvim_lsp";}
|
|
||||||
{name = "luasnip";}
|
|
||||||
{
|
|
||||||
name = "buffer";
|
|
||||||
option.get_bufnrs.__raw = "vim.api.nvim_list_bufs";
|
|
||||||
}
|
|
||||||
{name = "neorg";}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
list-of-lists-of-sources = {
|
|
||||||
plugins.nvim-cmp = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
sources = [
|
|
||||||
[
|
|
||||||
{name = "path";}
|
|
||||||
{name = "nvim_lsp";}
|
|
||||||
]
|
|
||||||
[
|
|
||||||
{
|
|
||||||
name = "buffer";
|
|
||||||
option.get_bufnrs.__raw = "vim.api.nvim_list_bufs";
|
|
||||||
}
|
|
||||||
]
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
example = {
|
example = {
|
||||||
plugins = {
|
plugins = {
|
||||||
nvim-cmp.enable = true;
|
cmp.enable = true;
|
||||||
|
|
||||||
obsidian = {
|
obsidian = {
|
||||||
enable = false;
|
enable = false;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue