Как установить правила автодополнения Zsh для второго аргумента (функции) в соответствии с правилами существующей команды?

Как установить правила автодополнения Zsh для второго аргумента (функции) в соответствии с правилами существующей команды?

У меня естьпользовательская функция Zshg:

function g() {
  # Handle arguments [...]
}

В нем я обрабатываю короткие аргументы, которые выполняют команды Git. Например:

g ls # Executes git ls-files ...
g g  # Executes git grep ...

Мне нужно иметь возможность установить правила автодополнения в соответствии с правилами Git для коротких аргументов, но я не уверен, как это сделать.

Например, мне нужно g ls <TAB>дополнить правила с помощью клавиши Tab, git ls-files <TAB>которые дадут мне аргументы для git ls-files:

$ g ls --<TAB>
--abbrev                 -- set minimum SHA1 display-length
--cached                 -- show cached files in output
--deleted                -- show deleted files in output
# Etc...

Это не просто настройка gавтозаполнения, gitпоскольку я сопоставляю свои пользовательские короткие команды с командами Git.

решение1

Я нашел /usr/share/zsh/functions/Completion/Unix/_gitнесколько советов по созданию псевдонимов, подобных этому, и в итоге определил следующие функции для псевдонимов:

_git-ls () {
  # Just return the _git-ls-files autocomplete function
  _git-ls-files
}

Затем я сделал прямой compdef g=git. Система автозаполнения увидит, что вы работаете, например, g lsи воспользуется _git-lsфункцией автозаполнения.

Спасибо пользователю user67060 за то, что он направил меня в правильном направлении.

решение2

Мне пришлось сделать что-то очень похожее, так что это примерно то, что должно решить вашу проблему.

_g () {
    case "${words[2]}" in
      ls) words[1,2]=(git ls-files);;
      g) words[1,2]=(git grep);;
      *) return 1;;
    esac

    _git # Delegate to completion
}
compdef _g g

Следует отметить, что если вы измените количество аргументов, вам придется скорректировать переменную $CURRENT.

решение3

Вот что бы я сделал:

_tg () {
    local _ret=1
    local cur cword prev

    cur=${words[CURRENT]}
    prev=${words[CURRENT-1]}
    cmd=${words[2]}
    let cword=CURRENT-1

    case "$cmd" in
    ls)
        emulate ksh -c _git_ls_files
        ;;
    g)
        emulate ksh -c _git_grep
        ;;
    esac

    let _ret && _default && _ret=0
    return _ret
}

compdef _tg tg

Однако здесь используется автодополнение Git, а не zsh:

https://git.kernel.org/cgit/git/git.git/tree/contrib/completion/git-completion.zsh

Связанный контент