I would like to do the following remap:

:inoremap <Option-Space> &nbsp;

In other words, pressing option-space would add an html-escaped space. How could this be done, so that it only works when ft=html ?


You can set shortcut based on filetype with autocmd mapping:

autocmd FileType html inoremap <buffer> <F5> &nbsp;
autocmd FileType c inoremap <buffer> <F5> Hello, C!

So in HTML files <F5> would type &nbsp; and in C files it would type Hello, C!

Probably your vimrc setting should be following:

autocmd FileType html inoremap <buffer> <Option-Space> &nbsp;

See more in help:

:h autocmd
:h :map-<buffer>
  • 1
    autocommand should always be defined within a group to permit reloading of the file where they are defined. Beside, the ft-specific mappings shall also be :map-<buffer>. Jun 9 '20 at 20:00
  • I disagree with this. File type local shortcuts are meant to be mapped via localmapleader. It is optimized for these purposes.
    – justahuman
    Jun 11 '20 at 14:00
  • @justahuman. <localleader> is just another global leader key. A non buffer restricted mapping will still be global, even with a <localleader>. Open two buffers, define :nnoremap <localleader>A :echo "foo"<cr> in one buffer, go to the other buffer, and trigger the mapping. You'll see that it will also exist: the mapping is global. ft-related mappings shall be defined with <buffer>. Jun 12 '20 at 0:28
  • 1
    @LucHermitte. Thanks for correction, did not know about <buffer> parameter in :map command. Edited answer, please check if it is correct now.
    – Dmitry
    Jun 12 '20 at 11:34
  • 1
    @Dmitry. Yes, it's much better, and correct :) The last thing is that it's better to put autocommands in a group: this permits to reload the file where they are defined without triggering multiple times the same autocommand. I don't know why teaching resources show this flawed approach first without at least showing a proper way to do it, like here: reddit.com/r/vim/wiki/where_to_put_filetype_specific_stuff Jun 12 '20 at 11:39

autocommands are a possible first step. In all cases they won't be enough (to restrict the mapping to the right filetype). And they don't really scale, that's why I recommend ftplugins instead.

Add a ftplugin in ~/.vim/ftplugin/{ftname}.vim (don't forget :filetype plugin on in your .vimrc).

Then, in this ftplugin declare a buffer local mapping (:h :map-<buffer>). The <buffer> part is important, otherwise every time you open a buffer of a different filetype, the setting could be overridden (and possibly lost...) as it would be a global one.

:inoremap <buffer> <Option-Space> &nbsp;
  • I see. So basically, if I open a python file after an html file it will still have the option-space mapping in there, or what do you mean it's a global one?
    – David542
    Jun 9 '20 at 20:15
  • 2
    Without <buffer>, if you open a python file after an html one, either you'll see <option-space> from html still working, or you'll override <option-space> with a new one (if you have another mapping dedicated to python), even in the previous html buffer. Without <buffer>, mappings and abbreviations are global: shared between all buffers. Jun 9 '20 at 20:22
  • I’ve had better experience with ~/.vim/after/ftplugin (I think to make sure I don’t prevent the distribution ftplugins from running, and to override plugin ftplugins where necessary)
    – D. Ben Knoble
    Jun 10 '20 at 12:45
  • @D.BenKnoble. Good point. I'll have to check my config some day. And to check whether in :runtime! {ft}*.vim {ft}/*.vim files are sourced sorted by files (specified by :runtime order) or by directory (specified by &rtp). Jun 10 '20 at 13:34

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.