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.
This commit is contained in:
Lewis Russell
2024-02-27 15:20:32 +00:00
committed by Lewis Russell
parent 813dd36b72
commit a5fe8f59d9
47 changed files with 2014 additions and 1450 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -61,6 +61,7 @@ error('Cannot require a meta file')
---
--- </pre>
---@nodoc
---@class vim.NIL
---@type vim.NIL

View File

@@ -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

View File

@@ -12,6 +12,7 @@
--- @return vim.regex
function vim.regex(re) end
--- @nodoc
--- @class vim.regex
local regex = {} -- luacheck: no unused

View File

@@ -797,6 +797,7 @@ end
--- `vim.opt_global`.
--- </pre>
--- @nodoc
--- @class vim.Option
local Option = {} -- luacheck: no unused

View File

@@ -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
--- @field open? boolean
--- @field title? string
--- @field severity? vim.diagnostic.Severity
---
--- 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
--- 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

View File

@@ -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

View File

@@ -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 {}

View File

@@ -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

View File

@@ -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 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 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.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<string, {total:number, time:number, [string]:number?}?>
@@ -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<string, CacheHash>
---@class (private) Loader
---@field private _rtp string[]
---@field private _rtp_pure string[]
---@field private _rtp_key string
---@field private _hashes? table<string, CacheHash>
local Loader = {
VERSION = 4,
---@type table<string, table<string,ModuleInfo>>
---@type table<string, table<string,vim.loader.ModuleInfo>>
_indexed = {},
---@type table<string, string[]>
_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)

View File

@@ -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<integer,lsp.Client>
local active_clients = {} --- @type table<integer,vim.lsp.Client>
local all_buffer_active_clients = {} --- @type table<integer,table<integer,true>>
local uninitialized_clients = {} --- @type table<integer,lsp.Client>
local uninitialized_clients = {} --- @type table<integer,vim.lsp.Client>
---@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/<filetype_name>.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<integer,lsp.Client>
local result = {} --- @type table<integer,vim.lsp.Client>
for _, client in ipairs(lsp.get_clients({ bufnr = resolve_bufnr(bufnr) })) do
result[client.id] = client
end

View File

@@ -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)

View File

