local helpers = require('test.functional.helpers')(after_each)
local lsp_helpers = require('test.functional.plugin.lsp.helpers')
local Screen = require('test.functional.ui.screen')
local command = helpers.command
local dedent = helpers.dedent
local eq = helpers.eq
local exec_lua = helpers.exec_lua
local feed = helpers.feed
local feed_command = helpers.feed_command
local insert = helpers.insert
local matches = helpers.matches
local clear_notrace = lsp_helpers.clear_notrace
local create_server_definition = lsp_helpers.create_server_definition
before_each(function()
clear_notrace()
end)
after_each(function()
exec_lua("vim.api.nvim_exec_autocmds('VimLeavePre', { modeline = false })")
end)
describe('semantic token highlighting', function()
describe('general', function()
local text = dedent([[
#include <iostream>
int main()
{
int x;
#ifdef __cplusplus
std::cout << x << "\n";
#else
printf("%d\n", x);
#endif
}
}]])
local legend = [[{
"tokenTypes": [
"variable", "variable", "parameter", "function", "method", "function", "property", "variable", "class", "interface", "enum", "enumMember", "type", "type", "unknown", "namespace", "typeParameter", "concept", "type", "macro", "comment"
],
"tokenModifiers": [
"declaration", "deprecated", "deduced", "readonly", "static", "abstract", "virtual", "dependentName", "defaultLibrary", "usedAsMutableReference", "functionScope", "classScope", "fileScope", "globalScope"
]
}]]
local response = [[{
"data": [ 2, 4, 4, 3, 8193, 2, 8, 1, 1, 1025, 1, 7, 11, 19, 8192, 1, 4, 3, 15, 8448, 0, 5, 4, 0, 8448, 0, 8, 1, 1, 1024, 1, 0, 5, 20, 0, 1, 0, 22, 20, 0, 1, 0, 6, 20, 0 ],
"resultId": 1
}]]
local edit_response = [[{
"edits": [ {"data": [ 2, 8, 1, 3, 8193, 1, 7, 11, 19, 8192, 1, 4, 3, 15, 8448, 0, 5, 4, 0, 8448, 0, 8, 1, 3, 8192 ], "deleteCount": 25, "start": 5 } ],
"resultId":"2"
}]]
local screen
before_each(function()
screen = Screen.new(40, 16)
screen:attach()
screen:set_default_attr_ids {
[1] = { bold = true, foreground = Screen.colors.Blue1 };
[2] = { foreground = Screen.colors.DarkCyan };
[3] = { foreground = Screen.colors.SlateBlue };
[4] = { bold = true, foreground = Screen.colors.SeaGreen };
[5] = { foreground = tonumber('0x6a0dad') };
[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 @function Special ]])
command([[ hi @declaration gui=bold ]])
exec_lua(create_server_definition)
exec_lua([[
local legend, response, edit_response = ...
server = _create_server({
capabilities = {
semanticTokensProvider = {
full = { delta = true },
legend = vim.fn.json_decode(legend),
},
},
handlers = {
['textDocument/semanticTokens/full'] = function()
return vim.fn.json_decode(response)
end,
['textDocument/semanticTokens/full/delta'] = function()
return vim.fn.json_decode(edit_response)
end,
}
})
]], legend, response, edit_response)
end)
it('buffer is highlighted when attached', function()
exec_lua([[
bufnr = vim.api.nvim_get_current_buf()
vim.api.nvim_win_set_buf(0, bufnr)
client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd })
]])
insert(text)
screen:expect { grid = [[
#include <iostream> |
|
int {8:main}() |
{ |
int {7:x}; |
#ifdef {5:__cplusplus} |
{4:std}::{2:cout} << {2:x} << "\n"; |
{6:#else} |
{6: printf("%d\n", x);} |
{6:#endif} |
} |
^} |
{1:~ }|
{1:~ }|
{1:~ }|
|
]] }
end)
it('buffer is unhighlighted when client is detached', function()
exec_lua([[
bufnr = vim.api.nvim_get_current_buf()
vim.api.nvim_win_set_buf(0, bufnr)
client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd })
]])
insert(text)
exec_lua([[
vim.notify = function() end
vim.lsp.buf_detach_client(bufnr, client_id)
]])
screen:expect { grid = [[
#include <iostream> |
|
int main() |
{ |
int x; |
#ifdef __cplusplus |
std::cout << x << "\n"; |
#else |
printf("%d\n", x); |
#endif |
} |
^} |
{1:~ }|
{1:~ }|
{1:~ }|
|
]] }
end)
it('buffer is highlighted and unhighlighted when semantic token highlighting is started and stopped'
, function()
exec_lua([[
bufnr = vim.api.nvim_get_current_buf()
vim.api.nvim_win_set_buf(0, bufnr)
client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd })
]])
insert(text)
exec_lua([[
vim.notify = function() end
vim.lsp.semantic_tokens.stop(bufnr, client_id)
]])
screen:expect { grid = [[
#include <iostream> |
|
int main() |
{ |
int x; |
#ifdef __cplusplus |
std::cout << x << "\n"; |
#else |
printf("%d\n", x); |
#endif |
} |
^} |
{1:~ }|
{1:~ }|
{1:~
|