Comment combiner l'auto-complétion zsh pour les arguments de la fonction wrapper et la command existante

Je travaille surtout dans gvim et de nombreux terminaux. A l'origine, j'ai préféré ouvrir tous mes files dans une seule instance de vim. À cette fin, j'ai utilisé un alias pour ouvrir les files de mes terminaux dans le «server vim» actuel.

alias rv="gvim --remote-silent" 

Mais le fait d'avoir plusieurs files provenant de plusieurs projets ouverts dans une seule instance de vim a un impact sur ma productivité. Je mets donc à niveau mon alias vers une fonction.

 # main function rv() { local args options server options=$(getopt -o hils:t: -l "help,info,list,set:,target:" -- "$@") if [[ $? -ne 0 ]]; then echo "Failed to parse options." return 1 fi # a little magic, necessary when using getopt eval set -- "$options" # go through the options with a case and use shift to analyze one option at a time. while true; do case "$1" in -h|--help) echo "Usage: $0 [-hil] [--help] [--info] [--list]"; echo " $0 {-s | --set} <name> [<file1 file2...>]"; echo " $0 {-t | --target} <name>] <file1 file2...>"; return 0;; -i|--info) gvim_show_info; return 0;; -l|--list) gvim_list_servers; return 0;; -s|--set) gvim_set_server_name ${2:u}; shift 2;; -t|--target) server="$2"; shift 2;; --) shift; break;; esac done if [[ "$#" -eq 0 ]]; then # if no files specified... if [[ -n "$server" ]]; then # throw error if --target option was specified. echo "Error! --target requires one or more filenames." return 1; fi else # if files were specified... if [[ -n "$server" ]]; then # if --target was specified gvim_run_remote $server "$@" else gvim_run_remote $(gvim_get_default_server) "$@" fi fi return 0; } 

Maintenant, cette nouvelle rv a ses propres options. Je peux l'utiliser pour:

  • list des servers vim disponibles (-l –list)
  • définir le server vim par défaut pour le shell actuel (-s –set)
  • affiche le server vim par défaut (-i –info)
  • ouvrir des files dans un server vim spécifique (-t –target)
  • ouvrir les files dans le server vim par défaut: rv files...

Cependant, puisque j'utilise une fonction pour rv au lieu d'un alias, je perds l'achèvement de zsh que j'ai déjà apprécié. J'ai lu sur la création d'une fonction de complétion, _rv , qui affichera les options de rv , mais je veux combiner mes options de complétion avec les options de complétion vim existantes. Je sais qu'il peut y avoir des conflits avec rv 's et vim 's -s , mais je pense que je peux gérer cela avec élégance avec le séparateur.

TLDR; Alors, comment créer un script de complétion qui combine les options _arguments pour _rv et _vim ? Je préfère réutiliser _vim si possible au lieu de copyr-coller sa list d'arguments dans _rv .

Voici mon _rv . Mis à jour le 06/06/2014 à 16h10

 #compdef rv _rv() { typeset -A opt_args local alternatives alternatives=( 'args:rv options:_rv_options' 'files:file:_vim_files' ) _alternative $alternatives && return 0 return 1 } _rv_options() { local arguments arguments=( '(-i -l -s -t --info --list --set --target)'{-h,--help}'[Print usage info.]' '(-h -l -s -t --help --list --set --target)'{-i,--info}'[Print default vim server. As stored in $GVIM_SERVER.]' '(-i -h -s -t --info --help --set --target)'{-l,--list}'[Print list of existing vim servers.]' '(-i -h -l -t --info --help --list --target)'{-s,--set}'[Set default vim server for the current shell.]:vim servers:_rv_vim_servers' '(-i -h -l -s --info --help --list --set)'{-t,--target}'[Open files in a particular vim server.]:vim servers:_rv_vim_servers' ) _arguments -s -C $arguments && return 0 return 1 } _rv_vim_servers() { local -a servers servers=( ${(f)"$(_call_program servers vim --serverlist 2>/dev/null)"} ) _wanted servers expl server compadd -M 'm:{az}={AZ}' -a servers && return } # invoke the completion command during autoload _rv "$@" 

Comportement actuel

Actuellement, l'achèvement de _rv sera utilisable, mais pas idéal.

  • Quand je tape rv <TAB> , je ne vois pas les options de vim. Seules les options et les paths de file rv sont affichés. _vim est en _vim compléter les paths de files pour moi, alors n'hésitez pas!
  • Quand je tape rv -s <TAB> , je vois la list des servers vim, mais aussi les paths des files sont affichés. Un file n'est pas autorisé à ce stade de la command et ne doit pas apparaître dans la saisie semi-automatique.

Comportement attendu

  • Lorsque je tape rv <TAB> , je m'attends à voir: 1) les options rv, 2) les options vim, 3) la list des paths de files
  • Lorsque je tape rv -s <TAB> , je m'attends à voir: 1) les noms de servers vim (fournis par _rv_vim_servers .
  • Lorsque je tape rv /valid/file/path/<TAB> , je ne vois qu'une list de paths de files. Puisque _vim déjà cette capacité, je préférerais y faire confiance.

J'ai trouvé / usr / share / zsh / fonctions / complétion / Unix / _git qui avait quelques conseils pour les alias comme celui-ci et a fini par définir ces fonctions pour les alias:

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

Ensuite, faites un compdef droit = ​​git. Le système de saisie semi-automatique verra que vous exécutez, par exemple, g ls et utilisez la fonction d'auto-complétion _git-ls.

Comme trouvé ici