-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Description
Current problem
The current syntax highlighting system is very slow, and there are noticeable lags when scrolling large C++ files which contain complex syntax elements.
Issues of tree-sitter
Previously, most people suggest something like nvim-treesitter which will analyze source code in a background treesitter process and render keywords in the foreground with text-property.
But is it a good idea? I don't really think so,
at least 4 disadvantages for treesitter solutions:
- power consumption: an extra background job is required, causing less battery life and more carbon dioxide.
- buffer sync: code must be written very carefully to guarantee that the source code in two processes (vim/treesitter) are the same, coc/nvim-treesitter sends the whole buffer to the background every time
changetick
increase to prevent such things, which is a little flaky. - reliability: an external program installed by the user is not reliable enough, they are plenty of issues in version compatibilities and environment misconfig, people need to take extra efforts to get syntax highlighting work.
- poor parser quality: treesitter is a great project, but language parsers are contributed by people all over the world and their quality is not under control (performance issues or inaccurate results in certain languages).
Background syntax highlighter is still immature, there are still many other strange issues in nvim-treesitter:
https://github.com/nvim-treesitter/nvim-treesitter/issues
If we introduce something like this, we shall take all these issues into account.
TextMate grammar system
Syntax highlighting is the most important part of an editor, better not rely on any uncontrollable external programs.
We need some new things that can satisfy such goals below:
- good performance
- robust and reliable
- accuracy
- low power consumption
- native and work in the same process (not require external programs)
And TextMate's grammar engine is really a good candidate which is widely used in many IDE/editors, including vscode (see syntax-highlight-guide for details), sublime and many others.
VS Code uses TextMate grammars as the syntax tokenization engine. Invented for the TextMate editor, they have been adopted by many other editors and IDEs due to the large number of language bundles created and maintained by the Open Source community.
TextMate grammars rely on Oniguruma regular expressions and are typically written as a plist or JSON. You can find a good introduction to TextMate grammars here, and you can take a look at existing TextMate grammars to learn more about how they work.
The grammar can be defined in JSON, that means can be translated into viml or just plain JSON files.
Possible Solution
We can specify which grammar engine to use for the given buffer:
- default engine: current vim's regex grammar
- textmate engine: textmate grammar system.
And some new command can be used to change grammar engine:
:syntax grammar textmate
:syntax grammar default
:syntax load ~/.vim/syntax/cpp.json
for example, the snippet below can be included in the head of syntax files:
if has('textmate')
syntax grammar textmate
syntax load syntax/cpp.json
finish
endif
....
And lots of existing vscode/textmate syntax files can be reused with minimal modification.