哦,我的Sdkman不正确的zsh完成脚本输出



我正在使用oh my zsh,我一直在尝试为sdkman开发一个自定义的完成脚本。

然而,我在尝试将一些命令相互化时遇到了一个小问题。

下面是完成脚本的开头。有三个函数使用_describe方法来输出完成帮助。

#compdef sdk
zstyle ':completion:*:descriptions' format '%B%d%b'
# Gets candidate lists and removes all unecessery things just to get candidate names
__get_candidate_list() {
echo `sdk list | grep --color=never  "$ sdk install" | sed 's/$ sdk install //g' | sed -e 's/[t ]//g;/^$/d'`
}
__get_current_installed_list() {
echo `sdk current | sed "s/Using://g" | sed "s/:.*//g"  | sed -e "s/[t ]//g;/^$/d"`
}
__describe_commands() {
local -a commands
commands=(
'install: install a program'
'uninstall: uninstal an existing program'
)
_describe -t commands "Commands" commands && ret=0
}
__describe_install() {
local -a candidate_list
candidate_list=( $( __get_candidate_list ) )
_describe -t candidate_list "Candidates available" candidate_list && ret=0
}
__describe_uninstall() { # FIXME THis is not working, it only displays candidate list
local -a candidates_to_uninstall
candidates_to_uninstall=( $( __get_current_installed_list ) )
_describe -t candidates_to_uninstall "Uninstallable candidates" candidates_to_uninstall && ret=0
}

__get_candidate_list返回以下值:

ant asciidoctorj bpipe ceylon crash cuba cxf gaiden glide gradle grails groovy groovyserv infrastructor java jbake kotlin kscript lazybones leiningen maven micronaut sbt scala spark springboot sshoogr vertx visualvm

__get_current_installed_list返回以下值:

gradle java kotlin maven sbt scala

下面脚本的第二部分是我们调用一切的地方,以便zsh:正确使用完成脚本

function _sdk() {
local ret=1
local target=$words[2]
_arguments -C 
'1: :->first_arg' 
'2: :->second_arg' 
&& ret=0
case $state in
first_arg)
__describe_commands
;;
second_arg)
case $target in
install)
__describe_install
;;
uninstall)
__describe_uninstall
;;
*)
;;
esac
;;
esac
return $ret
}
_sdk "$@"

问题如下:当我键入sdk install时,我得到了正确的输出,即来自__get_candidate_list方法的输出,但当我使用sdk uninstall时,它仍然会给我来自__get_cardidate_list的输出,尽管我期待着__ get_current_installed_list输出。

编辑:经过一点调试,zsh似乎没有错。我不知道为什么,但sdkman在完成脚本中为我提供了相同的sdk listsdk current(在sed命令之后(输出。在我的shell中,这两个命令都能正常使用shell。

我使用_describe方法的方式有问题吗?还有什么我没看到的吗?

谢谢你的帮助。

所以我终于找到了解决方法,但并不理想。

我选择在启动插件时在后台启动命令,并用结果填充文本文件,这样完成脚本就可以在之后使用这些命令。以下是我在zsh-sdkman.plugin.zsh文件中使用的代码,以防我的github存储库消失:

# --------------------------
# -------- Executed on shell launch for completion help
# --------------------------
# NOTE: Sdkman seems to always output the candidate list rather than the currently installted list when we do this through the completion script
# There are two goals in the code below:
#   - Optimization: the _sdkman_get_candidate_list command can take time, so it is done once and in background
#   - Bug correction: correct the problem with sdkman command output explained above
# WARNING: We are setting this as a local variable because we don't have it yet at the time of initialization
# A better approach would be welcome
SDKMAN_DIR_LOCAL=~/.sdkman
# Custom variables for later
export ZSH_SDKMAN_CANDIDATE_LIST_HOME=~/.zsh-sdkman.candidate-list
export ZSH_SDKMAN_INSTALLED_LIST_HOME=~/.zsh-sdkman.current-installed-list
_sdkman_get_candidate_list() {
(sdk list | grep --color=never  "$ sdk install" | sed 's/$ sdk install //g' | sed -e 's/[t ]//g;/^$/d' > $ZSH_SDKMAN_CANDIDATE_LIST_HOME &)
}
_sdkman_get_current_installed_list() {
(sdk current | sed "s/Using://g" | sed "s/:.*//g"  | sed -e "s/[t ]//g;/^$/d" > $ZSH_SDKMAN_INSTALLED_LIST_HOME &)
}
# "sdk" command is not found if we don't do this
source "$SDKMAN_DIR_LOCAL/bin/sdkman-init.sh"
# Initialize files with available candidate list and currently installted candidates
_sdkman_get_candidate_list "$@"
_sdkman_get_current_installed_list "$@"

有关更多信息,您可以查看我的插件的完整存储库:https://github.com/matthieusb/zsh-sdkman

如果你有另一个更清洁的解决方案,我愿意进行必要的修改,或者毫不犹豫地对该项目提出撤回请求。

最新更新