了解绑定映射以在 emacs 和 vi 模式之间切换

了解绑定映射以在 emacs 和 vi 模式之间切换

太长了;博士

如果我在 中执行以下命令bashCtrl+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,但我想了解我观察到的行为,主要是因为我对如何fzfkey-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似乎利用Ctrl+z映射(上面代码片段的顶部)在emacs-editing-mode和之间切换vi-editing-mode,从而应用逻辑
    1. 进入emacs-editing-mode模式
    2. 击中Alt+c
    3. 返回vi-editing-mode模式

我相对确定上述分析大部分是正确的。

Ctrl但是+的映射与+的映射z定义在相同的范围内,后者利用了前者;但后者有效,而前者无效。Altc

我缺少什么?

答案1

我预计发生的情况是,当手动尝试时,“\Cz”被终端本身捕获为“挂起”字符。

因此,readline内置函数bash实际上从未看到该角色,因此从未执行相关操作。当“\Cz”是映射的一部分时,它不会通过终端,因此不会被拦截。

我猜这就是为什么 fzf 选择使用该特定键进行“内部”切换的原因。

为了检查这一点,您可以打开一个新终端并运行stty -a。在该输出中,我希望您会看到susp = ^Z;确认 Cz 字符确实是终端要查找的字符。

然后在同一个终端中,您可以运行stty susp ^X来创建挂起字符^X,而不是^Z在测试C-z您定义的映射之前切换到emacs-editing-mode,如果我是对的,您的键绑定应该已经更改。

要点要明确:

  • bind -m vi-insert '"\C-z": emacs-editing-mode'
  • stty -a(只是为了查看)。
  • stty susp ^X
  • 按下C-z并查看按键绑定是否已更改。

相关内容