raddevon
raddevon

Reputation: 3340

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

I ask this question generally, but I will put it in terms of the specific problem I'm having.

I'm using the vim-lawrencium plugin for a project under Mercurial source control. I use the :Hgstatus command to open the status buffer.

The status buffer comes with some nice keymaps to make it easy to add files to the commit, look at diffs, and finalize the commit.

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>

Most of these seem to work. I've successfully tried diffing, adding, and q to close the status, but the <C-S> shortcut doesn't work at all. I can manually run the :Hgstatuscommit command it's mapped to. I've also looked at :map to verify the key is actually mapped for that buffer, and it does show up in the list.

What is my next step in debugging this? I want to fix this specific problem, but I also want to know how to fix it in the event I run across broken shortcuts in the future. I'm new to Vim, so I'm at a bit of a loss at this point.

UPDATE: Output of :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

SOLUTION: Turned out the problem was that my shell was intercepting Ctrl-S and it was never getting to Vim.

I added a Vim alias to my .zshrc to fix:

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

Found the fix on the Vim Wikia which also has a solution for bash shells.

Upvotes: 3

Views: 1089

Answers (3)

Peter Rincker
Peter Rincker

Reputation: 45117

Software Flow Control

If you are using using a terminal then it is often the case that <c-s> is being used for terminal's software flow control (XON/XOFF). Which makes <c-s> a trickier key to map.

Turn off flow control by adding the following to some startup script (e.g. ~/.bash_profile or ~/.bashrc):

stty -ixon

If you have frozen your terminal then you can unfreeze it by pressing <c-q>.

Generic map debuging

You can debug pretty much any custom vim mapping via the following command:

:verbose map

This will list out each key/chord ({lhs}) maps to what command ({rhs}), mode, and file the mapping was sourced from. For more information on this listing see :h map-listing and :h :map-verbose.

We can filter this list in a few ways:

  • Supplying a mode. e.g. :verbose nmap for normal mode and :verbose imap for insert mode.
  • Proving the key we want to query for. e.g :verbose nmap <c-s>
  • Can also see buffer specific mappings by adding <buffer>. e.g. :verbose nmap <buffer> <c-s>

So for your question the best way to debug what your mapping is set to would be to run the following query:

:verbose nmap <buffer> <c-s>

Note: Vim's native command are not listed via :verbose map. The best way to find one of Vim's native commands is to help. See :h for more.

Upvotes: 3

Anthony Geoghegan
Anthony Geoghegan

Reputation: 11983

I’d suspect that <C-S> is mapped to something else. You can use :map <C-S> to check how (or if) its mapping is configured. Even better, you can add the prefix to see where the mapping was set from, e.g., when I run :verbose map <C-L>, the following is displayed:

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

By contrast, I haven’t set a mapping for <C-S> so when I run, :map <C-S>, I get:

No mapping found

Prepending verbose to a command is a useful general debugging technique as it can show where any Vim option was set, e.g., :verbose set background? shows what the background option is currently set to and which Vim configuration file it was set in:

background=dark
    Last set from ~/.vimrc  

Upvotes: 1

svlasov
svlasov

Reputation: 10456

First, check that <C-S> still mapped to :Hgstatuscommit

map <C-S>

Hgstatuscommit calls s:HgStatus_Commit. Open its definition on line 1134 and put some debugging print outs:

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

After using the mapping, check :messages.

Upvotes: 2

Related Questions