My C++ language server ccls implements a semantic highlightingfeatures through the non-standard messages$ccls/publishSemanticHighlight
and$ccls/publishSkippedRanges
, supported by both emacs-cclsand vscode-ccls.
For years, my primary editor was Emacs. In 2018, I created emacs-ccls(a fork of emacs-cquery) and enjoyed its rainbow semantic highlighting.My setup also relied heavily on two features:
1 | (setq ccls-sem-highlight-method 'font-lock) |
My elisp skills have gotten a bit rusty since I haven't been codingin it for a while. Switching to Neovim presented a challenge: it lackedthe rainbow highlighting I loved.
Thankfully, Neovim supports "semantic tokens" from LSP 3.16, astandardized approach adopted by many editors.
I've made changes to ccls (available on abranch) to support semantic tokens. This basically adapts the$ccls/publishSemanticHighlight
code to supporttextDocument/semanticTokens/full
andtextDocument/semanticTokens/range
.
While semantic tokens do not differentiate symbols, we can definecustom modifiers to achieve similar results.
1 | tokenModifiers: { |
ccls assigns the same modifier ID to tokens belonging to the samesymbol. For different symbols, it attempts to assign unique IDs. Whilewe have only 10 predefined IDs (each linked to a specific color),there's a chance that two symbols might share the same ID. However, thisis uncommon and generally acceptable.
For a token with type variable
, Neovim's built-in LSPplugin assigns it a highlight group@lsp.typemod.variable.id$i.cpp
where $i
is aninteger between 0 and 9. We can customize a foreground color for eachmodifier ID. The complete Lua code follows:
1 | local func_colors = { |
Using this setup, let's examine the C++ code above:
This is quite appealing, but I need assistance to get code lensworking.
When this feature branch is merged, Emacs users can just remove thefollowing two lines:
1 | (setq ccls-sem-highlight-method 'font-lock) |
TODO: How to change lsp-semantic-token-modifier-faces
tosupport rainbow semantic tokens in lsp-mode and emacs-ccls?
Help is needed to remove $ccls/publishSemanticHighlight
to use the built-in semantic tokens support. Unfortunately, vscode-cclsis not actively maintained, and I lack the expertise to maintain theplugin of an editor I do not commonly use.