
Bei Verwendung von Bash mit festgelegten Emacs-Tastenkombinationen transponiert die Tastenkombination „transpose-words“ ( M-t
) keine Argumente, sondern „Wörter“ (gemäß ihrer eigenen Definition von Wörtern).
Wenn ich also Folgendes habe:
vimdiff project-number-One/Vagrantfile project-number-Two/Vagrantfile.old
und mein Cursor steht zwischen dem ersten und zweiten Argument, wenn ich eingebe optiont, erhalte ich stattdessen
vimdiff project-number-One/project Vagrantfile-number-Two/Vagrantfile.old
was offensichtlich nicht das ist, was ich will. Wie kann ich Argumente transponieren?
Antwort1
In Bash haben verschiedene Befehle unterschiedliche Wortbedeutungen.C-w
beendet das vorherige Leerzeichen, aber die meisten anderen Befehle M-t
verwenden durch Satzzeichen getrennte Wörter.
Wenn der Cursor zwischen dem ersten und zweiten Argument steht, C-w C-e SPC C-y
werden die beiden Wörter vertauscht.
Wenn Sie eine Taste an die Transposition von durch Leerzeichen getrennten Wörtern binden möchten, ist es komplizierter. Sieheverwirrendes Verhalten von Emacs-artigen Tastenkombinationen in Bash. Hier ist etwas minimal getesteter Code.
transpose_whitespace_words () {
local prefix=${READLINE_LINE:0:$READLINE_POINT} suffix=${READLINE_LINE:$READLINE_POINT}
if [[ $suffix =~ ^[^[:space:]] ]] && [[ $prefix =~ [^[:space:]]+$ ]]; then
prefix=${prefix%${BASH_REMATCH[0]}}
suffix=${BASH_REMATCH[0]}${suffix}
fi
if [[ $suffix =~ ^[[:space:]]+ ]]; then
prefix=${prefix}${BASH_REMATCH[0]}
suffix=${suffix#${BASH_REMATCH[0]}}
fi
if [[ $prefix =~ ([^[:space:]]+)([[:space:]]+)$ ]]; then
local word1=${BASH_REMATCH[1]} space=${BASH_REMATCH[2]}
prefix=${prefix%${BASH_REMATCH[0]}}
if [[ $suffix =~ [^[:space:]]+ ]]; then
suffix=${suffix#${BASH_REMATCH[0]}}
READLINE_LINE=${prefix}${BASH_REMATCH[0]}$space$word1$suffix
READLINE_POINT=$((${#READLINE_LINE} - ${#suffix}))
fi
fi
}
bind -x '"\e\C-t": transpose_whitespace_words'
In zsh ist das alles einfacher …
Antwort2
Wenn sich Ihr Cursor dort befindet:
vimdiff projectOne/Vagrantfile projectTwo/Vagrantfile
^
Drücken Sie Alt + BTTBBTFTBBTT
Oder einfach:
Drücken Sie Ctrl+ W, Ctrl+ E, fügen Sie ein Leerzeichen ein und drücken Sie Ctrl+Y
Antwort3
Für eine schnelle und einfache Lösung fügen Sie Folgendes zu Ihrer inputrc hinzu (wählen Sie selbst geeignete Schlüssel aus):
"\e\C-b": shell-backward-kill-word
"\eh": shell-backward-word
"\e\C-f": shell-forward-word
# Swap the preceding two arguments (control + alt + t)
"\e\C-t": "\e\C-b\eh\C-y"
# Swap the preceding argument with the next (control + alt + p)
"\e\C-p": "\e\C-b\e\C-f\C-y"
Bei shell-*
Versionen dieser FunktionenWörter werden durch Shell-Metazeichen ohne Anführungszeichen abgegrenzt.
Ein Zeichen, das, wenn es nicht in Anführungszeichen gesetzt ist, Wörter trennt. Ein Metazeichen ist ein Leerzeichen, ein Tabulator, ein Zeilenumbruch oder eines der folgenden Zeichen: „|“, „&“, „;“, „(“, „)“, „<“ oder „>“.
Hinweis: Der Cursor muss sich vor dem Drücken von Ctrl+ Alt+ hinter dem zweiten Argument befinden t, sodass das Argument vor dem Cursor effektiv an den Zeilenanfang verschoben wird.
$ true foo/bar.xyz even/without\ quotes.ok "too/too far.away"
^
$ true foo/bar.xyz "too/too far.away" even/without\ quotes.ok
^
$ true "too/too far.away" foo/bar.xyz even/without\ quotes.ok
^
Hinweis: Der Cursor muss sich vor dem Drücken von Ctrl+ Alt+ hinter dem ersten Argument befinden p, damit das Argument vor dem Cursor effektiv an das Zeilenende gezogen wird.
$ true "too/too far.away" foo/bar.xyz even/without\ quotes.ok
^
$ true foo/bar.xyz "too/too far.away" even/without\ quotes.ok
^
$ true foo/bar.xyz even/without\ quotes.ok "too/too far.away"
^
Antwort4
Sie müssen BTTBBT
anstelle einer einzelnen Taste drücken T
.