@@ -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<integer, integer> 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
---
---@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.
--- 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
---
--- 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<integer, vim.lsp.CodeActionResultEntry>
---@param opts? vim.lsp.buf.code_action.opts
---@param opts? vim.lsp.buf.code_action.Opts
local function on_code_action_results(results, opts)
---@param a lsp.Command|lsp.CodeAction
local function action_filter(a)
@@ -647,14 +699,15 @@ local function on_code_action_results(results, opts)
end
---@param action lsp.Command|lsp.CodeAction
---@param client lsp.Client
---@param client vim.lsp.Client
---@param ctx lsp.HandlerContext
local function apply_action(action, client, ctx)
if action.edit then
util.apply_workspace_edit(action.edit, client.offset_encoding)
end
if action.command then
local command = type(action.command) == 'table' and action.command or action
local a_cmd = action.command
if a_cmd then
local command = type(a_cmd) == 'table' and a_cmd or action
client:_exec_cmd(command, ctx)
end
end
@@ -676,7 +729,6 @@ local function on_code_action_results(results, opts)
-- command: string
-- arguments?: any[]
--
---@type lsp.Client
local client = assert(vim.lsp.get_client_by_id(choice.ctx.client_id))
local action = choice.action
local bufnr = assert(choice.ctx.bufnr, 'Must have buffer number')
@@ -726,29 +778,7 @@ end
--- Selects a code action available at the current
--- cursor position.
---
---@param options table|nil Optional table which holds the following optional fields:
--- - context: (table|nil)
--- Corresponds to `CodeActionContext` of the LSP specification:
--- - diagnostics (table|nil):
--- LSP `Diagnostic[]`. Inferred from the current
--- position if not provided.
--- - only (table|nil):
--- List of LSP `CodeActionKind`s used to filter the code actions.
--- Most language servers support values like `refactor`
--- or `quickfix`.
--- - triggerKind (number|nil): The reason why code actions were requested.
--- - filter: (function|nil)
--- Predicate taking an `CodeAction` and returning a boolean.
--- - apply: (boolean|nil)
--- When set to `true`, and there is just one remaining action
--- (after filtering), the action is applied without user query.
---
--- - range: (table|nil)
--- Range for which code actions should be requested.
--- If in visual mode this defaults to the active selection.
--- Table must contain `start` and `end` keys with {row,col} tuples
--- using mark-like indexing. See |api-indexing|
---
---@param options? vim.lsp.buf.code_action.Opts
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction
---@see vim.lsp.protocol.CodeActionTriggerKind
function M.code_action(options)
@@ -814,9 +844,8 @@ function M.code_action(options)
end
--- Executes an LSP server command.
---
---@param command_params table A valid `ExecuteCommandParams` object
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_executeCommand
--- @param command_params lsp.ExecuteCommandParams
--- @see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_executeCommand
function M.execute_command(command_params)
validate({
command = { command_params.command, 's' },

View File

@@ -6,38 +6,125 @@ local ms = lsp.protocol.Methods
local changetracking = lsp._changetracking
local validate = vim.validate
--- @alias vim.lsp.client.on_init_cb fun(client: lsp.Client, initialize_result: lsp.InitializeResult)
--- @alias vim.lsp.client.on_attach_cb fun(client: lsp.Client, bufnr: integer)
--- @alias vim.lsp.client.on_init_cb fun(client: vim.lsp.Client, initialize_result: lsp.InitializeResult)
--- @alias vim.lsp.client.on_attach_cb fun(client: vim.lsp.Client, bufnr: integer)
--- @alias vim.lsp.client.on_exit_cb fun(code: integer, signal: integer, client_id: integer)
--- @alias vim.lsp.client.before_init_cb fun(params: lsp.InitializeParams, config: lsp.ClientConfig)
--- @alias vim.lsp.client.before_init_cb fun(params: lsp.InitializeParams, config: vim.lsp.ClientConfig)
--- @class lsp.ClientConfig
--- @class vim.lsp.ClientConfig
--- 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()|
--- @field cmd string[]|fun(dispatchers: vim.lsp.rpc.Dispatchers): vim.lsp.rpc.PublicClient?
---
--- Directory to launch the `cmd` process. Not related to `root_dir`.
--- (default: cwd)
--- @field cmd_cwd? string
---
--- Environment flags to pass to the LSP on spawn.
--- Must be specified using a table.
--- Non-string values are coerced to string.
--- Example:
--- ```lua
--- { PORT = 8080; HOST = "0.0.0.0"; }
--- ```
--- @field cmd_env? table
---
--- 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.
--- (default: true)
--- @field detached? boolean
---
--- 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.
--- @field workspace_folders? lsp.WorkspaceFolder[]
---
--- 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.
--- @field capabilities? lsp.ClientCapabilities
---
--- Map of language server method names to |lsp-handler|
--- @field handlers? table<string,function>
---
--- Map with language server specific settings. These are returned to the language server if
--- requested via `workspace/configuration`. Keys are case-sensitive.
--- @field settings? 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.
--- @field commands? table<string,fun(command: lsp.Command, ctx: table)>
---
--- Values to pass in the initialization request as `initializationOptions`. See `initialize` in
--- the LSP spec.
--- @field init_options? table
---
--- Name in log messages.
--- (default: client-id)
--- @field name? string
---
--- Language ID as string. Defaults to the filetype.
--- @field get_language_id? fun(bufnr: integer, filetype: string): string
--- @field offset_encoding? string
---
--- The encoding that the LSP server expects. Client does not verify this is correct.
--- @field offset_encoding? 'utf-8'|'utf-16'|'utf-32'
---
--- Callback 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.
--- @field on_error? fun(code: integer, err: string)
---
--- Callback 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.
--- @field before_init? vim.lsp.client.before_init_cb
---
--- Callback 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.
--- @field on_init? elem_or_list<vim.lsp.client.on_init_cb>
---
--- Callback invoked on client exit.
--- - code: exit code of the process
--- - signal: number describing the signal used to terminate (if any)
--- - client_id: client handle
--- @field on_exit? elem_or_list<vim.lsp.client.on_exit_cb>
---
--- Callback invoked when client attaches to a buffer.
--- @field on_attach? elem_or_list<vim.lsp.client.on_attach_cb>
---
--- Passed directly to the language server in the initialize request. Invalid/empty values will
--- (default: "off")
--- @field trace? 'off'|'messages'|'verbose'
---
--- 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.
--- @field flags? table
---
--- Directory where the LSP server will base its workspaceFolders, rootUri, and rootPath on initialization.
--- @field root_dir? string
--- @class lsp.Client.Progress: vim.Ringbuf<{token: integer|string, value: any}>
--- @class vim.lsp.Client.Progress: vim.Ringbuf<{token: integer|string, value: any}>
--- @field pending table<lsp.ProgressToken,lsp.LSPAny>
--- @class lsp.Client
--- @class vim.lsp.Client
---
--- The id allocated to the client.
--- @field id integer
@@ -67,7 +154,7 @@ local validate = vim.validate
---
--- copy of the table that was passed by the user
--- to |vim.lsp.start_client()|.
--- @field config lsp.ClientConfig
--- @field config vim.lsp.ClientConfig
---
--- Response from the server sent on
--- initialize` describing the server's capabilities.
@@ -75,7 +162,7 @@ local validate = vim.validate
---
--- A ring buffer (|vim.ringbuf()|) containing progress messages
--- sent by the server.
--- @field progress lsp.Client.Progress
--- @field progress vim.lsp.Client.Progress
---
--- @field initialized true?
---
@@ -239,7 +326,7 @@ local function default_get_language_id(_bufnr, filetype)
end
--- Validates a client configuration as given to |vim.lsp.start_client()|.
--- @param config lsp.ClientConfig
--- @param config vim.lsp.ClientConfig
local function validate_config(config)
validate({
config = { config, 't' },
@@ -285,7 +372,7 @@ local function get_trace(trace)
end
--- @param id integer
--- @param config lsp.ClientConfig
--- @param config vim.lsp.ClientConfig
--- @return string
local function get_name(id, config)
local name = config.name
@@ -328,8 +415,8 @@ local function ensure_list(x)
end
--- @package
--- @param config lsp.ClientConfig
--- @return lsp.Client?
--- @param config vim.lsp.ClientConfig
--- @return vim.lsp.Client?
function Client.create(config)
validate_config(config)
@@ -337,7 +424,7 @@ function Client.create(config)
local id = client_index
local name = get_name(id, config)
--- @class lsp.Client
--- @class vim.lsp.Client
local self = {
id = id,
config = config,
@@ -370,7 +457,7 @@ function Client.create(config)
--- - lsp.WorkDoneProgressBegin,
--- - lsp.WorkDoneProgressReport (extended with title from Begin)
--- - lsp.WorkDoneProgressEnd (extended with title from Begin)
progress = vim.ringbuf(50) --[[@as lsp.Client.Progress]],
progress = vim.ringbuf(50) --[[@as vim.lsp.Client.Progress]],
--- @deprecated use client.progress instead
messages = { name = name, messages = {}, progress = {}, status = {} },
@@ -421,6 +508,7 @@ function Client.create(config)
return self
end
--- @private
--- @param cbs function[]
--- @param error_id integer
--- @param ... any
@@ -698,7 +786,7 @@ function Client:_cancel_request(id)
return self.rpc.notify(ms.dollar_cancelRequest, { id = id })
end
--- @nodoc
--- @private
--- Stops a client, optionally with force.
---
--- By default, it will just ask the - server to shutdown without force. If
@@ -853,6 +941,7 @@ function Client:write_error(code, err)
err_message(self._log_prefix, ': Error ', client_error, ': ', vim.inspect(err))
end
--- @private
--- @param method string
--- @param opts? {bufnr: integer?}
function Client:_supports_method(method, opts)

View File

@@ -279,7 +279,8 @@ function M.on_codelens(err, result, ctx, _)
end)
end
--- @class vim.lsp.codelens.RefreshOptions
--- @class vim.lsp.codelens.refresh.Opts
--- @inlinedoc
--- @field bufnr integer? filter by buffer. All buffers if nil, 0 for current buffer
--- Refresh the lenses.
@@ -292,8 +293,7 @@ end
--- autocmd BufEnter,CursorHold,InsertLeave <buffer> lua vim.lsp.codelens.refresh({ bufnr = 0 })
--- ```
---
--- @param opts? vim.lsp.codelens.RefreshOptions Table with the following fields:
--- - `bufnr` (integer|nil): filter by buffer. All buffers if nil, 0 for current buffer
--- @param opts? vim.lsp.codelens.refresh.Opts Optional fields
function M.refresh(opts)
opts = opts or {}
local bufnr = opts.bufnr and resolve_bufnr(opts.bufnr)

View File

@@ -390,7 +390,7 @@ local function clear(bufnr)
end
end
---@class lsp.diagnostic.bufstate
---@class (private) lsp.diagnostic.bufstate
---@field enabled boolean Whether inlay hints are enabled for this buffer
---@type table<integer, lsp.diagnostic.bufstate>
local bufstates = {}

View File

@@ -412,6 +412,7 @@ M[ms.textDocument_hover] = M.hover
---@param _ nil not used
---@param result (table) result of LSP method; a location or a list of locations.
---@param ctx (lsp.HandlerContext) table containing the context of the request, including the method
---@param config? vim.lsp.buf.LocationOpts
---(`textDocument/definition` can return `Location` or `Location[]`
local function location_handler(_, result, ctx, config)
if result == nil or vim.tbl_isempty(result) then

View File

@@ -4,12 +4,12 @@ local ms = require('vim.lsp.protocol').Methods
local api = vim.api
local M = {}
---@class lsp.inlay_hint.bufstate
---@class (private) vim.lsp.inlay_hint.bufstate
---@field version? integer
---@field client_hints? table<integer, table<integer, lsp.InlayHint[]>> client_id -> (lnum -> hints)
---@field applied table<integer, integer> Last version of hints applied to this line
---@field enabled boolean Whether inlay hints are enabled for this buffer
---@type table<integer, lsp.inlay_hint.bufstate>
---@type table<integer, vim.lsp.inlay_hint.bufstate>
local bufstates = {}
local namespace = api.nvim_create_namespace('vim_lsp_inlayhint')
@@ -103,11 +103,14 @@ function M.on_refresh(err, _, ctx, _)
return vim.NIL
end
--- @class vim.lsp.inlay_hint.get.filter
--- Optional filters |kwargs|:
--- @class vim.lsp.inlay_hint.get.Filter
--- @inlinedoc
--- @field bufnr integer?
--- @field range lsp.Range?
---
--- @class vim.lsp.inlay_hint.get.ret
--- @inlinedoc
--- @field bufnr integer
--- @field client_id integer
--- @field inlay_hint lsp.InlayHint
@@ -130,17 +133,8 @@ end
--- })
--- ```
---
--- @param filter vim.lsp.inlay_hint.get.filter?
--- Optional filters |kwargs|:
--- - bufnr (integer?): 0 for current buffer
--- - range (lsp.Range?)
---
--- @param filter vim.lsp.inlay_hint.get.Filter?
--- @return vim.lsp.inlay_hint.get.ret[]
--- Each list item is a table with the following fields:
--- - bufnr (integer)
--- - client_id (integer)
--- - inlay_hint (lsp.InlayHint)
---
--- @since 12
function M.get(filter)
vim.validate({ filter = { filter, 'table', true } })
@@ -241,7 +235,7 @@ end
--- Refresh inlay hints, only if we have attached clients that support it
---@param bufnr (integer) Buffer handle, or 0 for current
---@param opts? lsp.util.RefreshOptions Additional options to pass to util._refresh
---@param opts? vim.lsp.util._refresh.Opts Additional options to pass to util._refresh
---@private
local function _refresh(bufnr, opts)
opts = opts or {}

View File

@@ -26,7 +26,7 @@ local function format_message_with_content_length(message)
})
end
---@class vim.lsp.rpc.Headers: {string: any}
---@class (private) vim.lsp.rpc.Headers: {string: any}
---@field content_length integer
--- Parses an LSP Message's header
@@ -193,7 +193,9 @@ function M.rpc_response_error(code, message, data)
})
end
--- Dispatchers for LSP message types.
--- @class vim.lsp.rpc.Dispatchers
--- @inlinedoc
--- @field notification fun(method: string, params: table)
--- @field server_request fun(method: string, params: table): any?, lsp.ResponseError?
--- @field on_exit fun(code: integer, signal: integer)
@@ -266,8 +268,7 @@ function M.create_read_loop(handle_body, on_no_chunk, on_error)
end
end
---@private
---@class vim.lsp.rpc.Client
---@class (private) vim.lsp.rpc.Client
---@field message_index integer
---@field message_callbacks table<integer, function> dict of message_id to callback
---@field notify_reply_callbacks table<integer, function> dict of message_id to callback
@@ -522,7 +523,7 @@ function Client:handle_body(body)
end
end
---@class vim.lsp.rpc.Transport
---@class (private) vim.lsp.rpc.Transport
---@field write fun(msg: string)
---@field is_closing fun(): boolean
---@field terminate fun()
@@ -721,32 +722,21 @@ function M.domain_socket_connect(pipe_path)
end
end
---@class vim.lsp.rpc.ExtraSpawnParams
---@field cwd? string Working directory for the LSP server process
---@field detached? boolean Detach the LSP server process from the current process
---@field env? table<string,string> Additional environment variables for LSP server process. See |vim.system|
--- Additional context for the LSP server process.
--- @class vim.lsp.rpc.ExtraSpawnParams
--- @inlinedoc
--- @field cwd? string Working directory for the LSP server process
--- @field detached? boolean Detach the LSP server process from the current process
--- @field env? table<string,string> Additional environment variables for LSP server process. See |vim.system()|
--- Starts an LSP server process and create an LSP RPC client object to
--- interact with it. Communication with the spawned process happens via stdio. For
--- communication via TCP, spawn a process manually and use |vim.lsp.rpc.connect()|
---
---@param cmd string[] Command to start the LSP server.
---
---@param dispatchers? vim.lsp.rpc.Dispatchers Dispatchers for LSP message types.
--- Valid dispatcher names are:
--- - `"notification"`
--- - `"server_request"`
--- - `"on_error"`
--- - `"on_exit"`
---
---@param extra_spawn_params? vim.lsp.rpc.ExtraSpawnParams Additional context for the LSP
--- server process. May contain:
--- - {cwd} (string) Working directory for the LSP server process
--- - {detached?} (boolean) Detach the LSP server process from the current process.
--- Defaults to false on Windows and true otherwise.
--- - {env?} (table) Additional environment variables for LSP server process
---
---@return vim.lsp.rpc.PublicClient? Client RPC object, with these methods:
--- @param cmd string[] Command to start the LSP server.
--- @param dispatchers? vim.lsp.rpc.Dispatchers
--- @param extra_spawn_params? vim.lsp.rpc.ExtraSpawnParams
--- @return vim.lsp.rpc.PublicClient? : Client RPC object, with these methods:
--- - `notify()` |vim.lsp.rpc.notify()|
--- - `request()` |vim.lsp.rpc.request()|
--- - `is_closing()` returns a boolean indicating if the RPC is closing.

View File

@@ -4,7 +4,7 @@ local ms = require('vim.lsp.protocol').Methods
local util = require('vim.lsp.util')
local uv = vim.uv
--- @class STTokenRange
--- @class (private) STTokenRange
--- @field line integer line number 0-based
--- @field start_col integer start column 0-based
--- @field end_col integer end column 0-based
@@ -12,23 +12,23 @@ local uv = vim.uv
--- @field modifiers table<string,boolean> token modifiers as a set. E.g., { static = true, readonly = true }
--- @field marked boolean whether this token has had extmarks applied
---
--- @class STCurrentResult
--- @class (private) STCurrentResult
--- @field version? integer document version associated with this result
--- @field result_id? string resultId from the server; used with delta requests
--- @field highlights? STTokenRange[] cache of highlight ranges for this document version
--- @field tokens? integer[] raw token array as received by the server. used for calculating delta responses
--- @field namespace_cleared? boolean whether the namespace was cleared for this result yet
---
--- @class STActiveRequest
--- @class (private) STActiveRequest
--- @field request_id? integer the LSP request ID of the most recent request sent to the server
--- @field version? integer the document version associated with the most recent request
---
--- @class STClientState
--- @class (private) STClientState
--- @field namespace integer
--- @field active_request STActiveRequest
--- @field current_result STCurrentResult
---@class STHighlighter
---@class (private) STHighlighter
---@field active table<integer, STHighlighter>
---@field bufnr integer
---@field augroup integer augroup for buffer events
@@ -92,7 +92,7 @@ end
---
---@param data integer[]
---@param bufnr integer
---@param client lsp.Client
---@param client vim.lsp.Client
---@param request STActiveRequest
---@return STTokenRange[]
local function tokens_to_ranges(data, bufnr, client, request)
@@ -646,6 +646,7 @@ function M.stop(bufnr, client_id)
end
end
--- @nodoc
--- @class STTokenRangeInspect : STTokenRange
--- @field client_id integer
@@ -727,6 +728,13 @@ function M.force_refresh(bufnr)
end
end
--- @class vim.lsp.semantic_tokens.highlight_token.Opts
--- @inlinedoc
---
--- Priority for the applied extmark.
--- (Default: `vim.highlight.priorities.semantic_tokens + 3`)
--- @field priority? integer
--- Highlight a semantic token.
---
--- Apply an extmark with a given highlight group for a semantic token. The
@@ -735,11 +743,9 @@ end
--- use inside |LspTokenUpdate| callbacks.
---@param token (table) a semantic token, found as `args.data.token` in |LspTokenUpdate|.
---@param bufnr (integer) the buffer to highlight
---@param client_id (integer) The ID of the |vim.lsp.client|
---@param client_id (integer) The ID of the |vim.lsp.Client|
---@param hl_group (string) Highlight group name
---@param opts (table|nil) Optional parameters.
--- - priority: (integer|nil) Priority for the applied extmark. Defaults
--- to `vim.highlight.priorities.semantic_tokens + 3`
---@param opts? vim.lsp.semantic_tokens.highlight_token.Opts Optional parameters:
function M.highlight_token(token, bufnr, client_id, hl_group, opts)
local highlighter = STHighlighter.active[bufnr]
if not highlighter then

View File

@@ -675,13 +675,15 @@ local function get_bufs_with_prefix(prefix)
return buffers
end
--- @class vim.lsp.util.rename.Opts
--- @inlinedoc
--- @field overwrite? boolean
--- @field ignoreIfExists? boolean
--- Rename old_fname to new_fname
---
---@param old_fname string
---@param new_fname string
---@param opts? table options
--- - overwrite? boolean
--- - ignoreIfExists? boolean
--- @param old_fname string
--- @param new_fname string
--- @param opts? vim.lsp.util.rename.Opts Options:
function M.rename(old_fname, new_fname, opts)
opts = opts or {}
local skip = not opts.overwrite or opts.ignoreIfExists
@@ -1450,7 +1452,7 @@ function M.stylize_markdown(bufnr, contents, opts)
return stripped
end
--- @class lsp.util.NormalizeMarkdownOptions
--- @class (private) vim.lsp.util._normalize_markdown.Opts
--- @field width integer Thematic breaks are expanded to this size. Defaults to 80.
--- Normalizes Markdown input to a canonical form.
@@ -1466,7 +1468,7 @@ end
---
---@private
---@param contents string[]
---@param opts? lsp.util.NormalizeMarkdownOptions
---@param opts? vim.lsp.util._normalize_markdown.Opts
---@return string[] table of lines containing normalized Markdown
---@see https://github.github.com/gfm
function M._normalize_markdown(contents, opts)
@@ -1537,7 +1539,7 @@ local function close_preview_autocmd(events, winnr, bufnrs)
end
end
---@internal
---@private
--- Computes size of float needed to show contents (with optional wrapping)
---
---@param contents table of lines to show in window
@@ -1613,24 +1615,50 @@ function M._make_floating_popup_size(contents, opts)
return width, height
end
--- @class vim.lsp.util.open_floating_preview.Opts
--- @inlinedoc
---
--- Height of floating window
--- @field height? integer
---
--- Width of floating window
--- @field width? integer
---
--- Wrap long lines
--- (default: `true`)
--- @field wrap? boolean
---
--- Character to wrap at for computing height when wrap is enabled
--- @field wrap_at? integer
---
--- Maximal width of floating window
--- @field max_width? integer
---
--- Maximal height of floating window
--- @field max_height? integer
---
--- If a popup with this id is opened, then focus it
--- @field focus_id? string
---
--- List of events that closes the floating window
--- @field close_events? table
---
--- Make float focusable.
--- (default: `true`)
--- @field focusable? boolean
---
--- If `true`, and if {focusable} is also `true`, focus an existing floating
--- window with the same {focus_id}
--- (default: `true`)
--- @field focus? boolean
--- Shows contents in a floating window.
---
---@param contents table of lines to show in window
---@param syntax string of syntax to set for opened buffer
---@param opts table with optional fields (additional keys are filtered with |vim.lsp.util.make_floating_popup_options()|
--- before they are passed on to |nvim_open_win()|)
--- - height: (integer) height of floating window
--- - width: (integer) width of floating window
--- - wrap: (boolean, default true) wrap long lines
--- - wrap_at: (integer) character to wrap at for computing height when wrap is enabled
--- - max_width: (integer) maximal width of floating window
--- - max_height: (integer) maximal height of floating window
--- - focus_id: (string) if a popup with this id is opened, then focus it
--- - close_events: (table) list of events that closes the floating window
--- - focusable: (boolean, default true) Make float focusable
--- - focus: (boolean, default true) If `true`, and if {focusable}
--- is also `true`, focus an existing floating window with the same
--- {focus_id}
---@param opts? vim.lsp.util.open_floating_preview.Opts with optional fields
--- (additional keys are filtered with |vim.lsp.util.make_floating_popup_options()|
--- before they are passed on to |nvim_open_win()|)
---@return integer bufnr of newly created float window
---@return integer winid of newly created float window preview window
function M.open_floating_preview(contents, syntax, opts)
@@ -1794,7 +1822,8 @@ local position_sort = sort_by_key(function(v)
return { v.start.line, v.start.character }
end)
---@class vim.lsp.util.LocationItem
---@class vim.lsp.util.locations_to_items.ret
---@inlinedoc
---@field filename string
---@field lnum integer 1-indexed line number
---@field col integer 1-indexed column
@@ -1813,7 +1842,7 @@ end)
---@param locations lsp.Location[]|lsp.LocationLink[]
---@param offset_encoding string offset_encoding for locations utf-8|utf-16|utf-32
--- default to first client of buffer
---@return vim.lsp.util.LocationItem[] list of items
---@return vim.lsp.util.locations_to_items.ret[]
function M.locations_to_items(locations, offset_encoding)
if offset_encoding == nil then
vim.notify_once(
@@ -2221,16 +2250,16 @@ local function make_line_range_params(bufnr, start_line, end_line, offset_encodi
}
end
---@private
--- Request updated LSP information for a buffer.
---
---@class lsp.util.RefreshOptions
---@class (private) vim.lsp.util._refresh.Opts
---@field bufnr integer? Buffer to refresh (default: 0)
---@field only_visible? boolean Whether to only refresh for the visible regions of the buffer (default: false)
---@field client_id? integer Client ID to refresh (default: all clients)
--
---@private
--- Request updated LSP information for a buffer.
---
---@param method string LSP method to call
---@param opts? lsp.util.RefreshOptions Options table
---@param opts? vim.lsp.util._refresh.Opts Options table
function M._refresh(method, opts)
opts = opts or {}
local bufnr = opts.bufnr

View File

@@ -108,22 +108,25 @@ function M.read(path)
return contents
end
---@class vim.trust.opts
---@field action string
---@field path? string
---@field bufnr? integer
--- @class vim.trust.opts
--- @inlinedoc
---
--- - `'allow'` to add a file to the trust database and trust it,
--- - `'deny'` to add a file to the trust database and deny it,
--- - `'remove'` to remove file from the trust database
--- @field action 'allow'|'deny'|'remove'
---
--- Path to a file to update. Mutually exclusive with {bufnr}.
--- Cannot be used when {action} is "allow".
--- @field path? string
--- Buffer number to update. Mutually exclusive with {path}.
--- @field bufnr? integer
--- Manage the trust database.
---
--- The trust database is located at |$XDG_STATE_HOME|/nvim/trust.
---
---@param opts (table):
--- - action (string): "allow" to add a file to the trust database and trust it,
--- "deny" to add a file to the trust database and deny it,
--- "remove" to remove file from the trust database
--- - path (string|nil): Path to a file to update. Mutually exclusive with {bufnr}.
--- Cannot be used when {action} is "allow".
--- - bufnr (number|nil): Buffer number to update. Mutually exclusive with {path}.
---@param opts? vim.trust.opts
---@return boolean success true if operation was successful
---@return string msg full path if operation was successful, else error message
function M.trust(opts)

View File

@@ -65,8 +65,13 @@ function vim.deepcopy(orig, noref)
end
--- @class vim.gsplit.Opts
--- @field plain? boolean Use `sep` literally (as in string.find).
--- @field trimempty? boolean Discard empty segments at start and end of the sequence.
--- @inlinedoc
---
--- Use `sep` literally (as in string.find).
--- @field plain? boolean
---
--- Discard empty segments at start and end of the sequence.
--- @field trimempty? boolean
--- Gets an |iterator| that splits a string at each instance of a separator, in "lazy" fashion
--- (as opposed to |vim.split()| which is "eager").
@@ -96,10 +101,8 @@ end
---
--- @param s string String to split
--- @param sep string Separator or pattern
--- @param opts? vim.gsplit.Opts (table) Keyword arguments |kwargs|:
--- - plain: (boolean) Use `sep` literally (as in string.find).
--- - trimempty: (boolean) Discard empty segments at start and end of the sequence.
---@return fun():string|nil (function) Iterator over the split components
--- @param opts? vim.gsplit.Opts Keyword arguments |kwargs|:
--- @return fun():string|nil (function) Iterator over the split components
function vim.gsplit(s, sep, opts)
local plain --- @type boolean?
local trimempty = false
@@ -192,7 +195,7 @@ end
---
---@param s string String to split
---@param sep string Separator or pattern
---@param opts? table Keyword arguments |kwargs| accepted by |vim.gsplit()|
---@param opts? vim.gsplit.Opts Keyword arguments |kwargs|:
---@return string[] : List of split components
function vim.split(s, sep, opts)
local t = {}
@@ -276,6 +279,9 @@ function vim.tbl_filter(func, t)
end
--- @class vim.tbl_contains.Opts
--- @inlinedoc
---
--- `value` is a function reference to be checked (default false)
--- @field predicate? boolean
--- Checks if a table contains a given value, specified either directly or via
@@ -294,8 +300,7 @@ end
---
---@param t table Table to check
---@param value any Value to compare or predicate function reference
---@param opts? vim.tbl_contains.Opts (table) Keyword arguments |kwargs|:
--- - predicate: (boolean) `value` is a function reference to be checked (default false)
---@param opts? vim.tbl_contains.Opts Keyword arguments |kwargs|:
---@return boolean `true` if `t` contains `value`
function vim.tbl_contains(t, value, opts)
vim.validate({ t = { t, 't' }, opts = { opts, 't', true } })
@@ -764,6 +769,7 @@ do
['userdata'] = 'userdata',
}
--- @nodoc
--- @class vim.validate.Spec {[1]: any, [2]: string|string[], [3]: boolean }
--- @field [1] any Argument value
--- @field [2] string|string[]|fun(v:any):boolean, string? Type name, or callable

View File

@@ -101,7 +101,7 @@ local function get_extmark_range(bufnr, extmark_id)
return { mark[1], mark[2], mark[3].end_row, mark[3].end_col }
end
--- @class vim.snippet.Tabstop
--- @class (private) vim.snippet.Tabstop
--- @field extmark_id integer
--- @field bufnr integer
--- @field index integer
@@ -177,7 +177,7 @@ function Tabstop:set_right_gravity(right_gravity)
})
end
--- @class vim.snippet.Session
--- @class (private) vim.snippet.Session
--- @field bufnr integer
--- @field extmark_id integer
--- @field tabstops table<integer, vim.snippet.Tabstop[]>

View File

@@ -1,6 +1,6 @@
local api = vim.api
---@type table<integer,LanguageTree>
---@type table<integer,vim.treesitter.LanguageTree>
local parsers = setmetatable({}, { __mode = 'v' })
local M = vim._defer_require('vim.treesitter', {
@@ -30,7 +30,7 @@ M.minimum_language_version = vim._ts_get_minimum_language_version()
---@param lang string Language of the parser
---@param opts (table|nil) Options to pass to the created language tree
---
---@return LanguageTree object to use for parsing
---@return vim.treesitter.LanguageTree object to use for parsing
function M._create_parser(bufnr, lang, opts)
if bufnr == 0 then
bufnr = vim.api.nvim_get_current_buf()
@@ -80,7 +80,7 @@ end
---@param lang (string|nil) Filetype of this parser (default: buffer filetype)
---@param opts (table|nil) Options to pass to the created language tree
---
---@return LanguageTree object to use for parsing
---@return vim.treesitter.LanguageTree object to use for parsing
function M.get_parser(bufnr, lang, opts)
opts = opts or {}
@@ -119,7 +119,7 @@ end
---@param lang string Language of this string
---@param opts (table|nil) Options to pass to the created language tree
---
---@return LanguageTree object to use for parsing
---@return vim.treesitter.LanguageTree object to use for parsing
function M.get_string_parser(str, lang, opts)
vim.validate({
str = { str, 'string' },
@@ -172,7 +172,7 @@ end
---to get the range with directives applied.
---@param node TSNode
---@param source integer|string|nil Buffer or string from which the {node} is extracted
---@param metadata TSMetadata|nil
---@param metadata vim.treesitter.query.TSMetadata|nil
---@return Range6
function M.get_range(node, source, metadata)
if metadata and metadata.range then
@@ -326,10 +326,21 @@ function M.get_captures_at_cursor(winnr)
return captures
end
--- @class vim.treesitter.GetNodeOpts
--- Optional keyword arguments:
--- @class vim.treesitter.get_node.Opts
--- @inlinedoc
---
--- Buffer number (nil or 0 for current buffer)
--- @field bufnr integer?
---
--- 0-indexed (row, col) tuple. Defaults to cursor position in the
--- current window. Required if {bufnr} is not the current buffer
--- @field pos { [1]: integer, [2]: integer }?
---
--- Parser language. (default: from buffer filetype)
--- @field lang string?
---
--- Ignore injected languages (default true)
--- @field ignore_injections boolean?
--- Returns the smallest named node at the given position
@@ -342,12 +353,7 @@ end
--- vim.treesitter.get_parser(bufnr):parse(range)
--- ```
---
---@param opts vim.treesitter.GetNodeOpts? Optional keyword arguments:
--- - bufnr integer|nil Buffer number (nil or 0 for current buffer)
--- - pos table|nil 0-indexed (row, col) tuple. Defaults to cursor position in the
--- current window. Required if {bufnr} is not the current buffer
--- - lang string|nil Parser language. (default: from buffer filetype)
--- - ignore_injections boolean Ignore injected languages (default true)
---@param opts vim.treesitter.get_node.Opts?
---
---@return TSNode | nil Node at the given position
function M.get_node(opts)

View File

@@ -45,7 +45,7 @@ local function guess_query_lang(buf)
end
--- @param buf integer
--- @param opts QueryLinterOpts|QueryLinterNormalizedOpts|nil
--- @param opts vim.treesitter.query.lint.Opts|QueryLinterNormalizedOpts|nil
--- @return QueryLinterNormalizedOpts
local function normalize_opts(buf, opts)
opts = opts or {}
@@ -122,7 +122,7 @@ local parse = vim.func._memoize(hash_parse, function(node, buf, lang)
end)
--- @param buf integer
--- @param match TSMatch
--- @param match vim.treesitter.query.TSMatch
--- @param query Query
--- @param lang_context QueryLinterLanguageContext
--- @param diagnostics Diagnostic[]
@@ -153,7 +153,7 @@ end
--- @private
--- @param buf integer Buffer to lint
--- @param opts QueryLinterOpts|QueryLinterNormalizedOpts|nil Options for linting
--- @param opts vim.treesitter.query.lint.Opts|QueryLinterNormalizedOpts|nil Options for linting
function M.lint(buf, opts)
if buf == 0 then
buf = api.nvim_get_current_buf()

View File

@@ -1,23 +1,21 @@
local api = vim.api
---@class TSDevModule
local M = {}
---@private
---@class TSTreeView
---@class (private) vim.treesitter.dev.TSTreeView
---@field ns integer API namespace
---@field opts TSTreeViewOpts
---@field nodes TSP.Node[]
---@field named TSP.Node[]
---@field opts vim.treesitter.dev.TSTreeViewOpts
---@field nodes vim.treesitter.dev.Node[]
---@field named vim.treesitter.dev.Node[]
local TSTreeView = {}
---@private
---@class TSTreeViewOpts
---@class (private) vim.treesitter.dev.TSTreeViewOpts
---@field anon boolean If true, display anonymous nodes.
---@field lang boolean If true, display the language alongside each node.
---@field indent number Number of spaces to indent nested lines.
---@class TSP.Node
---@class (private) vim.treesitter.dev.Node
---@field node TSNode Treesitter node
---@field field string? Node field
---@field depth integer Depth of this node in the tree
@@ -25,7 +23,7 @@ local TSTreeView = {}
--- inspector is drawn.
---@field lang string Source language of this node
---@class TSP.Injection
---@class (private) vim.treesitter.dev.Injection
---@field lang string Source language of this injection
---@field root TSNode Root node of the injection
@@ -45,9 +43,9 @@ local TSTreeView = {}
---@param depth integer Current recursion depth
---@param field string|nil The field of the current node
---@param lang string Language of the tree currently being traversed
---@param injections table<string, TSP.Injection> Mapping of node ids to root nodes
---@param injections table<string, vim.treesitter.dev.Injection> Mapping of node ids to root nodes
--- of injected language trees (see explanation above)
---@param tree TSP.Node[] Output table containing a list of tables each representing a node in the tree
---@param tree vim.treesitter.dev.Node[] Output table containing a list of tables each representing a node in the tree
local function traverse(node, depth, field, lang, injections, tree)
table.insert(tree, {
node = node,
@@ -73,7 +71,7 @@ end
---@param bufnr integer Source buffer number
---@param lang string|nil Language of source buffer
---
---@return TSTreeView|nil
---@return vim.treesitter.dev.TSTreeView|nil
---@return string|nil Error message, if any
---
---@package
@@ -88,7 +86,7 @@ function TSTreeView:new(bufnr, lang)
-- the primary tree that contains that root. Add a mapping from the node in the primary tree to
-- the root in the child tree to the {injections} table.
local root = parser:parse(true)[1]:root()
local injections = {} ---@type table<string, TSP.Injection>
local injections = {} ---@type table<string, vim.treesitter.dev.Injection>
parser:for_each_tree(function(parent_tree, parent_ltree)
local parent = parent_tree:root()
@@ -109,7 +107,7 @@ function TSTreeView:new(bufnr, lang)
local nodes = traverse(root, 0, nil, parser:lang(), injections, {})
local named = {} ---@type TSP.Node[]
local named = {} ---@type vim.treesitter.dev.Node[]
for _, v in ipairs(nodes) do
if v.node:named() then
named[#named + 1] = v
@@ -120,7 +118,7 @@ function TSTreeView:new(bufnr, lang)
ns = api.nvim_create_namespace('treesitter/dev-inspect'),
nodes = nodes,
named = named,
---@type TSTreeViewOpts
---@type vim.treesitter.dev.TSTreeViewOpts
opts = {
anon = false,
lang = false,
@@ -171,7 +169,7 @@ end
--- Updates the cursor position in the inspector to match the node under the cursor.
---
--- @param treeview TSTreeView
--- @param treeview vim.treesitter.dev.TSTreeView
--- @param lang string
--- @param source_buf integer
--- @param inspect_buf integer
@@ -278,7 +276,7 @@ end
--- The node number is dependent on whether or not anonymous nodes are displayed.
---
---@param i integer Node number to get
---@return TSP.Node
---@return vim.treesitter.dev.Node
---@package
function TSTreeView:get(i)
local t = self.opts.anon and self.nodes or self.named
@@ -287,7 +285,7 @@ end
--- Iterate over all of the nodes in this View.
---
---@return (fun(): integer, TSP.Node) Iterator over all nodes in this View
---@return (fun(): integer, vim.treesitter.dev.Node) Iterator over all nodes in this View
---@return table
---@return integer
---@package
@@ -295,22 +293,31 @@ function TSTreeView:iter()
return ipairs(self.opts.anon and self.nodes or self.named)
end
--- @class InspectTreeOpts
--- @field lang string? The language of the source buffer. If omitted, the
--- filetype of the source buffer is used.
--- @field bufnr integer? Buffer to draw the tree into. If omitted, a new
--- buffer is created.
--- @field winid integer? Window id to display the tree buffer in. If omitted,
--- a new window is created with {command}.
--- @field command string? Vimscript command to create the window. Default
--- value is "60vnew". Only used when {winid} is nil.
--- @field title (string|fun(bufnr:integer):string|nil) Title of the window. If a
--- function, it accepts the buffer number of the source
--- buffer as its only argument and should return a string.
--- @class vim.treesitter.dev.inspect_tree.Opts
--- @inlinedoc
---
--- The language of the source buffer. If omitted, the filetype of the source
--- buffer is used.
--- @field lang string?
---
--- Buffer to draw the tree into. If omitted, a new buffer is created.
--- @field bufnr integer?
---
--- Window id to display the tree buffer in. If omitted, a new window is
--- created with {command}.
--- @field winid integer?
---
--- Vimscript command to create the window. Default value is "60vnew".
--- Only used when {winid} is nil.
--- @field command string?
---
--- Title of the window. If a function, it accepts the buffer number of the
--- source buffer as its only argument and should return a string.
--- @field title (string|fun(bufnr:integer):string|nil)
--- @private
---
--- @param opts InspectTreeOpts?
--- @param opts vim.treesitter.dev.inspect_tree.Opts?
function M.inspect_tree(opts)
vim.validate({
opts = { opts, 't', true },

View File

@@ -4,9 +4,9 @@ local Range = require('vim.treesitter._range')
local ns = api.nvim_create_namespace('treesitter/highlighter')
---@alias vim.treesitter.highlighter.Iter fun(end_line: integer|nil): integer, TSNode, TSMetadata
---@alias vim.treesitter.highlighter.Iter fun(end_line: integer|nil): integer, TSNode, vim.treesitter.query.TSMetadata
---@class vim.treesitter.highlighter.Query
---@class (private) vim.treesitter.highlighter.Query
---@field private _query vim.treesitter.Query?
---@field private lang string
---@field private hl_cache table<integer,integer>
@@ -52,22 +52,23 @@ function TSHighlighterQuery:query()
return self._query
end
---@class vim.treesitter.highlighter.State
---@class (private) vim.treesitter.highlighter.State
---@field tstree TSTree
---@field next_row integer
---@field iter vim.treesitter.highlighter.Iter?
---@field highlighter_query vim.treesitter.highlighter.Query
---@nodoc
---@class vim.treesitter.highlighter
---@field active table<integer,vim.treesitter.highlighter>
---@field bufnr integer
---@field orig_spelloptions string
---@field private orig_spelloptions string
--- A map of highlight states.
--- This state is kept during rendering across each line update.
---@field _highlight_states vim.treesitter.highlighter.State[]
---@field _queries table<string,vim.treesitter.highlighter.Query>
---@field tree LanguageTree
---@field redraw_count integer
---@field private _highlight_states vim.treesitter.highlighter.State[]
---@field private _queries table<string,vim.treesitter.highlighter.Query>
---@field tree vim.treesitter.LanguageTree
---@field private redraw_count integer
local TSHighlighter = {
active = {},
}
@@ -78,7 +79,7 @@ TSHighlighter.__index = TSHighlighter
---
--- Creates a highlighter for `tree`.
---
---@param tree LanguageTree parser object to use for highlighting
---@param tree vim.treesitter.LanguageTree parser object to use for highlighting
---@param opts (table|nil) Configuration of the highlighter:
--- - queries table overwrite queries used by the highlighter
---@return vim.treesitter.highlighter Created highlighter object

View File

@@ -56,10 +56,17 @@ function M.require_language(lang, path, silent, symbol_name)
return true
end
---@class vim.treesitter.language.RequireLangOpts
---@field path? string
---@field silent? boolean
---@class vim.treesitter.language.add.Opts
---@inlinedoc
---
---Default filetype the parser should be associated with.
---(Default: {lang})
---@field filetype? string|string[]
---
---Optional path the parser is located at
---@field path? string
---
---Internal symbol name for the language to load
---@field symbol_name? string
--- Load parser with name {lang}
@@ -67,13 +74,8 @@ end
--- Parsers are searched in the `parser` runtime directory, or the provided {path}
---
---@param lang string Name of the parser (alphanumerical and `_` only)
---@param opts (table|nil) Options:
--- - filetype (string|string[]) Default filetype the parser should be associated with.
--- Defaults to {lang}.
--- - path (string|nil) Optional path the parser is located at
--- - symbol_name (string|nil) Internal symbol name for the language to load
---@param opts? vim.treesitter.language.add.Opts Options:
function M.add(lang, opts)
---@cast opts vim.treesitter.language.RequireLangOpts
opts = opts or {}
local path = opts.path
local filetype = opts.filetype or lang

View File

@@ -67,10 +67,11 @@ local TSCallbackNames = {
on_child_removed = 'child_removed',
}
---@class LanguageTree
---@nodoc
---@class vim.treesitter.LanguageTree
---@field private _callbacks table<TSCallbackName,function[]> Callback handlers
---@field package _callbacks_rec table<TSCallbackName,function[]> Callback handlers (recursive)
---@field private _children table<string,LanguageTree> Injected languages
---@field private _children table<string,vim.treesitter.LanguageTree> Injected languages
---@field private _injection_query Query Queries defining injected languages
---@field private _injections_processed boolean
---@field private _opts table Options
@@ -89,7 +90,9 @@ local TSCallbackNames = {
---@field private _logfile? file*
local LanguageTree = {}
---@class LanguageTreeOpts
---Optional arguments:
---@class vim.treesitter.LanguageTree.new.Opts
---@inlinedoc
---@field queries table<string,string> -- Deprecated
---@field injections table<string,string>
@@ -102,14 +105,11 @@ LanguageTree.__index = LanguageTree
---
---@param source (integer|string) Buffer or text string to parse
---@param lang string Root language of this tree
---@param opts (table|nil) Optional arguments:
--- - injections table Map of language to injection query strings. Overrides the
--- built-in runtime file searching for language injections.
---@param opts vim.treesitter.LanguageTree.new.Opts?
---@param parent_lang? string Parent language name of this tree
---@return LanguageTree parser object
---@return vim.treesitter.LanguageTree parser object
function LanguageTree.new(source, lang, opts, parent_lang)
language.add(lang)
---@type LanguageTreeOpts
opts = opts or {}
if source == 0 then
@@ -118,7 +118,7 @@ function LanguageTree.new(source, lang, opts, parent_lang)
local injections = opts.injections or {}
--- @type LanguageTree
--- @type vim.treesitter.LanguageTree
local self = {
_source = source,
_lang = lang,
@@ -194,7 +194,7 @@ local function tcall(f, ...)
end
---@private
---@vararg any
---@param ... any
function LanguageTree:_log(...)
if not self._logger then
return
@@ -464,7 +464,7 @@ end
--- add recursion yourself if needed.
--- Invokes the callback for each |LanguageTree| and its children recursively
---
---@param fn fun(tree: LanguageTree, lang: string)
---@param fn fun(tree: vim.treesitter.LanguageTree, lang: string)
---@param include_self boolean|nil Whether to include the invoking tree in the results
function LanguageTree:for_each_child(fn, include_self)
vim.deprecate('LanguageTree:for_each_child()', 'LanguageTree:children()', '0.11')
@@ -481,7 +481,7 @@ end
---
--- Note: This includes the invoking tree's child trees as well.
---
---@param fn fun(tree: TSTree, ltree: LanguageTree)
---@param fn fun(tree: TSTree, ltree: vim.treesitter.LanguageTree)
function LanguageTree:for_each_tree(fn)
for _, tree in pairs(self._trees) do
fn(tree, self)
@@ -498,7 +498,7 @@ end
---
---@private
---@param lang string Language to add.
---@return LanguageTree injected
---@return vim.treesitter.LanguageTree injected
function LanguageTree:add_child(lang)
if self._children[lang] then
self:remove_child(lang)
@@ -668,7 +668,7 @@ end
---@param node TSNode
---@param source string|integer
---@param metadata TSMetadata
---@param metadata vim.treesitter.query.TSMetadata
---@param include_children boolean
---@return Range6[]
local function get_node_ranges(node, source, metadata, include_children)
@@ -702,13 +702,14 @@ local function get_node_ranges(node, source, metadata, include_children)
return ranges
end
---@class TSInjectionElem
---@nodoc
---@class vim.treesitter.languagetree.InjectionElem
---@field combined boolean
---@field regions Range6[][]
---@alias TSInjection table<string,table<integer,TSInjectionElem>>
---@alias vim.treesitter.languagetree.Injection table<string,table<integer,vim.treesitter.languagetree.InjectionElem>>
---@param t table<integer,TSInjection>
---@param t table<integer,vim.treesitter.languagetree.Injection>
---@param tree_index integer
---@param pattern integer
---@param lang string
@@ -783,7 +784,7 @@ end
--- Extract injections according to:
--- https://tree-sitter.github.io/tree-sitter/syntax-highlighting#language-injection
---@param match table<integer,TSNode[]>
---@param metadata TSMetadata
---@param metadata vim.treesitter.query.TSMetadata
---@return string?, boolean, Range6[]
function LanguageTree:_get_injection(match, metadata)
local ranges = {} ---@type Range6[]
@@ -836,7 +837,7 @@ function LanguageTree:_get_injections()
return {}
end
---@type table<integer,TSInjection>
---@type table<integer,vim.treesitter.languagetree.Injection>
local injections = {}
for index, tree in pairs(self._trees) do
@@ -1150,7 +1151,7 @@ end
--- Gets the appropriate language that contains {range}.
---
---@param range Range4 `{ start_line, start_col, end_line, end_col }`
---@return LanguageTree Managing {range}
---@return vim.treesitter.LanguageTree Managing {range}
function LanguageTree:language_for_range(range)
for _, child in pairs(self._children) do
if child:contains(range) then

View File

@@ -3,6 +3,7 @@ local language = require('vim.treesitter.language')
local M = {}
---@nodoc
---Parsed query, see |vim.treesitter.query.parse()|
---
---@class vim.treesitter.Query
@@ -31,6 +32,7 @@ function Query.new(lang, ts_query)
return self
end
---@nodoc
---Information for Query, see |vim.treesitter.query.parse()|
---@class vim.treesitter.QueryInfo
---
@@ -296,7 +298,7 @@ end
--- handling the "any" vs "all" semantics. They are called from the
--- predicate_handlers table with the appropriate arguments for each predicate.
local impl = {
--- @param match TSMatch
--- @param match vim.treesitter.query.TSMatch
--- @param source integer|string
--- @param predicate any[]
--- @param any boolean
@@ -331,7 +333,7 @@ local impl = {
return not any
end,
--- @param match TSMatch
--- @param match vim.treesitter.query.TSMatch
--- @param source integer|string
--- @param predicate any[]
--- @param any boolean
@@ -371,7 +373,7 @@ local impl = {
end,
})
--- @param match TSMatch
--- @param match vim.treesitter.query.TSMatch
--- @param source integer|string
--- @param predicate any[]
--- @param any boolean
@@ -394,7 +396,7 @@ local impl = {
end
end)(),
--- @param match TSMatch
--- @param match vim.treesitter.query.TSMatch
--- @param source integer|string
--- @param predicate any[]
--- @param any boolean
@@ -421,12 +423,13 @@ local impl = {
end,
}
---@class TSMatch
---@nodoc
---@class vim.treesitter.query.TSMatch
---@field pattern? integer
---@field active? boolean
---@field [integer] TSNode[]
---@alias TSPredicate fun(match: TSMatch, pattern: integer, source: integer|string, predicate: any[]): boolean
---@alias TSPredicate fun(match: vim.treesitter.query.TSMatch, pattern: integer, source: integer|string, predicate: any[]): boolean
-- Predicate handler receive the following arguments
-- (match, pattern, bufnr, predicate)
@@ -534,13 +537,14 @@ local predicate_handlers = {
predicate_handlers['vim-match?'] = predicate_handlers['match?']
predicate_handlers['any-vim-match?'] = predicate_handlers['any-match?']
---@class TSMetadata
---@nodoc
---@class vim.treesitter.query.TSMetadata
---@field range? Range
---@field conceal? string
---@field [integer] TSMetadata
---@field [integer] vim.treesitter.query.TSMetadata
---@field [string] integer|string
---@alias TSDirective fun(match: TSMatch, _, _, predicate: (string|integer)[], metadata: TSMetadata)
---@alias TSDirective fun(match: vim.treesitter.query.TSMatch, _, _, predicate: (string|integer)[], metadata: vim.treesitter.query.TSMetadata)
-- Predicate handler receive the following arguments
-- (match, pattern, bufnr, predicate)
@@ -767,7 +771,7 @@ local function is_directive(name)
end
---@private
---@param match TSMatch
---@param match vim.treesitter.query.TSMatch
---@param pattern integer
---@param source integer|string
function Query:match_preds(match, pattern, source)
@@ -806,8 +810,8 @@ function Query:match_preds(match, pattern, source)
end
---@private
---@param match TSMatch
---@param metadata TSMetadata
---@param match vim.treesitter.query.TSMatch
---@param metadata vim.treesitter.query.TSMetadata
function Query:apply_directives(match, pattern, source, metadata)
local preds = self.info.patterns[pattern]
@@ -871,7 +875,7 @@ end
---@param start? integer Starting line for the search. Defaults to `node:start()`.
---@param stop? integer Stopping line for the search (end-exclusive). Defaults to `node:end_()`.
---
---@return (fun(end_line: integer|nil): integer, TSNode, TSMetadata):
---@return (fun(end_line: integer|nil): integer, TSNode, vim.treesitter.query.TSMetadata):
--- capture id, capture node, metadata
function Query:iter_captures(node, source, start, stop)
if type(source) == 'number' and source == 0 then
@@ -880,7 +884,7 @@ function Query:iter_captures(node, source, start, stop)
start, stop = value_or_node_range(start, stop, node)
local raw_iter = node:_rawquery(self.query, true, start, stop) ---@type fun(): integer, TSNode, TSMatch
local raw_iter = node:_rawquery(self.query, true, start, stop) ---@type fun(): integer, TSNode, vim.treesitter.query.TSMatch
local function iter(end_line)
local capture, captured_node, match = raw_iter()
local metadata = {}
@@ -952,7 +956,7 @@ function Query:iter_matches(node, source, start, stop, opts)
start, stop = value_or_node_range(start, stop, node)
local raw_iter = node:_rawquery(self.query, false, start, stop, opts) ---@type fun(): integer, TSMatch
local raw_iter = node:_rawquery(self.query, false, start, stop, opts) ---@type fun(): integer, vim.treesitter.query.TSMatch
local function iter()
local pattern, match = raw_iter()
local metadata = {}
@@ -982,9 +986,16 @@ function Query:iter_matches(node, source, start, stop, opts)
return iter
end
---@class QueryLinterOpts
---@field langs (string|string[]|nil)
---@field clear (boolean)
--- Optional keyword arguments:
--- @class vim.treesitter.query.lint.Opts
--- @inlinedoc
---
--- Language(s) to use for checking the query.
--- If multiple languages are specified, queries are validated for all of them
--- @field langs? string|string[]
---
--- Just clear current lint errors
--- @field clear boolean
--- Lint treesitter queries using installed parser, or clear lint errors.
---
@@ -999,10 +1010,7 @@ end
--- of the query file, e.g., if the path ends in `/lua/highlights.scm`, the parser for the
--- `lua` language will be used.
---@param buf (integer) Buffer handle
---@param opts? QueryLinterOpts (table) Optional keyword arguments:
--- - langs (string|string[]|nil) Language(s) to use for checking the query.
--- If multiple languages are specified, queries are validated for all of them
--- - clear (boolean) if `true`, just clear current lint errors
---@param opts? vim.treesitter.query.lint.Opts
function M.lint(buf, opts)
if opts and opts.clear then
vim.treesitter._query_linter.clear(buf)

View File

@@ -54,7 +54,8 @@
local M = {}
---@class Version
---@nodoc
---@class vim.Version
---@field [1] number
---@field [2] number
---@field [3] number
@@ -111,7 +112,7 @@ function Version:__newindex(key, value)
end
end
---@param other Version
---@param other vim.Version
function Version:__eq(other)
for i = 1, 3 do
if self[i] ~= other[i] then
@@ -132,7 +133,7 @@ function Version:__tostring()
return ret
end
---@param other Version
---@param other vim.Version
function Version:__lt(other)
for i = 1, 3 do
if self[i] > other[i] then
@@ -144,7 +145,7 @@ function Version:__lt(other)
return -1 == cmp_prerel(self.prerelease, other.prerelease)
end
---@param other Version
---@param other vim.Version
function Version:__le(other)
return self < other or self == other
end
@@ -153,9 +154,9 @@ end
---
--- Creates a new Version object, or returns `nil` if `version` is invalid.
---
--- @param version string|number[]|Version
--- @param version string|number[]|vim.Version
--- @param strict? boolean Reject "1.0", "0-x", "3.2a" or other non-conforming version strings
--- @return Version?
--- @return vim.Version?
function M._version(version, strict) -- Adapted from https://github.com/folke/lazy.nvim
if type(version) == 'table' then
if version.major then
@@ -203,7 +204,7 @@ end
---TODO: generalize this, move to func.lua
---
---@generic T: Version
---@generic T: vim.Version
---@param versions T[]
---@return T?
function M.last(versions)
@@ -216,14 +217,15 @@ function M.last(versions)
return last
end
---@class VersionRange
---@field from Version
---@field to? Version
---@class vim.VersionRange
---@inlinedoc
---@field from vim.Version
---@field to? vim.Version
local VersionRange = {}
--- @private
---
---@param version string|Version
---@param version string|vim.Version
function VersionRange:has(version)
if type(version) == 'string' then
---@diagnostic disable-next-line: cast-local-type
@@ -272,6 +274,7 @@ end
--- @see # https://github.com/npm/node-semver#ranges
---
--- @param spec string Version range "spec"
--- @return vim.VersionRange
function M.range(spec) -- Adapted from https://github.com/folke/lazy.nvim
if spec == '*' or spec == '' then
return setmetatable({ from = M.parse('0.0.0') }, { __index = VersionRange })
@@ -300,8 +303,8 @@ function M.range(spec) -- Adapted from https://github.com/folke/lazy.nvim
local semver = M.parse(version)
if semver then
local from = semver --- @type Version?
local to = vim.deepcopy(semver, true) --- @type Version?
local from = semver --- @type vim.Version?
local to = vim.deepcopy(semver, true) --- @type vim.Version?
---@diagnostic disable: need-check-nil
if mods == '' or mods == '=' then
to.patch = to.patch + 1
@@ -340,7 +343,7 @@ function M.range(spec) -- Adapted from https://github.com/folke/lazy.nvim
end
end
---@param v string|Version
---@param v string|vim.Version
---@return string
local function create_err_msg(v)
if type(v) == 'string' then
@@ -369,8 +372,8 @@ end
---
--- @note Per semver, build metadata is ignored when comparing two otherwise-equivalent versions.
---
---@param v1 Version|number[]|string Version object.
---@param v2 Version|number[]|string Version to compare with `v1`.
---@param v1 vim.Version|number[]|string Version object.
---@param v2 vim.Version|number[]|string Version to compare with `v1`.
---@return integer -1 if `v1 < v2`, 0 if `v1 == v2`, 1 if `v1 > v2`.
function M.cmp(v1, v2)
local v1_parsed = assert(M._version(v1), create_err_msg(v1))
@@ -385,40 +388,40 @@ function M.cmp(v1, v2)
end
---Returns `true` if the given versions are equal. See |vim.version.cmp()| for usage.
---@param v1 Version|number[]|string
---@param v2 Version|number[]|string
---@param v1 vim.Version|number[]|string
---@param v2 vim.Version|number[]|string
---@return boolean
function M.eq(v1, v2)
return M.cmp(v1, v2) == 0
end
---Returns `true` if `v1 <= v2`. See |vim.version.cmp()| for usage.
---@param v1 Version|number[]|string
---@param v2 Version|number[]|string
---@param v1 vim.Version|number[]|string
---@param v2 vim.Version|number[]|string
---@return boolean
function M.le(v1, v2)
return M.cmp(v1, v2) <= 0
end
---Returns `true` if `v1 < v2`. See |vim.version.cmp()| for usage.
---@param v1 Version|number[]|string
---@param v2 Version|number[]|string
---@param v1 vim.Version|number[]|string
---@param v2 vim.Version|number[]|string
---@return boolean
function M.lt(v1, v2)
return M.cmp(v1, v2) == -1
end
---Returns `true` if `v1 >= v2`. See |vim.version.cmp()| for usage.
---@param v1 Version|number[]|string
---@param v2 Version|number[]|string
---@param v1 vim.Version|number[]|string
---@param v2 vim.Version|number[]|string
---@return boolean
function M.ge(v1, v2)
return M.cmp(v1, v2) >= 0
end
---Returns `true` if `v1 > v2`. See |vim.version.cmp()| for usage.
---@param v1 Version|number[]|string
---@param v2 Version|number[]|string
---@param v1 vim.Version|number[]|string
---@param v2 vim.Version|number[]|string
---@return boolean
function M.gt(v1, v2)
return M.cmp(v1, v2) == 1
@@ -438,7 +441,7 @@ end
--- - strict (boolean): Default false. If `true`, no coercion is attempted on
--- input not conforming to semver v2.0.0. If `false`, `parse()` attempts to
--- coerce input such as "1.0", "0-x", "tmux 3.2a" into valid versions.
---@return Version? parsed_version Version object or `nil` if input is invalid.
---@return vim.Version? parsed_version Version object or `nil` if input is invalid.
function M.parse(version, opts)
assert(type(version) == 'string', create_err_msg(version))
opts = opts or { strict = false }
@@ -447,9 +450,9 @@ end
setmetatable(M, {
--- Returns the current Nvim version.
---@return Version
---@return vim.Version
__call = function()
local version = vim.fn.api_info().version ---@type Version
local version = vim.fn.api_info().version ---@type vim.Version
-- Workaround: vim.fn.api_info().version reports "prerelease" as a boolean.
version.prerelease = version.prerelease and 'dev' or nil
return setmetatable(version, Version)