Emacs와 vi 모드 간 전환을 위한 바인딩 맵 이해

Emacs와 vi 모드 간 전환을 위한 바인딩 맵 이해

너무 길어요.

bash+ 다음 명령을 실행하면 아무 효과가 없는 Ctrl것 같습니다.z

bind -m vi-command '"\C-z": emacs-editing-mode'
bind -m vi-insert '"\C-z": emacs-editing-mode'
bind -m emacs-standard '"\C-z": vi-editing-mode'

그리고 이와 같은 어리석은 일이 작동합니다

bind -m vi-insert '"h": "ciaooooo"'

이 문제의 근원

항상 만족했기 때문에 이러한 매핑을 사용하고 싶다는 뜻은 아니지만 vi-editing-mode, 주로 어떻게 하는지 모르기 때문에 관찰하고 있는 동작을 이해하고 싶습니다.fzf~의key-bindings.bash일하다.

key-bindings.bash다음과 같은 여러 가지 함수가 정의되어 있습니다.__fzf_select__,__fzf_cd__및 기타 항목을 다양한 방법으로 키에 바인딩합니다.

이제 가정해보자최근의bash, 바인딩은 다음과 같습니다.

# Required to refresh the prompt after fzf
bind -m emacs-standard '"\er": redraw-current-line'

bind -m vi-command '"\C-z": emacs-editing-mode'
bind -m vi-insert '"\C-z": emacs-editing-mode'
bind -m emacs-standard '"\C-z": vi-editing-mode'

#if (( BASH_VERSINFO[0] < 4 )); then
# older versions of the commands in the else branch
#else
  # CTRL-T - Paste the selected file path into the command line
  bind -m emacs-standard -x '"\C-t": fzf-file-widget'
  bind -m vi-command -x '"\C-t": fzf-file-widget'
  bind -m vi-insert -x '"\C-t": fzf-file-widget'

  # CTRL-R - Paste the selected command from history into the command line
  bind -m emacs-standard -x '"\C-r": __fzf_history__'
  bind -m vi-command -x '"\C-r": __fzf_history__'
  bind -m vi-insert -x '"\C-r": __fzf_history__'
#fi

# ALT-C - cd into the selected directory
bind -m emacs-standard '"\ec": " \C-b\C-k \C-u`__fzf_cd__`\e\C-e\er\C-m\C-y\C-h\e \C-y\ey\C-x\C-x\C-d"'
bind -m vi-command '"\ec": "\C-z\ec\C-z"'
bind -m vi-insert '"\ec": "\C-z\ec\C-z"'

여기서 및 에 대해서는 , __fzf_history__, fzf-file-widget3개의 키맵에 대해 동일한 매핑이 수행됩니다 emacs-standard. 여태까지는 그런대로 잘됐다.vi-commandvi-insert

그러나 __fzf_cd__이야기는 다릅니다:

  • bind -m emacs-standard일련의 미친 emacs 특정 키 입력에서 이를 참조 하십시오 .
  • 반면 bind -m vi-command/는 + 매핑(위 코드 조각의 상단)을 vi-insert활용하여 전환 하고 논리를 적용하는 것으로 보입니다.Ctrlzemacs-editing-modevi-editing-mode
    1. 입력 emacs-editing-mode모드
    2. Alt+를 치다c
    3. 복귀 vi-editing-mode모드

나는 위의 분석이 대부분 정확하다고 비교적 확신합니다.

Ctrl그러나 + 매핑은 z+ 매핑과 동일한 범위에서 정의되며 후자가 전자를 활용하지만 후자는 유효하고 전자는 유효하지 않습니다.Altc

내가 무엇을 놓치고 있나요?

답변1

내가 예상하는 것은 수동으로 시도할 때 "\Cz"가 터미널 자체에 의해 "hang" 문자로 포착된다는 것입니다.

따라서 readline내장 함수는 bash실제로 역할을 볼 수 없으므로 관련 작업을 수행하지 않습니다. "\Cz"가 매핑의 일부인 경우 터미널을 통과하지 않으므로 가로채지 않습니다.

그래서 fzf가 "내부" 전환에 특정 키를 사용하기로 선택한 것 같습니다.

이를 확인하려면 새 터미널을 열고 stty -a. 이 출력에서 susp = ^Z;​​Cz 문자가 실제로 터미널에서 찾고 있는 문자인지 확인할 수 있기를 바랍니다 .

그런 다음 동일한 터미널에서 정의한 매핑을 테스트하기 전에 전환하는 대신 stty susp ^X매달린 문자를 생성하기 위해 실행할 수 있습니다 . 제가 맞다면 키 바인딩이 변경되어야 합니다.^X^ZC-zemacs-editing-mode

핵심 사항은 다음과 같이 명확해야 합니다.

  • bind -m vi-insert '"\C-z": emacs-editing-mode'
  • stty -a(그냥 보기 위해서).
  • stty susp ^X
  • C-z키 바인딩이 변경되었는지 확인하세요 .

관련 정보