aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua')
-rw-r--r--runtime/lua/vim/_editor.lua66
-rw-r--r--runtime/lua/vim/diagnostic.lua8
-rw-r--r--runtime/lua/vim/filetype.lua40
-rw-r--r--runtime/lua/vim/filetype/detect.lua2
-rw-r--r--runtime/lua/vim/keymap.lua26
-rw-r--r--runtime/lua/vim/lsp.lua26
-rw-r--r--runtime/lua/vim/lsp/buf.lua99
-rw-r--r--runtime/lua/vim/lsp/handlers.lua52
-rw-r--r--runtime/lua/vim/lsp/protocol.lua1
-rw-r--r--runtime/lua/vim/lsp/util.lua24
10 files changed, 225 insertions, 119 deletions
diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua
index 442d7b07d8..b8a7f71145 100644
--- a/runtime/lua/vim/_editor.lua
+++ b/runtime/lua/vim/_editor.lua
@@ -288,6 +288,9 @@ end
--- Execute Vim script commands.
---
+--- Note that `vim.cmd` can be indexed with a command name to return a callable function to the
+--- command.
+---
--- Example:
--- <pre>
--- vim.cmd('echo 42')
@@ -297,7 +300,23 @@ end
--- autocmd FileType c setlocal cindent
--- augroup END
--- ]])
---- vim.cmd({ cmd = 'echo', args = { '"foo"' } })
+---
+--- -- Ex command :echo "foo"
+--- -- Note string literals need to be double quoted.
+--- vim.cmd('echo "foo"')
+--- vim.cmd { cmd = 'echo', args = { '"foo"' } }
+--- vim.cmd.echo({ args = { '"foo"' } })
+--- vim.cmd.echo('"foo"')
+---
+--- -- Ex command :write! myfile.txt
+--- vim.cmd('write! myfile.txt')
+--- vim.cmd { cmd = 'write', args = { "myfile.txt" }, bang = true }
+--- vim.cmd.write { args = { "myfile.txt" }, bang = true }
+--- vim.cmd.write { "myfile.txt", bang = true }
+---
+--- -- Ex command :colorscheme blue
+--- vim.cmd('colorscheme blue')
+--- vim.cmd.colorscheme('blue')
--- </pre>
---
---@param command string|table Command(s) to execute.
@@ -307,14 +326,47 @@ end
--- If a table, executes a single command. In this case, it is an alias
--- to |nvim_cmd()| where `opts` is empty.
---@see |ex-cmd-index|
-function vim.cmd(command)
- if type(command) == 'table' then
- return vim.api.nvim_cmd(command, {})
- else
- return vim.api.nvim_exec(command, false)
- end
+function vim.cmd(command) -- luacheck: no unused
+ error(command) -- Stub for gen_vimdoc.py
end
+local VIM_CMD_ARG_MAX = 20
+
+vim.cmd = setmetatable({}, {
+ __call = function(_, command)
+ if type(command) == 'table' then
+ return vim.api.nvim_cmd(command, {})
+ else
+ return vim.api.nvim_exec(command, false)
+ end
+ end,
+ __index = function(t, command)
+ t[command] = function(...)
+ local opts
+ if select('#', ...) == 1 and type(select(1, ...)) == 'table' then
+ opts = select(1, ...)
+
+ -- Move indexed positions in opts to opt.args
+ if opts[1] and not opts.args then
+ opts.args = {}
+ for i = 1, VIM_CMD_ARG_MAX do
+ if not opts[i] then
+ break
+ end
+ opts.args[i] = opts[i]
+ opts[i] = nil
+ end
+ end
+ else
+ opts = { args = { ... } }
+ end
+ opts.cmd = command
+ return vim.api.nvim_cmd(opts, {})
+ end
+ return t[command]
+ end,
+})
+
-- These are the vim.env/v/g/o/bo/wo variable magic accessors.
do
local validate = vim.validate
diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua
index ae20b5c517..3f71d4f70d 100644
--- a/runtime/lua/vim/diagnostic.lua
+++ b/runtime/lua/vim/diagnostic.lua
@@ -586,12 +586,12 @@ end
---
--- For example, if a user enables virtual text globally with
--- <pre>
---- vim.diagnostic.config({virtual_text = true})
+--- vim.diagnostic.config({ virtual_text = true })
--- </pre>
---
--- and a diagnostic producer sets diagnostics with
--- <pre>
---- vim.diagnostic.set(ns, 0, diagnostics, {virtual_text = false})
+--- vim.diagnostic.set(ns, 0, diagnostics, { virtual_text = false })
--- </pre>
---
--- then virtual text will not be enabled for those diagnostics.
@@ -1525,8 +1525,8 @@ end
--- <pre>
--- local s = "WARNING filename:27:3: Variable 'foo' does not exist"
--- local pattern = "^(%w+) %w+:(%d+):(%d+): (.+)$"
---- local groups = {"severity", "lnum", "col", "message"}
---- vim.diagnostic.match(s, pattern, groups, {WARNING = vim.diagnostic.WARN})
+--- local groups = { "severity", "lnum", "col", "message" }
+--- vim.diagnostic.match(s, pattern, groups, { WARNING = vim.diagnostic.WARN })
--- </pre>
---
---@param str string String to parse diagnostics from.
diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua
index 70c8cd15eb..1b209e6a9d 100644
--- a/runtime/lua/vim/filetype.lua
+++ b/runtime/lua/vim/filetype.lua
@@ -176,6 +176,7 @@ local extension = {
bbappend = 'bitbake',
bbclass = 'bitbake',
bl = 'blank',
+ bsd = 'bsdl',
bsdl = 'bsdl',
bst = 'bst',
btm = function(path, bufnr)
@@ -968,7 +969,7 @@ local extension = {
txi = 'texinfo',
texinfo = 'texinfo',
text = 'text',
- tfvars = 'terraform',
+ tfvars = 'terraform-vars',
tla = 'tla',
tli = 'tli',
toml = 'toml',
@@ -1383,10 +1384,6 @@ local filename = {
['/etc/host.conf'] = 'hostconf',
['/etc/hosts.allow'] = 'hostsaccess',
['/etc/hosts.deny'] = 'hostsaccess',
- ['/i3/config'] = 'i3config',
- ['/sway/config'] = 'i3config',
- ['/.sway/config'] = 'i3config',
- ['/.i3/config'] = 'i3config',
['/.icewm/menu'] = 'icemenu',
['.indent.pro'] = 'indent',
indentrc = 'indent',
@@ -1668,7 +1665,6 @@ local pattern = {
['.*/build/conf/.*%.conf'] = 'bitbake',
['.*/meta/conf/.*%.conf'] = 'bitbake',
['.*/meta%-.*/conf/.*%.conf'] = 'bitbake',
- ['.*bsd'] = 'bsdl',
['bzr_log%..*'] = 'bzr',
['.*enlightenment/.*%.cfg'] = 'c',
['cabal%.project%..*'] = starsetf('cabalproject'),
@@ -1835,9 +1831,7 @@ local pattern = {
['.*/etc/hosts%.allow'] = 'hostsaccess',
['.*%.html%.m4'] = 'htmlm4',
['.*/%.i3/config'] = 'i3config',
- ['.*/sway/config'] = 'i3config',
['.*/i3/config'] = 'i3config',
- ['.*/%.sway/config'] = 'i3config',
['.*/%.icewm/menu'] = 'icemenu',
['.*/etc/initng/.*/.*%.i'] = 'initng',
['JAM.*%..*'] = starsetf('jam'),
@@ -2076,6 +2070,8 @@ local pattern = {
end,
['.*/etc/sudoers'] = 'sudoers',
['svn%-commit.*%.tmp'] = 'svn',
+ ['.*/sway/config'] = 'swayconfig',
+ ['.*/%.sway/config'] = 'swayconfig',
['.*%.swift%.gyb'] = 'swiftgyb',
['.*%.[Ss][Yy][Ss]'] = function(path, bufnr)
return require('vim.filetype.detect').sys(bufnr)
@@ -2241,30 +2237,30 @@ end
--- <pre>
--- vim.filetype.add({
--- extension = {
---- foo = "fooscript",
+--- foo = 'fooscript',
--- bar = function(path, bufnr)
--- if some_condition() then
---- return "barscript", function(bufnr)
+--- return 'barscript', function(bufnr)
--- -- Set a buffer variable
--- vim.b[bufnr].barscript_version = 2
--- end
--- end
---- return "bar"
+--- return 'bar'
--- end,
--- },
--- filename = {
---- [".foorc"] = "toml",
---- ["/etc/foo/config"] = "toml",
+--- ['.foorc'] = 'toml',
+--- ['/etc/foo/config'] = 'toml',
--- },
--- pattern = {
---- [".*/etc/foo/.*"] = "fooscript",
+--- ['.*/etc/foo/.*'] = 'fooscript',
--- -- Using an optional priority
---- [".*/etc/foo/.*%.conf"] = { "dosini", { priority = 10 } },
---- ["README.(%a+)$"] = function(path, bufnr, ext)
---- if ext == "md" then
---- return "markdown"
---- elseif ext == "rst" then
---- return "rst"
+--- ['.*/etc/foo/.*%.conf'] = { 'dosini', { priority = 10 } },
+--- ['README.(%a+)$'] = function(path, bufnr, ext)
+--- if ext == 'md' then
+--- return 'markdown'
+--- elseif ext == 'rst' then
+--- return 'rst'
--- end
--- end,
--- },
@@ -2279,9 +2275,9 @@ end
--- priority = -math.huge,
--- function(path, bufnr)
--- local content = vim.filetype.getlines(bufnr, 1)
---- if vim.filetype.matchregex(content, { [[^#!.*\\<mine\\>]] }) then
+--- if vim.filetype.matchregex(content, [[^#!.*\\<mine\\>]]) then
--- return 'mine'
---- elseif vim.filetype.matchregex(content, { [[\\<drawing\\>]] }) then
+--- elseif vim.filetype.matchregex(content, [[\\<drawing\\>]]) then
--- return 'drawing'
--- end
--- end,
diff --git a/runtime/lua/vim/filetype/detect.lua b/runtime/lua/vim/filetype/detect.lua
index 8c10517687..14f076717f 100644
--- a/runtime/lua/vim/filetype/detect.lua
+++ b/runtime/lua/vim/filetype/detect.lua
@@ -554,7 +554,7 @@ function M.inc(bufnr)
-- headers so assume POV-Ray
elseif findany(lines, { '^%s{', '^%s%(%*' }) or matchregex(lines, pascal_keywords) then
return 'pascal'
- elseif findany(lines, { '^%s*inherit ', '^%s*require ', '^%s*%w+%s+= ' }) then
+ elseif findany(lines, { '^%s*inherit ', '^%s*require ', '^%s*%u[%w_:${}]*%s+%??[?:+]?= ' }) then
return 'bitbake'
else
local syntax = M.asm_syntax(bufnr)
diff --git a/runtime/lua/vim/keymap.lua b/runtime/lua/vim/keymap.lua
index f4c2b507a9..7265beb56b 100644
--- a/runtime/lua/vim/keymap.lua
+++ b/runtime/lua/vim/keymap.lua
@@ -31,22 +31,19 @@ local keymap = {}
--- vim.keymap.set('n', 'asdf', function() return require('jkl').my_fun() end)
--- </pre>
---
----@param mode string|table Same mode short names as |nvim_set_keymap()|.
+---@param mode string|table Same mode short names as |nvim_set_keymap()|.
--- Can also be list of modes to create mapping on multiple modes.
----@param lhs string Left-hand side |{lhs}| of the mapping.
+---@param lhs string Left-hand side |{lhs}| of the mapping.
---@param rhs string|function Right-hand side |{rhs}| of the mapping. Can also be a Lua function.
---- If a Lua function and `opts.expr == true`, returning `nil` is
---- equivalent to an empty string.
--
---@param opts table A table of |:map-arguments| such as "silent". In addition to the options
--- listed in |nvim_set_keymap()|, this table also accepts the following keys:
--- - buffer: (number or boolean) Add a mapping to the given buffer. When "true"
--- or 0, use the current buffer.
---- - replace_keycodes: (boolean, default true) When both this and expr is "true",
---- |nvim_replace_termcodes()| is applied to the result of Lua expr maps.
--- - remap: (boolean) Make the mapping recursive. This is the
--- inverse of the "noremap" option from |nvim_set_keymap()|.
--- Default `false`.
+--- - replace_keycodes: (boolean) defaults to true if "expr" is true.
---@see |nvim_set_keymap()|
function keymap.set(mode, lhs, rhs, opts)
vim.validate({
@@ -60,22 +57,9 @@ function keymap.set(mode, lhs, rhs, opts)
local is_rhs_luaref = type(rhs) == 'function'
mode = type(mode) == 'string' and { mode } or mode
- if is_rhs_luaref and opts.expr then
- local user_rhs = rhs
- rhs = function()
- local res = user_rhs()
- if res == nil then
- -- TODO(lewis6991): Handle this in C?
- return ''
- elseif opts.replace_keycodes ~= false then
- return vim.api.nvim_replace_termcodes(res, true, true, true)
- else
- return res
- end
- end
+ if opts.expr and opts.replace_keycodes ~= false then
+ opts.replace_keycodes = true
end
- -- clear replace_keycodes from opts table
- opts.replace_keycodes = nil
if opts.remap == nil then
-- default remap value is false
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 61586ca44f..bf2201d9c8 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -371,7 +371,9 @@ do
state_by_client[client.id] = state
end
if not state.buffers[bufnr] then
- local buf_state = {}
+ local buf_state = {
+ name = api.nvim_buf_get_name(bufnr),
+ }
state.buffers[bufnr] = buf_state
if use_incremental_sync then
buf_state.lines = nvim_buf_get_lines(bufnr, 0, -1, true)
@@ -382,6 +384,15 @@ do
end
---@private
+ function changetracking._get_and_set_name(client, bufnr, name)
+ local state = state_by_client[client.id] or {}
+ local buf_state = (state.buffers or {})[bufnr]
+ local old_name = buf_state.name
+ buf_state.name = name
+ return old_name
+ end
+
+ ---@private
function changetracking.reset_buf(client, bufnr)
changetracking.flush(client, bufnr)
local state = state_by_client[client.id]
@@ -1405,6 +1416,19 @@ local function text_document_did_save_handler(bufnr)
local uri = vim.uri_from_bufnr(bufnr)
local text = once(buf_get_full_text)
for_each_buffer_client(bufnr, function(client)
+ 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('textDocument/didOpen', {
+ textDocument = {
+ version = 0,
+ uri = uri,
+ languageId = client.config.get_language_id(bufnr, vim.bo[bufnr].filetype),
+ text = buf_get_full_text(bufnr),
+ },
+ })
+ util.buf_versions[bufnr] = 0
+ end
local save_capability = vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'save')
if save_capability then
local included_text
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua
index 50a51e897c..63f4688d94 100644
--- a/runtime/lua/vim/lsp/buf.lua
+++ b/runtime/lua/vim/lsp/buf.lua
@@ -11,8 +11,8 @@ local M = {}
--- buffer.
---
---@param method (string) LSP method name
----@param params (optional, table) Parameters to send to the server
----@param handler (optional, functionnil) See |lsp-handler|. Follows |lsp-handler-resolution|
+---@param params (table|nil) Parameters to send to the server
+---@param handler (function|nil) See |lsp-handler|. Follows |lsp-handler-resolution|
--
---@returns 2-tuple:
--- - Map of client-id:request-id pairs for all successful requests.
@@ -61,6 +61,7 @@ end
---
---@param options table|nil additional options
--- - reuse_win: (boolean) Jump to existing window if buffer is already open.
+--- - on_list: (function) handler for list results. See |on-list-handler|
function M.declaration(options)
local params = util.make_position_params()
request_with_options('textDocument/declaration', params, options)
@@ -70,6 +71,7 @@ end
---
---@param options table|nil additional options
--- - reuse_win: (boolean) Jump to existing window if buffer is already open.
+--- - on_list: (function) handler for list results. See |on-list-handler|
function M.definition(options)
local params = util.make_position_params()
request_with_options('textDocument/definition', params, options)
@@ -79,6 +81,7 @@ end
---
---@param options table|nil additional options
--- - reuse_win: (boolean) Jump to existing window if buffer is already open.
+--- - on_list: (function) handler for list results. See |on-list-handler|
function M.type_definition(options)
local params = util.make_position_params()
request_with_options('textDocument/typeDefinition', params, options)
@@ -86,9 +89,12 @@ end
--- Lists all the implementations for the symbol under the cursor in the
--- quickfix window.
-function M.implementation()
+---
+---@param options table|nil additional options
+--- - on_list: (function) handler for list results. See |on-list-handler|
+function M.implementation(options)
local params = util.make_position_params()
- request('textDocument/implementation', params)
+ request_with_options('textDocument/implementation', params, options)
end
--- Displays signature information about the symbol under the cursor in a
@@ -151,7 +157,7 @@ end
--- - formatting_options (table|nil):
--- Can be used to specify FormattingOptions. Some unspecified options will be
--- automatically derived from the current Neovim options.
---- @see https://microsoft.github.io/language-server-protocol/specification#textDocument_formatting
+--- See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#formattingOptions
--- - timeout_ms (integer|nil, default 1000):
--- Time in milliseconds to block for formatting requests. No effect if async=true
--- - bufnr (number|nil):
@@ -496,20 +502,24 @@ end
---
---@param context (table) Context for the request
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references
-function M.references(context)
+---@param options table|nil additional options
+--- - on_list: (function) handler for list results. See |on-list-handler|
+function M.references(context, options)
validate({ context = { context, 't', true } })
local params = util.make_position_params()
params.context = context or {
includeDeclaration = true,
}
- request('textDocument/references', params)
+ request_with_options('textDocument/references', params, options)
end
--- Lists all symbols in the current buffer in the quickfix window.
---
-function M.document_symbol()
+---@param options table|nil additional options
+--- - on_list: (function) handler for list results. See |on-list-handler|
+function M.document_symbol(options)
local params = { textDocument = util.make_text_document_params() }
- request('textDocument/documentSymbol', params)
+ request_with_options('textDocument/documentSymbol', params, options)
end
---@private
@@ -648,13 +658,15 @@ end
--- string means no filtering is done.
---
---@param query (string, optional)
-function M.workspace_symbol(query)
+---@param options table|nil additional options
+--- - on_list: (function) handler for list results. See |on-list-handler|
+function M.workspace_symbol(query, options)
query = query or npcall(vim.fn.input, 'Query: ')
if query == nil then
return
end
local params = { query = query }
- request('workspace/symbol', params)
+ request_with_options('workspace/symbol', params, options)
end
--- Send request to the server to resolve document highlights for the current
@@ -830,20 +842,27 @@ end
--- cursor position.
---
---@param options table|nil Optional table which holds the following optional fields:
---- - context (table|nil):
---- Corresponds to `CodeActionContext` of the LSP specification:
---- - diagnostics (table|nil):
---- LSP `Diagnostic[]`. Inferred from the current
---- position if not provided.
---- - only (table|nil):
---- List of LSP `CodeActionKind`s used to filter the code actions.
---- Most language servers support values like `refactor`
---- or `quickfix`.
---- - filter (function|nil):
---- Predicate function taking an `CodeAction` and returning a boolean.
---- - apply (boolean|nil):
---- When set to `true`, and there is just one remaining action
---- (after filtering), the action is applied without user query.
+--- - context: (table|nil)
+--- Corresponds to `CodeActionContext` of the LSP specification:
+--- - diagnostics (table|nil):
+--- LSP `Diagnostic[]`. Inferred from the current
+--- position if not provided.
+--- - only (table|nil):
+--- List of LSP `CodeActionKind`s used to filter the code actions.
+--- Most language servers support values like `refactor`
+--- or `quickfix`.
+--- - filter: (function|nil)
+--- Predicate taking an `CodeAction` and returning a boolean.
+--- - apply: (boolean|nil)
+--- When set to `true`, and there is just one remaining action
+--- (after filtering), the action is applied without user query.
+---
+--- - range: (table|nil)
+--- Range for which code actions should be requested.
+--- If in visual mode this defaults to the active selection.
+--- Table must contain `start` and `end` keys with {row, col} tuples
+--- using mark-like indexing. See |api-indexing|
+---
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction
function M.code_action(options)
validate({ options = { options, 't', true } })
@@ -858,7 +877,34 @@ function M.code_action(options)
local bufnr = api.nvim_get_current_buf()
context.diagnostics = vim.lsp.diagnostic.get_line_diagnostics(bufnr)
end
- local params = util.make_range_params()
+ local params
+ local mode = api.nvim_get_mode().mode
+ if options.range then
+ assert(type(options.range) == 'table', 'code_action range must be a table')
+ local start = assert(options.range.start, 'range must have a `start` property')
+ local end_ = assert(options.range['end'], 'range must have a `end` property')
+ params = util.make_given_range_params(start, end_)
+ elseif mode == 'v' or mode == 'V' then
+ -- [bufnum, lnum, col, off]; both row and column 1-indexed
+ local start = vim.fn.getpos('v')
+ local end_ = vim.fn.getpos('.')
+ local start_row = start[2]
+ local start_col = start[3]
+ local end_row = end_[2]
+ local end_col = end_[3]
+
+ -- A user can start visual selection at the end and move backwards
+ -- Normalize the range to start < end
+ if start_row == end_row and end_col < start_col then
+ end_col, start_col = start_col, end_col
+ elseif end_row < start_row then
+ start_row, end_row = end_row, start_row
+ start_col, end_col = end_col, start_col
+ end
+ params = util.make_given_range_params({ start_row, start_col - 1 }, { end_row, end_col - 1 })
+ else
+ params = util.make_range_params()
+ end
params.context = context
code_action_request(params, options)
end
@@ -879,6 +925,7 @@ end
---@param end_pos ({number, number}, optional) mark-indexed position.
---Defaults to the end of the last visual selection.
function M.range_code_action(context, start_pos, end_pos)
+ vim.deprecate('vim.lsp.buf.range_code_action', 'vim.lsp.buf.code_action', '0.9.0')
validate({ context = { context, 't', true } })
context = context or {}
if not context.diagnostics then
diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua
index 3b869d8f5c..1e6ac8dddf 100644
--- a/runtime/lua/vim/lsp/handlers.lua
+++ b/runtime/lua/vim/lsp/handlers.lua
@@ -189,19 +189,17 @@ M['textDocument/references'] = function(_, result, ctx, config)
else
local client = vim.lsp.get_client_by_id(ctx.client_id)
config = config or {}
+ local title = 'References'
+ local items = util.locations_to_items(result, client.offset_encoding)
+
if config.loclist then
- vim.fn.setloclist(0, {}, ' ', {
- title = 'References',
- items = util.locations_to_items(result, client.offset_encoding),
- context = ctx,
- })
+ vim.fn.setloclist(0, {}, ' ', { title = title, items = items, context = ctx })
api.nvim_command('lopen')
+ elseif config.on_list then
+ assert(type(config.on_list) == 'function', 'on_list is not a function')
+ config.on_list({ title = title, items = items, context = ctx })
else
- vim.fn.setqflist({}, ' ', {
- title = 'References',
- items = util.locations_to_items(result, client.offset_encoding),
- context = ctx,
- })
+ vim.fn.setqflist({}, ' ', { title = title, items = items, context = ctx })
api.nvim_command('botright copen')
end
end
@@ -224,19 +222,17 @@ local function response_to_list(map_result, entity, title_fn)
vim.notify('No ' .. entity .. ' found')
else
config = config or {}
+ local title = title_fn(ctx)
+ local items = map_result(result, ctx.bufnr)
+
if config.loclist then
- vim.fn.setloclist(0, {}, ' ', {
- title = title_fn(ctx),
- items = map_result(result, ctx.bufnr),
- context = ctx,
- })
+ vim.fn.setloclist(0, {}, ' ', { title = title, items = items, context = ctx })
api.nvim_command('lopen')
+ elseif config.on_list then
+ assert(type(config.on_list) == 'function', 'on_list is not a function')
+ config.on_list({ title = title, items = items, context = ctx })
else
- vim.fn.setqflist({}, ' ', {
- title = title_fn(ctx),
- items = map_result(result, ctx.bufnr),
- context = ctx,
- })
+ vim.fn.setqflist({}, ' ', { title = title, items = items, context = ctx })
api.nvim_command('botright copen')
end
end
@@ -261,6 +257,7 @@ end)
--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_rename
M['textDocument/rename'] = function(_, result, ctx, _)
if not result then
+ vim.notify("Language server couldn't provide rename result", vim.log.levels.INFO)
return
end
local client = vim.lsp.get_client_by_id(ctx.client_id)
@@ -354,11 +351,16 @@ local function location_handler(_, result, ctx, config)
util.jump_to_location(result[1], client.offset_encoding, config.reuse_win)
if #result > 1 then
- vim.fn.setqflist({}, ' ', {
- title = 'LSP locations',
- items = util.locations_to_items(result, client.offset_encoding),
- })
- api.nvim_command('botright copen')
+ local title = 'LSP locations'
+ local items = util.locations_to_items(result, client.offset_encoding)
+
+ if config.on_list then
+ assert(type(config.on_list) == 'function', 'on_list is not a function')
+ config.on_list({ title = title, items = items })
+ else
+ vim.fn.setqflist({}, ' ', { title = title, items = items })
+ api.nvim_command('botright copen')
+ end
end
else
util.jump_to_location(result, client.offset_encoding, config.reuse_win)
diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua
index 6ecb9959d5..27da60b4ae 100644
--- a/runtime/lua/vim/lsp/protocol.lua
+++ b/runtime/lua/vim/lsp/protocol.lua
@@ -759,6 +759,7 @@ function protocol.make_client_capabilities()
},
hierarchicalWorkspaceSymbolSupport = true,
},
+ configuration = true,
workspaceFolders = true,
applyEdit = true,
workspaceEdit = {
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index 70f5010256..8e89d92a56 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -1821,7 +1821,7 @@ function M.try_trim_markdown_code_blocks(lines)
end
---@private
----@param window (optional, number): window handle or 0 for current, defaults to current
+---@param window number|nil: window handle or 0 for current, defaults to current
---@param offset_encoding string utf-8|utf-16|utf-32|nil defaults to `offset_encoding` of first client of buffer of `window`
local function make_position_param(window, offset_encoding)
window = window or 0
@@ -1841,7 +1841,7 @@ end
--- Creates a `TextDocumentPositionParams` object for the current buffer and cursor position.
---
----@param window (optional, number): window handle or 0 for current, defaults to current
+---@param window number|nil: window handle or 0 for current, defaults to current
---@param offset_encoding string utf-8|utf-16|utf-32|nil defaults to `offset_encoding` of first client of buffer of `window`
---@returns `TextDocumentPositionParams` object
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentPositionParams
@@ -1894,8 +1894,8 @@ end
--- `textDocument/codeAction`, `textDocument/colorPresentation`,
--- `textDocument/rangeFormatting`.
---
----@param window (optional, number): window handle or 0 for current, defaults to current
----@param offset_encoding string utf-8|utf-16|utf-32|nil defaults to `offset_encoding` of first client of buffer of `window`
+---@param window number|nil: window handle or 0 for current, defaults to current
+---@param offset_encoding "utf-8"|"utf-16"|"utf-32"|nil defaults to `offset_encoding` of first client of buffer of `window`
---@returns { textDocument = { uri = `current_file_uri` }, range = { start =
---`current_position`, end = `current_position` } }
function M.make_range_params(window, offset_encoding)
@@ -1911,12 +1911,12 @@ end
--- Using the given range in the current buffer, creates an object that
--- is similar to |vim.lsp.util.make_range_params()|.
---
----@param start_pos ({number, number}, optional) mark-indexed position.
----Defaults to the start of the last visual selection.
----@param end_pos ({number, number}, optional) mark-indexed position.
----Defaults to the end of the last visual selection.
----@param bufnr (optional, number): buffer handle or 0 for current, defaults to current
----@param offset_encoding string utf-8|utf-16|utf-32|nil defaults to `offset_encoding` of first client of `bufnr`
+---@param start_pos number[]|nil {row, col} mark-indexed position.
+--- Defaults to the start of the last visual selection.
+---@param end_pos number[]|nil {row, col} mark-indexed position.
+--- Defaults to the end of the last visual selection.
+---@param bufnr number|nil buffer handle or 0 for current, defaults to current
+---@param offset_encoding "utf-8"|"utf-16"|"utf-32"|nil defaults to `offset_encoding` of first client of `bufnr`
---@returns { textDocument = { uri = `current_file_uri` }, range = { start =
---`start_position`, end = `end_position` } }
function M.make_given_range_params(start_pos, end_pos, bufnr, offset_encoding)
@@ -1956,7 +1956,7 @@ end
--- Creates a `TextDocumentIdentifier` object for the current buffer.
---
----@param bufnr (optional, number): Buffer handle, defaults to current
+---@param bufnr number|nil: Buffer handle, defaults to current
---@returns `TextDocumentIdentifier`
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentIdentifier
function M.make_text_document_params(bufnr)
@@ -2000,7 +2000,7 @@ end
--- Returns the UTF-32 and UTF-16 offsets for a position in a certain buffer.
---
----@param buf buffer id (0 for current)
+---@param buf number buffer number (0 for current)
---@param row 0-indexed line
---@param col 0-indexed byte offset in line
---@param offset_encoding string utf-8|utf-16|utf-32|nil defaults to `offset_encoding` of first client of `buf`