aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/lsp/util.lua
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim/lsp/util.lua')
-rw-r--r--runtime/lua/vim/lsp/util.lua249
1 files changed, 133 insertions, 116 deletions
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index b041385c9c..70f5010256 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -44,12 +44,22 @@ local function get_border_size(opts)
shadow = { 1, 1 },
}
if border_size[border] == nil then
- error(string.format('invalid floating preview border: %s. :help vim.api.nvim_open_win()', vim.inspect(border)))
+ error(
+ string.format(
+ 'invalid floating preview border: %s. :help vim.api.nvim_open_win()',
+ vim.inspect(border)
+ )
+ )
end
height, width = unpack(border_size[border])
else
if 8 % #border ~= 0 then
- error(string.format('invalid floating preview border: %s. :help vim.api.nvim_open_win()', vim.inspect(border)))
+ error(
+ string.format(
+ 'invalid floating preview border: %s. :help vim.api.nvim_open_win()',
+ vim.inspect(border)
+ )
+ )
end
---@private
local function border_width(id)
@@ -61,7 +71,12 @@ local function get_border_size(opts)
-- border specified as a list of border characters
return vim.fn.strdisplaywidth(border[id])
end
- error(string.format('invalid floating preview border: %s. :help vim.api.nvim_open_win()', vim.inspect(border)))
+ error(
+ string.format(
+ 'invalid floating preview border: %s. :help vim.api.nvim_open_win()',
+ vim.inspect(border)
+ )
+ )
end
---@private
local function border_height(id)
@@ -73,7 +88,12 @@ local function get_border_size(opts)
-- border specified as a list of border characters
return #border[id] > 0 and 1 or 0
end
- error(string.format('invalid floating preview border: %s. :help vim.api.nvim_open_win()', vim.inspect(border)))
+ error(
+ string.format(
+ 'invalid floating preview border: %s. :help vim.api.nvim_open_win()',
+ vim.inspect(border)
+ )
+ )
end
height = height + border_height(2) -- top
height = height + border_height(6) -- bottom
@@ -218,14 +238,14 @@ local function get_lines(bufnr, rows)
-- This is needed for bufload and bufloaded
if bufnr == 0 then
- bufnr = vim.api.nvim_get_current_buf()
+ bufnr = api.nvim_get_current_buf()
end
---@private
local function buf_lines()
local lines = {}
for _, row in pairs(rows) do
- lines[row] = (vim.api.nvim_buf_get_lines(bufnr, row, row + 1, false) or { '' })[1]
+ lines[row] = (api.nvim_buf_get_lines(bufnr, row, row + 1, false) or { '' })[1]
end
return lines
end
@@ -407,7 +427,7 @@ function M.apply_text_edits(text_edits, bufnr, offset_encoding)
-- Some LSP servers are depending on the VSCode behavior.
-- The VSCode will re-locate the cursor position after applying TextEdit so we also do it.
- local is_current_buf = vim.api.nvim_get_current_buf() == bufnr
+ local is_current_buf = api.nvim_get_current_buf() == bufnr
local cursor = (function()
if not is_current_buf then
return {
@@ -415,7 +435,7 @@ function M.apply_text_edits(text_edits, bufnr, offset_encoding)
col = -1,
}
end
- local cursor = vim.api.nvim_win_get_cursor(0)
+ local cursor = api.nvim_win_get_cursor(0)
return {
row = cursor[1] - 1,
col = cursor[2],
@@ -435,11 +455,11 @@ function M.apply_text_edits(text_edits, bufnr, offset_encoding)
start_col = get_line_byte_from_position(bufnr, text_edit.range.start, offset_encoding),
end_row = text_edit.range['end'].line,
end_col = get_line_byte_from_position(bufnr, text_edit.range['end'], offset_encoding),
- text = vim.split(text_edit.newText, '\n', true),
+ text = split(text_edit.newText, '\n', true),
}
-- Some LSP servers may return +1 range of the buffer content but nvim_buf_set_text can't accept it so we should fix it here.
- local max = vim.api.nvim_buf_line_count(bufnr)
+ local max = api.nvim_buf_line_count(bufnr)
if max <= e.start_row or max <= e.end_row then
local len = #(get_line(bufnr, max - 1) or '')
if max <= e.start_row then
@@ -453,7 +473,7 @@ function M.apply_text_edits(text_edits, bufnr, offset_encoding)
end
has_eol_text_edit = true
end
- vim.api.nvim_buf_set_text(bufnr, e.start_row, e.start_col, e.end_row, e.end_col, e.text)
+ api.nvim_buf_set_text(bufnr, e.start_row, e.start_col, e.end_row, e.end_col, e.text)
-- Fix cursor position.
local row_count = (e.end_row - e.start_row) + 1
@@ -470,7 +490,7 @@ function M.apply_text_edits(text_edits, bufnr, offset_encoding)
end
end
- local max = vim.api.nvim_buf_line_count(bufnr)
+ local max = api.nvim_buf_line_count(bufnr)
-- Apply fixed cursor position.
if is_cursor_fixed then
@@ -478,7 +498,7 @@ function M.apply_text_edits(text_edits, bufnr, offset_encoding)
is_valid_cursor = is_valid_cursor and cursor.row < max
is_valid_cursor = is_valid_cursor and cursor.col <= #(get_line(bufnr, max - 1) or '')
if is_valid_cursor then
- vim.api.nvim_win_set_cursor(0, { cursor.row + 1, cursor.col })
+ api.nvim_win_set_cursor(0, { cursor.row + 1, cursor.col })
end
end
@@ -491,7 +511,7 @@ function M.apply_text_edits(text_edits, bufnr, offset_encoding)
)
fix_eol = fix_eol and get_line(bufnr, max - 1) == ''
if fix_eol then
- vim.api.nvim_buf_set_lines(bufnr, -2, -1, false, {})
+ api.nvim_buf_set_lines(bufnr, -2, -1, false, {})
end
end
@@ -531,7 +551,10 @@ function M.apply_text_document_edit(text_document_edit, index, offset_encoding)
local text_document = text_document_edit.textDocument
local bufnr = vim.uri_to_bufnr(text_document.uri)
if offset_encoding == nil then
- vim.notify_once('apply_text_document_edit must be called with valid offset encoding', vim.log.levels.WARN)
+ vim.notify_once(
+ 'apply_text_document_edit must be called with valid offset encoding',
+ vim.log.levels.WARN
+ )
end
-- For lists of text document edits,
@@ -701,7 +724,7 @@ end
-- ignoreIfExists? bool
function M.rename(old_fname, new_fname, opts)
opts = opts or {}
- local target_exists = vim.loop.fs_stat(new_fname) ~= nil
+ local target_exists = uv.fs_stat(new_fname) ~= nil
if target_exists and not opts.overwrite or opts.ignoreIfExists then
vim.notify('Rename target already exists. Skipping rename.')
return
@@ -741,7 +764,7 @@ end
local function delete_file(change)
local opts = change.options or {}
local fname = vim.uri_to_fname(change.uri)
- local stat = vim.loop.fs_stat(fname)
+ local stat = uv.fs_stat(fname)
if opts.ignoreIfNotExists and not stat then
return
end
@@ -765,7 +788,10 @@ end
--see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_applyEdit
function M.apply_workspace_edit(workspace_edit, offset_encoding)
if offset_encoding == nil then
- vim.notify_once('apply_workspace_edit must be called with valid offset encoding', vim.log.levels.WARN)
+ vim.notify_once(
+ 'apply_workspace_edit must be called with valid offset encoding',
+ vim.log.levels.WARN
+ )
end
if workspace_edit.documentChanges then
for idx, change in ipairs(workspace_edit.documentChanges) do
@@ -880,7 +906,7 @@ function M.convert_signature_help_to_markdown_lines(signature_help, ft, triggers
-- wrap inside a code block so stylize_markdown can render it properly
label = ('```%s\n%s\n```'):format(ft, label)
end
- vim.list_extend(contents, vim.split(label, '\n', true))
+ list_extend(contents, split(label, '\n', true))
if signature.documentation then
M.convert_input_to_markdown_lines(signature.documentation, contents)
end
@@ -1022,7 +1048,10 @@ function M.jump_to_location(location, offset_encoding, reuse_win)
return
end
if offset_encoding == nil then
- vim.notify_once('jump_to_location must be called with valid offset encoding', vim.log.levels.WARN)
+ vim.notify_once(
+ 'jump_to_location must be called with valid offset encoding',
+ vim.log.levels.WARN
+ )
end
local bufnr = vim.uri_to_bufnr(uri)
-- Save position in jumplist
@@ -1226,14 +1255,21 @@ function M.stylize_markdown(bufnr, contents, opts)
-- strip any empty lines or separators prior to this separator in actual markdown
if line:match('^---+$') then
while
- markdown_lines[#stripped] and (stripped[#stripped]:match('^%s*$') or stripped[#stripped]:match('^---+$'))
+ markdown_lines[#stripped]
+ and (stripped[#stripped]:match('^%s*$') or stripped[#stripped]:match('^---+$'))
do
markdown_lines[#stripped] = false
table.remove(stripped, #stripped)
end
end
-- add the line if its not an empty line following a separator
- if not (line:match('^%s*$') and markdown_lines[#stripped] and stripped[#stripped]:match('^---+$')) then
+ if
+ not (
+ line:match('^%s*$')
+ and markdown_lines[#stripped]
+ and stripped[#stripped]:match('^---+$')
+ )
+ then
table.insert(stripped, line)
markdown_lines[#stripped] = true
end
@@ -1254,7 +1290,7 @@ function M.stylize_markdown(bufnr, contents, opts)
end
end
- vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, stripped)
+ api.nvim_buf_set_lines(bufnr, 0, -1, false, stripped)
local idx = 1
---@private
@@ -1265,7 +1301,11 @@ function M.stylize_markdown(bufnr, contents, opts)
local function apply_syntax_to_region(ft, start, finish)
if ft == '' then
vim.cmd(
- string.format('syntax region markdownCode start=+\\%%%dl+ end=+\\%%%dl+ keepend extend', start, finish + 1)
+ string.format(
+ 'syntax region markdownCode start=+\\%%%dl+ end=+\\%%%dl+ keepend extend',
+ start,
+ finish + 1
+ )
)
return
end
@@ -1275,7 +1315,7 @@ function M.stylize_markdown(bufnr, contents, opts)
local lang = '@' .. ft:upper()
if not langs[lang] then
-- HACK: reset current_syntax, since some syntax files like markdown won't load if it is already set
- pcall(vim.api.nvim_buf_del_var, bufnr, 'current_syntax')
+ pcall(api.nvim_buf_del_var, bufnr, 'current_syntax')
-- TODO(ashkan): better validation before this.
if not pcall(vim.cmd, string.format('syntax include %s syntax/%s.vim', lang, ft)) then
return
@@ -1283,7 +1323,13 @@ function M.stylize_markdown(bufnr, contents, opts)
langs[lang] = true
end
vim.cmd(
- string.format('syntax region %s start=+\\%%%dl+ end=+\\%%%dl+ contains=%s keepend', name, start, finish + 1, lang)
+ string.format(
+ 'syntax region %s start=+\\%%%dl+ end=+\\%%%dl+ contains=%s keepend',
+ name,
+ start,
+ finish + 1,
+ lang
+ )
)
end
@@ -1309,6 +1355,24 @@ function M.stylize_markdown(bufnr, contents, opts)
end
---@private
+--- Closes the preview window
+---
+---@param winnr number window id of preview window
+---@param bufnrs table|nil optional list of ignored buffers
+local function close_preview_window(winnr, bufnrs)
+ vim.schedule(function()
+ -- exit if we are in one of ignored buffers
+ if bufnrs and vim.tbl_contains(bufnrs, api.nvim_get_current_buf()) then
+ return
+ end
+
+ local augroup = 'preview_window_' .. winnr
+ pcall(api.nvim_del_augroup_by_name, augroup)
+ pcall(api.nvim_win_close, winnr, true)
+ end)
+end
+
+---@private
--- Creates autocommands to close a preview window when events happen.
---
---@param events table list of events
@@ -1316,63 +1380,30 @@ end
---@param bufnrs table list of buffers where the preview window will remain visible
---@see |autocmd-events|
local function close_preview_autocmd(events, winnr, bufnrs)
- local augroup = 'preview_window_' .. winnr
+ local augroup = api.nvim_create_augroup('preview_window_' .. winnr, {
+ clear = true,
+ })
-- close the preview window when entered a buffer that is not
-- the floating window buffer or the buffer that spawned it
- vim.cmd(string.format(
- [[
- augroup %s
- autocmd!
- autocmd BufEnter * lua vim.lsp.util._close_preview_window(%d, {%s})
- augroup end
- ]],
- augroup,
- winnr,
- table.concat(bufnrs, ',')
- ))
+ api.nvim_create_autocmd('BufEnter', {
+ group = augroup,
+ callback = function()
+ close_preview_window(winnr, bufnrs)
+ end,
+ })
if #events > 0 then
- vim.cmd(string.format(
- [[
- augroup %s
- autocmd %s <buffer> lua vim.lsp.util._close_preview_window(%d)
- augroup end
- ]],
- augroup,
- table.concat(events, ','),
- winnr
- ))
+ api.nvim_create_autocmd(events, {
+ group = augroup,
+ buffer = bufnrs[2],
+ callback = function()
+ close_preview_window(winnr)
+ end,
+ })
end
end
----@private
---- Closes the preview window
----
----@param winnr number window id of preview window
----@param bufnrs table|nil optional list of ignored buffers
-function M._close_preview_window(winnr, bufnrs)
- vim.schedule(function()
- -- exit if we are in one of ignored buffers
- if bufnrs and vim.tbl_contains(bufnrs, api.nvim_get_current_buf()) then
- return
- end
-
- local augroup = 'preview_window_' .. winnr
- vim.cmd(string.format(
- [[
- augroup %s
- autocmd!
- augroup end
- augroup! %s
- ]],
- augroup,
- augroup
- ))
- pcall(vim.api.nvim_win_close, winnr, true)
- end)
-end
-
---@internal
--- Computes size of float needed to show contents (with optional wrapping)
---
@@ -1587,15 +1618,21 @@ do --[[ References ]]
offset_encoding = { offset_encoding, 'string', false },
})
for _, reference in ipairs(references) do
- local start_line, start_char = reference['range']['start']['line'], reference['range']['start']['character']
- local end_line, end_char = reference['range']['end']['line'], reference['range']['end']['character']
+ local start_line, start_char =
+ reference['range']['start']['line'], reference['range']['start']['character']
+ local end_line, end_char =
+ reference['range']['end']['line'], reference['range']['end']['character']
local start_idx = get_line_byte_from_position(
bufnr,
{ line = start_line, character = start_char },
offset_encoding
)
- local end_idx = get_line_byte_from_position(bufnr, { line = start_line, character = end_char }, offset_encoding)
+ local end_idx = get_line_byte_from_position(
+ bufnr,
+ { line = start_line, character = end_char },
+ offset_encoding
+ )
local document_highlight_kind = {
[protocol.DocumentHighlightKind.Text] = 'LspReferenceText',
@@ -1630,7 +1667,10 @@ end)
---@returns (table) list of items
function M.locations_to_items(locations, offset_encoding)
if offset_encoding == nil then
- vim.notify_once('locations_to_items must be called with valid offset encoding', vim.log.levels.WARN)
+ vim.notify_once(
+ 'locations_to_items must be called with valid offset encoding',
+ vim.log.levels.WARN
+ )
end
local items = {}
@@ -1683,35 +1723,6 @@ function M.locations_to_items(locations, offset_encoding)
return items
end
---- Fills target window's location list with given list of items.
---- Can be obtained with e.g. |vim.lsp.util.locations_to_items()|.
---- Defaults to current window.
----
----@deprecated Use |setloclist()|
----
----@param items (table) list of items
-function M.set_loclist(items, win_id)
- vim.deprecate('vim.lsp.util.set_loclist', 'setloclist', '0.8')
- vim.fn.setloclist(win_id or 0, {}, ' ', {
- title = 'Language Server',
- items = items,
- })
-end
-
---- Fills quickfix list with given list of items.
---- Can be obtained with e.g. |vim.lsp.util.locations_to_items()|.
----
----@deprecated Use |setqflist()|
----
----@param items (table) list of items
-function M.set_qflist(items)
- vim.deprecate('vim.lsp.util.set_qflist', 'setqflist', '0.8')
- vim.fn.setqflist({}, ' ', {
- title = 'Language Server',
- items = items,
- })
-end
-
-- According to LSP spec, if the client set "symbolKind.valueSet",
-- the client must handle it properly even if it receives a value outside the specification.
-- https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_documentSymbol
@@ -1740,7 +1751,7 @@ function M.symbols_to_items(symbols, bufnr)
local kind = M._get_symbol_kind_name(symbol.kind)
table.insert(_items, {
-- bufnr = _bufnr,
- filename = vim.api.nvim_buf_get_name(_bufnr),
+ filename = api.nvim_buf_get_name(_bufnr),
lnum = symbol.selectionRange.start.line + 1,
col = symbol.selectionRange.start.character + 1,
kind = kind,
@@ -1778,7 +1789,7 @@ function M.trim_empty_lines(lines)
break
end
end
- return vim.list_extend({}, lines, start, finish)
+ return list_extend({}, lines, start, finish)
end
--- Accepts markdown lines and tries to reduce them to a filetype if they
@@ -1814,7 +1825,7 @@ end
---@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
- local buf = vim.api.nvim_win_get_buf(window)
+ 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
@@ -1836,7 +1847,7 @@ end
---@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 = vim.api.nvim_win_get_buf(window)
+ local buf = api.nvim_win_get_buf(window)
offset_encoding = offset_encoding or M._get_offset_encoding(buf)
return {
textDocument = M.make_text_document_params(buf),
@@ -1857,7 +1868,10 @@ function M._get_offset_encoding(bufnr)
for _, client in pairs(vim.lsp.buf_get_clients(bufnr)) do
if client.offset_encoding == nil then
vim.notify_once(
- string.format('Client (id: %s) offset_encoding is nil. Do not unset offset_encoding.', client.id),
+ string.format(
+ 'Client (id: %s) offset_encoding is nil. Do not unset offset_encoding.',
+ client.id
+ ),
vim.log.levels.ERROR
)
end
@@ -1885,7 +1899,7 @@ end
---@returns { textDocument = { uri = `current_file_uri` }, range = { start =
---`current_position`, end = `current_position` } }
function M.make_range_params(window, offset_encoding)
- local buf = vim.api.nvim_win_get_buf(window or 0)
+ local buf = api.nvim_win_get_buf(window or 0)
offset_encoding = offset_encoding or M._get_offset_encoding(buf)
local position = make_position_param(window, offset_encoding)
return {
@@ -1911,7 +1925,7 @@ function M.make_given_range_params(start_pos, end_pos, bufnr, offset_encoding)
end_pos = { end_pos, 't', true },
offset_encoding = { offset_encoding, 's', true },
})
- bufnr = bufnr or vim.api.nvim_get_current_buf()
+ bufnr = bufnr or api.nvim_get_current_buf()
offset_encoding = offset_encoding or M._get_offset_encoding(bufnr)
local A = list_extend({}, start_pos or api.nvim_buf_get_mark(bufnr, '<'))
local B = list_extend({}, end_pos or api.nvim_buf_get_mark(bufnr, '>'))
@@ -1994,7 +2008,10 @@ end
function M.character_offset(buf, row, col, offset_encoding)
local line = get_line(buf, row)
if offset_encoding == nil then
- vim.notify_once('character_offset must be called with valid offset encoding', vim.log.levels.WARN)
+ vim.notify_once(
+ 'character_offset must be called with valid offset encoding',
+ vim.log.levels.WARN
+ )
end
-- If the col is past the EOL, use the line length.
if col > #line then