完成

Spring Shell 可以为交互式 Shell 和命令行提供完成建议。但是,两者之间存在差异,因为当 Shell 处于交互模式时,我们有一个活动的 Shell 实例,这意味着更容易提供更多编程方式来提供完成提示。当 Shell 纯粹作为命令行工具运行时,完成只能通过与操作系统级别的 Shell(如 bash)集成来实现。

交互式

完成提示是使用 函数接口 样式方法计算的,这些方法接收 CompletionContext 并返回一个 CompletionProposal 实例列表。CompletionContext 为您提供了有关当前上下文的各种信息,例如命令注册和选项。

如果这些提示对所有命令和场景都有用,则可以将通用解析器注册为 Bean。例如,现有的完成实现 RegistrationOptionsCompletionResolver 处理选项名称的完成。
static class MyValuesCompletionResolver implements CompletionResolver {

	@Override
	public List<CompletionProposal> apply(CompletionContext t) {
		return Arrays.asList("val1", "val2").stream()
			.map(CompletionProposal::new)
			.collect(Collectors.toList());
	}
}

使用基于构建器的命令注册的选项值可以针对每个选项进行定义。

void dump1() {
	CommandRegistration.builder()
		.withOption()
			.longNames("arg1")
			.completion(ctx -> {
				return Arrays.asList("val1", "val2").stream()
					.map(CompletionProposal::new)
					.collect(Collectors.toList());
			})
			.and()
		.build();
}

使用基于注解的命令注册的选项值通过 ValueProvider 接口处理,该接口可以使用 @ShellOption 注解进行定义。

static class MyValuesProvider implements ValueProvider {

	@Override
	public List<CompletionProposal> complete(CompletionContext completionContext) {
		return Arrays.asList("val1", "val2").stream()
			.map(CompletionProposal::new)
			.collect(Collectors.toList());
	}
}

使用基于注解的命令的实际 ValueProvider 需要注册为一个 Bean。

@ShellMethod(value = "complete", key = "complete")
public String complete(
	@ShellOption(valueProvider = MyValuesProvider.class) String arg1)
{
	return "You said " + arg1;
}

命令行

命令行完成目前仅支持 bash,并在内置的 completion 命令中进行了说明 完成