在OCaml自定义toplevel中设置提示符

6
在OCaml自定义toplevel中,有没有一种程序化设置提示符从#更改为其他内容的方法?我想能够根据用户使用我的自定义函数的最后一个响应来更改它(有点像在bash中如何设置PS1)。我甚至找不到更改它的#指令。谢谢!
1个回答

9
在toplevel/toploop.ml文件中:
let prompt =
  if !Clflags.noprompt then ""
  else if !first_line then "# "
  else if Lexer.in_comment () then "* "
  else "  "
in

等等!计算得出的提示被传递给!read_interactive_input,并且该引用被导出:

在toplevel/toploop.mli中:

(* Hooks for external line editor *)

val read_interactive_input : (string -> string -> int -> int * bool) ref

看起来,你只需要更改 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)

所以您可以使用:

# 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 = ()
%%%

1
顺便提一下,这里是它的用途。 - Gaius
2
或者,更短一些且稍微更易于“链式”使用的方式是:Toploop.read_interactive_input := let old = !Toploop.read_interactive_input in fun prompt buffer len -> old "%%%" buffer len ;; - Pascal Cuoq

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接