jackguo380 / vim-lsp-cxx-highlight

Vim plugin for C/C++/ObjC semantic highlighting using cquery, ccls, or clangd
MIT License
340 stars 26 forks source link

Using rainbow highlighting? I don't know how. #28

Open sapient-cogbag opened 4 years ago

sapient-cogbag commented 4 years ago

Is there any way to make this plugin use rainbow highlighting?

I use ccls and vim-lsp. The relevant parts of config are as follows:

" let g:lsp_semantic_enabled = 1
let g:lsp_cxx_hl_use_text_props = 1

" per-buffer stuff ^.^
function! s:on_lsp_buffer_enabled() abort
    "setlocal omnifunc=lsp#complete
    setlocal signcolumn=yes
    nmap <buffer> <leader>d <plug>(lsp-definition)
    nmap <buffer> <leader>r <plug>(lsp-rename)
    " refer to doc to add more commands
endfunction

" does what it says nya
augroup lsp_install
    au!
    " call s:on_lsp_buffer_enabled only for languages that has the server registered.
    autocmd User lsp_buffer_enabled call s:on_lsp_buffer_enabled()
augroup END

" Enable highlighting other uses of the hovered symbol nya
let g:lsp_highlight_references_enabled = 1

" Register the ccls language server :)
" nya
" Gotta fiddle around for rainbow highlights ^.^ nya

" Register ccls C++ lanuage server.
" This also gives rainbow highlighting
" Note we had to use: https://github.com/MaskRay/ccls/wiki/Visual-Studio-Code
" to deduce the actual associated options nyaa
if executable('ccls')
    au User lsp_setup call lsp#register_server({
        \'name': 'ccls',
        \'cmd': {server_info->['ccls']},
        \'root_uri': {server_info->lsp#utils#path_to_uri(lsp#utils#find_nearest_parent_file_directory(lsp#utils#get_buffer_path(), 'compile_commands.json'))},
        \'initialization_options': {
            \'cache': {
                \'directory': '/tmp/ccls/cache' 
            \},
            \'highlight': {
                \'function':{'face': 'enabled'}, 
                \'type':{'face':'enabled'}, 
                \'variable':{'face':'enabled'},
                \'lsRanges': v:true
            \} 
        \},
        \'whitelist': ['c', 'cpp', 'objc', 'objcpp', 'cc'],
    \})
endif

" AUTOCOMPLETION
" See: https://github.com/prabirshrestha/asyncomplete.vim

" Enable preview:
set completeopt+=preview

" Close preview on completion done nyaa
autocmd! CompleteDone * if pumvisible() == 0 | pclose | endif

" Stop other in-directory vimrcs running autocmd and/or writing files
" automatically, etc.

In the file (with removed comments and includes):


namespace brnn::net {

    class test {
    };

    static test a;
}

We get...

Debug Dump Symbols
0: id = 6989 parentKind = Unknown kind = Namespace storage = None
1: id = 15105 parentKind = Namespace kind = Variable storage = Static
2: id = 8471 parentKind = Namespace kind = Class storage = None
3: id = 0 parentKind = Unknown kind = Namespace storage = None
End of Debug Dump Symbols

from :LspCxxHlDumpSyms

