plugins/completion: move to by-name

- Move nvim-cmp to plugins/cmp
- Move other completion plugins to plugins/by-name
This commit is contained in:
Matt Sturgeon 2024-09-05 02:36:41 +01:00
parent 3211a63306
commit ad85cd760e
No known key found for this signature in database
GPG key ID: 4F91844CED1A8299
36 changed files with 2 additions and 9 deletions

View file

@ -0,0 +1,122 @@
{
lib,
...
}:
let
inherit (lib.nixvim) defaultNullOpts;
in
lib.nixvim.neovim-plugin.mkNeovimPlugin {
name = "codeium-nvim";
originalName = "codeium.nvim";
luaName = "codeium";
maintainers = with lib.maintainers; [
GaetanLepage
khaneliman
];
# TODO: added 2024-09-03 remove after 24.11
deprecateExtraOptions = true;
optionsRenamedToSettings = [
"configPath"
"binPath"
[
"api"
"host"
]
[
"api"
"port"
]
[
"tools"
"uname"
]
[
"tools"
"uuidgen"
]
[
"tools"
"curl"
]
[
"tools"
"gzip"
]
[
"tools"
"languageServer"
]
"wrapper"
];
# Register nvim-cmp association
imports = [
{ cmpSourcePlugins.codeium = "codeium-nvim"; }
];
settingsOptions = {
config_path = defaultNullOpts.mkStr {
__raw = "vim.fn.stdpath('cache') .. '/codeium/config.json'";
} "The path to the config file, used to store the API key.";
bin_path = defaultNullOpts.mkStr {
__raw = "vim.fn.stdpath('cache') .. '/codeium/bin'";
} "The path to the directory where the Codeium server will be downloaded to.";
api = {
host = defaultNullOpts.mkStr "server.codeium.com" ''
The hostname of the API server to use.
'';
port = defaultNullOpts.mkNullableWithRaw' {
# TODO: Added 2024-09-05; remove after 24.11
type = with lib.types; lib.nixvim.transitionType ints.positive toString (strMatching "[0-9]+");
pluginDefault = "443";
description = ''
The port of the API server to use.
'';
};
};
tools = {
uname = defaultNullOpts.mkStr null "The path to the `uname` binary.";
uuidgen = defaultNullOpts.mkStr null "The path to the `uuidgen` binary.";
curl = defaultNullOpts.mkStr null "The path to the `curl` binary.";
gzip = defaultNullOpts.mkStr null "The path to the `gzip` binary.";
language_server = defaultNullOpts.mkStr null ''
The path to the language server downloaded from the official source.
'';
};
wrapper = defaultNullOpts.mkStr null ''
The path to a wrapper script/binary that is used to execute any binaries not listed under
tools.
This is primarily useful for NixOS, where a FHS wrapper can be used for the downloaded
codeium server.
'';
detect_proxy = defaultNullOpts.mkBool false "Whether to enable the proxy detection.";
enable_chat = defaultNullOpts.mkBool false "Whether to enable the chat functionality.";
enterprise_mode = defaultNullOpts.mkBool false "Whether to enable the enterprise mode.";
};
settingsExample = lib.literalExpression ''
{
enable_chat = true;
tools = {
curl = lib.getExe pkgs.curl;
gzip = lib.getExe pkgs.gzip;
uname = lib.getExe' pkgs.coreutils "uname";
uuidgen = lib.getExe' pkgs.util-linux "uuidgen";
};
}
'';
}

View file

