JShell 除了支持覆写定义以外,还支持编辑功能,可以在 JShell 提示符下编辑输入,也可以使用所选择的外部编辑器中编辑输入。
通过 JShell 编辑功能,我们可以在输入时编辑代码片段和命令,以及检索和更改以前输入的片段和命令。而外部编辑器,则提供了另一种编辑和创建代码段的方法,一般用于编辑多行代码段。
本章节,我们主要讲讲如何在 JShell 提示符下编辑输入。
JShell 编辑
在命令提示符下编辑输入可以轻松更正输入并检索和修改以前输入的命令和片段。
JShell 中的 Shell 编辑是基于 JLine2 构建的。它在功能上类似于 Emacs 模式下的 BSD editline 和 GNU readline 。
输入行导航
JShell 支持编辑当前行,或通过以前的会话访问历史记录。这个功能是通过输入行导航实现的。
输入行导航,是通过 Ctrl + Meta
组合键实现的,如果你正在使用的键盘没有 Meta
键,那么也可以使用Alt
代替。
对于一行内的基本导航,可以使用向右箭头键 ->
和向左箭头键 <-
或向后按 Ctrl + B
,向前按 Ctrl + F
。
如果要在历史记录中的行之间进行导航,则可以使用向上和向下箭头键。当我们按下向上箭头时,会使用前一个命令或代码片段替换当前行。再次按下向上键则可以定位到更早的行,以此类推。历史记录包含命令和代码段行。如果代码段有多行,则向上和向下箭头会浏览代码段的每一行。
下表列出了导航功能可以使用的键和导航输入行所采取的操作。
按键 | 动作 |
---|---|
Return 回车键 | 进入当前行 |
Left arrow 向左箭头键 | 向左移动一个字符 |
Right arrow 向右箭头键 | 向右移动一个字符 |
Up arrow 向上箭头键 | 向上移动一行,也就是向后移动历史 |
Down arrow 向下箭头键 | 向下移动一行,也就是向前移动历史 |
Ctrl+A 组合键 | 移动到当前行的开头 |
Ctrl+E 组合键 | 移动到当前行的结尾 |
Meta+B 组合键 | 向后移动一个单词,也就是向左移动一个单词 |
Meta+F 组合键 | 向前移动一个单词,也就是向右移动一个单词 |
输入历史导航
JShell 会话中保留了所有输入过的代码片段和命令的历史记录。通过此历史记录,我们可以访问在当前和以前会话中输入的代码。
如果要重新输入或编辑先前的输入,可以使用向上,向下,向左和向右箭头来导航历史记录。通过这些键,之前输入的文本将插入当前行的光标处。
此外,还可以使用 Delete
键删除文本。Enter
键重新输入历史记录行,是否已修改。
向上和向下箭头键一次向前和向后移动历史记录,例如,我们先输入一个类,然后使用 /list
命令查看输入历史
jshell> class C { ...> int x; ...> } | 已创建 类 C jshell> /list 1 : class C { int x; }
当我们按下向上箭头键是,则会将上一次的输入,也就是 /list
命令显示到当前行中
jshell> <up arrow> jshell> /list
如果我们再次按下向上箭头键,则会把上上一次输入的 {
显示到当前行中
jshell> }
这时候如果我们按下向下箭头键,则又会回到 /list
命令,我们可以通过按下回车键 enter
来运行当前行
jshell> /list 1 : class C { int x; } jshell>
不知道你是否留意到,向上箭头键一次只会向上翻滚一行,对于多行输入,比如我们刚刚定义的类 C
则无能为力了,这时候我们可以使用 CTRL + 向上箭头键
的组合键来向上翻滚。对于单行代码片段,Ctrl +向上箭头
的行为与向上箭头相同。对于多行代码段,例如 C
类,Ctrl +向上箭头
会跳过其它行并转到代码段的顶部。
输入行修改
从历史记录中检索的输入行可以根据需要进行修改并重新运行,这样我们就不必重新键入一行就可以进行小范围的更改。
可以在光标处输入任意代码,还可以使用 输入行导航 中提到的快捷栏来移动光标。
而同时,JShell 还提供了很多快捷键方便我们修改
按键 | 动作 |
---|---|
Delete 删除键 | 删除当前光标所在的字符或之后的字符,具体取决于操作系统 |
Backspace 后退键 | 删除当前光标之前的字符 |
Ctrl+K | 删除当前行光标之后的所有字符 |
Meta+D | 删除当前光标之后的第一个词 |
Ctrl+W | 删除当前光标之前的第一个词 |
Ctrl+Y | 恢复上一次删除的文本 |
Meta+Y | 在 Ctrl+Y 之后,使用 Meta+Y 可以一直恢复之前的删除 |
查找和更多
JShell 提供了另一项非常重要的功能,就是搜索历史记录。
有了搜索历史记录,可以更轻松地找到所需的行,就不用使用 /list
命令肉眼全文查找了。
要使用 JShell 提供的历史记录搜索功能,首先要按下组合键 Ctrl-R
,然后在提示符下,输入搜索字符串。
jshell> <Ctrl+R> (reverse-i-search)`':
因为我们之前有定义一个类 C
,就是下面这个
jshell> class C { ...> int x; ...> } | 已创建 类 C
所以我们可以直接输入 class C
来进行搜索,它会显示最近的包含 class C
的输入
(reverse-i-search)`class': class C {
想必你也看到了,在进行输入的时候,反引号内的是输入的字符,而冒号之后的则是找到的匹配的输入
JShell 中的搜索功能是增量搜索,我们还可以仅使用字符 c
展开搜索,如果第一行不满足要求,我们可以重复使用 CTRL+C
在历史记录中搜索,而可以使用 CTRL+S
则可以将搜索向前移动到当前最新的输入。
也就是可以重复使用 CTRL+C
往后移动,而使用 CTRL+S
往前移动。
JShell 还允许我们定义键盘宏 ( macro ),可以通过先按下组合键 Ctrl-x (
,然后输入文本,最后再次按下组合键 Ctrl-x )
来定义键盘宏。
注意:是小括号,而不是字母
c
。
而键盘宏的使用,则是按下组合键 Ctrl + x e
。
同样的,JShell 也为搜索和键盘宏定义了很多快捷键
按键 | 动作 |
---|---|
Ctrl+R | 向后搜索历史记录 |
CTRL+S | 向前搜索历史记录 |
Ctrl+X ( | 开始一个宏定义 |
Ctrl+X ) | 结束一个宏定义 |
Ctrl+X e | 运行一个宏 |