diff --git a/src/brr/bruit_brr.ml b/src/brr/bruit_brr.ml index c8d603c..24fc2f0 100644 --- a/src/brr/bruit_brr.ml +++ b/src/brr/bruit_brr.ml @@ -74,12 +74,8 @@ let stdctx ?(redirect = false) (stdin : El.t) (prompt : El.t) (stdout : El.t) : Ev.prevent_default e; e |> Ev.as_type |> keyboard_event_to_key in - let write bs ~off ~len = - ignore (bs, off); - len - in let enter_raw_mode () = () in let exit_raw_mode () = () in - Bruit.make_ctx ~get_columns ~next_key ~write ~enter_raw_mode ~exit_raw_mode + Bruit.make_ctx ~get_columns ~next_key ~enter_raw_mode ~exit_raw_mode ~guess_printed_width (render ~output:stdout ~prompt_el:prompt ~input:stdin) diff --git a/src/bruit.ml b/src/bruit.ml index 674e3d3..183b400 100644 --- a/src/bruit.ml +++ b/src/bruit.ml @@ -92,20 +92,18 @@ type 'tio ctx = { get_columns : unit -> int option; guess_printed_width : string -> int; next_key : unit -> key; - write : bytes -> off:int -> len:int -> int; render : render_cmd -> unit; enter_raw_mode : unit -> 'tio; exit_raw_mode : 'tio -> unit; } -let make_ctx ~get_columns ~guess_printed_width ~next_key ~write ~enter_raw_mode +let make_ctx ~get_columns ~guess_printed_width ~next_key ~enter_raw_mode ~exit_raw_mode render = { get_columns; guess_printed_width; next_key; render; - write; enter_raw_mode; exit_raw_mode; } @@ -141,10 +139,6 @@ module State = struct let (Ctxt c) = t.ctxt in c.next_key - let write t = - let (Ctxt c) = t.ctxt in - c.write - let get_columns t = let (Ctxt c) = t.ctxt in c.get_columns () @@ -228,11 +222,6 @@ let with_raw_mode (state : State.t) fn = let tio = c.enter_raw_mode () in Fun.protect ~finally:(fun () -> c.exit_raw_mode tio) fn -let write_bytes (state : State.t) s = - let len = Bytes.length s in - let wrote = State.write state s ~off:0 ~len in - assert (Int.equal len wrote) - type edit = Editing of State.t | Finished of bytes option | Ctrl_c let read_char (state : State.t) = @@ -241,12 +230,19 @@ let read_char (state : State.t) = `Some key (* with Unix.Unix_error ((Unix.EWOULDBLOCK | Unix.EAGAIN), _, _) -> `Editing *) +let refresh_line ?prompt (state : State.t) = + let prompt = Option.value ~default:state.prompt prompt in + State.render state ~prompt ~buf:state.buf ~buf_len:state.len + ~cursor_pos:state.pos ~width:state.cols; + state + let edit_start state fn = with_raw_mode state @@ fun () -> let cols = State.get_columns state |> Option.value ~default:80 in (* Bytes.set state.buf 0 '\000'; *) let state = State.override ~cols ~buf_len:(state.buf_len - 1) state in - write_bytes state state.prompt; + (* Get the prompt out. *) + let state = refresh_line state in fn state let utf8_display_width state b len = @@ -268,9 +264,7 @@ let utf8_prev_char_len s off = in loop (off - 1) -type refresh_flag = Rewrite - -let refresh_with_hints ~pwidth ~ab (state : State.t) = +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 @@ -284,59 +278,6 @@ let refresh_with_hints ~pwidth ~ab (state : State.t) = Buffer.add_string ab (Format.flush_str_formatter ()) end -let _refresh_single_line ?(flags = []) ?prompt (state : State.t) = - let prompt = match prompt with None -> state.prompt | Some p -> p in - let pwidth = utf8_display_width state prompt state.plen in - let poscol = ref @@ utf8_display_width state state.buf state.pos in - let lencol = ref @@ utf8_display_width state state.buf state.len in - - let rec loop (state : State.t) = - if pwidth + !poscol >= state.cols then begin - let clen = utf8_next_char_len state.buf 0 in - let c_width = - Uchar.utf_8_byte_length - (Bytes.get_utf_8_uchar state.buf clen |> Uchar.utf_decode_uchar) - in - poscol := !poscol - c_width; - lencol := !lencol - c_width; - let state = - State.override ~len:(state.len - clen) ~pos:(state.pos - clen) state - in - loop state - end - else state - in - let state = loop state in - let ab = Buffer.create 0 in - (* Clear line *) - Buffer.add_char ab '\r'; - - (* Add prompt *) - if List.mem Rewrite flags then begin - Buffer.add_bytes ab prompt; - Buffer.add_bytes ab (Bytes.sub state.buf 0 state.len) - end; - - refresh_with_hints ~pwidth:state.len ~ab state; - - (* Erase to the right *) - Buffer.add_string ab "\x1b[0K"; - - (* Cursor to the original position *) - if List.mem Rewrite flags then begin - Buffer.add_string ab (Format.sprintf "\r\x1b[%dC" (!poscol + pwidth)) - end; - write_bytes state (Buffer.to_bytes ab); - state - -(* let refresh_line state = refresh_single_line ~flags:[ Rewrite ] state *) -(**) -let refresh_line ?prompt (state : State.t) = - let prompt = Option.value ~default:state.prompt prompt in - State.render state ~prompt ~buf:state.buf ~buf_len:state.len - ~cursor_pos:state.pos ~width:state.cols; - state - 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/bruit.mli b/src/bruit.mli index d9bede7..3944aaa 100644 --- a/src/bruit.mli +++ b/src/bruit.mli @@ -59,7 +59,6 @@ val make_ctx : get_columns:(unit -> int option) -> guess_printed_width:(string -> int) -> next_key:(unit -> key) -> - write:(bytes -> off:int -> len:int -> int) -> enter_raw_mode:(unit -> 'tio) -> exit_raw_mode:('tio -> unit) -> (render_cmd -> unit) -> diff --git a/src/unix/bruit_unix.ml b/src/unix/bruit_unix.ml index e25ba0e..67bdfbb 100644 --- a/src/unix/bruit_unix.ml +++ b/src/unix/bruit_unix.ml @@ -86,9 +86,8 @@ let render ofd = function let stdctx ?(stdin = Unix.stdin) ?(stdout = Unix.stdout) () = let read () = read stdin in let next_key () = Bruit.key read in - let write = write stdout in let enter_raw_mode = enter_raw_mode stdin in let exit_raw_mode = exit_raw_mode stdin in - Bruit.make_ctx ~next_key ~write ~enter_raw_mode ~exit_raw_mode + 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)