109 lines
3.6 KiB
Nix
109 lines
3.6 KiB
Nix
# NixOS module: automatic nushell completion generation from manpages
|
|
#
|
|
# Modeled on nixpkgs' programs/fish.nix completion generator.
|
|
# For each package in environment.systemPackages, a small derivation runs
|
|
# `inshellah manpage-dir` against its share/man directory. Results are merged
|
|
# into a single directory and placed in nushell's vendor autoload path.
|
|
#
|
|
# Usage in your NixOS configuration:
|
|
#
|
|
# { pkgs, ... }: {
|
|
# imports = [ ./path/to/inshellah/nix/module.nix ];
|
|
# programs.inshellah.enable = true;
|
|
# # Optionally add packages not in systemPackages:
|
|
# # programs.inshellah.extraPackages = [ pkgs.kubectl ];
|
|
# }
|
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
let
|
|
cfg = config.programs.inshellah;
|
|
|
|
# The inshellah binary — override this if you build from the local flake
|
|
inshellahPkg = cfg.package;
|
|
|
|
# Per-package derivation: run inshellah manpage-dir against a package's manpages
|
|
generateCompletions = package:
|
|
pkgs.runCommandLocal
|
|
(let
|
|
inherit (lib.strings) stringLength substring storeDir;
|
|
storeLength = stringLength storeDir + 34;
|
|
pathName = substring storeLength (stringLength package - storeLength) package;
|
|
in
|
|
(package.name or pathName) + "_nu-completions"
|
|
)
|
|
({
|
|
inherit package;
|
|
nativeBuildInputs = [ inshellahPkg ];
|
|
} // lib.optionalAttrs (package ? meta.priority) {
|
|
meta.priority = package.meta.priority;
|
|
})
|
|
''
|
|
mkdir -p $out
|
|
if [ -d "$package/share/man" ]; then
|
|
inshellah manpage-dir "$package/share/man" > "$out/completions.nu" 2>/dev/null || true
|
|
# Remove empty files
|
|
find $out -empty -delete
|
|
fi
|
|
'';
|
|
|
|
in {
|
|
options.programs.inshellah = {
|
|
enable = lib.mkEnableOption "nushell completion generation from manpages via inshellah";
|
|
|
|
package = lib.mkOption {
|
|
type = lib.types.package;
|
|
description = "The inshellah package to use for generating completions.";
|
|
};
|
|
|
|
extraPackages = lib.mkOption {
|
|
type = lib.types.listOf lib.types.package;
|
|
default = [];
|
|
description = ''
|
|
Additional packages to generate nushell completions from, beyond
|
|
those in {option}`environment.systemPackages`.
|
|
'';
|
|
};
|
|
|
|
generatedCompletionsPath = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "/share/nushell/vendor/autoload";
|
|
description = ''
|
|
Subdirectory within the merged environment where completion files
|
|
are placed. The default matches nushell's vendor autoload convention
|
|
(discovered via XDG_DATA_DIRS).
|
|
'';
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
# Merge all per-package completions into a single directory.
|
|
# This path ends up in the system profile, and nushell discovers it
|
|
# via XDG_DATA_DIRS -> $prefix/share/nushell/vendor/autoload/
|
|
environment.pathsToLink = [ cfg.generatedCompletionsPath ];
|
|
|
|
environment.systemPackages = [
|
|
(pkgs.buildEnv {
|
|
name = "nushell-generated-completions";
|
|
ignoreCollisions = true;
|
|
paths = map generateCompletions (
|
|
config.environment.systemPackages ++ cfg.extraPackages
|
|
);
|
|
pathsToLink = [ "/" ];
|
|
# Nest everything under the vendor autoload path
|
|
postBuild = ''
|
|
if [ -d "$out" ]; then
|
|
tmp=$(mktemp -d)
|
|
cp -r "$out/"* "$tmp/" 2>/dev/null || true
|
|
rm -rf "$out/"*
|
|
mkdir -p "$out${cfg.generatedCompletionsPath}"
|
|
for f in "$tmp"/*.nu; do
|
|
[ -f "$f" ] && cp "$f" "$out${cfg.generatedCompletionsPath}/"
|
|
done
|
|
rm -rf "$tmp"
|
|
fi
|
|
'';
|
|
})
|
|
];
|
|
};
|
|
}
|