Java 多行控制台输入和光标处理

Java Multi-Line Console Input and Cursor Handling

在为编程语言构建 REPL 控制台应用程序时出现以下问题。从本质上讲,该语言依赖于您能够编写多行文本。但是,ENTER 键也应该可用于计算表达式。

> 1 + 1<enter>
int int1 = 2
> <cursor>

为了允许多行输入,我使用了一种算法来计算圆括号、大括号、方括号和引号的数量,因此如果其中任何一个不平衡,它会插入一个换行符:

> if (int1 < 3) {<enter>
|     println "ok"<enter>
|     }<enter>
ok
> <cursor>

这种方法的主要问题是,只要我在一行上按回车键,就无法再编辑该行。在 } 符号处重复按 BACKSPACE 将首先删除它,然后停留在该位置而不删除换行符并允许我删除 println 行。这使得程序非常容易出错并且编辑非常繁琐。

另一个问题是我什至无法在某些控制台(如 Mac 终端)中使用光标。控制台将只显示该事件中的 ANSI 控制代码。


有没有办法解决这两个问题,也许是通过在我的 REPL 前端引入自定义游标处理? JVM 为我提供了多少访问封闭控制台的权限?我可以强制控制台将所有按键重定向到程序吗?而且,我是否必须针对不同的 IDE 控制台/终端/操作系统使用不同的技术?

问题不在于"the JVM",而是JavaRepl 的简单代码。控制台输入(参见 source)只是从标准输入读取

private static Mapper<Sequence<String>, String> readFromConsole() {
    return new Mapper<Sequence<String>, String>() {
        private final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        public String call(Sequence<String> lines) throws Exception {
            return reader.readLine();
        }
    };
}

BufferedReader really does not do a lot. Its documentation is also not helpful. A description on TutorialsPoint 有帮助;

The java.io.BufferedReader.readline() method read a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed.

要按照您的意愿改进 JavaRepl,必须将其修改为(至少)允许将左箭头和键盘删除发送的转义序列与 "backspace"(实际删除)。这是可行的(但可能不是 JavaRepl 的开发人员的意图:与旧版本 Java 的兼容性可能是一个考虑因素)。甚至 Java6 中的 "newer" Console class 也被记录下来,但没有暗示它不仅仅是对 BufferedReader 的适度修改以帮助密码提示。

要阅读转义序列,请参阅

要进行多行编辑,还需要更改其界面以允许检索先前的行并进行编辑。我认为这超出了 JavaRepl 的设计范围(但您可能会向开发人员建议)。