add darwin support

This commit is contained in:
atagen 2026-05-24 18:10:30 +10:00
parent 73904c036f
commit 4a7febee6c
10 changed files with 774 additions and 47 deletions

View file

@ -37,6 +37,18 @@ let inshellah_limit_args = { |flag|
if $inshellah_dynamic_limit == 0 { [] } else { [$flag $inshellah_dynamic_limit] }
}
# nushell's own cap on how many external completions it will display.
# mirrors the Rust completer's INSHELLAH_MAX_COMPLETIONS cap so both ends
# agree. 0 (or unset) keeps the historical default of 200.
let inshellah_default_max_results = 200
let inshellah_max_results = do {
let raw = (try {
$env.INSHELLAH_MAX_COMPLETIONS? | default 0 | into int
} catch { 0 })
if $raw > 0 { $raw } else { $inshellah_default_max_results }
}
let inshellah_with_timeout = { |body|
if $inshellah_dynamic_timeout_ms == 0 {
try { do $body } catch { null }
@ -853,4 +865,4 @@ let inshellah_complete = { |spans|
}
}
$env.config.completions.external = {enable: true, max_results: 200, completer: $inshellah_complete}
$env.config.completions.external = {enable: true, max_results: $inshellah_max_results, completer: $inshellah_complete}

View file

@ -1,4 +1,4 @@
# NixOS module: automatic nushell completion indexing
# NixOS / nix-darwin module: automatic nushell completion indexing
#
# Indexes completions using three strategies in priority order:
# 1. Native completion generators (e.g. CMD completions nushell)
@ -8,11 +8,18 @@
# Produces a directory of .json/.nu files at build time.
# The `complete` command reads from this directory as a system overlay.
#
# Usage:
# This module body only uses options shared by NixOS and nix-darwin
# (environment.{variables,systemPackages,pathsToLink,extraSetup}), so the
# same file backs both flake outputs. On macOS the indexer scrapes Mach-O
# binaries; on Linux, ELF — selected by the inshellah build's target os.
#
# Usage (NixOS):
# { pkgs, ... }: {
# imports = [ ./path/to/inshellah-rs/nix/module.nix ];
# programs.inshellah.enable = true;
# }
# Usage (nix-darwin): identical — import the same file (or the flake's
# darwinModules.default) and set programs.inshellah.enable = true.
{
config,
@ -100,6 +107,22 @@ in
'';
};
extraScrapePackages = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = [ ];
example = lib.literalExpression "[ pkgs.git pkgs.clang ]";
description = ''
additional packages to scrape for completions alongside the system
profile. each package's store path is passed to `inshellah index`
via `--prefix`, so it must contain bin/ and/or share/man/.
useful on macOS, where the active developer toolchain (git, clang,
) lives outside the nix system profile behind /usr/bin shims:
install the nix equivalents and list them here so their completions
get indexed reproducibly, rather than probing the host toolchain.
'';
};
timeoutMs = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
@ -132,6 +155,56 @@ in
'';
};
flagTriggers = lib.mkOption {
type = lib.types.str;
default = "-";
example = "-+";
description = ''
characters that trigger flag (option) completions when a partial
token begins with one of them. the default "-" reproduces the
original behaviour where only a leading dash surfaces flags. each
character is taken literally; whitespace is ignored. exported as
INSHELLAH_FLAG_TRIGGERS.
'';
};
flagOnEmpty = lib.mkOption {
type = lib.types.bool;
default = false;
example = true;
description = ''
also surface flag completions when nothing has been typed yet
i.e. right after a space/tab alongside subcommands. when false
(the default) an empty token hands off to file/dynamic completion.
exported as INSHELLAH_FLAG_ON_EMPTY.
'';
};
maxCompletions = lib.mkOption {
type = lib.types.int;
default = 0;
example = 100;
description = ''
upper bound on the number of static completion candidates returned,
and the nushell `max_results` shown. 0 means no inshellah-imposed
cap (nushell's built-in default of 200 still applies). exported as
INSHELLAH_MAX_COMPLETIONS.
'';
};
completeTimeoutMs = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
example = 400;
description = ''
per-subprocess timeout in milliseconds for the on-the-fly --help
resolution the completer performs for uncached commands. distinct
from `timeoutMs` (build-time indexing) and `dynamicTimeoutMs` (the
nushell shim's live providers). null uses the binary's compiled
default (currently 200ms). exported as INSHELLAH_TIMEOUT_MS.
'';
};
workers = lib.mkOption {
type = lib.types.nullOr lib.types.int;
default = null;
@ -155,6 +228,12 @@ in
config = lib.mkIf cfg.enable {
environment.variables.INSHELLAH_DYNAMIC_TIMEOUT_MS = toString cfg.dynamicTimeoutMs;
environment.variables.INSHELLAH_DYNAMIC_LIMIT = toString cfg.dynamicLimit;
environment.variables.INSHELLAH_FLAG_TRIGGERS = cfg.flagTriggers;
environment.variables.INSHELLAH_FLAG_ON_EMPTY = if cfg.flagOnEmpty then "1" else "0";
environment.variables.INSHELLAH_MAX_COMPLETIONS = toString cfg.maxCompletions;
environment.variables.INSHELLAH_TIMEOUT_MS = lib.mkIf (
cfg.completeTimeoutMs != null
) (toString cfg.completeTimeoutMs);
environment.systemPackages =
let
@ -191,13 +270,18 @@ in
helpOnlyFlag = lib.optionalString (cfg.helpOnlyCommands != [ ]) " --help-only ${helpOnlyFile}";
timeoutFlag = lib.optionalString (cfg.timeoutMs != null) " --timeout-ms ${toString cfg.timeoutMs}";
workersFlag = lib.optionalString (cfg.workers != null) " --workers ${toString cfg.workers}";
# roll the explicit extra packages up into a single colon-separated
# --prefix so they're scraped alongside the system profile.
prefixFlag = lib.optionalString (cfg.extraScrapePackages != [ ]) (
" --prefix " + lib.concatStringsSep ":" (map toString cfg.extraScrapePackages)
);
snippetFile = pkgs.writeText "inshellah-completer.nu" cfg.snippet;
in
''
mkdir -p ${destDir}
if [ -d "$out/bin" ] && [ -d "$out/share/man" ]; then
${inshellah} index "$out" --dir ${destDir}${ignoreFlag}${helpOnlyFlag}${timeoutFlag}${workersFlag} \
${inshellah} index "$out" --dir ${destDir}${ignoreFlag}${helpOnlyFlag}${prefixFlag}${timeoutFlag}${workersFlag} \
2>/dev/null || true
fi