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

@ -173,7 +173,7 @@ in {
# }
# 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 "";

View file

@ -6,7 +6,7 @@
...
}:
with helpers.vim-plugin;
with lib; {
with lib; rec {
mkCmpSourcePlugin = {
name,
extraPlugins ? [],
@ -16,6 +16,7 @@ with lib; {
mkVimPlugin config {
inherit name;
extraPlugins = extraPlugins ++ (lists.optional useDefaultPackage pkgs.vimPlugins.${name});
maintainers = [maintainers.GaetanLepage];
};
@ -63,4 +64,62 @@ with lib; {
"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

@ -8,7 +8,13 @@
with lib; let
cmpLib = import ../cmp-helpers.nix {inherit lib config helpers pkgs;};
cmpSourcesPluginNames = attrValues cmpLib.pluginAndSourceNames;
pluginModules = lists.map (name: cmpLib.mkCmpSourcePlugin {inherit name;}) cmpSourcesPluginNames;
pluginModules =
map
(
name:
cmpLib.mkCmpSourcePlugin {inherit name;}
)
cmpSourcesPluginNames;
in {
# For extra cmp plugins
imports =

View file

@ -49,7 +49,7 @@ in {
};
config = let
doCmp = cfg.cmp.enable && config.plugins.nvim-cmp.enable;
doCmp = cfg.cmp.enable && config.plugins.cmp.enable;
options =
{
inherit (cfg) mode preset;
@ -73,7 +73,7 @@ in {
require('lspkind').init(${helpers.toLuaObject options})
'';
plugins.nvim-cmp.formatting.format =
plugins.cmp.settings.formatting.format =
if cfg.cmp.after != null
then ''
function(entry, vim_item)

View file

@ -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())
'';
})
];
};
}

View file

@ -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

View file

@ -27,8 +27,7 @@
./completion/coq.nix
./completion/coq-thirdparty.nix
./completion/lspkind.nix
./completion/nvim-cmp
./completion/nvim-cmp/sources
./completion/cmp
./filetrees/chadtree.nix
./filetrees/neo-tree.nix

View file

@ -122,7 +122,7 @@ with lib; let
nvimCmp = helpers.mkNullOrOption types.bool ''
Set to false to disable completion.
Default: `true` if `nvim-cmp` is enabled.
Default: `true` if `cmp` is enabled.
'';
minChars = helpers.defaultNullOpts.mkUnsignedInt 2 ''
@ -500,10 +500,10 @@ in {
assertion = let
nvimCmpEnabled = isBool cfg.completion.nvimCmp && cfg.completion.nvimCmp;
in
nvimCmpEnabled -> config.plugins.nvim-cmp.enable;
nvimCmpEnabled -> config.plugins.cmp.enable;
message = ''
Nixvim (plugins.obsidian): You have enabled `completion.nvimCmp` but `plugins.nvim-cmp.enable` is `false`.
You need to enable `nvim-cmp` to use this setting.
Nixvim (plugins.obsidian): You have enabled `completion.nvimCmp` but `plugins.cmp.enable` is `false`.
You need to enable `cmp` to use this setting.
'';
}
];

View file

@ -100,7 +100,11 @@
enable = true;
};
nvim-cmp = {
cmp = {
enable = true;
autoEnableSources = true;
settings = {
formatting = {
format = ''
require("lspkind").cmp_format({
@ -111,15 +115,13 @@
'';
};
autoEnableSources = true;
snippet = {
expand.__raw = ''
expand = ''
function(args)
require("luasnip").lsp_expand(args.body)
end
'';
};
enable = true;
sources = [
{name = "nvim_lsp";}
{
@ -132,6 +134,7 @@
{name = "buffer";}
];
};
};
barbar.enable = true;
};

View file

@ -1,8 +1,8 @@
{
empty = {
plugins.nvim-cmp = {
plugins.cmp = {
enable = true;
sources = [
settings.sources = [
{name = "cmp_tabby";}
];
};
@ -10,9 +10,9 @@
defaults = {
plugins = {
nvim-cmp = {
cmp = {
enable = true;
sources = [
settings.sources = [
{name = "cmp_tabby";}
];
};

View 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' }
})
'';
};
};
};
};
}

View file

@ -4,10 +4,10 @@
};
enabled-by-cmp = {
plugins.nvim-cmp = {
plugins.cmp = {
enable = true;
sources = [
settings.sources = [
{name = "codeium";}
];
};

View file

@ -17,9 +17,9 @@
fixPairs = true;
};
nvim-cmp = {
cmp = {
enable = true;
sources = [
settings.sources = [
{name = "copilot";}
];
};

View file

@ -10,7 +10,7 @@
enable = true;
servers.clangd.enable = true;
};
nvim-cmp.enable = true;
cmp.enable = true;
lspkind.enable = true;
};
};

View file

@ -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";
}
]
];
};
};
}

View file

@ -6,7 +6,7 @@
example = {
plugins = {
nvim-cmp.enable = true;
cmp.enable = true;
obsidian = {
enable = false;