fix nix bash wrapper detection, add more completion keywords
This commit is contained in:
parent
daa0c24415
commit
f9d970f2e5
1 changed files with 47 additions and 6 deletions
53
bin/main.ml
53
bin/main.ml
|
|
@ -281,6 +281,34 @@ let nix_wrapper_target path =
|
|||
end
|
||||
with _ -> None
|
||||
|
||||
(* detect nix bash/sh wrapper scripts that exec a real binary.
|
||||
* nix sometimes generates small shell scripts (e.g. to set env vars like
|
||||
* XDG_CONFIG_HOME) that exec the real binary. these look like:
|
||||
* #!/nix/store/.../bash -e
|
||||
* export FOO=...
|
||||
* exec -a "$0" "/nix/store/.../bin/.foo-wrapped" "$@"
|
||||
* we extract the exec target path and resolve through it. *)
|
||||
let nix_script_wrapper_target path =
|
||||
try
|
||||
let real = Unix.realpath path in
|
||||
let ic = open_in real in
|
||||
let size = in_channel_length ic in
|
||||
if size > 4096 then (close_in ic; None)
|
||||
else begin
|
||||
let contents = Bytes.create size in
|
||||
really_input ic contents 0 size; close_in ic;
|
||||
let contents = Bytes.to_string contents in
|
||||
if not (contains_str contents "exec") then None
|
||||
else
|
||||
let re = Str.regexp "exec[ \t]+\\(-a[ \t]+\"\\$0\"[ \t]+\\)?\"?\\(/nix/store/[a-z0-9]+-[^\" \t\n]+/bin/[a-zA-Z0-9._-]+\\)\"?" in
|
||||
try ignore (Str.search_forward re contents 0);
|
||||
let target = Str.matched_group 2 contents in
|
||||
let target = Unix.realpath target in
|
||||
if Sys.file_exists target then Some target else None
|
||||
with Not_found -> None
|
||||
end
|
||||
with _ -> None
|
||||
|
||||
(* heuristic filter for binary names that should never be indexed.
|
||||
* skips: empty names, "-", dotfiles, libraries (lib-prefix), daemon wrappers
|
||||
* (suffixes -daemon, -wrapped), shared objects (.so suffix), and names with no
|
||||
|
|
@ -299,25 +327,37 @@ let skip_name name =
|
|||
* Try_native_and_help — try native nushell completion first, fall back to --help *)
|
||||
type bin_class = Skip | Try_help | Try_native_and_help
|
||||
|
||||
(* classify an elf binary path for indexing. *)
|
||||
let classify_elf path =
|
||||
let scan = elf_scan path ["-h"; "completion"] in
|
||||
if Hashtbl.mem scan "completion" then Try_native_and_help
|
||||
else if Hashtbl.mem scan "-h" then Try_help
|
||||
else Skip
|
||||
|
||||
(* classify a binary to decide the indexing strategy.
|
||||
* decision tree:
|
||||
* 1. nushell builtin or bad name -> Skip
|
||||
* 2. not executable -> Skip
|
||||
* 3. script (has shebang) -> Try_help (scripts can't have native completions)
|
||||
* 3. script (has shebang) -> resolve through nix script wrapper if possible,
|
||||
* otherwise Try_help
|
||||
* 4. elf binary containing "completion" -> Try_native_and_help
|
||||
* 5. elf binary containing "-h" -> Try_help
|
||||
* 6. nix wrapper -> Try_help (the wrapper itself is just an exec shim)
|
||||
* 6. nix c wrapper -> Try_help (the wrapper itself is just an exec shim)
|
||||
* 7. otherwise -> Skip (binary has no help infrastructure) *)
|
||||
let classify_binary bindir name =
|
||||
if is_nushell_builtin name || skip_name name then Skip
|
||||
else
|
||||
let path = Filename.concat bindir name in
|
||||
if not (is_executable path) then Skip
|
||||
else if is_script path then Try_help
|
||||
else if is_script path then
|
||||
match nix_script_wrapper_target path with
|
||||
| Some target ->
|
||||
let cls = classify_elf target in
|
||||
if cls <> Skip then cls else Try_help
|
||||
| None -> Try_help
|
||||
else
|
||||
let scan = elf_scan path ["-h"; "completion"] in
|
||||
if Hashtbl.mem scan "completion" then Try_native_and_help
|
||||
else if Hashtbl.mem scan "-h" then Try_help
|
||||
let cls = classify_elf path in
|
||||
if cls <> Skip then cls
|
||||
else if nix_wrapper_target path <> None then Try_help
|
||||
else Skip
|
||||
|
||||
|
|
@ -352,6 +392,7 @@ let try_native_completion bin_path =
|
|||
[bin_path; "--completion"; "nushell"];
|
||||
[bin_path; "generate-completion"; "nushell"];
|
||||
[bin_path; "--generate-completion"; "nushell"];
|
||||
[bin_path; "gen-completions"; "nushell"];
|
||||
[bin_path; "shell-completions"; "nushell"];
|
||||
]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue