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
的适度修改以帮助密码提示。
要阅读转义序列,请参阅
- Java framework for reading / writing ANSI escape-sequenced character streams
- Clear the console and control attributes
要进行多行编辑,还需要更改其界面以允许检索先前的行并进行编辑。我认为这超出了 JavaRepl 的设计范围(但您可能会向开发人员建议)。
在为编程语言构建 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
的适度修改以帮助密码提示。
要阅读转义序列,请参阅
- Java framework for reading / writing ANSI escape-sequenced character streams
- Clear the console and control attributes
要进行多行编辑,还需要更改其界面以允许检索先前的行并进行编辑。我认为这超出了 JavaRepl 的设计范围(但您可能会向开发人员建议)。