refactor(lsp): rename vim.lsp.semantic_tokens start/stop to enable()

This commit is contained in:
Yi Ming
2025-07-07 11:58:44 +08:00
parent a8d9f3331e
commit 7e8aa0585e
6 changed files with 103 additions and 102 deletions

View File

@ -35,6 +35,8 @@ LSP
`vim.wo.conceallevel = 2`.
• *vim.lsp.log.should_log()* Use |vim.lsp.log.set_format_func()| instead
and return `nil` to omit entries from the logfile.
• *vim.lsp.semantic_tokens.start()* Use `vim.lsp.semantic_tokens.enable(true)` instead
• *vim.lsp.semantic_tokens.stop()* Use `vim.lsp.semantic_tokens.enable(false)` instead
LUA

View File

@ -2162,11 +2162,25 @@ is_enabled({filter}) *vim.lsp.inlay_hint.is_enabled()*
==============================================================================
Lua module: vim.lsp.semantic_tokens *lsp-semantic_tokens*
enable({enable}, {filter}) *vim.lsp.semantic_tokens.enable()*
Enables or disables semantic tokens for the {filter}ed scope.
To "toggle", pass the inverse of `is_enabled()`: >lua
vim.lsp.semantic_tokens.enable(not vim.lsp.semantic_tokens.is_enabled())
<
Parameters: ~
• {enable} (`boolean?`) true/nil to enable, false to disable
• {filter} (`table?`) A table with the following fields:
• {bufnr}? (`integer`) Buffer number, or 0 for current
buffer, or nil for all.
• {client_id}? (`integer`) Client ID, or nil for all
force_refresh({bufnr}) *vim.lsp.semantic_tokens.force_refresh()*
Force a refresh of all semantic tokens
Only has an effect if the buffer is currently active for semantic token
highlighting (|vim.lsp.semantic_tokens.start()| has been called for it)
highlighting (|vim.lsp.semantic_tokens.enable()| has been called for it)
Parameters: ~
• {bufnr} (`integer?`) filter by buffer. All buffers if nil, current
@ -2215,38 +2229,14 @@ highlight_token({token}, {bufnr}, {client_id}, {hl_group}, {opts})
`vim.hl.priorities.semantic_tokens + 3`) Priority for
the applied extmark.
start({bufnr}, {client_id}, {opts}) *vim.lsp.semantic_tokens.start()*
Start the semantic token highlighting engine for the given buffer with the
given client. The client must already be attached to the buffer.
NOTE: This is currently called automatically by
|vim.lsp.buf_attach_client()|. To opt-out of semantic highlighting with a
server that supports it, you can delete the semanticTokensProvider table
from the {server_capabilities} of your client in your |LspAttach| callback
or your configuration's `on_attach` callback: >lua
client.server_capabilities.semanticTokensProvider = nil
<
is_enabled({filter}) *vim.lsp.semantic_tokens.is_enabled()*
Query whether semantic tokens is enabled in the {filter}ed scope
Parameters: ~
• {bufnr} (`integer`) Buffer number, or `0` for current buffer
• {client_id} (`integer`) The ID of the |vim.lsp.Client|
• {opts} (`table?`) Optional keyword arguments
• debounce (integer, default: 200): Debounce token
requests to the server by the given number in
milliseconds
stop({bufnr}, {client_id}) *vim.lsp.semantic_tokens.stop()*
Stop the semantic token highlighting engine for the given buffer with the
given client.
NOTE: This is automatically called by a |LspDetach| autocmd that is set up
as part of `start()`, so you should only need this function to manually
disengage the semantic token engine without fully detaching the LSP client
from the buffer.
Parameters: ~
• {bufnr} (`integer`) Buffer number, or `0` for current buffer
• {client_id} (`integer`) The ID of the |vim.lsp.Client|
• {filter} (`table?`) A table with the following fields:
• {bufnr}? (`integer`) Buffer number, or 0 for current
buffer, or nil for all.
• {client_id}? (`integer`) Client ID, or nil for all
==============================================================================

View File

@ -84,6 +84,8 @@ LSP
• `root_markers` in |vim.lsp.Config| can now be ordered by priority.
• The function set with |vim.lsp.log.set_format_func()| is now given all
arguments corresponding to a log entry instead of the individual arguments.
• `vim.lsp.semantic_tokens.start/stop` now renamed to
`vim.lsp.semantic_tokens.enable`
LUA

View File