I have the logs in case they are useful (added with the bug report guidelines even though this isn't a bug report)

Sat 16 May 2020 03:23:07 BST: lsp_cxx_hl beginning initialization...
Sat 16 May 2020 03:23:07 BST: vim-lsp successfully registered
Sat 16 May 2020 03:23:07 BST: LanguageClient-neovim not detected
Sat 16 May 2020 03:23:07 BST: coc.nvim not detected
Sat 16 May 2020 03:23:07 BST: Not registering nvim-lsp as this is not Neovim
Sat 16 May 2020 03:23:24 BST: Skipped Message: 
Sat 16 May 2020 03:23:24 BST: Received Message: $ccls/publishSkippedRanges
Sat 16 May 2020 03:23:24 BST: textprop notify skipped regions for /home/<usr>/repos/br-nn/src/brnn/net/addressing.cpp
Sat 16 May 2020 03:23:24 BST: operation notify_skipped /home/<usr>/repos/br-nn/src/brnn/net/addressing.cpp took   0.000553s to complete
Sat 16 May 2020 03:23:24 BST: Received Message: $ccls/publishSemanticHighlight
Sat 16 May 2020 03:23:24 BST: textprop notify symbols for /home/<usr>/repos/br-nn/src/brnn/net/addressing.cpp
Sat 16 May 2020 03:23:24 BST: operation notify_symbols /home/<usr>/repos/br-nn/src/brnn/net/addressing.cpp took   0.001575s to complete
Sat 16 May 2020 03:23:24 BST: Skipped Message: 
Sat 16 May 2020 03:23:24 BST: hl_symbols (textprop) highlighted 4 symbols in file /home/<usr>/repos/br-nn/src/brnn/net/addressing.cpp
Sat 16 May 2020 03:23:24 BST: operation hl_symbols (textprop) /home/<usr>/repos/br-nn/src/brnn/net/addressing.cpp took   0.001817s to complete
Sat 16 May 2020 03:23:24 BST: Received Message: $ccls/publishSemanticHighlight
Sat 16 May 2020 03:23:24 BST: textprop notify symbols for /home/<usr>/repos/br-nn/src/brnn/net/addressing.cpp
Sat 16 May 2020 03:23:24 BST: operation notify_symbols /home/<usr>/repos/br-nn/src/brnn/net/addressing.cpp took   0.000513s to complete
Sat 16 May 2020 03:23:24 BST: hl_symbols (textprop) highlighted 4 symbols in file /home/<usr>/repos/br-nn/src/brnn/net/addressing.cpp
Sat 16 May 2020 03:23:24 BST: operation hl_symbols (textprop) /home/<usr>/repos/br-nn/src/brnn/net/addressing.cpp took   0.001215s to complete
Sat 16 May 2020 03:23:25 BST: Skipped Message: textDocument/publishDiagnostics
Sat 16 May 2020 03:25:26 BST: Skipped Message: 
jackguo380 commented 4 years ago

Hi, I know that ccls' vscode extension supports it but currently vim-lsp-cxx-highlight does not support rainbow highlighting. Rainbow highlighting is actually fairly challenging to support with the way vim's highlighting system works. Since highlighting relies on using named highlight groups rather than simply a hex/RGB value it would require a large number of highlight groups to be defined. This may or may not have a performance penalty.

I do have a couple of ideas on how it might be implemented but I have yet to try them out. For now I'll just keep this open until I either figure out a solution or decide it cannot be done.

sapient-cogbag commented 4 years ago

Yeah.

The way semantic-highlighting does it is you give it a list of colours and it generates that number of highlight groups and uses them. I'm using that at the moment (until a better solution comes about, e.g. LSP clients or this plugin, becoming able to use these protocols nya) and it doesn't cause any particular performance issues at about 40-something colours.

I'd do it by generating a few hundred or more rainbow colours (as the user specified them e.g. in terms of brightness or sets of ranges of each component or something), then use those with however the ccls and the other ones' colour protocols send back colours - mapping the sent colours or colour-identifiers to your own generated rainbow colours.

A further suggestion, if the ccls and similar protocols send back colours intelligently (rather than just colour identifiers, or randomly) - i.e. ensuring good contrast in a given region of code or something nya - then you could order those colours in such a way that their contrast is similar to that provided by the protocol though in the past 10 minutes i haven't thought of a particularly performant algorithm for doing so.

jackguo380 commented 4 years ago

I was thinking of something along those lines, there are still a few implementation challenges to make sure it is fast to look up the highlight groups since you would need around 10-20 groups for each existing group so there would be around probably 50 different highlight groups.

Note that ccls and other semantic highlighting protocols have no concept of color values. All of them are centered around identifying what a kind a token is (Whether it is a function, variable, or type). Then it is up to the editor (vim, vscode, etc) to give the token a suitable color based on the current color scheme. If you change your colorscheme in vim you will notice that vim-lsp-cxx-highlight will use the colors from that.

For the contrast suggestion, I can see how it might be useful in some cases but the implementation would likely have massive runtime complexity/cost due to all the comparsions and lookups. The ccls vscode extension implements the rainbow highlighting using the id parameter you see in Dump Symbols (my implemention would probably use it as well). This id decides what color is used and is generated via hashing various information on the token making it pseudo-random. If your colors are fairly unique I think the randomness of the id would result in a fairly even distribution of colors so the contrast should be fairly good anyways.