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.
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 de compdev -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é.