Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: nix-community/nixvim
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 890686cdef2258069505aadeb6d74f49a77f1e6d
Choose a base ref
..
head repository: nix-community/nixvim
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 21c85fd338d97d0da90c677cd86f5653063614f5
Choose a head ref
Showing 326 changed files with 3,331 additions and 2,052 deletions.
55 changes: 35 additions & 20 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -34,47 +34,62 @@ To add a new plugin you need to do the following.

The vast majority of plugins fall into one of those two categories:
- _vim plugins_: They are configured through **global variables** (`g:plugin_foo_option` in vimscript and `vim.g.plugin_foo_option` in lua).\
For those, you should use the `helpers.vim-plugin.mkVimPlugin`.\
For those, you should use the `lib.nixvim.vim-plugin.mkVimPlugin`.\
-> See [this plugin](plugins/utils/direnv.nix) for an example.
- _neovim plugins_: They are configured through a `setup` function (`require('plugin').setup({opts})`).\
For those, you should use the `helpers.neovim-plugin.mkNeovimPlugin`.\
For those, you should use the `lib.nixvim.neovim-plugin.mkNeovimPlugin`.\
-> See the [template](plugins/TEMPLATE.nix).

2. Add the necessary parameters for the `mkNeovimPlugin`/`mkVimPlugin`:
- `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))
- e.g. `maintainers = [ lib.maintainers.JosephFourier ]`
- If you are already registered as a [`nixpkgs` maintainer][nixpkgs-maintainers], there is nothing more to do.
- Otherwise, you should add yourself to our [`maintainers.nix`](lib/maintainers.nix) list.
- See the documentation at the top of the [`nixpkgs` maintainers list][nixpkgs-maintainers] for more detail.
- `settingsOptions`: All or some (only the most important ones) option declarations for this plugin settings.\
See below for more information
- `settingsExample`: An example of what could the `settings` attrs look like.

#### Declaring plugin options

You will then need to add Nix options for all (or some) of the upstream plugin options.
These option declarations should be in `settingsOptions` and their names should match exactly the upstream plugin.
There are a number of helpers to help you correctly implement them:
3. Add to plugins/default.nix
- As a final step, please add your plugin to `plugins/default.nix` to ensure it gets imported.
- Note: the imports list is sorted and grouped. In vim, you can usually use `V` (visual-line mode) with the `:sort` command to achieve the desired result.

- `helpers.defaultNullOpts.{mkBool,mkInt,mkStr,...}`: This family of helpers takes a default value and a description, and sets the Nix default to `null`. These are the main functions you should use to define options.
- `helpers.defaultNullOpts.mkNullable`: This takes a type, a default and a description. This is useful for more complex options.
- `helpers.nixvimTypes.rawLua`: A type to represent raw lua code. The values are of the form `{ __raw = "<code>";}`. This should not be used if the option can only be raw lua code, `mkLua`/`mkLuaFn` should be used in this case.
[nixpkgs-maintainers]: https://github.com/NixOS/nixpkgs/blob/master/maintainers/maintainer-list.nix

The resulting `settings` attrs will be directly translated to `lua` and will be forwarded the plugin:
- Using globals (`vim.g.<globalPrefix><option-name>`) for plugins using `mkVimPlugin`
- Using the `require('<plugin>').setup()` function for the plugins using `mkNeovimPlugin`
#### Declaring plugin options

In either case, you don't need to bother implementing this part. It is done automatically.
> [!CAUTION]
> Declaring `settings`-options is **not required**, because the `settings` option is a freeform type.
>
> While `settings` options can be helpful for documentation and type-checking purposes, this is a double-edged sword because we have to ensure the options are correctly typed and documented to avoid unnecessary restrictions or confusion.
> [!TIP]
> Learn more about the [RFC 42](https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md) which motivated this new approach.
> [!NOTE]
> `settings` has a "freeform" type `attrsOf anything`, meaning it can be configured with _anything_.
> Declaring `settingsOptions` is therefore optional and just adds type-checking and documentation.
If you feel having nix options for some of the upstream plugin options adds value and is worth the maintenance cost, you can declare these in `settingsOptions`.

Take care to ensure option names exactly match the upstream plugin's option names (without `globalsPrefix`, if used).
You must also ensure that the option type is permissive enough to avoid unnecessarily restricting config definitions.
If unsure, you can forego declaring the option or use a permissive type such as `lib.types.anything`.

There are a number of helpers added into `lib` that can help you correctly implement them:

- `lib.nixvim.defaultNullOpts.{mkBool,mkInt,mkStr,...}`: This family of helpers takes a default value and a description, and sets the Nix default to `null`.
These are the main functions you should use to define options.
- `lib.nixvim.defaultNullOpts.<name>'`: These "prime" variants of the above helpers do the same thing, but expect a "structured" attrs argument.
This allows more flexibility in what arguments are passed through to the underlying `lib.mkOption` call.
- `lib.types.rawLua`: A type to represent raw lua code. The values are of the form `{ __raw = "<code>";}`.

