diff --git a/src/lib/interactive.ml b/src/lib/interactive.ml index 0db2e36..9a0a5f9 100644 --- a/src/lib/interactive.ml +++ b/src/lib/interactive.ml @@ -29,11 +29,24 @@ module Make (S : Types.State) (E : Types.Exec) (H : Types.History) = struct (Fpath.normalize @@ S.cwd state |> subst_tilde |> Fpath.to_string); Format.flush_str_formatter () + let resolve_programs name = + if not (String.contains name '/') then begin + Eunix.find_env "PATH" + |> Option.value ~default:"/bin:/usr/bin" + |> String.split_on_char ':' + |> List.concat_map (fun dir -> + let files = try Sys.readdir dir |> Array.to_list with _ -> [] in + List.filter (fun f -> String.starts_with ~prefix:name f) files) + end + else if Sys.file_exists name then [ name ] + else [] + let complete path = let rest, last_arg = String.split_on_char ' ' path |> List.rev |> function - | [] -> ([], None) - | x :: rest -> (List.rev rest, Some x) + | [] -> ([], `None) + | [ prog ] -> ([], `Prog prog) + | x :: rest -> (List.rev rest, `Path x) in let completions from_path basename = match (Unix.stat from_path).st_kind with @@ -53,8 +66,9 @@ module Make (S : Types.State) (E : Types.Exec) (H : Types.History) = struct | exception Unix.Unix_error (Unix.ENOENT, _, _) -> [] in match last_arg with - | None -> [] - | Some path -> ( + | `None -> [] + | `Prog prog -> resolve_programs prog + | `Path path -> ( match Unix.(stat path).st_kind with | exception Unix.Unix_error (Unix.ENOENT, _, _) -> let dirname = Filename.dirname path in @@ -87,7 +101,7 @@ module Make (S : Types.State) (E : Types.Exec) (H : Types.History) = struct match Bruit.bruit ~history:(fun command -> H.history ~command !h |> H.commands) - ~complete "" + ~complete "% " with | String None -> Fmt.pr "exit\n%!";