From de9ed1ca5478481679df23f894b92b6756be7aed Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Tue, 19 Nov 2024 22:29:18 +0100 Subject: vim-patch:9.1.0874: filetype: karel files are not detected Problem: filetype: karel files are not detected Solution: detect '*.kl' files as karel filetype, include syntax and filetype plugin (Kirill Morozov) closes: vim/vim#16075 https://github.com/vim/vim/commit/fdac54d7bbf6d68a8bf741e734b86d0f1998ac86 Co-authored-by: Kirill Morozov Co-authored-by: KnoP-01 --- runtime/lua/vim/filetype.lua | 2 ++ 1 file changed, 2 insertions(+) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index e1e73d63fe..9010adf777 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -653,6 +653,8 @@ local extension = { jsp = 'jsp', jl = 'julia', just = 'just', + kl = 'karel', + KL = 'karel', kdl = 'kdl', kv = 'kivy', kix = 'kix', -- cgit From 4c85c217d384c79013401f09b329467c53c8a01c Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Tue, 19 Nov 2024 22:30:50 +0100 Subject: vim-patch:9.1.0875: filetype: hyprlang detection can be improved Problem: filetype: hyprlang detection can be improved Solution: detect '/hypr/*.conf' files as hyprlang filetype, include basic syntax highlighting (Luca Saccarola) fixes: vim/vim#15875 closes: vim/vim#16064 https://github.com/vim/vim/commit/a13bd294ab2d9ab38634c9ec51fa76205af6eb62 Co-authored-by: Luca Saccarola --- runtime/lua/vim/filetype.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index 9010adf777..c23beb960c 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -2214,6 +2214,7 @@ local pattern = { ['/screengrab/.*%.conf$'] = 'dosini', ['^${GNUPGHOME}/gpg%.conf$'] = 'gpg', ['/boot/grub/grub%.conf$'] = 'grub', + ['/hypr/.*%.conf$'] = 'hyprlang', ['^lilo%.conf'] = starsetf('lilo'), ['^named.*%.conf$'] = 'named', ['^rndc.*%.conf$'] = 'named', -- cgit From 23ead4f2cb19b05d83f1c515b35bd5896ee77365 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Tue, 19 Nov 2024 22:33:30 +0100 Subject: vim-patch:9.1.0876: filetype: openCL files are not recognized Problem: filetype: openCL files are not recognized Solution: detect '*.cl' files as opencl or lisp filetype, include a opencl syntax and filetype plugin (Wu, Zhenyu) closes: vim/vim#15825 https://github.com/vim/vim/commit/e2c27ca8eff7cc8ec852b531d5a7f328a343a761 Co-authored-by: Wu, Zhenyu --- runtime/lua/vim/filetype.lua | 2 +- runtime/lua/vim/filetype/detect.lua | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index c23beb960c..285b7e2328 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -300,6 +300,7 @@ local extension = { cho = 'chordpro', chordpro = 'chordpro', ck = 'chuck', + cl = detect.cl, eni = 'cl', icl = 'clean', cljx = 'clojure', @@ -688,7 +689,6 @@ local extension = { ily = 'lilypond', liquid = 'liquid', liq = 'liquidsoap', - cl = 'lisp', L = 'lisp', lisp = 'lisp', el = 'lisp', diff --git a/runtime/lua/vim/filetype/detect.lua b/runtime/lua/vim/filetype/detect.lua index 98b001bd51..81b94c69db 100644 --- a/runtime/lua/vim/filetype/detect.lua +++ b/runtime/lua/vim/filetype/detect.lua @@ -180,6 +180,16 @@ function M.changelog(_, bufnr) return 'changelog' end +--- @type vim.filetype.mapfn +function M.cl(_, bufnr) + local lines = table.concat(getlines(bufnr, 1, 4)) + if lines:match('/%*') then + return 'opencl' + else + return 'lisp' + end +end + --- @type vim.filetype.mapfn function M.class(_, bufnr) -- Check if not a Java class (starts with '\xca\xfe\xba\xbe') -- cgit From f55c842ec7eabd2e12749411babdcadba47438bc Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Wed, 20 Nov 2024 08:51:39 +0100 Subject: vim-patch:9.1.0880: filetype: C3 files are not recognized Problem: filetype: C3 files are not recognized Solution: detect '*.c3*' files as c3 filetype (Turiiya) closes: vim/vim#16087 https://github.com/vim/vim/commit/c8dfcfc53ba5ed69b5d4e534fd7e8694de014e6a Co-authored-by: Turiiya <34311583+ttytm@users.noreply.github.com> --- runtime/lua/vim/filetype.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index 285b7e2328..4383c0983e 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -275,6 +275,9 @@ local extension = { mdh = 'c', epro = 'c', qc = 'c', + c3 = 'c3', + c3i = 'c3', + c3t = 'c3', cabal = 'cabal', cairo = 'cairo', capnp = 'capnp', -- cgit From 454ae672aad172a299dcff7c33c5e61a3b631c90 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Thu, 14 Nov 2024 11:53:20 +0000 Subject: feat(lsp): deprecate non-method client functions Deprecated: - `client.request()` -> `client:request()` - `client.request_sync()` -> `client:request_sync()` - `client.notify()` -> `client:notify()` - `client.cancel_request()` -> `client:cancel_request()` - `client.stop()` -> `client:stop()` - `client.is_stopped()` `client:is_stopped()` - `client.supports_method()` -> `client:supports_method()` - `client.on_attach()` -> `client:on_attach()` Fixed docgen to link class fields to the full function doc. --- runtime/lua/vim/lsp.lua | 54 ++++---- runtime/lua/vim/lsp/_changetracking.lua | 6 +- runtime/lua/vim/lsp/_tagfunc.lua | 2 +- runtime/lua/vim/lsp/_watchfiles.lua | 2 +- runtime/lua/vim/lsp/buf.lua | 30 +++-- runtime/lua/vim/lsp/client.lua | 214 ++++++++++++++------------------ runtime/lua/vim/lsp/codelens.lua | 2 +- runtime/lua/vim/lsp/completion.lua | 6 +- runtime/lua/vim/lsp/inlay_hint.lua | 4 +- runtime/lua/vim/lsp/semantic_tokens.lua | 8 +- runtime/lua/vim/lsp/util.lua | 4 +- 11 files changed, 151 insertions(+), 181 deletions(-) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 0de3b4ee4d..c032d25cb1 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -349,17 +349,17 @@ end ---@param bufnr integer function lsp._set_defaults(client, bufnr) if - client.supports_method(ms.textDocument_definition) and is_empty_or_default(bufnr, 'tagfunc') + client:supports_method(ms.textDocument_definition) and is_empty_or_default(bufnr, 'tagfunc') then vim.bo[bufnr].tagfunc = 'v:lua.vim.lsp.tagfunc' end if - client.supports_method(ms.textDocument_completion) and is_empty_or_default(bufnr, 'omnifunc') + client:supports_method(ms.textDocument_completion) and is_empty_or_default(bufnr, 'omnifunc') then vim.bo[bufnr].omnifunc = 'v:lua.vim.lsp.omnifunc' end if - client.supports_method(ms.textDocument_rangeFormatting) + client:supports_method(ms.textDocument_rangeFormatting) and is_empty_or_default(bufnr, 'formatprg') and is_empty_or_default(bufnr, 'formatexpr') then @@ -367,14 +367,14 @@ function lsp._set_defaults(client, bufnr) end vim._with({ buf = bufnr }, function() if - client.supports_method(ms.textDocument_hover) + client:supports_method(ms.textDocument_hover) and is_empty_or_default(bufnr, 'keywordprg') and vim.fn.maparg('K', 'n', false, false) == '' then vim.keymap.set('n', 'K', vim.lsp.buf.hover, { buffer = bufnr, desc = 'vim.lsp.buf.hover()' }) end end) - if client.supports_method(ms.textDocument_diagnostic) then + if client:supports_method(ms.textDocument_diagnostic) then lsp.diagnostic._enable(bufnr) end end @@ -485,12 +485,12 @@ local function text_document_did_save_handler(bufnr) local name = api.nvim_buf_get_name(bufnr) local old_name = changetracking._get_and_set_name(client, bufnr, name) if old_name and name ~= old_name then - client.notify(ms.textDocument_didClose, { + client:notify(ms.textDocument_didClose, { textDocument = { uri = vim.uri_from_fname(old_name), }, }) - client.notify(ms.textDocument_didOpen, { + client:notify(ms.textDocument_didOpen, { textDocument = { version = 0, uri = uri, @@ -506,7 +506,7 @@ local function text_document_did_save_handler(bufnr) if type(save_capability) == 'table' and save_capability.includeText then included_text = text(bufnr) end - client.notify(ms.textDocument_didSave, { + client:notify(ms.textDocument_didSave, { textDocument = { uri = uri, }, @@ -527,10 +527,10 @@ local function buf_detach_client(bufnr, client) changetracking.reset_buf(client, bufnr) - if client.supports_method(ms.textDocument_didClose) then + if client:supports_method(ms.textDocument_didClose) then local uri = vim.uri_from_bufnr(bufnr) local params = { textDocument = { uri = uri } } - client.notify(ms.textDocument_didClose, params) + client:notify(ms.textDocument_didClose, params) end client.attached_buffers[bufnr] = nil @@ -564,12 +564,12 @@ local function buf_attach(bufnr) }, reason = protocol.TextDocumentSaveReason.Manual, ---@type integer } - if client.supports_method(ms.textDocument_willSave) then - client.notify(ms.textDocument_willSave, params) + if client:supports_method(ms.textDocument_willSave) then + client:notify(ms.textDocument_willSave, params) end - if client.supports_method(ms.textDocument_willSaveWaitUntil) then + if client:supports_method(ms.textDocument_willSaveWaitUntil) then local result, err = - client.request_sync(ms.textDocument_willSaveWaitUntil, params, 1000, ctx.buf) + client:request_sync(ms.textDocument_willSaveWaitUntil, params, 1000, ctx.buf) if result and result.result then util.apply_text_edits(result.result, ctx.buf, client.offset_encoding) elseif err then @@ -603,8 +603,8 @@ local function buf_attach(bufnr) local params = { textDocument = { uri = uri } } for _, client in ipairs(clients) do changetracking.reset_buf(client, bufnr) - if client.supports_method(ms.textDocument_didClose) then - client.notify(ms.textDocument_didClose, params) + if client:supports_method(ms.textDocument_didClose) then + client:notify(ms.textDocument_didClose, params) end end for _, client in ipairs(clients) do @@ -662,7 +662,7 @@ function lsp.buf_attach_client(bufnr, client_id) -- Send didOpen for the client if it is initialized. If it isn't initialized -- then it will send didOpen on initialize. if client.initialized then - client:_on_attach(bufnr) + client:on_attach(bufnr) end return true end @@ -740,13 +740,13 @@ function lsp.stop_client(client_id, force) for _, id in ipairs(ids) do if type(id) == 'table' then if id.stop then - id.stop(force) + id:stop(force) end else --- @cast id -vim.lsp.Client local client = all_clients[id] if client then - client.stop(force) + client:stop(force) end end end @@ -790,7 +790,7 @@ function lsp.get_clients(filter) and (filter.id == nil or client.id == filter.id) and (filter.bufnr == nil or client.attached_buffers[bufnr]) and (filter.name == nil or client.name == filter.name) - and (filter.method == nil or client.supports_method(filter.method, { bufnr = filter.bufnr })) + and (filter.method == nil or client:supports_method(filter.method, filter.bufnr)) and (filter._uninitialized or client.initialized) then clients[#clients + 1] = client @@ -812,7 +812,7 @@ api.nvim_create_autocmd('VimLeavePre', { local active_clients = lsp.get_clients() log.info('exit_handler', active_clients) for _, client in pairs(all_clients) do - client.stop() + client:stop() end local timeouts = {} --- @type table @@ -847,7 +847,7 @@ api.nvim_create_autocmd('VimLeavePre', { if not vim.wait(max_timeout, check_clients_closed, poll_time) then for client_id, client in pairs(active_clients) do if timeouts[client_id] ~= nil then - client.stop(true) + client:stop(true) end end end @@ -883,11 +883,11 @@ function lsp.buf_request(bufnr, method, params, handler, on_unsupported) local clients = lsp.get_clients({ bufnr = bufnr }) local client_request_ids = {} --- @type table for _, client in ipairs(clients) do - if client.supports_method(method, { bufnr = bufnr }) then + if client:supports_method(method, bufnr) then method_supported = true local cparams = type(params) == 'function' and params(client, bufnr) or params --[[@as table?]] - local request_success, request_id = client.request(method, cparams, handler, bufnr) + local request_success, request_id = client:request(method, cparams, handler, bufnr) -- This could only fail if the client shut down in the time since we looked -- it up and we did the request, which should be rare. if request_success then @@ -910,7 +910,7 @@ function lsp.buf_request(bufnr, method, params, handler, on_unsupported) local function _cancel_all_requests() for client_id, request_id in pairs(client_request_ids) do local client = all_clients[client_id] - client.cancel_request(request_id) + client:cancel_request(request_id) end end @@ -1049,7 +1049,7 @@ function lsp.formatexpr(opts) end local bufnr = api.nvim_get_current_buf() for _, client in pairs(lsp.get_clients({ bufnr = bufnr })) do - if client.supports_method(ms.textDocument_rangeFormatting) then + if client:supports_method(ms.textDocument_rangeFormatting) then local params = util.make_formatting_params() local end_line = vim.fn.getline(end_lnum) --[[@as string]] local end_col = vim.str_utfindex(end_line, client.offset_encoding) @@ -1065,7 +1065,7 @@ function lsp.formatexpr(opts) }, } local response = - client.request_sync(ms.textDocument_rangeFormatting, params, timeout_ms, bufnr) + client:request_sync(ms.textDocument_rangeFormatting, params, timeout_ms, bufnr) if response and response.result then lsp.util.apply_text_edits(response.result, bufnr, client.offset_encoding) return 0 diff --git a/runtime/lua/vim/lsp/_changetracking.lua b/runtime/lua/vim/lsp/_changetracking.lua index b2be53269f..8588502697 100644 --- a/runtime/lua/vim/lsp/_changetracking.lua +++ b/runtime/lua/vim/lsp/_changetracking.lua @@ -40,7 +40,7 @@ local M = {} --- @class vim.lsp.CTGroupState --- @field buffers table --- @field debounce integer debounce duration in ms ---- @field clients table clients using this state. {client_id, client} +--- @field clients table clients using this state. {client_id, client} ---@param group vim.lsp.CTGroup ---@return string @@ -273,8 +273,8 @@ local function send_changes(bufnr, sync_kind, state, buf_state) end local uri = vim.uri_from_bufnr(bufnr) for _, client in pairs(state.clients) do - if not client.is_stopped() and vim.lsp.buf_is_attached(bufnr, client.id) then - client.notify(protocol.Methods.textDocument_didChange, { + if not client:is_stopped() and vim.lsp.buf_is_attached(bufnr, client.id) then + client:notify(protocol.Methods.textDocument_didChange, { textDocument = { uri = uri, version = util.buf_versions[bufnr], diff --git a/runtime/lua/vim/lsp/_tagfunc.lua b/runtime/lua/vim/lsp/_tagfunc.lua index f75d43f373..f6ffc63824 100644 --- a/runtime/lua/vim/lsp/_tagfunc.lua +++ b/runtime/lua/vim/lsp/_tagfunc.lua @@ -59,7 +59,7 @@ local function query_definition(pattern) remaining = remaining - 1 end local params = util.make_position_params(win, client.offset_encoding) - client.request(ms.textDocument_definition, params, on_response, bufnr) + client:request(ms.textDocument_definition, params, on_response, bufnr) end vim.wait(1000, function() return remaining == 0 diff --git a/runtime/lua/vim/lsp/_watchfiles.lua b/runtime/lua/vim/lsp/_watchfiles.lua index c4cdb5aea8..248969885c 100644 --- a/runtime/lua/vim/lsp/_watchfiles.lua +++ b/runtime/lua/vim/lsp/_watchfiles.lua @@ -116,7 +116,7 @@ function M.register(reg, client_id) local params = { changes = change_queues[client_id], } - client.notify(ms.workspace_didChangeWatchedFiles, params) + client:notify(ms.workspace_didChangeWatchedFiles, params) queue_timers[client_id] = nil change_queues[client_id] = nil change_cache[client_id] = nil diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 6383855a30..10c0dbefdc 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -232,7 +232,7 @@ local function get_locations(method, opts) end for _, client in ipairs(clients) do local params = util.make_position_params(win, client.offset_encoding) - client.request(method, params, function(_, result) + client:request(method, params, function(_, result) on_response(_, result, client) end) end @@ -568,12 +568,14 @@ function M.format(opts) end if opts.async then + --- @param idx integer + --- @param client vim.lsp.Client local function do_format(idx, client) if not client then return end local params = set_range(client, util.make_formatting_params(opts.formatting_options)) - client.request(method, params, function(...) + client:request(method, params, function(...) local handler = client.handlers[method] or lsp.handlers[method] handler(...) do_format(next(clients, idx)) @@ -584,7 +586,7 @@ function M.format(opts) local timeout_ms = opts.timeout_ms or 1000 for _, client in pairs(clients) do local params = set_range(client, util.make_formatting_params(opts.formatting_options)) - local result, err = client.request_sync(method, params, timeout_ms, bufnr) + local result, err = client:request_sync(method, params, timeout_ms, bufnr) if result and result.result then util.apply_text_edits(result.result, bufnr, client.offset_encoding) elseif err then @@ -648,6 +650,8 @@ function M.rename(new_name, opts) )[1] end + --- @param idx integer + --- @param client? vim.lsp.Client local function try_use_client(idx, client) if not client then return @@ -659,15 +663,15 @@ function M.rename(new_name, opts) params.newName = name local handler = client.handlers[ms.textDocument_rename] or lsp.handlers[ms.textDocument_rename] - client.request(ms.textDocument_rename, params, function(...) + client:request(ms.textDocument_rename, params, function(...) handler(...) try_use_client(next(clients, idx)) end, bufnr) end - if client.supports_method(ms.textDocument_prepareRename) then + if client:supports_method(ms.textDocument_prepareRename) then local params = util.make_position_params(win, client.offset_encoding) - client.request(ms.textDocument_prepareRename, params, function(err, result) + client:request(ms.textDocument_prepareRename, params, function(err, result) if err or result == nil then if next(clients, idx) then try_use_client(next(clients, idx)) @@ -706,7 +710,7 @@ function M.rename(new_name, opts) end, bufnr) else assert( - client.supports_method(ms.textDocument_rename), + client:supports_method(ms.textDocument_rename), 'Client must support textDocument/rename' ) if new_name then @@ -781,7 +785,7 @@ function M.references(context, opts) params.context = context or { includeDeclaration = true, } - client.request(ms.textDocument_references, params, function(_, result) + client:request(ms.textDocument_references, params, function(_, result) local items = util.locations_to_items(result or {}, client.offset_encoding) vim.list_extend(all_items, items) remaining = remaining - 1 @@ -813,7 +817,7 @@ local function request_with_id(client_id, method, params, handler, bufnr) ) return end - client.request(method, params, handler, bufnr) + client:request(method, params, handler, bufnr) end --- @param item lsp.TypeHierarchyItem|lsp.CallHierarchyItem @@ -880,7 +884,7 @@ local function hierarchy(method) for _, client in ipairs(clients) do local params = util.make_position_params(win, client.offset_encoding) --- @param result lsp.CallHierarchyItem[]|lsp.TypeHierarchyItem[]? - client.request(prepare_method, params, function(err, result, ctx) + client:request(prepare_method, params, function(err, result, ctx) if err then vim.notify(err.message, vim.log.levels.WARN) elseif result then @@ -1131,8 +1135,8 @@ local function on_code_action_results(results, opts) local action = choice.action local bufnr = assert(choice.ctx.bufnr, 'Must have buffer number') - if not action.edit and client.supports_method(ms.codeAction_resolve) then - client.request(ms.codeAction_resolve, action, function(err, resolved_action) + if not action.edit and client:supports_method(ms.codeAction_resolve) then + client:request(ms.codeAction_resolve, action, function(err, resolved_action) if err then if action.command then apply_action(action, client, choice.ctx) @@ -1253,7 +1257,7 @@ function M.code_action(opts) }) end - client.request(ms.textDocument_codeAction, params, on_result, bufnr) + client:request(ms.textDocument_codeAction, params, on_result, bufnr) end end diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index 11ecb87507..3b79da99ea 100644 --- a/runtime/lua/vim/lsp/client.lua +++ b/runtime/lua/vim/lsp/client.lua @@ -219,70 +219,28 @@ local validate = vim.validate --- @field private registrations table --- @field dynamic_capabilities lsp.DynamicCapabilities --- ---- Sends a request to the server. ---- This is a thin wrapper around {client.rpc.request} with some additional ---- checking. ---- If {handler} is not specified and if there's no respective global ---- handler, then an error will occur. ---- Returns: {status}, {client_id}?. {status} is a boolean indicating if ---- the notification was successful. If it is `false`, then it will always ---- be `false` (the client has shutdown). ---- If {status} is `true`, the function returns {request_id} as the second ---- result. You can use this with `client.cancel_request(request_id)` to cancel ---- the request. ---- @field request fun(method: string, params: table?, handler: lsp.Handler?, bufnr: integer?): boolean, integer? ---- ---- Sends a request to the server and synchronously waits for the response. ---- This is a wrapper around {client.request} ---- Returns: { err=err, result=result }, a dict, where `err` and `result` ---- come from the |lsp-handler|. On timeout, cancel or error, returns `(nil, ---- err)` where `err` is a string describing the failure reason. If the request ---- was unsuccessful returns `nil`. ---- @field request_sync fun(method: string, params: table?, timeout_ms: integer?, bufnr: integer): {err: lsp.ResponseError|nil, result:any}|nil, string|nil err # a dict ---- ---- Sends a notification to an LSP server. ---- Returns: a boolean to indicate if the notification was successful. If ---- it is false, then it will always be false (the client has shutdown). ---- @field notify fun(method: string, params: table?): boolean ---- ---- Cancels a request with a given request id. ---- Returns: same as `notify()`. ---- @field cancel_request fun(id: integer): boolean ---- ---- Stops a client, optionally with force. ---- By default, it will just ask the server to shutdown without force. ---- If you request to stop a client which has previously been requested to ---- shutdown, it will automatically escalate and force shutdown. ---- @field stop fun(force?: boolean) ---- ---- Runs the on_attach function from the client's config if it was defined. ---- Useful for buffer-local setup. ---- @field on_attach fun(bufnr: integer) ---- --- @field private _before_init_cb? vim.lsp.client.before_init_cb --- @field private _on_attach_cbs vim.lsp.client.on_attach_cb[] --- @field private _on_init_cbs vim.lsp.client.on_init_cb[] --- @field private _on_exit_cbs vim.lsp.client.on_exit_cb[] --- @field private _on_error_cb? fun(code: integer, err: string) ---- ---- Checks if a client supports a given method. ---- Always returns true for unknown off-spec methods. ---- {opts} is a optional `{bufnr?: integer}` table. ---- Some language server capabilities can be file specific. ---- @field supports_method fun(method: string, opts?: {bufnr: integer?}): boolean ---- ---- Checks whether a client is stopped. ---- Returns: true if the client is fully stopped. ---- @field is_stopped fun(): boolean local Client = {} Client.__index = Client ---- @param cls table ---- @param meth any ---- @return function -local function method_wrapper(cls, meth) - return function(...) - return meth(cls, ...) +--- @param obj table +--- @param cls table +--- @param name string +local function method_wrapper(obj, cls, name) + local meth = assert(cls[name]) + obj[name] = function(...) + local arg = select(1, ...) + if arg and getmetatable(arg) == cls then + -- First argument is self, call meth directly + return meth(...) + end + vim.deprecate('client.' .. name, 'client:' .. name, '0.13') + -- First argument is not self, insert it + return meth(obj, ...) end end @@ -499,24 +457,23 @@ function Client.create(config) end, } - self.request = method_wrapper(self, Client._request) - self.request_sync = method_wrapper(self, Client._request_sync) - self.notify = method_wrapper(self, Client._notify) - self.cancel_request = method_wrapper(self, Client._cancel_request) - self.stop = method_wrapper(self, Client._stop) - self.is_stopped = method_wrapper(self, Client._is_stopped) - self.on_attach = method_wrapper(self, Client._on_attach) - self.supports_method = method_wrapper(self, Client._supports_method) - --- @type table title of unfinished progress sequences by token self.progress.pending = {} --- @type vim.lsp.rpc.Dispatchers local dispatchers = { - notification = method_wrapper(self, Client._notification), - server_request = method_wrapper(self, Client._server_request), - on_error = method_wrapper(self, Client._on_error), - on_exit = method_wrapper(self, Client._on_exit), + notification = function(...) + return self:_notification(...) + end, + server_request = function(...) + return self:_server_request(...) + end, + on_error = function(...) + return self:_on_error(...) + end, + on_exit = function(...) + return self:_on_exit(...) + end, } -- Start the RPC client. @@ -533,6 +490,15 @@ function Client.create(config) setmetatable(self, Client) + method_wrapper(self, Client, 'request') + method_wrapper(self, Client, 'request_sync') + method_wrapper(self, Client, 'notify') + method_wrapper(self, Client, 'cancel_request') + method_wrapper(self, Client, 'stop') + method_wrapper(self, Client, 'is_stopped') + method_wrapper(self, Client, 'on_attach') + method_wrapper(self, Client, 'supports_method') + return self end @@ -616,7 +582,7 @@ function Client:initialize() end if next(self.settings) then - self:_notify(ms.workspace_didChangeConfiguration, { settings = self.settings }) + self:notify(ms.workspace_didChangeConfiguration, { settings = self.settings }) end -- If server is being restarted, make sure to re-attach to any previously attached buffers. @@ -628,7 +594,7 @@ function Client:initialize() for buf in pairs(reattach_bufs) do -- The buffer may have been detached in the on_init callback. if self.attached_buffers[buf] then - self:_on_attach(buf) + self:on_attach(buf) end end @@ -645,14 +611,14 @@ end --- Returns the default handler if the user hasn't set a custom one. --- --- @param method (string) LSP method name ---- @return lsp.Handler|nil handler for the given method, if defined, or the default from |vim.lsp.handlers| +--- @return lsp.Handler? handler for the given method, if defined, or the default from |vim.lsp.handlers| function Client:_resolve_handler(method) return self.handlers[method] or lsp.handlers[method] end --- Returns the buffer number for the given {bufnr}. --- ---- @param bufnr (integer|nil) Buffer number to resolve. Defaults to current buffer +--- @param bufnr integer? Buffer number to resolve. Defaults to current buffer --- @return integer bufnr local function resolve_bufnr(bufnr) validate('bufnr', bufnr, 'number', true) @@ -662,7 +628,6 @@ local function resolve_bufnr(bufnr) return bufnr end ---- @private --- Sends a request to the server. --- --- This is a thin wrapper around {client.rpc.request} with some additional @@ -671,15 +636,14 @@ end --- @param method string LSP method name. --- @param params? table LSP request params. --- @param handler? lsp.Handler Response |lsp-handler| for this method. ---- @param bufnr integer Buffer handle (0 for current). ---- @return boolean status, integer? request_id {status} is a bool indicating ---- whether the request was successful. If it is `false`, then it will ---- always be `false` (the client has shutdown). If it was ---- successful, then it will return {request_id} as the ---- second result. You can use this with `client.cancel_request(request_id)` +--- @param bufnr? integer Buffer handle. 0 for current (default). +--- @return boolean status indicates whether the request was successful. +--- If it is `false`, then it will always be `false` (the client has shutdown). +--- @return integer? request_id Can be used with |Client:cancel_request()|. +--- `nil` is request failed. --- to cancel the-request. --- @see |vim.lsp.buf_request_all()| -function Client:_request(method, params, handler, bufnr) +function Client:request(method, params, handler, bufnr) if not handler then handler = assert( self:_resolve_handler(method), @@ -688,8 +652,8 @@ function Client:_request(method, params, handler, bufnr) end -- Ensure pending didChange notifications are sent so that the server doesn't operate on a stale state changetracking.flush(self, bufnr) - local version = lsp.util.buf_versions[bufnr] bufnr = resolve_bufnr(bufnr) + local version = lsp.util.buf_versions[bufnr] log.debug(self._log_prefix, 'client.request', self.id, method, params, handler, bufnr) local success, request_id = self.rpc.request(method, params, function(err, result) local context = { @@ -743,29 +707,27 @@ local function err_message(...) end end ---- @private --- Sends a request to the server and synchronously waits for the response. --- ---- This is a wrapper around {client.request} +--- This is a wrapper around |Client:request()| --- ---- @param method (string) LSP method name. ---- @param params (table) LSP request params. ---- @param timeout_ms (integer|nil) Maximum time in milliseconds to wait for +--- @param method string LSP method name. +--- @param params table LSP request params. +--- @param timeout_ms integer? Maximum time in milliseconds to wait for --- a result. Defaults to 1000 ---- @param bufnr (integer) Buffer handle (0 for current). ---- @return {err: lsp.ResponseError|nil, result:any}|nil, string|nil err # a dict, where ---- `err` and `result` come from the |lsp-handler|. ---- On timeout, cancel or error, returns `(nil, err)` where `err` is a ---- string describing the failure reason. If the request was unsuccessful ---- returns `nil`. +--- @param bufnr integer Buffer handle (0 for current). +--- @return {err: lsp.ResponseError?, result:any}? `result` and `err` from the |lsp-handler|. +--- `nil` is the request was unsuccessful +--- @return string? err On timeout, cancel or error, where `err` is a +--- string describing the failure reason. --- @see |vim.lsp.buf_request_sync()| -function Client:_request_sync(method, params, timeout_ms, bufnr) +function Client:request_sync(method, params, timeout_ms, bufnr) local request_result = nil local function _sync_handler(err, result) request_result = { err = err, result = result } end - local success, request_id = self:_request(method, params, _sync_handler, bufnr) + local success, request_id = self:request(method, params, _sync_handler, bufnr) if not success then return nil end @@ -776,22 +738,20 @@ function Client:_request_sync(method, params, timeout_ms, bufnr) if not wait_result then if request_id then - self:_cancel_request(request_id) + self:cancel_request(request_id) end return nil, wait_result_reason[reason] end return request_result end ---- @package --- Sends a notification to an LSP server. --- --- @param method string LSP method name. ---- @param params table|nil LSP request params. ---- @return boolean status true if the notification was successful. ---- If it is false, then it will always be false ---- (the client has shutdown). -function Client:_notify(method, params) +--- @param params table? LSP request params. +--- @return boolean status indicating if the notification was successful. +--- If it is false, then the client has shutdown. +function Client:notify(method, params) if method ~= ms.textDocument_didChange then changetracking.flush(self) end @@ -814,13 +774,12 @@ function Client:_notify(method, params) return client_active end ---- @private --- Cancels a request with a given request id. --- ---- @param id (integer) id of request to cancel ---- @return boolean status true if notification was successful. false otherwise ---- @see |vim.lsp.client.notify()| -function Client:_cancel_request(id) +--- @param id integer id of request to cancel +--- @return boolean status indicating if the notification was successful. +--- @see |Client:notify()| +function Client:cancel_request(id) validate('id', id, 'number') local request = self.requests[id] if request and request.type == 'pending' then @@ -834,15 +793,14 @@ function Client:_cancel_request(id) return self.rpc.notify(ms.dollar_cancelRequest, { id = id }) end ---- @private --- Stops a client, optionally with force. --- ---- By default, it will just ask the - server to shutdown without force. If +--- By default, it will just request the server to shutdown without force. If --- you request to stop a client which has previously been requested to --- shutdown, it will automatically escalate and force shutdown. --- ---- @param force boolean|nil -function Client:_stop(force) +--- @param force? boolean +function Client:stop(force) local rpc = self.rpc if rpc.is_closing() then @@ -966,12 +924,11 @@ function Client:_get_registration(method, bufnr) end end ---- @private --- Checks whether a client is stopped. --- --- @return boolean # true if client is stopped or in the process of being --- stopped; false otherwise -function Client:_is_stopped() +function Client:is_stopped() return self.rpc.is_closing() end @@ -1013,7 +970,7 @@ function Client:exec_cmd(command, context, handler) command = cmdname, arguments = command.arguments, } - self.request(ms.workspace_executeCommand, params, handler, context.bufnr) + self:request(ms.workspace_executeCommand, params, handler, context.bufnr) end --- Default handler for the 'textDocument/didOpen' LSP notification. @@ -1021,14 +978,14 @@ end --- @param bufnr integer Number of the buffer, or 0 for current function Client:_text_document_did_open_handler(bufnr) changetracking.init(self, bufnr) - if not self.supports_method(ms.textDocument_didOpen) then + if not self:supports_method(ms.textDocument_didOpen) then return end if not api.nvim_buf_is_loaded(bufnr) then return end - self.notify(ms.textDocument_didOpen, { + self:notify(ms.textDocument_didOpen, { textDocument = { version = lsp.util.buf_versions[bufnr], uri = vim.uri_from_bufnr(bufnr), @@ -1049,8 +1006,9 @@ function Client:_text_document_did_open_handler(bufnr) end --- Runs the on_attach function from the client's config if it was defined. +--- Useful for buffer-local setup. --- @param bufnr integer Buffer number -function Client:_on_attach(bufnr) +function Client:on_attach(bufnr) self:_text_document_did_open_handler(bufnr) lsp._set_defaults(self, bufnr) @@ -1085,10 +1043,18 @@ function Client:write_error(code, err) err_message(self._log_prefix, ': Error ', client_error, ': ', vim.inspect(err)) end ---- @private +--- Checks if a client supports a given method. +--- Always returns true for unknown off-spec methods. +--- +--- Note: Some language server capabilities can be file specific. --- @param method string ---- @param opts? {bufnr: integer?} -function Client:_supports_method(method, opts) +--- @param bufnr? integer +function Client:supports_method(method, bufnr) + -- Deprecated form + if type(bufnr) == 'table' then + --- @diagnostic disable-next-line:no-unknown + bufnr = bufnr.bufnr + end local required_capability = lsp._request_name_to_capability[method] -- if we don't know about the method, assume that the client supports it. if not required_capability then @@ -1101,12 +1067,12 @@ function Client:_supports_method(method, opts) local rmethod = lsp._resolve_to_request[method] if rmethod then if self:_supports_registration(rmethod) then - local reg = self:_get_registration(rmethod, opts and opts.bufnr) + local reg = self:_get_registration(rmethod, bufnr) return vim.tbl_get(reg or {}, 'registerOptions', 'resolveProvider') or false end else if self:_supports_registration(method) then - return self:_get_registration(method, opts and opts.bufnr) ~= nil + return self:_get_registration(method, bufnr) ~= nil end end return false @@ -1207,7 +1173,7 @@ function Client:_add_workspace_folder(dir) local wf = assert(get_workspace_folders(dir)) - self:_notify(ms.workspace_didChangeWorkspaceFolders, { + self:notify(ms.workspace_didChangeWorkspaceFolders, { event = { added = wf, removed = {} }, }) @@ -1222,7 +1188,7 @@ end function Client:_remove_workspace_folder(dir) local wf = assert(get_workspace_folders(dir)) - self:_notify(ms.workspace_didChangeWorkspaceFolders, { + self:notify(ms.workspace_didChangeWorkspaceFolders, { event = { added = {}, removed = wf }, }) diff --git a/runtime/lua/vim/lsp/codelens.lua b/runtime/lua/vim/lsp/codelens.lua index fdbdda695a..a11f84d6c6 100644 --- a/runtime/lua/vim/lsp/codelens.lua +++ b/runtime/lua/vim/lsp/codelens.lua @@ -231,7 +231,7 @@ local function resolve_lenses(lenses, bufnr, client_id, callback) countdown() else assert(client) - client.request(ms.codeLens_resolve, lens, function(_, result) + client:request(ms.codeLens_resolve, lens, function(_, result) if api.nvim_buf_is_loaded(bufnr) and result and result.command then lens.command = result.command -- Eager display to have some sort of incremental feedback diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua index 92bc110a97..0f388a88fd 100644 --- a/runtime/lua/vim/lsp/completion.lua +++ b/runtime/lua/vim/lsp/completion.lua @@ -404,7 +404,7 @@ local function request(clients, bufnr, win, callback) for _, client in pairs(clients) do local client_id = client.id local params = lsp.util.make_position_params(win, client.offset_encoding) - local ok, request_id = client.request(ms.textDocument_completion, params, function(err, result) + local ok, request_id = client:request(ms.textDocument_completion, params, function(err, result) responses[client_id] = { err = err, result = result } remaining_requests = remaining_requests - 1 if remaining_requests == 0 then @@ -421,7 +421,7 @@ local function request(clients, bufnr, win, callback) for client_id, request_id in pairs(request_ids) do local client = lsp.get_client_by_id(client_id) if client then - client.cancel_request(request_id) + client:cancel_request(request_id) end end end @@ -582,7 +582,7 @@ local function on_complete_done() local changedtick = vim.b[bufnr].changedtick --- @param result lsp.CompletionItem - client.request(ms.completionItem_resolve, completion_item, function(err, result) + client:request(ms.completionItem_resolve, completion_item, function(err, result) if changedtick ~= vim.b[bufnr].changedtick then return end diff --git a/runtime/lua/vim/lsp/inlay_hint.lua b/runtime/lua/vim/lsp/inlay_hint.lua index f1ae9a8e9e..f1a58de621 100644 --- a/runtime/lua/vim/lsp/inlay_hint.lua +++ b/runtime/lua/vim/lsp/inlay_hint.lua @@ -122,12 +122,12 @@ end --- 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) ---- local resp = client.request_sync('inlayHint/resolve', hint.inlay_hint, 100, 0) +--- local resp = client:request_sync('inlayHint/resolve', hint.inlay_hint, 100, 0) --- local resolved_hint = assert(resp and resp.result, resp.err) --- vim.lsp.util.apply_text_edits(resolved_hint.textEdits, 0, client.encoding) --- --- location = resolved_hint.label[1].location ---- client.request('textDocument/hover', { +--- client:request('textDocument/hover', { --- textDocument = { uri = location.uri }, --- position = location.range.start, --- }) diff --git a/runtime/lua/vim/lsp/semantic_tokens.lua b/runtime/lua/vim/lsp/semantic_tokens.lua index 215e5f41aa..01421fea29 100644 --- a/runtime/lua/vim/lsp/semantic_tokens.lua +++ b/runtime/lua/vim/lsp/semantic_tokens.lua @@ -273,7 +273,7 @@ function STHighlighter:send_request() if client and current_result.version ~= version and active_request.version ~= version then -- cancel stale in-flight request if active_request.request_id then - client.cancel_request(active_request.request_id) + client:cancel_request(active_request.request_id) active_request = {} state.active_request = active_request end @@ -288,7 +288,7 @@ function STHighlighter:send_request() method = method .. '/delta' params.previousResultId = current_result.result_id end - local success, request_id = client.request(method, params, function(err, response, ctx) + local success, request_id = client:request(method, params, function(err, response, ctx) -- look client up again using ctx.client_id instead of using a captured -- client object local c = vim.lsp.get_client_by_id(ctx.client_id) @@ -519,7 +519,7 @@ function STHighlighter:reset() if state.active_request.request_id then local client = vim.lsp.get_client_by_id(client_id) assert(client) - client.cancel_request(state.active_request.request_id) + client:cancel_request(state.active_request.request_id) state.active_request = {} end end @@ -547,7 +547,7 @@ function STHighlighter:mark_dirty(client_id) if state.active_request.request_id then local client = vim.lsp.get_client_by_id(client_id) assert(client) - client.cancel_request(state.active_request.request_id) + client:cancel_request(state.active_request.request_id) state.active_request = {} end end diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 6eab0f3da4..9e352dbcfd 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -2122,7 +2122,7 @@ function M._refresh(method, opts) local first = vim.fn.line('w0', window) local last = vim.fn.line('w$', window) for _, client in ipairs(clients) do - client.request(method, { + client:request(method, { textDocument = textDocument, range = make_line_range_params(bufnr, first - 1, last - 1, client.offset_encoding), }, nil, bufnr) @@ -2131,7 +2131,7 @@ function M._refresh(method, opts) end else for _, client in ipairs(clients) do - client.request(method, { + client:request(method, { textDocument = textDocument, range = make_line_range_params( bufnr, -- cgit From 629483e24eed3f2c07e55e0540c553361e0345a2 Mon Sep 17 00:00:00 2001 From: Yi Ming Date: Thu, 21 Nov 2024 04:19:07 +0800 Subject: feat(lsp): require `offset_encoding` param #31249 Problem: Since [version 3.17](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocuments), LSP supports specifying the position encoding (aka offset encoding) supported by the client through `positionEncoding`. Since #31209, Nvim fully supports `utf-8`, `utf-16`, and `utf-32` encodings. Previously, nvim assumed all clients for a buffer had the same `offset_encoding`, so: * Nvim provides `vim.lsp._get_offset_encoding()` to get `offset_encoding`, but this function is incorrect because `offset_encoding` is per-client, not per-buffer. * Based on the strategy of `vim.lsp._get_offset_encoding()`, `vim.lsp.util.make_position_params()`, `vim.lsp.util.make_range_params()`, and `vim.lsp.util.make_given_range_params()` do not require the caller to pass `offset_encoding`, which is invalid. * https://github.com/neovim/neovim/issues/25272 Solution: * Mark `vim.lsp._get_offset_encoding()` as `@deprecated`. * Change the type annotations of `vim.lsp.util.make_position_params()`, `vim.lsp.util.make_range_params()`, `vim.lsp.util.make_given_range_params()` to require the `offset_encoding` param. --- runtime/lua/vim/lsp/util.lua | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 9e352dbcfd..cfa8a194d9 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -1848,12 +1848,11 @@ function M.try_trim_markdown_code_blocks(lines) end ---@param window integer?: window handle or 0 for current, defaults to current ----@param offset_encoding? 'utf-8'|'utf-16'|'utf-32'? defaults to `offset_encoding` of first client of buffer of `window` +---@param offset_encoding 'utf-8'|'utf-16'|'utf-32' local function make_position_param(window, offset_encoding) window = window or 0 local buf = api.nvim_win_get_buf(window) local row, col = unpack(api.nvim_win_get_cursor(window)) - offset_encoding = offset_encoding or M._get_offset_encoding(buf) row = row - 1 local line = api.nvim_buf_get_lines(buf, row, row + 1, true)[1] if not line then @@ -1868,13 +1867,19 @@ end --- Creates a `TextDocumentPositionParams` object for the current buffer and cursor position. --- ---@param window integer?: window handle or 0 for current, defaults to current ----@param offset_encoding 'utf-8'|'utf-16'|'utf-32'? defaults to `offset_encoding` of first client of buffer of `window` +---@param offset_encoding 'utf-8'|'utf-16'|'utf-32' ---@return lsp.TextDocumentPositionParams ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentPositionParams function M.make_position_params(window, offset_encoding) window = window or 0 local buf = api.nvim_win_get_buf(window) - offset_encoding = offset_encoding or M._get_offset_encoding(buf) + if offset_encoding == nil then + vim.notify_once( + 'warning: offset_encoding is required, using the offset_encoding from the first client', + vim.log.levels.WARN + ) + offset_encoding = M._get_offset_encoding(buf) + end return { textDocument = M.make_text_document_params(buf), position = make_position_param(window, offset_encoding), @@ -1882,6 +1887,7 @@ function M.make_position_params(window, offset_encoding) end --- Utility function for getting the encoding of the first LSP client on the given buffer. +---@deprecated ---@param bufnr integer buffer handle or 0 for current, defaults to current ---@return string encoding first client if there is one, nil otherwise function M._get_offset_encoding(bufnr) @@ -1904,7 +1910,7 @@ function M._get_offset_encoding(bufnr) offset_encoding = this_offset_encoding elseif offset_encoding ~= this_offset_encoding then vim.notify_once( - 'warning: multiple different client offset_encodings detected for buffer, this is not supported yet', + 'warning: multiple different client offset_encodings detected for buffer, vim.lsp.util._get_offset_encoding() uses the offset_encoding from the first client', vim.log.levels.WARN ) end @@ -1919,12 +1925,17 @@ end --- `textDocument/rangeFormatting`. --- ---@param window integer? window handle or 0 for current, defaults to current ----@param offset_encoding "utf-8"|"utf-16"|"utf-32"? defaults to `offset_encoding` of first client of buffer of `window` ----@return table { textDocument = { uri = `current_file_uri` }, range = { start = ----`current_position`, end = `current_position` } } +---@param offset_encoding "utf-8"|"utf-16"|"utf-32" +---@return { textDocument: { uri: lsp.DocumentUri }, range: lsp.Range } function M.make_range_params(window, offset_encoding) local buf = api.nvim_win_get_buf(window or 0) - offset_encoding = offset_encoding or M._get_offset_encoding(buf) + if offset_encoding == nil then + vim.notify_once( + 'warning: offset_encoding is required, using the offset_encoding from the first client', + vim.log.levels.WARN + ) + offset_encoding = M._get_offset_encoding(buf) + end local position = make_position_param(window, offset_encoding) return { textDocument = M.make_text_document_params(buf), @@ -1940,15 +1951,20 @@ end ---@param end_pos [integer,integer]? {row,col} mark-indexed position. --- Defaults to the end of the last visual selection. ---@param bufnr integer? buffer handle or 0 for current, defaults to current ----@param offset_encoding 'utf-8'|'utf-16'|'utf-32'? defaults to `offset_encoding` of first client of `bufnr` ----@return table { textDocument = { uri = `current_file_uri` }, range = { start = ----`start_position`, end = `end_position` } } +---@param offset_encoding 'utf-8'|'utf-16'|'utf-32' +---@return { textDocument: { uri: lsp.DocumentUri }, range: lsp.Range } function M.make_given_range_params(start_pos, end_pos, bufnr, offset_encoding) validate('start_pos', start_pos, 'table', true) validate('end_pos', end_pos, 'table', true) validate('offset_encoding', offset_encoding, 'string', true) bufnr = bufnr or api.nvim_get_current_buf() - offset_encoding = offset_encoding or M._get_offset_encoding(bufnr) + if offset_encoding == nil then + vim.notify_once( + 'warning: offset_encoding is required, using the offset_encoding from the first client', + vim.log.levels.WARN + ) + offset_encoding = M._get_offset_encoding(bufnr) + end --- @type [integer, integer] local A = { unpack(start_pos or api.nvim_buf_get_mark(bufnr, '<')) } --- @type [integer, integer] -- cgit From cedf155fb5c4d687747e59f5d3fdad76a40aa069 Mon Sep 17 00:00:00 2001 From: zshuzh <40901142+zshuzh@users.noreply.github.com> Date: Wed, 20 Nov 2024 22:01:59 +0000 Subject: refactor(options): impl default 'titlestring' by format flags #30843 Problem: Unnecessary C impl of default 'titlestring'. Solutin: Define it using format flags. --- runtime/lua/vim/_meta/options.lua | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua index cb783720ac..e485009ca2 100644 --- a/runtime/lua/vim/_meta/options.lua +++ b/runtime/lua/vim/_meta/options.lua @@ -7122,6 +7122,13 @@ vim.go.titleold = vim.o.titleold --- expanded according to the rules used for 'statusline'. If it contains --- an invalid '%' format, the value is used as-is and no error or warning --- will be given when the value is set. +--- +--- The default behaviour is equivalent to: +--- +--- ```vim +--- set titlestring=%t%(\ %M%)%(\ \(%{expand(\"%:~:h\")}\)%)%a\ -\ Nvim +--- ``` +--- --- This option cannot be set in a modeline when 'modelineexpr' is off. --- --- Example: -- cgit From 7d8db544417e7811ae6e3c5398e9d0481a0ada22 Mon Sep 17 00:00:00 2001 From: glepnir Date: Fri, 22 Nov 2024 15:34:49 +0800 Subject: fix(lsp): delete b:lsp_floating_preview buf var after win close Problem: After floating preview window closed the buf var still exist Solution: delete after floating window closed. --- runtime/lua/vim/lsp/util.lua | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index cfa8a194d9..24837c3b44 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -1344,6 +1344,10 @@ local function close_preview_window(winnr, bufnrs) local augroup = 'preview_window_' .. winnr pcall(api.nvim_del_augroup_by_name, augroup) + local buf = vim.w[winnr].buf_hold_win + if buf and api.nvim_buf_is_valid(buf) then + vim.b[buf].lsp_floating_window = nil + end pcall(api.nvim_win_close, winnr, true) end) end @@ -1609,6 +1613,7 @@ function M.open_floating_preview(contents, syntax, opts) { silent = true, noremap = true, nowait = true } ) close_preview_autocmd(opts.close_events, floating_winnr, { floating_bufnr, bufnr }) + vim.w[floating_winnr].buf_hold_win = bufnr -- save focus_id if opts.focus_id then -- cgit From 9a681ad09e2add96d47bf3f39cca8029f3bf09df Mon Sep 17 00:00:00 2001 From: andrew snelling <72226000+snelling-a@users.noreply.github.com> Date: Fri, 22 Nov 2024 13:51:30 +0100 Subject: fix(lsp): hover keymap (#31208) * fix: use function call in keymap * fix: test --- runtime/lua/vim/lsp.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index c032d25cb1..6d29c9e4df 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -371,7 +371,9 @@ function lsp._set_defaults(client, bufnr) and is_empty_or_default(bufnr, 'keywordprg') and vim.fn.maparg('K', 'n', false, false) == '' then - vim.keymap.set('n', 'K', vim.lsp.buf.hover, { buffer = bufnr, desc = 'vim.lsp.buf.hover()' }) + vim.keymap.set('n', 'K', function() + vim.lsp.buf.hover() + end, { buffer = bufnr, desc = 'vim.lsp.buf.hover()' }) end end) if client:supports_method(ms.textDocument_diagnostic) then -- cgit From 2a1f604c77a161f076f7d520d66fc6f051b625e7 Mon Sep 17 00:00:00 2001 From: glepnir Date: Sat, 23 Nov 2024 19:11:30 +0800 Subject: fix(lsp): delete bufvar inside WinClosed event Problem: floaing preview window can be closed by some ex commands like `only` `fclose` which will not clean the bufvar Solution: use WinClosed event with floating_winnr for clean bufnr, and add test cases for vim.lsp.util.open_floating_preview --- runtime/lua/vim/lsp/util.lua | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 24837c3b44..0f608ffbd1 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -1344,10 +1344,6 @@ local function close_preview_window(winnr, bufnrs) local augroup = 'preview_window_' .. winnr pcall(api.nvim_del_augroup_by_name, augroup) - local buf = vim.w[winnr].buf_hold_win - if buf and api.nvim_buf_is_valid(buf) then - vim.b[buf].lsp_floating_window = nil - end pcall(api.nvim_win_close, winnr, true) end) end @@ -1613,7 +1609,6 @@ function M.open_floating_preview(contents, syntax, opts) { silent = true, noremap = true, nowait = true } ) close_preview_autocmd(opts.close_events, floating_winnr, { floating_bufnr, bufnr }) - vim.w[floating_winnr].buf_hold_win = bufnr -- save focus_id if opts.focus_id then @@ -1622,6 +1617,22 @@ function M.open_floating_preview(contents, syntax, opts) api.nvim_buf_set_var(bufnr, 'lsp_floating_preview', floating_winnr) end + local augroup_name = ('closing_floating_preview_%d'):format(floating_winnr) + local ok = + pcall(api.nvim_get_autocmds, { group = augroup_name, pattern = tostring(floating_winnr) }) + if not ok then + api.nvim_create_autocmd('WinClosed', { + group = api.nvim_create_augroup(augroup_name, {}), + pattern = tostring(floating_winnr), + callback = function() + if api.nvim_buf_is_valid(bufnr) then + vim.b[bufnr].lsp_floating_preview = nil + end + api.nvim_del_augroup_by_name(augroup_name) + end, + }) + end + if do_stylize then vim.wo[floating_winnr].conceallevel = 2 end -- cgit From 5c603064421b8829cf106c845902fcc41d3e31f2 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 24 Nov 2024 22:36:33 +0800 Subject: vim-patch:9.1.0883: message history cleanup is missing some tests (#31331) Problem: message history cleanup is missing some tests Solution: Add tests, refactor common code into did_set_msghistory() (Shougo Matsushita) closes: vim/vim#16078 https://github.com/vim/vim/commit/9f860a14c308f7a9a27a6850d36790615717a710 Co-authored-by: Shougo Matsushita Co-authored-by: Milly --- runtime/lua/vim/_meta/options.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua index e485009ca2..c635d9bd3b 100644 --- a/runtime/lua/vim/_meta/options.lua +++ b/runtime/lua/vim/_meta/options.lua @@ -4381,6 +4381,7 @@ vim.go.mouset = vim.go.mousetime --- Determines how many entries are remembered in the `:messages` history. --- The maximum value is 10000. +--- Setting it to zero clears the message history. --- --- @type integer vim.o.msghistory = 500 -- cgit From ff00d583af8f1ce21a508d701d09c54d2621b16e Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Sun, 24 Nov 2024 15:05:48 +0100 Subject: vim-patch:9.1.0886: filetype: debian control file not detected Problem: filetype: debian control file not detected Solution: detect 'debian/control' files as debcontrol filetype (author) closes: vim/vim#16067 https://github.com/vim/vim/commit/57b947e3c3b8d52b914158979263855d785445d5 Co-authored-by: Wu, Zhenyu --- runtime/lua/vim/filetype.lua | 2 ++ runtime/lua/vim/filetype/detect.lua | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index 4383c0983e..aa566973b6 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -1490,6 +1490,7 @@ local filename = { ['NEWS.dch'] = 'debchangelog', ['NEWS.Debian'] = 'debchangelog', ['/debian/control'] = 'debcontrol', + ['/DEBIAN/control'] = 'debcontrol', ['/debian/copyright'] = 'debcopyright', ['/etc/apt/sources.list'] = 'debsources', ['denyhosts.conf'] = 'denyhosts', @@ -2319,6 +2320,7 @@ local pattern = { ['%.cmake%.in$'] = 'cmake', ['^crontab%.'] = starsetf('crontab'), ['^cvs%d+$'] = 'cvs', + ['/DEBIAN/control$'] = 'debcontrol', ['^php%.ini%-'] = 'dosini', ['^php%-fpm%.conf'] = 'dosini', ['^www%.conf'] = 'dosini', diff --git a/runtime/lua/vim/filetype/detect.lua b/runtime/lua/vim/filetype/detect.lua index 81b94c69db..4f2fef5b1f 100644 --- a/runtime/lua/vim/filetype/detect.lua +++ b/runtime/lua/vim/filetype/detect.lua @@ -237,7 +237,8 @@ end --- Debian Control --- @type vim.filetype.mapfn function M.control(_, bufnr) - if getline(bufnr, 1):find('^Source:') then + local line1 = getline(bufnr, 1) + if line1 and findany(line1, { '^Source:', '^Package:' }) then return 'debcontrol' end end -- cgit From 165b099fa38c5f4a9855cda3d13575bf63767647 Mon Sep 17 00:00:00 2001 From: Yi Ming Date: Tue, 26 Nov 2024 00:06:05 +0800 Subject: refactor(lsp): rename `offset_encoding` to `position_encoding` #31286 Problem: LSP spec uses the term "position encoding" where we say "offset encoding". Solution: - Rename it everywhere except `vim.lsp.Client.offset_encoding` (which would be breaking). - Mention "position encoding" in the documentation for `vim.lsp.Client.offset_encoding`. --- runtime/lua/vim/lsp/_changetracking.lua | 10 +-- runtime/lua/vim/lsp/_tagfunc.lua | 16 ++-- runtime/lua/vim/lsp/buf.lua | 8 +- runtime/lua/vim/lsp/client.lua | 11 ++- runtime/lua/vim/lsp/completion.lua | 6 +- runtime/lua/vim/lsp/diagnostic.lua | 6 +- runtime/lua/vim/lsp/sync.lua | 52 ++++++------ runtime/lua/vim/lsp/util.lua | 140 +++++++++++++++++--------------- 8 files changed, 130 insertions(+), 119 deletions(-) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/lsp/_changetracking.lua b/runtime/lua/vim/lsp/_changetracking.lua index 8588502697..c2ff66b90e 100644 --- a/runtime/lua/vim/lsp/_changetracking.lua +++ b/runtime/lua/vim/lsp/_changetracking.lua @@ -18,14 +18,14 @@ local M = {} --- --- None: One group for all clients --- Full: One group for all clients ---- Incremental: One group per `offset_encoding` +--- Incremental: One group per `position_encoding` --- --- Sending changes can be debounced per buffer. To simplify the implementation the --- smallest debounce interval is used and we don't group clients by different intervals. --- --- @class vim.lsp.CTGroup --- @field sync_kind integer TextDocumentSyncKind, considers config.flags.allow_incremental_sync ---- @field offset_encoding "utf-8"|"utf-16"|"utf-32" +--- @field position_encoding "utf-8"|"utf-16"|"utf-32" --- --- @class vim.lsp.CTBufferState --- @field name string name of the buffer @@ -46,7 +46,7 @@ local M = {} ---@return string local function group_key(group) if group.sync_kind == protocol.TextDocumentSyncKind.Incremental then - return tostring(group.sync_kind) .. '\0' .. group.offset_encoding + return tostring(group.sync_kind) .. '\0' .. group.position_encoding end return tostring(group.sync_kind) end @@ -72,7 +72,7 @@ local function get_group(client) end return { sync_kind = sync_kind, - offset_encoding = client.offset_encoding, + position_encoding = client.offset_encoding, } end @@ -310,7 +310,7 @@ local function send_changes_for_group(bufnr, firstline, lastline, new_lastline, -- The contents would further change and startline/endline may no longer fit local changes = incremental_changes( buf_state, - group.offset_encoding, + group.position_encoding, bufnr, firstline, lastline, diff --git a/runtime/lua/vim/lsp/_tagfunc.lua b/runtime/lua/vim/lsp/_tagfunc.lua index f6ffc63824..554f0cb991 100644 --- a/runtime/lua/vim/lsp/_tagfunc.lua +++ b/runtime/lua/vim/lsp/_tagfunc.lua @@ -6,12 +6,12 @@ local ms = lsp.protocol.Methods ---@param name string ---@param range lsp.Range ---@param uri string ----@param offset_encoding string +---@param position_encoding string ---@return {name: string, filename: string, cmd: string, kind?: string} -local function mk_tag_item(name, range, uri, offset_encoding) +local function mk_tag_item(name, range, uri, position_encoding) local bufnr = vim.uri_to_bufnr(uri) -- This is get_line_byte_from_position is 0-indexed, call cursor expects a 1-indexed position - local byte = util._get_line_byte_from_position(bufnr, range.start, offset_encodin