From a5fe8f59d98398d04bed8586cee73864bbcdde92 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Tue, 27 Feb 2024 15:20:32 +0000 Subject: docs: improve/add documentation of Lua types - Added `@inlinedoc` so single use Lua types can be inlined into the functions docs. E.g. ```lua --- @class myopts --- @inlinedoc --- --- Documentation for some field --- @field somefield integer --- @param opts myOpts function foo(opts) end ``` Will be rendered as ``` foo(opts) Parameters: - {opts} (table) Object with the fields: - somefield (integer) Documentation for some field ``` - Marked many classes with with `@nodoc` or `(private)`. We can eventually introduce these when we want to. --- runtime/lua/tohtml.lua | 47 +++-- runtime/lua/vim/_editor.lua | 5 +- runtime/lua/vim/_inspector.lua | 28 ++- runtime/lua/vim/_meta/builtin.lua | 1 + runtime/lua/vim/_meta/lpeg.lua | 2 + runtime/lua/vim/_meta/regex.lua | 1 + runtime/lua/vim/_options.lua | 1 + runtime/lua/vim/diagnostic.lua | 123 ++++++++--- runtime/lua/vim/filetype.lua | 32 +-- runtime/lua/vim/fs.lua | 49 +++-- runtime/lua/vim/iter.lua | 3 + runtime/lua/vim/loader.lua | 72 ++++--- runtime/lua/vim/lsp.lua | 297 +++++---------------------- runtime/lua/vim/lsp/_changetracking.lua | 12 +- runtime/lua/vim/lsp/buf.lua | 251 ++++++++++++---------- runtime/lua/vim/lsp/client.lua | 123 +++++++++-- runtime/lua/vim/lsp/codelens.lua | 6 +- runtime/lua/vim/lsp/diagnostic.lua | 2 +- runtime/lua/vim/lsp/handlers.lua | 1 + runtime/lua/vim/lsp/inlay_hint.lua | 24 +-- runtime/lua/vim/lsp/rpc.lua | 40 ++-- runtime/lua/vim/lsp/semantic_tokens.lua | 26 ++- runtime/lua/vim/lsp/util.lua | 91 +++++--- runtime/lua/vim/secure.lua | 25 ++- runtime/lua/vim/shared.lua | 24 ++- runtime/lua/vim/snippet.lua | 4 +- runtime/lua/vim/treesitter.lua | 30 +-- runtime/lua/vim/treesitter/_query_linter.lua | 6 +- runtime/lua/vim/treesitter/dev.lua | 69 ++++--- runtime/lua/vim/treesitter/highlighter.lua | 19 +- runtime/lua/vim/treesitter/language.lua | 20 +- runtime/lua/vim/treesitter/languagetree.lua | 41 ++-- runtime/lua/vim/treesitter/query.lua | 52 +++-- runtime/lua/vim/version.lua | 61 +++--- 34 files changed, 838 insertions(+), 750 deletions(-) (limited to 'runtime/lua') diff --git a/runtime/lua/tohtml.lua b/runtime/lua/tohtml.lua index e3c7fc68c0..52e0742ef3 100644 --- a/runtime/lua/tohtml.lua +++ b/runtime/lua/tohtml.lua @@ -25,13 +25,7 @@ -- Remarks: -- - Not all visuals are supported, so it may differ. ---- @class vim.tohtml.opt ---- @field title? string|false ---- @field number_lines? boolean ---- @field font? string[]|string ---- @field width? integer - ---- @class vim.tohtml.state.global +--- @class (private) vim.tohtml.state.global --- @field background string --- @field foreground string --- @field title string|false @@ -39,7 +33,7 @@ --- @field highlights_name table --- @field conf vim.tohtml.opt ---- @class vim.tohtml.state:vim.tohtml.state.global +--- @class (private) vim.tohtml.state:vim.tohtml.state.global --- @field style vim.tohtml.styletable --- @field tabstop string|false --- @field opt vim.wo @@ -48,20 +42,20 @@ --- @field width integer --- @field buflen integer ---- @class vim.tohtml.styletable +--- @class (private) vim.tohtml.styletable --- @field [integer] vim.tohtml.line (integer: (1-index, exclusive)) ---- @class vim.tohtml.line +--- @class (private) vim.tohtml.line --- @field virt_lines {[integer]:{[1]:string,[2]:integer}[]} --- @field pre_text string[][] --- @field hide? boolean --- @field [integer] vim.tohtml.cell? (integer: (1-index, exclusive)) ---- @class vim.tohtml.cell +--- @class (private) vim.tohtml.cell --- @field [1] integer[] start --- @field [2] integer[] close ---- @field [3] any[][] virt_text ---- @field [4] any[][] overlay_text +--- @field [3] any[][] virt_text +--- @field [4] any[][] overlay_text local HIDE_ID = -1 -- stylua: ignore start @@ -1319,14 +1313,29 @@ end local M = {} +--- @class vim.tohtml.opt +--- @inlinedoc +--- +--- Title tag to set in the generated HTML code. +--- (default: buffer name) +--- @field title? string|false +--- +--- Show line numbers. +--- (default: `false`) +--- @field number_lines? boolean +--- +--- Fonts to use. +--- (default: `guifont`) +--- @field font? string[]|string +--- +--- Width used for items which are either right aligned or repeat a character +--- infinitely. +--- (default: 'textwidth' if non-zero or window width otherwise) +--- @field width? integer + --- Converts the buffer shown in the window {winid} to HTML and returns the output as a list of string. --- @param winid? integer Window to convert (defaults to current window) ---- @param opt? vim.tohtml.opt (table) Optional parameters. ---- - title (string): Title tag to set in the generated HTML code (defaults to buffer name) ---- - number_lines (boolean): Show line numbers (defaults to `false`) ---- - font (string|string[]): Fonts to use (defaults to `guifont`) ---- - width (integer) Width used for items which are either right aligned or repeat a character infinitely ---- (defaults to 'textwidth' if non-zero or window width otherwise) +--- @param opt? vim.tohtml.opt Optional parameters. --- @return string[] function M.tohtml(winid, opt) return win_to_html(winid or 0, opt) diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 4e39abb2be..d14007312e 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -190,6 +190,7 @@ function vim._os_proc_children(ppid) return children end +--- @nodoc --- @class vim.inspect.Opts --- @field depth? integer --- @field newline? string @@ -454,7 +455,7 @@ vim.cmd = setmetatable({}, { end, }) ---- @class vim.var_accessor +--- @class (private) vim.var_accessor --- @field [string] any --- @field [integer] vim.var_accessor @@ -1048,7 +1049,7 @@ function vim.deprecate(name, alternative, version, plugin, backtrace) -- e.g., when planned to be removed in version = '0.12' (soft-deprecated since 0.10-dev), -- show warnings since 0.11, including 0.11-dev (hard_deprecated_since = 0.11-dev). if plugin == 'Nvim' then - local current_version = vim.version() ---@type Version + local current_version = vim.version() ---@type vim.Version local removal_version = assert(vim.version.parse(version)) local is_hard_deprecated ---@type boolean diff --git a/runtime/lua/vim/_inspector.lua b/runtime/lua/vim/_inspector.lua index 9a073c32c4..a19d40c50d 100644 --- a/runtime/lua/vim/_inspector.lua +++ b/runtime/lua/vim/_inspector.lua @@ -1,8 +1,18 @@ ----@class InspectorFilter ----@field syntax boolean include syntax based highlight groups (defaults to true) ----@field treesitter boolean include treesitter based highlight groups (defaults to true) ----@field extmarks boolean|"all" include extmarks. When `all`, then extmarks without a `hl_group` will also be included (defaults to true) ----@field semantic_tokens boolean include semantic token highlights (defaults to true) +--- @class vim._inspector.Filter +--- @inlinedoc +--- +--- Include syntax based highlight groups (defaults to true) +--- @field syntax boolean +--- +--- Include treesitter based highlight groups (defaults to true) +--- @field treesitter boolean +--- +--- Include extmarks. When `all`, then extmarks without a `hl_group` will also be included. +--- (default: true) +--- @field extmarks boolean|"all" +--- +--- Include semantic token highlights (defaults to true) +--- @field semantic_tokens boolean local defaults = { syntax = true, treesitter = true, @@ -17,11 +27,7 @@ local defaults = { ---@param bufnr? integer defaults to the current buffer ---@param row? integer row to inspect, 0-based. Defaults to the row of the current cursor ---@param col? integer col to inspect, 0-based. Defaults to the col of the current cursor ----@param filter? InspectorFilter (table) a table with key-value pairs to filter the items ---- - syntax (boolean): include syntax based highlight groups (defaults to true) ---- - treesitter (boolean): include treesitter based highlight groups (defaults to true) ---- - extmarks (boolean|"all"): include extmarks. When `all`, then extmarks without a `hl_group` will also be included (defaults to true) ---- - semantic_tokens (boolean): include semantic tokens (defaults to true) +---@param filter? vim._inspector.Filter Table with key-value pairs to filter the items ---@return {treesitter:table,syntax:table,extmarks:table,semantic_tokens:table,buffer:integer,col:integer,row:integer} (table) a table with the following key-value pairs. Items are in "traversal order": --- - treesitter: a list of treesitter captures --- - syntax: a list of syntax groups @@ -139,7 +145,7 @@ end ---@param bufnr? integer defaults to the current buffer ---@param row? integer row to inspect, 0-based. Defaults to the row of the current cursor ---@param col? integer col to inspect, 0-based. Defaults to the col of the current cursor ----@param filter? InspectorFilter (table) see |vim.inspect_pos()| +---@param filter? vim._inspector.Filter (table) see |vim.inspect_pos()| function vim.show_pos(bufnr, row, col, filter) local items = vim.inspect_pos(bufnr, row, col, filter) diff --git a/runtime/lua/vim/_meta/builtin.lua b/runtime/lua/vim/_meta/builtin.lua index 472162ecc1..4831989e1a 100644 --- a/runtime/lua/vim/_meta/builtin.lua +++ b/runtime/lua/vim/_meta/builtin.lua @@ -61,6 +61,7 @@ error('Cannot require a meta file') --- --- +---@nodoc ---@class vim.NIL ---@type vim.NIL diff --git a/runtime/lua/vim/_meta/lpeg.lua b/runtime/lua/vim/_meta/lpeg.lua index 202c99f18c..1ce40f3340 100644 --- a/runtime/lua/vim/_meta/lpeg.lua +++ b/runtime/lua/vim/_meta/lpeg.lua @@ -21,6 +21,7 @@ error('Cannot require a meta file') vim.lpeg = {} +--- @nodoc --- @class vim.lpeg.Pattern --- @operator unm: vim.lpeg.Pattern --- @operator add(vim.lpeg.Pattern): vim.lpeg.Pattern @@ -167,6 +168,7 @@ function vim.lpeg.S(string) end --- @return vim.lpeg.Pattern function vim.lpeg.V(v) end +--- @nodoc --- @class vim.lpeg.Locale --- @field alnum userdata --- @field alpha userdata diff --git a/runtime/lua/vim/_meta/regex.lua b/runtime/lua/vim/_meta/regex.lua index ab403b97e7..595ad96319 100644 --- a/runtime/lua/vim/_meta/regex.lua +++ b/runtime/lua/vim/_meta/regex.lua @@ -12,6 +12,7 @@ --- @return vim.regex function vim.regex(re) end +--- @nodoc --- @class vim.regex local regex = {} -- luacheck: no unused diff --git a/runtime/lua/vim/_options.lua b/runtime/lua/vim/_options.lua index f1fed50c6d..bde9421552 100644 --- a/runtime/lua/vim/_options.lua +++ b/runtime/lua/vim/_options.lua @@ -797,6 +797,7 @@ end --- `vim.opt_global`. --- +--- @nodoc --- @class vim.Option local Option = {} -- luacheck: no unused diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 49165c4db9..3979e5512c 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -2,18 +2,44 @@ local api, if_nil = vim.api, vim.F.if_nil local M = {} +--- *diagnostic-structure* +--- +--- Diagnostics use the same indexing as the rest of the Nvim API (i.e. 0-based +--- rows and columns). |api-indexing| --- @class vim.Diagnostic +--- +--- Buffer number --- @field bufnr? integer ---- @field lnum integer 0-indexed ---- @field end_lnum? integer 0-indexed ---- @field col integer 0-indexed ---- @field end_col? integer 0-indexed +--- +--- The starting line of the diagnostic (0-indexed) +--- @field lnum integer +--- +--- The final line of the diagnostic (0-indexed) +--- @field end_lnum? integer +--- +--- The starting column of the diagnostic (0-indexed) +--- @field col integer +--- +--- The final column of the diagnostic (0-indexed) +--- @field end_col? integer +--- +--- The severity of the diagnostic |vim.diagnostic.severity| --- @field severity? vim.diagnostic.Severity +--- +--- The diagnostic text --- @field message string +--- +--- The source of the diagnostic --- @field source? string +--- +--- The diagnostic code --- @field code? string|integer +--- --- @field _tags? { deprecated: boolean, unnecessary: boolean} +--- +--- Arbitrary data plugins or users can add --- @field user_data? any arbitrary data plugins can add +--- --- @field namespace? integer --- @class vim.diagnostic.Opts @@ -104,7 +130,7 @@ local global_diagnostic_options = { severity_sort = false, } ---- @class vim.diagnostic.Handler +--- @class (private) vim.diagnostic.Handler --- @field show? fun(namespace: integer, bufnr: integer, diagnostics: vim.Diagnostic[], opts?: vim.diagnostic.OptsResolved) --- @field hide? fun(namespace:integer, bufnr:integer) @@ -154,7 +180,7 @@ do }) end ---- @class vim.diagnostic._extmark +--- @class (private) vim.diagnostic._extmark --- @field [1] integer id --- @field [2] integer start --- @field [3] integer end @@ -1018,31 +1044,52 @@ function M.get_next_pos(opts) return { next.lnum, next.col } end +--- A table with the following keys: --- @class vim.diagnostic.GetOpts +--- @inlinedoc +--- +--- Limit diagnostics to the given namespace. --- @field namespace? integer +--- +--- Limit diagnostics to the given line number. --- @field lnum? integer +--- +--- See |diagnostic-severity|. --- @field severity? vim.diagnostic.SeverityFilter +--- Configuration table with the following keys: --- @class vim.diagnostic.GotoOpts : vim.diagnostic.GetOpts +--- @inlinedoc +--- +--- Only consider diagnostics from the given namespace. +--- @field namespace integer +--- +--- Cursor position as a (row, col) tuple. +--- See |nvim_win_get_cursor()|. Defaults to the current cursor position. --- @field cursor_position? {[1]:integer,[2]:integer} +--- +--- Whether to loop around file or not. Similar to 'wrapscan'. +--- (default: `true`) --- @field wrap? boolean +--- +--- See |diagnostic-severity|. +--- @field severity vim.diagnostic.Severity +--- +--- If "true", call |vim.diagnostic.open_float()| +--- after moving. If a table, pass the table as the {opts} parameter +--- to |vim.diagnostic.open_float()|. Unless overridden, the float will show +--- diagnostics at the new cursor position (as if "cursor" were passed to +--- the "scope" option). +--- (default: `true`) --- @field float? boolean|vim.diagnostic.Opts.Float +--- +--- Window ID +--- (default: `0`) --- @field win_id? integer --- Move to the next diagnostic. --- ----@param opts? vim.diagnostic.GotoOpts (table) Configuration table with the following keys: ---- - namespace: (integer) Only consider diagnostics from the given namespace. ---- - cursor_position: (cursor position) Cursor position as a (row, col) tuple. ---- See |nvim_win_get_cursor()|. Defaults to the current cursor position. ---- - wrap: (boolean, default true) Whether to loop around file or not. Similar to 'wrapscan'. ---- - severity: See |diagnostic-severity|. ---- - float: (boolean or table, default true) If "true", call |vim.diagnostic.open_float()| ---- after moving. If a table, pass the table as the {opts} parameter ---- to |vim.diagnostic.open_float()|. Unless overridden, the float will show ---- diagnostics at the new cursor position (as if "cursor" were passed to ---- the "scope" option). ---- - win_id: (number, default 0) Window ID +---@param opts? vim.diagnostic.GotoOpts function M.goto_next(opts) diagnostic_move_pos(opts, M.get_next_pos(opts)) end @@ -1789,38 +1836,54 @@ function M.reset(namespace, bufnr) end end +--- Configuration table with the following keys: --- @class vim.diagnostic.setqflist.Opts +--- @inlinedoc +--- +--- Only add diagnostics from the given namespace. --- @field namespace? integer +--- +--- Open quickfix list after setting. +--- (default: `true`) --- @field open? boolean +--- +--- Title of quickfix list. Defaults to "Diagnostics". --- @field title? string +--- +--- See |diagnostic-severity|. --- @field severity? vim.diagnostic.Severity --- Add all diagnostics to the quickfix list. --- ----@param opts? vim.diagnostic.setqflist.Opts (table) Configuration table with the following keys: ---- - namespace: (number) Only add diagnostics from the given namespace. ---- - open: (boolean, default true) Open quickfix list after setting. ---- - title: (string) Title of quickfix list. Defaults to "Diagnostics". ---- - severity: See |diagnostic-severity|. +---@param opts? vim.diagnostic.setqflist.Opts function M.setqflist(opts) set_list(false, opts) end +---Configuration table with the following keys: --- @class vim.diagnostic.setloclist.Opts +--- @inlinedoc +--- +--- Only add diagnostics from the given namespace. --- @field namespace? integer +--- +--- Window number to set location list for. +--- (default: `0`) +--- @field winnr? integer +--- +--- Open the location list after setting. +--- (default: `true`) --- @field open? boolean +--- +--- Title of the location list. Defaults to "Diagnostics". --- @field title? string +--- +--- See |diagnostic-severity|. --- @field severity? vim.diagnostic.Severity ---- @field winnr? integer --- Add buffer diagnostics to the location list. --- ----@param opts? vim.diagnostic.setloclist.Opts (table) Configuration table with the following keys: ---- - namespace: (number) Only add diagnostics from the given namespace. ---- - winnr: (number, default 0) Window number to set location list for. ---- - open: (boolean, default true) Open the location list after setting. ---- - title: (string) Title of the location list. Defaults to "Diagnostics". ---- - severity: See |diagnostic-severity|. +---@param opts? vim.diagnostic.setloclist.Opts function M.setloclist(opts) set_list(true, opts) end diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index e7971d8916..fba76f93b2 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -2082,6 +2082,7 @@ local function normalize_path(path, as_pattern) end --- @class vim.filetype.add.filetypes +--- @inlinedoc --- @field pattern? vim.filetype.mapping --- @field extension? vim.filetype.mapping --- @field filename? vim.filetype.mapping @@ -2170,7 +2171,7 @@ end --- } --- ``` --- ----@param filetypes vim.filetype.add.filetypes (table) A table containing new filetype maps (see example). +---@param filetypes vim.filetype.add.filetypes A table containing new filetype maps (see example). function M.add(filetypes) for k, v in pairs(filetypes.extension or {}) do extension[k] = v @@ -2272,8 +2273,23 @@ local function match_pattern(name, path, tail, pat) end --- @class vim.filetype.match.args +--- @inlinedoc +--- +--- Buffer number to use for matching. Mutually exclusive with {contents} --- @field buf? integer +--- +--- Filename to use for matching. When {buf} is given, +--- defaults to the filename of the given buffer number. The +--- file need not actually exist in the filesystem. When used +--- without {buf} only the name of the file is used for +--- filetype matching. This may result in failure to detect +--- the filetype in cases where the filename alone is not +--- enough to disambiguate the filetype. --- @field filename? string +--- +--- An array of lines representing file contents to use for +--- matching. Can be used with {filename}. Mutually exclusive +--- with {buf}. --- @field contents? string[] --- Perform filetype detection. @@ -2305,20 +2321,8 @@ end --- vim.filetype.match({ contents = {'#!/usr/bin/env bash'} }) --- ``` --- ----@param args vim.filetype.match.args (table) Table specifying which matching strategy to use. +---@param args vim.filetype.match.args Table specifying which matching strategy to use. --- Accepted keys are: ---- * buf (number): Buffer number to use for matching. Mutually exclusive with ---- {contents} ---- * filename (string): Filename to use for matching. When {buf} is given, ---- defaults to the filename of the given buffer number. The ---- file need not actually exist in the filesystem. When used ---- without {buf} only the name of the file is used for ---- filetype matching. This may result in failure to detect ---- the filetype in cases where the filename alone is not ---- enough to disambiguate the filetype. ---- * contents (table): An array of lines representing file contents to use for ---- matching. Can be used with {filename}. Mutually exclusive ---- with {buf}. ---@return string|nil # If a match was found, the matched filetype. ---@return function|nil # A function that modifies buffer state when called (for example, to set some --- filetype specific buffer variables). The function accepts a buffer number as diff --git a/runtime/lua/vim/fs.lua b/runtime/lua/vim/fs.lua index 0af5fc4f30..a47b35e991 100644 --- a/runtime/lua/vim/fs.lua +++ b/runtime/lua/vim/fs.lua @@ -147,11 +147,29 @@ function M.dir(path, opts) end) end ---- @class vim.fs.find.opts +--- @class vim.fs.find.Opts +--- @inlinedoc +--- +--- Path to begin searching from. If +--- omitted, the |current-directory| is used. --- @field path string +--- +--- Search upward through parent directories. +--- Otherwise, search through child directories (recursively). +--- (default: `false`) --- @field upward boolean +--- +--- Stop searching when this directory is reached. +--- The directory itself is not searched. --- @field stop string +--- +--- Find only items of the given type. +--- If omitted, all items that match {names} are included. --- @field type string +--- +--- Stop the search after finding this many matches. +--- Use `math.huge` to place no limit on the number of matches. +--- (default: `1`) --- @field limit number --- Find files or directories (or other items as specified by `opts.type`) in the given path. @@ -194,23 +212,10 @@ end --- - path: full path of the current item --- The function should return `true` if the given item is considered a match. --- ----@param opts (table) Optional keyword arguments: ---- - path (string): Path to begin searching from. If ---- omitted, the |current-directory| is used. ---- - upward (boolean, default false): If true, search ---- upward through parent directories. Otherwise, ---- search through child directories ---- (recursively). ---- - stop (string): Stop searching when this directory is ---- reached. The directory itself is not searched. ---- - type (string): Find only items of the given type. ---- If omitted, all items that match {names} are included. ---- - limit (number, default 1): Stop the search after ---- finding this many matches. Use `math.huge` to ---- place no limit on the number of matches. +---@param opts vim.fs.find.Opts Optional keyword arguments: ---@return (string[]) # Normalized paths |vim.fs.normalize()| of all matching items function M.find(names, opts) - opts = opts or {} --[[@as vim.fs.find.opts]] + opts = opts or {} vim.validate({ names = { names, { 's', 't', 'f' } }, path = { opts.path, 's', true }, @@ -318,6 +323,13 @@ function M.find(names, opts) return matches end +--- @class vim.fs.normalize.Opts +--- @inlinedoc +--- +--- Expand environment variables. +--- (default: `true`) +--- @field expand_env boolean + --- Normalize a path to a standard format. A tilde (~) character at the --- beginning of the path is expanded to the user's home directory and any --- backslash (\) characters are converted to forward slashes (/). Environment @@ -337,9 +349,8 @@ end --- ``` --- ---@param path (string) Path to normalize ----@param opts table|nil Options: ---- - expand_env: boolean Expand environment variables (default: true) ----@return (string) Normalized path +---@param opts? vim.fs.normalize.Opts +---@return (string) : Normalized path function M.normalize(path, opts) opts = opts or {} diff --git a/runtime/lua/vim/iter.lua b/runtime/lua/vim/iter.lua index 798428014d..09de969b5b 100644 --- a/runtime/lua/vim/iter.lua +++ b/runtime/lua/vim/iter.lua @@ -64,11 +64,13 @@ --- In addition to the |vim.iter()| function, the |vim.iter| module provides --- convenience functions like |vim.iter.filter()| and |vim.iter.totable()|. +---@nodoc ---@class IterMod ---@operator call:Iter local M = {} +---@nodoc ---@class Iter local Iter = {} Iter.__index = Iter @@ -77,6 +79,7 @@ Iter.__call = function(self) end --- Special case implementations for iterators on list tables. +---@nodoc ---@class ListIter : Iter ---@field _table table Underlying table data ---@field _head number Index to the front of a table iterator diff --git a/runtime/lua/vim/loader.lua b/runtime/lua/vim/loader.lua index 5f3da55544..0d708ca1eb 100644 --- a/runtime/lua/vim/loader.lua +++ b/runtime/lua/vim/loader.lua @@ -10,16 +10,37 @@ local M = {} ---@alias CacheHash {mtime: {nsec: integer, sec: integer}, size: integer, type?: uv.aliases.fs_stat_types} ---@alias CacheEntry {hash:CacheHash, chunk:string} ----@class ModuleFindOpts ----@field all? boolean Search for all matches (defaults to `false`) ----@field rtp? boolean Search for modname in the runtime path (defaults to `true`) ----@field patterns? string[] Patterns to use (defaults to `{"/init.lua", ".lua"}`) ----@field paths? string[] Extra paths to search for modname - ----@class ModuleInfo ----@field modpath string Path of the module ----@field modname string Name of the module ----@field stat? uv.uv_fs_t File stat of the module path +--- @class vim.loader.find.Opts +--- @inlinedoc +--- +--- Search for modname in the runtime path. +--- (default: `true`) +--- @field rtp? boolean +--- +--- Extra paths to search for modname +--- (default: `{}`) +--- @field paths? string[] +--- +--- List of patterns to use when searching for modules. +--- A pattern is a string added to the basename of the Lua module being searched. +--- (default: `{"/init.lua", ".lua"}`) +--- @field patterns? string[] +--- +--- Search for all matches. +--- (default: `false`) +--- @field all? boolean + +--- @class vim.loader.ModuleInfo +--- @inlinedoc +--- +--- Path of the module +--- @field modpath string +--- +--- Name of the module +--- @field modname string +--- +--- The fs_stat of the module path. Won't be returned for `modname="*"` +--- @field stat? uv.uv_fs_t ---@alias LoaderStats table @@ -29,14 +50,14 @@ M.path = vim.fn.stdpath('cache') .. '/luac' ---@nodoc M.enabled = false ----@class Loader ----@field _rtp string[] ----@field _rtp_pure string[] ----@field _rtp_key string ----@field _hashes? table +---@class (private) Loader +---@field private _rtp string[] +---@field private _rtp_pure string[] +---@field private _rtp_key string +---@field private _hashes? table local Loader = { VERSION = 4, - ---@type table> + ---@type table> _indexed = {}, ---@type table _topmods = {}, @@ -270,17 +291,8 @@ end --- Finds Lua modules for the given module name. ---@param modname string Module name, or `"*"` to find the top-level modules instead ----@param opts? ModuleFindOpts (table) Options for finding a module: ---- - rtp: (boolean) Search for modname in the runtime path (defaults to `true`) ---- - paths: (string[]) Extra paths to search for modname (defaults to `{}`) ---- - patterns: (string[]) List of patterns to use when searching for modules. ---- A pattern is a string added to the basename of the Lua module being searched. ---- (defaults to `{"/init.lua", ".lua"}`) ---- - all: (boolean) Return all matches instead of just the first one (defaults to `false`) ----@return ModuleInfo[] (table) A list of results with the following properties: ---- - modpath: (string) the path to the module ---- - modname: (string) the name of the module ---- - stat: (table|nil) the fs_stat of the module path. Won't be returned for `modname="*"` +---@param opts? vim.loader.find.Opts Options for finding a module: +---@return vim.loader.ModuleInfo[] function M.find(modname, opts) opts = opts or {} @@ -306,7 +318,7 @@ function M.find(modname, opts) patterns[p] = '/lua/' .. basename .. pattern end - ---@type ModuleInfo[] + ---@type vim.loader.ModuleInfo[] local results = {} -- Only continue if we haven't found anything yet or we want to find all @@ -472,12 +484,12 @@ function Loader.track(stat, f) end end ----@class ProfileOpts +---@class (private) vim.loader._profile.Opts ---@field loaders? boolean Add profiling to the loaders --- Debug function that wraps all loaders and tracks stats ---@private ----@param opts ProfileOpts? +---@param opts vim.loader._profile.Opts? function M._profile(opts) Loader.get_rtp = Loader.track('get_rtp', Loader.get_rtp) Loader.read = Loader.track('read', Loader.read) diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 19497e40dc..8ebf4de3cb 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -108,12 +108,12 @@ function lsp._buf_get_line_ending(bufnr) end -- Tracks all clients created via lsp.start_client -local active_clients = {} --- @type table +local active_clients = {} --- @type table local all_buffer_active_clients = {} --- @type table> -local uninitialized_clients = {} --- @type table +local uninitialized_clients = {} --- @type table ---@param bufnr? integer ----@param fn fun(client: lsp.Client, client_id: integer, bufnr: integer) +---@param fn fun(client: vim.lsp.Client, client_id: integer, bufnr: integer) local function for_each_buffer_client(bufnr, fn, restrict_client_ids) validate({ fn = { fn, 'f' }, @@ -200,105 +200,15 @@ local function once(fn) end end --- FIXME: DOC: Shouldn't need to use a dummy function --- ---- LSP client object. You can get an active client object via ---- |vim.lsp.get_client_by_id()| or |vim.lsp.get_clients()|. +--- @class vim.lsp.start.Opts +--- @inlinedoc --- ---- - Methods: ---- - request(method, params, [handler], bufnr) ---- Sends a request to the server. ---- This is a thin wrapper around {client.rpc.request} with some additional ---- checking. ---- If {handler} is not specified, If one is not found there, 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. +--- Predicate used to decide if a client should be re-used. Used on all +--- running clients. The default implementation re-uses a client if name and +--- root_dir matches. +--- @field reuse_client fun(client: vim.lsp.Client, config: table): boolean --- ---- - request_sync(method, params, timeout_ms, bufnr) ---- 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 dictionary, 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`. ---- ---- - notify(method, params) ---- 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). ---- ---- - cancel_request(id) ---- Cancels a request with a given request id. ---- Returns: same as `notify()`. ---- ---- - stop([force]) ---- 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. ---- ---- - is_stopped() ---- Checks whether a client is stopped. ---- Returns: true if the client is fully stopped. ---- ---- - on_attach(client, bufnr) ---- Runs the on_attach function from the client's config if it was defined. ---- Useful for buffer-local setup. ---- ---- - supports_method(method, [opts]): boolean ---- 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. ---- ---- - Members ---- - {id} (number): The id allocated to the client. ---- ---- - {name} (string): If a name is specified on creation, that will be ---- used. Otherwise it is just the client id. This is used for ---- logs and messages. ---- ---- - {rpc} (table): RPC client object, for low level interaction with the ---- client. See |vim.lsp.rpc.start()|. ---- ---- - {offset_encoding} (string): The encoding used for communicating ---- with the server. You can modify this in the `config`'s `on_init` method ---- before text is sent to the server. ---- ---- - {handlers} (table): The handlers used by the client as described in |lsp-handler|. ---- ---- - {commands} (table): Table of command name to function which is called if ---- any LSP action (code action, code lenses, ...) triggers the command. ---- Client commands take precedence over the global command registry. ---- ---- - {requests} (table): The current pending requests in flight ---- to the server. Entries are key-value pairs with the key ---- being the request ID while the value is a table with `type`, ---- `bufnr`, and `method` key-value pairs. `type` is either "pending" ---- for an active request, or "cancel" for a cancel request. It will ---- be "complete" ephemerally while executing |LspRequest| autocmds ---- when replies are received from the server. ---- ---- - {config} (table): Reference of the table that was passed by the user ---- to |vim.lsp.start_client()|. ---- ---- - {server_capabilities} (table): Response from the server sent on ---- `initialize` describing the server's capabilities. ---- ---- - {progress} A ring buffer (|vim.ringbuf()|) containing progress messages ---- sent by the server. ---- ---- - {settings} Map with language server specific settings. ---- See {config} in |vim.lsp.start_client()| ---- ---- - {flags} A table with flags for the client. See {config} in |vim.lsp.start_client()| -lsp.client = nil - ---- @class lsp.StartOpts ---- @field reuse_client fun(client: lsp.Client, config: table): boolean +--- Buffer handle to attach to if starting or re-using a client (0 for current). --- @field bufnr integer --- Create a new LSP client and start a language server or reuses an already @@ -337,17 +247,9 @@ lsp.client = nil --- Either use |:au|, |nvim_create_autocmd()| or put the call in a --- `ftplugin/.lua` (See |ftplugin-name|) --- ----@param config lsp.ClientConfig Same configuration as documented in |vim.lsp.start_client()| ----@param opts lsp.StartOpts? Optional keyword arguments: ---- - reuse_client (fun(client: client, config: table): boolean) ---- Predicate used to decide if a client should be re-used. ---- Used on all running clients. ---- The default implementation re-uses a client if name ---- and root_dir matches. ---- - bufnr (number) ---- Buffer handle to attach to if starting or re-using a ---- client (0 for current). ----@return integer? client_id +--- @param config vim.lsp.ClientConfig Configuration for the server. +--- @param opts vim.lsp.start.Opts? Optional keyword arguments +--- @return integer? client_id function lsp.start(config, opts) opts = opts or {} local reuse_client = opts.reuse_client @@ -428,7 +330,7 @@ local function is_empty_or_default(bufnr, option) end ---@private ----@param client lsp.Client +---@param client vim.lsp.Client ---@param bufnr integer function lsp._set_defaults(client, bufnr) if @@ -482,7 +384,7 @@ local function reset_defaults(bufnr) end) end ---- @param client lsp.Client +--- @param client vim.lsp.Client local function on_client_init(client) local id = client.id uninitialized_clients[id] = nil @@ -552,121 +454,9 @@ local function on_client_exit(code, signal, client_id) end) end --- FIXME: DOC: Currently all methods on the `vim.lsp.client` object are --- documented twice: Here, and on the methods themselves (e.g. --- `client.request()`). This is a workaround for the vimdoc generator script --- not handling method names correctly. If you change the documentation on --- either, please make sure to update the other as well. --- --- Starts and initializes a client with the given configuration. ---- ---- Field `cmd` in {config} is required. ---- ----@param config (lsp.ClientConfig) Configuration for the server: ---- - cmd: (string[]|fun(dispatchers: table):table) command string[] that launches the language ---- server (treated as in |jobstart()|, must be absolute or on `$PATH`, shell constructs like ---- "~" are not expanded), or function that creates an RPC client. Function receives ---- a `dispatchers` table and returns a table with member functions `request`, `notify`, ---- `is_closing` and `terminate`. ---- See |vim.lsp.rpc.request()|, |vim.lsp.rpc.notify()|. ---- For TCP there is a builtin RPC client factory: |vim.lsp.rpc.connect()| ---- ---- - cmd_cwd: (string, default=|getcwd()|) Directory to launch ---- the `cmd` process. Not related to `root_dir`. ---- ---- - cmd_env: (table) Environment flags to pass to the LSP on ---- spawn. Must be specified using a table. ---- Non-string values are coerced to string. ---- Example: ---- ``` ---- { PORT = 8080; HOST = "0.0.0.0"; } ---- ``` ---- ---- - detached: (boolean, default true) Daemonize the server process so that it runs in a ---- separate process group from Nvim. Nvim will shutdown the process on exit, but if Nvim fails to ---- exit cleanly this could leave behind orphaned server processes. ---- ---- - workspace_folders: (table) List of workspace folders passed to the ---- language server. For backwards compatibility rootUri and rootPath will be ---- derived from the first workspace folder in this list. See `workspaceFolders` in ---- the LSP spec. ---- ---- - capabilities: Map overriding the default capabilities defined by ---- \|vim.lsp.protocol.make_client_capabilities()|, passed to the language ---- server on initialization. Hint: use make_client_capabilities() and modify ---- its result. ---- ---- - Note: To send an empty dictionary use |vim.empty_dict()|, else it will be encoded as an ---- array. ---- ---- - handlers: Map of language server method names to |lsp-handler| ---- ---- - settings: Map with language server specific settings. These are ---- returned to the language server if requested via `workspace/configuration`. ---- Keys are case-sensitive. ---- ---- - commands: table Table that maps string of clientside commands to user-defined functions. ---- Commands passed to start_client take precedence over the global command registry. Each key ---- must be a unique command name, and the value is a function which is called if any LSP action ---- (code action, code lenses, ...) triggers the command. ---- ---- - init_options Values to pass in the initialization request ---- as `initializationOptions`. See `initialize` in the LSP spec. ---- ---- - name: (string, default=client-id) Name in log messages. ---- ---- - get_language_id: function(bufnr, filetype) -> language ID as string. ---- Defaults to the filetype. ---- ---- - offset_encoding: (default="utf-16") One of "utf-8", "utf-16", ---- or "utf-32" which is the encoding that the LSP server expects. Client does ---- not verify this is correct. ---- ---- - on_error: Callback with parameters (code, ...), invoked ---- when the client operation throws an error. `code` is a number describing ---- the error. Other arguments may be passed depending on the error kind. See ---- `vim.lsp.rpc.client_errors` for possible errors. ---- Use `vim.lsp.rpc.client_errors[code]` to get human-friendly name. ---- ---- - before_init: Callback with parameters (initialize_params, config) ---- invoked before the LSP "initialize" phase, where `params` contains the ---- parameters being sent to the server and `config` is the config that was ---- passed to |vim.lsp.start_client()|. You can use this to modify parameters before ---- they are sent. ---- ---- - on_init: Callback (client, initialize_result) invoked after LSP ---- "initialize", where `result` is a table of `capabilities` and anything else ---- the server may send. For example, clangd sends ---- `initialize_result.offsetEncoding` if `capabilities.offsetEncoding` was ---- sent to it. You can only modify the `client.offset_encoding` here before ---- any notifications are sent. ---- ---- - on_exit Callback (code, signal, client_id) invoked on client ---- exit. ---- - code: exit code of the process ---- - signal: number describing the signal used to terminate (if any) ---- - client_id: client handle ---- ---- - on_attach: Callback (client, bufnr) invoked when client ---- attaches to a buffer. ---- ---- - trace: ("off" | "messages" | "verbose" | nil) passed directly to the language ---- server in the initialize request. Invalid/empty values will default to "off" ---- ---- - flags: A table with flags for the client. The current (experimental) flags are: ---- - allow_incremental_sync (bool, default true): Allow using incremental sync for buffer edits ---- - debounce_text_changes (number, default 150): Debounce didChange ---- notifications to the server by the given number in milliseconds. No debounce ---- occurs if nil ---- - exit_timeout (number|boolean, default false): Milliseconds to wait for server to ---- exit cleanly after sending the "shutdown" request before sending kill -15. ---- If set to false, nvim exits immediately after sending the "shutdown" request to the server. ---- ---- - root_dir: (string) Directory where the LSP ---- server will base its workspaceFolders, rootUri, and rootPath ---- on initialization. ---- ----@return integer|nil client_id. |vim.lsp.get_client_by_id()| Note: client may not be +--- @param config vim.lsp.ClientConfig Configuration for the server. +--- @return integer|nil client_id |vim.lsp.get_client_by_id()| Note: client may not be --- fully initialized. Use `on_init` to do any actions once --- the client has been initialized. function lsp.start_client(config) @@ -927,7 +717,7 @@ end --- ---@param client_id integer client id --- ----@return (nil|lsp.Client) client rpc object +---@return (nil|vim.lsp.Client) client rpc object function lsp.get_client_by_id(client_id) return active_clients[client_id] or uninitialized_clients[client_id] end @@ -943,7 +733,7 @@ end --- Stops a client(s). --- ---- You can also use the `stop()` function on a |vim.lsp.client| object. +--- You can also use the `stop()` function on a |vim.lsp.Client| object. --- To stop all clients: --- --- ```lua @@ -953,7 +743,7 @@ end --- By default asks the server to shutdown, unless stop was requested --- already for this client, then force-shutdown is attempted. --- ----@param client_id integer|table id or |vim.lsp.client| object, or list thereof +---@param client_id integer|vim.lsp.Client id or |vim.lsp.Client| object, or list thereof ---@param force boolean|nil shutdown forcefully function lsp.stop_client(client_id, force) local ids = type(client_id) == 'table' and client_id or { client_id } @@ -968,28 +758,32 @@ function lsp.stop_client(client_id, force) end end ----@class vim.lsp.get_clients.filter ----@field id integer|nil Match clients by id ----@field bufnr integer|nil match clients attached to the given buffer ----@field name string|nil match clients by name ----@field method string|nil match client by supported method name +--- Key-value pairs used to filter the returned clients. +--- @class vim.lsp.get_clients.Filter +--- @inlinedoc +--- +--- Only return clients with the given id +--- @field id? integer +--- +--- Only return clients attached to this buffer +--- @field bufnr? integer +--- +--- Only return clients with the given name +--- @field name? string +--- +--- Only return clients supporting the given method +--- @field method? string --- Get active clients. --- ----@param filter vim.lsp.get_clients.filter|nil (table|nil) A table with ---- key-value pairs used to filter the returned clients. ---- The available keys are: ---- - id (number): Only return clients with the given id ---- - bufnr (number): Only return clients attached to this buffer ---- - name (string): Only return clients with the given name ---- - method (string): Only return clients supporting the given method ----@return lsp.Client[]: List of |vim.lsp.client| objects +---@param filter? vim.lsp.get_clients.Filter +---@return vim.lsp.Client[]: List of |vim.lsp.Client| objects function lsp.get_clients(filter) validate({ filter = { filter, 't', true } }) filter = filter or {} - local clients = {} --- @type lsp.Client[] + local clients = {} --- @type vim.lsp.Client[] local t = filter.bufnr and (all_buffer_active_clients[resolve_bufnr(filter.bufnr)] or {}) or active_clients @@ -1233,15 +1027,20 @@ function lsp.omnifunc(findstart, base) return vim.lsp._completion.omnifunc(findstart, base) end +--- @class vim.lsp.formatexpr.Opts +--- @inlinedoc +--- +--- The timeout period for the formatting request. +--- (default: 500ms). +--- @field timeout_ms integer + --- Provides an interface between the built-in client and a `formatexpr` function. --- --- Currently only supports a single client. This can be set via --- `setlocal formatexpr=v:lua.vim.lsp.formatexpr()` but will typically or in `on_attach` --- via `vim.bo[bufnr].formatexpr = 'v:lua.vim.lsp.formatexpr(#{timeout_ms:250})'`. --- ----@param opts table options for customizing the formatting expression which takes the ---- following optional keys: ---- * timeout_ms (default 500ms). The timeout period for the formatting request. +---@param opts? vim.lsp.formatexpr.Opts function lsp.formatexpr(opts) opts = opts or {} local timeout_ms = opts.timeout_ms or 500 @@ -1313,14 +1112,14 @@ function lsp.client_is_stopped(client_id) end --- Gets a map of client_id:client pairs for the given buffer, where each value ---- is a |vim.lsp.client| object. +--- is a |vim.lsp.Client| object. --- ---@param bufnr (integer|nil): Buffer handle, or 0 for current ---@return table result is table of (client_id, client) pairs ---@deprecated Use |vim.lsp.get_clients()| instead. function lsp.buf_get_clients(bufnr) vim.deprecate('vim.lsp.buf_get_clients()', 'vim.lsp.get_clients()', '0.12') - local result = {} --- @type table + local result = {} --- @type table for _, client in ipairs(lsp.get_clients({ bufnr = resolve_bufnr(bufnr) })) do result[client.id] = client end diff --git a/runtime/lua/vim/lsp/_changetracking.lua b/runtime/lua/vim/lsp/_changetracking.lua index 3ecdec1659..b2be53269f 100644 --- a/runtime/lua/vim/lsp/_changetracking.lua +++ b/runtime/lua/vim/lsp/_changetracking.lua @@ -61,7 +61,7 @@ local state_by_group = setmetatable({}, { end, }) ----@param client lsp.Client +---@param client vim.lsp.Client ---@return vim.lsp.CTGroup local function get_group(client) local allow_inc_sync = vim.F.if_nil(client.flags.allow_incremental_sync, true) --- @type boolean @@ -127,7 +127,7 @@ local function incremental_changes(state, encoding, bufnr, firstline, lastline, return incremental_change end ----@param client lsp.Client +---@param client vim.lsp.Client ---@param bufnr integer function M.init(client, bufnr) assert(client.offset_encoding, 'lsp client must have an offset_encoding') @@ -165,7 +165,7 @@ function M.init(client, bufnr) end end ---- @param client lsp.Client +--- @param client vim.lsp.Client --- @param bufnr integer --- @param name string --- @return string @@ -189,7 +189,7 @@ local function reset_timer(buf_state) end end ---- @param client lsp.Client +--- @param client vim.lsp.Client --- @param bufnr integer function M.reset_buf(client, bufnr) M.flush(client, bufnr) @@ -207,7 +207,7 @@ function M.reset_buf(client, bufnr) end end ---- @param client lsp.Client +--- @param client vim.lsp.Client function M.reset(client) local state = state_by_group[get_group(client)] if not state then @@ -350,7 +350,7 @@ function M.send_changes(bufnr, firstline, lastline, new_lastline) end --- Flushes any outstanding change notification. ----@param client lsp.Client +---@param client vim.lsp.Client ---@param bufnr? integer function M.flush(client, bufnr) local group = get_group(client) diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index d2e92de083..377c8680c7 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -11,7 +11,7 @@ local M = {} --- ---@param method (string) LSP method name ---@param params (table|nil) Parameters to send to the server ----@param handler (function|nil) See |lsp-handler|. Follows |lsp-handler-resolution| +---@param handler lsp.Handler? See |lsp-handler|. Follows |lsp-handler-resolution| --- ---@return table client_request_ids Map of client-id:request-id pairs ---for all successful requests. @@ -31,7 +31,7 @@ end --- Checks whether the language servers attached to the current buffer are --- ready. --- ----@return boolean if server responds. +---@return boolean : if server responds. ---@deprecated function M.server_ready() vim.deprecate('vim.lsp.buf.server_ready()', nil, '0.10') @@ -57,35 +57,57 @@ local function request_with_options(name, params, options) request(name, params, req_handler) end ---- Jumps to the declaration of the symbol under the cursor. ----@note Many servers do not implement this method. Generally, see |vim.lsp.buf.definition()| instead. +--- @class vim.lsp.ListOpts +--- +--- list-handler replacing the default handler. +--- Called for any non-empty result. +--- This table can be used with |setqflist()| or |setloclist()|. E.g.: +--- ```lua +--- local function on_list(options) +--- vim.fn.setqflist({}, ' ', options) +--- vim.cmd.cfirst() +--- end --- ----@param options table|nil additional options ---- - reuse_win: (boolean) Jump to existing window if buffer is already open. ---- - on_list: (function) |lsp-on-list-handler| replacing the default handler. ---- Called for any non-empty result. +--- vim.lsp.buf.definition({ on_list = on_list }) +--- vim.lsp.buf.references(nil, { on_list = on_list }) +--- ``` +--- +--- If you prefer loclist do something like this: +--- ```lua +--- local function on_list(options) +--- vim.fn.setloclist(0, {}, ' ', options) +--- vim.cmd.lopen() +--- end +--- ``` +--- @field on_list? fun(t: vim.lsp.LocationOpts.OnList) + +--- @class vim.lsp.LocationOpts.OnList +--- @field items table[] Structured like |setqflist-what| +--- @field title? string Title for the list. +--- @field context? table `ctx` from |lsp-handler| + +--- @class vim.lsp.LocationOpts: vim.lsp.ListOpts +--- +--- Jump to existing window if buffer is already open. +--- @field reuse_win? boolean + +--- Jumps to the declaration of the symbol under the cursor. +--- @note Many servers do not implement this method. Generally, see |vim.lsp.buf.definition()| instead. +--- @param options? vim.lsp.LocationOpts function M.declaration(options) local params = util.make_position_params() request_with_options(ms.textDocument_declaration, params, options) end --- Jumps to the definition of the symbol under the cursor. ---- ----@param options table|nil additional options ---- - reuse_win: (boolean) Jump to existing window if buffer is already open. ---- - on_list: (function) |lsp-on-list-handler| replacing the default handler. ---- Called for any non-empty result. +--- @param options? vim.lsp.LocationOpts function M.definition(options) local params = util.make_position_params() request_with_options(ms.textDocument_definition, params, options) end --- Jumps to the definition of the type of the symbol under the cursor. ---- ----@param options table|nil additional options ---- - reuse_win: (boolean) Jump to existing window if buffer is already open. ---- - on_list: (function) |lsp-on-list-handler| replacing the default handler. ---- Called for any non-empty result. +--- @param options? vim.lsp.LocationOpts function M.type_definition(options) local params = util.make_position_params() request_with_options(ms.textDocument_typeDefinition, params, options) @@ -93,10 +115,7 @@ end --- Lists all the implementations for the symbol under the cursor in the --- quickfix window. ---- ----@param options table|nil additional options ---- - on_list: (function) |lsp-on-list-handler| replacing the default handler. ---- Called for any non-empty result. +--- @param options? vim.lsp.LocationOpts function M.implementation(options) local params = util.make_position_params() request_with_options(ms.textDocument_implementation, params, options) @@ -156,45 +175,55 @@ local function range_from_selection(bufnr, mode) } end +--- @class vim.lsp.buf.format.Opts +--- @inlinedoc +--- +--- Can be used to specify FormattingOptions. Some unspecified options will be +--- automatically derived from the current Nvim options. +--- See https://microsoft.github.io/language-server-protocol/specification/#formattingOptions +--- @field formatting_options? table +--- +--- Time in milliseconds to block for formatting requests. No effect if async=true. +--- (default: `1000`) +--- @field timeout_ms? integer +--- +--- Restrict formatting to the clients attached to the given buffer. +--- (default: current buffer) +--- @field bufnr? integer +--- +--- Predicate used to filter clients. Receives a client as argument and must +--- return a boolean. Clients matching the predicate are included. Example: +--- ```lua +--- -- Never request typescript-language-server for formatting +--- vim.lsp.buf.format { +--- filter = function(client) return client.name ~= "tsserver" end +--- } +--- ``` +--- @field filter? fun(client: vim.lsp.Client): boolean? +--- +--- If true the method won't block. +--- Editing the buffer while formatting asynchronous can lead to unexpected +--- changes. +--- (Default: false) +--- @field async? boolean +--- +--- Restrict formatting to the client with ID (client.id) matching this field. +--- @field id? integer +--- +--- Restrict formatting to the client with name (client.name) matching this field. +--- @field name? string +--- +--- Range to format. +--- Table must contain `start` and `end` keys with {row,col} tuples using +--- (1,0) indexing. +--- (Default: current selection in visual mode, `nil` in other modes, +--- formatting the full buffer) +--- @field range? {start:integer[],end:integer[]} + --- Formats a buffer using the attached (and optionally filtered) language --- server clients. --- ---- @param options table|nil Optional table which holds the following optional fields: ---- - formatting_options (table|nil): ---- Can be used to specify FormattingOptions. Some unspecified options will be ---- automatically derived from the current Nvim options. ---- See https://microsoft.github.io/language-server-protocol/specification/#formattingOptions ---- - timeout_ms (integer|nil, default 1000): ---- Time in milliseconds to block for formatting requests. No effect if async=true ---- - bufnr (number|nil): ---- Restrict formatting to the clients attached to the given buffer, defaults to the current ---- buffer (0). ---- ---- - filter (function|nil): ---- Predicate used to filter clients. Receives a client as argument and must return a ---- boolean. Clients matching the predicate are included. Example: ---- ```lua ---- -- Never request typescript-language-server for formatting ---- vim.lsp.buf.format { ---- filter = function(client) return client.name ~= "tsserver" end ---- } ---- ``` ---- ---- - async boolean|nil ---- If true the method won't block. Defaults to false. ---- Editing the buffer while formatting asynchronous can lead to unexpected ---- changes. ---- ---- - id (number|nil): ---- Restrict formatting to the client with ID (client.id) matching this field. ---- - name (string|nil): ---- Restrict formatting to the client with name (client.name) matching this field. ---- ---- - range (table|nil) Range to format. ---- Table must contain `start` and `end` keys with {row,col} tuples using ---- (1,0) indexing. ---- Defaults to current selection in visual mode ---- Defaults to `nil` in other modes, formatting the full buffer +--- @param options? vim.lsp.buf.format.Opts function M.format(options) options = options or {} local bufnr = options.bufnr or api.nvim_get_current_buf() @@ -229,8 +258,7 @@ function M.format(options) end if options.async then - local do_format - do_format = function(idx, client) + local function do_format(idx, client) if not client then return end @@ -256,17 +284,22 @@ function M.format(options) end end +--- @class vim.lsp.buf.rename.Opts +--- @inlinedoc +--- +--- Predicate used to filter clients. Receives a client as argument and +--- must return a boolean. Clients matching the predicate are included. +--- @field filter? fun(client: vim.lsp.Client): boolean? +--- +--- Restrict clients used for rename to ones where client.name matches +--- this field. +--- @field name? string + --- Renames all references to the symbol under the cursor. --- ---@param new_name string|nil If not provided, the user will be prompted for a new --- name using |vim.ui.input()|. ----@param options table|nil additional options ---- - filter (function|nil): ---- Predicate used to filter clients. Receives a client as argument and ---- must return a boolean. Clients matching the predicate are included. ---- - name (string|nil): ---- Restrict clients used for rename to ones where client.name matches ---- this field. +---@param options? vim.lsp.buf.rename.Opts Additional options: function M.rename(new_name, options) options = options or {} local bufnr = options.bufnr or api.nvim_get_current_buf() @@ -386,8 +419,7 @@ end --- ---@param context (table|nil) Context for the request ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references ----@param options table|nil additional options ---- - on_list: (function) handler for list results. See |lsp-on-list-handler| +---@param options? vim.lsp.ListOpts function M.references(context, options) validate({ context = { context, 't', true } }) local params = util.make_position_params() @@ -398,14 +430,13 @@ function M.references(context, options) end --- Lists all symbols in the current buffer in the quickfix window. ---- ----@param options table|nil additional options ---- - on_list: (function) handler for list results. See |lsp-on-list-handler| +--- @param options? vim.lsp.ListOpts function M.document_symbol(options) local params = { textDocument = util.make_text_document_params() } request_with_options(ms.textDocument_documentSymbol, params, options) end +--- @param call_hierarchy_items lsp.CallHierarchyItem[]? local function pick_call_hierarchy_item(call_hierarchy_items) if not call_hierarchy_items then return @@ -425,8 +456,10 @@ local function pick_call_hierarchy_item(call_hierarchy_items) return choice end +--- @param method string local function call_hierarchy(method) local params = util.make_position_params() + --- @param result lsp.CallHierarchyItem[]? request(ms.textDocument_prepareCallHierarchy, params, function(err, result, ctx) if err then vim.notify(err.message, vim.log.levels.WARN) @@ -545,9 +578,8 @@ end --- call, the user is prompted to enter a string on the command line. An empty --- string means no filtering is done. --- ----@param query string|nil optional ----@param options table|nil additional options ---- - on_list: (function) handler for list results. See |lsp-on-list-handler| +--- @param query string? optional +--- @param options? vim.lsp.ListOpts function M.workspace_symbol(query, options) query = query or npcall(vim.fn.input, 'Query: ') if query == nil then @@ -582,16 +614,36 @@ function M.clear_references() util.buf_clear_references() end +---@nodoc ---@class vim.lsp.CodeActionResultEntry ---@field error? lsp.ResponseError ---@field result? (lsp.Command|lsp.CodeAction)[] ---@field ctx lsp.HandlerContext ----@class vim.lsp.buf.code_action.opts ----@field context? lsp.CodeActionContext ----@field filter? fun(x: lsp.CodeAction|lsp.Command):boolean ----@field apply? boolean ----@field range? {start: integer[], end: integer[]} +--- @class vim.lsp.buf.code_action.Opts +--- @inlinedoc +--- +--- Corresponds to `CodeActionContext` of the LSP specification: +--- - {diagnostics}? (`table`) LSP `Diagnostic[]`. Inferred from the current +--- position if not provided. +--- - {only}? (`table`) List of LSP `CodeActionKind`s used to filter the code actions. +--- Most language servers support values like `refactor` +--- or `quickfix`. +--- - {triggerKind}? (`integer`) The reason why code actions were requested. +--- @field context? lsp.CodeActionContext +--- +--- Predicate taking an `CodeAction` and returning a boolean. +--- @field filter? fun(x: lsp.CodeAction|lsp.Command):boolean +--- +--- When set to `true`, and there is just one remaining action +--- (after filtering), the action is applied without user query. +--- @field apply? boolean +--- +--- 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| +--- @field range? {start: integer[], end: integer[]} --- This is not public because the main extension point is --- vim.ui.select which can be overridden independently. @@ -602,7 +654,7 @@ end --- need to be able to link a `CodeAction|Command` to the right client for --- `codeAction/resolve` ---@param results table