Buffer-specific mappings are supported by vim out of the box. I am trying to implement window-specific mappings. My plan is to override the default keybinding by one that checks if a window-specific map should be executed, if so, it executes that, and if not, execues the default action for that keybinding (this is the ExecuteWindowMap function).

I'm having trouble with setting the map, see SetWindowMap. This function is called with an argument, a:map, a string of keys. It needs to include pass this string of keys to a function call, so it makes sense to use noremap; with map these keys would get pressed instead of passed to the function! On the other hand, I can only call that function using<CR>, which doesn't work with noremap!

I see two possible solutions:

  1. Use map and somehow escape the key sequence contained in a:map.

  2. Use noremap in a way that allows a calling a function.

    function! SetWindowMap(map)
      exe "noremap " . a:map . " :call ExecuteWindowMap('" . a:map . "')<CR>"
    function! ExecuteWindowMap(map)
      if exists("w:winMaps") && has_key(w:winMaps, a:map)
            exe w:winMaps[a:map]
            exe "unmap " . a:map 
            exe "'a:map'"
            call SetWindowMap(a:map) 
    function! WindowMap(map, cmd)
      if !exists("w:winMaps")
            let w:winMaps = {}
      let w:winMaps[a:map] = a:cmd
      call SetWindowMap(a:map)
  • If you did solve your problem, do consider posting an answer instead of deleting the question. – muru May 26 '16 at 0:02
  • Sorry, I don't have much time for a serious answer. However, I have many functions that generate mappings, restore/remove mappings (see lh#on#exit()), and so on. For instance, you could have a look at lh#menu#map_all() and its test case, or lh-bracket s:DefineMap(). – Luc Hermitte May 26 '16 at 17:19
  • As a side note, your need is quite odd. While I often need modal mappings (that are just defined for the duration of some specific tasks), I don't see a use case where a window mapping could make sense. The task won't be simple as you'll need to restore buffer mappings that you've overridden for the current window. – Luc Hermitte May 26 '16 at 17:22

I was encouraged to answer my own question, I initially deleted it, because I was just not familiar with the way strings work in vim. When you use double quotes, characters preceded by a backslash are escaped before the string is used by the function. You thus need to use double backslashes, or use a literal string with single quotes. It is explained further here and here (Chapter 26 & 31 of Learn Vimscript the Hard Way).

  • 1
    And your other recently-deleted question about matchadd is also an instance of the same quoting problem. – muru May 26 '16 at 0:59

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.