Ordnen Sie im bash vi-Modus jk dem Exit-Modus zu

11

Ich verwende eine Neuinstallation von Ubuntu 16.04 mit der Bash-Shell. Es gibt zwei Dinge, die ich tun möchte:

  1. Richten Sie den vi-Modus so ein, dass ich vom Terminal aus vim-ähnliche Bewegungen ausführen kann
  2. Beenden Sie den Einfügemodus durch Eingabe jk

Ich habe in einem anderen Beitrag gelesen, wie das geht zsh, wie kann ich das machen bash?

tl; dr

setzen bind '"jk":vi-movement-mode'in die .bashrcDatei nach set -o vi:)

server@thinkpad:~$ tail -n 2 .bashrc
set -o vi
bind '"jk":vi-movement-mode'

Eine ausführlichere Erklärung finden Sie in der Antwort von @ gro♀

mbigras
quelle
1
Was meinst du mit Remapping jk? Ist das eine spezielle Taste auf Ihrer Tastatur?
Stephen Harris
Bitte sehen Sie bearbeiten
mbigras
.bashrcWird für Ihre erste Shell normalerweise für jede Shell aufgerufen (z. B. wenn Sie eine Shell verlassen vi), .bash_profilewird jedoch nur für Login-Shells aufgerufen. Also .bashrcist der richtige Ort dafür set -o vi. Ich habe keine Antwort auf Ihre überarbeitete 2. Frage :-(
Stephen Harris
Wie fängst du deine Bash Shell an? Hier ist eine gute Erklärung für den Unterschied zwischen .bashrc und .bash_profile
the_velour_fog
set -o vigeht rein.bashrc , siehe Warum funktioniert mein ~ / .bash_profile nicht?
Gilles 'SO - hör auf böse zu sein'

Antworten:

10

TL; DR

Bash hat eine ähnliche Funktionalität wie zsh's bindkeythrough' bind, aber es gibt nicht mehrere viModi wie zsh. Nachdem set -o viSie tun können:

bind '"jk":vi-movement-mode'

das ist das Äquivalent von zsh'sbindkey -M <all vi modes> jk vi-movement-mode

Die vi-movement-modeFunktionen kommen von inputrc(siehe /etc/inputrcfür eine Liste von ihnen).

Voller Text

Wie Stephen Harris in seinem Kommentar betont:

  • .bashrcwird von bashimmer (und insbesondere nicht von anderen Muscheln) aufgerufen .

  • .bash_profile wird nur bei Login-Shells aufgerufen (und wieder nur bei Bash).

Einige Distributionen haben ein .bash_profileSkelett, das wie folgt aussieht:

# ~/.bash_profile
[[ -f ~/.bashrc ]] && . ~/.bashrc

Welches ist ein guter Inhalt für, .bash_profileda Sie einfach vergessen können, dass es existiert.

Nun zur Karte jkzu Escin der Shell - Sitzung, die nicht wirklich möglich ist. Wenn Sie das tun:

inoremap jk <esc>

In Vim jweiß Vim nach der Eingabe, dass es ein wenig warten muss, um zu sehen, ob Sie als knächstes eingeben, und es sollte die Zuordnung aufrufen (oder dass Sie einen anderen Schlüssel eingeben und die Zuordnung nicht ausgelöst werden sollte). Als Nachtrag wird dies von :set timeoutlen=<miliseconds>in Vim kontrolliert (siehe :h timeoutlen).

Einige Shells oder X11 haben keine solche Zeitüberschreitungssteuerung und erlauben keine Zuordnung mehrerer Zeichen. Es ist nur eine Zuordnung eines einzelnen Schlüssels zulässig (siehe jedoch die folgenden Support-Hinweise).

set -o vi

Liest nicht .vimrc, es ahmt nur einige vi(nicht einmal vim) Tastenkombinationen nach, die in der Shell verwendet werden können. Das gleiche kann gesagt werden -o emacs, es kommt nicht mit der vollen Kraft von emacs.


zsh Unterstützung

zshunterstützt tatsächlich das Karten-Timeout. Und Sie können die folgende verwenden , um Karte jkzu <esc>:

bindkey -v  # instead of set -o vi
bindkey -e jk \\e

(Das muss ~/.zshrcnicht gehen ~/.bashrc)

Ich rate jedoch davon ab. Ich benutze vimund die zshmeiste Zeit. Ich habe inoremap jk <esc>in meinem vimrcund ich habe versucht, die bindkeyobige Kombination zu verwenden. zshwartet zu lange, um zu drucken, jwenn ich es benutze, und das hat mich sehr geärgert.


Bash-Unterstützung

bashunterstützt readline bind. Ich glaube, dass bashdies kompiliert werden kann, ohne readilnedass es einige seltene Systeme gibt, die Bash haben, die nicht unterstützt werden bind(seien Sie wachsam). Zur Karte jkzu <esc>in was bashSie tun müssen:

set -o vi
bind '"jk":"\e"'

(Ja, das ist eine doppelte Zitierstufe, es wird benötigt)

Auch dies macht das Tippen jziemlich nervig. Aber irgendwie weniger nervig als die zshLösung auf meinem Computer (wahrscheinlich ist das Standard-Timeout kürzer).


Problemumgehung (für Nicht-Bash- und Nicht-Zsh-Shells)

Der Grund für die Neuzuordnung der EscTaste liegt darin, dass sie ziemlich weit entfernt auf der Tastatur liegt und das Eingeben einige Zeit in Anspruch nimmt. Ein Trick, der von den emacsJungs ausgeliehen werden kann, ist die Neuzuordnung, CapsLockda es sich sowieso um einen nutzlosen Schlüssel handelt. emacsJungs ordnen es neu zu, Ctrlaber wir werden es neu zuordnen Esc.

Lassen Sie uns xev -event keyboardden Schlüsselcode von überprüfen CapsLock:

KeyPress event, serial 25, synthetic NO, window 0x1c00001,
    root 0x496, subw 0x0, time 8609026, (764,557), root:(765,576),
    state 0x0, keycode 66 (keysym 0xffe5, Caps_Lock), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

Und um die Funktion von zu überprüfen Esc:

KeyPress event, serial 25, synthetic NO, window 0x1c00001,
    root 0x496, subw 0x0, time 9488531, (571,525), root:(572,544),
    state 0x0, keycode 9 (keysym 0xff1b, Escape), same_screen YES,
    XLookupString gives 1 bytes: (1b) "
    XmbLookupString gives 1 bytes: (1b) "
    XFilterEvent returns: False

Sehr gut, CapsLockist der Schlüsselcode 66 und Escdie Funktion heißt "Escape". Jetzt können wir tun:

# diable caps lock
xmodmap -e "remove lock = Caps_Lock"
# make an Esc key from the keycode 66
xmodmap -e "keycode 66 = Escape"

Das Obige muss in dieser Reihenfolge erfolgen. Jetzt CapsLockfunktioniert es jedes Mal, wenn Sie es Escdrücken, wie eine Taste.


Der schwierige Teil ist, wo dies eingestellt werden soll. Eine Datei ~/.Xmodmapmit dem Inhalt:

remove lock = Caps_Lock
keycode 66 = Escape

Sollte von den meisten Distributionen respektiert werden (eigentlich Display-Manager, aber ich sage der Einfachheit halber Distributionen), aber ich habe solche gesehen, die mehrere ~/X*Dateien nicht respektieren . Für solche Distributionen können Sie Folgendes ausprobieren:

if [ "x" != "x$DISPLAY" ]; then
    xmodmap -e "remove lock = Caps_Lock"
    xmodmap -e "keycode 66 = Escape"
fi

In deinem .bashrc.

(Theoretisch wäre das besser, ~/.xinitrcaber wenn ein Display-Manager dies nicht respektiert .Xmodmap, wird er es definitiv nicht respektieren ~/.xnintrc.)

Zusätzliche Anmerkung: Diese remaps nur CapsLockauf Escin einer X11 - Sitzung, damit die Karte funktioniert nur in Terminal - Emulatoren. Tatsächlich ttywird die Karte nicht angezeigt.

Referenzen und zusätzliche Lektüre:

gro♀
quelle
danke für die ausführliche erklärung. Wären Sie bereit, denselben Prozess zu veranschaulichen, außer für das Mapping jkanstelle von CapsLock? Ich habe es auf meiner Osx-Maschine eingestellt; Ich habe es jedoch nicht für den Rest des Wochenendes und ich kann mich nicht erinnern, wie ich es gemacht habe :)
Mbigras
@mbigras - Bist du sicher, dass du es in Bash gemacht hast? Bash hat keine mehrdeutigen Karten. Ich kenne eine Möglichkeit, dies zu tun zsh: bindkey -v; bindkey -s jk \\e. Aber das ist etwas , das kommt zurück und beißen Sie zurück , wenn Sie brauchen jk, weil der Timer nicht konfigurierbar ist , und Sie haben nicht <leader>in zsh.
Gro♀
Ich habe es definitiv gemacht zshund nicht bash, ist es nicht möglich in Bash?
Mbigras
@mbigras - Warte, ich habe mich geirrt! Lesen man bashfand ich , binddass die Arbeit ziemlich ähnlich wie zsh‚s bindkey. Ich werde die Antwort aktualisieren. Los geht's, ich benutze zshzu viel.
Gro♀
2
@ Jason - Hey, das ist die Vi SE. Hier schreibt jeder ein ALL CAPS-Wort mit: "type word" <Esc> viwU :). Keine Fertigstellung erforderlich
gro♀
2

Vielen Dank, für frühere Antworten verwende ich dies in meinem ~ / .zshrc für vi-ähnliche Verknüpfungen in meinem Terminal. Ich hoffe es wird jemandem helfen.

bindkey -v
bindkey 'jk' vi-cmd-mode
Alexandr Skripkin
quelle
Ich bin hierher gekommen, um nach einer Antwort zu suchen, die zum Binden der Taste '^ G' funktioniert, um in vi-fähigem zsh in den "normalen Modus" zu gelangen, und dies ist die einzige, die funktioniert hat.
Dalker