Completion

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

交互式

补全提示是通过 functioninterface 风格的方法计算的,这些方法接受 CompletionContext 并返回 CompletionProposal 实例列表。CompletionContext 提供有关当前上下文的各种信息,例如命令注册和选项。

如果通用解析器对所有命令和场景都有用,可以将其注册为 beans。例如,现有的补全实现 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());
	}
}

使用基于 builder 的命令注册时,可以为每个选项定义选项值。

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 命令 补全 中有文档说明。