Je travaille principalement dans GVIM et de nombreux terminaux. À l'origine, je préférais ouvrir tous mes fichiers dans une seule instance de vim. À cette fin, j'ai utilisé un alias pour ouvrir les fichiers de mes terminaux dans le «serveur vim» actuel.
alias rv="gvim --remote-silent"
Toutefois, le fait que plusieurs fichiers de plusieurs projets soient ouverts dans une seule instance de vim a une incidence sur ma productivité. Je suis donc en train de mettre à 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:
- liste les serveurs vim disponibles (-l --list)
- définir le serveur vim par défaut pour le shell actuel (-s --set)
- affiche le serveur vim par défaut (-i --info)
- ouvrir des fichiers sur un serveur vim spécifique (-t --target)
- ouvrir les fichiers sur le serveur vim par défaut:
rv files...
Cependant, étant donné que j'utilise une fonction au rv
lieu d'un alias, je perds la finalisation de zsh dont je jouissais auparavant. J'ai lu des informations sur la création d'une fonction d'achèvement _rv
, qui affichera rv
les options, mais je souhaite combiner mes options d'achèvement avec les options d'achèvement vim existantes. Je sais qu'il peut y avoir des conflits avec rv
' -s
et vim
' -s
, mais je suppose que je peux gérer cela avec élégance avec le --
séparateur.
TLDR; Alors, comment puis-je créer un script d'achèvement qui combine les _arguments
options pour _rv
et _vim
? Je préfère réutiliser _vim
si possible au lieu de copier-coller sa liste d'arguments dans _rv
.
Voici mon _rv
. Mis à jour le 2014/6/10 16:10
#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:{a-z}={A-Z}' -a servers && return
}
# invoke the completion command during autoload
_rv "$@"
Comportement actuel
Actuellement, le _rv
testament est utilisable, mais pas idéal.
- Lorsque je tape
rv <TAB>
, je ne vois pas les options de vim. Seules les options rv et les chemins de fichiers sont affichés._vim
complète les chemins de fichiers pour moi, alors allez-y! - Lorsque je tape
rv -s <TAB>
, je vois la liste des serveurs vim, mais les chemins de fichiers sont également affichés. Un fichier n'est pas autorisé à ce stade de la commande 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 liste des chemins de fichiers - Lorsque je tape
rv -s <TAB>
, j’attends de voir: 1) les noms de serveurs vim (tels que fournis par_rv_vim_servers
. - Lorsque je tape
rv /valid/file/path/<TAB>
, je m'attends à ne voir qu'une liste de chemins de fichiers. Étant donné que_vim
cette capacité existe déjà, je préférerais compter sur elle.
la source
compdef
a une-n
option qui dit "empêche les remplacements déjà définis pour la commande ou le contexte d'être écrasés". Alors, avez-vous essayécompdef _vim rv
suivi decompdev -n _rv rv
?_vim
fichier d' origine , mais avant cela, écrasez la_arguments
fonction par une fonction locale personnalisée? Ce faisant, vous obtiendrez les arguments de_vim
. Peut-être avec un processus zsh séparé.Réponses:
J'ai trouvé / usr / share / zsh / functions / Completion / Unix / _git qui contient quelques astuces pour des alias comme celui-ci et a fini par définir ces fonctions pour les alias:
Ensuite, faites une compdef droite g = git. Le système autocomplete verra que vous exécutez, par exemple, g ls et utilisera la fonction _git-ls autocomplete.
Comme trouvé ici
la source
_git-ls-files
. Cette question agit-ls
(pour rester avec votre convention) avec ses propres options, et certaines de ces options se chevauchentgit-ls-files
. Au lieu d'écrire autocomplete pour toutes les options degit-ls
, comment puis-je écrire une autocomplète qui prend l'auto-complétion_git-ls-files
(qui couvre par exemple 90%) et les combine avec la complétion automatique des options restantes (disons 10%)?