18

I have a project with a bunch of C++ header files that follow the standard C++ header naming convention; that is, a class called Foo would be declared in a file called Foo, not Foo.h or Foo.hh. Is there a good way to configure vim to do syntax highlighting for these files only? A slightly-less-pleasing fallback would be to enable C++-style highlighting for all files that don't have an extension. I'm not sure if there's any more sophisticated way to detect the type of file instead of relying solely on its extension.

Jason R
  • 11,159
  • 6
  • 50
  • 81
  • Relevant SO post: – dirkgently May 14 '12 at 13:48
  • 1
    `:set syntax=cpp` will force C++ highlighting on the current file. Probably most people ending up here are looking for this solution, rather than setting it up on a per project basis. – Sdra Jun 28 '21 at 15:28

3 Answers3

18

You can use the modeline feature for this. Modelines allow you to set certain options from within a comment in the first/last few lines of your file.

This makes it a great place to set parameters for coding guidelines, folding. Some options cannot be set for security reasons. See the documentation for more information.

Put this at the top or bottom of the file:

/* vim: set ft=cpp: */

EDIT: More details, prompted by the comments :) :

It will only work if modeline is enabled. In normal circumstances it should be by default. To make sure it is enabled, or to change the size of the area it is detected in, set the modeline option in your .vimrc:

set modelines=5

will make sure the line like the one quoted above will be detected in the first five or the last five lines of each file.

Inside the modeline, setlocal means to set options for the buffer the file is loaded in. The ft option, also known as filetype, is what determines the syntax highlighting language. The value cpp is the one that is used by C++ files.

EDIT 2: Without the modeline, with a bit more work, if you can identify a magic pattern:

au BufRead * if search('MagicPattern', 'nw') | setlocal ft=cpp | endif

Meaning: Every time you open a file, check if "MagicPattern" is in there. If it is, treat it as C++. The pattern argument is in vim dialect of regular expressions; check help pattern for details.

Amadan
  • 191,408
  • 23
  • 240
  • 301
  • As alternative to @Amadan solution you may change the VIM auto-detection code to match your coding style (default should be that the first or second line should start with a comment). – Adriano Repetti May 14 '12 at 13:52
  • And don't forget `modeline` support has to be enabled for this to work – sehe May 14 '12 at 13:52
  • @sehe: Exactly. However, it's on by default for normal users of vim; off for vi or admins. You shouldn't code as `root`; and the question was for vim; so unless OP specifically switched it off, he should be fine. :P – Amadan May 14 '12 at 13:54
  • @Adriano: If all of the headers have comments (either C- or C++-style) in the first line, can this be exploited to activate the C++ syntax highlighting? – Jason R May 14 '12 at 13:58
  • @Amadan Don't assume so much. All these sound like excuses for laziness, whereas in reality, answers that actually explain what makes it work and how things are called gain value. This is what makes StackOverflow work. I won't even go near 'teach a man how to fish' etc :) – sehe May 14 '12 at 13:58
  • @JasonR: Yes. It doesn't even have to be in the first line; if you have `set modeline=5`, it will be detected if it is in the first five or the last five lines of the file. Take a look at `help 'modeline'`. – Amadan May 14 '12 at 14:00
  • @Amadan: I wasn't specifically asking about the modeline approach that you noted, as I would like to do this without modifying the code in question if possible. It is a large library that I'm just using in my project. I was wondering if there is a good way to detect the presence of any comment at the beginning of a no-extension file, and if present, to activate C++ highlighting. – Jason R May 14 '12 at 14:01
  • @JasonR You can do almost anything. It would in practice be cheaper to reuse existing solutions (libmagic/[`file`](http://unixhelp.ed.ac.uk/CGI/man-cgi?file) from an autocommand, or, indeed, conventional file extensions, files in a certain directory etc.) @Amadan: +1 after edits – sehe May 14 '12 at 14:09
  • @JasonR I agree with sehe, conventions can help a lot (filetype.vim C/C++ autodetection is far from great by default) – Adriano Repetti May 14 '12 at 14:10
  • @JasonR: There we go; added a `modeline`-less solution. – Amadan May 14 '12 at 14:20
  • I found the answer to the same question [here](https://stackoverflow.com/a/2669295/2023370) very useful: put `au BufNewFile,BufRead * if &syntax == '' | set syntax=cpp | endif` in your .vimrc file. It sets files that don't have their syntax set, to C++. – user2023370 Dec 15 '22 at 11:39
15

With default vim settings, add this to the top of a file to have vim pick up the filetype:

/* vim: set filetype=cpp: */

If you are in another language, adjust accordingly, e.g.:

# vim: set filetype=python:

modeline Versus modelines Clarification

In the answer, https://stackoverflow.com/a/10584645,

set modeline=5

Should be:

set modelines=5

See docs: https://stackoverflow.com/a/10584645. Specifically, modeline is a boolean enable flag that is on by default http://vimdoc.sourceforge.net/htmldoc/options.html#%27modeline%27, and modelines takes an integer argument (defaulting to 5 in any case) that sets the number of lines to be looked at if modeline is enabled http://vimdoc.sourceforge.net/htmldoc/options.html#%27modelines%27.

None of this is of interest to the OP, but I add it here for anyone who arrives from a search to remind themselves how to tell vim the filetype at the top of a file.

Community
  • 1
  • 1
ahcox
  • 9,349
  • 5
  • 33
  • 38
0

Looking for a solution to this, I also found this answer, which is perfect if you want to set a specific file extension as a synonym for a standard one:

https://vi.stackexchange.com/a/5203/31568

For example, in my case I use the extension .icc to store the inline definitions of C++ methods, and following the answer linked here above, I could assign the icc extension to the cpp language in a custom filetype.vim file:

" My own filetype file
" where I define custom filetypes/extensions
"
if exists("did_load_filetypes")
    finish
endif
augroup filetypedetect
    au! BufRead,BufNewFile *.icc       setfiletype cpp
augroup END
rmbianchi
  • 6,241
  • 6
  • 26
  • 27