Skip to content

lib/*-plugins: initial support for lib.mkPackageOption #2139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ The vast majority of plugins fall into one of those two categories:
- `name`: The name of the plugin. The resulting nixvim module will have `plugins.<name>` as a path.\
For a plugin named `foo-bar.nvim`, set this to `foo-bar` (subject to exceptions).
- `originalName`: The "real" name of the plugin (i.e. `foo-bar.nvim`). This is used mostly in documentation.
- `defaultPackage`: The nixpkgs package for this plugin (e.g. `pkgs.vimPlugins.foo-bar-nvim`).
- `package`: The nixpkgs package attr for this plugin
e.g. `"foo-bar-nvim` for `pkgs.vimPlugins.foo-bar-nvim`, or `[ "hello" "world" ]` for `pkgs.hello.world`.
- `maintainers`: Register yourself as a maintainer for this plugin:
- `[lib.maintainers.JosephFourier]` if you are already registered as a [`nixpkgs` maintainer](https://github.com/NixOS/nixpkgs/blob/master/maintainers/maintainer-list.nix)
- `[helpers.maintainers.GaspardMonge]` otherwise. (Also add yourself to [`maintainers.nix`](lib/maintainers.nix))
Expand Down
2 changes: 2 additions & 0 deletions docs/user-guide/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ The [nixpkgs manual](https://nixos.org/manual/nixpkgs/stable/#managing-plugins-w

When using NixVim it is possible to encounter an error of the type `attribute 'name' missing`, for example it could look like:

<!-- TODO: Update example now that we use `mkPackageOption` -->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we want to handle this in this PR or follow up?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we'll leave it for later. Next time a user reports a mismatched nixpkgs error we can use the error message they report in the example here.


```
(stack trace truncated; use '--show-trace' to show the full trace)

Expand Down
132 changes: 77 additions & 55 deletions lib/neovim-plugin.nix
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ with lib;
{
name,
maintainers,
url ? defaultPackage.meta.homepage,
url ? throw "default",
imports ? [ ],
description ? null,
# deprecations
Expand All @@ -28,7 +28,12 @@ with lib;
colorscheme ? name,
# options
originalName ? name,
defaultPackage,
# Can be a string, a list of strings, or a module option:
# - A string will be intrpreted as `pkgs.vimPlugins.${package}`
# - A list will be interpreted as a "pkgs path", e.g. `pkgs.${elem1}.${elem2}.${etc...}`
# - An option will be used as-is, but should be built using `lib.mkPackageOption`
# Defaults to `name`, i.e. `pkgs.vimPlugins.${name}`
package ? name,
settingsOptions ? { },
settingsExample ? null,
settingsDescription ? "Options provided to the `require('${luaName}')${setup}` function.",
Expand All @@ -42,22 +47,78 @@ with lib;
extraPackages ? [ ],
callSetup ? true,
installPackage ? true,
}:
}@args:
let
namespace = if isColorscheme then "colorschemes" else "plugins";

module =
{
config,
options,
pkgs,
...
}:
let
cfg = config.${namespace}.${name};
opt = options.${namespace}.${name};
extraConfigNamespace = if isColorscheme then "extraConfigLuaPre" else "extraConfigLua";
in
{
meta = {
inherit maintainers;
nixvimInfo = {
inherit description;
url = args.url or opt.package.default.meta.homepage;
path = [
namespace
name
];
};
};

options.${namespace}.${name} =
{
enable = mkEnableOption originalName;
package =
if lib.isOption package then
package
else
lib.mkPackageOption pkgs originalName {
default =
if builtins.isList package then
package
else
[
"vimPlugins"
package
];
};
}
// optionalAttrs hasSettings {
settings = helpers.mkSettingsOption {
description = settingsDescription;
options = settingsOptions;
example = settingsExample;
};
}
// extraOptions;

config = mkIf cfg.enable (mkMerge [
{
extraPlugins = (optional installPackage cfg.package) ++ extraPlugins;
inherit extraPackages;
}
(optionalAttrs callSetup {
${extraConfigNamespace} = ''
require('${luaName}')${setup}(${optionalString (cfg ? settings) (helpers.toLuaObject cfg.settings)})
'';
})
(optionalAttrs (isColorscheme && (colorscheme != null)) { colorscheme = mkDefault colorscheme; })
(extraConfig cfg)
]);
};
in
{
meta = {
inherit maintainers;
nixvimInfo = {
inherit description url;
path = [
namespace
name
];
};
};

imports =
let
basePluginPath = [
Expand All @@ -67,49 +128,10 @@ with lib;
settingsPath = basePluginPath ++ [ "settings" ];
in
imports
++ [ module ]
++ (optional deprecateExtraOptions (
mkRenamedOptionModule (basePluginPath ++ [ "extraOptions" ]) settingsPath
))
++ (nixvim.mkSettingsRenamedOptionModules basePluginPath settingsPath optionsRenamedToSettings)
++ [
(
{ config, ... }:
{
config =
let
cfg = config.${namespace}.${name};
extraConfigNamespace = if isColorscheme then "extraConfigLuaPre" else "extraConfigLua";
in
mkIf cfg.enable (mkMerge [
{
extraPlugins = (optional installPackage cfg.package) ++ extraPlugins;
inherit extraPackages;
}
(optionalAttrs callSetup {
${extraConfigNamespace} = ''
require('${luaName}')${setup}(${optionalString (cfg ? settings) (helpers.toLuaObject cfg.settings)})
'';
})
(optionalAttrs (isColorscheme && (colorscheme != null)) { colorscheme = mkDefault colorscheme; })
(extraConfig cfg)
]);
}
)
];

options.${namespace}.${name} =
{
enable = mkEnableOption originalName;

package = helpers.mkPluginPackageOption originalName defaultPackage;
}
// optionalAttrs hasSettings {
settings = helpers.mkSettingsOption {
description = settingsDescription;
options = settingsOptions;
example = settingsExample;
};
}
// extraOptions;
++ (nixvim.mkSettingsRenamedOptionModules basePluginPath settingsPath optionsRenamedToSettings);
};
}
2 changes: 2 additions & 0 deletions lib/options.nix
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ rec {
);
};

# TODO: Deprecated 2024-09-02; remove once all internal uses are gone
mkPackageOption =
args:
# A default package is required
Expand All @@ -326,6 +327,7 @@ rec {
}
);

# TODO: Deprecated 2024-09-02; remove once all internal uses are gone
mkPluginPackageOption =
name: default:
mkOption {
Expand Down
110 changes: 63 additions & 47 deletions lib/vim-plugin.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ with lib;
mkVimPlugin =
{
name,
url ? if defaultPackage != null then defaultPackage.meta.homepage else null,
url ? throw "default",
maintainers,
imports ? [ ],
description ? null,
Expand All @@ -16,7 +16,12 @@ with lib;
colorscheme ? name,
# options
originalName ? name,
defaultPackage ? null,
# Can be a string, a list of strings, or a module option:
# - A string will be intrpreted as `pkgs.vimPlugins.${package}`
# - A list will be interpreted as a "pkgs path", e.g. `pkgs.${elem1}.${elem2}.${etc...}`
# - An option will be used as-is, but should be built using `lib.mkPackageOption`
# Defaults to `name`, i.e. `pkgs.vimPlugins.${name}`
package ? name,
settingsOptions ? { },
settingsExample ? null,
globalPrefix ? "",
Expand All @@ -25,17 +30,10 @@ with lib;
extraConfig ? cfg: { },
extraPlugins ? [ ],
extraPackages ? [ ],
}:
}@args:
let
namespace = if isColorscheme then "colorschemes" else "plugins";

# does this evaluate package?
packageOption =
if defaultPackage == null then
{ }
else
{ package = helpers.mkPluginPackageOption name defaultPackage; };

createSettingsOption = (isString globalPrefix) && (globalPrefix != "");

settingsOption = optionalAttrs createSettingsOption {
Expand All @@ -54,42 +52,61 @@ with lib;
};
};

modules = [
(
{ config, ... }:
let
cfg = config.${namespace}.${name};
in
{
config = mkIf cfg.enable (mkMerge [
{
inherit extraPackages;
globals = mapAttrs' (n: nameValuePair (globalPrefix + n)) (cfg.settings or { });
# does this evaluate package? it would not be desired to evaluate package if we use another package.
extraPlugins = extraPlugins ++ optional (defaultPackage != null) cfg.package;
}
(optionalAttrs (isColorscheme && (colorscheme != null)) { colorscheme = mkDefault colorscheme; })
(extraConfig cfg)
]);
}
)
];
module =
{
config,
options,
pkgs,
...
}:
let
cfg = config.${namespace}.${name};
opt = options.${namespace}.${name};
in
{
meta = {
inherit maintainers;
nixvimInfo = {
inherit description;
url = args.url or opt.package.default.meta.homepage;
path = [
namespace
name
];
};
};

options.${namespace}.${name} = {
enable = mkEnableOption originalName;
package =
if lib.isOption package then
package
else
lib.mkPackageOption pkgs originalName {
default =
if builtins.isList package then
package
else
[
"vimPlugins"
package
];
};
} // settingsOption // extraOptions;

config = mkIf cfg.enable (mkMerge [
{
inherit extraPackages;
globals = mapAttrs' (n: nameValuePair (globalPrefix + n)) (cfg.settings or { });
# does this evaluate package? it would not be desired to evaluate package if we use another package.
extraPlugins = extraPlugins ++ optional (cfg.package != null) cfg.package;
}
(optionalAttrs (isColorscheme && (colorscheme != null)) { colorscheme = mkDefault colorscheme; })
(extraConfig cfg)
]);
};
in
{
meta = {
inherit maintainers;
nixvimInfo = {
inherit description url;
path = [
namespace
name
];
};
};
options.${namespace}.${name} = {
enable = mkEnableOption originalName;
} // settingsOption // packageOption // extraOptions;

imports =
let
basePluginPath = [
Expand All @@ -99,11 +116,10 @@ with lib;
settingsPath = basePluginPath ++ [ "settings" ];
in
imports
++ [ module ]
++ (optional (deprecateExtraConfig && createSettingsOption) (
mkRenamedOptionModule (basePluginPath ++ [ "extraConfig" ]) settingsPath
))
++ (nixvim.mkSettingsRenamedOptionModules basePluginPath settingsPath optionsRenamedToSettings)
++ modules;

++ (nixvim.mkSettingsRenamedOptionModules basePluginPath settingsPath optionsRenamedToSettings);
};
}
8 changes: 2 additions & 6 deletions plugins/TEMPLATE.nix
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
{
lib,
pkgs,
...
}:
{ lib, ... }:
let
inherit (lib.nixvim) defaultNullOpts;
in
lib.nixvim.neovim-plugin.mkNeovimPlugin {
name = "my-plugin";
originalName = "my-plugin.nvim"; # TODO replace (or remove entirely if it is the same as `name`)
defaultPackage = pkgs.vimPlugins.my-plugin-nvim; # TODO replace
package = "my-plugin-nvim"; # TODO replace

maintainers = [ lib.maintainers.MyName ]; # TODO replace with your name

Expand Down
2 changes: 1 addition & 1 deletion plugins/ai/chatgpt.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ with lib;
helpers.neovim-plugin.mkNeovimPlugin {
name = "chatgpt";
originalName = "ChatGPT.nvim";
defaultPackage = pkgs.vimPlugins.ChatGPT-nvim;
package = "ChatGPT-nvim";

maintainers = [ maintainers.GaetanLepage ];

Expand Down
3 changes: 1 addition & 2 deletions plugins/ai/copilot-chat.nix
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
{
lib,
helpers,
pkgs,
...
}:
with lib;
helpers.neovim-plugin.mkNeovimPlugin {
name = "copilot-chat";
originalName = "CopilotChat.nvim";
luaName = "CopilotChat";
defaultPackage = pkgs.vimPlugins.CopilotChat-nvim;
package = "CopilotChat-nvim";

maintainers = [ maintainers.GaetanLepage ];

Expand Down
Loading