92 lines
2.7 KiB
Nix
92 lines
2.7 KiB
Nix
# NixOS module: automatic nushell completion generation
|
|
#
|
|
# Generates completions using three strategies in priority order:
|
|
# 1. Native completion generators (e.g. CMD completions nushell)
|
|
# 2. Manpage parsing
|
|
# 3. --help output parsing
|
|
#
|
|
# Runs as a single pass during the system profile build.
|
|
#
|
|
# Usage:
|
|
# { pkgs, ... }: {
|
|
# imports = [ ./path/to/inshellah/nix/module.nix ];
|
|
# programs.inshellah.enable = true;
|
|
# }
|
|
|
|
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
|
|
let
|
|
cfg = config.programs.inshellah;
|
|
in
|
|
{
|
|
options.programs.inshellah = {
|
|
enable = lib.mkEnableOption "nushell completion generation via inshellah";
|
|
|
|
package = lib.mkOption {
|
|
type = lib.types.package;
|
|
description = "The inshellah package to use for generating completions.";
|
|
};
|
|
|
|
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).
|
|
'';
|
|
};
|
|
|
|
ignoreCommands = lib.mkOption {
|
|
type = lib.types.listOf lib.types.str;
|
|
default = [];
|
|
example = [ "meat" "problematic-tool" ];
|
|
description = ''
|
|
List of command names to skip during completion generation.
|
|
'';
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
environment.pathsToLink = [ cfg.generatedCompletionsPath ];
|
|
|
|
environment.extraSetup =
|
|
let
|
|
inshellah = "${cfg.package}/bin/inshellah";
|
|
destDir = "$out${cfg.generatedCompletionsPath}";
|
|
segments = lib.filter (s: s != "") (lib.splitString "/" cfg.generatedCompletionsPath);
|
|
derefPath = lib.concatMapStringsSep "\n " (seg: ''
|
|
_cur="$_cur/${seg}"
|
|
if [ -L "$_cur" ]; then
|
|
_target=$(readlink "$_cur")
|
|
rm "$_cur"
|
|
mkdir -p "$_cur"
|
|
if [ -d "$_target" ]; then
|
|
cp -rT "$_target" "$_cur"
|
|
chmod -R u+w "$_cur"
|
|
fi
|
|
fi'') segments;
|
|
ignoreFile = pkgs.writeText "inshellah-ignore" (lib.concatStringsSep "\n" cfg.ignoreCommands);
|
|
ignoreFlag = lib.optionalString (cfg.ignoreCommands != []) " --ignore ${ignoreFile}";
|
|
in
|
|
''
|
|
_cur="$out"
|
|
${derefPath}
|
|
mkdir -p ${destDir}
|
|
|
|
# Generate all completions in one pass:
|
|
# native generators > manpages > --help fallback
|
|
if [ -d "$out/bin" ] && [ -d "$out/share/man" ]; then
|
|
${inshellah} generate "$out/bin" "$out/share/man" -o ${destDir}${ignoreFlag} \
|
|
2>/dev/null || true
|
|
fi
|
|
|
|
find ${destDir} -maxdepth 1 -empty -delete
|
|
'';
|
|
};
|
|
}
|