Sdkman Неверный вывод скрипта завершения zsh - PullRequest
0 голосов
/ 19 ноября 2018

Я использую 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 ? Что-то еще я не вижу?

Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 18 декабря 2018

Итак, я наконец нашел способ обойти это, но это не идеально.

Я решил запускать команды в фоновом режиме при запуске плагина и заполнять текстовые файлы результатами, чтобы скрипты завершенияможете использовать их после.Ниже приведен код, который я использовал в файле 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

Если у вас есть другое более чистое решение, я буду готов внести необходимые изменения, или не стесняйтесь сделать запрос на извлечение проекта.

...