오래된 답변

오래된 답변

기본적으로 모든 기본 keymap emacs키 바인딩을 사용할 수 있고 여전히 vi-command모드로 변경할 수 있는 하이브리드 모드를 원합니다.

어떻게 설정하나요?

답변1

나는 읽었다@tomhale대답 여기그리고여기.

더 나은 접근 방식은 vi-insert바인딩을 로 이동하는 대신 바인딩을 로 이동하는 것입니다. 그 이유는 전환할 바인딩이 있고, 모드로 전환하도록 기능을 시뮬레이션하기 어렵기 때문입니다.emacsemacsvi-insertvi-commandvi-insertemacs

예를 들어, A명령의 vi-command기본값은 vi-append-eol(줄 끝에 추가하고 로 전환 vi-insert)입니다.

매크로가 아닌 함수에 바인딩되어 있기 때문에 모드 A로 전환 할 수 없습니다 .emacs

예를 들어, 이것은 작동하지 않습니다

"A": vi-append-eol emacs-editing-mode

이것도 아니고 써보세요@tomhale~의답변

"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-insertvi-insertemacsvi-insert

오른쪽 열( )에 고유한 바인딩이 있는 경우 vi-insert, 예를 들어

    "\e": vi-movement-mode

`vi-insert에 이미 있으므로 제거하십시오.

나머지 바인딩은 왼쪽 열( emacs)에 있습니다. 에 추가할 것이므로 이것들은 그대로 두십시오 vi-insert.


이것이 제가 에 추가하기로 선택한 바인딩입니다 .inputrc.emacsvi-insert

"kj"나는 스위치를 사용하지 않기로 결정했습니다 vi-command.@tomhale~의답변왜냐하면 당신은 그것을 사용하여 "\ee"에서 로 이동하는 퀘스트를 완료하고 emacs, vi-insert그런 다음 에서 로 이동하는 또 다른 퀘스트를 완료할 수 "\e"있기 때문입니다 . 실제로는 있습니다vi-insertvi-commandblackjack을 제외하고 kj가 포함된 단어그리고jk가 포함된 단어(주로 지명)

보관했다 "\C-d": delete-char가 버렸어요 "\C-d": vi-eof-maybe. Enterfor를 사용할 수 vi-eof-maybe있고 readline을 눌러 실수로 readline을 종료하고 싶지 않기 때문입니다 "\C-d". 이는 모드에서 바인딩을 "\C-d": vi-eof-maybe재정의하기 위해 바인딩을 사용하고 있기 때문에 바인딩을 제거한다는 의미입니다.vi-eof-maybevi-insertdelete-char

대신 아래쪽 화살표를 사용할 수 있으므로 "\C-n": menu-complete그대로 유지합니다 . 이는 이미 바인딩이 있으므로 두 바인딩을 모두 제거하는 것을 의미합니다 ."\C-n": next-historynext-historyvi-insertmenu-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-commandemacsvi-insert"\e"

이는 "jk"moshing이 주석 처리되었음을 나타냅니다. 현재 "\ee"루프 모드를 사용하고 있습니다. "\e"필요하지 않다고 생각했기 때문에 from 을 바인딩 해제하지 않았습니다 . 그래서 그것이 하는 일은 당신이 누르고 기다리면, 당신은 갈 것입니다.vi-insertvi-command"\e"vi-insertvi-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.emacsvi-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 emacsvi-movement-modevi-commandshow-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-standardvi-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 emacsvi-movement-mode참고: 모드 로 직접 전환하려고 바인딩을 추가하면 vi-command프롬프트가 업데이트되지 않습니다( show-mode-in-prompt on.

이것이 위의 솔루션이 emacs에 바인딩을 추가하는 이유입니다 vi-insert. 이로 인해 시간이 더 길어지지만 .inputrc완전한 솔루션을 위해서는 필요합니다.

관련 정보