Merge pull request #1030 from NotAShelf/notashelf/push-nprwpvxsxrmv
Some checks failed
Set up binary cache / cachix (default) (push) Waiting to run
Set up binary cache / cachix (maximal) (push) Waiting to run
Set up binary cache / cachix (nix) (push) Waiting to run
Treewide Checks / Validate flake (push) Waiting to run
Treewide Checks / Check formatting (push) Waiting to run
Treewide Checks / Check source tree for typos (push) Waiting to run
Treewide Checks / Validate documentation builds (push) Waiting to run
Treewide Checks / Validate hyperlinks in documentation sources (push) Waiting to run
Treewide Checks / Validate Editorconfig conformance (push) Waiting to run
Build and deploy documentation / Check latest commit (push) Has been cancelled
Build and deploy documentation / publish (push) Has been cancelled

flake: move packages to a by-name overlay
This commit is contained in:
raf 2025-07-21 23:47:47 +03:00 committed by GitHub
commit 0115325759
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 231 additions and 108 deletions

View file

@ -1,25 +1,92 @@
# Adding Plugins {#sec-additional-plugins}
To add a new Neovim plugin, use `npins`
There are two methods for adding new Neovim plugins to **nvf**. npins is the
faster option that should be preferred if the plugin consists of pure Lua or
Vimscript code. In which case there is no building required, and we can easily
handle the copying of plugin files. Alternative method, which is required when
plugins try to build their own libraries (e.g., in Rust or C) that need to be
built with Nix to function correctly.
Use:
## With npins {#sec-npins-for-plugins}
`nix-shell -p npins` or `nix shell nixpkgs#npins`
npins is the standard method of adding new plugins to **nvf**. You simply need
the repository URL for the plugin, and can add it as a source to be built
automatically with one command. To add a new Neovim plugin, use `npins`. For
example:
```bash
nix-shell -p npins # or nix shell nixpkgs#npins if using flakes
```
Then run:
`npins add --name <plugin name> github <owner> <repo> -b <branch>`
```bash
npins add --name <plugin name> github <owner> <repo> -b <branch>
```
Be sure to replace any non-alphanumeric characters with `-` for `--name`
::: {.note}
For example
Be sure to replace any non-alphanumeric characters with `-` for `--name`. For
example
`npins add --name lazydev-nvim github folke lazydev.nvim -b main`
```bash
npins add --name lazydev-nvim github folke lazydev.nvim -b main
```
You can now reference this plugin as a **string**.
:::
Once the `npins` command is done, you can start referencing the plugin as a
**string**.
```nix
config.vim.startPlugins = ["lazydev-nvim"];
{
config.vim.startPlugins = ["lazydev-nvim"];
}
```
## Packaging Complex Plugins {#sec-pkgs-for-plugins}
[blink.cmp]: https://github.com/Saghen/blink.cmp
Some plugins require additional packages to be built and substituted to function
correctly. For example [blink.cmp] requires its own fuzzy matcher library, built
with Rust, to be installed or else defaults to a much slower Lua implementation.
In the Blink documentation, you are advised to build with `cargo` but that is
not ideal since we are leveraging the power of Nix. In this case the ideal
solution is to write a derivation for the plugin.
We use `buildRustPackage` to build the library from the repository root, and
copy everything in the `postInstall` phase.
```nix
postInstall = ''
cp -r {lua,plugin} "$out"
mkdir -p "$out/doc"
cp 'doc/'*'.txt' "$out/doc/"
mkdir -p "$out/target"
mv "$out/lib" "$out/target/release"
'';
```
In a similar fashion, you may utilize `stdenv.mkDerivation` and other Nixpkgs
builders to build your library from source, and copy the relevant files and Lua
plugin files in the `postInstall` phase. Do note, however, that you still need
to fetch the plugin sources somehow. npins is, once again, the recommended
option to fetch the plugin sources. Refer to the previous section on how to use
npins to add a new plugin.
Plugins built from source must go into the `flake/pkgs/by-name` overlay. It will
automatically create flake outputs for individual packages. Lastly, you must add
your package to the plugin builder (`pluginBuilders`) function manually in
`modules/wrapper/build/config.nix`. Once done, you may refer to your plugin as a
**string**.
```nix
{
config.vim.startPlugins = ["blink-cmp"];
}
```
## Modular setup options {#sec-modular-setup-options}
@ -70,7 +137,7 @@ in {
}
```
This above config will result in this lua script:
This above config will result in this Lua script:
```lua
require('plugin-name').setup({
@ -101,23 +168,41 @@ own fields!
As you've seen above, `toLuaObject` is used to convert our nix attrSet
`cfg.setupOpts`, into a lua table. Here are some rules of the conversion:
1. nix `null` converts to lua `nil`
2. number and strings convert to their lua counterparts
3. nix attrSet/list convert into lua tables
4. you can write raw lua code using `lib.generators.mkLuaInline`. This function
is part of nixpkgs.
1. Nix `null` converts to lua `nil`
2. Number and strings convert to their lua counterparts
3. Nix attribute sets (`{}`) and lists (`[]`) convert into Lua dictionaries and
tables respectively. Here is an example of Nix -> Lua conversion.
- `{foo = "bar"}` -> `{["foo"] = "bar"}`
- `["foo" "bar"]` -> `{"foo", "bar"}`
4. You can write raw Lua code using `lib.generators.mkLuaInline`. This function
is part of nixpkgs, and is accessible without relying on **nvf**'s extended
library.
- `mkLuaInline "function add(a, b) return a + b end"` will yield the
following result:
Example:
```nix
{
_type = "lua-inline";
expr = "function add(a, b) return a + b end";
}
```
```nix
vim.your-plugin.setupOpts = {
on_init = lib.generators.mkLuaInline ''
function()
print('we can write lua!')
end
'';
}
```
The above expression will be interpreted as a Lua expression in the final
config. Without the `mkLuaInline` function, you will only receive a string
literal. You can use it to feed plugin configuration tables Lua functions
that return specific values as expected by the plugins.
```nix
{
vim.your-plugin.setupOpts = {
on_init = lib.generators.mkLuaInline ''
function()
print('we can write lua!')
end
'';
};
}
```
## Lazy plugins {#sec-lazy-plugins}
@ -126,25 +211,24 @@ Lazy plugins are managed by `lz.n`.
```nix
# in modules/.../your-plugin/config.nix
{lib, config, ...}:
let
{config, ...}: let
cfg = config.vim.your-plugin;
in {
vim.lazy.plugins.your-plugin = {
# instead of vim.startPlugins, use this:
# Instead of vim.startPlugins, use this:
package = "your-plugin";
# if your plugin uses the `require('your-plugin').setup{...}` pattern
# ıf your plugin uses the `require('your-plugin').setup{...}` pattern
setupModule = "your-plugin";
inherit (cfg) setupOpts;
# events that trigger this plugin to be loaded
# Events that trigger this plugin to be loaded
event = ["DirChanged"];
cmd = ["YourPluginCommand"];
# keymaps
# Plugin Keymaps
keys = [
# we'll cover this in detail in the keymaps section
# We'll cover this in detail in the 'keybinds' section
{
key = "<leader>d";
mode = "n";
@ -152,7 +236,6 @@ in {
}
];
};
;
}
```
@ -163,7 +246,9 @@ require('lz.n').load({
{
"name-of-your-plugin",
after = function()
require('your-plugin').setup({--[[ your setupOpts ]]})
require('your-plugin').setup({
--[[ your setupOpts ]]--
})
end,
event = {"DirChanged"},
@ -175,5 +260,7 @@ require('lz.n').load({
})
```
A full list of options can be found
[here](https://notashelf.github.io/nvf/options.html#opt-vim.lazy.plugins
[`vim.lazy.plugins` spec]: https://notashelf.github.io/nvf/options.html#opt-vim.lazy.plugins
A full list of options can be found in the [`vim.lazy.plugins` spec] on the
rendered manual.

View file

@ -9,84 +9,114 @@
lib,
...
}: let
inherit (lib.customisation) makeScope;
inherit (lib.attrsets) isDerivation isAttrs concatMapAttrs;
inherit (lib.strings) concatStringsSep;
inherit (lib.filesystem) packagesFromDirectoryRecursive;
# Entrypoint for nvf documentation and relevant packages.
docs = import ../docs {inherit pkgs inputs lib;};
# Helper function for creating demo configurations for nvf
# TODO: make this more generic.
buildPkg = maximal:
(args.config.flake.lib.nvim.neovimConfiguration {
inherit pkgs;
modules = [(import ../configuration.nix maximal)];
}).neovim;
# This constructs a by-name overlay similar to the one found in Nixpkgs.
# The goal is to automatically discover and packages found in pkgs/by-name
# as long as they have a 'package.nix' in the package directory. We also
# pass 'inputs' and 'pins' to all packages in the 'callPackage' scope, therefore
# they are always available in the relevant 'package.nix' files.
# ---
# The logic is borrowed from drupol/pkgs-by-name-for-flake-parts, available
# under the MIT license.
flattenPkgs = separator: path: value:
if isDerivation value
then {
${concatStringsSep separator path} = value;
}
else if isAttrs value
then concatMapAttrs (name: flattenPkgs separator (path ++ [name])) value
else
# Ignore the functions which makeScope returns
{};
inputsScope = makeScope pkgs.newScope (_: {
inherit inputs;
inherit (self) pins;
});
scopeFromDirectory = directory:
packagesFromDirectoryRecursive {
inherit directory;
inherit (inputsScope) newScope callPackage;
};
legacyPackages = scopeFromDirectory ./pkgs/by-name;
in {
packages = {
blink-cmp = pkgs.callPackage ./blink {};
avante-nvim = let
pin = self.pins.avante-nvim;
in
pkgs.callPackage ./avante-nvim {
version = pin.branch;
src = pkgs.fetchFromGitHub {
inherit (pin.repository) owner repo;
rev = pin.revision;
sha256 = pin.hash;
};
pins = self.pins;
};
packages =
(flattenPkgs "/" [] legacyPackages)
// {
inherit (docs.manual) htmlOpenTool;
inherit (docs.manual) htmlOpenTool;
# Documentation
docs = docs.manual.html;
docs-html = docs.manual.html;
docs-manpages = docs.manPages;
docs-json = docs.options.json;
docs-linkcheck = let
site = config.packages.docs;
in
pkgs.testers.lycheeLinkCheck {
inherit site;
# Documentation
docs = docs.manual.html;
docs-html = docs.manual.html;
docs-manpages = docs.manPages;
docs-json = docs.options.json;
docs-linkcheck = let
site = config.packages.docs;
in
pkgs.testers.lycheeLinkCheck {
inherit site;
remap = {
"https://notashelf.github.io/nvf/" = site;
remap = {
"https://notashelf.github.io/nvf/" = site;
};
extraConfig = {
exclude = [];
include_mail = true;
include_verbatim = true;
};
};
extraConfig = {
exclude = [];
include_mail = true;
include_verbatim = true;
};
};
# Helper utility for building the HTML manual and opening it in the
# browser with $BROWSER or using xdg-open as a fallback tool.
# Adapted from Home-Manager, available under the MIT license.
docs-html-wrapped = let
xdg-open = lib.getExe' pkgs.xdg-utils "xdg-open";
docs-html = docs.manual.html + /share/doc/nvf;
in
pkgs.writeShellScriptBin "docs-html-wrapped" ''
set -euo pipefail
# Helper utility for building the HTML manual and opening it in the
# browser with $BROWSER or using xdg-open as a fallback tool.
# Adapted from Home-Manager, available under the MIT license.
docs-html-wrapped = let
xdg-open = lib.getExe' pkgs.xdg-utils "xdg-open";
docs-html = docs.manual.html + /share/doc/nvf;
in
pkgs.writeShellScriptBin "docs-html-wrapped" ''
set -euo pipefail
if [[ ! -v BROWSER || -z $BROWSER ]]; then
for candidate in xdg-open open w3m; do
BROWSER="$(type -P $candidate || true)"
if [[ -x $BROWSER ]]; then
break;
fi
done
fi
if [[ ! -v BROWSER || -z $BROWSER ]]; then
for candidate in xdg-open open w3m; do
BROWSER="$(type -P $candidate || true)"
if [[ -x $BROWSER ]]; then
break;
fi
done
fi
if [[ ! -v BROWSER || -z $BROWSER ]]; then
echo "$0: unable to start a web browser; please set \$BROWSER"
echo "$0: Trying xdg-open as a fallback"
${xdg-open} ${docs-html}/index.xhtml
else
echo "\$BROWSER is set. Attempting to open manual"
exec "$BROWSER" "${docs-html}/index.xhtml"
fi
'';
if [[ ! -v BROWSER || -z $BROWSER ]]; then
echo "$0: unable to start a web browser; please set \$BROWSER"
echo "$0: Trying xdg-open as a fallback"
${xdg-open} ${docs-html}/index.xhtml
else
echo "\$BROWSER is set. Attempting to open manual"
exec "$BROWSER" "${docs-html}/index.xhtml"
fi
'';
# Exposed neovim configurations
nix = buildPkg false;
maximal = buildPkg true;
default = config.packages.nix;
};
# Exposed neovim configurations
nix = buildPkg false;
maximal = buildPkg true;
default = config.packages.nix;
};
};
}

View file

@ -1,4 +1,5 @@
{
pins,
openssl,
pkg-config,
rustPlatform,
@ -6,11 +7,17 @@
vimUtils,
makeWrapper,
pkgs,
version,
src,
...
}: let
inherit version src;
# From npins
pin = pins.avante-nvim;
version = pin.branch;
src = pkgs.fetchFromGitHub {
inherit (pin.repository) owner repo;
rev = pin.revision;
sha256 = pin.hash;
};
avante-nvim-lib = rustPlatform.buildRustPackage {
pname = "avante-nvim-lib";
inherit version src;
@ -48,10 +55,9 @@ in
ext = stdenv.hostPlatform.extensions.sharedLibrary;
in ''
mkdir -p $out/build
ln -s ${avante-nvim-lib}/lib/libavante_repo_map${ext} $out/build/avante_repo_map${ext}
ln -s ${avante-nvim-lib}/lib/libavante_templates${ext} $out/build/avante_templates${ext}
ln -s ${avante-nvim-lib}/lib/libavante_tokenizers${ext} $out/build/avante_tokenizers${ext}
ln -s ${avante-nvim-lib}/lib/libavante_html2md${ext} $out/build/avante_html2md${ext}
for lib in avante_repo_map avante_templates avante_tokenizers avante_html2md; do
ln -s ${avante-nvim-lib}/lib/lib$lib${ext} $out/build/$$lib${ext}
done
'';
nvimSkipModules = [