I have a plugin (c.vim) which includes a lot of maps (all with leader key). I changed my leader key to space, which I like, but the problem is that the maps also apply to insert mode. I would like to disable all imaps containing <Space>, so space in insert doesn't cause a delay (and sometimes a command).

I tried :iunmaping specific maps using what I saw in :imap, but that said E31: No such mapping.

I also tried using .vim/after/plugin/map.vim and autocmd VimEnter * imapclear, neither of which worked.

  • 3
    What is the c.vim plugin? – Maxim Kim Jul 9 '20 at 6:55

If your insert mode mappings are filetype specific then .vim/after/plugin/map.vim and autocmd VimEnter * imapclear would not work as they are executed before fitetype creates them. Also imapclear deletes all insert mode mappings including default ones.

You can try to apply imapclear <buffer> on bufread/filetype event though:

using after/ftplugin

create .vim/after/ftplugin/c.vim:

imapclear <buffer>

using autocommands

put it into your vimrc:

augroup cvim_imapclear | au!
    au BufRead,BufNewFile *.c imapclear <buffer>
augroup end

PS, although I would challenge your c.vim plugin if it has other means of tuning it/turning those off.

PPS, what is the :imap output? Can you see those mappings?

  • imap example i <Space>hm @<C-C>:call C_Help("m")<CR>. – Not me Jul 9 '20 at 19:12
  • There is smth wrong with this c.vim. It should provide non-intrusive buffer local insert mode mappings. – Maxim Kim Jul 10 '20 at 7:37

You can try to analyze the result of split(execute('imap <buffer> <space>'), "\n")

From there, keep only the second field (IIRC). => ->map({k,v -> split(v)[1]}), and generate the clearing commands, => prefer ->map({k,v -> 'iunmap <buffer> '.split(v)[1]})

And finally ->execute().


:call execute('imap <buffer> <space>')
\ ->split("\n")
\ ->map({k,v -> 'iunmap <buffer> '.split(v)[1]})
\ ->execute()

I guess it should be done in ~/.vim/after/ftplugin/c/clear-imaps.vim

PS: I don't user (local/)leader in insert mode mappings in lh-cpp ^^'

  • Could you loop over maparg results, unmapping them? – D. Ben Knoble Jul 9 '20 at 13:05
  • @D.BenKnoble, the problem is that maparg() returns only one result and it has to receive the exact key sequence. maparg('<space>', 'i') won't return anything in OP's case. mapcheck() will work on a partial match, but again, only a single result will be returned. They can't be exploited to answer OP's question. – Luc Hermitte Jul 9 '20 at 13:16
  • Maybe i was looking at the wrong function, so it’s mapcheck that does partial matches. But if you do something like while mapcheck != empty | iunmap (pseudocode)? Surely that could give you all of them? – D. Ben Knoble Jul 9 '20 at 13:26
  • @D.BenKnoble. May be. But as I don't like loops (slow and painful to debug), I prefer the functional approach. ^^' Beside, as we cannot have ` while (m = mapcheck(...); !empty(m))` in Vimscript language, the loops will be clumsy with repeated lines. – Luc Hermitte Jul 9 '20 at 14:09
  • 1
    @D.BenKnoble There are risks indeed: 1. I don't know whether newlines can appears in a mapping. I don't see how. 2. The output format of :map may change in the future. In an ideal world mapcheck() would have another parameter to return all matches. – Luc Hermitte Jul 9 '20 at 14:36

This should work to clear all Insert-mode mappings starting with space:

let l:map = mapcheck(' ', 'i')
while !empty(l:map)
  execute 'iunmap' l:map
  let l:map = mapcheck(' ', 'i')

Unfortunately, there is no way to restrict mapcheck to buffer-local mappings only; however, the ugly loop does let us sidestep parsing command output, which may be brittle and break if the output ever changes or contains something unexpected.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.