aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua')
-rw-r--r--runtime/lua/vim/lsp.lua2
-rw-r--r--runtime/lua/vim/lsp/callbacks.lua72
-rw-r--r--runtime/lua/vim/lsp/util.lua69
-rw-r--r--runtime/lua/vim/shared.lua11
-rw-r--r--runtime/lua/vim/treesitter.lua2
-rw-r--r--runtime/lua/vim/uri.lua3
6 files changed, 92 insertions, 67 deletions
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 8af20ea1f9..afff4d9900 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -614,6 +614,8 @@ do
if tbl_isempty(all_buffer_active_clients[bufnr] or {}) then
return
end
+
+ util.buf_versions[bufnr] = changedtick
-- Lazy initialize these because clients may not even need them.
local incremental_changes = once(function(client)
local size_index = encoding_index[client.offset_encoding]
diff --git a/runtime/lua/vim/lsp/callbacks.lua b/runtime/lua/vim/lsp/callbacks.lua
index 644c12f98c..b6396f5798 100644
--- a/runtime/lua/vim/lsp/callbacks.lua
+++ b/runtime/lua/vim/lsp/callbacks.lua
@@ -29,6 +29,17 @@ M['textDocument/publishDiagnostics'] = function(_, _, result)
return
end
util.buf_clear_diagnostics(bufnr)
+
+ -- https://microsoft.github.io/language-server-protocol/specifications/specification-current/#diagnostic
+ -- The diagnostic's severity. Can be omitted. If omitted it is up to the
+ -- client to interpret diagnostics as error, warning, info or hint.
+ -- TODO: Replace this with server-specific heuristics to infer severity.
+ for _, diagnostic in ipairs(result.diagnostics) do
+ if diagnostic.severity == nil then
+ diagnostic.severity = protocol.DiagnosticSeverity.Error
+ end
+ end
+
util.buf_diagnostics_save_positions(bufnr, result.diagnostics)
util.buf_diagnostics_underline(bufnr, result.diagnostics)
util.buf_diagnostics_virtual_text(bufnr, result.diagnostics)
@@ -114,72 +125,13 @@ M['textDocument/definition'] = location_callback
M['textDocument/typeDefinition'] = location_callback
M['textDocument/implementation'] = location_callback
---- Convert SignatureHelp response to preview contents.
--- https://microsoft.github.io/language-server-protocol/specifications/specification-3-14/#textDocument_signatureHelp
-local function signature_help_to_preview_contents(input)
- if not input.signatures then
- return
- end
- --The active signature. If omitted or the value lies outside the range of
- --`signatures` the value defaults to zero or is ignored if `signatures.length
- --=== 0`. Whenever possible implementors should make an active decision about
- --the active signature and shouldn't rely on a default value.
- local contents = {}
- local active_signature = input.activeSignature or 0
- -- If the activeSignature is not inside the valid range, then clip it.
- if active_signature >= #input.signatures then
- active_signature = 0
- end
- local signature = input.signatures[active_signature + 1]
- if not signature then
- return
- end
- vim.list_extend(contents, vim.split(signature.label, '\n', true))
- if signature.documentation then
- util.convert_input_to_markdown_lines(signature.documentation, contents)
- end
- if input.parameters then
- local active_parameter = input.activeParameter or 0
- -- If the activeParameter is not inside the valid range, then clip it.
- if active_parameter >= #input.parameters then
- active_parameter = 0
- end
- local parameter = signature.parameters and signature.parameters[active_parameter]
- if parameter then
- --[=[
- --Represents a parameter of a callable-signature. A parameter can
- --have a label and a doc-comment.
- interface ParameterInformation {
- --The label of this parameter information.
- --
- --Either a string or an inclusive start and exclusive end offsets within its containing
- --signature label. (see SignatureInformation.label). The offsets are based on a UTF-16
- --string representation as `Position` and `Range` does.
- --
- --*Note*: a label of type string should be a substring of its containing signature label.
- --Its intended use case is to highlight the parameter label part in the `SignatureInformation.label`.
- label: string | [number, number];
- --The human-readable doc-comment of this parameter. Will be shown
- --in the UI but can be omitted.
- documentation?: string | MarkupContent;
- }
- --]=]
- -- TODO highlight parameter
- if parameter.documentation then
- util.convert_input_to_markdown_lines(parameter.documentation, contents)
- end
- end
- end
- return contents
-end
-
M['textDocument/signatureHelp'] = function(_, method, result)
util.focusable_preview(method, function()
if not (result and result.signatures and result.signatures[1]) then
return { 'No signature available' }
end
-- TODO show popup when signatures is empty?
- local lines = signature_help_to_preview_contents(result)
+ local lines = util.convert_signature_help_to_markdown_lines(result)
lines = util.trim_empty_lines(lines)
if vim.tbl_isempty(lines) then
return { 'No signature available' }
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index 5217464c22..ce5baf5b4b 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -135,7 +135,7 @@ function M.apply_text_document_edit(text_document_edit)
local text_document = text_document_edit.textDocument
local bufnr = vim.uri_to_bufnr(text_document.uri)
-- TODO(ashkan) check this is correct.
- if api.nvim_buf_get_changedtick(bufnr) > text_document.version then
+ if (M.buf_versions[bufnr] or 0) > text_document.version then
print("Buffer ", text_document.uri, " newer than edits.")
return
end
@@ -287,6 +287,65 @@ function M.convert_input_to_markdown_lines(input, contents)
return contents
end
+--- Convert SignatureHelp response to markdown lines.
+-- https://microsoft.github.io/language-server-protocol/specifications/specification-3-14/#textDocument_signatureHelp
+function M.convert_signature_help_to_markdown_lines(signature_help)
+ if not signature_help.signatures then
+ return
+ end
+ --The active signature. If omitted or the value lies outside the range of
+ --`signatures` the value defaults to zero or is ignored if `signatures.length
+ --=== 0`. Whenever possible implementors should make an active decision about
+ --the active signature and shouldn't rely on a default value.
+ local contents = {}
+ local active_signature = signature_help.activeSignature or 0
+ -- If the activeSignature is not inside the valid range, then clip it.
+ if active_signature >= #signature_help.signatures then
+ active_signature = 0
+ end
+ local signature = signature_help.signatures[active_signature + 1]
+ if not signature then
+ return
+ end
+ vim.list_extend(contents, vim.split(signature.label, '\n', true))
+ if signature.documentation then
+ M.convert_input_to_markdown_lines(signature.documentation, contents)
+ end
+ if signature_help.parameters then
+ local active_parameter = signature_help.activeParameter or 0
+ -- If the activeParameter is not inside the valid range, then clip it.
+ if active_parameter >= #signature_help.parameters then
+ active_parameter = 0
+ end
+ local parameter = signature.parameters and signature.parameters[active_parameter]
+ if parameter then
+ --[=[
+ --Represents a parameter of a callable-signature. A parameter can
+ --have a label and a doc-comment.
+ interface ParameterInformation {
+ --The label of this parameter information.
+ --
+ --Either a string or an inclusive start and exclusive end offsets within its containing
+ --signature label. (see SignatureInformation.label). The offsets are based on a UTF-16
+ --string representation as `Position` and `Range` does.
+ --
+ --*Note*: a label of type string should be a substring of its containing signature label.
+ --Its intended use case is to highlight the parameter label part in the `SignatureInformation.label`.
+ label: string | [number, number];
+ --The human-readable doc-comment of this parameter. Will be shown
+ --in the UI but can be omitted.
+ documentation?: string | MarkupContent;
+ }
+ --]=]
+ -- TODO highlight parameter
+ if parameter.documentation then
+ M.convert_input_help_to_markdown_lines(parameter.documentation, contents)
+ end
+ end
+ end
+ return contents
+end
+
function M.make_floating_popup_options(width, height, opts)
validate {
opts = { opts, 't', true };
@@ -534,8 +593,7 @@ function M.open_floating_preview(contents, filetype, opts)
end
api.nvim_buf_set_lines(floating_bufnr, 0, -1, true, contents)
api.nvim_buf_set_option(floating_bufnr, 'modifiable', false)
- -- TODO make InsertCharPre disappearing optional?
- api.nvim_command("autocmd CursorMoved,BufHidden,InsertCharPre <buffer> ++once lua pcall(vim.api.nvim_win_close, "..floating_winnr..", true)")
+ M.close_preview_autocmd({"CursorMoved", "CursorMovedI", "BufHidden"}, floating_winnr)
return floating_bufnr, floating_winnr
end
@@ -737,7 +795,8 @@ do
[protocol.DocumentHighlightKind.Read] = "LspReferenceRead";
[protocol.DocumentHighlightKind.Write] = "LspReferenceWrite";
}
- highlight_range(bufnr, reference_ns, document_highlight_kind[reference["kind"]], start_pos, end_pos)
+ local kind = reference["kind"] or protocol.DocumentHighlightKind.Text
+ highlight_range(bufnr, reference_ns, document_highlight_kind[kind], start_pos, end_pos)
end
end
@@ -973,5 +1032,7 @@ function M.character_offset(buf, row, col)
return str_utfindex(line, col)
end
+M.buf_versions = {}
+
return M
-- vim:sw=2 ts=2 et
diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua
index 1bf1c63fd7..d18fcfaf95 100644
--- a/runtime/lua/vim/shared.lua
+++ b/runtime/lua/vim/shared.lua
@@ -8,6 +8,9 @@ local vim = vim or {}
--- Returns a deep copy of the given object. Non-table objects are copied as
--- in a typical Lua assignment, whereas table objects are copied recursively.
+--- Functions are naively copied, so functions in the copied table point to the
+--- same functions as those in the input table. Userdata and threads are not
+--- copied and will throw an error.
---
--@param orig Table to copy
--@returns New table of copied keys and (nested) values.
@@ -34,10 +37,16 @@ vim.deepcopy = (function()
string = _id,
['nil'] = _id,
boolean = _id,
+ ['function'] = _id,
}
return function(orig)
- return deepcopy_funcs[type(orig)](orig)
+ local f = deepcopy_funcs[type(orig)]
+ if f then
+ return f(orig)
+ else
+ error("Cannot deepcopy object of type "..type(orig))
+ end
end
end)()
diff --git a/runtime/lua/vim/treesitter.lua b/runtime/lua/vim/treesitter.lua
index 8dacfa11cf..1836227540 100644
--- a/runtime/lua/vim/treesitter.lua
+++ b/runtime/lua/vim/treesitter.lua
@@ -124,7 +124,7 @@ end
function M.parse_query(lang, query)
M.require_language(lang)
local self = setmetatable({}, Query)
- self.query = vim._ts_parse_query(lang, query)
+ self.query = vim._ts_parse_query(lang, vim.fn.escape(query,'\\'))
self.info = self.query:inspect()
self.captures = self.info.captures
self.regexes = {}
diff --git a/runtime/lua/vim/uri.lua b/runtime/lua/vim/uri.lua
index 1065f84f4c..d91fb7ffd3 100644
--- a/runtime/lua/vim/uri.lua
+++ b/runtime/lua/vim/uri.lua
@@ -70,6 +70,7 @@ local function uri_from_bufnr(bufnr)
end
local function uri_to_fname(uri)
+ uri = uri_decode(uri)
-- TODO improve this.
if is_windows_file_uri(uri) then
uri = uri:gsub('^file:///', '')
@@ -77,7 +78,7 @@ local function uri_to_fname(uri)
else
uri = uri:gsub('^file://', '')
end
- return uri_decode(uri)
+ return uri
end
-- Return or create a buffer for a uri.