11

I'm trying to fix syntax highlighting for python; my colors are different from those in screenshots of what it "should" look like in different vim color schemes. And you can see the difference in comparing .rb (which displays correctly) to .py, which looks like it's off:

enter image description here

For example, notice how self isn't highlighted. (This is in base16, but the comparison would be similar in other color schemes). Generally, it looks like the object syntax highlighting is wrong.

Some things I've tried:

  1. Looking at the syntax scripts vim loads; the only difference between .py and .rb in the example below is that, of course, ruby gets indent/ruby.vim and syntax/ruby.vim while python gets indent/python.vim and syntax/python.vim. These are the files that come with homebrew vim.
  2. Loading the same files in macvim rather than terminal (iterm2) vim; same problem, the files look exactly the same as in the picture.
  3. Adding the new python.vim file. Doesn't solve the problem, even if used as an .vim/after script.

Any suggestions are welcome; I've been banging my head on this for hours, and can't figure out why the highlighting isn't working as expected.

  • Note that Python doesn't have symbols, and I would strongly recommend you use Python 3 syntax for new code. – Martin Tournoij Jul 14 '16 at 18:25
12

How syntax highlighting works in brief:

  • In syntax/<filetype>.vim the syntax rules are defined with the :syntax command. This command defines, well, syntax. It says "if text matches this regular expression, it's a string", and so forth. To do so, it assigns a highlight group. It does not say anything about colours as such.

  • :highlight says "highlight this group with these colours". This is done in the colour scheme, not the syntax file. There are a bunch of default Highlight groups (String, Function, Special, and so forth) which all colour schemes should define.

    You're by no means restricted to these default groups though, and you can create as many groups as you want (but default syntax files typically don't).

  • The indent/<filetype>.vim file controls automatic indentation. For example for Ruby it says "the line after def should increase the indentation level" and "the line after end should decrease the indentation one level". It doesn't do anything with colours or syntax highlighting.


Why do different programming languages get highlighted different? In part because of the of personal aesthetics and opinions of whoever wrote it. For example in Ruby the Type highlight group is used for class names. But it could also have been Function or something else. Why is it Type? Probably because the author thought that it looked better in his or her colour scheme.

But more importantly, the languages have different semantics and sensibilities. In Ruby, self is a special keyword. You can't do self = "foo" or def self(). These are errors. But this is not the case in Python. It's just another variable without any special properties. Doing:

x = Object()
x.foo()

is really "translated" by Python to:

Object.foo(x)

The name self is just convention (almost universally adopted) but you can name it anything you like; def x(this): or def x(xxx): are equally valid. You can also use the name self anywhere you like; self = 'foo' and def self(): are perfectly fine.

I would argue that self shouldn't be highlighted, as it's neither a special keyword, nor a pre-defined variable (like str). There is no trace of the word self in the syntax file, so it looks like the author of it reasoned the same :-)


If you want self highlighted you'll have to create a syntax rule for it:

:syn keyword pythonBuiltin self

The pythonBuiltin group name is already defined in the default syntax file and linked to the Function highlight group. To use a new highlight group, use something like:

:syn keyword pythonSelf self
:highlight def link pythonSelf Special

To make these changes you can't just stick 'em in your vimrc file. The syntax file will override it. Instead you'll need to run it after the syntax file loads, which you can do in two ways:

  1. Use a FileType autocmd:

    augroup python
        autocmd!
        autocmd FileType python
                    \   syn keyword pythonSelf self
                    \ | highlight def link pythonSelf Special
    augroup end
    
  2. Use the after-directory, ~/.vim/after/syntax/python.vim:

    syn keyword pythonSelf self
    highlight def link pythonSelf Special
    

Both methods are effectively the same. Use whichever you prefer.

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.