forked from
lass.pds.lassul.us/superconfig
This repository has no description
4.4 kB
134 lines
1{ self, ... }:
2{
3 perSystem =
4 { pkgs, lib, ... }:
5 let
6 # Collect all completable package names
7 packageNames = builtins.attrNames self.packages.${pkgs.system};
8 legacyPackageNames =
9 let
10 lp = self.legacyPackages.${pkgs.system} or { };
11 flatten =
12 prefix: attrs:
13 lib.concatLists (
14 lib.mapAttrsToList (
15 name: value:
16 let
17 path = if prefix == "" then name else "${prefix}.${name}";
18 in
19 if lib.isDerivation value then
20 [ path ]
21 else if builtins.isAttrs value then
22 flatten path value
23 else
24 [ ]
25 ) attrs
26 );
27 in
28 flatten "" lp;
29 allNames = packageNames ++ legacyPackageNames;
30
31 completionPath = lib.makeBinPath [
32 pkgs.nix
33 pkgs.jq
34 pkgs.usage
35 ];
36
37 zshCompletion = pkgs.writeText "_s" ''
38 #compdef s
39
40 _s() {
41 local -x PATH="${completionPath}:$PATH"
42
43 if (( CURRENT == 2 )); then
44 # Complete package name
45 local -a packages
46 packages=(
47 ${lib.concatMapStringsSep "\n " (name: "'${name}'") allNames}
48 )
49 _describe 'package' packages
50 else
51 # Complete args for the selected package using usage spec
52 local pkg="''${words[2]}"
53 [[ -z "$pkg" ]] && return
54
55 # Resolve flake path (same logic as s itself)
56 local flake
57 if [[ -d "$HOME/src/superconfig" ]]; then
58 flake="$HOME/src/superconfig"
59 elif [[ -d "$HOME/sync/superconfig" ]]; then
60 flake="$HOME/sync/superconfig"
61 else
62 flake="github:Lassulus/superconfig"
63 fi
64
65 # Cache directory
66 local cache_dir="''${XDG_CACHE_HOME:-$HOME/.cache}/s-completions"
67
68 # Get cache key from flake narHash (~0.1s)
69 local cache_key
70 cache_key=$(nix flake metadata "$flake" --json 2>/dev/null | jq -r '.locked.narHash // .narHash // (.lastModified | tostring)' 2>/dev/null) || return
71 [[ -z "$cache_key" ]] && return
72 cache_key=''${cache_key//\//_}
73
74 local cached_file="$cache_dir/''${cache_key}/''${pkg}.kdl"
75
76 if [[ ! -f "$cached_file" ]]; then
77 # Cache miss: fetch usage spec via nix eval (~3.6s, first time only)
78 mkdir -p "$cache_dir/$cache_key"
79 local sys
80 sys=$(nix eval --impure --raw --expr 'builtins.currentSystem' 2>/dev/null) || return
81 nix eval "''${flake}#packages.''${sys}.''${pkg}.usage" --raw 2>/dev/null > "$cached_file" || {
82 rm -f "$cached_file"
83 return
84 }
85 # Empty file means no usage spec
86 [[ -s "$cached_file" ]] || { rm -f "$cached_file"; return; }
87 fi
88
89 # Feed to usage complete-word (~4ms), using the ((...)) format that _arguments expects
90 _arguments "*: :(($(usage complete-word --shell zsh -f "$cached_file" -- "''${words[@]:1}")))"
91 fi
92 }
93
94 _s "$@"
95 '';
96 in
97 {
98 packages.s =
99 (pkgs.writeShellApplication {
100 name = "s";
101 runtimeInputs = [ pkgs.nix ];
102 text = ''
103 # Use local checkout if it exists, otherwise fall back to GitHub
104 if [ -d "$HOME/src/superconfig" ]; then
105 flake="$HOME/src/superconfig"
106 elif [ -d "$HOME/sync/superconfig" ]; then
107 flake="$HOME/sync/superconfig"
108 else
109 flake="github:Lassulus/superconfig"
110 fi
111
112 if [ $# -eq 0 ]; then
113 echo "Usage: s <package> [args...]" >&2
114 echo "Runs a package from superconfig ($flake)" >&2
115 exit 1
116 fi
117
118 pkg="$1"
119 shift
120
121 exec nix run "$flake#$pkg" -- "$@"
122 '';
123 }).overrideAttrs
124 (old: {
125 buildCommand = old.buildCommand + ''
126 mkdir -p $out/share/zsh/site-functions
127 cp ${zshCompletion} $out/share/zsh/site-functions/_s
128 '';
129 passthru = (old.passthru or { }) // {
130 usage = builtins.readFile ./usage.kdl;
131 };
132 });
133 };
134}