一次滚动整个多行命令的 Readline 类型包装器

问题描述

我正在使用增强型 kotlin REPL 并输入了多行代码片段:

$rlwrap bin/ki.sh
ki-shell 0.3/1.4.21
type :h for help
[0] fun reformat(
    str: String,normalizeCase: Boolean = true,upperCaseFirstLetter: Boolean = true,divideByCamelHumps: Boolean = false,wordSeparator: Char = ' ',)
 {
  println("In reformat")
}

如果您细心观察,您可能已经注意到 kotlin shell 已经用 rlwrap “包裹”了。我曾希望这将提供一个单一的击键来滚动通过该多行命令。但是,如下面的屏幕截图所示,向上箭头键(以及同样的 shift- 或 option- 或 command- 或 control- 向上箭头)一次只能向上移动一行

enter image description here

那么,是否有类似 REPL 的实用程序的此类包装器可以启用多行滚动?

请注意,scala REPL 在某些情况下确实像 ipython 一样具有多行滚动功能(在我的情况下仅在 iTerm 下,但在 Terminal 下没有)。

我在 macOS Catalina,但希望答案同样适用于大多数 *NIX 变体。

解决方法

来自 rlwrap 手册:

-m,--multi-line [newline_substitute]
  Enable  multi-line input using a "newline substitute" character
  sequence (" \ ",[space-backslash-space] by default). Newline sub‐
  stitutes are translated to newlines before sending the input to 
  command.  With this option,you can call an external  editor  
  $RLWRAP_EDITOR  on  the  (expanded)  current  input  with the    
  rlwrap_call_editor key (CTRL-^ by default)

使用 rlwrap -m 时,按 CTRL+^ 会将您带入编辑器,您可以在其中编辑多行代码段。退出编辑器后,代码段将被发送到 rlwrapped 命令,并作为 one 单行放入 rlwrap 历史记录(换行符由“换行符替换") 使用 浏览历史记录仍会将这些片段显示为 一行,但您可以随时展开它们再次按 CTRL+^ 进入编辑器中的多行文本

不是正是您正在寻找的内容,但它确实一次滚动整个多行命令,我比例如更喜欢它ipython 您仍然(至少使用我使用的终端)必须按 几次才能移过大型函数定义。

当然,与任何 readline 包装器一样,也有缺点:您将 lose 您的 CLI 可能具有的任何上下文相关的完成,甚至微不足道的 rlwrap 完成机制在多行编辑器。

设置:

它应该“开箱即用”,只需发布​​

$ rlwrap -m -a <my_cli_command> # -a because your cli probably 
                                # does some line editing already

一些调整:

  • 如果您喜欢不同的编辑器,请添加一行
    export RLWRAP_EDITOR='<my_editor_of_choice>[-opts] 在您的 .bashrc 中。默认值为 vi +%L%F 中的 %L%CRLWRAP_EDITOR 将分别替换为文件名、行和列,以便将您放入光标所在位置的编辑器中在rlwrap
  • 要使用不同的编辑热键,请在 "\C-b":rlwrap-call-editor 中添加类似 ~/.inputrc 的行(CTRL+^ 是默认值)
  • 要使用不同的“换行符替换”(例如“||”),请向 -m 添加一个参数,如 rlwrap -m'||'(默认为 ' \ '
  • 如果您的 editor_of_choice 根据文件扩展名进行语法着色,请添加参数 -M.ext(默认:无扩展名)

例如:

export RLWRAP_EDITOR='my_edit --auto-save-on-exit %F:%L'
# ... or put the above in .bashrc
rlwrap -a -m': ' -M_bas QLSuperBasic # ... those were the days