Skip to content

Add LTerm.flush term when lTerm_read_line accepts user inputs (press Enter). #106

@arbipher

Description

@arbipher

I am working on my repl based on examples/repl.ml. A common scenario is e.g. Interpreter.eval prints something to the stdout.

module Interpreter = struct
  type state = { n : int }

  let eval state s =
    let out = "evaluated " ^ s in
    let new_state = { n = state.n + 1 } in

    Printf.printf "(side effect: \nwrite to stdout)\n";
    flush stdout;
 
    (new_state, out)
end

This will make the LTerm_read_line behave strange (though reasonable). It will write the user input line again and line border if show_box is set true e.g.

$ dune exec examples/repl.exe
In  [1]: 11(side effect: 
write to stdout)───────────────────────────────────────────────────────────────────────────────────────────────────┐
In  [1]: 11
Out [2]: evaluated 11

The original example prints like this when my input is 1 1 (Enter).

$ dune exec examples/repl.exe
In  [1]: 11
Out [2]: evaluated 11

My expected restult is

$ dune exec examples/repl.exe
In  [1]: 11
(side effect: 
write to stdout)
Out [2]: evaluated 11

The problem can be fixed by adding a flush in the main loop of the example

let rec loop term history state =
  Lwt.catch (fun () ->
    let rl = new read_line ~term ~history:(LTerm_history.contents history) ~state in
    rl#run >|= fun command -> Some command)
    (function
      | Sys.Break -> return None
      | exn -> Lwt.fail exn)
  >>= function
  | Some command ->
    (* ADD HERE *)
    (* flush the stdout when it got a user input *)
    LTerm.flush term >>= fun () ->

    let command_utf8= Zed_string.to_utf8 command in
    let state, out = Interpreter.eval state command_utf8 in
    LTerm.fprintls term (make_output state out)
    >>= fun () ->
    LTerm_history.add history command;
    loop term history state
  | None ->
    loop term history state
...

My point to make the issue is I think it may be better to flush the stdout inside src/lterm_read_line.ml when it accepts user input when pressing enter (or ^M). There are LTerm.flush term in the code when handling other cases.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions