diff --git a/src/lib/interactive.ml b/src/lib/interactive.ml index 800e741..39e4d13 100644 --- a/src/lib/interactive.ml +++ b/src/lib/interactive.ml @@ -42,7 +42,7 @@ module Make (S : Types.State) (E : Types.Exec) (H : Types.History) = struct else if Sys.file_exists name then [ name ] else [] - let complete ~home:_ path = + let complete ~home path = let rest, last_arg = String.split_on_char ' ' path |> List.rev |> function | [] -> ([], `None) @@ -71,6 +71,13 @@ module Make (S : Types.State) (E : Types.Exec) (H : Types.History) = struct | `None -> [] | `Prog prog -> resolve_programs prog | `Path path -> ( + (* We should probably thread expansion logic from the evaluator back into this, + but for now we manually, and crudely, expand the tilde if it is there. *) + let path = + match String.get path 0 with + | '~' -> home ^ String.sub path 1 (String.length path - 1) + | _ | (exception Invalid_argument _) -> path + in match Unix.(stat path).st_kind with | exception Unix.Unix_error ((Unix.ENOENT | Unix.ENOTDIR), _, _) -> let dirname = Filename.dirname path in @@ -116,8 +123,11 @@ module Make (S : Types.State) (E : Types.Exec) (H : Types.History) = struct in let complete = match S.lookup (Exit.value ctx |> Eval.state) ~param:"HOME" with - | Some home -> complete ~home - | None -> complete ~home:(Eunix.find_env "HOME") + | Some home -> complete ~home:(Ast.Fragment.join_list ~sep:"" home) + | None -> + (* TODO: many shells implement a lookup of passwd to fill this in if no HOME + is set. I believe the POSIX specification says "comme vous voulez" *) + complete ~home:(Option.value ~default:"/" @@ Eunix.find_env "HOME") in match Bruit.bruit ~hint