bash vi 모드에서 jk를 삽입 모드를 종료하도록 맵핑하십시오. 움직임을 가질 수 있도록

bash 쉘과 함께 ubuntu 16.04의 새로 설치를 사용하고 있습니다. 내가하고 싶은 두 가지가 있습니다.

  1. 터미널에서 vim 같은 움직임을 가질 수 있도록 vi 모드를 설정하십시오.
  2. 다음을 입력하여 삽입 모드를 종료하십시오. jk

내가 읽어 다른 게시물 이가 함께 할 수있는 방법 zsh, 내가 함께 할 수있는 방법 bash?

tl; dr

후에 파일에 넣으 bind '"jk":vi-movement-mode'십시오 🙂.bashrcset -o vi

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

자세한 설명은 @grochmal의 답변을 참조하십시오



답변

TL; DR

강타는 유사한 기능을 가지고 zshbindkey를 통해 bind,하지만 몇 가지가없는 vi등의 모드를 zsh. set -o vi당신이 할 수있는 후 :

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

동등한 이는 zsh‘들bindkey -M <all vi modes> jk vi-movement-mode

vi-movement-mode기능에서 제공 inputrc합니다 ( /etc/inputrc이들의 목록).

전문

스티븐 해리스 (Stephen Harris)는 다음과 같이 지적했다.

  • .bashrcbash항상 호출됩니다 (특히 다른 쉘은 아닙니다).

  • .bash_profile 로그인 쉘에서만 호출됩니다 (그리고 다시 bash 만).

여러 배포판 .bash_profile에는 다음과 같은 골격이 있습니다.

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

.bash_profile단순히 존재하는 것을 잊을 수 있기 때문에 좋은 콘텐츠입니다 .

이제 셸 세션에서 매핑 jk하는 Esc것은 실제로 불가능합니다. 할 때 :

inoremap jk <esc>

Vim에서을 입력 한 후 jVim은 k다음에 입력하는지 확인하기 위해 조금 기다려야한다는 것을 알고 있으며 매핑을 호출해야합니다 (또는 다른 키를 입력하면 매핑이 트리거되지 않아야 함). 부록으로서 이것은 :set timeoutlen=<miliseconds>Vim에서 제어합니다 (참조 :h timeoutlen).

여러 쉘 또는 X11에는 이러한 시간 종료 제어가 없으며 여러 문자 맵핑을 허용하지 않습니다. 단일 키의 매핑 만 허용됩니다 (하지만 아래의 지원 정보 참조).

set -o vi

읽지 않으면 셸에서 사용할 수있는 .vimrc일부 키 조합 만 모방 합니다. 이것에 대해 말할 수 있지만 , 그것의 완전한 힘은 없습니다 .vivim-o emacsemacs


zsh 지원

zsh실제로지도 시간 종료를 지원합니다. 그리고 당신은 매핑하려면 다음을 사용할 수 있습니다 jk<esc>:

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

( ~/.zshrc그러지 말아야 할 것입니다 ~/.bashrc)

그러나 나는 이것에 반대한다. 내가 사용 vim하고 zsh대부분의 시간. 나는 inoremap jk <esc>내 안에 있고 위 vimrcbindkey조합을 사용해 보았습니다. 그것을 사용할 때 zsh인쇄하기에 너무 오래 j기다렸고, 그것은 저를 많이 화나게했습니다.


배쉬 지원

bash지원합니다 readline bind. 나는 그렇게 bash하지 않고 컴파일 할 수 있다고 믿지 readilne않는 bash가있는 희귀 한 시스템이있을 수 있다고 생각합니다 bind. 매핑하려면 jk<esc>에서 bash당신이 할 필요가 :

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

(예, 인용의 이중 수준이므로 필요합니다)

다시 말하지만, 이것은 타이핑을 j상당히 성가 시게합니다. 그러나 어떻게 든 zsh내 컴퓨터 의 솔루션 보다 성가신 것이 적습니다 (아마도 기본 시간 초과가 더 짧습니다).


해결 방법 (비 bash 및 비 zsh 셸의 경우)

Esc키 를 다시 매핑하는 이유 는 키보드에서 멀리 떨어져있어 시간이 오래 걸리기 때문입니다. 어쨌든 쓸모없는 열쇠이기 때문에 emacs사람들 에게서 빌릴 수있는 트릭 은 다시 매핑 CapsLock하는 것입니다. emacs사람들 Ctrl은 그것을 다시 매핑하지만 우리는 그것을 다시 매핑 할 것 Esc입니다.

xev -event keyboard키 코드를 확인하는 데 사용하자 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

그리고 기능을 확인하려면 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

CapsLock키 코드 66은 매우 훌륭하며 그 Esc기능은 “탈출”이라고합니다. 이제 우리는 할 수 있습니다 :

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

위의 순서대로 수행 해야합니다 . 이제 당신이 CapsLock그것을 칠 때마다 Esc열쇠 처럼 작동 합니다.


까다로운 부분은 이것을 설정하는 곳입니다. 내용이 담긴 파일 ~/.Xmodmap:

remove lock = Caps_Lock
keycode 66 = Escape

대부분의 배포판 (실제로 디스플레이 관리자이지만 단순성을 위해 배포판을 말하고 있습니다)은 존중해야하지만 여러 ~/X*파일을 존중하지 않는 것을 보았습니다 . 이러한 배포판의 경우 다음과 같은 것을 시도해 볼 수 있습니다.

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

당신의 .bashrc.

이론적으로 ~/.xinitrc는 디스플레이 관리자가 존중하지 않으면 .Xmodmap분명히 존중하지 않을 것입니다 ~/.xnintrc.

추가 참고 :이 내용은 다시 매핑 CapsLockEsc하는 X11 세션에 따라서지도 것 터미널 에뮬레이터에서만 작동합니다. 실제 tty의지도는 표시되지 않습니다.

참고 문헌 및 추가 자료 :


답변

감사합니다. 이전 답변의 경우 ~ / .zshrc 에서 터미널의 vi와 같은 단축키를 사용합니다. 누군가에게 도움이되기를 바랍니다.

bindkey -v
bindkey 'jk' vi-cmd-mode


답변