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_candidate_list, хотя я ожидаю вывод __get_current_installed_list.
РЕДАКТИРОВАТЬ: После небольшой отладки кажется, что здесь не виноват zsh. Я не могу понять, почему, но SDKMAN дает мне одинаковый вывод с обоими sdk list
а также sdk current
(После команд sed) из скрипта завершения. В моей оболочке обе команды корректно работают с оболочкой.
Что-то не так с тем, как я использую метод _describe? Что-нибудь еще я не вижу?
Спасибо за вашу помощь.
0 ответов
Поэтому я наконец нашел способ обойти это, но он не идеален.
Я решил запускать команды в фоновом режиме при запуске плагина и заполнять текстовые файлы результатами, чтобы скрипты завершения могли использовать их после. Ниже приведен код, который я использовал в файле 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
Если у вас есть другое более чистое решение, я буду готов внести необходимые изменения, или не стесняйтесь сделать предварительную заявку на проект.