@ -0,0 +1,143 @@
{
lib,
helpers,
pkgs,
...
}:
with lib;
let
keymapsDefinitions = {
clear = {
default = "<C-]>";
description = "Keymap for clearing current suggestion.";
command = "vim.fn['codeium#Clear']()";
};
next = {
default = "<M-]>";
description = "Keymap for cycling to the next suggestion.";
command = "vim.fn['codeium#CycleCompletions'](1)";
};
prev = {
default = "<M-[>";
description = "Keymap for cycling to the previous suggestion.";
command = "vim.fn['codeium#CycleCompletions'](-1)";
};
accept = {
default = "<Tab>";
description = "Keymap for inserting the proposed suggestion.";
command = "vim.fn['codeium#Accept']()";
};
complete = {
default = "<M-Bslash>";
description = "Keymap for manually triggering the suggestion.";
command = "vim.fn['codeium#Complete']()";
};
};
in
helpers.vim-plugin.mkVimPlugin {
name = "codeium-vim";
originalName = "codeium.vim";
globalPrefix = "codeium_";
maintainers = [ maintainers.GaetanLepage ];
# TODO introduced 2024-02-19: remove 2024-03-19
deprecateExtraConfig = true;
optionsRenamedToSettings = [
"bin"
"filetypes"
"manual"
"noMapTab"
"idleDelay"
"render"
"tabFallback"
"disableBindings"
];
settingsOptions = {
bin = mkOption {
type = with types; nullOr str;
default = "${pkgs.codeium}/bin/codeium_language_server";
description = "The path to the codeium language server executable.";
};
filetypes =
helpers.defaultNullOpts.mkAttrsOf types.bool
{
help = false;
gitcommit = false;
gitrebase = false;
"." = false;
}
''
A dictionary mapping whether codeium should be enabled or disabled in certain filetypes.
This can be used to opt out of completions for certain filetypes.
'';
manual = helpers.defaultNullOpts.mkBool false ''
If true, codeium completions will never automatically trigger.
'';
no_map_tab = helpers.defaultNullOpts.mkBool false ''
Whether to disable the `<Tab>` keybinding.
'';
idle_delay = helpers.defaultNullOpts.mkPositiveInt 75 ''
Delay in milliseconds before autocompletions are shown (limited by language server to a
minimum of 75).
'';
render = helpers.defaultNullOpts.mkBool true ''
A global boolean flag that controls whether codeium renders are enabled or disabled.
'';
tab_fallback = helpers.mkNullOrOption types.str ''
The fallback key when there is no suggestion display in `codeium#Accept()`.
Default: "\<C-N>" when a popup menu is visible, else "\t".
'';
disable_bindings = helpers.defaultNullOpts.mkBool false ''
Whether to disable default keybindings.
'';
};
extraOptions = {
keymaps = mapAttrs (
optionName: v:
helpers.defaultNullOpts.mkStr v.default ''
${v.description}
Command: `${v.command}`
''
) keymapsDefinitions;
};
extraConfig = cfg: {
plugins.codeium-vim.settings.enabled = true;
keymaps =
let
processKeymap =
optionName: v:
optional (v != null) {
key = v;
action =
let
inherit (keymapsDefinitions.${optionName}) command;
in
helpers.mkRaw "function() ${command} end";
};
keymapsList = flatten (mapAttrsToList processKeymap cfg.keymaps);
defaults = {
mode = "i";
options = {
silent = true;
expr = true;
};
};
in
helpers.keymaps.mkKeymaps defaults keymapsList;
};
}

View file

