At moment, mostly for random reasons, I have

$ cat ~/.vim/ftplugin/c.vim 
set tabstop=2 softtabstop=2 expandtab shiftwidth=2 smarttab smartindent autoindent cinoptions=g2

and this

$ cat ~/.vim/ftplugin/cpp.vim 
let c_no_curly_error = 1
set tabstop=8 softtabstop=8 expandtab shiftwidth=8 smarttab smartindent autoindent cinoptions=g2
set mps+=<:>

where I've put 2s and 8s in the two files for debugging purpose.

Since :echo &tabstop gives 2 when I open a *.cpp file (and also when I open a *.c file, which is expected), I'm pretty sure I've put those files in the wrong place or, at least, some lines of those files in the wrong file and wrong place.

In Chapter 42 from Learn Vimscript the Hard Way I read the following


Files in ~/.vim/indent/ are a lot like ftplugin files. They get loaded based on their names.

indent files should set options related to indentation for their filetypes, and those options should be buffer-local.

Yes, you could simply put this code in the ftplugin files, but it's better to separate it out so other Vim users will understand what you're doing. It's just a convention, but please be a considerate plugin author and follow it.

which tells me that, on the one hand, ~/.vim/indent/ would be a better place for filetype-specific Vim files containing set tabstop=... ..., and on the other hand tells me that ~/.vim/ftplugin/ isn't that bad.

Nonetheless, If I move those two files from ~/.vim/ftplugin/ to ~/.vim/indent/, then :echo &tabstop gives the correct output of 8 for *.cpp files and 2 for *.c files.

This troubleshooting tells me that probably ~/.vim/ftplugin/ is a wrong place to put that setting, and ~/.vim/indent is maybe the right place.

  • Is this the case?

If the answer is affirmative, then I know where I have to move c.vim into, and that I have to create a cpp.vim file beside that containing only the second line from the cpp.vim which is above.

  • As a side question, where should I put the other two options, which are not indentation specific? What is their most appropriate location?
  • 1
    I didn't read all the details, but maybe try setlocal instead of set?
    – D. Ben Knoble
    Dec 9, 2020 at 19:59
  • @D.BenKnoble, without moving the files, I observe the same behavior even when I use setlocal (in both the c.vim and cpp.vim files). On the other hand many files in /usr/share/vim/vim82/ftplugin/ and use setlocal, so doing this change is probably good for some other good reason.
    – Enlico
    Dec 9, 2020 at 20:11
  • 2
    Yeah, setlocal keeps the change local to that buffer (relevant if you have many buffers with different filetypes!). For personal stuff, after is also a good way to be sure your settings take effect no matter what
    – D. Ben Knoble
    Dec 9, 2020 at 20:52

2 Answers 2


When in doubt look into the standard Vim runtime files.

ts sts et sw should be set by after/ftplugin.

sta is basically no-op, as you have &sw == &sts anyway.

si ai are basically no-op as you have &cindent on. And also, in general, there's nothing in setting ai si on if you have any meaningful indent/xyz.vim.

cino should probably be set by after/indent, but in this case I'd rather use after/ftplugin to get rid of after/indent completely (the standard indent/c.vim doesn't set any cino values, so it should be okay).

  • 4
    Wow, Matt, if you use non-short names for options, the readability of your answer improves a hundered times.
    – Enlico
    Dec 9, 2020 at 20:01

Yes, perhaps you might want to store these settings in a Vim script in the indent/ directory, though the distinction might not be very clear on which settings belong to indent/ and which ones belong to plugin/.

In practical terms, it mostly matters if you only enable filetype plug-ins but not indent (:filetype plugin on) or indent plug-ins only but not filetype plug-ins (:filetype indent on).

There might be some issues regarding the order in which plug-ins get loaded (I believe scripts from ftplugin/ are loaded before those from indent/, though this might depend on whether you call filetype plugin indent on in a single command or use separate commands to enable each kind), but in most cases this will only matter if you're trying to override something from the Vim runtime files.

It's actually debatable whether the specific settings you have belong in indent/ or ftplugin/ though. Settings such as 'autoindent' and 'smartindent' typically would belong in indent/, but in this case (C and C++ file types) they're actually not getting into effect, since the indent/c.vim from Vim runtimes enables 'cindent', which supercedes these two others.

Regardless, one thing you should definitely do is use setlocal instead of set in these files. You definitely want to affect the current buffer only and not change globals when a C or C++ file is opened.

You might also want to look into :help undo_ftplugin and :help undo_indent, which can be relevant if you switch file types once a file is already opened. (This is a rare operation, but you might want to implement that for completeness.)

See examples under $VIMRUNTIME/ftplugin/ and $VIMRUNTIME/indent/ to get inspiration on those.

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.