在OCaml自定义顶层中设置提示

Gai*_*ius 6 ocaml

在OCaml自定义顶层中,有没有办法以编程方式将提示设置#为其他内容?我希望能够更改它以响应用户的最后一个自定义函数(有点像bash你可以设置PS1).我甚至找不到#directive来改变它.谢谢!

Pas*_*uoq 9

在toplevel/toploop.ml中:

let prompt =
  if !Clflags.noprompt then ""
  else if !first_line then "# "
  else if Lexer.in_comment () then "* "
  else "  "
in
Run Code Online (Sandbox Code Playgroud)

可是等等!传递计算的提示!read_interactive_input,并导出此引用:

在toplevel/toploop.mli中:

(* Hooks for external line editor *)

val read_interactive_input : (string -> string -> int -> int * bool) ref
Run Code Online (Sandbox Code Playgroud)

所以你似乎要做的就是将Toploop.read_interactive_input默认值更改为忽略传递提示的函数,然后打印出你想要的那个.

默认值为read_interactive_input:

let read_input_default prompt buffer len =
  output_string Pervasives.stdout prompt; flush Pervasives.stdout;
  let i = ref 0 in
  try
    while true do
      if !i >= len then raise Exit;
      let c = input_char Pervasives.stdin in
      buffer.[!i] <- c;
      incr i;
      if c = '\n' then raise Exit;
    done;
    (!i, false)
  with
  | End_of_file ->
      (!i, true)
  | Exit ->
      (!i, false)
Run Code Online (Sandbox Code Playgroud)

所以你可以使用:

# let my_read_input prompt buffer len =
  output_string Pervasives.stdout  "%%%" ; flush Pervasives.stdout;
  let i = ref 0 in
  try
    while true do
      if !i >= len then raise Exit;
      let c = input_char Pervasives.stdin in
      buffer.[!i] <- c;
      incr i;
      if c = '\n' then raise Exit;
    done;
    (!i, false)
  with
  | End_of_file ->
      (!i, true)
  | Exit ->
      (!i, false)
                                  ;;
val my_read_input : 'a -> string -> int -> int * bool = <fun>
# Toploop.read_interactive_input := my_read_input ;;
- : unit = ()
%%%
Run Code Online (Sandbox Code Playgroud)

  • 或者,更短和更"可链接":`Toploop.read_interactive_input:= let old =!Toploop.read_interactive_input在fun提示缓冲区len - > old"%%%"缓冲区len ;; (2认同)