@ -0,0 +1,220 @@
{
lib,
helpers,
config,
pkgs,
...
}:
with lib;
let
cfg = config.plugins.copilot-lua;
in
{
options = {
plugins.copilot-lua =
let
keymapOption = helpers.defaultNullOpts.mkNullable (with types; either (enum [ false ]) str);
in
helpers.neovim-plugin.extraOptionsOptions
// {
enable = mkEnableOption "copilot.lua";
package = lib.mkPackageOption pkgs "copilot.lua" {
default = [
"vimPlugins"
"copilot-lua"
];
};
panel = {
enabled = helpers.defaultNullOpts.mkBool true "Enable the panel.";
autoRefresh = helpers.defaultNullOpts.mkBool false "Enable auto-refresh.";
keymap = {
jumpPrev = keymapOption "[[" "Keymap for jumping to the previous suggestion.";
jumpNext = keymapOption "]]" "Keymap for jumping to the next suggestion.";
accept = keymapOption "<CR>" "Keymap to accept the proposed suggestion.";
refresh = keymapOption "gr" "Keymap to refresh the suggestions.";
open = keymapOption "<M-CR>" "Keymap to open.";
};
layout = {
position =
helpers.defaultNullOpts.mkEnumFirstDefault
[
"bottom"
"top"
"left"
"right"
]
''
The panel position.
'';
ratio = helpers.defaultNullOpts.mkNullable (types.numbers.between 0.0 1.0) 0.4 ''
The panel ratio.
'';
};
};
suggestion = {
enabled = helpers.defaultNullOpts.mkBool true "Enable suggestion.";
autoTrigger = helpers.defaultNullOpts.mkBool false "Enable auto-trigger.";
debounce = helpers.defaultNullOpts.mkInt 75 "Debounce.";
keymap = {
accept = keymapOption "<M-l>" "Keymap for accepting the suggestion.";
acceptWord = keymapOption false "Keymap for accepting a word suggestion.";
acceptLine = keymapOption false "Keymap for accepting a line suggestion.";
next = keymapOption "<M-]>" "Keymap for accepting the next suggestion.";
prev = keymapOption "<M-[>" "Keymap for accepting the previous suggestion.";
dismiss = keymapOption "<C-]>" "Keymap to dismiss the suggestion.";
};
};
filetypes =
helpers.defaultNullOpts.mkAttrsOf types.bool
{
yaml = false;
markdown = false;
help = false;
gitcommit = false;
gitrebase = false;
hgcommit = false;
svn = false;
cvs = false;
"." = false;
}
''
Specify filetypes for attaching copilot.
Each value can be either a boolean or a lua function that returns a boolean.
Example:
```nix
{
markdown = true; # overrides default
terraform = false; # disallow specific filetype
sh.__raw = \'\'
function ()
if string.match(vim.fs.basename(vim.api.nvim_buf_get_name(0)), '^%.env.*') then
-- disable for .env files
return false
end
return true
end
\'\';
}
```
The key `"*"` can be used to disable the default configuration.
Example:
```nix
{
javascript = true; # allow specific filetype
typescript = true; # allow specific filetype
"*" = false; # disable for all other filetypes and ignore default `filetypes`
}
```
'';
copilotNodeCommand = mkOption {
type = types.str;
default = "${pkgs.nodejs-18_x}/bin/node";
description = ''
Use this field to provide the path to a specific node version such as one installed by
`nvm`.
Node.js version must be 16.x or newer.
'';
};
serverOptsOverrides = helpers.defaultNullOpts.mkAttrsOf' {
type = types.anything;
pluginDefault = { };
description = ''
Override copilot lsp client `settings`.
The settings field is where you can set the values of the options defined in
https://github.com/zbirenbaum/copilot.lua/blob/master/SettingsOpts.md.
These options are specific to the copilot lsp and can be used to customize its behavior.
Ensure that the `name` field is not overridden as is is used for efficiency reasons in
numerous checks to verify copilot is actually running.
See `:h vim.lsp.start_client` for list of options.
'';
example = {
trace = "verbose";
settings = {
advanced = {
listCount = 10; # number of completions for panel
inlineSuggestCount = 3; # number of completions for getCompletions
};
};
};
};
};
};
config = mkIf cfg.enable {
assertions = [
{
assertion = !config.plugins.copilot-vim.enable;
message = ''
You currently have both `copilot-vim` and `copilot-lua` enabled.
Please disable one of them.
'';
}
];
extraPlugins = [ cfg.package ];
extraConfigLua =
let
setupOptions =
with cfg;
{
panel = with panel; {
inherit enabled;
auto_refresh = autoRefresh;
keymap = with keymap; {
jump_prev = jumpPrev;
jump_next = jumpNext;
inherit accept refresh open;
};
layout = with layout; {
inherit position ratio;
};
};
suggestion = with suggestion; {
inherit enabled;
auto_trigger = autoTrigger;
inherit debounce;
keymap = with keymap; {
inherit accept;
accept_word = acceptWord;
accept_line = acceptLine;
inherit next prev dismiss;
};
};
inherit filetypes;
copilot_node_command = copilotNodeCommand;
server_opts_overrides = serverOptsOverrides;
}
// cfg.extraOptions;
in
''
require('copilot').setup(${helpers.toLuaObject setupOptions})
'';
};
}

