기본적으로 모든 기본 keymap emacs
키 바인딩을 사용할 수 있고 여전히 vi-command
모드로 변경할 수 있는 하이브리드 모드를 원합니다.
어떻게 설정하나요?
답변1
더 나은 접근 방식은 vi-insert
바인딩을 로 이동하는 대신 바인딩을 로 이동하는 것입니다. 그 이유는 전환할 바인딩이 있고, 모드로 전환하도록 기능을 시뮬레이션하기 어렵기 때문입니다.emacs
emacs
vi-insert
vi-command
vi-insert
emacs
예를 들어, A
명령의 vi-command
기본값은 vi-append-eol
(줄 끝에 추가하고 로 전환 vi-insert
)입니다.
매크로가 아닌 함수에 바인딩되어 있기 때문에 모드 A
로 전환 할 수 없습니다 .emacs
예를 들어, 이것은 작동하지 않습니다
"A": vi-append-eol emacs-editing-mode
"A": vi-append-eol "\ee"
다음을 수행할 수 있습니다.
"A": "$a\ee"
"a"
하지만 이제는 명령 에 따라 vi-append-mode
바운스도 필요합니다. "a"
그런 다음 계속 진행할 시간입니다 "i"
. "i"
로 전환하는 것이 가능합니다 emacs
. 매크로로 변환해야 하는 전체 명령 체인이 있는데 이는 고통스럽습니다.
따라서 emacs
바인딩을 vi-insert
.
vi-insert
따라서 고유한 바인딩을 설정 emacs
하고 동일한 키 시퀀스에 대해 서로 다른 바인딩이 있는 경우 사용할 바인딩을 결정하려고 합니다. 동일한 바인딩이 있으면 무시합니다.
이 작업은 다음 명령을 사용하여 수행할 수 있습니다.
comm -3\
<(INPUTRC=/dev/null bash -c 'bind -pm emacs' |
LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
sort) \
<(INPUTRC=/dev/null bash -c 'bind -pm vi-insert' |
LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
sort) | cat
| cat
존재 이유를 설명하다여기
"정확히 동일한 바인딩"은 삭제되므로 -3
이 목록을 살펴보고 왼쪽 열에서 바인딩을 찾습니다. 왼쪽 열의 각 바인딩에 대해 다음을 수행합니다.
동일한 키 시퀀스에 대한 중복 바인딩이 있는 경우(예:
"\C-d": delete-char
"\C-d": vi-eof-maybe
그 중 하나를 선택하세요. 이미 바인딩이 있는 곳에 이러한 바인딩을 추가할 예정이므로 원하는 경우 이 두 줄을 삭제할 수 있습니다 vi-insert
(오른쪽). 원하는 경우 (왼쪽) 제거하세요 .vi-insert
vi-insert
emacs
vi-insert
오른쪽 열( )에 고유한 바인딩이 있는 경우 vi-insert
, 예를 들어
"\e": vi-movement-mode
`vi-insert에 이미 있으므로 제거하십시오.
나머지 바인딩은 왼쪽 열( emacs
)에 있습니다. 에 추가할 것이므로 이것들은 그대로 두십시오 vi-insert
.
이것이 제가 에 추가하기로 선택한 바인딩입니다 .inputrc
.emacs
vi-insert
"kj"
나는 스위치를 사용하지 않기로 결정했습니다 vi-command
.@tomhale~의답변왜냐하면 당신은 그것을 사용하여 "\ee"
에서 로 이동하는 퀘스트를 완료하고 emacs
, vi-insert
그런 다음 에서 로 이동하는 또 다른 퀘스트를 완료할 수 "\e"
있기 때문입니다 . 실제로는 있습니다vi-insert
vi-command
blackjack을 제외하고 kj가 포함된 단어그리고jk가 포함된 단어(주로 지명)
보관했다 "\C-d": delete-char
가 버렸어요 "\C-d": vi-eof-maybe
. Enter
for를 사용할 수 vi-eof-maybe
있고 readline을 눌러 실수로 readline을 종료하고 싶지 않기 때문입니다 "\C-d"
. 이는 모드에서 바인딩을 "\C-d": vi-eof-maybe
재정의하기 위해 바인딩을 사용하고 있기 때문에 바인딩을 제거한다는 의미입니다.vi-eof-maybe
vi-insert
delete-char
대신 아래쪽 화살표를 사용할 수 있으므로 "\C-n": menu-complete
그대로 유지합니다 . 이는 이미 바인딩이 있으므로 두 바인딩을 모두 제거하는 것을 의미합니다 ."\C-n": next-history
next-history
vi-insert
menu-complete
"\C-p": menu-complete-backward
대신 "\C-p": previous-history
위쪽 화살표를 누를 수 있기 때문에 계속 유지합니다 previous-history
. 이는 vi-insert
이미 바인딩이 있으므로 두 바인딩을 모두 제거하는 것을 의미합니다 menu-complete-backward
.
"\C-w": vi-unix-word-rubout
대신 예약합니다 "\C-w": unix-word-rubout
. 차이점이 무엇인지 모르겠습니다. 나는 vi-insert
그 중 하나를 고수합니다. 이는 vi-insert
이미 바인딩이 있으므로 두 바인딩을 모두 제거하는 것을 의미합니다 vi-unix-word-rubout
.
나는 그것을 지켰다 "\e": vi-movement-mode
. 이는 vi-insert
이미 존재하는 바인딩을 제거하는 것을 의미합니다 vi-movement-mode
.
set editing-mode vi
set keymap emacs
"\ee": vi-editing-mode
set keymap vi-command
"\ee": emacs-editing-mode
# key bindings to get out of vi-editing-mode
set keymap vi-insert
"\ee": emacs-editing-mode
# emacs keybindings in vi-insert mode
"\C-@": set-mark
"\C-]": character-search
"\C-_": undo
"\C-a": beginning-of-line
"\C-b": backward-char
"\C-d": delete-char
"\C-e": end-of-line
"\C-f": forward-char
"\C-g": abort
"\C-k": kill-line
"\C-l": clear-screen
"\C-o": operate-and-get-next
"\C-q": quoted-insert
"\C-x!": possible-command-completions
"\C-x$": possible-variable-completions
"\C-x(": start-kbd-macro
"\C-x)": end-kbd-macro
"\C-x*": glob-expand-word
"\C-x/": possible-filename-completions
"\C-x@": possible-hostname-completions
"\C-x\C-?": backward-kill-line
"\C-x\C-e": edit-and-execute-command
"\C-x\C-g": abort
"\C-x\C-r": re-read-init-file
"\C-x\C-u": undo
"\C-x\C-v": display-shell-version
"\C-x\C-x": exchange-point-and-mark
"\C-xe": call-last-kbd-macro
"\C-xg": glob-list-expansions
"\C-x~": possible-username-completions
"\e ": set-mark
"\e!": complete-command
"\e#": insert-comment
"\e$": complete-variable
"\e&": tilde-expand
"\e*": insert-completions
"\e-": digit-argument
"\e.": insert-last-argument
"\e.": yank-last-arg
"\e/": complete-filename
"\e0": digit-argument
"\e1": digit-argument
"\e2": digit-argument
"\e3": digit-argument
"\e4": digit-argument
"\e5": digit-argument
"\e6": digit-argument
"\e7": digit-argument
"\e8": digit-argument
"\e9": digit-argument
"\e<": beginning-of-history
"\e=": possible-completions
"\e>": end-of-history
"\e?": possible-completions
"\e@": complete-hostname
"\e\C-?": backward-kill-word
"\e\C-]": character-search-backward
"\e\C-e": shell-expand-line
"\e\C-g": abort
"\e\C-h": backward-kill-word
"\e\C-i": dynamic-complete-history
"\e\C-r": revert-line
"\e\C-y": yank-nth-arg
"\e\\": delete-horizontal-space
"\e\e": complete
"\e^": history-expand-line
"\e_": insert-last-argument
"\e_": yank-last-arg
"\eb": backward-word
"\ec": capitalize-word
"\ed": kill-word
"\ef": forward-word
"\eg": glob-complete-word
"\el": downcase-word
"\en": non-incremental-forward-search-history
"\ep": non-incremental-reverse-search-history
"\er": revert-line
"\et": transpose-words
"\eu": upcase-word
"\ey": yank-pop
"\e{": complete-into-braces
"\e~": complete-username
고쳐 쓰다
제가 좀 더 잘한 것 같아요. 리더로 사용하기 위해 많은 명령이 전송되었기 때문에 스위치를 누를 때 지연이 발생하여 "jk"
스위치를 명령으로 다시 열었던 때가 있었습니다 .vi command
"\e"
vi-command
emacs
vi-insert
"\e"
이는 "jk"
moshing이 주석 처리되었음을 나타냅니다. 현재 "\ee"
루프 모드를 사용하고 있습니다. "\e"
필요하지 않다고 생각했기 때문에 from 을 바인딩 해제하지 않았습니다 . 그래서 그것이 하는 일은 당신이 누르고 기다리면, 당신은 갈 것입니다.vi-insert
vi-command
"\e"
vi-insert
vi-command
에서 로 이동하려면 vi-command
명령 vi-insert
중 하나를 누르기만 하면 됩니다. 예를 들어 "A"
2 개 "i"
모드 사이를 순환할 수도 있으므로 3개 모드 사이를 순환해도 문제가 되지 않습니다 vi
.
set keymap emacs
"\ee": vi-editing-mode
set keymap vi-command
"\ee": emacs-editing-mode
# key bindings to get out of vi-editing-mode
set keymap vi-insert
# Choose one of these editor switching modes
#
# moosh jk to switch
#"\ee": emacs-editing-mode
#"\ejk": vi-movement-mode
#"\ekj": vi-movement-mode
#
# "\ee" to cycle
# can unmap "\e" to switch to vi-command but don't see a need
#"\e":
"\ee": vi-movement-mode
고쳐 쓰다
에서는 `vi-unix-word-rubout에 바인딩 vi-insert
되어 "\C-w"
단어 경계나 다른 곳에서 중지됩니다. 이 기능이 마음에 들지 않습니다.
예를 들어 다음을 시도해 보세요.
$ cannot-delete'
# press left arrow to go back behind the single quote
# press \C-w in vi-insert to try to delete cannot-delete, it won't work
이 버그 보고서제공된 예제에는 문제가 없지만 문제가 설명되어 있습니다.
따라서 이 문제를 해결하기 위해 "\C-w"
emacs에 바인딩할 수 있습니다.unix-word-rubout
다시 바인딩하려면 "\C-w"
필요할 수 있습니다바인딩 해제 기본값.
# In .bashrc
stty werase undef
모든 기본값을 바인딩 해제하려면 다음을 수행하세요.
# In .inputrc
set bind-tty-special-chars off
이것이 중요한지는 확실하지 않지만 macOS를 사용하고 있으므로 거기에 있습니다.내가 제거한 다른 기본 바인딩.
그런 다음 .inputrc
:
"\C-w": unix-word-rubout
답변2
다음 .inputrc
줄을 사용하면 Meta / Alt+와 모드 사이를 전환할 수 있습니다 E.emacs
vi-insert
j동시에 Moo Moo가 k당신을 모드로 데려갈 것입니다 vi-command
.
참고: "kj"가 포함된 유일한 영어 단어는 "blackjack"이며, "jk"가 포함된 단어는 없습니다.)
set show-mode-in-prompt on
set keymap emacs
"\ee": vi-editing-mode
"jk": "\eejk"
"kj": "\eejk"
set keymap vi-insert
"\ee": emacs-editing-mode
"jk": vi-movement-mode
"kj": vi-movement-mode
set keymap vi-command
"\ee": emacs-editing-mode
참고: v4.3.11(1)에서 bash
키맵으로 직접 전환을 시도하기 위해 아래에 바인딩을 추가하면 프롬프트가 업데이트되지 않으므로(있는 경우) 이 해결 방법이 필요합니다.keymap emacs
vi-movement-mode
vi-command
show-mode-in-prompt on
흥미로운 사실:
모드 vi-insert
에 쉽게 추가할 수 있는 모드별 바인딩은 4개뿐입니다 .emacs
"\C-d": vi-eof-maybe
"\C-n": menu-complete
"\C-p": menu-complete-backward
"\e": vi-movement-mode
그러나 다음은 기본 emacs
바인딩입니다.
"\C-d": delete-char
"\C-n": next-history
"\C-p": previous-history
저는 다음과 같이 해결했습니다.
set keymap emacs
"\e": "kj" # needs to be below "kj" mapping
"\C-d": delete-char # eof-maybe: ^D does nothing if there is text on the line
"\C-n": menu-complete
"\C-p": menu-complete-backward
"\C-y": previous-history # historY
"\e\C-y": previous-history
오래된 답변
emacs
에서 으로 직접 가기 전에는 이렇게 했습니다 vi-command
. 여기에는 emacs
모든 기본 명령을 vi-insert
키맵으로 가져오는 작업이 포함됩니다.
기본값 emacs-standard
과 vi-insert
매핑을 가져옵니다.
INPUTRC=~/dev/null bash -c 'bind -pm emacs-standard' | grep -vE '^#|: (do-lowercase-version|self-insert)$' | sort > emacs-standard
INPUTRC=~/dev/null bash -c 'bind -pm vi-insert' | grep -vE '^#|: (do-lowercase-version|self-insert)$' | sort > vi-insert
다음에서 추가 항목만 가져옵니다 emacs-standard
.
comm -23 emacs-standard vi-insert > vi-insert-emacs-additions
그런 다음 에서 ~/.inputrc
줄 아래에 다음을 추가합니다.vi-insert-emacs-additions
(echo set editing-mode vi && echo set keymap vi-insert && cat vi-insert-emacs-additions) >> ~/.inputrc
편의를 위해 bash 4.3.11(1) 릴리스에서는 다음과 vi-insert-emacs-additions
같이 표시됩니다.
"\C-a": beginning-of-line "\C-b": backward-char "\C-]": character-search "\C-d": delete-char "\C-e": end-of-line "\C-f": forward-char "\C-g": abort "\C-k": kill-line "\C-l": clear-screen "\C-n": next-history "\C-o": operate-and-get-next "\C-p": previous-history "\C-q": quoted-insert "\C-@": set-mark "\C-_": undo "\C-x\C-?": backward-kill-line "\C-x\C-e": edit-and-execute-command "\C-x\C-g": abort "\C-x\C-r": re-read-init-file "\C-x\C-u": undo "\C-x\C-v": display-shell-version "\C-x\C-x": exchange-point-and-mark "\C-xe": call-last-kbd-macro "\C-x)": end-kbd-macro "\C-xg": glob-list-expansions "\C-x*": glob-expand-word "\C-x!": possible-command-completions "\C-x/": possible-filename-completions "\C-x@": possible-hostname-completions "\C-x~": possible-username-completions "\C-x$": possible-variable-completions "\C-x(": start-kbd-macro "\e0": digit-argument "\e1": digit-argument "\e2": digit-argument "\e3": digit-argument "\e4": digit-argument "\e5": digit-argument "\e6": digit-argument "\e7": digit-argument "\e8": digit-argument "\e9": digit-argument "\eb": backward-word "\e<": beginning-of-history "\e\C-?": backward-kill-word "\ec": capitalize-word "\e\C-]": character-search-backward "\e\C-e": shell-expand-line "\e\C-g": abort "\e\C-h": backward-kill-word "\e\C-i": dynamic-complete-history "\e!": complete-command "\e/": complete-filename "\e@": complete-hostname "\e{": complete-into-braces "\e~": complete-username "\e$": complete-variable "\e\C-r": revert-line "\e\C-y": yank-nth-arg "\e\\": delete-horizontal-space "\e-": digit-argument "\ed": kill-word "\e\e": complete "\e>": end-of-history "\ef": forward-word "\eg": glob-complete-word "\e^": history-expand-line "\e#": insert-comment "\e*": insert-completions "\e_": insert-last-argument "\e.": insert-last-argument "\el": downcase-word "\en": non-incremental-forward-search-history "\ep": non-incremental-reverse-search-history "\e=": possible-completions "\e?": possible-completions "\er": revert-line "\e ": set-mark "\e&": tilde-expand "\et": transpose-words "\eu": upcase-word "\e_": yank-last-arg "\e.": yank-last-arg "\ey": yank-pop
keymap emacs
vi-movement-mode
참고: 모드 로 직접 전환하려고 바인딩을 추가하면 vi-command
프롬프트가 업데이트되지 않습니다( show-mode-in-prompt on
.
이것이 위의 솔루션이 emacs
에 바인딩을 추가하는 이유입니다 vi-insert
. 이로 인해 시간이 더 길어지지만 .inputrc
완전한 솔루션을 위해서는 필요합니다.