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 命令 補全 中有文件說明。