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

9

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

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

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

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

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

Например, мне нужно g ls <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
Если ваша функция отображает только короткие имена в подкоманды git, вы также можете использовать для этого систему псевдонимов git. Читайте об этом в карте man git-config.
Лукас

Ответы:

3

Я нашел /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переменную.

Кевин Кокс
источник
1

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

_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

FelipeC
источник
Спасибо, я пошел другим путем, так как не знал, где найти правила завершения Git, и получал ошибки. Смотри мой ответ.
Эрик Номич