From 75b64b7dfad9ce659d91128fb49773dfa78926ee Mon Sep 17 00:00:00 2001 From: Patrick Ferris Date: Mon, 3 Aug 2026 15:00:33 +0100 Subject: [PATCH] Add hint to unix backend --- example/unix/main.ml | 8 ++++++-- src/bruit.ml | 14 -------------- src/unix/bruit_unix.ml | 19 +++++++++++++++---- src/unix/bruit_unix.mli | 1 + 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/example/unix/main.ml b/example/unix/main.ml index a9b449e..76f0f83 100644 --- a/example/unix/main.ml +++ b/example/unix/main.ml @@ -6,12 +6,16 @@ let history prefix = let complete s = match String.get s 0 with - | 'h' -> [ "hello"; "hello there" ] + | 'h' -> [ "hello"; "hello there"; "heya" ] | _ | (exception Invalid_argument _) -> [] +let hint = function + | "h" | "he" | "hel" -> Some ("hello", `Fg `Cyan) + | _ -> None + let () = Fmt_tty.setup_std_outputs (); - let ctx = Bruit_unix.stdctx () in + let ctx = Bruit_unix.stdctx ~hint () in let rec loop sys_break = let prompt = if sys_break then "[\x1b[31m130\x1b[0m] \x1b[33m>>\x1b[0m " diff --git a/src/bruit.ml b/src/bruit.ml index 8193e19..92167d1 100644 --- a/src/bruit.ml +++ b/src/bruit.ml @@ -259,20 +259,6 @@ let utf8_prev_char_len s off = in loop (off - 1) -let _refresh_with_hints ~pwidth ~ab (state : State.t) = - let buf_width = utf8_display_width state state.buf state.len in - if pwidth + buf_width < state.cols then - begin match state.hint (State.buf state |> Bytes.to_string) with - | None -> () - | Some (hint, style) -> - let () = - Format.fprintf Format.str_formatter "%a" - Fmt.(styled style string) - hint - in - Buffer.add_string ab (Format.flush_str_formatter ()) - end - let refresh_line_with_completions (state : State.t) lcs = if state.completion_idx < List.length lcs then let saved_state = state in diff --git a/src/unix/bruit_unix.ml b/src/unix/bruit_unix.ml index 9ade011..2a2d75c 100644 --- a/src/unix/bruit_unix.ml +++ b/src/unix/bruit_unix.ml @@ -39,7 +39,17 @@ let utf8_next_char_len s off = Bytes.get_utf_8_uchar s off |> Uchar.utf_decode_uchar |> Uchar.utf_8_byte_length -let render ofd = function +let refresh_with_hints ~hint ~ab buf = + begin match hint (buf |> Bytes.to_string) with + | None -> () + | Some (hint, style) -> + let () = + Format.fprintf Format.str_formatter "%a" Fmt.(styled style string) hint + in + Buffer.add_string ab (Format.flush_str_formatter ()) + end + +let render ~hint ofd = function | Bruit.Clear_screen -> let b = Bytes.of_string "\x1b[H\x1b[2J" in let _ : int = write ofd b ~off:0 ~len:(Bytes.length b) in @@ -71,7 +81,7 @@ let render ofd = function Buffer.add_bytes ab prompt; Buffer.add_bytes ab (Bytes.sub buf 0 buf_len); - (* refresh_with_hints ~pwidth:state.len ~ab state; *) + refresh_with_hints ~hint ~ab (Bytes.sub buf 0 buf_len); (* Erase to the right *) Buffer.add_string ab "\x1b[0K"; @@ -82,11 +92,12 @@ let render ofd = function let _ : int = write ofd bs ~off:0 ~len:(Bytes.length bs) in () -let stdctx ?(stdin = Unix.stdin) ?(stdout = Unix.stdout) () = +let stdctx ?(stdin = Unix.stdin) ?(stdout = Unix.stdout) ?(hint = fun _ -> None) + () = let read () = read stdin in let next_key () = Bruit.key read in let enter_raw_mode = enter_raw_mode stdin in let exit_raw_mode = exit_raw_mode stdin in Bruit.make_ctx ~next_key ~enter_raw_mode ~exit_raw_mode ~get_columns:Terminal.Size.get_columns - ~guess_printed_width:Terminal.guess_printed_width (render stdout) + ~guess_printed_width:Terminal.guess_printed_width (render ~hint stdout) diff --git a/src/unix/bruit_unix.mli b/src/unix/bruit_unix.mli index ac52d67..195548d 100644 --- a/src/unix/bruit_unix.mli +++ b/src/unix/bruit_unix.mli @@ -5,6 +5,7 @@ val stdctx : ?stdin:Unix.file_descr -> ?stdout:Unix.file_descr -> + ?hint:(string -> (string * Fmt.style) option) -> unit -> Unix.terminal_io Bruit.ctx (** [stdctx ()] will by default use {! Unix.stdin} and {! Unix.stdout}. It is up -- 2.51.2