From 37079fca58f396fd866dc7b7d87a0100c17ee760 Mon Sep 17 00:00:00 2001 From: Mathias Fußenegger Date: Fri, 30 Jun 2023 11:33:28 +0200 Subject: feat(lsp): move inlay_hint() to vim.lsp (#24130) Allows to keep more functions hidden and gives a path forward for further inlay_hint related functions - like applying textEdits. See https://github.com/neovim/neovim/pull/23984#pullrequestreview-1486624668 --- runtime/lua/vim/lsp/inlay_hint.lua | 313 +++++++++++++++++++++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 runtime/lua/vim/lsp/inlay_hint.lua (limited to 'runtime/lua/vim/lsp/inlay_hint.lua') diff --git a/runtime/lua/vim/lsp/inlay_hint.lua b/runtime/lua/vim/lsp/inlay_hint.lua new file mode 100644 index 0000000000..1af18bbc61 --- /dev/null +++ b/runtime/lua/vim/lsp/inlay_hint.lua @@ -0,0 +1,313 @@ +local util = require('vim.lsp.util') +local log = require('vim.lsp.log') +local api = vim.api +local M = {} + +---@class lsp._inlay_hint.bufstate +---@field version integer +---@field client_hint table> client_id -> (lnum -> hints) +---@field enabled boolean Whether inlay hints are enabled for the buffer +---@field timer uv.uv_timer_t? Debounce timer associated with the buffer +---@field applied table Last version of hints applied to this line + +---@type table +local bufstates = {} + +local namespace = api.nvim_create_namespace('vim_lsp_inlayhint') +local augroup = api.nvim_create_augroup('vim_lsp_inlayhint', {}) + +--- Reset the request debounce timer of a buffer +---@private +local function reset_timer(reset_bufnr) + local timer = bufstates[reset_bufnr].timer + if timer then + bufstates[reset_bufnr].timer = nil + if not timer:is_closing() then + timer:stop() + timer:close() + end + end +end + +--- |lsp-handler| for the method `textDocument/inlayHint` +--- Store hints for a specific buffer and client +---@private +function M.on_inlayhint(err, result, ctx, _) + if err then + local _ = log.error() and log.error('inlayhint', err) + return + end + local bufnr = ctx.bufnr + if util.buf_versions[bufnr] ~= ctx.version then + return + end + local client_id = ctx.client_id + if not result then + return + end + local bufstate = bufstates[bufnr] + if not (bufstate.client_hint and bufstate.version) then + bufstate.client_hint = vim.defaulttable() + bufstate.version = ctx.version + end + local hints_by_client = bufstate.client_hint + local client = vim.lsp.get_client_by_id(client_id) + + local new_hints_by_lnum = vim.defaulttable() + local num_unprocessed = #result + if num_unprocessed == 0 then + hints_by_client[client_id] = {} + bufstate.version = ctx.version + api.nvim__buf_redraw_range(bufnr, 0, -1) + return + end + + local lines = api.nvim_buf_get_lines(bufnr, 0, -1, false) + ---@private + local function pos_to_byte(position) + local col = position.character + if col > 0 then + local line = lines[position.line + 1] or '' + local ok, convert_result + ok, convert_result = pcall(util._str_byteindex_enc, line, col, client.offset_encoding) + if ok then + return convert_result + end + return math.min(#line, col) + end + return col + end + + for _, hint in ipairs(result) do + local lnum = hint.position.line + hint.position.character = pos_to_byte(hint.position) + table.insert(new_hints_by_lnum[lnum], hint) + end + + hints_by_client[client_id] = new_hints_by_lnum + bufstate.version = ctx.version + api.nvim__buf_redraw_range(bufnr, 0, -1) +end + +---@private +local function resolve_bufnr(bufnr) + return bufnr > 0 and bufnr or api.nvim_get_current_buf() +end + +--- Refresh inlay hints for a buffer +--- +---@param opts (nil|table) Optional arguments +--- - bufnr (integer, default: 0): Buffer whose hints to refresh +--- - only_visible (boolean, default: false): Whether to only refresh hints for the visible regions of the buffer +--- +---@private +local function refresh(opts) + opts = opts or {} + local bufnr = resolve_bufnr(opts.bufnr or 0) + local bufstate = bufstates[bufnr] + if not (bufstate and bufstate.enabled) then + return + end + local only_visible = opts.only_visible or false + local buffer_windows = {} + for _, winid in ipairs(api.nvim_list_wins()) do + if api.nvim_win_get_buf(winid) == bufnr then + table.insert(buffer_windows, winid) + end + end + for _, window in ipairs(buffer_windows) do + local first = vim.fn.line('w0', window) + local last = vim.fn.line('w$', window) + local params = { + textDocument = util.make_text_document_params(bufnr), + range = { + start = { line = first - 1, character = 0 }, + ['end'] = { line = last, character = 0 }, + }, + } + vim.lsp.buf_request(bufnr, 'textDocument/inlayHint', params) + end + if not only_visible then + local params = { + textDocument = util.make_text_document_params(bufnr), + range = { + start = { line = 0, character = 0 }, + ['end'] = { line = api.nvim_buf_line_count(bufnr), character = 0 }, + }, + } + vim.lsp.buf_request(bufnr, 'textDocument/inlayHint', params) + end +end + +--- |lsp-handler| for the method `textDocument/inlayHint/refresh` +---@private +function M.on_refresh(err, _, ctx, _) + if err then + return vim.NIL + end + for _, bufnr in ipairs(vim.lsp.get_buffers_by_client_id(ctx.client_id)) do + for _, winid in ipairs(api.nvim_list_wins()) do + if api.nvim_win_get_buf(winid) == bufnr then + refresh({ bufnr = bufnr }) + break + end + end + end + + return vim.NIL +end + +--- Clear inlay hints +---@param bufnr (integer) Buffer handle, or 0 for current +---@private +local function clear(bufnr) + bufnr = resolve_bufnr(bufnr) + if not bufstates[bufnr] then + return + end + reset_timer(bufnr) + local bufstate = bufstates[bufnr] + local client_lens = (bufstate or {}).client_hint or {} + local client_ids = vim.tbl_keys(client_lens) + for _, iter_client_id in ipairs(client_ids) do + if bufstate then + bufstate.client_hint[iter_client_id] = {} + end + end + api.nvim_buf_clear_namespace(bufnr, namespace, 0, -1) + api.nvim__buf_redraw_range(bufnr, 0, -1) +end + +---@private +local function make_request(request_bufnr) + reset_timer(request_bufnr) + refresh({ bufnr = request_bufnr }) +end + +--- Enable inlay hints for a buffer +---@param bufnr (integer) Buffer handle, or 0 for current +---@private +local function enable(bufnr) + bufnr = resolve_bufnr(bufnr) + local bufstate = bufstates[bufnr] + if not (bufstate and bufstate.enabled) then + bufstates[bufnr] = { enabled = true, timer = nil, applied = {} } + refresh({ bufnr = bufnr }) + api.nvim_buf_attach(bufnr, true, { + on_lines = function(_, cb_bufnr) + if not bufstates[cb_bufnr].enabled then + return true + end + reset_timer(cb_bufnr) + bufstates[cb_bufnr].timer = vim.defer_fn(function() + make_request(cb_bufnr) + end, 200) + end, + on_reload = function(_, cb_bufnr) + clear(cb_bufnr) + if bufstates[cb_bufnr] and bufstates[cb_bufnr].enabled then + bufstates[cb_bufnr] = { enabled = true, applied = {} } + end + refresh({ bufnr = cb_bufnr }) + end, + on_detach = function(_, cb_bufnr) + clear(cb_bufnr) + bufstates[cb_bufnr] = nil + end, + }) + api.nvim_create_autocmd('LspDetach', { + buffer = bufnr, + callback = function(opts) + clear(opts.buf) + end, + once = true, + group = augroup, + }) + end +end + +--- Disable inlay hints for a buffer +---@param bufnr (integer) Buffer handle, or 0 for current +---@private +local function disable(bufnr) + bufnr = resolve_bufnr(bufnr) + if bufstates[bufnr] and bufstates[bufnr].enabled then + clear(bufnr) + bufstates[bufnr].enabled = nil + bufstates[bufnr].timer = nil + end +end + +--- Toggle inlay hints for a buffer +---@param bufnr (integer) Buffer handle, or 0 for current +---@private +local function toggle(bufnr) + bufnr = resolve_bufnr(bufnr) + local bufstate = bufstates[bufnr] + if bufstate and bufstate.enabled then + M.disable(bufnr) + else + M.enable(bufnr) + end +end + +api.nvim_set_decoration_provider(namespace, { + on_win = function(_, _, bufnr, topline, botline) + local bufstate = bufstates[bufnr] + if not bufstate then + return + end + + if bufstate.version ~= util.buf_versions[bufnr] then + return + end + local hints_by_client = bufstate.client_hint + + for lnum = topline, botline do + if bufstate.applied[lnum] ~= bufstate.version then + api.nvim_buf_clear_namespace(bufnr, namespace, lnum, lnum + 1) + for _, hints_by_lnum in pairs(hints_by_client) do + local line_hints = hints_by_lnum[lnum] or {} + for _, hint in pairs(line_hints) do + local text = '' + if type(hint.label) == 'string' then + text = hint.label + else + for _, part in ipairs(hint.label) do + text = text .. part.value + end + end + local vt = {} + if hint.paddingLeft then + vt[#vt + 1] = { ' ' } + end + vt[#vt + 1] = { text, 'LspInlayHint' } + if hint.paddingRight then + vt[#vt + 1] = { ' ' } + end + api.nvim_buf_set_extmark(bufnr, namespace, lnum, hint.position.character, { + virt_text_pos = 'inline', + ephemeral = false, + virt_text = vt, + hl_mode = 'combine', + }) + end + end + bufstate.applied[lnum] = bufstate.version + end + end + end, +}) + +return setmetatable(M, { + __call = function(_, bufnr, enable_) + vim.validate({ enable = { enable_, { 'boolean', 'nil' } }, bufnr = { bufnr, 'number' } }) + if enable_ then + enable(bufnr) + elseif enable_ == false then + disable(bufnr) + else + toggle(bufnr) + end + end, +}) -- cgit From d191bdf9d5e54722e28ddb0cccc8eb2312a234df Mon Sep 17 00:00:00 2001 From: Sanchayan Maity Date: Fri, 30 Jun 2023 17:12:58 +0530 Subject: fix(lsp): fix attempt to call non existent function (#24212) Commit 37079fc moved inlay_hint to vim.lsp() but in the process did missed converting a call to disable/enable which are now local. Fixes the below error when trying to toggle inlay hints. E5108: Error executing lua /usr/local/share/nvim/runtime/lua/vim/lsp/inlay_hint.lua:248: attempt to call field 'disable' (a nil value) stack traceback: /usr/local/share/nvim/runtime/lua/vim/lsp/inlay_hint.lua:248: in function 'toggle' /usr/local/share/nvim/runtime/lua/vim/lsp/inlay_hint.lua:310: in function 'inlay_hint' [string ":lua"]:1: in main chunk --- runtime/lua/vim/lsp/inlay_hint.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'runtime/lua/vim/lsp/inlay_hint.lua') diff --git a/runtime/lua/vim/lsp/inlay_hint.lua b/runtime/lua/vim/lsp/inlay_hint.lua index 1af18bbc61..f577a31696 100644 --- a/runtime/lua/vim/lsp/inlay_hint.lua +++ b/runtime/lua/vim/lsp/inlay_hint.lua @@ -245,9 +245,9 @@ local function toggle(bufnr) bufnr = resolve_bufnr(bufnr) local bufstate = bufstates[bufnr] if bufstate and bufstate.enabled then - M.disable(bufnr) + disable(bufnr) else - M.enable(bufnr) + enable(bufnr) end end -- cgit From 21fa19f3e8c1d7b427c6d7c0dbcd6702d1e4e397 Mon Sep 17 00:00:00 2001 From: Chinmay Dalal Date: Sat, 8 Jul 2023 12:44:52 +0530 Subject: fix(lsp): don't use hl_mode = combine for inlay hints #24276 Problem: `hl_mode` for inlay hints is `combine`, causing bugs like inlay hints using highlights from the previous character (#24152, #24068) Solution: Don't use hl_mode=combine for inlay hints. --- runtime/lua/vim/lsp/inlay_hint.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'runtime/lua/vim/lsp/inlay_hint.lua') diff --git a/runtime/lua/vim/lsp/inlay_hint.lua b/runtime/lua/vim/lsp/inlay_hint.lua index f577a31696..6426b0c039 100644 --- a/runtime/lua/vim/lsp/inlay_hint.lua +++ b/runtime/lua/vim/lsp/inlay_hint.lua @@ -289,7 +289,6 @@ api.nvim_set_decoration_provider(namespace, { virt_text_pos = 'inline', ephemeral = false, virt_text = vt, - hl_mode = 'combine', }) end end -- cgit From be74807eef13ff8c90d55cf8b22b01d6d33b1641 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Tue, 18 Jul 2023 15:42:30 +0100 Subject: docs(lua): more improvements (#24387) * docs(lua): teach lua2dox how to table * docs(lua): teach gen_vimdoc.py about local functions No more need to mark local functions with @private * docs(lua): mention @nodoc and @meta in dev-lua-doc * fixup! Co-authored-by: Justin M. Keyes --------- Co-authored-by: Justin M. Keyes --- runtime/lua/vim/lsp/inlay_hint.lua | 9 --------- 1 file changed, 9 deletions(-) (limited to 'runtime/lua/vim/lsp/inlay_hint.lua') diff --git a/runtime/lua/vim/lsp/inlay_hint.lua b/runtime/lua/vim/lsp/inlay_hint.lua index 6426b0c039..bec6f33e93 100644 --- a/runtime/lua/vim/lsp/inlay_hint.lua +++ b/runtime/lua/vim/lsp/inlay_hint.lua @@ -17,7 +17,6 @@ local namespace = api.nvim_create_namespace('vim_lsp_inlayhint') local augroup = api.nvim_create_augroup('vim_lsp_inlayhint', {}) --- Reset the request debounce timer of a buffer ----@private local function reset_timer(reset_bufnr) local timer = bufstates[reset_bufnr].timer if timer then @@ -63,7 +62,6 @@ function M.on_inlayhint(err, result, ctx, _) end local lines = api.nvim_buf_get_lines(bufnr, 0, -1, false) - ---@private local function pos_to_byte(position) local col = position.character if col > 0 then @@ -89,7 +87,6 @@ function M.on_inlayhint(err, result, ctx, _) api.nvim__buf_redraw_range(bufnr, 0, -1) end ----@private local function resolve_bufnr(bufnr) return bufnr > 0 and bufnr or api.nvim_get_current_buf() end @@ -100,7 +97,6 @@ end --- - bufnr (integer, default: 0): Buffer whose hints to refresh --- - only_visible (boolean, default: false): Whether to only refresh hints for the visible regions of the buffer --- ----@private local function refresh(opts) opts = opts or {} local bufnr = resolve_bufnr(opts.bufnr or 0) @@ -159,7 +155,6 @@ end --- Clear inlay hints ---@param bufnr (integer) Buffer handle, or 0 for current ----@private local function clear(bufnr) bufnr = resolve_bufnr(bufnr) if not bufstates[bufnr] then @@ -178,7 +173,6 @@ local function clear(bufnr) api.nvim__buf_redraw_range(bufnr, 0, -1) end ----@private local function make_request(request_bufnr) reset_timer(request_bufnr) refresh({ bufnr = request_bufnr }) @@ -186,7 +180,6 @@ end --- Enable inlay hints for a buffer ---@param bufnr (integer) Buffer handle, or 0 for current ----@private local function enable(bufnr) bufnr = resolve_bufnr(bufnr) local bufstate = bufstates[bufnr] @@ -228,7 +221,6 @@ end --- Disable inlay hints for a buffer ---@param bufnr (integer) Buffer handle, or 0 for current ----@private local function disable(bufnr) bufnr = resolve_bufnr(bufnr) if bufstates[bufnr] and bufstates[bufnr].enabled then @@ -240,7 +232,6 @@ end --- Toggle inlay hints for a buffer ---@param bufnr (integer) Buffer handle, or 0 for current ----@private local function toggle(bufnr) bufnr = resolve_bufnr(bufnr) local bufstate = bufstates[bufnr] -- cgit From 63b3408551561127f7845470eb51404bcd6f547b Mon Sep 17 00:00:00 2001 From: Chris AtLee Date: Thu, 20 Jul 2023 03:03:48 -0400 Subject: feat(lsp): implement textDocument/diagnostic (#24128) --- runtime/lua/vim/lsp/inlay_hint.lua | 77 ++++++++++---------------------------- 1 file changed, 20 insertions(+), 57 deletions(-) (limited to 'runtime/lua/vim/lsp/inlay_hint.lua') diff --git a/runtime/lua/vim/lsp/inlay_hint.lua b/runtime/lua/vim/lsp/inlay_hint.lua index bec6f33e93..1c29e8a866 100644 --- a/runtime/lua/vim/lsp/inlay_hint.lua +++ b/runtime/lua/vim/lsp/inlay_hint.lua @@ -87,54 +87,6 @@ function M.on_inlayhint(err, result, ctx, _) api.nvim__buf_redraw_range(bufnr, 0, -1) end -local function resolve_bufnr(bufnr) - return bufnr > 0 and bufnr or api.nvim_get_current_buf() -end - ---- Refresh inlay hints for a buffer ---- ----@param opts (nil|table) Optional arguments ---- - bufnr (integer, default: 0): Buffer whose hints to refresh ---- - only_visible (boolean, default: false): Whether to only refresh hints for the visible regions of the buffer ---- -local function refresh(opts) - opts = opts or {} - local bufnr = resolve_bufnr(opts.bufnr or 0) - local bufstate = bufstates[bufnr] - if not (bufstate and bufstate.enabled) then - return - end - local only_visible = opts.only_visible or false - local buffer_windows = {} - for _, winid in ipairs(api.nvim_list_wins()) do - if api.nvim_win_get_buf(winid) == bufnr then - table.insert(buffer_windows, winid) - end - end - for _, window in ipairs(buffer_windows) do - local first = vim.fn.line('w0', window) - local last = vim.fn.line('w$', window) - local params = { - textDocument = util.make_text_document_params(bufnr), - range = { - start = { line = first - 1, character = 0 }, - ['end'] = { line = last, character = 0 }, - }, - } - vim.lsp.buf_request(bufnr, 'textDocument/inlayHint', params) - end - if not only_visible then - local params = { - textDocument = util.make_text_document_params(bufnr), - range = { - start = { line = 0, character = 0 }, - ['end'] = { line = api.nvim_buf_line_count(bufnr), character = 0 }, - }, - } - vim.lsp.buf_request(bufnr, 'textDocument/inlayHint', params) - end -end - --- |lsp-handler| for the method `textDocument/inlayHint/refresh` ---@private function M.on_refresh(err, _, ctx, _) @@ -144,8 +96,11 @@ function M.on_refresh(err, _, ctx, _) for _, bufnr in ipairs(vim.lsp.get_buffers_by_client_id(ctx.client_id)) do for _, winid in ipairs(api.nvim_list_wins()) do if api.nvim_win_get_buf(winid) == bufnr then - refresh({ bufnr = bufnr }) - break + local bufstate = bufstates[bufnr] + if bufstate and bufstate.enabled then + util._refresh('textDocument/inlayHint', { bufnr = bufnr }) + break + end end end end @@ -156,7 +111,9 @@ end --- Clear inlay hints ---@param bufnr (integer) Buffer handle, or 0 for current local function clear(bufnr) - bufnr = resolve_bufnr(bufnr) + if bufnr == nil or bufnr == 0 then + bufnr = api.nvim_get_current_buf() + end if not bufstates[bufnr] then return end @@ -175,17 +132,19 @@ end local function make_request(request_bufnr) reset_timer(request_bufnr) - refresh({ bufnr = request_bufnr }) + util._refresh('textDocument/inlayHint', { bufnr = request_bufnr }) end --- Enable inlay hints for a buffer ---@param bufnr (integer) Buffer handle, or 0 for current local function enable(bufnr) - bufnr = resolve_bufnr(bufnr) + if bufnr == nil or bufnr == 0 then + bufnr = api.nvim_get_current_buf() + end local bufstate = bufstates[bufnr] if not (bufstate and bufstate.enabled) then bufstates[bufnr] = { enabled = true, timer = nil, applied = {} } - refresh({ bufnr = bufnr }) + util._refresh('textDocument/inlayHint', { bufnr = bufnr }) api.nvim_buf_attach(bufnr, true, { on_lines = function(_, cb_bufnr) if not bufstates[cb_bufnr].enabled then @@ -201,7 +160,7 @@ local function enable(bufnr) if bufstates[cb_bufnr] and bufstates[cb_bufnr].enabled then bufstates[cb_bufnr] = { enabled = true, applied = {} } end - refresh({ bufnr = cb_bufnr }) + util._refresh('textDocument/inlayHint', { bufnr = cb_bufnr }) end, on_detach = function(_, cb_bufnr) clear(cb_bufnr) @@ -222,7 +181,9 @@ end --- Disable inlay hints for a buffer ---@param bufnr (integer) Buffer handle, or 0 for current local function disable(bufnr) - bufnr = resolve_bufnr(bufnr) + if bufnr == nil or bufnr == 0 then + bufnr = api.nvim_get_current_buf() + end if bufstates[bufnr] and bufstates[bufnr].enabled then clear(bufnr) bufstates[bufnr].enabled = nil @@ -233,7 +194,9 @@ end --- Toggle inlay hints for a buffer ---@param bufnr (integer) Buffer handle, or 0 for current local function toggle(bufnr) - bufnr = resolve_bufnr(bufnr) + if bufnr == nil or bufnr == 0 then + bufnr = api.nvim_get_current_buf() + end local bufstate = bufstates[bufnr] if bufstate and bufstate.enabled then disable(bufnr) -- cgit From 4b57ff77febbe6073bc4c5c3a45b0ad0d5d40e6c Mon Sep 17 00:00:00 2001 From: Chris AtLee Date: Sat, 22 Jul 2023 05:00:17 -0400 Subject: refactor(lsp): use LspNotify for inlay_hint (#24411) --- runtime/lua/vim/lsp/inlay_hint.lua | 86 +++++++++++++++----------------------- 1 file changed, 34 insertions(+), 52 deletions(-) (limited to 'runtime/lua/vim/lsp/inlay_hint.lua') diff --git a/runtime/lua/vim/lsp/inlay_hint.lua b/runtime/lua/vim/lsp/inlay_hint.lua index 1c29e8a866..912ce6898e 100644 --- a/runtime/lua/vim/lsp/inlay_hint.lua +++ b/runtime/lua/vim/lsp/inlay_hint.lua @@ -6,28 +6,14 @@ local M = {} ---@class lsp._inlay_hint.bufstate ---@field version integer ---@field client_hint table> client_id -> (lnum -> hints) ----@field enabled boolean Whether inlay hints are enabled for the buffer ----@field timer uv.uv_timer_t? Debounce timer associated with the buffer ---@field applied table Last version of hints applied to this line - +---@field autocmd_id integer The autocmd id for the buffer ---@type table local bufstates = {} local namespace = api.nvim_create_namespace('vim_lsp_inlayhint') local augroup = api.nvim_create_augroup('vim_lsp_inlayhint', {}) ---- Reset the request debounce timer of a buffer -local function reset_timer(reset_bufnr) - local timer = bufstates[reset_bufnr].timer - if timer then - bufstates[reset_bufnr].timer = nil - if not timer:is_closing() then - timer:stop() - timer:close() - end - end -end - --- |lsp-handler| for the method `textDocument/inlayHint` --- Store hints for a specific buffer and client ---@private @@ -97,7 +83,7 @@ function M.on_refresh(err, _, ctx, _) for _, winid in ipairs(api.nvim_list_wins()) do if api.nvim_win_get_buf(winid) == bufnr then local bufstate = bufstates[bufnr] - if bufstate and bufstate.enabled then + if bufstate then util._refresh('textDocument/inlayHint', { bufnr = bufnr }) break end @@ -117,7 +103,6 @@ local function clear(bufnr) if not bufstates[bufnr] then return end - reset_timer(bufnr) local bufstate = bufstates[bufnr] local client_lens = (bufstate or {}).client_hint or {} local client_ids = vim.tbl_keys(client_lens) @@ -130,9 +115,17 @@ local function clear(bufnr) api.nvim__buf_redraw_range(bufnr, 0, -1) end -local function make_request(request_bufnr) - reset_timer(request_bufnr) - util._refresh('textDocument/inlayHint', { bufnr = request_bufnr }) +--- Disable inlay hints for a buffer +---@param bufnr (integer) Buffer handle, or 0 for current +local function disable(bufnr) + if bufnr == nil or bufnr == 0 then + bufnr = api.nvim_get_current_buf() + end + clear(bufnr) + if bufstates[bufnr] and bufstates[bufnr].autocmd_id then + api.nvim_del_autocmd(bufstates[bufnr].autocmd_id) + end + bufstates[bufnr] = nil end --- Enable inlay hints for a buffer @@ -142,35 +135,37 @@ local function enable(bufnr) bufnr = api.nvim_get_current_buf() end local bufstate = bufstates[bufnr] - if not (bufstate and bufstate.enabled) then - bufstates[bufnr] = { enabled = true, timer = nil, applied = {} } - util._refresh('textDocument/inlayHint', { bufnr = bufnr }) - api.nvim_buf_attach(bufnr, true, { - on_lines = function(_, cb_bufnr) - if not bufstates[cb_bufnr].enabled then - return true + if not bufstate then + bufstates[bufnr] = { applied = {} } + bufstates[bufnr].autocmd_id = api.nvim_create_autocmd('LspNotify', { + buffer = bufnr, + callback = function(opts) + if opts.data.method ~= 'textDocument/didChange' then + return + end + if bufstates[bufnr] then + util._refresh('textDocument/inlayHint', { bufnr = bufnr }) end - reset_timer(cb_bufnr) - bufstates[cb_bufnr].timer = vim.defer_fn(function() - make_request(cb_bufnr) - end, 200) end, + group = augroup, + }) + util._refresh('textDocument/inlayHint', { bufnr = bufnr }) + api.nvim_buf_attach(bufnr, true, { on_reload = function(_, cb_bufnr) clear(cb_bufnr) - if bufstates[cb_bufnr] and bufstates[cb_bufnr].enabled then - bufstates[cb_bufnr] = { enabled = true, applied = {} } + if bufstates[cb_bufnr] then + bufstates[cb_bufnr].applied = {} + util._refresh('textDocument/inlayHint', { bufnr = cb_bufnr }) end - util._refresh('textDocument/inlayHint', { bufnr = cb_bufnr }) end, on_detach = function(_, cb_bufnr) - clear(cb_bufnr) - bufstates[cb_bufnr] = nil + disable(cb_bufnr) end, }) api.nvim_create_autocmd('LspDetach', { buffer = bufnr, - callback = function(opts) - clear(opts.buf) + callback = function() + disable(bufnr) end, once = true, group = augroup, @@ -178,19 +173,6 @@ local function enable(bufnr) end end ---- Disable inlay hints for a buffer ----@param bufnr (integer) Buffer handle, or 0 for current -local function disable(bufnr) - if bufnr == nil or bufnr == 0 then - bufnr = api.nvim_get_current_buf() - end - if bufstates[bufnr] and bufstates[bufnr].enabled then - clear(bufnr) - bufstates[bufnr].enabled = nil - bufstates[bufnr].timer = nil - end -end - --- Toggle inlay hints for a buffer ---@param bufnr (integer) Buffer handle, or 0 for current local function toggle(bufnr) @@ -198,7 +180,7 @@ local function toggle(bufnr) bufnr = api.nvim_get_current_buf() end local bufstate = bufstates[bufnr] - if bufstate and bufstate.enabled then + if bufstate then disable(bufnr) else enable(bufnr) -- cgit From e55e80d51ca5d85770981bffb9254badc3662e0c Mon Sep 17 00:00:00 2001 From: Chris AtLee Date: Tue, 1 Aug 2023 08:13:52 -0400 Subject: fix(lsp): inlay hints: "Failed to delete autocmd" when closing buffer #24469 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: "Failed to delete autocmd" error when deleting LspNotify autocmd. #24456 Solution: Change a few things in the inlay_hint and diagnostic LSP code: 1. Re-introduce the `enabled` flag for the buffer state tables. Previously I was relying on the presence of an autocmd id in the state table to track whether inlay_hint / diagnostic was enabled for a buffer. There are two reasons why this doesn't work well: - Each time inlay_hint / diagnostic is enabled, we call `nvim_buf_attach` on the buffer, resulting in multiple `on_reload` or `on_detach` callbacks being registered. - Commands like `bwipeout` delete buffer local autocmds, sometimes before our `on_detach` callbacks have a chance to delete them first. This causes the - Use module local enabled state for diagnostic as well. bwipeout can race with on_detach callbacks for deleting autocmds. Error referenced in #24456. 2. Change the `LspDetach` autocmd to run each time (i.e., remove the `once` flag). Since we're only registering autocmds once per buffer now, we need to make sure that we set the enabled flag properly each time the LSP client detaches from the buffer. - Remove `once` from the LspDetach autocmds for inlay_hint and diagnostic. We only set up the autocmd once now. Gets removed when buffer is deleted. 3. Have the `LspNotify` handler also refresh the inlay_hint / diagnostics when receiving the `textDocument/didOpen` event. Before this point, the LSP backend doesn't have the contents of the buffer, so can't provide inlay hints or diagnostics. Downsides of this approach: * When inlay_hint / diagnostics are disabled on a buffer, it will continue to receive `LspNotify` events for that buffer. The callback exits early since the `enabled` flag is false. Alternatives: * Can we wrap the call to `nvim_del_autocmd` in `pcall` to swallow any errors resulting from trying to delete the autocmd? Fixes #24456 Helped-by: Maria José Solano --- runtime/lua/vim/lsp/inlay_hint.lua | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) (limited to 'runtime/lua/vim/lsp/inlay_hint.lua') diff --git a/runtime/lua/vim/lsp/inlay_hint.lua b/runtime/lua/vim/lsp/inlay_hint.lua index 912ce6898e..2bf0fb9cb2 100644 --- a/runtime/lua/vim/lsp/inlay_hint.lua +++ b/runtime/lua/vim/lsp/inlay_hint.lua @@ -3,12 +3,12 @@ local log = require('vim.lsp.log') local api = vim.api local M = {} ----@class lsp._inlay_hint.bufstate +---@class lsp.inlay_hint.bufstate ---@field version integer ---@field client_hint table> client_id -> (lnum -> hints) ---@field applied table Last version of hints applied to this line ----@field autocmd_id integer The autocmd id for the buffer ----@type table +---@field enabled boolean Whether inlay hints are enabled for this buffer +---@type table local bufstates = {} local namespace = api.nvim_create_namespace('vim_lsp_inlayhint') @@ -31,6 +31,9 @@ function M.on_inlayhint(err, result, ctx, _) return end local bufstate = bufstates[bufnr] + if not bufstate or not bufstate.enabled then + return + end if not (bufstate.client_hint and bufstate.version) then bufstate.client_hint = vim.defaulttable() bufstate.version = ctx.version @@ -122,10 +125,9 @@ local function disable(bufnr) bufnr = api.nvim_get_current_buf() end clear(bufnr) - if bufstates[bufnr] and bufstates[bufnr].autocmd_id then - api.nvim_del_autocmd(bufstates[bufnr].autocmd_id) + if bufstates[bufnr] then + bufstates[bufnr] = { enabled = false, applied = {} } end - bufstates[bufnr] = nil end --- Enable inlay hints for a buffer @@ -136,24 +138,27 @@ local function enable(bufnr) end local bufstate = bufstates[bufnr] if not bufstate then - bufstates[bufnr] = { applied = {} } - bufstates[bufnr].autocmd_id = api.nvim_create_autocmd('LspNotify', { + bufstates[bufnr] = { applied = {}, enabled = true } + api.nvim_create_autocmd('LspNotify', { buffer = bufnr, callback = function(opts) - if opts.data.method ~= 'textDocument/didChange' then + if + opts.data.method ~= 'textDocument/didChange' + and opts.data.method ~= 'textDocument/didOpen' + then return end - if bufstates[bufnr] then + if bufstates[bufnr] and bufstates[bufnr].enabled then util._refresh('textDocument/inlayHint', { bufnr = bufnr }) end end, group = augroup, }) util._refresh('textDocument/inlayHint', { bufnr = bufnr }) - api.nvim_buf_attach(bufnr, true, { + api.nvim_buf_attach(bufnr, false, { on_reload = function(_, cb_bufnr) clear(cb_bufnr) - if bufstates[cb_bufnr] then + if bufstates[cb_bufnr] and bufstates[cb_bufnr].enabled then bufstates[cb_bufnr].applied = {} util._refresh('textDocument/inlayHint', { bufnr = cb_bufnr }) end @@ -167,9 +172,11 @@ local function enable(bufnr) callback = function() disable(bufnr) end, - once = true, group = augroup, }) + else + bufstate.enabled = true + util._refresh('textDocument/inlayHint', { bufnr = bufnr }) end end @@ -180,7 +187,7 @@ local function toggle(bufnr) bufnr = api.nvim_get_current_buf() end local bufstate = bufstates[bufnr] - if bufstate then + if bufstate and bufstate.enabled then disable(bufnr) else enable(bufnr) -- cgit From f1772272b4fda43c093fc495f54b5e7c11968d62 Mon Sep 17 00:00:00 2001 From: Raphael Date: Thu, 3 Aug 2023 19:03:48 +0800 Subject: refactor(lsp): use protocol.Methods instead of strings #24537 --- runtime/lua/vim/lsp/inlay_hint.lua | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'runtime/lua/vim/lsp/inlay_hint.lua') diff --git a/runtime/lua/vim/lsp/inlay_hint.lua b/runtime/lua/vim/lsp/inlay_hint.lua index 2bf0fb9cb2..eb2f59b312 100644 --- a/runtime/lua/vim/lsp/inlay_hint.lua +++ b/runtime/lua/vim/lsp/inlay_hint.lua @@ -1,5 +1,6 @@ local util = require('vim.lsp.util') local log = require('vim.lsp.log') +local ms = require('vim.lsp.protocol').Methods local api = vim.api local M = {} @@ -87,7 +88,7 @@ function M.on_refresh(err, _, ctx, _) if api.nvim_win_get_buf(winid) == bufnr then local bufstate = bufstates[bufnr] if bufstate then - util._refresh('textDocument/inlayHint', { bufnr = bufnr }) + util._refresh(ms.textDocument_inlayHint, { bufnr = bufnr }) break end end @@ -143,24 +144,24 @@ local function enable(bufnr) buffer = bufnr, callback = function(opts) if - opts.data.method ~= 'textDocument/didChange' - and opts.data.method ~= 'textDocument/didOpen' + opts.data.method ~= ms.textDocument_didChange + and opts.data.method ~= ms.textDocument_didOpen then return end if bufstates[bufnr] and bufstates[bufnr].enabled then - util._refresh('textDocument/inlayHint', { bufnr = bufnr }) + util._refresh(ms.textDocument_inlayHint, { bufnr = bufnr }) end end, group = augroup, }) - util._refresh('textDocument/inlayHint', { bufnr = bufnr }) + util._refresh(ms.textDocument_inlayHint, { bufnr = bufnr }) api.nvim_buf_attach(bufnr, false, { on_reload = function(_, cb_bufnr) clear(cb_bufnr) if bufstates[cb_bufnr] and bufstates[cb_bufnr].enabled then bufstates[cb_bufnr].applied = {} - util._refresh('textDocument/inlayHint', { bufnr = cb_bufnr }) + util._refresh(ms.textDocument_inlayHint, { bufnr = cb_bufnr }) end end, on_detach = function(_, cb_bufnr) @@ -176,7 +177,7 @@ local function enable(bufnr) }) else bufstate.enabled = true - util._refresh('textDocument/inlayHint', { bufnr = bufnr }) + util._refresh(ms.textDocument_inlayHint, { bufnr = bufnr }) end end -- cgit From c43c745a14dced87a23227d7be4f1c33d4455193 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Wed, 9 Aug 2023 11:06:13 +0200 Subject: fix(lua): improve annotations for stricter luals diagnostics (#24609) Problem: luals returns stricter diagnostics with bundled luarc.json Solution: Improve some function and type annotations: * use recognized uv.* types * disable diagnostic for global `vim` in shared.lua * docs: don't start comment lines with taglink (otherwise LuaLS will interpret it as a type) * add type alias for lpeg pattern * fix return annotation for `vim.secure.trust` * rename local Range object in vim.version (shadows `Range` in vim.treesitter) * fix some "missing fields" warnings * add missing required fields for test functions in eval.lua * rename lsp meta files for consistency --- runtime/lua/vim/lsp/inlay_hint.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'runtime/lua/vim/lsp/inlay_hint.lua') diff --git a/runtime/lua/vim/lsp/inlay_hint.lua b/runtime/lua/vim/lsp/inlay_hint.lua index eb2f59b312..8407105d47 100644 --- a/runtime/lua/vim/lsp/inlay_hint.lua +++ b/runtime/lua/vim/lsp/inlay_hint.lua @@ -5,8 +5,8 @@ local api = vim.api local M = {} ---@class lsp.inlay_hint.bufstate ----@field version integer ----@field client_hint table> client_id -> (lnum -> hints) +---@field version? integer +---@field client_hint? table> client_id -> (lnum -> hints) ---@field applied table Last version of hints applied to this line ---@field enabled boolean Whether inlay hints are enabled for this buffer ---@type table -- cgit From c235959fd909d75248c066a781475e207606c5aa Mon Sep 17 00:00:00 2001 From: Chris AtLee Date: Thu, 31 Aug 2023 04:00:24 -0400 Subject: fix(lsp): only disable inlay hints / diagnostics if no other clients are connected (#24535) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes the issue where the LspNotify handlers for inlay_hint / diagnostics would end up refreshing all attached clients. The handler would call util._refresh, which called vim.lsp.buf_request, which calls the method on all attached clients. Now util._refresh takes an optional client_id parameter, which is used to specify a specific client to update. This commit also fixes util._refresh's handling of the `only_visible` flag. Previously if `only_visible` was false, two requests would be made to the server: one for the visible region, and one for the entire file. Co-authored-by: Stanislav Asunkin <1353637+stasjok@users.noreply.github.com> Co-authored-by: Mathias Fußenegger --- runtime/lua/vim/lsp/inlay_hint.lua | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'runtime/lua/vim/lsp/inlay_hint.lua') diff --git a/runtime/lua/vim/lsp/inlay_hint.lua b/runtime/lua/vim/lsp/inlay_hint.lua index 8407105d47..7b58188c53 100644 --- a/runtime/lua/vim/lsp/inlay_hint.lua +++ b/runtime/lua/vim/lsp/inlay_hint.lua @@ -131,6 +131,16 @@ local function disable(bufnr) end end +--- Refresh inlay hints, only if we have attached clients that support it +---@param bufnr (integer) Buffer handle, or 0 for current +---@param opts? table Additional options to pass to util._refresh +---@private +local function _refresh(bufnr, opts) + opts = opts or {} + opts['bufnr'] = bufnr + util._refresh(ms.textDocument_inlayHint, opts) +end + --- Enable inlay hints for a buffer ---@param bufnr (integer) Buffer handle, or 0 for current local function enable(bufnr) @@ -150,18 +160,18 @@ local function enable(bufnr) return end if bufstates[bufnr] and bufstates[bufnr].enabled then - util._refresh(ms.textDocument_inlayHint, { bufnr = bufnr }) + _refresh(bufnr, { client_id = opts.data.client_id }) end end, group = augroup, }) - util._refresh(ms.textDocument_inlayHint, { bufnr = bufnr }) + _refresh(bufnr) api.nvim_buf_attach(bufnr, false, { on_reload = function(_, cb_bufnr) clear(cb_bufnr) if bufstates[cb_bufnr] and bufstates[cb_bufnr].enabled then bufstates[cb_bufnr].applied = {} - util._refresh(ms.textDocument_inlayHint, { bufnr = cb_bufnr }) + _refresh(cb_bufnr) end end, on_detach = function(_, cb_bufnr) @@ -170,14 +180,22 @@ local function enable(bufnr) }) api.nvim_create_autocmd('LspDetach', { buffer = bufnr, - callback = function() - disable(bufnr) + callback = function(args) + local clients = vim.lsp.get_clients({ bufnr = bufnr, method = ms.textDocument_inlayHint }) + + if + not vim.iter(clients):any(function(c) + return c.id ~= args.data.client_id + end) + then + disable(bufnr) + end end, group = augroup, }) else bufstate.enabled = true - util._refresh(ms.textDocument_inlayHint, { bufnr = bufnr }) + _refresh(bufnr) end end -- cgit From 448907f65d6709fa234d8366053e33311a01bdb9 Mon Sep 17 00:00:00 2001 From: LW Date: Sun, 12 Nov 2023 04:54:27 -0800 Subject: feat(lsp)!: vim.lsp.inlay_hint.get(), enable(), is_enabled() #25512 refactor!: `vim.lsp.inlay_hint()` -> `vim.lsp.inlay_hint.enable()` Problem: The LSP specification allows inlay hints to include tooltips, clickable label parts, and code actions; but Neovim provides no API to query for these. Solution: Add minimal viable extension point from which plugins can query for inlay hints in a range, in order to build functionality on top of. Possible Next Steps --- - Add `virt_text_idx` field to `vim.fn.getmousepos()` return value, for usage in mappings of ``, ``, etc --- runtime/lua/vim/lsp/inlay_hint.lua | 163 +++++++++++++++++++++++++++++-------- 1 file changed, 131 insertions(+), 32 deletions(-) (limited to 'runtime/lua/vim/lsp/inlay_hint.lua') diff --git a/runtime/lua/vim/lsp/inlay_hint.lua b/runtime/lua/vim/lsp/inlay_hint.lua index 7b58188c53..cdda5dcc17 100644 --- a/runtime/lua/vim/lsp/inlay_hint.lua +++ b/runtime/lua/vim/lsp/inlay_hint.lua @@ -98,6 +98,107 @@ function M.on_refresh(err, _, ctx, _) return vim.NIL end +--- @class vim.lsp.inlay_hint.get.filter +--- @field bufnr integer? +--- @field range lsp.Range? +--- +--- @class vim.lsp.inlay_hint.get.ret +--- @field bufnr integer +--- @field client_id integer +--- @field inlay_hint lsp.InlayHint + +--- Get the list of inlay hints, (optionally) restricted by buffer, client, or range. +--- +--- Example usage: +--- +--- ```lua +--- local hint = vim.lsp.inlay_hint.get({ bufnr = 0 })[1] -- 0 for current buffer +--- +--- local client = vim.lsp.get_client_by_id(hint.client_id) +--- resolved_hint = client.request_sync('inlayHint/resolve', hint.inlay_hint, 100, 0).result +--- vim.lsp.util.apply_text_edits(resolved_hint.textEdits, 0, client.encoding) +--- +--- location = resolved_hint.label[1].location +--- client.request('textDocument/hover', { +--- textDocument = { uri = location.uri }, +--- position = location.range.start, +--- }) +--- ``` +--- +--- @param filter vim.lsp.inlay_hint.get.filter? +--- Optional filters |kwargs|: +--- - bufnr (integer?): 0 for current buffer +--- - range (lsp.Range?) +--- +--- @return vim.lsp.inlay_hint.get.ret[] +--- Each list item is a table with the following fields: +--- - bufnr (integer) +--- - client_id (integer) +--- - inlay_hint (lsp.InlayHint) +function M.get(filter) + vim.validate({ filter = { filter, 'table', true } }) + filter = filter or {} + + local bufnr = filter.bufnr + if not bufnr then + --- @type vim.lsp.inlay_hint.get.ret[] + local hints = {} + --- @param buf integer + vim.tbl_map(function(buf) + vim.list_extend(hints, M.get(vim.tbl_extend('keep', { bufnr = buf }, filter))) + end, vim.api.nvim_list_bufs()) + return hints + elseif bufnr == 0 then + bufnr = api.nvim_get_current_buf() + end + + local bufstate = bufstates[bufnr] + if not (bufstate and bufstate.client_hint) then + return {} + end + + local clients = vim.lsp.get_clients({ + bufnr = bufnr, + method = ms.textDocument_inlayHint, + }) + if #clients == 0 then + return {} + end + + local range = filter.range + if not range then + range = { + start = { line = 0, character = 0 }, + ['end'] = { line = api.nvim_buf_line_count(bufnr), character = 0 }, + } + end + + --- @type vim.lsp.inlay_hint.get.ret[] + local hints = {} + for _, client in pairs(clients) do + local hints_by_lnum = bufstate.client_hint[client.id] + if hints_by_lnum then + for lnum = range.start.line, range['end'].line do + local line_hints = hints_by_lnum[lnum] or {} + for _, hint in pairs(line_hints) do + local line, char = hint.position.line, hint.position.character + if + (line > range.start.line or char >= range.start.character) + and (line < range['end'].line or char <= range['end'].character) + then + table.insert(hints, { + bufnr = bufnr, + client_id = client.id, + inlay_hint = hint, + }) + end + end + end + end + end + return hints +end + --- Clear inlay hints ---@param bufnr (integer) Buffer handle, or 0 for current local function clear(bufnr) @@ -120,8 +221,8 @@ local function clear(bufnr) end --- Disable inlay hints for a buffer ----@param bufnr (integer) Buffer handle, or 0 for current -local function disable(bufnr) +---@param bufnr (integer|nil) Buffer handle, or 0 or nil for current +local function _disable(bufnr) if bufnr == nil or bufnr == 0 then bufnr = api.nvim_get_current_buf() end @@ -142,8 +243,8 @@ local function _refresh(bufnr, opts) end --- Enable inlay hints for a buffer ----@param bufnr (integer) Buffer handle, or 0 for current -local function enable(bufnr) +---@param bufnr (integer|nil) Buffer handle, or 0 or nil for current +local function _enable(bufnr) if bufnr == nil or bufnr == 0 then bufnr = api.nvim_get_current_buf() end @@ -175,7 +276,7 @@ local function enable(bufnr) end end, on_detach = function(_, cb_bufnr) - disable(cb_bufnr) + _disable(cb_bufnr) end, }) api.nvim_create_autocmd('LspDetach', { @@ -188,7 +289,7 @@ local function enable(bufnr) return c.id ~= args.data.client_id end) then - disable(bufnr) + _disable(bufnr) end end, group = augroup, @@ -199,20 +300,6 @@ local function enable(bufnr) end end ---- Toggle inlay hints for a buffer ----@param bufnr (integer) Buffer handle, or 0 for current -local function toggle(bufnr) - if bufnr == nil or bufnr == 0 then - bufnr = api.nvim_get_current_buf() - end - local bufstate = bufstates[bufnr] - if bufstate and bufstate.enabled then - disable(bufnr) - else - enable(bufnr) - end -end - api.nvim_set_decoration_provider(namespace, { on_win = function(_, _, bufnr, topline, botline) local bufstate = bufstates[bufnr] @@ -260,15 +347,27 @@ api.nvim_set_decoration_provider(namespace, { end, }) -return setmetatable(M, { - __call = function(_, bufnr, enable_) - vim.validate({ enable = { enable_, { 'boolean', 'nil' } }, bufnr = { bufnr, 'number' } }) - if enable_ then - enable(bufnr) - elseif enable_ == false then - disable(bufnr) - else - toggle(bufnr) - end - end, -}) +--- @param bufnr (integer|nil) Buffer handle, or 0 or nil for current +--- @return boolean +function M.is_enabled(bufnr) + vim.validate({ bufnr = { bufnr, 'number', true } }) + if bufnr == nil or bufnr == 0 then + bufnr = api.nvim_get_current_buf() + end + return bufstates[bufnr] and bufstates[bufnr].enabled or false +end + +--- Enable/disable/toggle inlay hints for a buffer +--- +--- @param bufnr (integer|nil) Buffer handle, or 0 or nil for current +--- @param enable (boolean|nil) true/nil to enable, false to disable +function M.enable(bufnr, enable) + vim.validate({ enable = { enable, 'boolean', true }, bufnr = { bufnr, 'number', true } }) + if enable == false then + _disable(bufnr) + else + _enable(bufnr) + end +end + +return M -- cgit From 9fa9b3cad94a1ea7fced128fed2cd5ac3ff7bc44 Mon Sep 17 00:00:00 2001 From: LW Date: Mon, 27 Nov 2023 08:23:04 -0800 Subject: docs: support @since for api level #25574 close #25416 --- runtime/lua/vim/lsp/inlay_hint.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'runtime/lua/vim/lsp/inlay_hint.lua') diff --git a/runtime/lua/vim/lsp/inlay_hint.lua b/runtime/lua/vim/lsp/inlay_hint.lua index cdda5dcc17..4f7a3b0076 100644 --- a/runtime/lua/vim/lsp/inlay_hint.lua +++ b/runtime/lua/vim/lsp/inlay_hint.lua @@ -107,7 +107,7 @@ end --- @field client_id integer --- @field inlay_hint lsp.InlayHint ---- Get the list of inlay hints, (optionally) restricted by buffer, client, or range. +--- Get the list of inlay hints, (optionally) restricted by buffer or range. --- --- Example usage: --- @@ -135,6 +135,8 @@ end --- - bufnr (integer) --- - client_id (integer) --- - inlay_hint (lsp.InlayHint) +--- +--- @since 12 function M.get(filter) vim.validate({ filter = { filter, 'table', true } }) filter = filter or {} @@ -349,6 +351,7 @@ api.nvim_set_decoration_provider(namespace, { --- @param bufnr (integer|nil) Buffer handle, or 0 or nil for current --- @return boolean +--- @since 12 function M.is_enabled(bufnr) vim.validate({ bufnr = { bufnr, 'number', true } }) if bufnr == nil or bufnr == 0 then @@ -361,6 +364,7 @@ end --- --- @param bufnr (integer|nil) Buffer handle, or 0 or nil for current --- @param enable (boolean|nil) true/nil to enable, false to disable +--- @since 12 function M.enable(bufnr, enable) vim.validate({ enable = { enable, 'boolean', true }, bufnr = { bufnr, 'number', true } }) if enable == false then -- cgit