Ich arbeite hauptsächlich in gvim und vielen Terminals. Ursprünglich habe ich es vorgezogen, alle meine Dateien in einer einzigen vim-Instanz zu öffnen. Zu diesem Zweck habe ich einen Alias verwendet, um Dateien von meinen Terminals auf dem aktuellen 'vim-Server' zu öffnen.
alias rv="gvim --remote-silent"
Das Öffnen vieler Dateien aus mehreren Projekten in einer einzigen vim-Instanz wirkt sich jedoch auf meine Produktivität aus. Daher aktualisiere ich meinen Alias auf eine Funktion.
# 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;
}
Jetzt hat dieser neue rv
seine eigenen Optionen. Ich kann es verwenden, um:
- Liste der verfügbaren VIM-Server (-l --list)
- Legt den vim-Standardserver für die aktuelle Shell fest (-s --set)
- zeige den vim Standardserver (-i --info)
- Dateien auf einem bestimmten VIM-Server öffnen (-t --target)
- Dateien auf dem vim-Standardserver öffnen:
rv files...
Da ich jedoch eine Funktion für rv
anstelle eines Alias verwende, verliere ich die zsh-Vervollständigung, die ich zuvor genossen habe. Ich habe auf die Schaffung einer Vervollständigungsfunktion, nachlesen _rv
, dass zeigt rv
‚s Optionen, aber ich möchte meinen Abschluss Optionen mit den bestehenden vim Abschluss Optionen kombinieren. Ich weiß , dass es einige Konflikte mit sein rv
‚s -s
und vim
‘ s -s
, aber ich glaube ich , dass elegant mit dem Griff kann --
Separator.
TLDR; Wie erstelle ich ein Abschlussskript, das die _arguments
Optionen für _rv
und kombiniert _vim
? Ich bevorzuge die Wiederverwendung, _vim
wenn möglich, anstatt die Argumente in die Liste einzufügen _rv
.
Hier ist meine _rv
. Aktualisiert 10.06.2014 16:10 Uhr
#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 "$@"
Aktuelles Verhalten
Derzeit ist der _rv
Abschlusswille verwendbar, aber nicht ideal.
- Bei
rv <TAB>
der Eingabe werden die vim-Optionen nicht angezeigt. Es werden nur die rv-Optionen und Dateipfade angezeigt._vim
vervollständigt Dateipfade für mich, also auf Wiedersehen! - Bei
rv -s <TAB>
der Eingabe wird die Liste der VIM-Server angezeigt, aber auch die Dateipfade. Eine Datei ist zu diesem Zeitpunkt im Befehl nicht zulässig und sollte nicht in der Autovervollständigung angezeigt werden.
Erwartetes Verhalten
- Bei der
rv <TAB>
Eingabe erwarte ich Folgendes: 1) rv-Optionen, 2) vim-Optionen, 3) Dateipfadliste - Wenn ich tippe
rv -s <TAB>
, erwarte ich Folgendes: 1) VIM-Servernamen (wie von bereitgestellt)_rv_vim_servers
. - Bei der Eingabe
rv /valid/file/path/<TAB>
erwarte ich nur eine Dateipfadliste. Da_vim
diese Fähigkeit bereits vorhanden ist, würde ich mich lieber darauf verlassen.
quelle
compdef
hat eine-n
Option, die besagt, dass verhindert wird, dass bereits für den Befehl oder den Kontext definierte Vervollständigungen überschrieben werden. Also, hast du es versucht,compdef _vim rv
gefolgt voncompdev -n _rv rv
?_vim
erzeugen, aber vorher die_arguments
Funktion mit einer benutzerdefinierten lokalen Funktion zu überschreiben ? Auf diese Weise würden Sie die Argumente von erhalten_vim
. Vielleicht mit einem separaten zsh-Prozess.Antworten:
Ich fand / usr / share / zsh / functions / Completion / Unix / _git, das einige Tipps für Aliase wie dieses hatte, und definierte schließlich diese Funktionen für die Aliase:
Führen Sie dann eine gerade compdef g = git aus. Das Autocomplete-System erkennt, dass Sie beispielsweise g ls ausführen und die Autocomplete-Funktion _git-ls verwenden.
Wie gefunden Hier
quelle
_git-ls-files
. Diese Frage hat einegit-ls
(um sich an Ihre Konvention zu halten) mit eigenen Optionen, und einige dieser Optionen überschneiden sich mitgit-ls-files
. Anstatt Autovervollständigen für alle Optionen von zugit-ls
schreiben, wie schreibe ich ein Autovervollständigen, das das Autovervollständigen von_git-ls-files
(das etwa 90% abdeckt) nimmt und es mit dem Autovervollständigen der verbleibenden (etwa 10%) Optionen kombiniert?