如果我们对 JShell 预定义的模式不太满意,也可以自己自定义一个。我们可以自定义要显示的提示信息和自定义代码片段运行的结果反馈。
我们先来看看一个反馈模式到底包含哪些东西 ?
- 提示: 常规或者继续
- 截断: 到达最大显示显示字符
- 格式: 对要显示的结果进行格式化
定义自定义的反馈模式最简单的方法就是创建现有的预定义模式的副本。例如下面的语句创建了 normal
模式的副本 mine
jshell> /set mode mine normal -command | 已创建新的反馈模式: mine
从反馈提示中可以看出,我们定义了一个新模式 mine
,这个模式是 normal
模式的副本。 -command
选项表示预定义模式需要命令反馈。
如果你不希望命令描述发生的操作,可以使用 -quiet
代替 -command
设置提示
与所有的其它 /set
命令一样, /set prompt
命令可以显示当前模式下的的提示方式
jshell> /set prompt normal | /set prompt normal "\njshell> " " ...> " jshell>
在前面的示例提供的反馈中,第一个字符串是常规提示,第二个字符串是在代码段扩展到多行时使用的延续提示。
下面的示例演示了如何切换到新模式并使用。
jshell> /set prompt mine "\nmy mode: " ".......: " jshell> /set feedback mine | 反馈模式: mine my mode: class C { .......: int x; .......: } | 已创建 类 C my mode:
提示字符串可以使用 %s
,并会在实际显示时替换为下一个代码段 ID。但是,如果输入命令或代码段导致错误,则可能不会为用户在提示符处输入的值分配该 ID。
所有的设置只会在当前会话范围内有效,且不会被 /reset
命令重置,如果你希望将设置作为将来会话的默认设置,那么就要使用 -retain
选项保存它们
my mode: /set mode mine -retain my mode: /set feedback mine -retain | 反馈模式: mine my mode: /exit | 再见 [yufei@www.twle.cn ~]$ jshell | 欢迎使用 JShell -- 版本 10.0.2 | 要大致了解该版本, 请键入: /help intro my mode:
设置截断
如果要显示的内容太长,那么会在显示时自动截断。我们可以使用 /set truncation
命令设置显示内容的最大字符。
如果我们没有为 /set/ truncation
命令传递任何设置,则会显示当前模式的可显示的最大字符。
下面的示例显示了从正常模式继承的设置
my mode: /set truncation mine | /set truncation mine 80 | /set truncation mine 1000 expression,varvalue my mode: String big = IntStream.range(0,1200).mapToObj(n -> "" + (char) ('a' + n % 26)).collect(Collectors.joining()) big ==> "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuv ... fghijklmnopqrstuvwxyzabcd" my mode:
截断设置生效的条件由截断长度后输入的可选选择器确定。JShell 预定义了两种类型的选择器( 在线帮助中称为选择器类型 ):
- 一个
case
选择器指示其值显示的片段类型 - 一个
action
选择器描述了代码段发生的情况
有关这两种选择器的详细信息,可以使用 /help /set truncation
命令获取。
在上一个示例中,显示的设置意味着提示会被截断为 80 个字符,除非该值是表达式( expression
case 选择器 )的值或变量的值,如通过仅输入变量名称( varvalue 情况 )明确请求的那样的选择器。
此外,输入的顺序也很重要,只会显示最后一个输入的运行结果。如果顺序被颠倒,那么所有提示都将被截断为 80 个字符。
my mode: /set truncation mine 100 my mode: /set truncation mine 300 varvalue my mode: big + big $2 ==> "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi ... yzabcdefghijklmnopqrstuvwxyzabcd" my mode: big big ==> "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl ... jklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd" my mode: /set mode mine -retain my mode:
为了保留刚刚的设置,需要使用 /set mode mine -retain
命令,就像示例结尾所示。
设置显示格式
代码片段的输出是我们可以自定义的另一个设置。在从 normal
模式继承的格式中,import
并不会提供任何反馈,并且不显示值的类型。
my mode: import java.beans.* my mode: Locale.CANADA.getUnicodeLocaleAttributes() $5 ==> [] my mode:
我们可以使用 /set format
命令改变这种默认的代码片段输出的格式。我们可以使用 /set format
命令并传递想要查看的反馈模式,就可以显示指定格式的 显示格式
my mode: /set format mine | /set format mine action "已创建" added-primary | /set format mine action "已修改" modified-primary | /set format mine action "已替换" replaced-primary | /set format mine action "已覆盖" overwrote-primary | /set format mine action "已删除" dropped-primary | /set format mine action " 更新已创建" added-update | /set format mine action " 更新已修改" modified-update | /set format mine action " 更新已替换" replaced-update | /set format mine action " 更新已覆盖" overwrote-update | /set format mine action " 更新已删除" dropped-update | /set format mine display "{result}{pre}已创建暂存变量 {name} : {type}{post}" expression-added,modified,replaced-primary | /set format mine display "{result}{pre}{name} 的值: {type}{post}" varvalue-added,modified,replaced-primary | /set format mine display "{result}{pre}已分配给 {name} : {type}{post}" assignment-primary | /set format mine display "{result}{pre}{action} 变量 {name} : {type}{resolve}{post}" vardecl,varinit | /set format mine display "{pre}{action} 变量 {name}{resolve}{post}" vardecl,varinit-notdefined | /set format mine display "{pre}{action} 变量 {name}{post}" vardecl,varinit,expression-dropped | /set format mine display "{pre}{action} {typeKind} {name}{resolve}{post}" class,interface,enum,annotation | /set format mine display "{pre}{action} 方法 {name}({type}){resolve}{post}" method | /set format mine display "{pre}已尝试使用 {typeKind} {name}{resolve}{post}" class,interface,enum,annotation-used | /set format mine display "{pre}已尝试调用方法 {name}({type}){resolve}{post}" method-used | /set format mine display "" added,modified,replaced,overwrote,dropped-update | /set format mine display "{pre}{action} 变量 {name}, 重置为空值{post}" vardecl,varinit-replaced-update-ok | /set format mine display "{result}" vardecl,varinit,expression,varvalue,assignment-added,modified,replaced-primary-ok | /set format mine err "%6$s" | /set format mine errorline "{post}{pre} {err}" | /set format mine errorpost "%n" | /set format mine errorpre "| " | /set format mine errors "%5$s" | /set format mine name "%1$s" | /set format mine post "%n" | /set format mine pre "| " | /set format mine resolve "{until}{unrerr}" added,modified,replaced,used-defined,notdefined | /set format mine result "{name} ==> {value}{post}" added,modified,replaced-primary-ok | /set format mine type "%2$s" | /set format mine typeKind "类" class | /set format mine typeKind "接口" interface | /set format mine typeKind "枚举" enum | /set format mine typeKind "注释接口" annotation | /set format mine unrerr "{unresolved} 已声明" unresolved1-error0 | /set format mine unrerr "{unresolved} 已声明" unresolved2-error0 | /set format mine unrerr " 此错误已更正: {errors}" unresolved0-error1 | /set format mine unrerr "{unresolved} 已声明, 并且此错误已更正: {errors}" unresolved1-error1 | /set format mine unrerr "{unresolved} 已声明, 并且此错误已更正: {errors}" unresolved2-error1 | /set format mine unrerr " 这些错误已更正: {errors}" unresolved0-error2 | /set format mine unrerr "{unresolved} 已声明并且这些错误已更正: {errors}" unresolved1-error2 | /set format mine unrerr "{unresolved} 已声明并且这些错误已更正: {errors}" unresolved2-error2 | /set format mine unresolved "%4$s" | /set format mine until ", 不过, 它无法实例化或者其方法无法调用, 直至" class-primary-defined | /set format mine until ", 不过, 其方法无法调用, 直至" interface-primary-defined | /set format mine until ", 不过, 它无法使用, 直至" enum,annotation-primary-defined | /set format mine until ", 不过, 它无法调用, 直至" method-primary-defined | /set format mine until ", 不过, 它无法引用, 直至" primary-notdefined | /set format mine until " 它无法实例化或者其方法无法调用, 直至" class-update-defined | /set format mine until " 其方法无法调用, 直至" interface-update-defined | /set format mine until " 它无法调用, 直至" method-update-defined | /set format mine until " 它无法引用, 直至" update-notdefined | /set format mine value "%3$s" my mode:
如果你想了解 /set format
命令的详细资料,可以输入 /help /set format
命令查看。因为 显示格式 涉及到的配置项太多,因此你也可以使用它们作本节其余部分的参考,其中提到了在定义格式时使用的字段。
主要的运行结果反馈由 display
字段决定,除此之外,还可以定义其它字段,用于帮助定义 display
字段。
silent
模式之外的其它模式都定义了其中几个字段。正如 /help /set format
命令的输出中所示,这些字段是从 normal
中继承而来的。
例如我们可以使用下面的命令重新定义某些显示格式
my mode: /set format mine display "{pre}added import {name}{post}" import-added my mode: /set format mine display "{pre}re-added import {name}{post}" import-modified,replaced
name
字段会被预定义为代码段的名称。下面的示例演示了当前模式下 import
命令的运行反馈
my mode: import java.beans.* | re-added import java.beans.*
上一章节中定义的格式和这个示例中显示的结果,我们可以看到: {pre}
字段和 {post}
字段用于显示每行反馈输出的前缀和后缀字符。为了演示这两个字段,我们在下面的范例中将垂直条前缀更改为空字符串
my mode: /set format mine pre "" my mode: void m() {} 已创建 方法 m() my mode: import java.beans.* re-added import java.beans.* my mode: /set truncation mine /set truncation mine 100 /set truncation mine 300 varvalue my mode:
注意
对前缀字符的更改会影响所有反馈,包括命令反馈
要在显示值时同时显示类型,那么就要更改由预定义模式定义的结果字段
my mode: /set format mine result "{type} {name} = {value}{post}" added,modified,replaced-primary-ok my mode: Locale.CANADA.getUnicodeLocaleAttributes() Set<String> $12 = [] my mode: 2+2 int $13 = 4 my mode: