如何在 Vim 中调试无效的键盘映射?

How do I debug a non-functioning keymap in Vim?

我一般会问这个问题,但我会根据我遇到的具体问题来提出。

我正在为 Mercurial 源代码管理下的项目使用 vim-lawrencium 插件。我使用 :Hgstatus 命令打开状态缓冲区。

状态缓冲区随 some nice keymaps 一起提供,可以轻松地将文件添加到提交、查看差异和完成提交。

nnoremap <buffer> <silent> <cr>  :Hgstatusedit<cr>
nnoremap <buffer> <silent> <C-N> :call search('^[MARC\!\?I ]\s.', 'We')<cr>
nnoremap <buffer> <silent> <C-P> :call search('^[MARC\!\?I ]\s.', 'Wbe')<cr>
nnoremap <buffer> <silent> <C-D> :Hgstatustabdiff<cr>
nnoremap <buffer> <silent> <C-V> :Hgstatusvdiff<cr>
nnoremap <buffer> <silent> <C-U> :Hgstatusdiffsum<cr>
nnoremap <buffer> <silent> <C-H> :Hgstatusvdiffsum<cr>
nnoremap <buffer> <silent> <C-A> :Hgstatusaddremove<cr>
nnoremap <buffer> <silent> <C-S> :Hgstatuscommit<cr>
nnoremap <buffer> <silent> <C-R> :Hgstatusrefresh<cr>
nnoremap <buffer> <silent> q     :bdelete!<cr>

其中大部分似乎都有效。我已经成功地尝试了比较、添加和 q 来关闭状态,但是 <C-S> 快捷方式根本不起作用。我可以手动 运行 它映射到的 :Hgstatuscommit 命令。我还查看了 :map 以验证密钥实际上已映射到该缓冲区,并且它确实显示在列表中。

调试此程序的下一步是什么?我想解决这个具体问题,但我也想知道 如何 解决它,以防将来我 运行 跨过损坏的快捷方式。我是 Vim 的新手,所以此时我有点不知所措。

更新: :verbose map <C-S>

的输出
v  <C-S>       *@:Hgstatuscommit<CR>
        Last set from ~/.spf13-vim-3/.vim/bundle/vim-lawrencium/plugin/lawrencium.vim
n  <C-S>       *@:Hgstatuscommit<CR>
        Last set from ~/.spf13-vim-3/.vim/bundle/vim-lawrencium/plugin/lawrencium.vim

解决方案: 原来问题是我的 shell 正在拦截 Ctrl-S 而它永远不会到达 Vim。

我在我的 .zshrc 中添加了一个 Vim 别名来修复:

alias vim="stty stop '' -ixoff ; vim"
ttyctl -f

找到 the fix on the Vim Wikia 也有 bash shells.

的解决方案

我怀疑 <C-S> 被映射到其他东西。您可以使用 :map <C-S> 检查其映射是如何(或是否)配置的。更好的是,你可以 添加前缀以查看映射的设置位置,例如,当我 运行 :verbose map <C-L>,显示如下:

<C-L>       * :noh<CR><C-L>
    Last set from ~/.vimrc

相比之下,我没有为 <C-S> 设置映射,所以当我 运行、:map <C-S>、 我得到:

No mapping found

在命令前添加 verbose 是一种有用的通用调试技术,因为它可以显示设置任何 Vim 选项的位置,例如,:verbose set background? 显示 background 的内容选项当前设置为哪个 Vim 配置文件:

background=dark
    Last set from ~/.vimrc  

首先,检查 <C-S> 是否仍映射到 :Hgstatuscommit

map <C-S>

Hgstatuscommit 呼叫 s:HgStatus_Commit。打开它在 line 1134 上的定义并放置一些调试打印输出:

echom a:linestart
echom a:lineend
echom a:bang
echom a:vertical

使用映射后,检查:messages

软件流控制

如果您使用的是终端,那么 <c-s> 通常用于终端的软件流控制 (XON/XOFF)。这使得 <c-s> 成为一个更棘手的映射键。

通过将以下内容添加到某些启动脚本(例如 ~/.bash_profile~/.bashrc)来关闭流量控制:

stty -ixon

如果您已经冻结了您的终端,那么您可以通过按 <c-q> 来解冻它。

通用地图调试

您可以通过以下命令调试几乎任何自定义 vim 映射:

:verbose map

这将列出每个 key/chord ({lhs}) 映射到哪个命令 ({rhs})、模式和映射来源的文件。有关此清单的更多信息,请参阅 :h map-listing:h :map-verbose

我们可以通过几种方式过滤此列表:

  • 提供模式。例如:verbose nmap 用于普通模式,:verbose imap 用于插入模式。
  • 证明我们要查询的密钥。例如 :verbose nmap <c-s>
  • 还可以通过添加 <buffer> 查看特定于缓冲区的映射。例如:verbose nmap <buffer> <c-s>

因此,对于您的问题,调试映射设置的最佳方法是 运行 以下查询:

:verbose nmap <buffer> <c-s>

注意:Vim 的本机命令未通过 :verbose map 列出。找到 Vim 的本机命令之一的最佳方法是提供帮助。有关更多信息,请参阅 :h