View file

@ -0,0 +1,83 @@
{
lib,
helpers,
pkgs,
...
}:
with lib;
with helpers.vim-plugin;
helpers.vim-plugin.mkVimPlugin {
name = "copilot-vim";
originalName = "copilot.vim";
globalPrefix = "copilot_";
maintainers = [ maintainers.GaetanLepage ];
# TODO introduced 2024-03-02: remove 2024-05-02
deprecateExtraConfig = true;
optionsRenamedToSettings = [
"nodeCommand"
"filetypes"
"proxy"
];
settingsOptions = {
node_command = mkOption {
type = with types; nullOr str;
default = "${pkgs.nodejs-18_x}/bin/node";
description = "Tell Copilot what `node` binary to use.";
};
filetypes = mkOption {
type = with types; nullOr (attrsOf bool);
default = null;
description = "A dictionary mapping file types to their enabled status.";
example = {
"*" = false;
python = true;
};
};
proxy = mkOption {
type = with types; nullOr str;
default = null;
description = ''
Tell Copilot what proxy server to use.
If this is not set, Copilot will use the value of environment variables like
`$HTTPS_PROXY`.
'';
example = "localhost:3128";
};
proxy_strict_ssl = helpers.mkNullOrOption types.bool ''
Corporate proxies sometimes use a man-in-the-middle SSL certificate which is incompatible
with GitHub Copilot.
To work around this, SSL certificate verification can be disabled by setting this option to
`false`.
You can also tell `Node.js` to disable SSL verification by setting the
`$NODE_TLS_REJECT_UNAUTHORIZED` environment variable to `"0"`.
'';
workspace_folders = helpers.mkNullOrOption (with types; listOf str) ''
A list of "workspace folders" or project roots that Copilot may use to improve to improve
the quality of suggestions.
Example: ["~/Projects/myproject"]
You can also set `b:workspace_folder` for an individual buffer and newly seen values will be
added automatically.
'';
};
settingsExample = {
filetypes = {
"*" = false;
python = true;
};
proxy = "localhost:3128";
proxy_strict_ssl = false;
workspace_folders = [ "~/Projects/myproject" ];
};
}

View file

@ -0,0 +1,94 @@
{
lib,
helpers,
pkgs,
...
}:
with lib;
helpers.neovim-plugin.mkNeovimPlugin {
name = "coq-nvim";
originalName = "coq_nvim";
package = "coq_nvim";
maintainers = [
maintainers.traxys
helpers.maintainers.Kareem-Medhat
];
extraOptions = {
# TODO: should this enable option be replaced with `nullable = true` in the package option?
installArtifacts = mkEnableOption "and install coq-artifacts";
artifactsPackage = mkPackageOption pkgs "coq-artifacts" {
extraDescription = "Installed when `installArtifacts` is enabled.";
default = [
"vimPlugins"
"coq-artifacts"
];
};
};
# TODO: Introduced 12-03-2022, remove 12-05-2022
optionsRenamedToSettings = [
"xdg"
"autoStart"
];
imports =
let
basePath = [
"plugins"
"coq-nvim"
];
settingsPath = basePath ++ [ "settings" ];
in
[
(mkRenamedOptionModule (basePath ++ [ "recommendedKeymaps" ]) (
settingsPath
++ [
"keymap"
"recommended"
]
))
(mkRenamedOptionModule (basePath ++ [ "alwaysComplete" ]) (
settingsPath
++ [
"completion"
"always"
]
))
];
callSetup = false;
settingsOptions = {
auto_start = helpers.mkNullOrOption (
with helpers.nixvimTypes; maybeRaw (either bool (enum [ "shut-up" ]))
) "Auto-start or shut up";
xdg = mkOption {
type = types.bool;
default = true;
description = "Use XDG paths. May be required when installing coq with Nix.";
};
keymap.recommended = helpers.defaultNullOpts.mkBool true "Use the recommended keymaps";
completion.always = helpers.defaultNullOpts.mkBool true "Always trigger completion on keystroke";
};
extraConfig = cfg: {
extraPlugins = mkIf cfg.installArtifacts [ cfg.artifactsPackage ];
globals = {
coq_settings = cfg.settings;
};
extraConfigLua = "require('coq')";
plugins.lsp = {
preConfig = ''
local coq = require 'coq'
'';
setupWrappers = [ (s: ''coq.lsp_ensure_capabilities(${s})'') ];
};
};
}

