In vim, many keys in normal mode perform an action only when appended by another character. For example g, by itself, doesn't do anything. But gg goes to the top of the page, gt goes to the next tab, and gT goes to the previous tab. This is an example of a double character combo where the first character is sort of behaving like a verb I guess, and the second character specifies the action.

I'd like to have a button in normal mode that waits for two additional characters to specify a behavior/mapping. Is this possible? This would solve two of my problems: firstly, it would drastically expand the number of empty/available bindings (since there are many more unique triple character combos than double) so I'm free to create as many mappings as I desire. Secondly, it makes sense from a syntactical perspective to allow more specificity of behavior in vim, for the users who want it.

For example, if i want to enter in a template empty docstring under a function's definition based on the language (since docstrings have a different syntax in different languages), the first character can be i for insert, then d for docstring, and then e.g. p for python or c for c++.

  • 1
    you sure can! but maybe you can give an example?
    – Mass
    Commented Sep 1, 2020 at 0:54
  • Added an example:)
    – WalksB
    Commented Sep 1, 2020 at 1:17
  • Be advised, though, that choosing something like i as the first character of your mapping may not be desirable as when you just want to go from Normal mode to Insert (i.e. by hitting i) you will encounter a small delay (whose length is configurable). Most people prefer to start with an unbound key (and that usually means their leader key).
    – B Layer
    Commented Sep 1, 2020 at 1:28
  • 1
    See help for these settings for details 'timeout', 'ttimeout', 'timeoutlen', 'ttimeoutlen. It's for those times when what happens next is ambiguous to vim since there may be a mapping x as well as a mapping xx. Or xy and xz. In those cases what happens when you've just hit x.
    – B Layer
    Commented Sep 1, 2020 at 2:11
  • 1
    :h map-typing, too
    – B Layer
    Commented Sep 1, 2020 at 2:20

1 Answer 1


Vim mappings you create can have arbitrary lengths. Typically you'll try to make them short, since the shorter they are, the easier to type.

Three character mappings are fairly common though. For example, many plug-ins that comment and uncomment lines (such as vim-commentary or NERD Commenter) use gcc to toggle comment on the current line.

As another example, the SpaceVim distribution sets up many 3 or 4 character mappings, most of them starting with <Space> (or SPC) which is SpaceVim's "leader" key. For example, SPC c l to toggle comment on lines, SPC i l p to insert a "lorem-ipsum" paragraph (of filler text), SPC x a = to align on the "=" symbol, SPC b n to switch to the next buffer, etc. Since SpaceVim creates so many mappings, its flagship feature is actually a hierarchical menu displaying the next choices, triggered by the SPC at the start of the mapping, to help users navigate so many possible choices. (SpaceVim also displays an interactive menu for g and z, which are Vim's native multi-character prefixes for mappings.)

If I want to enter in a template empty docstring under a function's definition based on the language (since docstrings have a different syntax in different languages), the first character can be i for insert, then d for docstring, and then e.g. p for Python or c for C++.

As mentioned, using i as a prefix is not a good idea, since it's already a one-character command.

If you're assuming these would come after a leader (possibly the one you set to mapleader, which you access in mappings with <Leader>), then it's fine.

But: do you really need both i and d? Do you have another action to do on a docstring other than inserting it? Shouldn't <Leader>d perhaps suffice? (But then, if you have many many mappings, you might really need another level of mappings.)

Regarding supporting multiple languages, you should probably implement a single mapping to insert a docstring and have it insert the appropriate format based on the type of file. Vim can recognize file types (or you can set them explicitly) through the 'filetype' option.

See :help filetype-plugin for help creating a plug-in for a specific file type, which you can use to create sets of similar mappings implementing the same feature (such as inserting a docstring) for each relevant file type.

For inserting boilerplate, consider also the many snippet plug-ins available in Vim, which are perfect for this kind of task and typically allow you to define snippets per file type (so, again, you can use a single trigger for docstring and implement it differently for each language you care about.) Snippet plug-ins normally expand snippets from insert mode, so you usually don't need to reserve normal mode mappings (and deal with deep mappings, with long character sequences), which addresses another motivation you mentioned in the question.

  • 1
    And if you have lots of mapping prefixes, you can use my popsikey for a simpler HUD then SpaceVim’s (im pretty sure it doesn’t support multiple prefix levels yet, and I’m not sure i have the motivation to make it do so)
    – D. Ben Knoble
    Commented Sep 1, 2020 at 11:51
  • I do need both i and d, i is for insert, and sometimes I would like to insert other things, such as unit test templates. so (leader)iup would be inserting a python unit test, for example. I have <Leader>d already mapped to deleting to black hole register. Regarding creating a plugin based on file type, I'll look more into it!
    – WalksB
    Commented Sep 1, 2020 at 18:53
  • @ZaidGharaybeh I really recommend you look into snippets... I really like UltiSnips and you can find a nice snippet library at honza/vim-snippets that is ready to use and will get you started... And snippet managers such as UltiSnips make it easy for you to create more of your own snippets.
    – filbranden
    Commented Sep 1, 2020 at 20:53
  • See, for example, testcase and doc for a docstring.
    – filbranden
    Commented Sep 1, 2020 at 20:56
  • 1
    :h 'timeout', 'ttimeout', 'timeoutlen', 'ttimeoutlen', 'map-typing'
    – WalksB
    Commented Sep 19, 2020 at 1:28

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.