@ -1077,7 +1077,7 @@ function Client:on_attach(bufnr)
-- opt-out (deleting the semanticTokensProvider from capabilities)
vim.schedule(function()
if vim.tbl_get(self.server_capabilities, 'semanticTokensProvider', 'full') then
lsp.semantic_tokens.start(bufnr, self.id)
lsp.semantic_tokens._start(bufnr, self.id)
end
if vim.tbl_get(self.server_capabilities, 'foldingRangeProvider') then
lsp._folding_range._setup(bufnr)

View File

@ -7,6 +7,8 @@ local uv = vim.uv
local Capability = require('vim.lsp._capability')
local M = {}
--- @class (private) STTokenRange
--- @field line integer line number 0-based
--- @field start_col integer start column 0-based
@ -194,11 +196,13 @@ function STHighlighter:new(bufnr)
if not highlighter then
return true
end
highlighter:on_change()
if M.is_enabled({ bufnr = buf }) then
highlighter:on_change()
end
end,
on_reload = function(_, buf)
local highlighter = STHighlighter.active[buf]
if highlighter then
if highlighter and M.is_enabled({ bufnr = bufnr }) then
highlighter:reset()
highlighter:send_request()
end
@ -209,7 +213,9 @@ function STHighlighter:new(bufnr)
buffer = self.bufnr,
group = self.augroup,
callback = function()
self:send_request()
if M.is_enabled({ bufnr = bufnr }) then
self:send_request()
end
end,
})
@ -582,7 +588,25 @@ function STHighlighter:reset_timer()
end
end
local M = {}
---@param bufnr (integer) Buffer number, or `0` for current buffer
---@param client_id (integer) The ID of the |vim.lsp.Client|
---@param debounce? (integer) (default: 200): Debounce token requests
--- to the server by the given number in milliseconds
function M._start(bufnr, client_id, debounce)
local highlighter = STHighlighter.active[bufnr]
if not highlighter then
highlighter = STHighlighter:new(bufnr)
highlighter.debounce = debounce or 200
else
highlighter.debounce = debounce or highlighter.debounce
end
highlighter:on_attach(client_id)
if M.is_enabled({ bufnr = bufnr }) then
highlighter:send_request()
end
end
--- Start the semantic token highlighting engine for the given buffer with the
--- given client. The client must already be attached to the buffer.
@ -597,12 +621,14 @@ local M = {}
--- client.server_capabilities.semanticTokensProvider = nil
--- ```
---
---@deprecated
---@param bufnr (integer) Buffer number, or `0` for current buffer
---@param client_id (integer) The ID of the |vim.lsp.Client|
---@param opts? (table) Optional keyword arguments
--- - debounce (integer, default: 200): Debounce token requests
--- to the server by the given number in milliseconds
function M.start(bufnr, client_id, opts)
vim.deprecate('vim.lsp.semantic_tokens.start', 'vim.lsp.semantic_tokens.enable(true)', '0.13.0')
vim.validate('bufnr', bufnr, 'number')
vim.validate('client_id', client_id, 'number')
@ -633,17 +659,7 @@ function M.start(bufnr, client_id, opts)
return
end
local highlighter = STHighlighter.active[bufnr]
if not highlighter then
highlighter = STHighlighter:new(bufnr)
highlighter.debounce = opts.debounce or 200
else
highlighter.debounce = math.max(highlighter.debounce, opts.debounce or 200)
end
highlighter:on_attach(client_id)
highlighter:send_request()
M._start(bufnr, client_id, opts.debounce)
end
--- Stop the semantic token highlighting engine for the given buffer with the
@ -653,9 +669,11 @@ end
--- of `start()`, so you should only need this function to manually disengage the semantic
--- token engine without fully detaching the LSP client from the buffer.
---
---@deprecated
---@param bufnr (integer) Buffer number, or `0` for current buffer
---@param client_id (integer) The ID of the |vim.lsp.Client|
function M.stop(bufnr, client_id)
vim.deprecate('vim.lsp.semantic_tokens.stop', 'vim.lsp.semantic_tokens.enable(false)', '0.13.0')
vim.validate('bufnr', bufnr, 'number')
vim.validate('client_id', client_id, 'number')
@ -673,6 +691,37 @@ function M.stop(bufnr, client_id)
end
end
--- Query whether semantic tokens is enabled in the {filter}ed scope
---@param filter? vim.lsp.enable.Filter
function M.is_enabled(filter)
return util._is_enabled('semantic_tokens', filter)
end
--- Enables or disables semantic tokens for the {filter}ed scope.
---
--- To "toggle", pass the inverse of `is_enabled()`:
---
--- ```lua
--- vim.lsp.semantic_tokens.enable(not vim.lsp.semantic_tokens.is_enabled())
--- ```
---
---@param enable? boolean true/nil to enable, false to disable
---@param filter? vim.lsp.enable.Filter
function M.enable(enable, filter)
util._enable('semantic_tokens', enable, filter)
for _, bufnr in ipairs(api.nvim_list_bufs()) do
local highlighter = STHighlighter.active[bufnr]
if highlighter then
if M.is_enabled({ bufnr = bufnr }) then
highlighter:send_request()
else
highlighter:reset()
end
end
end
end
--- @nodoc
--- @class STTokenRangeInspect : STTokenRange
--- @field client_id integer
@ -736,7 +785,7 @@ end
--- Force a refresh of all semantic tokens
---
--- Only has an effect if the buffer is currently active for semantic token
--- highlighting (|vim.lsp.semantic_tokens.start()| has been called for it)
--- highlighting (|vim.lsp.semantic_tokens.enable()| has been called for it)
---
---@param bufnr (integer|nil) filter by buffer. All buffers if nil, current
--- buffer if 0
@ -748,7 +797,7 @@ function M.force_refresh(bufnr)
for _, buffer in ipairs(buffers) do
local highlighter = STHighlighter.active[buffer]
if highlighter then
if highlighter and M.is_enabled({ bufnr = bufnr }) then
highlighter:reset()
highlighter:send_request()
end
@ -831,4 +880,7 @@ api.nvim_set_decoration_provider(namespace, {
---@private
M.__STHighlighter = STHighlighter
-- Semantic tokens is enabled by default
util._enable('semantic_tokens', true)
return M

View File

@ -9,7 +9,6 @@ local eq = t.eq
local exec_lua = n.exec_lua
local feed = n.feed
local insert = n.insert
local matches = t.matches
local api = n.api
local clear_notrace = t_lsp.clear_notrace
@ -254,10 +253,10 @@ describe('semantic token highlighting', function()
end)
it(
'buffer is highlighted and unhighlighted when semantic token highlighting is started and stopped',
'buffer is highlighted and unhighlighted when semantic token highlighting is enabled and disabled',
function()
local bufnr = n.api.nvim_get_current_buf()
local client_id = exec_lua(function()
exec_lua(function()
vim.api.nvim_win_set_buf(0, bufnr)
return vim.lsp.start({ name = 'dummy', cmd = _G.server.cmd })
end)
@ -267,7 +266,7 @@ describe('semantic token highlighting', function()
exec_lua(function()
--- @diagnostic disable-next-line:duplicate-set-field
vim.notify = function() end
vim.lsp.semantic_tokens.stop(bufnr, client_id)
vim.lsp.semantic_tokens.enable(false)
end)
screen:expect {
@ -290,7 +289,7 @@ describe('semantic token highlighting', function()
}
exec_lua(function()
vim.lsp.semantic_tokens.start(bufnr, client_id)
vim.lsp.semantic_tokens.enable(true)
end)
screen:expect {
@ -315,7 +314,7 @@ describe('semantic token highlighting', function()
)
it('highlights start and stop when using "0" for current buffer', function()
local client_id = exec_lua(function()
exec_lua(function()
return vim.lsp.start({ name = 'dummy', cmd = _G.server.cmd })
end)
@ -324,7 +323,7 @@ describe('semantic token highlighting', function()
exec_lua(function()
--- @diagnostic disable-next-line:duplicate-set-field
vim.notify = function() end
vim.lsp.semantic_tokens.stop(0, client_id)
vim.lsp.semantic_tokens.enable(false, { bufnr = 0 })
end)
screen:expect {
@ -347,7 +346,7 @@ describe('semantic token highlighting', function()
}
exec_lua(function()
vim.lsp.semantic_tokens.start(0, client_id)
vim.lsp.semantic_tokens.enable(true, { bufnr = 0 })
end)
screen:expect {
@ -495,36 +494,6 @@ describe('semantic token highlighting', function()
}
end)
it('prevents starting semantic token highlighting with invalid conditions', function()
local client_id = exec_lua(function()
_G.notifications = {}
--- @diagnostic disable-next-line:duplicate-set-field
vim.notify = function(...)
table.insert(_G.notifications, 1, { ... })
end
return vim.lsp.start({ name = 'dummy', cmd = _G.server.cmd }, { attach = false })
end)
eq(false, exec_lua('return vim.lsp.buf_is_attached(0, ...)', client_id))
insert(text)
matches(
'%[LSP%] Client with id %d not attached to buffer %d',
exec_lua(function()
vim.lsp.semantic_tokens.start(0, client_id)
return _G.notifications[1][1]
end)
)
matches(
'%[LSP%] No client with id %d',
exec_lua(function()
vim.lsp.semantic_tokens.start(0, client_id + 1)
return _G.notifications[1][1]
end)
)
end)
it(
'opt-out: does not activate semantic token highlighting if disabled in client attach',
function()
@ -561,19 +530,6 @@ describe('semantic token highlighting', function()
]],
}
eq(
'[LSP] Server does not support semantic tokens',
exec_lua(function()
local notifications = {}
--- @diagnostic disable-next-line:duplicate-set-field
vim.notify = function(...)
table.insert(notifications, 1, { ... })
end
vim.lsp.semantic_tokens.start(0, client_id)
return notifications[1][1]
end)
)
screen:expect {
grid = [[
#include <iostream> |
@ -1598,8 +1554,7 @@ int main()
-- speed up vim.api.nvim_buf_set_lines calls by changing debounce to 10 for these tests
vim.schedule(function()
vim.lsp.semantic_tokens.stop(bufnr, client_id)
vim.lsp.semantic_tokens.start(bufnr, client_id, { debounce = 10 })
vim.lsp.semantic_tokens._start(bufnr, client_id, 10)
end)
return client_id
end, test.legend, test.response1, test.response2)