mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	feat(lsp): highlight semantic token modifiers (#21390)
Apply semantic token modifiers as separate extmarks with corresponding highlight groups (e.g., `@readonly`). This is a low-effort PR to enable the most common use cases (applying, e.g., italics or backgrounds on top of type highlights; language-specific fallbacks like `@global.lua` are also available). This can be replaced by more complicated selector-style themes later on.
This commit is contained in:
		| @@ -1340,7 +1340,7 @@ start({bufnr}, {client_id}, {opts})          *vim.lsp.semantic_tokens.start()* | |||||||
|     |vim.lsp.buf_attach_client()|. To opt-out of semantic highlighting with a |     |vim.lsp.buf_attach_client()|. To opt-out of semantic highlighting with a | ||||||
|     server that supports it, you can delete the semanticTokensProvider table |     server that supports it, you can delete the semanticTokensProvider table | ||||||
|     from the {server_capabilities} of your client in your |LspAttach| callback |     from the {server_capabilities} of your client in your |LspAttach| callback | ||||||
|     or your configuration's `on_attach` callback. >lua |     or your configuration's `on_attach` callback: >lua | ||||||
|  |  | ||||||
|        client.server_capabilities.semanticTokensProvider = nil |        client.server_capabilities.semanticTokensProvider = nil | ||||||
| < | < | ||||||
|   | |||||||
| @@ -409,7 +409,17 @@ function STHighlighter:on_win(topline, botline) | |||||||
|             strict = false, |             strict = false, | ||||||
|           }) |           }) | ||||||
|  |  | ||||||
|           --TODO(jdrouhard): do something with the modifiers |           -- TODO(bfredl) use single extmark when hl_group supports table | ||||||
|  |           if #token.modifiers > 0 then | ||||||
|  |             for _, modifier in pairs(token.modifiers) do | ||||||
|  |               api.nvim_buf_set_extmark(self.bufnr, state.namespace, token.line, token.start_col, { | ||||||
|  |                 hl_group = '@' .. modifier, | ||||||
|  |                 end_col = token.end_col, | ||||||
|  |                 priority = vim.highlight.priorities.semantic_tokens, | ||||||
|  |                 strict = false, | ||||||
|  |               }) | ||||||
|  |             end | ||||||
|  |           end | ||||||
|  |  | ||||||
|           token.extmark_added = true |           token.extmark_added = true | ||||||
|         end |         end | ||||||
| @@ -494,7 +504,7 @@ local M = {} | |||||||
| --- opt-out of semantic highlighting with a server that supports it, you can | --- opt-out of semantic highlighting with a server that supports it, you can | ||||||
| --- delete the semanticTokensProvider table from the {server_capabilities} of | --- delete the semanticTokensProvider table from the {server_capabilities} of | ||||||
| --- your client in your |LspAttach| callback or your configuration's | --- your client in your |LspAttach| callback or your configuration's | ||||||
| --- `on_attach` callback. | --- `on_attach` callback: | ||||||
| --- <pre>lua | --- <pre>lua | ||||||
| ---   client.server_capabilities.semanticTokensProvider = nil | ---   client.server_capabilities.semanticTokensProvider = nil | ||||||
| --- </pre> | --- </pre> | ||||||
|   | |||||||
| @@ -69,9 +69,12 @@ describe('semantic token highlighting', function() | |||||||
|         [4] = { bold = true, foreground = Screen.colors.SeaGreen }; |         [4] = { bold = true, foreground = Screen.colors.SeaGreen }; | ||||||
|         [5] = { foreground = tonumber('0x6a0dad') }; |         [5] = { foreground = tonumber('0x6a0dad') }; | ||||||
|         [6] = { foreground = Screen.colors.Blue1 }; |         [6] = { foreground = Screen.colors.Blue1 }; | ||||||
|  |         [7] = { bold = true, foreground = Screen.colors.DarkCyan }; | ||||||
|  |         [8] = { bold = true, foreground = Screen.colors.SlateBlue }; | ||||||
|       } |       } | ||||||
|       command([[ hi link @namespace Type ]]) |       command([[ hi link @namespace Type ]]) | ||||||
|       command([[ hi link @function Special ]]) |       command([[ hi link @function Special ]]) | ||||||
|  |       command([[ hi @declaration gui=bold ]]) | ||||||
|  |  | ||||||
|       exec_lua(create_server_definition) |       exec_lua(create_server_definition) | ||||||
|       exec_lua([[ |       exec_lua([[ | ||||||
| @@ -107,9 +110,9 @@ describe('semantic token highlighting', function() | |||||||
|       screen:expect { grid = [[ |       screen:expect { grid = [[ | ||||||
|         #include <iostream>                     | |         #include <iostream>                     | | ||||||
|                                                 | |                                                 | | ||||||
|         int {3:main}()                              | |         int {8:main}()                              | | ||||||
|         {                                       | |         {                                       | | ||||||
|             int {2:x};                              | |             int {7:x};                              | | ||||||
|         #ifdef {5:__cplusplus}                      | |         #ifdef {5:__cplusplus}                      | | ||||||
|             {4:std}::{2:cout} << {2:x} << "\n";             | |             {4:std}::{2:cout} << {2:x} << "\n";             | | ||||||
|         {6:#else}                                   | |         {6:#else}                                   | | ||||||
| @@ -199,9 +202,9 @@ describe('semantic token highlighting', function() | |||||||
|       screen:expect { grid = [[ |       screen:expect { grid = [[ | ||||||
|         #include <iostream>                     | |         #include <iostream>                     | | ||||||
|                                                 | |                                                 | | ||||||
|         int {3:main}()                              | |         int {8:main}()                              | | ||||||
|         {                                       | |         {                                       | | ||||||
|             int {2:x};                              | |             int {7:x};                              | | ||||||
|         #ifdef {5:__cplusplus}                      | |         #ifdef {5:__cplusplus}                      | | ||||||
|             {4:std}::{2:cout} << {2:x} << "\n";             | |             {4:std}::{2:cout} << {2:x} << "\n";             | | ||||||
|         {6:#else}                                   | |         {6:#else}                                   | | ||||||
| @@ -228,9 +231,9 @@ describe('semantic token highlighting', function() | |||||||
|       screen:expect { grid = [[ |       screen:expect { grid = [[ | ||||||
|         #include <iostream>                     | |         #include <iostream>                     | | ||||||
|                                                 | |                                                 | | ||||||
|         int {3:main}()                              | |         int {8:main}()                              | | ||||||
|         {                                       | |         {                                       | | ||||||
|             int {2:x};                              | |             int {7:x};                              | | ||||||
|         #ifdef {5:__cplusplus}                      | |         #ifdef {5:__cplusplus}                      | | ||||||
|             {4:std}::{2:cout} << {2:x} << "\n";             | |             {4:std}::{2:cout} << {2:x} << "\n";             | | ||||||
|         {6:#else}                                   | |         {6:#else}                                   | | ||||||
| @@ -251,9 +254,9 @@ describe('semantic token highlighting', function() | |||||||
|       screen:expect { grid = [[ |       screen:expect { grid = [[ | ||||||
|         #include <iostream>                     | |         #include <iostream>                     | | ||||||
|                                                 | |                                                 | | ||||||
|         int {3:main}()                              | |         int {8:main}()                              | | ||||||
|         {                                       | |         {                                       | | ||||||
|             int {2:x};                              | |             int {7:x};                              | | ||||||
|         #ifdef {5:__cplusplus}                      | |         #ifdef {5:__cplusplus}                      | | ||||||
|             {4:std}::{2:cout} << {2:x} << "\n";             | |             {4:std}::{2:cout} << {2:x} << "\n";             | | ||||||
|         {6:#else}                                   | |         {6:#else}                                   | | ||||||
| @@ -309,9 +312,9 @@ describe('semantic token highlighting', function() | |||||||
|       screen:expect { grid = [[ |       screen:expect { grid = [[ | ||||||
|         #include <iostream>                     | |         #include <iostream>                     | | ||||||
|                                                 | |                                                 | | ||||||
|         int {3:main}()                              | |         int {8:main}()                              | | ||||||
|         {                                       | |         {                                       | | ||||||
|             ^int {3:x}();                            | |             ^int {8:x}();                            | | ||||||
|         #ifdef {5:__cplusplus}                      | |         #ifdef {5:__cplusplus}                      | | ||||||
|             {4:std}::{2:cout} << {3:x} << "\n";             | |             {4:std}::{2:cout} << {3:x} << "\n";             | | ||||||
|         {6:#else}                                   | |         {6:#else}                                   | | ||||||
| @@ -489,9 +492,9 @@ describe('semantic token highlighting', function() | |||||||
|       screen:expect { grid = [[ |       screen:expect { grid = [[ | ||||||
|         #include <iostream>                     | |         #include <iostream>                     | | ||||||
|                                                 | |                                                 | | ||||||
|         int {3:main}()                              | |         int {8:main}()                              | | ||||||
|         {                                       | |         {                                       | | ||||||
|             int {2:x};                              | |             int {7:x};                              | | ||||||
|         #ifdef {5:__cplusplus}                      | |         #ifdef {5:__cplusplus}                      | | ||||||
|             {4:std}::{2:cout} << {2:x} << "\n";             | |             {4:std}::{2:cout} << {2:x} << "\n";             | | ||||||
|         {6:#else}                                   | |         {6:#else}                                   | | ||||||
| @@ -513,9 +516,9 @@ describe('semantic token highlighting', function() | |||||||
|       screen:expect { grid = [[ |       screen:expect { grid = [[ | ||||||
|         #include <iostream>                     | |         #include <iostream>                     | | ||||||
|                                                 | |                                                 | | ||||||
|         int {3:main}()                              | |         int {8:main}()                              | | ||||||
|         {                                       | |         {                                       | | ||||||
|             ^int {2:x}();                            | |             ^int {7:x}();                            | | ||||||
|         #ifdef {5:__cplusplus}                      | |         #ifdef {5:__cplusplus}                      | | ||||||
|             {4:std}::{2:cout} << {2:x} << "\n";             | |             {4:std}::{2:cout} << {2:x} << "\n";             | | ||||||
|         {6:#else}                                   | |         {6:#else}                                   | | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Christian Clason
					Christian Clason