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, 2016 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(). May 26, 2016 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. May 26, 2016 at 17:22

1 Answer 1


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, 2016 at 0:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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