-
Notifications
You must be signed in to change notification settings - Fork 43
Open
Description
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
Labels
No labels