diff options
author | TJ DeVries <devries.timothyj@gmail.com> | 2020-08-25 09:52:22 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-25 09:52:22 -0400 |
commit | 43202964f39eed4e28fd8ad6ad0ec79a1868c33f (patch) | |
tree | da9abce08cca5b7502f0a5a6320eba52ee42b8e8 /runtime/lua/vim/lsp/util.lua | |
parent | 8a333afec53a48c90de7b0bde30f9db2d02d1898 (diff) | |
parent | 9d9edebceb73657899256430ed3e2f49c92898a8 (diff) | |
download | rneovim-43202964f39eed4e28fd8ad6ad0ec79a1868c33f.tar.gz rneovim-43202964f39eed4e28fd8ad6ad0ec79a1868c33f.tar.bz2 rneovim-43202964f39eed4e28fd8ad6ad0ec79a1868c33f.zip |
Merge pull request #12708 from runiq/lsp-doc
Add docs for some methods in vim.lsp
Diffstat (limited to 'runtime/lua/vim/lsp/util.lua')
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 308 |
1 files changed, 240 insertions, 68 deletions
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 33fca29ecd..3ec7311d65 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -7,6 +7,7 @@ local highlight = require 'vim.highlight' local M = {} +-- FIXME: DOC: Expose in vimdocs --- Diagnostics received from the server via `textDocument/publishDiagnostics` -- by buffer. -- @@ -33,18 +34,30 @@ local M = {} M.diagnostics_by_buf = {} local split = vim.split +--@private local function split_lines(value) return split(value, '\n', true) end +--@private local function ok_or_nil(status, ...) if not status then return end return ... end +--@private local function npcall(fn, ...) return ok_or_nil(pcall(fn, ...)) end +--- Replaces text in a range with new text. +--- +--- CAUTION: Changes in-place! +--- +--@param lines (table) Original list of strings +--@param A (table) Start position; a 2-tuple of {line, col} numbers +--@param B (table) End position; a 2-tuple of {line, col} numbers +--@param new_lines A list of strings to replace the original +--@returns (table) The modified {lines} object function M.set_lines(lines, A, B, new_lines) -- 0-indexing to 1-indexing local i_0 = A[1] + 1 @@ -78,6 +91,7 @@ function M.set_lines(lines, A, B, new_lines) return lines end +--@private local function sort_by_key(fn) return function(a,b) local ka, kb = fn(a), fn(b) @@ -91,13 +105,15 @@ local function sort_by_key(fn) return false end end +--@private local edit_sort_key = sort_by_key(function(e) return {e.A[1], e.A[2], e.i} end) +--@private --- Position is a https://microsoft.github.io/language-server-protocol/specifications/specification-current/#position --- Returns a zero-indexed column, since set_lines() does the conversion to --- 1-indexed +--- Returns a zero-indexed column, since set_lines() does the conversion to +--- 1-indexed local function get_line_byte_from_position(bufnr, position) -- LSP's line and characters are 0-indexed -- Vim's line and columns are 1-indexed @@ -114,6 +130,9 @@ local function get_line_byte_from_position(bufnr, position) return col end +--- Applies a list of text edits to a buffer. +--@param text_edits (table) list of `TextEdit` objects +--@param buf_nr (number) Buffer id function M.apply_text_edits(text_edits, bufnr) if not next(text_edits) then return end if not api.nvim_buf_is_loaded(bufnr) then @@ -168,20 +187,30 @@ end -- function M.glob_to_regex(glob) -- end --- textDocument/completion response returns one of CompletionItem[], CompletionList or null. --- https://microsoft.github.io/language-server-protocol/specification#textDocument_completion +--- Can be used to extract the completion items from a +--- `textDocument/completion` request, which may return one of +--- `CompletionItem[]`, `CompletionList` or null. +--@param result (table) The result of a `textDocument/completion` request +--@returns (table) List of completion items +--@see https://microsoft.github.io/language-server-protocol/specification#textDocument_completion function M.extract_completion_items(result) if type(result) == 'table' and result.items then + -- result is a `CompletionList` return result.items elseif result ~= nil then + -- result is `CompletionItem[]` return result else + -- result is `null` return {} end end ---- Apply the TextDocumentEdit response. --- @params TextDocumentEdit [table] see https://microsoft.github.io/language-server-protocol/specification +--- Applies a `TextDocumentEdit`, which is a list of changes to a single +-- document. +--- +--@param text_document_edit (table) a `TextDocumentEdit` object +--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentEdit 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) @@ -195,6 +224,13 @@ function M.apply_text_document_edit(text_document_edit) M.apply_text_edits(text_document_edit.edits, bufnr) end +--@private +--- Recursively parses snippets in a completion entry. +--- +--@param input (string) Snippet text to parse for snippets +--@param inner (bool) Whether this function is being called recursively +--@returns 2-tuple of strings: The first is the parsed result, the second is the +---unparsed rest of the input local function parse_snippet_rec(input, inner) local res = "" @@ -248,15 +284,20 @@ local function parse_snippet_rec(input, inner) return res, input end --- Parse completion entries, consuming snippet tokens +--- Parses snippets in a completion entry. +--- +--@param input (string) unparsed snippet +--@returns (string) parsed snippet function M.parse_snippet(input) local res, _ = parse_snippet_rec(input, false) return res end --- Sort by CompletionItem.sortText --- https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion +--@private +--- Sorts by CompletionItem.sortText. +--- +--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion local function sort_completion_items(items) if items[1] and items[1].sortText then table.sort(items, function(a, b) return a.sortText < b.sortText @@ -264,9 +305,10 @@ local function sort_completion_items(items) end end --- Returns text that should be inserted when selecting completion item. The precedence is as follows: --- textEdit.newText > insertText > label --- https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion +--@private +--- Returns text that should be inserted when selecting completion item. The +--- precedence is as follows: textEdit.newText > insertText > label +--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion local function get_completion_word(item) if item.textEdit ~= nil and item.textEdit.newText ~= nil then if protocol.InsertTextFormat[item.insertTextFormat] == "PlainText" then @@ -284,8 +326,10 @@ local function get_completion_word(item) return item.label end --- Some language servers return complementary candidates whose prefixes do not match are also returned. --- So we exclude completion candidates whose prefix does not match. +--@private +--- Some language servers return complementary candidates whose prefixes do not +--- match are also returned. So we exclude completion candidates whose prefix +--- does not match. local function remove_unmatch_completion_items(items, prefix) return vim.tbl_filter(function(item) local word = get_completion_word(item) @@ -293,16 +337,26 @@ local function remove_unmatch_completion_items(items, prefix) end, items) end --- Acording to LSP spec, if the client set "completionItemKind.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_completion +--- Acording to LSP spec, if the client set `completionItemKind.valueSet`, +--- the client must handle it properly even if it receives a value outside the +--- specification. +--- +--@param completion_item_kind (`vim.lsp.protocol.completionItemKind`) +--@returns (`vim.lsp.protocol.completionItemKind`) +--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion function M._get_completion_item_kind_name(completion_item_kind) return protocol.CompletionItemKind[completion_item_kind] or "Unknown" end ---- Getting vim complete-items with incomplete flag. --- @params CompletionItem[], CompletionList or nil (https://microsoft.github.io/language-server-protocol/specification#textDocument_completion) --- @return { matches = complete-items table, incomplete = boolean } +--- Turns the result of a `textDocument/completion` request into vim-compatible +--- |complete-items|. +--- +--@param result The result of a `textDocument/completion` call, e.g. from +---|vim.lsp.buf.completion()|, which may be one of `CompletionItem[]`, +--- `CompletionList` or `null` +--@param prefix (string) the prefix to filter the completion items +--@returns { matches = complete-items table, incomplete = bool } +--@see |complete-items| function M.text_document_completion_list_to_complete_items(result, prefix) local items = M.extract_completion_items(result) if vim.tbl_isempty(items) then @@ -350,7 +404,10 @@ function M.text_document_completion_list_to_complete_items(result, prefix) return matches end --- @params WorkspaceEdit [table] see https://microsoft.github.io/language-server-protocol/specification +--- Applies a `WorkspaceEdit`. +--- +--@param workspace_edit (table) `WorkspaceEdit` +-- @see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_applyEdit function M.apply_workspace_edit(workspace_edit) if workspace_edit.documentChanges then for _, change in ipairs(workspace_edit.documentChanges) do @@ -375,9 +432,15 @@ function M.apply_workspace_edit(workspace_edit) end end ---- Convert any of MarkedString | MarkedString[] | MarkupContent into markdown text lines --- see https://microsoft.github.io/language-server-protocol/specifications/specification-3-14/#textDocument_hover --- Useful for textDocument/hover, textDocument/signatureHelp, and potentially others. +--- Converts any of `MarkedString` | `MarkedString[]` | `MarkupContent` into +--- a list of lines containing valid markdown. Useful to populate the hover +--- window for `textDocument/hover`, for parsing the result of +--- `textDocument/signatureHelp`, and potentially others. +--- +--@param input (`MarkedString` | `MarkedString[]` | `MarkupContent`) +--@param contents (table, optional, default `{}`) List of strings to extend with converted lines +--@returns {contents}, extended with lines of converted markdown. +--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_hover function M.convert_input_to_markdown_lines(input, contents) contents = contents or {} -- MarkedString variation 1 @@ -416,8 +479,11 @@ 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 +--- Converts `textDocument/SignatureHelp` response to markdown lines. +--- +--@param signature_help Response of `textDocument/SignatureHelp` +--@returns list of lines of converted markdown. +--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_signatureHelp function M.convert_signature_help_to_markdown_lines(signature_help) if not signature_help.signatures then return @@ -475,6 +541,13 @@ function M.convert_signature_help_to_markdown_lines(signature_help) return contents end +--- Creates a table with sensible default options for a floating window. The +--- table can be passed to |nvim_open_win()|. +--- +--@param width (number) window width (in character cells) +--@param height (number) window height (in character cells) +--@param opts (table, optional) +--@returns (table) Options function M.make_floating_popup_options(width, height, opts) validate { opts = { opts, 't', true }; @@ -520,6 +593,10 @@ function M.make_floating_popup_options(width, height, opts) } end +--- Jumps to a location. +--- +--@param location (`Location`|`LocationLink`) +--@returns `true` if the jump succeeded function M.jump_to_location(location) -- location may be Location or LocationLink local uri = location.uri or location.targetUri @@ -543,14 +620,14 @@ function M.jump_to_location(location) return true end ---- Preview a location in a floating windows +--- Previews a location in a floating window --- --- behavior depends on type of location: --- - for Location, range is shown (e.g., function definition) --- - for LocationLink, targetRange is shown (e.g., body of function definition) --- ---@param location a single Location or LocationLink ---@return bufnr,winnr buffer and window number of floating window or nil +--@param location a single `Location` or `LocationLink` +--@returns (bufnr,winnr) buffer and window number of floating window or nil function M.preview_location(location) -- location may be LocationLink or Location (more useful for the former) local uri = location.targetUri or location.uri @@ -565,6 +642,7 @@ function M.preview_location(location) return M.open_floating_preview(contents, filetype) end +--@private local function find_window_by_var(name, value) for _, win in ipairs(api.nvim_list_wins()) do if npcall(api.nvim_win_get_var, win, name) == value then @@ -573,12 +651,18 @@ local function find_window_by_var(name, value) end end --- Check if a window with `unique_name` tagged is associated with the current --- buffer. If not, make a new preview. --- --- fn()'s return bufnr, winnr --- case that a new floating window should be created. +--- Enters/leaves the focusable window associated with the current buffer via the +--window - variable `unique_name`. If no such window exists, run the function +--{fn}. +--- +--@param unique_name (string) Window variable +--@param fn (function) should return create a new window and return a tuple of +---({focusable_buffer_id}, {window_id}). if {focusable_buffer_id} is a valid +---buffer id, the newly created window will be the new focus associated with +---the current buffer via the tag `unique_name`. +--@returns (pbufnr, pwinnr) if `fn()` has created a new window; nil otherwise function M.focusable_float(unique_name, fn) + -- Go back to previous window if we are in a focusable one if npcall(api.nvim_win_get_var, 0, unique_name) then return api.nvim_command("wincmd p") end @@ -598,18 +682,21 @@ function M.focusable_float(unique_name, fn) end end --- Check if a window with `unique_name` tagged is associated with the current --- buffer. If not, make a new preview. --- --- fn()'s return values will be passed directly to open_floating_preview in the --- case that a new floating window should be created. +--- Focuses/unfocuses the floating preview window associated with the current +--- buffer via the window variable `unique_name`. If no such preview window +--- exists, makes a new one. +--- +--@param unique_name (string) Window variable +--@param fn (function) The return values of this function will be passed +---directly to |vim.lsp.util.open_floating_preview()|, in the case that a new +---floating window should be created function M.focusable_preview(unique_name, fn) return M.focusable_float(unique_name, function() return M.open_floating_preview(fn()) end) end ---- Trim empty lines from input and pad left and right with spaces +--- Trims empty lines from input and pad left and right with spaces --- --@param contents table of lines to trim and pad --@param opts dictionary with optional fields @@ -617,7 +704,7 @@ end -- - pad_right number of columns to pad contents at right (default 1) -- - pad_top number of lines to pad contents at top (default 0) -- - pad_bottom number of lines to pad contents at bottom (default 0) ---@return contents table of trimmed and padded lines +--@returns contents table of trimmed and padded lines function M._trim_and_pad(contents, opts) validate { contents = { contents, 't' }; @@ -645,12 +732,13 @@ end ---- Convert markdown into syntax highlighted regions by stripping the code +-- TODO: refactor to separate stripping/converting and make use of open_floating_preview +-- +--- Converts markdown into syntax highlighted regions by stripping the code --- blocks and converting them into highlighted code. --- This will by default insert a blank line separator after those code block --- regions to improve readability. ---- The result is shown in a floating preview ---- TODO: refactor to separate stripping/converting and make use of open_floating_preview +--- The result is shown in a floating preview. --- --@param contents table of lines to show in window --@param opts dictionary with optional fields @@ -664,7 +752,7 @@ end -- - pad_top number of lines to pad contents at top -- - pad_bottom number of lines to pad contents at bottom -- - separator insert separator after code block ---@return width,height size of float +--@returns width,height size of float function M.fancy_floating_markdown(contents, opts) validate { contents = { contents, 't' }; @@ -738,6 +826,7 @@ function M.fancy_floating_markdown(contents, opts) vim.cmd("ownsyntax markdown") local idx = 1 + --@private local function apply_syntax_to_region(ft, start, finish) if ft == '' then return end local name = ft..idx @@ -763,11 +852,17 @@ function M.fancy_floating_markdown(contents, opts) return bufnr, winnr end +--- Creates autocommands to close a preview window when events happen. +--- +--@param events (table) list of events +--@param winnr (number) window id of preview window +--@see |autocmd-events| function M.close_preview_autocmd(events, winnr) api.nvim_command("autocmd "..table.concat(events, ',').." <buffer> ++once lua pcall(vim.api.nvim_win_close, "..winnr..", true)") end ---- Compute size of float needed to show contents (with optional wrapping) +--@internal +--- Computes size of float needed to show contents (with optional wrapping) --- --@param contents table of lines to show in window --@param opts dictionary with optional fields @@ -776,7 +871,7 @@ end -- - wrap_at character to wrap at for computing height -- - max_width maximal width of floating window -- - max_height maximal height of floating window ---@return width,height size of float +--@returns width,height size of float function M._make_floating_popup_size(contents, opts) validate { contents = { contents, 't' }; @@ -827,7 +922,7 @@ function M._make_floating_popup_size(contents, opts) return width, height end ---- Show contents in a floating window +--- Shows contents in a floating window. --- --@param contents table of lines to show in window --@param filetype string of filetype to set for opened buffer @@ -841,7 +936,8 @@ end -- - pad_right number of columns to pad contents at right -- - pad_top number of lines to pad contents at top -- - pad_bottom number of lines to pad contents at bottom ---@return bufnr,winnr buffer and window number of floating window or nil +--@returns bufnr,winnr buffer and window number of the newly created floating +---preview window function M.open_floating_preview(contents, filetype, opts) validate { contents = { contents, 't' }; @@ -912,6 +1008,9 @@ do severity_floating_highlights[severity] = floating_highlight_name end + --- Clears diagnostics for a buffer. + --- + --@param bufnr (number) buffer id function M.buf_clear_diagnostics(bufnr) validate { bufnr = {bufnr, 'n', true} } bufnr = bufnr == 0 and api.nvim_get_current_buf() or bufnr @@ -923,10 +1022,18 @@ do api.nvim_buf_clear_namespace(bufnr, diagnostic_ns, 0, -1) end + --- Gets the name of a severity's highlight group. + --- + --@param severity A member of `vim.lsp.protocol.DiagnosticSeverity` + --@returns (string) Highlight group name function M.get_severity_highlight_name(severity) return severity_highlights[severity] end + --- Gets list of diagnostics for the current line. + --- + --@returns (table) list of `Diagnostic` tables + --@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#diagnostic function M.get_line_diagnostics() local bufnr = api.nvim_get_current_buf() local linenr = api.nvim_win_get_cursor(0)[1] - 1 @@ -941,6 +1048,8 @@ do return diagnostics_by_line[linenr] or {} end + --- Displays the diagnostics for the current line in a floating hover + --- window. function M.show_line_diagnostics() -- local marks = api.nvim_buf_get_extmarks(bufnr, diagnostic_ns, {line, 0}, {line, -1}, {}) -- if #marks == 0 then @@ -977,10 +1086,10 @@ do return popup_bufnr, winnr end - --- Saves the diagnostics (Diagnostic[]) into diagnostics_by_buf + --- Saves diagnostics into vim.lsp.util.diagnostics_by_buf[{bufnr}]. --- - --@param bufnr bufnr for which the diagnostics are for. - --@param diagnostics Diagnostics[] received from the language server. + --@param bufnr (number) buffer id for which the diagnostics are for + --@param diagnostics list of `Diagnostic`s received from the LSP server function M.buf_diagnostics_save_positions(bufnr, diagnostics) validate { bufnr = {bufnr, 'n', true}; @@ -1000,6 +1109,10 @@ do M.diagnostics_by_buf[bufnr] = diagnostics end + --- Highlights a list of diagnostics in a buffer by underlining them. + --- + --@param bufnr (number) buffer id + --@param diagnostics (list of `Diagnostic`s) function M.buf_diagnostics_underline(bufnr, diagnostics) for _, diagnostic in ipairs(diagnostics) do local start = diagnostic.range["start"] @@ -1020,11 +1133,18 @@ do end end + --- Removes document highlights from a buffer. + --- + --@param bufnr buffer id function M.buf_clear_references(bufnr) validate { bufnr = {bufnr, 'n', true} } api.nvim_buf_clear_namespace(bufnr, reference_ns, 0, -1) end + --- Shows a list of document highlights for a certain buffer. + --- + --@param bufnr buffer id + --@param references List of `DocumentHighlight` objects to highlight function M.buf_highlight_references(bufnr, references) validate { bufnr = {bufnr, 'n', true} } for _, reference in ipairs(references) do @@ -1040,11 +1160,19 @@ do end end + --- Groups a list of diagnostics by line. + --- + --@param diagnostics (table) list of `Diagnostic`s + --@returns (table) dictionary mapping lines to lists of diagnostics valid on + ---those lines + --@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#diagnostic function M.diagnostics_group_by_line(diagnostics) if not diagnostics then return end local diagnostics_by_line = {} for _, diagnostic in ipairs(diagnostics) do local start = diagnostic.range.start + -- TODO: Are diagnostics only valid for a single line? I don't understand + -- why this would be okay otherwise local line_diagnostics = diagnostics_by_line[start.line] if not line_diagnostics then line_diagnostics = {} @@ -1055,6 +1183,11 @@ do return diagnostics_by_line end + --- Given a list of diagnostics, sets the corresponding virtual text for a + --- buffer. + --- + --@param bufnr buffer id + --@param diagnostics (table) list of `Diagnostic`s function M.buf_diagnostics_virtual_text(bufnr, diagnostics) if not diagnostics then return @@ -1093,8 +1226,7 @@ do --- </pre> --- --@param kind Diagnostic severity kind: See |vim.lsp.protocol.DiagnosticSeverity| - --- - --@return Count of diagnostics + --@returns Count of diagnostics function M.buf_diagnostics_count(kind) local bufnr = vim.api.nvim_get_current_buf() local diagnostics = M.diagnostics_by_buf[bufnr] @@ -1115,7 +1247,7 @@ do [protocol.DiagnosticSeverity.Hint] = "LspDiagnosticsHintSign"; } - --- Place signs for each diagnostic in the sign column. + --- Places signs for each diagnostic in the sign column. --- --- Sign characters can be customized with the following commands: --- @@ -1136,8 +1268,11 @@ local position_sort = sort_by_key(function(v) return {v.start.line, v.start.character} end) --- Returns the items with the byte position calculated correctly and in sorted --- order. +--- Returns the items with the byte position calculated correctly and in sorted +--- order, for display in quickfix and location lists. +--- +--@param locations (table) list of `Location`s or `LocationLink`s +--@returns (table) list of items function M.locations_to_items(locations) local items = {} local grouped = setmetatable({}, { @@ -1180,6 +1315,10 @@ function M.locations_to_items(locations) return items end +--- Fills current window's location list with given list of items. +--- Can be obtained with e.g. |vim.lsp.util.locations_to_items()|. +--- +--@param items (table) list of items function M.set_loclist(items) vim.fn.setloclist(0, {}, ' ', { title = 'Language Server'; @@ -1187,6 +1326,10 @@ function M.set_loclist(items) }) end +--- Fills quickfix list with given list of items. +--- Can be obtained with e.g. |vim.lsp.util.locations_to_items()|. +--- +--@param items (table) list of items function M.set_qflist(items) vim.fn.setqflist({}, ' ', { title = 'Language Server'; @@ -1201,10 +1344,11 @@ function M._get_symbol_kind_name(symbol_kind) return protocol.SymbolKind[symbol_kind] or "Unknown" end ---- Convert symbols to quickfix list items +--- Converts symbols to quickfix list items. --- --@param symbols DocumentSymbol[] or SymbolInformation[] function M.symbols_to_items(symbols, bufnr) + --@private local function _symbols_to_items(_symbols, _items, _bufnr) for _, symbol in ipairs(_symbols) do if symbol.location then -- SymbolInformation type @@ -1239,7 +1383,9 @@ function M.symbols_to_items(symbols, bufnr) return _symbols_to_items(symbols, {}, bufnr) end --- Remove empty lines from the beginning and end. +--- Removes empty lines from the beginning and end. +--@param lines (table) list of lines to trim +--@returns (table) trimmed list of lines function M.trim_empty_lines(lines) local start = 1 for i = 1, #lines do @@ -1258,11 +1404,13 @@ function M.trim_empty_lines(lines) return vim.list_extend({}, lines, start, finish) end --- Accepts markdown lines and tries to reduce it to a filetype if it is --- just a single code block. --- Note: This modifies the input. --- --- Returns: filetype or 'markdown' if it was unchanged. +--- Accepts markdown lines and tries to reduce them to a filetype if they +--- comprise just a single code block. +--- +--- CAUTION: Modifies the input in-place! +--- +--@param lines (table) list of lines +--@returns (string) filetype or 'markdown' if it was unchanged. function M.try_trim_markdown_code_blocks(lines) local language_id = lines[1]:match("^```(.*)") if language_id then @@ -1285,6 +1433,7 @@ function M.try_trim_markdown_code_blocks(lines) end local str_utfindex = vim.str_utfindex +--@private local function make_position_param() local row, col = unpack(api.nvim_win_get_cursor(0)) row = row - 1 @@ -1293,6 +1442,10 @@ local function make_position_param() return { line = row; character = col; } end +--- Creates a `TextDocumentPositionParams` object for the current buffer and cursor position. +--- +--@returns `TextDocumentPositionParams` object +--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentPositionParams function M.make_position_params() return { textDocument = M.make_text_document_params(); @@ -1300,6 +1453,13 @@ function M.make_position_params() } end +--- Using the current position in the current buffer, creates an object that +--- can be used as a building block for several LSP requests, such as +--- `textDocument/codeAction`, `textDocument/colorPresentation`, +--- `textDocument/rangeFormatting`. +--- +--@returns { textDocument = { uri = `current_file_uri` }, range = { start = +---`current_position`, end = `current_position` } } function M.make_range_params() local position = make_position_param() return { @@ -1308,11 +1468,15 @@ function M.make_range_params() } end +--- Creates a `TextDocumentIdentifier` object for the current buffer. +--- +--@returns `TextDocumentIdentifier` +--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentIdentifier function M.make_text_document_params() return { uri = vim.uri_from_bufnr(0) } end ---- Get visual width of tabstop. +--- Returns visual width of tabstop. --- --@see |softtabstop| --@param bufnr (optional, number): Buffer handle, defaults to current @@ -1324,6 +1488,11 @@ function M.get_effective_tabstop(bufnr) return (sts > 0 and sts) or (sts < 0 and bo.shiftwidth) or bo.tabstop end +--- Creates a `FormattingOptions` object for the current buffer and cursor position. +--- +--@param options Table with valid `FormattingOptions` entries +--@returns `FormattingOptions object +--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_formatting function M.make_formatting_params(options) validate { options = {options, 't', true} } options = vim.tbl_extend('keep', options or {}, { @@ -1336,9 +1505,12 @@ function M.make_formatting_params(options) } end --- @param buf buffer handle or 0 for current. --- @param row 0-indexed line --- @param col 0-indexed byte offset in line +--- Returns the UTF-32 and UTF-16 offsets for a position in a certain buffer. +--- +--@param buf buffer id (0 for current) +--@param row 0-indexed line +--@param col 0-indexed byte offset in line +--@returns (number, number) UTF-32 and UTF-16 index of the character in line {row} column {col} in buffer {buf} function M.character_offset(buf, row, col) local line = api.nvim_buf_get_lines(buf, row, row+1, true)[1] -- If the col is past the EOL, use the line length. |