Python syntax highlighting for Vim that understands type annotations.
Vim's built-in Python syntax has no notion of annotations: ->, list[int]
and Optional[User] are colored like any other code, and str looks the same
in name: str as in str(x). This plugin replaces syntax/python.vim with
one that colors types only where they are types: parameter and return
annotations, x: T and self.attr: T, class bases, and PEP 695 type
parameters and type aliases.
- Return arrows, generics (
dict[str, list[int]]), unions (X | Y) and forward references ("User") inside annotations list(...)in regular code stays a builtin, andkey: valuelines in a multi-line dict or call are not mistaken for annotations|is a union only inside a type; elsewhere it is the bitwise operatortypingnames (Optional,Callable,Annotated,Protocol,TypeIs, ...) and user types (User,T) inside annotations- Python 3.12 type parameters and aliases:
def f[T](x: T) -> T:,type Point = tuple[int, int] # type: intcomments (# type: ignorestays a plain comment)- Docstrings, including after wrapped signatures and comment lines
- f-strings (including
f"{x=}"),match/case,except* - An optional color palette for the new groups (see below)
By default every group is linked to a standard group (Type, Operator,
String, ...), so your colorscheme decides the colors, as in the screenshot
above. The plugin also has its own palette, which you can turn on with:
let g:python_enhanced_colors = 1| Element | Palette color | Highlight group |
|---|---|---|
| Class names | Cyan | pythonClass |
Optional, Callable, Generic, etc. |
Orange | pythonTypingType |
str, int, bool, list, dict in annotations |
Blue | pythonPrimitiveType |
-> and | (union) |
Magenta | pythonReturnArrow, pythonTypeUnion |
Builtins in code (print, len, str(...)) |
Lavender | pythonBuiltin |
| Docstrings | Green | pythonDocstring |
User types in annotations (User, T) |
colorscheme Type |
pythonTypeName |
self, cls |
colorscheme Identifier |
pythonClassVar |
Plug 'aaronbcarlisle/python-syntax-enhanced'Plugin 'aaronbcarlisle/python-syntax-enhanced'git clone https://github.com/aaronbcarlisle/python-syntax-enhanced.git \
~/.vim/pack/plugins/start/python-syntax-enhancedOn Windows, use ~/vimfiles/pack/plugins/start/python-syntax-enhanced.
Run :helptags ALL once afterwards to enable :help python-syntax-enhanced.
{ "aaronbcarlisle/python-syntax-enhanced" }Tested in CI on Vim 9.1 (Linux), Vim 9.2 (macOS, Windows) and Neovim 0.12.
It replaces Vim's built-in syntax/python.vim, so disable other Python syntax
plugins (see Troubleshooting).
In Neovim this is a regular syntax file: it applies when Python is highlighted by the syntax engine (Neovim's default). If Tree-sitter highlighting is enabled for Python, the plugin does not load.
Options are read when a Python buffer's syntax is loaded, so set them in your
vimrc (after changing one, reopen the file with :e).
" Enable all features
let g:python_enhanced_highlight_all = 1Or configure individually:
let g:python_highlight_type_annotations = 1 " Type annotations (default: 1)
let g:python_highlight_operators = 1 " Operators (default: 1)
let g:python_highlight_func_calls = 1 " Function calls (default: 0)
let g:python_highlight_class_vars = 1 " self, cls (default: 1)
let g:python_highlight_builtins = 1 " Builtins (default: 1)
let g:python_highlight_exceptions = 1 " Exceptions (default: 1)
let g:python_highlight_string_formatting = 1 " String formatting (default: 1)
let g:python_highlight_doctests = 1 " Doctests (default: 1)
let g:python_highlight_space_errors = 0 " Space errors (default: 0)
let g:python_enhanced_colors = 1 " Built-in palette (default: 0)For large files:
let g:python_slow_sync = 1 " syntax sync fromstartType colors apply inside these positions only; everywhere else the same names keep their normal highlighting:
def find[T](items: list[T], key: Callable[[T], str] | None = None) -> T | None: ...
class Stack(Generic[T], Protocol): ...
users: dict[str, "User"] = {}
self._items: list[T] = []
type Pair[K] = tuple[K, K]
x = [] # type: list[int]To change single colors, override the groups in your vimrc after your
colorscheme (with the palette on, a later :colorscheme re-applies it):
Brackets, commas and colons inside annotations are not colored, like the rest
of Python's punctuation. To color them, link pythonTypeBracket,
pythonTypeComma, pythonTypeColon, pythonParams or pythonDefColon, e.g.
hi link pythonTypeBracket Delimiter.
" Example: Make typing types cyan instead of orange
hi pythonTypingType ctermfg=44 guifg=#00d7d7
" Example: Make primitives yellow
hi pythonPrimitiveType ctermfg=220 guifg=#ffd700:PythonSyntaxEnableAll- Enable all highlighting features and reload syntax in the current Python buffer:PythonSyntaxInfo- Show current configuration
Syntax breaks in long files:
let g:python_slow_sync = 1Manual resync:
:syntax sync fromstart
" Or add a mapping:
nnoremap <leader>ss :syntax sync fromstart<CR>Old syntax file interfering:
Disable other Python syntax plugins (like vim-python/python-syntax). If one
of them wins the runtimepath lookup, this plugin clears it and loads its own
syntax/python.vim on FileType python, so the other one is loaded for nothing.
- Types are recognized by position, not by analysis: any name inside an
annotation is colored as a type, and
typingnames are matched by name. - Statement annotations (
x: int = 1) are recognized at the start of a line only, not after;. - The file replaces Vim's
syntax/python.vim, whosepython_no_*_highlightoptions are not read (python_highlight_allis).
Visual fixture:
tests/test_highlighting.py
Automated checks (synID assertions plus a syntax-loading test), run in CI on every push and PR:
sh tests/run.sh # uses vim
VIM_BIN=/path/to/vim sh tests/run.shSee AUTHORS for full attribution.
- Vim's built-in Python syntax (Zvezdan Petkovic)
- vim-python/python-syntax (for inspiration)
- Python typing PEPs (484, 526, 544, 585, 604, 612, 673, 695, 742)