The resulting `settings` attrs will be directly translated to `lua` and will be forwarded the plugin:
- Using globals (`vim.g.<globalPrefix><option-name>`) for plugins using `mkVimPlugin`
- Using the `require('<plugin>').setup(<options>)` function for the plugins using `mkNeovimPlugin`

In either case, you don't need to bother implementing this part. It is done automatically.

### Tests

6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -18,8 +18,8 @@ NixVim is a [Neovim](https://neovim.io) distribution built around
configured through Nix, all while leaving room for your plugins and your vimrc.

## What does it look like?
Here is a simple configuration that uses gruvbox as the colorscheme and uses the
lightline plugin:
Here is a simple configuration that uses catppuccin as the colorscheme and uses the
lualine plugin:

```nix
{
@@ -89,7 +89,7 @@ If you have any question, please use the [discussions page](https://github.com/n
>
> If you want to use NixVim with nixpkgs 24.05 you should use the `nixos-24.05` branch.
For more detail, see the [Installation](https://nix-community.github.io/nixvim/install.html#installation) section of our documentation.
For more detail, see the [Installation](https://nix-community.github.io/nixvim) section of our documentation.

<details>
<summary><strong>Without flakes</strong></summary>
45 changes: 22 additions & 23 deletions docs/mdbook/default.nix
Original file line number Diff line number Diff line change
@@ -7,7 +7,6 @@
hmOptions,
search,
}:
with lib;
let
inherit (evaledModules.config.meta) nixvimInfo;

@@ -31,17 +30,17 @@ let
removeWhitespace = builtins.replaceStrings [ " " ] [ "" ];

getSubOptions =
opts: path: optionalAttrs (isVisible opts) (removeUnwanted (opts.type.getSubOptions path));
opts: path: lib.optionalAttrs (isVisible opts) (removeUnwanted (opts.type.getSubOptions path));

isVisible =
opts:
if isOption opts then
if lib.isOption opts then
opts.visible or true
else if opts.isOption then
opts.index.options.visible or true
else
let
filterFunc = filterAttrs (_: v: if isAttrs v then isVisible v else true);
filterFunc = lib.filterAttrs (_: v: if lib.isAttrs v then isVisible v else true);

hasEmptyIndex = (filterFunc opts.index.options) == { };
hasEmptyComponents = (filterFunc opts.components) == { };
@@ -54,11 +53,11 @@ let
if isOpt then
opts
else
filterAttrs (_: component: component.isOption && (isVisible component)) opts;
path = removeWhitespace (concatStringsSep "/" path);
lib.filterAttrs (_: component: component.isOption && (isVisible component)) opts;
path = removeWhitespace (lib.concatStringsSep "/" path);
moduleDoc =
let
info = optionalAttrs (hasAttrByPath path nixvimInfo) (getAttrFromPath path nixvimInfo);
info = lib.attrByPath path { } nixvimInfo;
maintainers = lib.unique (evaledModules.config.meta.maintainers.${info.file} or [ ]);
maintainersNames = builtins.map maintToMD maintainers;
maintToMD = m: if m ? github then "[${m.name}](https://github.com/${m.github})" else m.name;
@@ -85,7 +84,7 @@ let
if isOpt then
{ }
else
filterAttrs (_: component: !component.isOption && (isVisible component)) opts;
lib.filterAttrs (_: component: !component.isOption && (isVisible component)) opts;

hasComponents = components != { };

@@ -100,7 +99,7 @@ let
let
g =
name: opts:
if !isOption opts then
if !lib.isOption opts then
wrapModule (path ++ [ name ]) (recurse (path ++ [ name ]) opts) false
else
let
@@ -113,7 +112,7 @@ let
# This is necessary to include the submodule option's definition in the docs (description, type, etc.)
# For instance, this helps submodules like "autoCmd" to include their base definitions and examples in the docs
# Though there might be a better, less "hacky" solution than this.
${name} = recursiveUpdate opts {
${name} = lib.recursiveUpdate opts {
isOption = true;
type.getSubOptions = _: _: { }; # Used to exclude suboptions from the submodule definition itself
};
@@ -122,9 +121,9 @@ let
else
wrapModule (path ++ [ name ]) opts true;
in
mapAttrs g mods;
lib.mapAttrs g mods;
in
foldlAttrs (
lib.foldlAttrs (
acc: name: opts:
let
group = if !opts.hasComponents then "Neovim Options" else "none";
@@ -141,17 +140,17 @@ let
hasComponents = false;
};

isOpt = !opts.hasComponents && (isOption opts.index.options);
isOpt = !opts.hasComponents && (lib.isOption opts.index.options);
in
acc
// {
${group} = recursiveUpdate last {
index.options = optionalAttrs isOpt { ${name} = opts.index.options; };
${group} = lib.recursiveUpdate last {
index.options = lib.optionalAttrs isOpt { ${name} = opts.index.options; };

components = optionalAttrs (!isOpt) {
${name} = recursiveUpdate opts {
components = lib.optionalAttrs (!isOpt) {
${name} = lib.recursiveUpdate opts {
index.path = removeWhitespace (
concatStringsSep "/" ((optional (group != "none") group) ++ [ opts.index.path ])
lib.concatStringsSep "/" ((lib.optional (group != "none") group) ++ [ opts.index.path ])
);
hasComponents = true;
};
@@ -177,7 +176,7 @@ let
else
f name opts;
in
concatStringsSep "\n" (mapAttrsToList g mods);
lib.concatStringsSep "\n" (lib.mapAttrsToList g mods);
in
recurse modules;

@@ -186,10 +185,10 @@ let
commands = mapModulesToString (
name: opts:
let
isBranch = if (hasSuffix "index" opts.index.path) then true else opts.hasComponents;
isBranch = if (lib.hasSuffix "index" opts.index.path) then true else opts.hasComponents;
path = if isBranch then "${opts.index.path}/index.md" else "${opts.index.path}.md";
in
(optionalString isBranch "mkdir -p ${opts.index.path}\n")
(lib.optionalString isBranch "mkdir -p ${opts.index.path}\n")
+ (
if opts.index.moduleDoc == null then
"cp ${mkMDDoc opts.index.options} ${path}"
@@ -222,7 +221,7 @@ let

indentLevel = with builtins; length (filter isString (split "/" opts.index.path)) - 1;

padding = concatStrings (builtins.genList (_: "\t") indentLevel);
padding = lib.concatStrings (builtins.genList (_: "\t") indentLevel);
in
"${padding}- [${name}](${path})"
) docs.modules;
@@ -254,7 +253,7 @@ pkgs.stdenv.mkDerivation {
phases = [ "buildPhase" ];

buildInputs = [ pkgs.mdbook ];
inputs = sourceFilesBySuffices ./. [
inputs = lib.sourceFilesBySuffices ./. [
".md"
".toml"
".js"
2 changes: 2 additions & 0 deletions docs/user-guide/faq.md
Original file line number Diff line number Diff line change
@@ -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` -->

```
(stack trace truncated; use '--show-trace' to show the full trace)
1 change: 1 addition & 0 deletions flake-modules/dev/default.nix
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@

settings = {
global.excludes = [
".editorconfig"
".envrc"
".git-blame-ignore-revs"
".gitignore"
5 changes: 4 additions & 1 deletion flake-modules/tests.nix
Original file line number Diff line number Diff line change
@@ -9,12 +9,14 @@
...
}:
let
inherit (self'.legacyPackages.lib) helpers makeNixvimWithModule;
callTest = lib.callPackageWith (
pkgs
// {
nixvimLib = self'.legacyPackages.lib;
inherit (self'.legacyPackages.lib) helpers makeNixvimWithModule;
inherit helpers makeNixvimWithModule;
inherit (self'.legacyPackages.lib.check) mkTestDerivationFromNvim mkTestDerivationFromNixvimModule;
evaluatedNixvim = helpers.modules.evalNixvim { check = false; };
}
);
in
@@ -32,6 +34,7 @@
lib-tests = callTest ../tests/lib-tests.nix { };
maintainers = callTest ../tests/maintainers.nix { };
generated = callTest ../tests/generated.nix { };
package-options = callTest ../tests/package-options.nix { };
} // callTest ../tests { inherit pkgsUnfree; };
};
}
18 changes: 9 additions & 9 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading