A lot of languages use curly braces {} to enclose code blocks, so it's nice to have a mapping something like:

inoremap  <buffer>  {<CR>    {<CR>}<Esc>O

I have this mapping in my c.vim ftplugin, but also in: r.vim, scala.vim, and json.vim.

But this forces me to duplicate it four times. If I come up with an improvement, or I want to rebind the keys, I have to do it in each place.

Sourcing a shared script in each ftplugin seems like a good solution, but I'm not sure where the right place to put those shared scripts is. Putting them in plugin/ means they are loaded every time, which is not what I want. autoload/ seems to be designed for functions more than mappings, but perhaps there is a way to use it that way?

So, in short:

How can I define these mappings (but more generally, any part of an ftplugin) once, and then use them in multiple ftplugin files?

1 Answer 1


I see several ways to proceed

  1. When I want to store code to load and execute on demand, I use the old macros/ directories.

    runtime macros/some_script.vim
  2. Another approach is to put the mappings you which to define in a series of functions in an autoload plugin and to call the functions from the various ftplugins.

    call ns1#ns2#my_init_function1(args)
  3. A third approach, which is the one I've chosen in lh-brackets in to have very generic mappings I use quite everywhere in a plugin/, and specialized <buffer>-mappings in buffers where I desire a different behaviour (in ftplugins). Of course, this works only when the specialized behaviour is not do nothing which is not standard.

PS: By experience, a mapping on {<cr> is a bad idea as it'll introduce a delay every time you'll type {. Having a contextual mapping on <cr> that detects whether there is a { before the cursor, or even if the cursor is between a pair of curly brackets, will give a much better user experience. See what I've done in lh-brackets.

if get(g:, 'cb_newline_within_empty_brackets', 1)
  " The following function will fall back to an existing previous
  " mapping definition, if any, or to default behaviour if the 
  " condition isn't met
  call lh#brackets#enrich_imap('<cr>',
        \ {'condition': 'getline(".")[col(".")-2:col(".")-1]=="{}"',
        \   'action': 'lh#brackets#_add_newline_between_brackets()'},
        \ 0
        \ )
  • Not only a great answer, but a second answer to a question I did not know I should ask! Thanks! I went with option 1. after trying 2. independently and finding it a little less elegant.
    – Alex
    Dec 8, 2018 at 3:52

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.