View file

@ -0,0 +1,77 @@
{
lib,
helpers,
config,
pkgs,
...
}:
with lib;
let
cfg = config.plugins.coq-thirdparty;
in
{
options.plugins.coq-thirdparty = {
enable = mkEnableOption "coq-thirdparty";
package = lib.mkPackageOption pkgs "coq-thirdparty" {
default = [
"vimPlugins"
"coq-thirdparty"
];
};
sources = mkOption {
type = types.listOf (
types.submodule {
freeformType = types.attrs;
options = {
src = mkOption {
type = types.str;
description = "The name of the source";
};
short_name = mkOption {
type = types.nullOr types.str;
description = ''
A short name for the source.
If not specified, it is uppercase `src`.
'';
example = "nLUA";
default = null;
};
};
}
);
description = ''
List of sources.
Each source is a free-form type, so additional settings like `accept_key` may be specified even if they are not declared by nixvim.
'';
default = [ ];
example = [
{
src = "nvimlua";
short_name = "nLUA";
}
{
src = "vimtex";
short_name = "vTEX";
}
{
src = "copilot";
short_name = "COP";
accept_key = "<c-f>";
}
{ src = "demo"; }
];
};
};
config = mkIf cfg.enable {
extraPlugins = [ cfg.package ];
extraConfigLua = ''
require('coq_3p')(${helpers.toLuaObject cfg.sources})
'';
};
}

View file

@ -0,0 +1,95 @@
{
lib,
helpers,
config,
pkgs,
...
}:
with lib;
let
cfg = config.plugins.lspkind;
in
{
options.plugins.lspkind = helpers.neovim-plugin.extraOptionsOptions // {
enable = mkEnableOption "lspkind.nvim";
package = lib.mkPackageOption pkgs "lspkind" {
default = [
"vimPlugins"
"lspkind-nvim"
];
};
mode = helpers.defaultNullOpts.mkEnum [
"text"
"text_symbol"
"symbol_text"
"symbol"
] "symbol_text" "Defines how annotations are shown";
preset = helpers.defaultNullOpts.mkEnum [
"default"
"codicons"
] "codicons" "Default symbol map";
symbolMap = helpers.mkNullOrOption (types.attrsOf types.str) "Override preset symbols";
cmp = {
enable = mkOption {
type = types.bool;
default = true;
description = "Integrate with nvim-cmp";
};
maxWidth = helpers.mkNullOrOption types.int "Maximum number of characters to show in the popup";
ellipsisChar = helpers.mkNullOrOption types.str "Character to show when the popup exceeds maxwidth";
menu = helpers.mkNullOrOption (types.attrsOf types.str) "Show source names in the popup";
after = helpers.mkNullOrOption types.str "Function to run after calculating the formatting. function(entry, vim_item, kind)";
};
};
config =
let
doCmp = cfg.cmp.enable && config.plugins.cmp.enable;
options =
{
inherit (cfg) mode preset;
symbol_map = cfg.symbolMap;
}
// (
if doCmp then
{
maxwidth = cfg.cmp.maxWidth;
ellipsis_char = cfg.cmp.ellipsisChar;
inherit (cfg.cmp) menu;
}
else
{ }
)
// cfg.extraOptions;
in
mkIf cfg.enable {
extraPlugins = [ cfg.package ];
extraConfigLua = optionalString (!doCmp) ''
require('lspkind').init(${helpers.toLuaObject options})
'';
plugins.cmp.settings.formatting.format =
if cfg.cmp.after != null then
''
function(entry, vim_item)
local kind = require('lspkind').cmp_format(${helpers.toLuaObject options})(entry, vim_item)
return (${cfg.cmp.after})(entry, vim_item, kind)
end
''
else
''
require('lspkind').cmp_format(${helpers.toLuaObject options})
'';
};
}