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:
Christian Clason
2022-12-12 20:43:14 +01:00
committed by GitHub
parent 3869a2e0cf
commit 54d6a32fbd
3 changed files with 30 additions and 17 deletions

View File

@@ -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
< <

View File

@@ -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>

View File

@@ -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} |