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

@@ -141,7 +141,7 @@ LSP FUNCTIONS
- *vim.lsp.buf.range_formatting()* Use |vim.lsp.formatexpr()| - *vim.lsp.buf.range_formatting()* Use |vim.lsp.formatexpr()|
or |vim.lsp.buf.format()| instead. or |vim.lsp.buf.format()| instead.
- *vim.lsp.util.get_progress_messages()* Use |vim.lsp.status()| or access - *vim.lsp.util.get_progress_messages()* Use |vim.lsp.status()| or access
`progress` of |vim.lsp.client| `progress` of |vim.lsp.Client|
- *vim.lsp.get_active_clients()* Use |vim.lsp.get_clients()| - *vim.lsp.get_active_clients()* Use |vim.lsp.get_clients()|
- *vim.lsp.for_each_buffer_client()* Use |vim.lsp.get_clients()| - *vim.lsp.for_each_buffer_client()* Use |vim.lsp.get_clients()|
- *vim.lsp.util.lookup_section()* Use |vim.tbl_get()| and - *vim.lsp.util.lookup_section()* Use |vim.tbl_get()| and

View File

@@ -179,6 +179,8 @@ Strict "vimdoc" subset:
- Do not use indentation in random places—that prevents the page from using - Do not use indentation in random places—that prevents the page from using
"flow" layout. If you need a preformatted section, put it in "flow" layout. If you need a preformatted section, put it in
a |help-codeblock| starting with ">". a |help-codeblock| starting with ">".
- Parameters and fields are documented as `{foo}`.
- Optional parameters and fields are documented as `{foo}?`.
C docstrings ~ C docstrings ~
@@ -189,9 +191,8 @@ from the docstrings defined in src/nvim/api/*.c.
Docstring format: Docstring format:
- Lines start with `///` - Lines start with `///`
- Special tokens start with `@` followed by the token name: - Special tokens start with `@` followed by the token name:
`@note`, `@param`, `@returns` `@note`, `@param`, `@return`
- Limited markdown is supported. - Markdown is supported.
- List-items start with `-` (useful to nest or "indent")
- Use ``` for code samples. - Use ``` for code samples.
Code samples can be annotated as `vim` or `lua` Code samples can be annotated as `vim` or `lua`
@@ -233,11 +234,33 @@ definitions. The |lua-vim| :help is generated from the docstrings.
Docstring format: Docstring format:
- Use LuaCATS annotations: https://luals.github.io/wiki/annotations/ - Use LuaCATS annotations: https://luals.github.io/wiki/annotations/
- Limited markdown is supported. - Markdown is supported.
- List-items start with `-` (useful to nest or "indent")
- Use ``` for code samples. - Use ``` for code samples.
Code samples can be annotated as `vim` or `lua` Code samples can be annotated as `vim` or `lua`
- Use `@nodoc` to prevent documentation generation. - Use `@nodoc` to prevent documentation generation.
- Use `@inlinedoc` to inline `@class` blocks into `@param` blocks.
E.g. >lua
--- Object with fields:
--- @class myOpts
--- @inlinedoc
---
--- Documentation for some field
--- @field somefield? integer
--- @param opts? myOpts
function foo(opts)
end
<
Will be rendered as: >vimdoc
foo({opts})
Parameters:
- {opts}? (table) Object with the fields:
- {somefield}? (integer) Documentation
for some field
<
- Files which has `@meta` are only used for typing and documentation. - Files which has `@meta` are only used for typing and documentation.
Example: the help for |vim.paste()| is generated from a docstring decorating Example: the help for |vim.paste()| is generated from a docstring decorating

View File

@@ -38,24 +38,6 @@ optionally supplied). A good rule of thumb is that if a method is meant to
modify the diagnostics for a buffer (e.g. |vim.diagnostic.set()|) then it modify the diagnostics for a buffer (e.g. |vim.diagnostic.set()|) then it
requires a namespace. requires a namespace.
*diagnostic-structure*
A diagnostic is a Lua table with the following keys. Required keys are
indicated with (+):
bufnr: Buffer number
lnum(+): The starting line of the diagnostic
end_lnum: The final line of the diagnostic
col(+): The starting column of the diagnostic
end_col: The final column of the diagnostic
severity: The severity of the diagnostic |vim.diagnostic.severity|
message(+): The diagnostic text
source: The source of the diagnostic
code: The diagnostic code
user_data: Arbitrary data plugins or users can add
Diagnostics use the same indexing as the rest of the Nvim API (i.e. 0-based
rows and columns). |api-indexing|
*vim.diagnostic.severity* *diagnostic-severity* *vim.diagnostic.severity* *diagnostic-severity*
The "severity" key in a diagnostic is one of the values defined in The "severity" key in a diagnostic is one of the values defined in
`vim.diagnostic.severity`: `vim.diagnostic.severity`:
@@ -361,6 +343,105 @@ Example: >lua
============================================================================== ==============================================================================
Lua module: vim.diagnostic *diagnostic-api* Lua module: vim.diagnostic *diagnostic-api*
*vim.Diagnostic*
*diagnostic-structure*
Diagnostics use the same indexing as the rest of the Nvim API (i.e.
0-based rows and columns). |api-indexing|
Fields: ~
• {bufnr}? (`integer`) Buffer number
• {lnum} (`integer`) The starting line of the diagnostic
(0-indexed)
• {end_lnum}? (`integer`) The final line of the diagnostic (0-indexed)
• {col} (`integer`) The starting column of the diagnostic
(0-indexed)
• {end_col}? (`integer`) The final column of the diagnostic
(0-indexed)
• {severity}? (`vim.diagnostic.Severity`) The severity of the
diagnostic |vim.diagnostic.severity|
• {message} (`string`) The diagnostic text
• {source}? (`string`) The source of the diagnostic
• {code}? (`string|integer`) The diagnostic code
• {_tags}? (`{ deprecated: boolean, unnecessary: boolean}`)
• {user_data}? (`any`) arbitrary data plugins can add
• {namespace}? (`integer`)
*vim.diagnostic.NS*
Fields: ~
• {name} (`string`)
• {opts} (`vim.diagnostic.Opts`)
• {user_data} (`table`)
• {disabled}? (`boolean`)
*vim.diagnostic.Opts*
Fields: ~
• {float}? (`boolean|vim.diagnostic.Opts.Float`)
• {update_in_insert}? (`boolean`)
• {underline}? (`boolean|vim.diagnostic.Opts.Underline`)
• {virtual_text}? (`boolean|vim.diagnostic.Opts.VirtualText`)
• {signs}? (`boolean|vim.diagnostic.Opts.Signs`)
• {severity_sort}? (`boolean|{reverse?:boolean}`)
*vim.diagnostic.Opts.Float*
Fields: ~
• {bufnr}? (`integer`)
• {namespace}? (`integer`)
• {scope}? (`'line'|'buffer'|'cursor'|'c'|'l'|'b'`)
• {pos}? (`integer|{[1]:integer,[2]:integer}`)
• {severity_sort}? (`boolean|{reverse?:boolean}`)
• {severity}? (`vim.diagnostic.SeverityFilter`)
• {header}? (`string|{[1]:string,[2]:any}`)
• {source}? (`boolean|string`)
• {format}? (`fun(diagnostic:vim.Diagnostic): string`)
• {prefix}? (`string|table`)
• {suffix}? (`string|table`)
• {focus_id}? (`string`)
*vim.diagnostic.Opts.Signs*
Fields: ~
• {severity}? (`vim.diagnostic.SeverityFilter`)
• {priority}? (`integer`)
• {text}? (`table<vim.diagnostic.Severity,string>`)
• {numhl}? (`table<vim.diagnostic.Severity,string>`)
• {linehl}? (`table<vim.diagnostic.Severity,string>`)
• {texthl}? (`table<vim.diagnostic.Severity,string>`)
*vim.diagnostic.Opts.Underline*
Fields: ~
• {severity}? (`vim.diagnostic.SeverityFilter`)
*vim.diagnostic.Opts.VirtualText*
Fields: ~
• {severity}? (`vim.diagnostic.SeverityFilter`)
• {source}? (`boolean|string`)
• {prefix}? (`string|function`)
• {suffix}? (`string|function`)
• {spacing}? (`integer`)
• {format}? (`function`)
• {hl_mode}? (`'replace'|'combine'|'blend'`)
• {virt_text}? (`{[1]:string,[2]:any}[]`)
• {virt_text_pos}? (`'eol'|'overlay'|'right_align'|'inline'`)
• {virt_text_win_col}? (`integer`)
• {virt_text_hide}? (`boolean`)
*vim.diagnostic.OptsResolved*
Fields: ~
• {float} (`vim.diagnostic.Opts.Float`)
• {update_in_insert} (`boolean`)
• {underline} (`vim.diagnostic.Opts.Underline`)
• {virtual_text} (`vim.diagnostic.Opts.VirtualText`)
• {signs} (`vim.diagnostic.Opts.Signs`)
• {severity_sort} (`{reverse?:boolean}`)
config({opts}, {namespace}) *vim.diagnostic.config()* config({opts}, {namespace}) *vim.diagnostic.config()*
Configure diagnostic options globally or for a specific diagnostic Configure diagnostic options globally or for a specific diagnostic
namespace. namespace.
@@ -518,7 +599,8 @@ fromqflist({list}) *vim.diagnostic.fromqflist()*
|getloclist()|. |getloclist()|.
Return: ~ Return: ~
(`vim.Diagnostic[]`) array of |diagnostic-structure| (`vim.Diagnostic[]`) array of |diagnostic-structure|. See
|vim.Diagnostic|.
get({bufnr}, {opts}) *vim.diagnostic.get()* get({bufnr}, {opts}) *vim.diagnostic.get()*
Get current diagnostics. Get current diagnostics.
@@ -538,7 +620,7 @@ get({bufnr}, {opts}) *vim.diagnostic.get()*
Return: ~ Return: ~
(`vim.Diagnostic[]`) table A list of diagnostic items (`vim.Diagnostic[]`) table A list of diagnostic items
|diagnostic-structure|. Keys `bufnr`, `end_lnum`, `end_col`, and |diagnostic-structure|. Keys `bufnr`, `end_lnum`, `end_col`, and
`severity` are guaranteed to be present. `severity` are guaranteed to be present. See |vim.Diagnostic|.
get_namespace({namespace}) *vim.diagnostic.get_namespace()* get_namespace({namespace}) *vim.diagnostic.get_namespace()*
Get namespace metadata. Get namespace metadata.
@@ -563,7 +645,7 @@ get_next({opts}) *vim.diagnostic.get_next()*
• {opts} (`table?`) See |vim.diagnostic.goto_next()| • {opts} (`table?`) See |vim.diagnostic.goto_next()|
Return: ~ Return: ~
(`vim.Diagnostic?`) Next diagnostic (`vim.Diagnostic?`) Next diagnostic. See |vim.Diagnostic|.
get_next_pos({opts}) *vim.diagnostic.get_next_pos()* get_next_pos({opts}) *vim.diagnostic.get_next_pos()*
Return the position of the next diagnostic in the current buffer. Return the position of the next diagnostic in the current buffer.
@@ -582,7 +664,7 @@ get_prev({opts}) *vim.diagnostic.get_prev()*
• {opts} (`table?`) See |vim.diagnostic.goto_next()| • {opts} (`table?`) See |vim.diagnostic.goto_next()|
Return: ~ Return: ~
(`vim.Diagnostic?`) Previous diagnostic (`vim.Diagnostic?`) Previous diagnostic. See |vim.Diagnostic|.
get_prev_pos({opts}) *vim.diagnostic.get_prev_pos()* get_prev_pos({opts}) *vim.diagnostic.get_prev_pos()*
Return the position of the previous diagnostic in the current buffer. Return the position of the previous diagnostic in the current buffer.
@@ -599,21 +681,22 @@ goto_next({opts}) *vim.diagnostic.goto_next()*
Parameters: ~ Parameters: ~
• {opts} (`table?`) Configuration table with the following keys: • {opts} (`table?`) Configuration table with the following keys:
• namespace: (integer) Only consider diagnostics from the {namespace} (`integer`) Only consider diagnostics from the
given namespace. given namespace.
• cursor_position: (cursor position) Cursor position as a {cursor_position}? (`{[1]:integer,[2]:integer}`) Cursor
(row, col) tuple. See |nvim_win_get_cursor()|. Defaults to position as a (row, col) tuple. See |nvim_win_get_cursor()|.
the current cursor position. Defaults to the current cursor position.
• wrap: (boolean, default true) Whether to loop around file or {wrap}? (`boolean`, default: `true`) Whether to loop around
not. Similar to 'wrapscan'. file or not. Similar to 'wrapscan'.
• severity: See |diagnostic-severity|. {severity} (`vim.diagnostic.Severity`) See
• float: (boolean or table, default true) If "true", call |diagnostic-severity|.
|vim.diagnostic.open_float()| after moving. If a table, pass • {float}? (`boolean|vim.diagnostic.Opts.Float`, default:
the table as the {opts} parameter to `true`) If "true", call |vim.diagnostic.open_float()| after
|vim.diagnostic.open_float()|. Unless overridden, the float moving. If a table, pass the table as the {opts} parameter
will show diagnostics at the new cursor position (as if to |vim.diagnostic.open_float()|. Unless overridden, the
"cursor" were passed to the "scope" option). float will show diagnostics at the new cursor position (as
• win_id: (number, default 0) Window ID if "cursor" were passed to the "scope" option).
• {win_id}? (`integer`, default: `0`) Window ID
goto_prev({opts}) *vim.diagnostic.goto_prev()* goto_prev({opts}) *vim.diagnostic.goto_prev()*
Move to the previous diagnostic in the current buffer. Move to the previous diagnostic in the current buffer.
@@ -678,7 +761,7 @@ match({str}, {pat}, {groups}, {severity_map}, {defaults})
Return: ~ Return: ~
(`vim.Diagnostic?`) |diagnostic-structure| or `nil` if {pat} fails to (`vim.Diagnostic?`) |diagnostic-structure| or `nil` if {pat} fails to
match {str}. match {str}. See |vim.Diagnostic|.
open_float({opts}) *vim.diagnostic.open_float()* open_float({opts}) *vim.diagnostic.open_float()*
Show diagnostics in a floating window. Show diagnostics in a floating window.
@@ -758,7 +841,7 @@ set({namespace}, {bufnr}, {diagnostics}, {opts}) *vim.diagnostic.set()*
• {namespace} (`integer`) The diagnostic namespace • {namespace} (`integer`) The diagnostic namespace
• {bufnr} (`integer`) Buffer number • {bufnr} (`integer`) Buffer number
• {diagnostics} (`vim.Diagnostic[]`) A list of diagnostic items • {diagnostics} (`vim.Diagnostic[]`) A list of diagnostic items
|diagnostic-structure| |diagnostic-structure|. See |vim.Diagnostic|.
• {opts} (`table?`) Display options to pass to • {opts} (`table?`) Display options to pass to
|vim.diagnostic.show()| |vim.diagnostic.show()|
@@ -767,28 +850,30 @@ setloclist({opts}) *vim.diagnostic.setloclist()*
Parameters: ~ Parameters: ~
• {opts} (`table?`) Configuration table with the following keys: • {opts} (`table?`) Configuration table with the following keys:
• namespace: (number) Only add diagnostics from the given {namespace}? (`integer`) Only add diagnostics from the given
namespace. namespace.
• winnr: (number, default 0) Window number to set location {winnr}? (`integer`, default: `0`) Window number to set
list for. location list for.
• open: (boolean, default true) Open the location list after {open}? (`boolean`, default: `true`) Open the location list
setting. after setting.
• title: (string) Title of the location list. Defaults to {title}? (`string`) Title of the location list. Defaults to
"Diagnostics". "Diagnostics".
• severity: See |diagnostic-severity|. {severity}? (`vim.diagnostic.Severity`) See
|diagnostic-severity|.
setqflist({opts}) *vim.diagnostic.setqflist()* setqflist({opts}) *vim.diagnostic.setqflist()*
Add all diagnostics to the quickfix list. Add all diagnostics to the quickfix list.
Parameters: ~ Parameters: ~
• {opts} (`table?`) Configuration table with the following keys: • {opts} (`table?`) Configuration table with the following keys:
• namespace: (number) Only add diagnostics from the given {namespace}? (`integer`) Only add diagnostics from the given
namespace. namespace.
• open: (boolean, default true) Open quickfix list after {open}? (`boolean`, default: `true`) Open quickfix list
setting. after setting.
• title: (string) Title of quickfix list. Defaults to {title}? (`string`) Title of quickfix list. Defaults to
"Diagnostics". "Diagnostics".
• severity: See |diagnostic-severity|. {severity}? (`vim.diagnostic.Severity`) See
|diagnostic-severity|.
*vim.diagnostic.show()* *vim.diagnostic.show()*
show({namespace}, {bufnr}, {diagnostics}, {opts}) show({namespace}, {bufnr}, {diagnostics}, {opts})
@@ -804,7 +889,7 @@ show({namespace}, {bufnr}, {diagnostics}, {opts})
namespace and buffer. This can be used to display a namespace and buffer. This can be used to display a
list of diagnostics without saving them or to display list of diagnostics without saving them or to display
only a subset of diagnostics. May not be used when only a subset of diagnostics. May not be used when
{namespace} or {bufnr} is nil. {namespace} or {bufnr} is nil. See |vim.Diagnostic|.
• {opts} (`table?`) Display options. See • {opts} (`table?`) Display options. See
|vim.diagnostic.config()|. |vim.diagnostic.config()|.
@@ -814,7 +899,7 @@ toqflist({diagnostics}) *vim.diagnostic.toqflist()*
Parameters: ~ Parameters: ~
• {diagnostics} (`vim.Diagnostic[]`) List of diagnostics • {diagnostics} (`vim.Diagnostic[]`) List of diagnostics
|diagnostic-structure|. |diagnostic-structure|. See |vim.Diagnostic|.
Return: ~ Return: ~
(`table[]`) of quickfix list items |setqflist-what| (`table[]`) of quickfix list items |setqflist-what|

View File

@@ -218,7 +218,7 @@ Each response handler has this signature: >
- {ctx} (table) Table of calling state associated with the - {ctx} (table) Table of calling state associated with the
handler, with these keys: handler, with these keys:
- {method} (string) |lsp-method| name. - {method} (string) |lsp-method| name.
- {client_id} (number) |vim.lsp.client| identifier. - {client_id} (number) |vim.lsp.Client| identifier.
- {bufnr} (Buffer) Buffer handle. - {bufnr} (Buffer) Buffer handle.
- {params} (table|nil) Request parameters table. - {params} (table|nil) Request parameters table.
- {version} (number) Document version at time of - {version} (number) Document version at time of
@@ -366,31 +366,6 @@ https://microsoft.github.io/language-server-protocol/specifications/specificatio
LSP notification shape: LSP notification shape:
https://microsoft.github.io/language-server-protocol/specifications/specification-current/#notificationMessage https://microsoft.github.io/language-server-protocol/specifications/specification-current/#notificationMessage
*lsp-on-list-handler*
`on_list` receives a table with:
- `items` table[], structured like |setqflist-what|
- `title` string, title for the list.
- `context` table|nil. `ctx` from |lsp-handler|
This table can be used with vim.fn.setqflist or vim.fn.setloclist. E.g.:
>lua
local function on_list(options)
vim.fn.setqflist({}, ' ', options)
vim.api.nvim_command('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.api.nvim_command('lopen')
end
<
================================================================================ ================================================================================
LSP HIGHLIGHT *lsp-highlight* LSP HIGHLIGHT *lsp-highlight*
@@ -557,7 +532,7 @@ LspNotify *LspNotify*
LspProgress *LspProgress* LspProgress *LspProgress*
Upon receipt of a progress notification from the server. Notifications can Upon receipt of a progress notification from the server. Notifications can
be polled from a `progress` ring buffer of a |vim.lsp.client| or use be polled from a `progress` ring buffer of a |vim.lsp.Client| or use
|vim.lsp.status()| to get an aggregate message |vim.lsp.status()| to get an aggregate message
If the server sends a "work done progress", the `pattern` is set to `kind` If the server sends a "work done progress", the `pattern` is set to `kind`
@@ -583,7 +558,7 @@ LspRequest *LspRequest*
will trigger with {type} == `cancel`. will trigger with {type} == `cancel`.
When used from Lua, the client ID, request ID, and request are sent in When used from Lua, the client ID, request ID, and request are sent in
the "data" table. See {requests} in |vim.lsp.client| for details on the the "data" table. See {requests} in |vim.lsp.Client| for details on the
{request} value. If the request type is `complete`, the request will be {request} value. If the request type is `complete`, the request will be
deleted from the client's pending requests table immediately after deleted from the client's pending requests table immediately after
calling the event's callbacks. Example: >lua calling the event's callbacks. Example: >lua
@@ -712,77 +687,6 @@ buf_request_sync({bufnr}, {method}, {params}, {timeout_ms})
(`string?`) err On timeout, cancel, or error, `err` is a string (`string?`) err On timeout, cancel, or error, `err` is a string
describing the failure reason, and `result` is nil. describing the failure reason, and `result` is nil.
client *vim.lsp.client*
LSP client object. You can get an active client object via
|vim.lsp.get_client_by_id()| or |vim.lsp.get_clients()|.
• 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.
• 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()|
client_is_stopped({client_id}) *vim.lsp.client_is_stopped()* client_is_stopped({client_id}) *vim.lsp.client_is_stopped()*
Checks whether a client is stopped. Checks whether a client is stopped.
@@ -820,10 +724,9 @@ formatexpr({opts}) *vim.lsp.formatexpr()*
'v:lua.vim.lsp.formatexpr(#{timeout_ms:250})'`. 'v:lua.vim.lsp.formatexpr(#{timeout_ms:250})'`.
Parameters: ~ Parameters: ~
• {opts} (`table`) options for customizing the formatting expression • {opts} (`table?`) A table with the following fields:
which takes the following optional keys: • {timeout_ms} (`integer`, default: 500ms) The timeout period
• timeout_ms (default 500ms). The timeout period for the for the formatting request..
formatting request.
*vim.lsp.get_buffers_by_client_id()* *vim.lsp.get_buffers_by_client_id()*
get_buffers_by_client_id({client_id}) get_buffers_by_client_id({client_id})
@@ -843,23 +746,23 @@ get_client_by_id({client_id}) *vim.lsp.get_client_by_id()*
• {client_id} (`integer`) client id • {client_id} (`integer`) client id
Return: ~ Return: ~
(`lsp.Client?`) client rpc object (`vim.lsp.Client?`) client rpc object
get_clients({filter}) *vim.lsp.get_clients()* get_clients({filter}) *vim.lsp.get_clients()*
Get active clients. Get active clients.
Parameters: ~ Parameters: ~
• {filter} (`table?`) A table with key-value pairs used to filter the • {filter} (`table?`) Key-value pairs used to filter the returned
returned clients. The available keys are: clients.
• id (number): Only return clients with the given id {id}? (`integer`) Only return clients with the given id
• bufnr (number): Only return clients attached to this {bufnr}? (`integer`) Only return clients attached to this
buffer buffer
• name (string): Only return clients with the given name {name}? (`string`) Only return clients with the given name
• method (string): Only return clients supporting the given {method}? (`string`) Only return clients supporting the
method given method
Return: ~ Return: ~
(`lsp.Client[]`) List of |vim.lsp.client| objects (`vim.lsp.Client[]`) List of |vim.lsp.Client| objects
get_log_path() *vim.lsp.get_log_path()* get_log_path() *vim.lsp.get_log_path()*
Gets the path of the logfile used by the LSP client. Gets the path of the logfile used by the LSP client.
@@ -937,15 +840,16 @@ start({config}, {opts}) *vim.lsp.start()*
`ftplugin/<filetype_name>.lua` (See |ftplugin-name|) `ftplugin/<filetype_name>.lua` (See |ftplugin-name|)
Parameters: ~ Parameters: ~
• {config} (`lsp.ClientConfig`) Same configuration as documented in • {config} (`vim.lsp.ClientConfig`) Configuration for the server. See
|vim.lsp.start_client()| |vim.lsp.ClientConfig|.
• {opts} (`lsp.StartOpts?`) Optional keyword arguments: • {opts} (`table?`) Optional keyword arguments
• reuse_client (fun(client: client, config: table): boolean) {reuse_client} (`fun(client: vim.lsp.Client, config:
Predicate used to decide if a client should be re-used. table): boolean`) Predicate used to decide if a client
Used on all running clients. The default implementation should be re-used. Used on all running clients. The
re-uses a client if name and root_dir matches. default implementation re-uses a client if name and
• bufnr (number) Buffer handle to attach to if starting or root_dir matches.
re-using a client (0 for current). • {bufnr} (`integer`) Buffer handle to attach to if starting
or re-using a client (0 for current).
Return: ~ Return: ~
(`integer?`) client_id (`integer?`) client_id
@@ -953,112 +857,12 @@ start({config}, {opts}) *vim.lsp.start()*
start_client({config}) *vim.lsp.start_client()* start_client({config}) *vim.lsp.start_client()*
Starts and initializes a client with the given configuration. Starts and initializes a client with the given configuration.
Field `cmd` in {config} is required.
Parameters: ~ Parameters: ~
• {config} (`lsp.ClientConfig`) Configuration for the server: • {config} (`vim.lsp.ClientConfig`) Configuration for the server. See
• cmd: (string[]|fun(dispatchers: table):table) command |vim.lsp.ClientConfig|.
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: ~ Return: ~
(`integer?`) client_id. |vim.lsp.get_client_by_id()| Note: client may (`integer?`) client_id |vim.lsp.get_client_by_id()| Note: client may
not be fully initialized. Use `on_init` to do any actions once the not be fully initialized. Use `on_init` to do any actions once the
client has been initialized. client has been initialized.
@@ -1072,7 +876,7 @@ status() *vim.lsp.status()*
stop_client({client_id}, {force}) *vim.lsp.stop_client()* stop_client({client_id}, {force}) *vim.lsp.stop_client()*
Stops a client(s). Stops a client(s).
You can also use the `stop()` function on a |vim.lsp.client| object. To You can also use the `stop()` function on a |vim.lsp.Client| object. To
stop all clients: >lua stop all clients: >lua
vim.lsp.stop_client(vim.lsp.get_clients()) vim.lsp.stop_client(vim.lsp.get_clients())
< <
@@ -1081,8 +885,8 @@ stop_client({client_id}, {force}) *vim.lsp.stop_client()*
for this client, then force-shutdown is attempted. for this client, then force-shutdown is attempted.
Parameters: ~ Parameters: ~
• {client_id} (`integer|table`) id or |vim.lsp.client| object, or list • {client_id} (`integer|vim.lsp.Client`) id or |vim.lsp.Client| object,
thereof or list thereof
• {force} (`boolean?`) shutdown forcefully • {force} (`boolean?`) shutdown forcefully
tagfunc({pattern}, {flags}) *vim.lsp.tagfunc()* tagfunc({pattern}, {flags}) *vim.lsp.tagfunc()*
@@ -1109,9 +913,281 @@ with({handler}, {override_config}) *vim.lsp.with()*
behavior of the {handler} behavior of the {handler}
==============================================================================
Lua module: vim.lsp.client *lsp-client*
*vim.lsp.Client*
Fields: ~
• {id} (`integer`) 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} (`vim.lsp.rpc.PublicClient`) 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<string,lsp.Handler>`) The handlers
used by the client as described in
|lsp-handler|.
• {requests} (`table<integer,{ type: string, bufnr: integer, method: string}>`)
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} (`vim.lsp.ClientConfig`) copy of the table
that was passed by the user to
|vim.lsp.start_client()|.
• {server_capabilities} (`lsp.ServerCapabilities?`) Response from the
server sent on initialize` describing the
server's capabilities.
• {progress} (`vim.lsp.Client.Progress`) A ring buffer
(|vim.ringbuf()|) containing progress messages
sent by the server.
• {initialized} (`true?`)
• {workspace_folders} (`lsp.WorkspaceFolder[]?`) The workspace
folders configured in the client when the
server starts. This property is only available
if the client supports workspace folders. It
can be `null` if the client supports workspace
folders but none are configured.
• {root_dir} (`string`)
• {attached_buffers} (`table<integer,true>`)
• {commands} (`table<string,fun(command: lsp.Command, ctx:
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.
• {settings} (`table`)
• {flags} (`table`)
• {get_language_id} (`fun(bufnr: integer, filetype: string): string`)
• {capabilities} (`lsp.ClientCapabilities`) The capabilities
provided by the client (editor or tool)
• {dynamic_capabilities} (`lsp.DynamicCapabilities`)
• {request} (`fun(method: string, params: table?, handler: lsp.Handler?, bufnr: integer): boolean, integer?`)
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.
• {request_sync} (`fun(method: string, params: table?, timeout_ms: integer?, bufnr: integer): {err: lsp.ResponseError?, result:any}?, string?`)
err # a dictionary, where
• {notify} (`fun(method: string, params: table?):
boolean`) 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} (`fun(id: integer): boolean`) Cancels a
request with a given request id. Returns: same
as `notify()`.
• {stop} (`fun(force?: boolean)`) 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.
• {on_attach} (`fun(bufnr: integer)`) Runs the on_attach
function from the client's config if it was
defined. Useful for buffer-local setup.
• {supports_method} (`fun(method: string, opts?: {bufnr: integer?}): 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.
• {is_stopped} (`fun(): boolean`) Checks whether a client is
stopped. Returns: true if the client is fully
stopped.
*vim.lsp.Client.Progress*
Extends: |vim.Ringbuf|
Fields: ~
• {pending} (`table<lsp.ProgressToken,lsp.LSPAny>`)
*vim.lsp.ClientConfig*
Fields: ~
• {cmd} (`string[]|fun(dispatchers: vim.lsp.rpc.Dispatchers): vim.lsp.rpc.PublicClient?`)
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: cwd) 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: >lua
{ 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}? (`lsp.WorkspaceFolder[]`) 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}? (`lsp.ClientCapabilities`) 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}? (`table<string,function>`) Map of language
server method names to |lsp-handler|
• {settings}? (`table`) Map with language server specific
settings. These are returned to the language
server if requested via
`workspace/configuration`. Keys are
case-sensitive.
• {commands}? (`table<string,fun(command: lsp.Command, ctx:
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}? (`table`) 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}? (`fun(bufnr: integer, filetype: string):
string`) Language ID as string. Defaults to the
filetype.
• {offset_encoding}? (`'utf-8'|'utf-16'|'utf-32'`) The encoding that
the LSP server expects. Client does not verify
this is correct.
• {on_error}? (`fun(code: integer, err: string)`) 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.
• {before_init}? (`vim.lsp.client.before_init_cb`) 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.
• {on_init}? (`elem_or_list<vim.lsp.client.on_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.
• {on_exit}? (`elem_or_list<vim.lsp.client.on_exit_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
• {on_attach}? (`elem_or_list<vim.lsp.client.on_attach_cb>`)
Callback invoked when client attaches to a
buffer.
• {trace}? (`'off'|'messages'|'verbose'`, default: "off")
Passed directly to the language server in the
initialize request. Invalid/empty values will
• {flags}? (`table`) 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.
============================================================================== ==============================================================================
Lua module: vim.lsp.buf *lsp-buf* Lua module: vim.lsp.buf *lsp-buf*
*vim.lsp.ListOpts*
Fields: ~
• {on_list}? (`fun(t: vim.lsp.LocationOpts.OnList)`) 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
<
*vim.lsp.LocationOpts*
Extends: |vim.lsp.ListOpts|
Fields: ~
• {reuse_win}? (`boolean`) Jump to existing window if buffer is already
open.
*vim.lsp.LocationOpts.OnList*
Fields: ~
• {items} (`table[]`) Structured like |setqflist-what|
• {title}? (`string`) Title for the list.
• {context}? (`table`) `ctx` from |lsp-handler|
*vim.lsp.buf.add_workspace_folder()* *vim.lsp.buf.add_workspace_folder()*
add_workspace_folder({workspace_folder}) add_workspace_folder({workspace_folder})
Add the folder at path to the workspace folders. If {path} is not Add the folder at path to the workspace folders. If {path} is not
@@ -1127,27 +1203,26 @@ code_action({options}) *vim.lsp.buf.code_action()*
Selects a code action available at the current cursor position. Selects a code action available at the current cursor position.
Parameters: ~ Parameters: ~
• {options} (`table?`) Optional table which holds the following • {options} (`table?`) A table with the following fields:
optional fields: • {context}? (`lsp.CodeActionContext`) Corresponds to
• context: (table|nil) Corresponds to `CodeActionContext` `CodeActionContext` of the LSP specification:
of the LSP specification: • {diagnostics}? (`table`) LSP `Diagnostic[]`. Inferred
• diagnostics (table|nil): LSP `Diagnostic[]`. Inferred
from the current position if not provided. from the current position if not provided.
• only (table|nil): List of LSP `CodeActionKind`s used to {only}? (`table`) List of LSP `CodeActionKind`s used to
filter the code actions. Most language servers support filter the code actions. Most language servers support
values like `refactor` or `quickfix`. values like `refactor` or `quickfix`.
• triggerKind (number|nil): The reason why code actions {triggerKind}? (`integer`) The reason why code actions
were requested. were requested.
• filter: (function|nil) Predicate taking an `CodeAction` {filter}? (`fun(x: lsp.CodeAction|lsp.Command):boolean`)
and returning a boolean. Predicate taking an `CodeAction` and returning a boolean.
• apply: (boolean|nil) When set to `true`, and there is {apply}? (`boolean`) When set to `true`, and there is
just one remaining action (after filtering), the action just one remaining action (after filtering), the action
is applied without user query. is applied without user query.
• range: (table|nil) Range for which code actions should be {range}? (`{start: integer[], end: integer[]}`) Range for
requested. If in visual mode this defaults to the active which code actions should be requested. If in visual mode
selection. Table must contain `start` and `end` keys with this defaults to the active selection. Table must contain
{row,col} tuples using mark-like indexing. See `start` and `end` keys with {row,col} tuples using
|api-indexing| mark-like indexing. See |api-indexing|
See also: ~ See also: ~
• https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction • https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction
@@ -1174,21 +1249,13 @@ declaration({options}) *vim.lsp.buf.declaration()*
|vim.lsp.buf.definition()| instead. |vim.lsp.buf.definition()| instead.
Parameters: ~ Parameters: ~
• {options} (`table?`) additional options • {options} (`vim.lsp.LocationOpts?`) See |vim.lsp.LocationOpts|.
• 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.
definition({options}) *vim.lsp.buf.definition()* definition({options}) *vim.lsp.buf.definition()*
Jumps to the definition of the symbol under the cursor. Jumps to the definition of the symbol under the cursor.
Parameters: ~ Parameters: ~
• {options} (`table?`) additional options • {options} (`vim.lsp.LocationOpts?`) See |vim.lsp.LocationOpts|.
• 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.
document_highlight() *vim.lsp.buf.document_highlight()* document_highlight() *vim.lsp.buf.document_highlight()*
Send request to the server to resolve document highlights for the current Send request to the server to resolve document highlights for the current
@@ -1208,15 +1275,13 @@ document_symbol({options}) *vim.lsp.buf.document_symbol()*
Lists all symbols in the current buffer in the quickfix window. Lists all symbols in the current buffer in the quickfix window.
Parameters: ~ Parameters: ~
• {options} (`table?`) additional options • {options} (`vim.lsp.ListOpts?`) See |vim.lsp.ListOpts|.
• on_list: (function) handler for list results. See
|lsp-on-list-handler|
execute_command({command_params}) *vim.lsp.buf.execute_command()* execute_command({command_params}) *vim.lsp.buf.execute_command()*
Executes an LSP server command. Executes an LSP server command.
Parameters: ~ Parameters: ~
• {command_params} (`table`) A valid `ExecuteCommandParams` object • {command_params} (`lsp.ExecuteCommandParams`)
See also: ~ See also: ~
• https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_executeCommand • https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_executeCommand
@@ -1226,38 +1291,37 @@ format({options}) *vim.lsp.buf.format()*
server clients. server clients.
Parameters: ~ Parameters: ~
• {options} (`table?`) Optional table which holds the following • {options} (`table?`) A table with the following fields:
optional fields: • {formatting_options}? (`table`) Can be used to specify
• formatting_options (table|nil): Can be used to specify
FormattingOptions. Some unspecified options will be FormattingOptions. Some unspecified options will be
automatically derived from the current Nvim options. See automatically derived from the current Nvim options. See
https://microsoft.github.io/language-server-protocol/specification/#formattingOptions https://microsoft.github.io/language-server-protocol/specification/#formattingOptions
• timeout_ms (integer|nil, default 1000): Time in {timeout_ms}? (`integer`, default: `1000`) Time in
milliseconds to block for formatting requests. No effect milliseconds to block for formatting requests. No effect
if async=true if async=true.
• bufnr (number|nil): Restrict formatting to the clients {bufnr}? (`integer`, default: current buffer) Restrict
attached to the given buffer, defaults to the current formatting to the clients attached to the given buffer.
buffer (0). • {filter}? (`fun(client: vim.lsp.Client): boolean?`)
• filter (function|nil): Predicate used to filter clients. Predicate used to filter clients. Receives a client as
Receives a client as argument and must return a boolean. argument and must return a boolean. Clients matching the
Clients matching the predicate are included. Example: >lua predicate are included. Example: >lua
-- Never request typescript-language-server for formatting -- Never request typescript-language-server for formatting
vim.lsp.buf.format { vim.lsp.buf.format {
filter = function(client) return client.name ~= "tsserver" end filter = function(client) return client.name ~= "tsserver" end
} }
< <
• async boolean|nil If true the method won't block. {async}? (`boolean`, default: false) If true the method
Defaults to false. Editing the buffer while formatting won't block. Editing the buffer while formatting
asynchronous can lead to unexpected changes. asynchronous can lead to unexpected changes.
• id (number|nil): Restrict formatting to the client with {id}? (`integer`) Restrict formatting to the client with
ID (client.id) matching this field. ID (client.id) matching this field.
• name (string|nil): Restrict formatting to the client with {name}? (`string`) Restrict formatting to the client with
name (client.name) matching this field. name (client.name) matching this field.
• range (table|nil) Range to format. Table must contain {range}? (`{start:integer[],end:integer[]}`, default:
`start` and `end` keys with {row,col} tuples using (1,0) current selection in visual mode, `nil` in other modes,
indexing. Defaults to current selection in visual mode formatting the full buffer) Range to format. Table must
Defaults to `nil` in other modes, formatting the full contain `start` and `end` keys with {row,col} tuples
buffer using (1,0) indexing.
hover() *vim.lsp.buf.hover()* hover() *vim.lsp.buf.hover()*
Displays hover information about the symbol under the cursor in a floating Displays hover information about the symbol under the cursor in a floating
@@ -1268,9 +1332,7 @@ implementation({options}) *vim.lsp.buf.implementation()*
quickfix window. quickfix window.
Parameters: ~ Parameters: ~
• {options} (`table?`) additional options • {options} (`vim.lsp.LocationOpts?`) See |vim.lsp.LocationOpts|.
• on_list: (function) |lsp-on-list-handler| replacing the
default handler. Called for any non-empty result.
incoming_calls() *vim.lsp.buf.incoming_calls()* incoming_calls() *vim.lsp.buf.incoming_calls()*
Lists all the call sites of the symbol under the cursor in the |quickfix| Lists all the call sites of the symbol under the cursor in the |quickfix|
@@ -1291,9 +1353,7 @@ references({context}, {options}) *vim.lsp.buf.references()*
Parameters: ~ Parameters: ~
• {context} (`table?`) Context for the request • {context} (`table?`) Context for the request
• {options} (`table?`) additional options • {options} (`vim.lsp.ListOpts?`) See |vim.lsp.ListOpts|.
• on_list: (function) handler for list results. See
|lsp-on-list-handler|
See also: ~ See also: ~
• https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references • https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references
@@ -1312,11 +1372,12 @@ rename({new_name}, {options}) *vim.lsp.buf.rename()*
Parameters: ~ Parameters: ~
• {new_name} (`string?`) If not provided, the user will be prompted for • {new_name} (`string?`) If not provided, the user will be prompted for
a new name using |vim.ui.input()|. a new name using |vim.ui.input()|.
• {options} (`table?`) additional options • {options} (`table?`) Additional options:
• filter (function|nil): Predicate used to filter clients. {filter}? (`fun(client: vim.lsp.Client): boolean?`)
Receives a client as argument and must return a boolean. Predicate used to filter clients. Receives a client as
Clients matching the predicate are included. argument and must return a boolean. Clients matching the
• name (string|nil): Restrict clients used for rename to predicate are included.
• {name}? (`string`) Restrict clients used for rename to
ones where client.name matches this field. ones where client.name matches this field.
signature_help() *vim.lsp.buf.signature_help()* signature_help() *vim.lsp.buf.signature_help()*
@@ -1327,11 +1388,7 @@ type_definition({options}) *vim.lsp.buf.type_definition()*
Jumps to the definition of the type of the symbol under the cursor. Jumps to the definition of the type of the symbol under the cursor.
Parameters: ~ Parameters: ~
• {options} (`table?`) additional options • {options} (`vim.lsp.LocationOpts?`) See |vim.lsp.LocationOpts|.
• 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.
workspace_symbol({query}, {options}) *vim.lsp.buf.workspace_symbol()* workspace_symbol({query}, {options}) *vim.lsp.buf.workspace_symbol()*
Lists all symbols in the current workspace in the quickfix window. Lists all symbols in the current workspace in the quickfix window.
@@ -1342,9 +1399,7 @@ workspace_symbol({query}, {options}) *vim.lsp.buf.workspace_symbol()*
Parameters: ~ Parameters: ~
• {query} (`string?`) optional • {query} (`string?`) optional
• {options} (`table?`) additional options • {options} (`vim.lsp.ListOpts?`) See |vim.lsp.ListOpts|.
• on_list: (function) handler for list results. See
|lsp-on-list-handler|
============================================================================== ==============================================================================
@@ -1470,10 +1525,9 @@ refresh({opts}) *vim.lsp.codelens.refresh()*
< <
Parameters: ~ Parameters: ~
• {opts} (`vim.lsp.codelens.RefreshOptions?`) Table with the following • {opts} (`table?`) Optional fields
fields: • {bufnr} (`integer?`) filter by buffer. All buffers if nil, 0
• `bufnr` (integer|nil): filter by buffer. All buffers if nil, for current buffer
0 for current buffer
run() *vim.lsp.codelens.run()* run() *vim.lsp.codelens.run()*
Run the code lens in the current line Run the code lens in the current line
@@ -1525,17 +1579,15 @@ get({filter}) *vim.lsp.inlay_hint.get()*
• This API is pre-release (unstable). • This API is pre-release (unstable).
Parameters: ~ Parameters: ~
• {filter} (`vim.lsp.inlay_hint.get.filter?`) Optional filters • {filter} (`table?`) Optional filters |kwargs|:
|kwargs|: • {bufnr} (`integer?`)
bufnr (integer?): 0 for current buffer {range} (`lsp.Range?`)
• range (lsp.Range?)
Return: ~ Return: ~
(`vim.lsp.inlay_hint.get.ret[]`) Each list item is a table with the (`table[]`) A list of objects with the following fields:
following fields: • {bufnr} (`integer`)
bufnr (integer) {client_id} (`integer`)
client_id (integer) {inlay_hint} (`lsp.InlayHint`)
• inlay_hint (lsp.InlayHint)
is_enabled({bufnr}) *vim.lsp.inlay_hint.is_enabled()* is_enabled({bufnr}) *vim.lsp.inlay_hint.is_enabled()*
@@ -1596,12 +1648,12 @@ highlight_token({token}, {bufnr}, {client_id}, {hl_group}, {opts})
• {token} (`table`) a semantic token, found as `args.data.token` in • {token} (`table`) a semantic token, found as `args.data.token` in
|LspTokenUpdate|. |LspTokenUpdate|.
• {bufnr} (`integer`) the buffer to highlight • {bufnr} (`integer`) the buffer to highlight
• {client_id} (`integer`) The ID of the |vim.lsp.client| • {client_id} (`integer`) The ID of the |vim.lsp.Client|
• {hl_group} (`string`) Highlight group name • {hl_group} (`string`) Highlight group name
• {opts} (`table?`) Optional parameters. • {opts} (`table?`) Optional parameters:
• priority: (integer|nil) Priority for the applied {priority}? (`integer`, default:
extmark. Defaults to `vim.highlight.priorities.semantic_tokens + 3`)
`vim.highlight.priorities.semantic_tokens + 3` Priority for the applied extmark.
start({bufnr}, {client_id}, {opts}) *vim.lsp.semantic_tokens.start()* start({bufnr}, {client_id}, {opts}) *vim.lsp.semantic_tokens.start()*
Start the semantic token highlighting engine for the given buffer with the Start the semantic token highlighting engine for the given buffer with the
@@ -1841,7 +1893,12 @@ locations_to_items({locations}, {offset_encoding})
buffer buffer
Return: ~ Return: ~
(`vim.lsp.util.LocationItem[]`) list of items (`table[]`) A list of objects with the following fields:
• {filename} (`string`)
• {lnum} (`integer`) 1-indexed line number
• {col} (`integer`) 1-indexed column
• {text} (`string`)
• {user_data} (`lsp.Location|lsp.LocationLink`)
*vim.lsp.util.make_floating_popup_options()* *vim.lsp.util.make_floating_popup_options()*
make_floating_popup_options({width}, {height}, {opts}) make_floating_popup_options({width}, {height}, {opts})
@@ -1966,22 +2023,25 @@ open_floating_preview({contents}, {syntax}, {opts})
Parameters: ~ Parameters: ~
• {contents} (`table`) of lines to show in window • {contents} (`table`) of lines to show in window
• {syntax} (`string`) of syntax to set for opened buffer • {syntax} (`string`) of syntax to set for opened buffer
• {opts} (`table`) with optional fields (additional keys are • {opts} (`table?`) with optional fields (additional keys are
filtered with |vim.lsp.util.make_floating_popup_options()| filtered with |vim.lsp.util.make_floating_popup_options()|
before they are passed on to |nvim_open_win()|) before they are passed on to |nvim_open_win()|)
• height: (integer) height of floating window {height}? (`integer`) Height of floating window
• width: (integer) width of floating window {width}? (`integer`) Width of floating window
• wrap: (boolean, default true) wrap long lines {wrap}? (`boolean`, default: `true`) Wrap long lines
• wrap_at: (integer) character to wrap at for computing {wrap_at}? (`integer`) Character to wrap at for
height when wrap is enabled computing height when wrap is enabled
• max_width: (integer) maximal width of floating window {max_width}? (`integer`) Maximal width of floating
• max_height: (integer) maximal height of floating window window
focus_id: (string) if a popup with this id is opened, {max_height}? (`integer`) Maximal height of floating
then focus it window
close_events: (table) list of events that closes the {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 floating window
• focusable: (boolean, default true) Make float focusable {focusable}? (`boolean`, default: `true`) Make float
focus: (boolean, default true) If `true`, and if focusable.
• {focus}? (`boolean`, default: `true`) If `true`, and if
{focusable} is also `true`, focus an existing floating {focusable} is also `true`, focus an existing floating
window with the same {focus_id} window with the same {focus_id}
@@ -2011,9 +2071,9 @@ rename({old_fname}, {new_fname}, {opts}) *vim.lsp.util.rename()*
Parameters: ~ Parameters: ~
• {old_fname} (`string`) • {old_fname} (`string`)
• {new_fname} (`string`) • {new_fname} (`string`)
• {opts} (`table?`) options • {opts} (`table?`) Options:
• overwrite? boolean {overwrite}? (`boolean`)
• ignoreIfExists? boolean {ignoreIfExists}? (`boolean`)
*vim.lsp.util.show_document()* *vim.lsp.util.show_document()*
show_document({location}, {offset_encoding}, {opts}) show_document({location}, {offset_encoding}, {opts})
@@ -2106,6 +2166,17 @@ should_log({level}) *vim.lsp.log.should_log()*
============================================================================== ==============================================================================
Lua module: vim.lsp.rpc *lsp-rpc* Lua module: vim.lsp.rpc *lsp-rpc*
*vim.lsp.rpc.PublicClient*
Fields: ~
• {request} (`fun(method: string, params: table?, callback: fun(err: lsp.ResponseError?, result: any), notify_reply_callback: fun(integer)?):boolean,integer?`)
see |vim.lsp.rpc.request()|
• {notify} (`fun(method: string, params: any):boolean`) see
|vim.lsp.rpc.notify()|
• {is_closing} (`fun(): boolean`)
• {terminate} (`fun()`)
connect({host}, {port}) *vim.lsp.rpc.connect()* connect({host}, {port}) *vim.lsp.rpc.connect()*
Create a LSP RPC client factory that connects via TCP to the given host Create a LSP RPC client factory that connects via TCP to the given host
and port. and port.
@@ -2199,28 +2270,31 @@ start({cmd}, {dispatchers}, {extra_spawn_params}) *vim.lsp.rpc.start()*
Parameters: ~ Parameters: ~
• {cmd} (`string[]`) Command to start the LSP server. • {cmd} (`string[]`) Command to start the LSP server.
• {dispatchers} (`vim.lsp.rpc.Dispatchers?`) Dispatchers for LSP • {dispatchers} (`table?`) Dispatchers for LSP message types.
message types. Valid dispatcher names are: • {notification} (`fun(method: string, params:
• `"notification"` table)`)
`"server_request"` {server_request} (`fun(method: string, params:
• `"on_error"` table): any?, lsp.ResponseError?`)
`"on_exit"` {on_exit} (`fun(code: integer, signal:
• {extra_spawn_params} (`vim.lsp.rpc.ExtraSpawnParams?`) Additional integer)`)
context for the LSP server process. May contain: • {on_error} (`fun(code: integer, err: any)`)
• {cwd} (string) Working directory for the LSP • {extra_spawn_params} (`table?`) Additional context for the LSP server
server process process.
• {detached?} (boolean) Detach the LSP server • {cwd}? (`string`) Working directory for the
process from the current process. Defaults to LSP server process
false on Windows and true otherwise. • {detached}? (`boolean`) Detach the LSP server
• {env?} (table) Additional environment process from the current process
variables for LSP server process • {env}? (`table<string,string>`) Additional
environment variables for LSP server process.
See |vim.system()|
Return: ~ Return: ~
(`vim.lsp.rpc.PublicClient?`) Client RPC object, with these methods: (`vim.lsp.rpc.PublicClient?`) Client RPC object, with these methods:
• `notify()` |vim.lsp.rpc.notify()| • `notify()` |vim.lsp.rpc.notify()|
• `request()` |vim.lsp.rpc.request()| • `request()` |vim.lsp.rpc.request()|
• `is_closing()` returns a boolean indicating if the RPC is closing. • `is_closing()` returns a boolean indicating if the RPC is closing.
• `terminate()` terminates the RPC client. • `terminate()` terminates the RPC client. See
|vim.lsp.rpc.PublicClient|.
============================================================================== ==============================================================================

View File

@@ -1828,16 +1828,16 @@ vim.inspect_pos({bufnr}, {row}, {col}, {filter}) *vim.inspect_pos()*
the current cursor the current cursor
• {col} (`integer?`) col to inspect, 0-based. Defaults to the col of • {col} (`integer?`) col to inspect, 0-based. Defaults to the col of
the current cursor the current cursor
• {filter} (`table?`) a table with key-value pairs to filter the items • {filter} (`table?`) Table with key-value pairs to filter the items
• syntax (boolean): include syntax based highlight groups {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) (defaults to true)
• {treesitter} (`boolean`) Include treesitter based
highlight groups (defaults to true)
• {extmarks} (`boolean|"all"`, default: true) Include
extmarks. When `all`, then extmarks without a `hl_group`
will also be included.
• {semantic_tokens} (`boolean`) Include semantic token
highlights (defaults to true)
Return: ~ Return: ~
(`table`) a table with the following key-value pairs. Items are in (`table`) a table with the following key-value pairs. Items are in
@@ -1866,6 +1866,17 @@ vim.show_pos({bufnr}, {row}, {col}, {filter}) *vim.show_pos()*
*vim.Ringbuf*
Fields: ~
• {clear} (`fun()`) Clear all items
• {push} (`fun(item: T)`) Adds an item, overriding the oldest item if
the buffer is full.
• {pop} (`fun(): T?`) Removes and returns the first unread item
• {peek} (`fun(): T?`) Returns the first unread item without removing
it
Ringbuf:clear() *Ringbuf:clear()* Ringbuf:clear() *Ringbuf:clear()*
Clear all items Clear all items
@@ -1970,9 +1981,10 @@ vim.gsplit({s}, {sep}, {opts}) *vim.gsplit()*
• {s} (`string`) String to split • {s} (`string`) String to split
• {sep} (`string`) Separator or pattern • {sep} (`string`) Separator or pattern
• {opts} (`table?`) Keyword arguments |kwargs|: • {opts} (`table?`) Keyword arguments |kwargs|:
• plain: (boolean) Use `sep` literally (as in string.find). {plain}? (`boolean`) Use `sep` literally (as in
• trimempty: (boolean) Discard empty segments at start and end string.find).
of the sequence. • {trimempty}? (`boolean`) Discard empty segments at start and
end of the sequence.
Return: ~ Return: ~
(`function`) Iterator over the split components (`function`) Iterator over the split components
@@ -2104,8 +2116,11 @@ vim.split({s}, {sep}, {opts}) *vim.split()*
Parameters: ~ Parameters: ~
• {s} (`string`) String to split • {s} (`string`) String to split
• {sep} (`string`) Separator or pattern • {sep} (`string`) Separator or pattern
• {opts} (`table?`) Keyword arguments |kwargs| accepted by • {opts} (`table?`) Keyword arguments |kwargs|:
|vim.gsplit()| • {plain}? (`boolean`) Use `sep` literally (as in
string.find).
• {trimempty}? (`boolean`) Discard empty segments at start and
end of the sequence.
Return: ~ Return: ~
(`string[]`) List of split components (`string[]`) List of split components
@@ -2151,8 +2166,8 @@ vim.tbl_contains({t}, {value}, {opts}) *vim.tbl_contains()*
• {t} (`table`) Table to check • {t} (`table`) Table to check
• {value} (`any`) Value to compare or predicate function reference • {value} (`any`) Value to compare or predicate function reference
• {opts} (`table?`) Keyword arguments |kwargs|: • {opts} (`table?`) Keyword arguments |kwargs|:
• predicate: (boolean) `value` is a function reference to be {predicate}? (`boolean`) `value` is a function reference to
checked (default false) be checked (default false)
Return: ~ Return: ~
(`boolean`) `true` if `t` contains `value` (`boolean`) `true` if `t` contains `value`
@@ -2419,23 +2434,23 @@ vim.loader.find({modname}, {opts}) *vim.loader.find()*
• {modname} (`string`) Module name, or `"*"` to find the top-level • {modname} (`string`) Module name, or `"*"` to find the top-level
modules instead modules instead
• {opts} (`table?`) Options for finding a module: • {opts} (`table?`) Options for finding a module:
• rtp: (boolean) Search for modname in the runtime path {rtp}? (`boolean`, default: `true`) Search for modname in
(defaults to `true`) the runtime path.
• paths: (string[]) Extra paths to search for modname {paths}? (`string[]`, default: `{}`) Extra paths to
(defaults to `{}`) search for modname
• patterns: (string[]) List of patterns to use when {patterns}? (`string[]`, default: `{"/init.lua",
searching for modules. A pattern is a string added to the ".lua"}`) List of patterns to use when searching for
basename of the Lua module being searched. (defaults to modules. A pattern is a string added to the basename of
`{"/init.lua", ".lua"}`) the Lua module being searched.
• all: (boolean) Return all matches instead of just the {all}? (`boolean`, default: `false`) Search for all
first one (defaults to `false`) matches.
Return: ~ Return: ~
(`table`) A list of results with the following properties: (`table[]`) A list of objects with the following fields:
• modpath: (string) the path to the module {modpath} (`string`) Path of the module
• modname: (string) the name of the module {modname} (`string`) Name of the module
• stat: (table|nil) the fs_stat of the module path. Won't be returned {stat}? (`uv.uv_fs_t`) The fs_stat of the module path. Won't be
for `modname="*"` returned for `modname="*"`
vim.loader.reset({path}) *vim.loader.reset()* vim.loader.reset({path}) *vim.loader.reset()*
Resets the cache for the path, or all the paths if path is nil. Resets the cache for the path, or all the paths if path is nil.
@@ -2678,6 +2693,9 @@ vim.filetype.add({filetypes}) *vim.filetype.add()*
Parameters: ~ Parameters: ~
• {filetypes} (`table`) A table containing new filetype maps (see • {filetypes} (`table`) A table containing new filetype maps (see
example). example).
• {pattern}? (`vim.filetype.mapping`)
• {extension}? (`vim.filetype.mapping`)
• {filename}? (`vim.filetype.mapping`)
*vim.filetype.get_option()* *vim.filetype.get_option()*
vim.filetype.get_option({filetype}, {option}) vim.filetype.get_option({filetype}, {option})
@@ -2734,16 +2752,16 @@ vim.filetype.match({args}) *vim.filetype.match()*
Parameters: ~ Parameters: ~
• {args} (`table`) Table specifying which matching strategy to use. • {args} (`table`) Table specifying which matching strategy to use.
Accepted keys are: Accepted keys are:
• buf (number): Buffer number to use for matching. Mutually {buf}? (`integer`) Buffer number to use for matching.
exclusive with {contents} Mutually exclusive with {contents}
• filename (string): Filename to use for matching. When {buf} {filename}? (`string`) Filename to use for matching. When
is given, defaults to the filename of the given buffer {buf} is given, defaults to the filename of the given buffer
number. The file need not actually exist in the filesystem. number. The file need not actually exist in the filesystem.
When used without {buf} only the name of the file is used When used without {buf} only the name of the file is used
for filetype matching. This may result in failure to detect for filetype matching. This may result in failure to detect
the filetype in cases where the filename alone is not enough the filetype in cases where the filename alone is not enough
to disambiguate the filetype. to disambiguate the filetype.
• contents (table): An array of lines representing file {contents}? (`string[]`) An array of lines representing file
contents to use for matching. Can be used with {filename}. contents to use for matching. Can be used with {filename}.
Mutually exclusive with {buf}. Mutually exclusive with {buf}.
@@ -2896,18 +2914,18 @@ vim.fs.find({names}, {opts}) *vim.fs.find()*
• path: full path of the current item The function should • path: full path of the current item The function should
return `true` if the given item is considered a match. return `true` if the given item is considered a match.
• {opts} (`table`) Optional keyword arguments: • {opts} (`table`) Optional keyword arguments:
• path (string): Path to begin searching from. If omitted, {path} (`string`) Path to begin searching from. If omitted,
the |current-directory| is used. the |current-directory| is used.
• upward (boolean, default false): If true, search upward {upward} (`boolean`, default: `false`) Search upward
through parent directories. Otherwise, search through child through parent directories. Otherwise, search through child
directories (recursively). directories (recursively).
• stop (string): Stop searching when this directory is {stop} (`string`) Stop searching when this directory is
reached. The directory itself is not searched. reached. The directory itself is not searched.
• type (string): Find only items of the given type. If {type} (`string`) Find only items of the given type. If
omitted, all items that match {names} are included. omitted, all items that match {names} are included.
• limit (number, default 1): Stop the search after finding {limit} (`number`, default: `1`) Stop the search after
this many matches. Use `math.huge` to place no limit on the finding this many matches. Use `math.huge` to place no
number of matches. limit on the number of matches.
Return: ~ Return: ~
(`string[]`) Normalized paths |vim.fs.normalize()| of all matching (`string[]`) Normalized paths |vim.fs.normalize()| of all matching
@@ -2942,9 +2960,9 @@ vim.fs.normalize({path}, {opts}) *vim.fs.normalize()*
Parameters: ~ Parameters: ~
• {path} (`string`) Path to normalize • {path} (`string`) Path to normalize
• {opts} (`table?`) Options: • {opts} (`table?`) A table with the following fields:
• expand_env: boolean Expand environment variables (default: {expand_env} (`boolean`, default: `true`) Expand environment
true) variables.
Return: ~ Return: ~
(`string`) Normalized path (`string`) Normalized path
@@ -3538,14 +3556,15 @@ vim.secure.trust({opts}) *vim.secure.trust()*
The trust database is located at |$XDG_STATE_HOME|/nvim/trust. The trust database is located at |$XDG_STATE_HOME|/nvim/trust.
Parameters: ~ Parameters: ~
• {opts} (`table`) • {opts} (`table?`) A table with the following fields:
• action (string): "allow" to add a file to the trust database {action} (`'allow'|'deny'|'remove'`) - `'allow'` to add a
and trust it, "deny" to add a file to the trust database and file to the trust database and trust it,
deny it, "remove" to remove file from the trust database • `'deny'` to add a file to the trust database and deny it,
path (string|nil): Path to a file to update. Mutually `'remove'` to remove file from the trust database
• {path}? (`string`) Path to a file to update. Mutually
exclusive with {bufnr}. Cannot be used when {action} is exclusive with {bufnr}. Cannot be used when {action} is
"allow". "allow".
• bufnr (number|nil): Buffer number to update. Mutually {bufnr}? (`integer`) Buffer number to update. Mutually
exclusive with {path}. exclusive with {path}.
Return (multiple): ~ Return (multiple): ~
@@ -3628,8 +3647,8 @@ vim.version.cmp({v1}, {v2}) *vim.version.cmp()*
otherwise-equivalent versions. otherwise-equivalent versions.
Parameters: ~ Parameters: ~
• {v1} (`Version|number[]|string`) Version object. • {v1} (`vim.Version|number[]|string`) Version object.
• {v2} (`Version|number[]|string`) Version to compare with `v1`. • {v2} (`vim.Version|number[]|string`) Version to compare with `v1`.
Return: ~ Return: ~
(`integer`) -1 if `v1 < v2`, 0 if `v1 == v2`, 1 if `v1 > v2`. (`integer`) -1 if `v1 < v2`, 0 if `v1 == v2`, 1 if `v1 > v2`.
@@ -3639,8 +3658,8 @@ vim.version.eq({v1}, {v2}) *vim.version.eq()*
for usage. for usage.
Parameters: ~ Parameters: ~
• {v1} (`Version|number[]|string`) • {v1} (`vim.Version|number[]|string`)
• {v2} (`Version|number[]|string`) • {v2} (`vim.Version|number[]|string`)
Return: ~ Return: ~
(`boolean`) (`boolean`)
@@ -3649,8 +3668,8 @@ vim.version.ge({v1}, {v2}) *vim.version.ge()*
Returns `true` if `v1 >= v2`. See |vim.version.cmp()| for usage. Returns `true` if `v1 >= v2`. See |vim.version.cmp()| for usage.
Parameters: ~ Parameters: ~
• {v1} (`Version|number[]|string`) • {v1} (`vim.Version|number[]|string`)
• {v2} (`Version|number[]|string`) • {v2} (`vim.Version|number[]|string`)
Return: ~ Return: ~
(`boolean`) (`boolean`)
@@ -3659,8 +3678,8 @@ vim.version.gt({v1}, {v2}) *vim.version.gt()*
Returns `true` if `v1 > v2`. See |vim.version.cmp()| for usage. Returns `true` if `v1 > v2`. See |vim.version.cmp()| for usage.
Parameters: ~ Parameters: ~
• {v1} (`Version|number[]|string`) • {v1} (`vim.Version|number[]|string`)
• {v2} (`Version|number[]|string`) • {v2} (`vim.Version|number[]|string`)
Return: ~ Return: ~
(`boolean`) (`boolean`)
@@ -3669,17 +3688,17 @@ vim.version.last({versions}) *vim.version.last()*
TODO: generalize this, move to func.lua TODO: generalize this, move to func.lua
Parameters: ~ Parameters: ~
• {versions} (`Version[]`) • {versions} (`vim.Version[]`)
Return: ~ Return: ~
(`Version?`) (`vim.Version?`)
vim.version.le({v1}, {v2}) *vim.version.le()* vim.version.le({v1}, {v2}) *vim.version.le()*
Returns `true` if `v1 <= v2`. See |vim.version.cmp()| for usage. Returns `true` if `v1 <= v2`. See |vim.version.cmp()| for usage.
Parameters: ~ Parameters: ~
• {v1} (`Version|number[]|string`) • {v1} (`vim.Version|number[]|string`)
• {v2} (`Version|number[]|string`) • {v2} (`vim.Version|number[]|string`)
Return: ~ Return: ~
(`boolean`) (`boolean`)
@@ -3688,8 +3707,8 @@ vim.version.lt({v1}, {v2}) *vim.version.lt()*
Returns `true` if `v1 < v2`. See |vim.version.cmp()| for usage. Returns `true` if `v1 < v2`. See |vim.version.cmp()| for usage.
Parameters: ~ Parameters: ~
• {v1} (`Version|number[]|string`) • {v1} (`vim.Version|number[]|string`)
• {v2} (`Version|number[]|string`) • {v2} (`vim.Version|number[]|string`)
Return: ~ Return: ~
(`boolean`) (`boolean`)
@@ -3710,7 +3729,7 @@ vim.version.parse({version}, {opts}) *vim.version.parse()*
"1.0", "0-x", "tmux 3.2a" into valid versions. "1.0", "0-x", "tmux 3.2a" into valid versions.
Return: ~ Return: ~
(`Version?`) parsed_version Version object or `nil` if input is (`vim.Version?`) parsed_version Version object or `nil` if input is
invalid. invalid.
See also: ~ See also: ~
@@ -3744,6 +3763,12 @@ vim.version.range({spec}) *vim.version.range()*
Parameters: ~ Parameters: ~
• {spec} (`string`) Version range "spec" • {spec} (`string`) Version range "spec"
Return: ~
(`table`) A table with the following fields:
• {from} (`vim.Version`)
• {to}? (`vim.Version`)
• {has} (`fun(self: vim.VersionRangeversion: string|vim.Version)`)
See also: ~ See also: ~
• https://github.com/npm/node-semver#ranges • https://github.com/npm/node-semver#ranges
@@ -4380,15 +4405,15 @@ tohtml.tohtml({winid}, {opt}) *tohtml.tohtml.tohtml()*
Parameters: ~ Parameters: ~
• {winid} (`integer?`) Window to convert (defaults to current window) • {winid} (`integer?`) Window to convert (defaults to current window)
• {opt} (`table?`) Optional parameters. • {opt} (`table?`) Optional parameters.
• title (string): Title tag to set in the generated HTML code {title}? (`string|false`, default: buffer name) Title tag
(defaults to buffer name) to set in the generated HTML code.
• number_lines (boolean): Show line numbers (defaults to {number_lines}? (`boolean`, default: `false`) Show line
`false`) numbers.
• font (string|string[]): Fonts to use (defaults to {font}? (`string[]|string`, default: `guifont`) Fonts to
`guifont`) use.
• width (integer) Width used for items which are either right {width}? (`integer`, default: 'textwidth' if non-zero or
aligned or repeat a character infinitely (defaults to window width otherwise) Width used for items which are
'textwidth' if non-zero or window width otherwise) either right aligned or repeat a character infinitely.
Return: ~ Return: ~
(`string[]`) (`string[]`)

View File

@@ -732,16 +732,16 @@ get_node({opts}) *vim.treesitter.get_node()*
< <
Parameters: ~ Parameters: ~
• {opts} (`vim.treesitter.GetNodeOpts?`) Optional keyword arguments: • {opts} (`table?`) Optional keyword arguments:
• bufnr integer|nil Buffer number (nil or 0 for current {bufnr} (`integer?`) Buffer number (nil or 0 for current
buffer) buffer)
• pos table|nil 0-indexed (row, col) tuple. Defaults to cursor {pos} (`{ [1]: integer, [2]: integer }?`) 0-indexed (row,
position in the current window. Required if {bufnr} is not col) tuple. Defaults to cursor position in the current
the current buffer window. Required if {bufnr} is not the current buffer
• lang string|nil Parser language. (default: from buffer {lang} (`string?`) Parser language. (default: from buffer
filetype) filetype)
• ignore_injections boolean Ignore injected languages (default {ignore_injections} (`boolean?`) Ignore injected languages
true) (default true)
Return: ~ Return: ~
(`TSNode?`) Node at the given position (`TSNode?`) Node at the given position
@@ -787,7 +787,7 @@ get_parser({bufnr}, {lang}, {opts}) *vim.treesitter.get_parser()*
• {opts} (`table?`) Options to pass to the created language tree • {opts} (`table?`) Options to pass to the created language tree
Return: ~ Return: ~
(`LanguageTree`) object to use for parsing (`vim.treesitter.LanguageTree`) object to use for parsing
get_range({node}, {source}, {metadata}) *vim.treesitter.get_range()* get_range({node}, {source}, {metadata}) *vim.treesitter.get_range()*
Get the range of a |TSNode|. Can also supply {source} and {metadata} to Get the range of a |TSNode|. Can also supply {source} and {metadata} to
@@ -797,7 +797,7 @@ get_range({node}, {source}, {metadata}) *vim.treesitter.get_range()*
• {node} (`TSNode`) • {node} (`TSNode`)
• {source} (`integer|string?`) Buffer or string from which the {node} • {source} (`integer|string?`) Buffer or string from which the {node}
is extracted is extracted
• {metadata} (`TSMetadata?`) • {metadata} (`vim.treesitter.query.TSMetadata?`)
Return: ~ Return: ~
(`Range6`) (`Range6`)
@@ -812,7 +812,7 @@ get_string_parser({str}, {lang}, {opts})
• {opts} (`table?`) Options to pass to the created language tree • {opts} (`table?`) Options to pass to the created language tree
Return: ~ Return: ~
(`LanguageTree`) object to use for parsing (`vim.treesitter.LanguageTree`) object to use for parsing
inspect_tree({opts}) *vim.treesitter.inspect_tree()* inspect_tree({opts}) *vim.treesitter.inspect_tree()*
Open a window that displays a textual representation of the nodes in the Open a window that displays a textual representation of the nodes in the
@@ -917,10 +917,10 @@ add({lang}, {opts}) *vim.treesitter.language.add()*
Parameters: ~ Parameters: ~
• {lang} (`string`) Name of the parser (alphanumerical and `_` only) • {lang} (`string`) Name of the parser (alphanumerical and `_` only)
• {opts} (`table?`) Options: • {opts} (`table?`) Options:
• filetype (string|string[]) Default filetype the parser {filetype}? (`string|string[]`, default: {lang}) Default
should be associated with. Defaults to {lang}. filetype the parser should be associated with.
• path (string|nil) Optional path the parser is located at {path}? (`string`) Optional path the parser is located at
• symbol_name (string|nil) Internal symbol name for the {symbol_name}? (`string`) Internal symbol name for the
language to load language to load
get_filetypes({lang}) *vim.treesitter.language.get_filetypes()* get_filetypes({lang}) *vim.treesitter.language.get_filetypes()*
@@ -1069,10 +1069,10 @@ lint({buf}, {opts}) *vim.treesitter.query.lint()*
Parameters: ~ Parameters: ~
• {buf} (`integer`) Buffer handle • {buf} (`integer`) Buffer handle
• {opts} (`table?`) Optional keyword arguments: • {opts} (`table?`) Optional keyword arguments:
• langs (string|string[]|nil) Language(s) to use for checking {langs}? (`string|string[]`) Language(s) to use for checking
the query. If multiple languages are specified, queries are the query. If multiple languages are specified, queries are
validated for all of them validated for all of them
• clear (boolean) if `true`, just clear current lint errors {clear} (`boolean`) Just clear current lint errors
list_directives() *vim.treesitter.query.list_directives()* list_directives() *vim.treesitter.query.list_directives()*
Lists the currently available directives to use in queries. Lists the currently available directives to use in queries.
@@ -1153,8 +1153,8 @@ Query:iter_captures({node}, {source}, {start}, {stop})
Defaults to `node:end_()`. Defaults to `node:end_()`.
Return: ~ Return: ~
(`fun(end_line: integer?): integer, TSNode, TSMetadata`) capture id, (`fun(end_line: integer?): integer, TSNode,
capture node, metadata vim.treesitter.query.TSMetadata`) capture id, capture node, metadata
*Query:iter_matches()* *Query:iter_matches()*
Query:iter_matches({node}, {source}, {start}, {stop}, {opts}) Query:iter_matches({node}, {source}, {start}, {stop}, {opts})
@@ -1279,7 +1279,7 @@ LanguageTree:for_each_tree({fn}) *LanguageTree:for_each_tree()*
Note: This includes the invoking tree's child trees as well. Note: This includes the invoking tree's child trees as well.
Parameters: ~ Parameters: ~
• {fn} (`fun(tree: TSTree, ltree: LanguageTree)`) • {fn} (`fun(tree: TSTree, ltree: vim.treesitter.LanguageTree)`)
LanguageTree:included_regions() *LanguageTree:included_regions()* LanguageTree:included_regions() *LanguageTree:included_regions()*
Gets the set of included regions managed by this LanguageTree. This can be Gets the set of included regions managed by this LanguageTree. This can be
@@ -1318,7 +1318,7 @@ LanguageTree:language_for_range({range})
• {range} (`Range4`) `{ start_line, start_col, end_line, end_col }` • {range} (`Range4`) `{ start_line, start_col, end_line, end_col }`
Return: ~ Return: ~
(`LanguageTree`) Managing {range} (`vim.treesitter.LanguageTree`) Managing {range}
*LanguageTree:named_node_for_range()* *LanguageTree:named_node_for_range()*
LanguageTree:named_node_for_range({range}, {opts}) LanguageTree:named_node_for_range({range}, {opts})

View File

@@ -25,13 +25,7 @@
-- Remarks: -- Remarks:
-- - Not all visuals are supported, so it may differ. -- - Not all visuals are supported, so it may differ.
--- @class vim.tohtml.opt --- @class (private) vim.tohtml.state.global
--- @field title? string|false
--- @field number_lines? boolean
--- @field font? string[]|string
--- @field width? integer
--- @class vim.tohtml.state.global
--- @field background string --- @field background string
--- @field foreground string --- @field foreground string
--- @field title string|false --- @field title string|false
@@ -39,7 +33,7 @@
--- @field highlights_name table<integer,string> --- @field highlights_name table<integer,string>
--- @field conf vim.tohtml.opt --- @field conf vim.tohtml.opt
--- @class vim.tohtml.state:vim.tohtml.state.global --- @class (private) vim.tohtml.state:vim.tohtml.state.global
--- @field style vim.tohtml.styletable --- @field style vim.tohtml.styletable
--- @field tabstop string|false --- @field tabstop string|false
--- @field opt vim.wo --- @field opt vim.wo
@@ -48,20 +42,20 @@
--- @field width integer --- @field width integer
--- @field buflen integer --- @field buflen integer
--- @class vim.tohtml.styletable --- @class (private) vim.tohtml.styletable
--- @field [integer] vim.tohtml.line (integer: (1-index, exclusive)) --- @field [integer] vim.tohtml.line (integer: (1-index, exclusive))
--- @class vim.tohtml.line --- @class (private) vim.tohtml.line
--- @field virt_lines {[integer]:{[1]:string,[2]:integer}[]} --- @field virt_lines {[integer]:{[1]:string,[2]:integer}[]}
--- @field pre_text string[][] --- @field pre_text string[][]
--- @field hide? boolean --- @field hide? boolean
--- @field [integer] vim.tohtml.cell? (integer: (1-index, exclusive)) --- @field [integer] vim.tohtml.cell? (integer: (1-index, exclusive))
--- @class vim.tohtml.cell --- @class (private) vim.tohtml.cell
--- @field [1] integer[] start --- @field [1] integer[] start
--- @field [2] integer[] close --- @field [2] integer[] close
--- @field [3] any[][] virt_text --- @field [3] any[][] virt_text
--- @field [4] any[][] overlay_text --- @field [4] any[][] overlay_text
local HIDE_ID = -1 local HIDE_ID = -1
-- stylua: ignore start -- stylua: ignore start
@@ -1319,14 +1313,29 @@ end
local M = {} local M = {}
--- @class vim.tohtml.opt
--- @inlinedoc
---
--- Title tag to set in the generated HTML code.
--- (default: buffer name)
--- @field title? string|false
---
--- Show line numbers.
--- (default: `false`)
--- @field number_lines? boolean
---
--- Fonts to use.
--- (default: `guifont`)
--- @field font? string[]|string
---
--- Width used for items which are either right aligned or repeat a character
--- infinitely.
--- (default: 'textwidth' if non-zero or window width otherwise)
--- @field width? integer
--- Converts the buffer shown in the window {winid} to HTML and returns the output as a list of string. --- Converts the buffer shown in the window {winid} to HTML and returns the output as a list of string.
--- @param winid? integer Window to convert (defaults to current window) --- @param winid? integer Window to convert (defaults to current window)
--- @param opt? vim.tohtml.opt (table) Optional parameters. --- @param opt? vim.tohtml.opt Optional parameters.
--- - title (string): Title tag to set in the generated HTML code (defaults to buffer name)
--- - number_lines (boolean): Show line numbers (defaults to `false`)
--- - font (string|string[]): Fonts to use (defaults to `guifont`)
--- - width (integer) Width used for items which are either right aligned or repeat a character infinitely
--- (defaults to 'textwidth' if non-zero or window width otherwise)
--- @return string[] --- @return string[]
function M.tohtml(winid, opt) function M.tohtml(winid, opt)
return win_to_html(winid or 0, opt) return win_to_html(winid or 0, opt)

View File

@@ -190,6 +190,7 @@ function vim._os_proc_children(ppid)
return children return children
end end
--- @nodoc
--- @class vim.inspect.Opts --- @class vim.inspect.Opts
--- @field depth? integer --- @field depth? integer
--- @field newline? string --- @field newline? string
@@ -454,7 +455,7 @@ vim.cmd = setmetatable({}, {
end, end,
}) })
--- @class vim.var_accessor --- @class (private) vim.var_accessor
--- @field [string] any --- @field [string] any
--- @field [integer] vim.var_accessor --- @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), -- 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). -- show warnings since 0.11, including 0.11-dev (hard_deprecated_since = 0.11-dev).
if plugin == 'Nvim' then 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 removal_version = assert(vim.version.parse(version))
local is_hard_deprecated ---@type boolean local is_hard_deprecated ---@type boolean

View File

@@ -1,8 +1,18 @@
---@class InspectorFilter --- @class vim._inspector.Filter
---@field syntax boolean include syntax based highlight groups (defaults to true) --- @inlinedoc
---@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) --- Include syntax based highlight groups (defaults to true)
---@field semantic_tokens boolean include semantic token highlights (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 = { local defaults = {
syntax = true, syntax = true,
treesitter = true, treesitter = true,
@@ -17,11 +27,7 @@ local defaults = {
---@param bufnr? integer defaults to the current buffer ---@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 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 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 ---@param filter? vim._inspector.Filter 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)
---@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": ---@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 --- - treesitter: a list of treesitter captures
--- - syntax: a list of syntax groups --- - syntax: a list of syntax groups
@@ -139,7 +145,7 @@ end
---@param bufnr? integer defaults to the current buffer ---@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 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 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) function vim.show_pos(bufnr, row, col, filter)
local items = vim.inspect_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> --- </pre>
---@nodoc
---@class vim.NIL ---@class vim.NIL
---@type vim.NIL ---@type vim.NIL

View File

@@ -21,6 +21,7 @@ error('Cannot require a meta file')
vim.lpeg = {} vim.lpeg = {}
--- @nodoc
--- @class vim.lpeg.Pattern --- @class vim.lpeg.Pattern
--- @operator unm: vim.lpeg.Pattern --- @operator unm: vim.lpeg.Pattern
--- @operator add(vim.lpeg.Pattern): 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 --- @return vim.lpeg.Pattern
function vim.lpeg.V(v) end function vim.lpeg.V(v) end
--- @nodoc
--- @class vim.lpeg.Locale --- @class vim.lpeg.Locale
--- @field alnum userdata --- @field alnum userdata
--- @field alpha userdata --- @field alpha userdata

View File

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

View File

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

View File

@@ -2,18 +2,44 @@ local api, if_nil = vim.api, vim.F.if_nil
local M = {} 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 --- @class vim.Diagnostic
---
--- Buffer number
--- @field bufnr? integer --- @field bufnr? integer
--- @field lnum integer 0-indexed ---
--- @field end_lnum? integer 0-indexed --- The starting line of the diagnostic (0-indexed)
--- @field col integer 0-indexed --- @field lnum integer
--- @field end_col? integer 0-indexed ---
--- 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 --- @field severity? vim.diagnostic.Severity
---
--- The diagnostic text
--- @field message string --- @field message string
---
--- The source of the diagnostic
--- @field source? string --- @field source? string
---
--- The diagnostic code
--- @field code? string|integer --- @field code? string|integer
---
--- @field _tags? { deprecated: boolean, unnecessary: boolean} --- @field _tags? { deprecated: boolean, unnecessary: boolean}
---
--- Arbitrary data plugins or users can add
--- @field user_data? any arbitrary data plugins can add --- @field user_data? any arbitrary data plugins can add
---
--- @field namespace? integer --- @field namespace? integer
--- @class vim.diagnostic.Opts --- @class vim.diagnostic.Opts
@@ -104,7 +130,7 @@ local global_diagnostic_options = {
severity_sort = false, 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 show? fun(namespace: integer, bufnr: integer, diagnostics: vim.Diagnostic[], opts?: vim.diagnostic.OptsResolved)
--- @field hide? fun(namespace:integer, bufnr:integer) --- @field hide? fun(namespace:integer, bufnr:integer)
@@ -154,7 +180,7 @@ do
}) })
end end
--- @class vim.diagnostic._extmark --- @class (private) vim.diagnostic._extmark
--- @field [1] integer id --- @field [1] integer id
--- @field [2] integer start --- @field [2] integer start
--- @field [3] integer end --- @field [3] integer end
@@ -1018,31 +1044,52 @@ function M.get_next_pos(opts)
return { next.lnum, next.col } return { next.lnum, next.col }
end end
--- A table with the following keys:
--- @class vim.diagnostic.GetOpts --- @class vim.diagnostic.GetOpts
--- @inlinedoc
---
--- Limit diagnostics to the given namespace.
--- @field namespace? integer --- @field namespace? integer
---
--- Limit diagnostics to the given line number.
--- @field lnum? integer --- @field lnum? integer
---
--- See |diagnostic-severity|.
--- @field severity? vim.diagnostic.SeverityFilter --- @field severity? vim.diagnostic.SeverityFilter
--- Configuration table with the following keys:
--- @class vim.diagnostic.GotoOpts : vim.diagnostic.GetOpts --- @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} --- @field cursor_position? {[1]:integer,[2]:integer}
---
--- Whether to loop around file or not. Similar to 'wrapscan'.
--- (default: `true`)
--- @field wrap? boolean --- @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 --- @field float? boolean|vim.diagnostic.Opts.Float
---
--- Window ID
--- (default: `0`)
--- @field win_id? integer --- @field win_id? integer
--- Move to the next diagnostic. --- Move to the next diagnostic.
--- ---
---@param opts? vim.diagnostic.GotoOpts (table) Configuration table with the following keys: ---@param opts? vim.diagnostic.GotoOpts
--- - 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
function M.goto_next(opts) function M.goto_next(opts)
diagnostic_move_pos(opts, M.get_next_pos(opts)) diagnostic_move_pos(opts, M.get_next_pos(opts))
end end
@@ -1789,38 +1836,54 @@ function M.reset(namespace, bufnr)
end end
end end
--- Configuration table with the following keys:
--- @class vim.diagnostic.setqflist.Opts --- @class vim.diagnostic.setqflist.Opts
--- @inlinedoc
---
--- Only add diagnostics from the given namespace.
--- @field namespace? integer --- @field namespace? integer
---
--- Open quickfix list after setting.
--- (default: `true`)
--- @field open? boolean --- @field open? boolean
---
--- Title of quickfix list. Defaults to "Diagnostics".
--- @field title? string --- @field title? string
---
--- See |diagnostic-severity|.
--- @field severity? vim.diagnostic.Severity --- @field severity? vim.diagnostic.Severity
--- Add all diagnostics to the quickfix list. --- Add all diagnostics to the quickfix list.
--- ---
---@param opts? vim.diagnostic.setqflist.Opts (table) Configuration table with the following keys: ---@param opts? vim.diagnostic.setqflist.Opts
--- - 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|.
function M.setqflist(opts) function M.setqflist(opts)
set_list(false, opts) set_list(false, opts)
end end
---Configuration table with the following keys:
--- @class vim.diagnostic.setloclist.Opts --- @class vim.diagnostic.setloclist.Opts
--- @inlinedoc
---
--- Only add diagnostics from the given namespace.
--- @field namespace? integer --- @field namespace? integer
--- @field open? boolean ---
--- @field title? string --- Window number to set location list for.
--- @field severity? vim.diagnostic.Severity --- (default: `0`)
--- @field winnr? integer --- @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. --- Add buffer diagnostics to the location list.
--- ---
---@param opts? vim.diagnostic.setloclist.Opts (table) Configuration table with the following keys: ---@param opts? vim.diagnostic.setloclist.Opts
--- - 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|.
function M.setloclist(opts) function M.setloclist(opts)
set_list(true, opts) set_list(true, opts)
end end

View File

@@ -2082,6 +2082,7 @@ local function normalize_path(path, as_pattern)
end end
--- @class vim.filetype.add.filetypes --- @class vim.filetype.add.filetypes
--- @inlinedoc
--- @field pattern? vim.filetype.mapping --- @field pattern? vim.filetype.mapping
--- @field extension? vim.filetype.mapping --- @field extension? vim.filetype.mapping
--- @field filename? 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) function M.add(filetypes)
for k, v in pairs(filetypes.extension or {}) do for k, v in pairs(filetypes.extension or {}) do
extension[k] = v extension[k] = v
@@ -2272,8 +2273,23 @@ local function match_pattern(name, path, tail, pat)
end end
--- @class vim.filetype.match.args --- @class vim.filetype.match.args
--- @inlinedoc
---
--- Buffer number to use for matching. Mutually exclusive with {contents}
--- @field buf? integer --- @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 --- @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[] --- @field contents? string[]
--- Perform filetype detection. --- Perform filetype detection.
@@ -2305,20 +2321,8 @@ end
--- vim.filetype.match({ contents = {'#!/usr/bin/env bash'} }) --- 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: --- 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 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 ---@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 --- filetype specific buffer variables). The function accepts a buffer number as

View File

@@ -147,11 +147,29 @@ function M.dir(path, opts)
end) end)
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 --- @field path string
---
--- Search upward through parent directories.
--- Otherwise, search through child directories (recursively).
--- (default: `false`)
--- @field upward boolean --- @field upward boolean
---
--- Stop searching when this directory is reached.
--- The directory itself is not searched.
--- @field stop string --- @field stop string
---
--- Find only items of the given type.
--- If omitted, all items that match {names} are included.
--- @field type string --- @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 --- @field limit number
--- Find files or directories (or other items as specified by `opts.type`) in the given path. --- 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 --- - path: full path of the current item
--- The function should return `true` if the given item is considered a match. --- The function should return `true` if the given item is considered a match.
--- ---
---@param opts (table) Optional keyword arguments: ---@param opts vim.fs.find.Opts 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.
---@return (string[]) # Normalized paths |vim.fs.normalize()| of all matching items ---@return (string[]) # Normalized paths |vim.fs.normalize()| of all matching items
function M.find(names, opts) function M.find(names, opts)
opts = opts or {} --[[@as vim.fs.find.opts]] opts = opts or {}
vim.validate({ vim.validate({
names = { names, { 's', 't', 'f' } }, names = { names, { 's', 't', 'f' } },
path = { opts.path, 's', true }, path = { opts.path, 's', true },
@@ -318,6 +323,13 @@ function M.find(names, opts)
return matches return matches
end 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 --- 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 --- beginning of the path is expanded to the user's home directory and any
--- backslash (\) characters are converted to forward slashes (/). Environment --- backslash (\) characters are converted to forward slashes (/). Environment
@@ -337,9 +349,8 @@ end
--- ``` --- ```
--- ---
---@param path (string) Path to normalize ---@param path (string) Path to normalize
---@param opts table|nil Options: ---@param opts? vim.fs.normalize.Opts
--- - expand_env: boolean Expand environment variables (default: true) ---@return (string) : Normalized path
---@return (string) Normalized path
function M.normalize(path, opts) function M.normalize(path, opts)
opts = opts or {} opts = opts or {}

View File

@@ -64,11 +64,13 @@
--- In addition to the |vim.iter()| function, the |vim.iter| module provides --- In addition to the |vim.iter()| function, the |vim.iter| module provides
--- convenience functions like |vim.iter.filter()| and |vim.iter.totable()|. --- convenience functions like |vim.iter.filter()| and |vim.iter.totable()|.
---@nodoc
---@class IterMod ---@class IterMod
---@operator call:Iter ---@operator call:Iter
local M = {} local M = {}
---@nodoc
---@class Iter ---@class Iter
local Iter = {} local Iter = {}
Iter.__index = Iter Iter.__index = Iter
@@ -77,6 +79,7 @@ Iter.__call = function(self)
end end
--- Special case implementations for iterators on list tables. --- Special case implementations for iterators on list tables.
---@nodoc
---@class ListIter : Iter ---@class ListIter : Iter
---@field _table table Underlying table data ---@field _table table Underlying table data
---@field _head number Index to the front of a table iterator ---@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 CacheHash {mtime: {nsec: integer, sec: integer}, size: integer, type?: uv.aliases.fs_stat_types}
---@alias CacheEntry {hash:CacheHash, chunk:string} ---@alias CacheEntry {hash:CacheHash, chunk:string}
---@class ModuleFindOpts --- @class vim.loader.find.Opts
---@field all? boolean Search for all matches (defaults to `false`) --- @inlinedoc
---@field rtp? boolean Search for modname in the runtime path (defaults to `true`) ---
---@field patterns? string[] Patterns to use (defaults to `{"/init.lua", ".lua"}`) --- Search for modname in the runtime path.
---@field paths? string[] Extra paths to search for modname --- (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 --- @class vim.loader.ModuleInfo
---@field modpath string Path of the module --- @inlinedoc
---@field modname string Name of the module ---
---@field stat? uv.uv_fs_t File stat of the module path --- 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?}?> ---@alias LoaderStats table<string, {total:number, time:number, [string]:number?}?>
@@ -29,14 +50,14 @@ M.path = vim.fn.stdpath('cache') .. '/luac'
---@nodoc ---@nodoc
M.enabled = false M.enabled = false
---@class Loader ---@class (private) Loader
---@field _rtp string[] ---@field private _rtp string[]
---@field _rtp_pure string[] ---@field private _rtp_pure string[]
---@field _rtp_key string ---@field private _rtp_key string
---@field _hashes? table<string, CacheHash> ---@field private _hashes? table<string, CacheHash>
local Loader = { local Loader = {
VERSION = 4, VERSION = 4,
---@type table<string, table<string,ModuleInfo>> ---@type table<string, table<string,vim.loader.ModuleInfo>>
_indexed = {}, _indexed = {},
---@type table<string, string[]> ---@type table<string, string[]>
_topmods = {}, _topmods = {},
@@ -270,17 +291,8 @@ end
--- Finds Lua modules for the given module name. --- Finds Lua modules for the given module name.
---@param modname string Module name, or `"*"` to find the top-level modules instead ---@param modname string Module name, or `"*"` to find the top-level modules instead
---@param opts? ModuleFindOpts (table) Options for finding a module: ---@param opts? vim.loader.find.Opts Options for finding a module:
--- - rtp: (boolean) Search for modname in the runtime path (defaults to `true`) ---@return vim.loader.ModuleInfo[]
--- - 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="*"`
function M.find(modname, opts) function M.find(modname, opts)
opts = opts or {} opts = opts or {}
@@ -306,7 +318,7 @@ function M.find(modname, opts)
patterns[p] = '/lua/' .. basename .. pattern patterns[p] = '/lua/' .. basename .. pattern
end end
---@type ModuleInfo[] ---@type vim.loader.ModuleInfo[]
local results = {} local results = {}
-- Only continue if we haven't found anything yet or we want to find all -- 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
end end
---@class ProfileOpts ---@class (private) vim.loader._profile.Opts
---@field loaders? boolean Add profiling to the loaders ---@field loaders? boolean Add profiling to the loaders
--- Debug function that wraps all loaders and tracks stats --- Debug function that wraps all loaders and tracks stats
---@private ---@private
---@param opts ProfileOpts? ---@param opts vim.loader._profile.Opts?
function M._profile(opts) function M._profile(opts)
Loader.get_rtp = Loader.track('get_rtp', Loader.get_rtp) Loader.get_rtp = Loader.track('get_rtp', Loader.get_rtp)
Loader.read = Loader.track('read', Loader.read) Loader.read = Loader.track('read', Loader.read)

View File

@@ -108,12 +108,12 @@ function lsp._buf_get_line_ending(bufnr)
end end
-- Tracks all clients created via lsp.start_client -- 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 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 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) local function for_each_buffer_client(bufnr, fn, restrict_client_ids)
validate({ validate({
fn = { fn, 'f' }, fn = { fn, 'f' },
@@ -200,105 +200,15 @@ local function once(fn)
end end
end end
-- FIXME: DOC: Shouldn't need to use a dummy function --- @class vim.lsp.start.Opts
-- --- @inlinedoc
--- LSP client object. You can get an active client object via
--- |vim.lsp.get_client_by_id()| or |vim.lsp.get_clients()|.
--- ---
--- - Methods: --- Predicate used to decide if a client should be re-used. Used on all
--- - request(method, params, [handler], bufnr) --- running clients. The default implementation re-uses a client if name and
--- Sends a request to the server. --- root_dir matches.
--- This is a thin wrapper around {client.rpc.request} with some additional --- @field reuse_client fun(client: vim.lsp.Client, config: table): boolean
--- 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.
--- ---
--- - request_sync(method, params, timeout_ms, bufnr) --- Buffer handle to attach to if starting or re-using a client (0 for current).
--- 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
--- @field bufnr integer --- @field bufnr integer
--- Create a new LSP client and start a language server or reuses an already --- 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 --- Either use |:au|, |nvim_create_autocmd()| or put the call in a
--- `ftplugin/<filetype_name>.lua` (See |ftplugin-name|) --- `ftplugin/<filetype_name>.lua` (See |ftplugin-name|)
--- ---
---@param config lsp.ClientConfig Same configuration as documented in |vim.lsp.start_client()| --- @param config vim.lsp.ClientConfig Configuration for the server.
---@param opts lsp.StartOpts? Optional keyword arguments: --- @param opts vim.lsp.start.Opts? Optional keyword arguments
--- - reuse_client (fun(client: client, config: table): boolean) --- @return integer? client_id
--- 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
function lsp.start(config, opts) function lsp.start(config, opts)
opts = opts or {} opts = opts or {}
local reuse_client = opts.reuse_client local reuse_client = opts.reuse_client
@@ -428,7 +330,7 @@ local function is_empty_or_default(bufnr, option)
end end
---@private ---@private
---@param client lsp.Client ---@param client vim.lsp.Client
---@param bufnr integer ---@param bufnr integer
function lsp._set_defaults(client, bufnr) function lsp._set_defaults(client, bufnr)
if if
@@ -482,7 +384,7 @@ local function reset_defaults(bufnr)
end) end)
end end
--- @param client lsp.Client --- @param client vim.lsp.Client
local function on_client_init(client) local function on_client_init(client)
local id = client.id local id = client.id
uninitialized_clients[id] = nil uninitialized_clients[id] = nil
@@ -552,121 +454,9 @@ local function on_client_exit(code, signal, client_id)
end) end)
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. --- Starts and initializes a client with the given configuration.
--- --- @param config vim.lsp.ClientConfig Configuration for the server.
--- Field `cmd` in {config} is required. --- @return integer|nil client_id |vim.lsp.get_client_by_id()| Note: client may not be
---
---@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
--- fully initialized. Use `on_init` to do any actions once --- fully initialized. Use `on_init` to do any actions once
--- the client has been initialized. --- the client has been initialized.
function lsp.start_client(config) function lsp.start_client(config)
@@ -927,7 +717,7 @@ end
--- ---
---@param client_id integer client id ---@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) function lsp.get_client_by_id(client_id)
return active_clients[client_id] or uninitialized_clients[client_id] return active_clients[client_id] or uninitialized_clients[client_id]
end end
@@ -943,7 +733,7 @@ end
--- Stops a client(s). --- 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: --- To stop all clients:
--- ---
--- ```lua --- ```lua
@@ -953,7 +743,7 @@ end
--- By default asks the server to shutdown, unless stop was requested --- By default asks the server to shutdown, unless stop was requested
--- already for this client, then force-shutdown is attempted. --- 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 ---@param force boolean|nil shutdown forcefully
function lsp.stop_client(client_id, force) function lsp.stop_client(client_id, force)
local ids = type(client_id) == 'table' and client_id or { client_id } 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
end end
---@class vim.lsp.get_clients.filter --- Key-value pairs used to filter the returned clients.
---@field id integer|nil Match clients by id --- @class vim.lsp.get_clients.Filter
---@field bufnr integer|nil match clients attached to the given buffer --- @inlinedoc
---@field name string|nil match clients by name ---
---@field method string|nil match client by supported method name --- 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. --- Get active clients.
--- ---
---@param filter vim.lsp.get_clients.filter|nil (table|nil) A table with ---@param filter? vim.lsp.get_clients.Filter
--- key-value pairs used to filter the returned clients. ---@return vim.lsp.Client[]: List of |vim.lsp.Client| objects
--- 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
function lsp.get_clients(filter) function lsp.get_clients(filter)
validate({ filter = { filter, 't', true } }) validate({ filter = { filter, 't', true } })
filter = filter or {} 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 {}) local t = filter.bufnr and (all_buffer_active_clients[resolve_bufnr(filter.bufnr)] or {})
or active_clients or active_clients
@@ -1233,15 +1027,20 @@ function lsp.omnifunc(findstart, base)
return vim.lsp._completion.omnifunc(findstart, base) return vim.lsp._completion.omnifunc(findstart, base)
end 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. --- Provides an interface between the built-in client and a `formatexpr` function.
--- ---
--- Currently only supports a single client. This can be set via --- 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` --- `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})'`. --- 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 ---@param opts? vim.lsp.formatexpr.Opts
--- following optional keys:
--- * timeout_ms (default 500ms). The timeout period for the formatting request.
function lsp.formatexpr(opts) function lsp.formatexpr(opts)
opts = opts or {} opts = opts or {}
local timeout_ms = opts.timeout_ms or 500 local timeout_ms = opts.timeout_ms or 500
@@ -1313,14 +1112,14 @@ function lsp.client_is_stopped(client_id)
end end
--- Gets a map of client_id:client pairs for the given buffer, where each value --- 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 ---@param bufnr (integer|nil): Buffer handle, or 0 for current
---@return table result is table of (client_id, client) pairs ---@return table result is table of (client_id, client) pairs
---@deprecated Use |vim.lsp.get_clients()| instead. ---@deprecated Use |vim.lsp.get_clients()| instead.
function lsp.buf_get_clients(bufnr) function lsp.buf_get_clients(bufnr)
vim.deprecate('vim.lsp.buf_get_clients()', 'vim.lsp.get_clients()', '0.12') 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 for _, client in ipairs(lsp.get_clients({ bufnr = resolve_bufnr(bufnr) })) do
result[client.id] = client result[client.id] = client
end end

View File

@@ -61,7 +61,7 @@ local state_by_group = setmetatable({}, {
end, end,
}) })
---@param client lsp.Client ---@param client vim.lsp.Client
---@return vim.lsp.CTGroup ---@return vim.lsp.CTGroup
local function get_group(client) local function get_group(client)
local allow_inc_sync = vim.F.if_nil(client.flags.allow_incremental_sync, true) --- @type boolean 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 return incremental_change
end end
---@param client lsp.Client ---@param client vim.lsp.Client
---@param bufnr integer ---@param bufnr integer
function M.init(client, bufnr) function M.init(client, bufnr)
assert(client.offset_encoding, 'lsp client must have an offset_encoding') assert(client.offset_encoding, 'lsp client must have an offset_encoding')
@@ -165,7 +165,7 @@ function M.init(client, bufnr)
end end
end end
--- @param client lsp.Client --- @param client vim.lsp.Client
--- @param bufnr integer --- @param bufnr integer
--- @param name string --- @param name string
--- @return string --- @return string
@@ -189,7 +189,7 @@ local function reset_timer(buf_state)
end end
end end
--- @param client lsp.Client --- @param client vim.lsp.Client
--- @param bufnr integer --- @param bufnr integer
function M.reset_buf(client, bufnr) function M.reset_buf(client, bufnr)
M.flush(client, bufnr) M.flush(client, bufnr)
@@ -207,7 +207,7 @@ function M.reset_buf(client, bufnr)
end end
end end
--- @param client lsp.Client --- @param client vim.lsp.Client
function M.reset(client) function M.reset(client)
local state = state_by_group[get_group(client)] local state = state_by_group[get_group(client)]
if not state then if not state then
@@ -350,7 +350,7 @@ function M.send_changes(bufnr, firstline, lastline, new_lastline)
end end
--- Flushes any outstanding change notification. --- Flushes any outstanding change notification.
---@param client lsp.Client ---@param client vim.lsp.Client
---@param bufnr? integer ---@param bufnr? integer
function M.flush(client, bufnr) function M.flush(client, bufnr)
local group = get_group(client) local group = get_group(client)

View File

@@ -11,7 +11,7 @@ local M = {}
--- ---
---@param method (string) LSP method name ---@param method (string) LSP method name
---@param params (table|nil) Parameters to send to the server ---@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 ---@return table<integer, integer> client_request_ids Map of client-id:request-id pairs
---for all successful requests. ---for all successful requests.
@@ -31,7 +31,7 @@ end
--- Checks whether the language servers attached to the current buffer are --- Checks whether the language servers attached to the current buffer are
--- ready. --- ready.
--- ---
---@return boolean if server responds. ---@return boolean : if server responds.
---@deprecated ---@deprecated
function M.server_ready() function M.server_ready()
vim.deprecate('vim.lsp.buf.server_ready()', nil, '0.10') 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) request(name, params, req_handler)
end end
--- Jumps to the declaration of the symbol under the cursor. --- @class vim.lsp.ListOpts
---@note Many servers do not implement this method. Generally, see |vim.lsp.buf.definition()| instead.
--- ---
---@param options table|nil additional options --- list-handler replacing the default handler.
--- - reuse_win: (boolean) Jump to existing window if buffer is already open. --- Called for any non-empty result.
--- - on_list: (function) |lsp-on-list-handler| replacing the default handler. --- This table can be used with |setqflist()| or |setloclist()|. E.g.:
--- Called for any non-empty result. --- ```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) function M.declaration(options)
local params = util.make_position_params() local params = util.make_position_params()
request_with_options(ms.textDocument_declaration, params, options) request_with_options(ms.textDocument_declaration, params, options)
end end
--- Jumps to the definition of the symbol under the cursor. --- Jumps to the definition of the symbol under the cursor.
--- --- @param options? vim.lsp.LocationOpts
---@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.
function M.definition(options) function M.definition(options)
local params = util.make_position_params() local params = util.make_position_params()
request_with_options(ms.textDocument_definition, params, options) request_with_options(ms.textDocument_definition, params, options)
end end
--- Jumps to the definition of the type of the symbol under the cursor. --- Jumps to the definition of the type of the symbol under the cursor.
--- --- @param options? vim.lsp.LocationOpts
---@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.
function M.type_definition(options) function M.type_definition(options)
local params = util.make_position_params() local params = util.make_position_params()
request_with_options(ms.textDocument_typeDefinition, params, options) 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 --- Lists all the implementations for the symbol under the cursor in the
--- quickfix window. --- quickfix window.
--- --- @param options? vim.lsp.LocationOpts
---@param options table|nil additional options
--- - on_list: (function) |lsp-on-list-handler| replacing the default handler.
--- Called for any non-empty result.
function M.implementation(options) function M.implementation(options)
local params = util.make_position_params() local params = util.make_position_params()
request_with_options(ms.textDocument_implementation, params, options) request_with_options(ms.textDocument_implementation, params, options)
@@ -156,45 +175,55 @@ local function range_from_selection(bufnr, mode)
} }
end 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 --- Formats a buffer using the attached (and optionally filtered) language
--- server clients. --- server clients.
--- ---
--- @param options table|nil Optional table which holds the following optional fields: --- @param options? vim.lsp.buf.format.Opts
--- - 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
function M.format(options) function M.format(options)
options = options or {} options = options or {}
local bufnr = options.bufnr or api.nvim_get_current_buf() local bufnr = options.bufnr or api.nvim_get_current_buf()
@@ -229,8 +258,7 @@ function M.format(options)
end end
if options.async then if options.async then
local do_format local function do_format(idx, client)
do_format = function(idx, client)
if not client then if not client then
return return
end end
@@ -256,17 +284,22 @@ function M.format(options)
end end
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. --- 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 ---@param new_name string|nil If not provided, the user will be prompted for a new
--- name using |vim.ui.input()|. --- name using |vim.ui.input()|.
---@param options table|nil additional options ---@param options? vim.lsp.buf.rename.Opts 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.
function M.rename(new_name, options) function M.rename(new_name, options)
options = options or {} options = options or {}
local bufnr = options.bufnr or api.nvim_get_current_buf() local bufnr = options.bufnr or api.nvim_get_current_buf()
@@ -386,8 +419,7 @@ end
--- ---
---@param context (table|nil) Context for the request ---@param context (table|nil) Context for the request
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references
---@param options table|nil additional options ---@param options? vim.lsp.ListOpts
--- - on_list: (function) handler for list results. See |lsp-on-list-handler|
function M.references(context, options) function M.references(context, options)
validate({ context = { context, 't', true } }) validate({ context = { context, 't', true } })
local params = util.make_position_params() local params = util.make_position_params()
@@ -398,14 +430,13 @@ function M.references(context, options)
end end
--- Lists all symbols in the current buffer in the quickfix window. --- Lists all symbols in the current buffer in the quickfix window.
--- --- @param options? vim.lsp.ListOpts
---@param options table|nil additional options
--- - on_list: (function) handler for list results. See |lsp-on-list-handler|
function M.document_symbol(options) function M.document_symbol(options)
local params = { textDocument = util.make_text_document_params() } local params = { textDocument = util.make_text_document_params() }
request_with_options(ms.textDocument_documentSymbol, params, options) request_with_options(ms.textDocument_documentSymbol, params, options)
end end
--- @param call_hierarchy_items lsp.CallHierarchyItem[]?
local function pick_call_hierarchy_item(call_hierarchy_items) local function pick_call_hierarchy_item(call_hierarchy_items)
if not call_hierarchy_items then if not call_hierarchy_items then
return return
@@ -425,8 +456,10 @@ local function pick_call_hierarchy_item(call_hierarchy_items)
return choice return choice
end end
--- @param method string
local function call_hierarchy(method) local function call_hierarchy(method)
local params = util.make_position_params() local params = util.make_position_params()
--- @param result lsp.CallHierarchyItem[]?
request(ms.textDocument_prepareCallHierarchy, params, function(err, result, ctx) request(ms.textDocument_prepareCallHierarchy, params, function(err, result, ctx)
if err then if err then
vim.notify(err.message, vim.log.levels.WARN) 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 --- call, the user is prompted to enter a string on the command line. An empty
--- string means no filtering is done. --- string means no filtering is done.
--- ---
---@param query string|nil optional --- @param query string? optional
---@param options table|nil additional options --- @param options? vim.lsp.ListOpts
--- - on_list: (function) handler for list results. See |lsp-on-list-handler|
function M.workspace_symbol(query, options) function M.workspace_symbol(query, options)
query = query or npcall(vim.fn.input, 'Query: ') query = query or npcall(vim.fn.input, 'Query: ')
if query == nil then if query == nil then
@@ -582,16 +614,36 @@ function M.clear_references()
util.buf_clear_references() util.buf_clear_references()
end end
---@nodoc
---@class vim.lsp.CodeActionResultEntry ---@class vim.lsp.CodeActionResultEntry
---@field error? lsp.ResponseError ---@field error? lsp.ResponseError
---@field result? (lsp.Command|lsp.CodeAction)[] ---@field result? (lsp.Command|lsp.CodeAction)[]
---@field ctx lsp.HandlerContext ---@field ctx lsp.HandlerContext
---@class vim.lsp.buf.code_action.opts --- @class vim.lsp.buf.code_action.Opts
---@field context? lsp.CodeActionContext --- @inlinedoc
---@field filter? fun(x: lsp.CodeAction|lsp.Command):boolean ---
---@field apply? boolean --- Corresponds to `CodeActionContext` of the LSP specification:
---@field range? {start: integer[], end: integer[]} --- - {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 --- This is not public because the main extension point is
--- vim.ui.select which can be overridden independently. --- 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 --- need to be able to link a `CodeAction|Command` to the right client for
--- `codeAction/resolve` --- `codeAction/resolve`
---@param results table<integer, vim.lsp.CodeActionResultEntry> ---@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) local function on_code_action_results(results, opts)
---@param a lsp.Command|lsp.CodeAction ---@param a lsp.Command|lsp.CodeAction
local function action_filter(a) local function action_filter(a)
@@ -647,14 +699,15 @@ local function on_code_action_results(results, opts)
end end
---@param action lsp.Command|lsp.CodeAction ---@param action lsp.Command|lsp.CodeAction
---@param client lsp.Client ---@param client vim.lsp.Client
---@param ctx lsp.HandlerContext ---@param ctx lsp.HandlerContext
local function apply_action(action, client, ctx) local function apply_action(action, client, ctx)
if action.edit then if action.edit then
util.apply_workspace_edit(action.edit, client.offset_encoding) util.apply_workspace_edit(action.edit, client.offset_encoding)
end end
if action.command then local a_cmd = action.command
local command = type(action.command) == 'table' and action.command or action if a_cmd then
local command = type(a_cmd) == 'table' and a_cmd or action
client:_exec_cmd(command, ctx) client:_exec_cmd(command, ctx)
end end
end end
@@ -676,7 +729,6 @@ local function on_code_action_results(results, opts)
-- command: string -- command: string
-- arguments?: any[] -- arguments?: any[]
-- --
---@type lsp.Client
local client = assert(vim.lsp.get_client_by_id(choice.ctx.client_id)) local client = assert(vim.lsp.get_client_by_id(choice.ctx.client_id))
local action = choice.action local action = choice.action
local bufnr = assert(choice.ctx.bufnr, 'Must have buffer number') local bufnr = assert(choice.ctx.bufnr, 'Must have buffer number')
@@ -726,29 +778,7 @@ end
--- Selects a code action available at the current --- Selects a code action available at the current
--- cursor position. --- cursor position.
--- ---
---@param options table|nil Optional table which holds the following optional fields: ---@param options? vim.lsp.buf.code_action.Opts
--- - 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|
---
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction
---@see vim.lsp.protocol.CodeActionTriggerKind ---@see vim.lsp.protocol.CodeActionTriggerKind
function M.code_action(options) function M.code_action(options)
@@ -814,9 +844,8 @@ function M.code_action(options)
end end
--- Executes an LSP server command. --- Executes an LSP server command.
--- --- @param command_params lsp.ExecuteCommandParams
---@param command_params table A valid `ExecuteCommandParams` object --- @see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_executeCommand
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_executeCommand
function M.execute_command(command_params) function M.execute_command(command_params)
validate({ validate({
command = { command_params.command, 's' }, command = { command_params.command, 's' },

View File

@@ -6,38 +6,125 @@ local ms = lsp.protocol.Methods
local changetracking = lsp._changetracking local changetracking = lsp._changetracking
local validate = vim.validate local validate = vim.validate
--- @alias vim.lsp.client.on_init_cb fun(client: lsp.Client, initialize_result: lsp.InitializeResult) --- @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: lsp.Client, bufnr: integer) --- @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.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? --- @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 --- @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 --- @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 --- @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[] --- @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 --- @field capabilities? lsp.ClientCapabilities
---
--- Map of language server method names to |lsp-handler|
--- @field handlers? table<string,function> --- @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 --- @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)> --- @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 --- @field init_options? table
---
--- Name in log messages.
--- (default: client-id)
--- @field name? string --- @field name? string
---
--- Language ID as string. Defaults to the filetype.
--- @field get_language_id? fun(bufnr: integer, filetype: string): string --- @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) --- @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 --- @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> --- @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> --- @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> --- @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' --- @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 --- @field flags? table
---
--- Directory where the LSP server will base its workspaceFolders, rootUri, and rootPath on initialization.
--- @field root_dir? string --- @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> --- @field pending table<lsp.ProgressToken,lsp.LSPAny>
--- @class lsp.Client --- @class vim.lsp.Client
--- ---
--- The id allocated to the client. --- The id allocated to the client.
--- @field id integer --- @field id integer
@@ -67,7 +154,7 @@ local validate = vim.validate
--- ---
--- copy of the table that was passed by the user --- copy of the table that was passed by the user
--- to |vim.lsp.start_client()|. --- to |vim.lsp.start_client()|.
--- @field config lsp.ClientConfig --- @field config vim.lsp.ClientConfig
--- ---
--- Response from the server sent on --- Response from the server sent on
--- initialize` describing the server's capabilities. --- initialize` describing the server's capabilities.
@@ -75,7 +162,7 @@ local validate = vim.validate
--- ---
--- A ring buffer (|vim.ringbuf()|) containing progress messages --- A ring buffer (|vim.ringbuf()|) containing progress messages
--- sent by the server. --- sent by the server.
--- @field progress lsp.Client.Progress --- @field progress vim.lsp.Client.Progress
--- ---
--- @field initialized true? --- @field initialized true?
--- ---
@@ -239,7 +326,7 @@ local function default_get_language_id(_bufnr, filetype)
end end
--- Validates a client configuration as given to |vim.lsp.start_client()|. --- 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) local function validate_config(config)
validate({ validate({
config = { config, 't' }, config = { config, 't' },
@@ -285,7 +372,7 @@ local function get_trace(trace)
end end
--- @param id integer --- @param id integer
--- @param config lsp.ClientConfig --- @param config vim.lsp.ClientConfig
--- @return string --- @return string
local function get_name(id, config) local function get_name(id, config)
local name = config.name local name = config.name
@@ -328,8 +415,8 @@ local function ensure_list(x)
end end
--- @package --- @package
--- @param config lsp.ClientConfig --- @param config vim.lsp.ClientConfig
--- @return lsp.Client? --- @return vim.lsp.Client?
function Client.create(config) function Client.create(config)
validate_config(config) validate_config(config)
@@ -337,7 +424,7 @@ function Client.create(config)
local id = client_index local id = client_index
local name = get_name(id, config) local name = get_name(id, config)
--- @class lsp.Client --- @class vim.lsp.Client
local self = { local self = {
id = id, id = id,
config = config, config = config,
@@ -370,7 +457,7 @@ function Client.create(config)
--- - lsp.WorkDoneProgressBegin, --- - lsp.WorkDoneProgressBegin,
--- - lsp.WorkDoneProgressReport (extended with title from Begin) --- - lsp.WorkDoneProgressReport (extended with title from Begin)
--- - lsp.WorkDoneProgressEnd (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 --- @deprecated use client.progress instead
messages = { name = name, messages = {}, progress = {}, status = {} }, messages = { name = name, messages = {}, progress = {}, status = {} },
@@ -421,6 +508,7 @@ function Client.create(config)
return self return self
end end
--- @private
--- @param cbs function[] --- @param cbs function[]
--- @param error_id integer --- @param error_id integer
--- @param ... any --- @param ... any
@@ -698,7 +786,7 @@ function Client:_cancel_request(id)
return self.rpc.notify(ms.dollar_cancelRequest, { id = id }) return self.rpc.notify(ms.dollar_cancelRequest, { id = id })
end end
--- @nodoc --- @private
--- Stops a client, optionally with force. --- Stops a client, optionally with force.
--- ---
--- By default, it will just ask the - server to shutdown without force. If --- 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)) err_message(self._log_prefix, ': Error ', client_error, ': ', vim.inspect(err))
end end
--- @private
--- @param method string --- @param method string
--- @param opts? {bufnr: integer?} --- @param opts? {bufnr: integer?}
function Client:_supports_method(method, opts) function Client:_supports_method(method, opts)

View File

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

View File

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

View File

@@ -412,6 +412,7 @@ M[ms.textDocument_hover] = M.hover
---@param _ nil not used ---@param _ nil not used
---@param result (table) result of LSP method; a location or a list of locations. ---@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 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[]` ---(`textDocument/definition` can return `Location` or `Location[]`
local function location_handler(_, result, ctx, config) local function location_handler(_, result, ctx, config)
if result == nil or vim.tbl_isempty(result) then 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 api = vim.api
local M = {} local M = {}
---@class lsp.inlay_hint.bufstate ---@class (private) vim.lsp.inlay_hint.bufstate
---@field version? integer ---@field version? integer
---@field client_hints? table<integer, table<integer, lsp.InlayHint[]>> client_id -> (lnum -> hints) ---@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 applied table<integer, integer> Last version of hints applied to this line
---@field enabled boolean Whether inlay hints are enabled for this buffer ---@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 bufstates = {}
local namespace = api.nvim_create_namespace('vim_lsp_inlayhint') local namespace = api.nvim_create_namespace('vim_lsp_inlayhint')
@@ -103,11 +103,14 @@ function M.on_refresh(err, _, ctx, _)
return vim.NIL return vim.NIL
end end
--- @class vim.lsp.inlay_hint.get.filter --- Optional filters |kwargs|:
--- @class vim.lsp.inlay_hint.get.Filter
--- @inlinedoc
--- @field bufnr integer? --- @field bufnr integer?
--- @field range lsp.Range? --- @field range lsp.Range?
---
--- @class vim.lsp.inlay_hint.get.ret --- @class vim.lsp.inlay_hint.get.ret
--- @inlinedoc
--- @field bufnr integer --- @field bufnr integer
--- @field client_id integer --- @field client_id integer
--- @field inlay_hint lsp.InlayHint --- @field inlay_hint lsp.InlayHint
@@ -130,17 +133,8 @@ end
--- }) --- })
--- ``` --- ```
--- ---
--- @param filter vim.lsp.inlay_hint.get.filter? --- @param filter vim.lsp.inlay_hint.get.Filter?
--- Optional filters |kwargs|:
--- - bufnr (integer?): 0 for current buffer
--- - range (lsp.Range?)
---
--- @return vim.lsp.inlay_hint.get.ret[] --- @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 --- @since 12
function M.get(filter) function M.get(filter)
vim.validate({ filter = { filter, 'table', true } }) vim.validate({ filter = { filter, 'table', true } })
@@ -241,7 +235,7 @@ end
--- Refresh inlay hints, only if we have attached clients that support it --- Refresh inlay hints, only if we have attached clients that support it
---@param bufnr (integer) Buffer handle, or 0 for current ---@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 ---@private
local function _refresh(bufnr, opts) local function _refresh(bufnr, opts)
opts = opts or {} opts = opts or {}

View File

@@ -26,7 +26,7 @@ local function format_message_with_content_length(message)
}) })
end end
---@class vim.lsp.rpc.Headers: {string: any} ---@class (private) vim.lsp.rpc.Headers: {string: any}
---@field content_length integer ---@field content_length integer
--- Parses an LSP Message's header --- Parses an LSP Message's header
@@ -193,7 +193,9 @@ function M.rpc_response_error(code, message, data)
}) })
end end
--- Dispatchers for LSP message types.
--- @class vim.lsp.rpc.Dispatchers --- @class vim.lsp.rpc.Dispatchers
--- @inlinedoc
--- @field notification fun(method: string, params: table) --- @field notification fun(method: string, params: table)
--- @field server_request fun(method: string, params: table): any?, lsp.ResponseError? --- @field server_request fun(method: string, params: table): any?, lsp.ResponseError?
--- @field on_exit fun(code: integer, signal: integer) --- @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
end end
---@private ---@class (private) vim.lsp.rpc.Client
---@class vim.lsp.rpc.Client
---@field message_index integer ---@field message_index integer
---@field message_callbacks table<integer, function> dict of message_id to callback ---@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 ---@field notify_reply_callbacks table<integer, function> dict of message_id to callback
@@ -522,7 +523,7 @@ function Client:handle_body(body)
end end
end end
---@class vim.lsp.rpc.Transport ---@class (private) vim.lsp.rpc.Transport
---@field write fun(msg: string) ---@field write fun(msg: string)
---@field is_closing fun(): boolean ---@field is_closing fun(): boolean
---@field terminate fun() ---@field terminate fun()
@@ -721,32 +722,21 @@ function M.domain_socket_connect(pipe_path)
end end
end end
---@class vim.lsp.rpc.ExtraSpawnParams --- Additional context for the LSP server process.
---@field cwd? string Working directory for the LSP server process --- @class vim.lsp.rpc.ExtraSpawnParams
---@field detached? boolean Detach the LSP server process from the current process --- @inlinedoc
---@field env? table<string,string> Additional environment variables for LSP server process. See |vim.system| --- @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 --- 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 --- 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()| --- communication via TCP, spawn a process manually and use |vim.lsp.rpc.connect()|
--- ---
---@param cmd string[] Command to start the LSP server. --- @param cmd string[] Command to start the LSP server.
--- --- @param dispatchers? vim.lsp.rpc.Dispatchers
---@param dispatchers? vim.lsp.rpc.Dispatchers Dispatchers for LSP message types. --- @param extra_spawn_params? vim.lsp.rpc.ExtraSpawnParams
--- Valid dispatcher names are: --- @return vim.lsp.rpc.PublicClient? : Client RPC object, with these methods:
--- - `"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:
--- - `notify()` |vim.lsp.rpc.notify()| --- - `notify()` |vim.lsp.rpc.notify()|
--- - `request()` |vim.lsp.rpc.request()| --- - `request()` |vim.lsp.rpc.request()|
--- - `is_closing()` returns a boolean indicating if the RPC is closing. --- - `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 util = require('vim.lsp.util')
local uv = vim.uv local uv = vim.uv
--- @class STTokenRange --- @class (private) STTokenRange
--- @field line integer line number 0-based --- @field line integer line number 0-based
--- @field start_col integer start column 0-based --- @field start_col integer start column 0-based
--- @field end_col integer end 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 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 --- @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 version? integer document version associated with this result
--- @field result_id? string resultId from the server; used with delta requests --- @field result_id? string resultId from the server; used with delta requests
--- @field highlights? STTokenRange[] cache of highlight ranges for this document version --- @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 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 --- @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 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 --- @field version? integer the document version associated with the most recent request
--- ---
--- @class STClientState --- @class (private) STClientState
--- @field namespace integer --- @field namespace integer
--- @field active_request STActiveRequest --- @field active_request STActiveRequest
--- @field current_result STCurrentResult --- @field current_result STCurrentResult
---@class STHighlighter ---@class (private) STHighlighter
---@field active table<integer, STHighlighter> ---@field active table<integer, STHighlighter>
---@field bufnr integer ---@field bufnr integer
---@field augroup integer augroup for buffer events ---@field augroup integer augroup for buffer events
@@ -92,7 +92,7 @@ end
--- ---
---@param data integer[] ---@param data integer[]
---@param bufnr integer ---@param bufnr integer
---@param client lsp.Client ---@param client vim.lsp.Client
---@param request STActiveRequest ---@param request STActiveRequest
---@return STTokenRange[] ---@return STTokenRange[]
local function tokens_to_ranges(data, bufnr, client, request) local function tokens_to_ranges(data, bufnr, client, request)
@@ -646,6 +646,7 @@ function M.stop(bufnr, client_id)
end end
end end
--- @nodoc
--- @class STTokenRangeInspect : STTokenRange --- @class STTokenRangeInspect : STTokenRange
--- @field client_id integer --- @field client_id integer
@@ -727,6 +728,13 @@ function M.force_refresh(bufnr)
end end
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. --- Highlight a semantic token.
--- ---
--- Apply an extmark with a given highlight group for a semantic token. The --- Apply an extmark with a given highlight group for a semantic token. The
@@ -735,11 +743,9 @@ end
--- use inside |LspTokenUpdate| callbacks. --- use inside |LspTokenUpdate| callbacks.
---@param token (table) a semantic token, found as `args.data.token` in |LspTokenUpdate|. ---@param token (table) a semantic token, found as `args.data.token` in |LspTokenUpdate|.
---@param bufnr (integer) the buffer to highlight ---@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 hl_group (string) Highlight group name
---@param opts (table|nil) Optional parameters. ---@param opts? vim.lsp.semantic_tokens.highlight_token.Opts Optional parameters:
--- - priority: (integer|nil) Priority for the applied extmark. Defaults
--- to `vim.highlight.priorities.semantic_tokens + 3`
function M.highlight_token(token, bufnr, client_id, hl_group, opts) function M.highlight_token(token, bufnr, client_id, hl_group, opts)
local highlighter = STHighlighter.active[bufnr] local highlighter = STHighlighter.active[bufnr]
if not highlighter then if not highlighter then

View File

@@ -675,13 +675,15 @@ local function get_bufs_with_prefix(prefix)
return buffers return buffers
end end
--- @class vim.lsp.util.rename.Opts
--- @inlinedoc
--- @field overwrite? boolean
--- @field ignoreIfExists? boolean
--- Rename old_fname to new_fname --- Rename old_fname to new_fname
--- --- @param old_fname string
---@param old_fname string --- @param new_fname string
---@param new_fname string --- @param opts? vim.lsp.util.rename.Opts Options:
---@param opts? table options
--- - overwrite? boolean
--- - ignoreIfExists? boolean
function M.rename(old_fname, new_fname, opts) function M.rename(old_fname, new_fname, opts)
opts = opts or {} opts = opts or {}
local skip = not opts.overwrite or opts.ignoreIfExists local skip = not opts.overwrite or opts.ignoreIfExists
@@ -1450,7 +1452,7 @@ function M.stylize_markdown(bufnr, contents, opts)
return stripped return stripped
end 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. --- @field width integer Thematic breaks are expanded to this size. Defaults to 80.
--- Normalizes Markdown input to a canonical form. --- Normalizes Markdown input to a canonical form.
@@ -1466,7 +1468,7 @@ end
--- ---
---@private ---@private
---@param contents string[] ---@param contents string[]
---@param opts? lsp.util.NormalizeMarkdownOptions ---@param opts? vim.lsp.util._normalize_markdown.Opts
---@return string[] table of lines containing normalized Markdown ---@return string[] table of lines containing normalized Markdown
---@see https://github.github.com/gfm ---@see https://github.github.com/gfm
function M._normalize_markdown(contents, opts) function M._normalize_markdown(contents, opts)
@@ -1537,7 +1539,7 @@ local function close_preview_autocmd(events, winnr, bufnrs)
end end
end end
---@internal ---@private
--- Computes size of float needed to show contents (with optional wrapping) --- Computes size of float needed to show contents (with optional wrapping)
--- ---
---@param contents table of lines to show in window ---@param contents table of lines to show in window
@@ -1613,24 +1615,50 @@ function M._make_floating_popup_size(contents, opts)
return width, height return width, height
end 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. --- Shows contents in a floating window.
--- ---
---@param contents table of lines to show in window ---@param contents table of lines to show in window
---@param syntax string of syntax to set for opened buffer ---@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()| ---@param opts? vim.lsp.util.open_floating_preview.Opts with optional fields
--- before they are passed on to |nvim_open_win()|) --- (additional keys are filtered with |vim.lsp.util.make_floating_popup_options()|
--- - height: (integer) height of floating window --- before they are passed on to |nvim_open_win()|)
--- - 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}
---@return integer bufnr of newly created float window ---@return integer bufnr of newly created float window
---@return integer winid of newly created float window preview window ---@return integer winid of newly created float window preview window
function M.open_floating_preview(contents, syntax, opts) 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 } return { v.start.line, v.start.character }
end) end)
---@class vim.lsp.util.LocationItem ---@class vim.lsp.util.locations_to_items.ret
---@inlinedoc
---@field filename string ---@field filename string
---@field lnum integer 1-indexed line number ---@field lnum integer 1-indexed line number
---@field col integer 1-indexed column ---@field col integer 1-indexed column
@@ -1813,7 +1842,7 @@ end)
---@param locations lsp.Location[]|lsp.LocationLink[] ---@param locations lsp.Location[]|lsp.LocationLink[]
---@param offset_encoding string offset_encoding for locations utf-8|utf-16|utf-32 ---@param offset_encoding string offset_encoding for locations utf-8|utf-16|utf-32
--- default to first client of buffer --- 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) function M.locations_to_items(locations, offset_encoding)
if offset_encoding == nil then if offset_encoding == nil then
vim.notify_once( vim.notify_once(
@@ -2221,16 +2250,16 @@ local function make_line_range_params(bufnr, start_line, end_line, offset_encodi
} }
end end
---@private ---@class (private) vim.lsp.util._refresh.Opts
--- Request updated LSP information for a buffer.
---
---@class lsp.util.RefreshOptions
---@field bufnr integer? Buffer to refresh (default: 0) ---@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 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) ---@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 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) function M._refresh(method, opts)
opts = opts or {} opts = opts or {}
local bufnr = opts.bufnr local bufnr = opts.bufnr

View File

@@ -108,22 +108,25 @@ function M.read(path)
return contents return contents
end end
---@class vim.trust.opts --- @class vim.trust.opts
---@field action string --- @inlinedoc
---@field path? string ---
---@field bufnr? integer --- - `'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. --- Manage the trust database.
--- ---
--- The trust database is located at |$XDG_STATE_HOME|/nvim/trust. --- The trust database is located at |$XDG_STATE_HOME|/nvim/trust.
--- ---
---@param opts (table): ---@param opts? vim.trust.opts
--- - 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}.
---@return boolean success true if operation was successful ---@return boolean success true if operation was successful
---@return string msg full path if operation was successful, else error message ---@return string msg full path if operation was successful, else error message
function M.trust(opts) function M.trust(opts)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -752,7 +752,7 @@ end
--- ---
--- @param fname string help file to parse --- @param fname string help file to parse
--- @param parser_path string? path to non-default vimdoc.so --- @param parser_path string? path to non-default vimdoc.so
--- @return LanguageTree, integer (lang_tree, bufnr) --- @return vim.treesitter.LanguageTree, integer (lang_tree, bufnr)
local function parse_buf(fname, parser_path) local function parse_buf(fname, parser_path)
local buf ---@type integer local buf ---@type integer
if type(fname) == 'string' then if type(fname) == 'string' then

View File

@@ -269,6 +269,7 @@ local config = {
filename = 'lsp.txt', filename = 'lsp.txt',
section_order = { section_order = {
'lsp.lua', 'lsp.lua',
'client.lua',
'buf.lua', 'buf.lua',
'diagnostic.lua', 'diagnostic.lua',
'codelens.lua', 'codelens.lua',
@@ -362,15 +363,25 @@ local function replace_generics(ty, generics)
return generics[ty] or ty return generics[ty] or ty
end end
--- @param name string
local function fmt_field_name(name)
local name0, opt = name:match('^([^?]*)(%??)$')
return fmt('{%s}%s', name0, opt)
end
--- @param ty string --- @param ty string
--- @param generics? table<string,string> --- @param generics? table<string,string>
local function render_type(ty, generics) --- @param default? string
local function render_type(ty, generics, default)
if generics then if generics then
ty = replace_generics(ty, generics) ty = replace_generics(ty, generics)
end end
ty = ty:gsub('%s*|%s*nil', '?') ty = ty:gsub('%s*|%s*nil', '?')
ty = ty:gsub('nil%s*|%s*(.*)', '%1?') ty = ty:gsub('nil%s*|%s*(.*)', '%1?')
ty = ty:gsub('%s*|%s*', '|') ty = ty:gsub('%s*|%s*', '|')
if default then
return fmt('(`%s`, default: %s)', ty, default)
end
return fmt('(`%s`)', ty) return fmt('(`%s`)', ty)
end end
@@ -379,10 +390,101 @@ local function should_render_param(p)
return not p.access and not contains(p.name, { '_', 'self' }) return not p.access and not contains(p.name, { '_', 'self' })
end end
--- @param desc? string
--- @return string?, string?
local function get_default(desc)
if not desc then
return
end
local default = desc:match('\n%s*%([dD]efault: ([^)]+)%)')
if default then
desc = desc:gsub('\n%s*%([dD]efault: [^)]+%)', '')
end
return desc, default
end
--- @param ty string
--- @param classes? table<string,nvim.luacats.parser.class>
--- @return nvim.luacats.parser.class?
local function get_class(ty, classes)
if not classes then
return
end
local cty = ty:gsub('%s*|%s*nil', '?'):gsub('?$', ''):gsub('%[%]$', '')
return classes[cty]
end
--- @param obj nvim.luacats.parser.param|nvim.luacats.parser.return|nvim.luacats.parser.field
--- @param classes? table<string,nvim.luacats.parser.class>
local function inline_type(obj, classes)
local ty = obj.type
if not ty then
return
end
local cls = get_class(ty, classes)
if not cls or cls.nodoc then
return
end
if not cls.inlinedoc then
-- Not inlining so just add a: "See |tag|."
local tag = fmt('|%s|', cls.name)
if obj.desc and obj.desc:find(tag) then
-- Tag already there
return
end
-- TODO(lewis6991): Aim to remove this. Need this to prevent dead
-- references to types defined in runtime/lua/vim/lsp/_meta/protocol.lua
if not vim.startswith(cls.name, 'vim.') then
return
end
obj.desc = obj.desc or ''
local period = (obj.desc == '' or vim.endswith(obj.desc, '.')) and '' or '.'
obj.desc = obj.desc .. fmt('%s See %s.', period, tag)
return
end
local ty_isopt = (ty:match('%?$') or ty:match('%s*|%s*nil')) ~= nil
local ty_islist = (ty:match('%[%]$')) ~= nil
ty = ty_isopt and 'table?' or ty_islist and 'table[]' or 'table'
local desc = obj.desc or ''
if cls.desc then
desc = desc .. cls.desc
elseif desc == '' then
if ty_islist then
desc = desc .. 'A list of objects with the following fields:'
else
desc = desc .. 'A table with the following fields:'
end
end
local desc_append = {}
for _, f in ipairs(cls.fields) do
local fdesc, default = get_default(f.desc)
local fty = render_type(f.type, nil, default)
local fnm = fmt_field_name(f.name)
table.insert(desc_append, table.concat({ '-', fnm, fty, fdesc }, ' '))
end
desc = desc .. '\n' .. table.concat(desc_append, '\n')
obj.type = ty
obj.desc = desc
end
--- @param xs (nvim.luacats.parser.param|nvim.luacats.parser.field)[] --- @param xs (nvim.luacats.parser.param|nvim.luacats.parser.field)[]
--- @param generics? table<string,string> --- @param generics? table<string,string>
--- @param classes? table<string,nvim.luacats.parser.class>
--- @param exclude_types? true --- @param exclude_types? true
local function render_fields_or_params(xs, generics, exclude_types) local function render_fields_or_params(xs, generics, classes, exclude_types)
local ret = {} --- @type string[] local ret = {} --- @type string[]
xs = vim.tbl_filter(should_render_param, xs) xs = vim.tbl_filter(should_render_param, xs)
@@ -398,15 +500,27 @@ local function render_fields_or_params(xs, generics, exclude_types)
end end
for _, p in ipairs(xs) do for _, p in ipairs(xs) do
local nm, ty = p.name, p.type local pdesc, default = get_default(p.desc)
local desc = p.desc p.desc = pdesc
local pnm = fmt(' • %-' .. indent .. 's', '{' .. nm .. '}')
inline_type(p, classes)
local nm, ty, desc = p.name, p.type, p.desc
local fnm = p.kind == 'operator' and fmt('op(%s)', nm) or fmt_field_name(nm)
local pnm = fmt(' • %-' .. indent .. 's', fnm)
if ty then if ty then
local pty = render_type(ty, generics) local pty = render_type(ty, generics, default)
if desc then if desc then
desc = fmt('%s %s', pty, desc)
table.insert(ret, pnm) table.insert(ret, pnm)
table.insert(ret, md_to_vimdoc(desc, 1, 9 + indent, TEXT_WIDTH, true)) if #pty > TEXT_WIDTH - indent then
vim.list_extend(ret, { ' ', pty, '\n' })
table.insert(ret, md_to_vimdoc(desc, 9 + indent, 9 + indent, TEXT_WIDTH, true))
else
desc = fmt('%s %s', pty, desc)
table.insert(ret, md_to_vimdoc(desc, 1, 9 + indent, TEXT_WIDTH, true))
end
else else
table.insert(ret, fmt('%s %s\n', pnm, pty)) table.insert(ret, fmt('%s %s\n', pnm, pty))
end end
@@ -421,24 +535,46 @@ local function render_fields_or_params(xs, generics, exclude_types)
return table.concat(ret) return table.concat(ret)
end end
-- --- @param class lua2vimdoc.class --- @param class nvim.luacats.parser.class
-- local function render_class(class) local function render_class(class)
-- writeln(fmt('*%s*', class.name)) if class.access or class.nodoc or class.inlinedoc then
-- writeln() return
-- if #class.fields > 0 then end
-- writeln(' Fields: ~')
-- render_fields_or_params(class.fields)
-- end
-- writeln()
-- end
-- --- @param cls table<string,lua2vimdoc.class> local ret = {} --- @type string[]
-- local function render_classes(cls)
-- --- @diagnostic disable-next-line:no-unknown table.insert(ret, fmt('*%s*\n', class.name))
-- for _, class in vim.spairs(cls) do
-- render_class(class) if class.parent then
-- end local txt = fmt('Extends: |%s|', class.parent)
-- end table.insert(ret, md_to_vimdoc(txt, INDENTATION, INDENTATION, TEXT_WIDTH))
end
if class.desc then
table.insert(ret, md_to_vimdoc(class.desc, INDENTATION, INDENTATION, TEXT_WIDTH))
end
local fields_txt = render_fields_or_params(class.fields)
if not fields_txt:match('^%s*$') then
table.insert(ret, '\n Fields: ~\n')
table.insert(ret, fields_txt)
end
table.insert(ret, '\n')
return table.concat(ret)
end
--- @param cls table<string,nvim.luacats.parser.class>
local function render_classes(cls)
local ret = {} --- @type string[]
--- @diagnostic disable-next-line:no-unknown
for _, class in vim.spairs(cls) do
ret[#ret + 1] = render_class(class)
end
return table.concat(ret)
end
--- @param fun nvim.luacats.parser.fun --- @param fun nvim.luacats.parser.fun
--- @param cfg nvim.gen_vimdoc.Config --- @param cfg nvim.gen_vimdoc.Config
@@ -448,7 +584,7 @@ local function render_fun_header(fun, cfg)
local args = {} --- @type string[] local args = {} --- @type string[]
for _, p in ipairs(fun.params or {}) do for _, p in ipairs(fun.params or {}) do
if p.name ~= 'self' then if p.name ~= 'self' then
args[#args + 1] = fmt('{%s}', p.name:gsub('%?$', '')) args[#args + 1] = fmt_field_name(p.name)
end end
end end
@@ -480,8 +616,9 @@ end
--- @param returns nvim.luacats.parser.return[] --- @param returns nvim.luacats.parser.return[]
--- @param generics? table<string,string> --- @param generics? table<string,string>
--- @param classes? table<string,nvim.luacats.parser.class>
--- @param exclude_types boolean --- @param exclude_types boolean
local function render_returns(returns, generics, exclude_types) local function render_returns(returns, generics, classes, exclude_types)
local ret = {} --- @type string[] local ret = {} --- @type string[]
returns = vim.deepcopy(returns) returns = vim.deepcopy(returns)
@@ -498,26 +635,26 @@ local function render_returns(returns, generics, exclude_types)
end end
for _, p in ipairs(returns) do for _, p in ipairs(returns) do
inline_type(p, classes)
local rnm, ty, desc = p.name, p.type, p.desc local rnm, ty, desc = p.name, p.type, p.desc
local blk = ''
local blk = {} --- @type string[]
if ty then if ty then
blk = render_type(ty, generics) blk[#blk + 1] = render_type(ty, generics)
end end
if rnm then blk[#blk + 1] = rnm
blk = blk .. ' ' .. rnm blk[#blk + 1] = desc
end
if desc then table.insert(ret, md_to_vimdoc(table.concat(blk, ' '), 8, 8, TEXT_WIDTH, true))
blk = blk .. ' ' .. desc
end
table.insert(ret, md_to_vimdoc(blk, 8, 8, TEXT_WIDTH, true))
end end
return table.concat(ret) return table.concat(ret)
end end
--- @param fun nvim.luacats.parser.fun --- @param fun nvim.luacats.parser.fun
--- @param classes table<string,nvim.luacats.parser.class>
--- @param cfg nvim.gen_vimdoc.Config --- @param cfg nvim.gen_vimdoc.Config
local function render_fun(fun, cfg) local function render_fun(fun, classes, cfg)
if fun.access or fun.deprecated or fun.nodoc then if fun.access or fun.deprecated or fun.nodoc then
return return
end end
@@ -570,7 +707,7 @@ local function render_fun(fun, cfg)
end end
if fun.params and #fun.params > 0 then if fun.params and #fun.params > 0 then
local param_txt = render_fields_or_params(fun.params, fun.generics, cfg.exclude_types) local param_txt = render_fields_or_params(fun.params, fun.generics, classes, cfg.exclude_types)
if not param_txt:match('^%s*$') then if not param_txt:match('^%s*$') then
table.insert(ret, '\n Parameters: ~\n') table.insert(ret, '\n Parameters: ~\n')
ret[#ret + 1] = param_txt ret[#ret + 1] = param_txt
@@ -578,7 +715,7 @@ local function render_fun(fun, cfg)
end end
if fun.returns then if fun.returns then
local txt = render_returns(fun.returns, fun.generics, cfg.exclude_types) local txt = render_returns(fun.returns, fun.generics, classes, cfg.exclude_types)
if not txt:match('^%s*$') then if not txt:match('^%s*$') then
table.insert(ret, '\n') table.insert(ret, '\n')
ret[#ret + 1] = txt ret[#ret + 1] = txt
@@ -597,15 +734,16 @@ local function render_fun(fun, cfg)
end end
--- @param funs nvim.luacats.parser.fun[] --- @param funs nvim.luacats.parser.fun[]
--- @param classes table<string,nvim.luacats.parser.class>
--- @param cfg nvim.gen_vimdoc.Config --- @param cfg nvim.gen_vimdoc.Config
local function render_funs(funs, cfg) local function render_funs(funs, classes, cfg)
local ret = {} --- @type string[] local ret = {} --- @type string[]
for _, f in ipairs(funs) do for _, f in ipairs(funs) do
if cfg.fn_xform then if cfg.fn_xform then
cfg.fn_xform(f) cfg.fn_xform(f)
end end
ret[#ret + 1] = render_fun(f, cfg) ret[#ret + 1] = render_fun(f, classes, cfg)
end end
-- Sort via prototype -- Sort via prototype
@@ -745,15 +883,35 @@ local function gen_target(cfg)
expand_files(cfg.files) expand_files(cfg.files)
--- @type table<string,{[1]:table<string,nvim.luacats.parser.class>, [2]: nvim.luacats.parser.fun[], [3]: string[]}>
local file_results = {}
--- @type table<string,nvim.luacats.parser.class>
local all_classes = {}
--- First pass so we can collect all classes
for _, f in pairs(cfg.files) do for _, f in pairs(cfg.files) do
local ext = assert(f:match('%.([^.]+)$')) --[[@as 'h'|'c'|'lua']] local ext = assert(f:match('%.([^.]+)$')) --[[@as 'h'|'c'|'lua']]
local parser = assert(parsers[ext]) local parser = assert(parsers[ext])
local _, funs, briefs = parser(f) local classes, funs, briefs = parser(f)
file_results[f] = { classes, funs, briefs }
all_classes = vim.tbl_extend('error', all_classes, classes)
end
for f, r in pairs(file_results) do
local classes, funs, briefs = r[1], r[2], r[3]
local briefs_txt = {} --- @type string[] local briefs_txt = {} --- @type string[]
for _, b in ipairs(briefs) do for _, b in ipairs(briefs) do
briefs_txt[#briefs_txt + 1] = md_to_vimdoc(b, 0, 0, TEXT_WIDTH) briefs_txt[#briefs_txt + 1] = md_to_vimdoc(b, 0, 0, TEXT_WIDTH)
end end
local funs_txt = render_funs(funs, cfg) local funs_txt = render_funs(funs, all_classes, cfg)
if next(classes) then
local classes_txt = render_classes(classes)
if vim.trim(classes_txt) ~= '' then
funs_txt = classes_txt .. '\n' .. funs_txt
end
end
-- FIXME: Using f_base will confuse `_meta/protocol.lua` with `protocol.lua` -- FIXME: Using f_base will confuse `_meta/protocol.lua` with `protocol.lua`
local f_base = assert(vim.fs.basename(f)) local f_base = assert(vim.fs.basename(f))
sections[f_base] = make_section(f_base, cfg, briefs_txt, funs_txt) sections[f_base] = make_section(f_base, cfg, briefs_txt, funs_txt)

View File

@@ -21,8 +21,7 @@ local function opt(x)
return x ^ -1 return x ^ -1
end end
local nl = P('\r\n') + P('\n') local ws = rep1(S(' \t'))
local ws = rep1(S(' \t') + nl)
local fill = opt(ws) local fill = opt(ws)
local any = P(1) -- (consume one character) local any = P(1) -- (consume one character)
@@ -30,11 +29,11 @@ local letter = R('az', 'AZ') + S('_$')
local num = R('09') local num = R('09')
local ident = letter * rep(letter + num + S '-.') local ident = letter * rep(letter + num + S '-.')
local string_single = P "'" * rep(any - P "'") * P "'" local string_single = P "'" * rep(any - P "'") * P "'"
local string_double = P '"' * rep(any - P '"') * P '"' local string_double = P('"') * rep(any - P('"')) * P('"')
local literal = (string_single + string_double + (opt(P '-') * num) + P 'false' + P 'true') local literal = (string_single + string_double + (opt(P('-')) * num) + P('false') + P('true'))
local lname = (ident + P '...') * opt(P '?') local lname = (ident + P('...')) * opt(P('?'))
--- @param x string --- @param x string
local function Pf(x) local function Pf(x)
@@ -47,13 +46,23 @@ local function Sf(x)
end end
--- @param x vim.lpeg.Pattern --- @param x vim.lpeg.Pattern
local function comma(x) local function paren(x)
return x * rep(Pf ',' * x) return Pf('(') * x * fill * P(')')
end end
--- @param x vim.lpeg.Pattern --- @param x vim.lpeg.Pattern
local function parenOpt(x) local function parenOpt(x)
return (Pf('(') * x * fill * P(')')) + x return paren(x) + x
end
--- @param x vim.lpeg.Pattern
local function comma1(x)
return parenOpt(x * rep(Pf(',') * x))
end
--- @param x vim.lpeg.Pattern
local function comma(x)
return opt(comma1(x))
end end
--- @type table<string,vim.lpeg.Pattern> --- @type table<string,vim.lpeg.Pattern>
@@ -63,7 +72,15 @@ local v = setmetatable({}, {
end, end,
}) })
local colon = Pf(':')
local opt_exact = opt(Cg(Pf('(exact)'), 'access'))
local access = P('private') + P('protected') + P('package')
local caccess = Cg(access, 'access')
local desc_delim = Sf '#:' + ws local desc_delim = Sf '#:' + ws
local desc = Cg(rep(any), 'desc')
local opt_desc = opt(desc_delim * desc)
local cname = Cg(ident, 'name')
local opt_parent = opt(colon * Cg(ident, 'parent'))
--- @class nvim.luacats.Param --- @class nvim.luacats.Param
--- @field kind 'param' --- @field kind 'param'
@@ -85,6 +102,7 @@ local desc_delim = Sf '#:' + ws
--- @field kind 'class' --- @field kind 'class'
--- @field name string --- @field name string
--- @field parent? string --- @field parent? string
--- @field access? 'private'|'protected'|'package'
--- @class nvim.luacats.Field --- @class nvim.luacats.Field
--- @field kind 'field' --- @field kind 'field'
@@ -107,112 +125,60 @@ local desc_delim = Sf '#:' + ws
--- @class nvim.luacats.grammar --- @class nvim.luacats.grammar
--- @field match fun(self, input: string): nvim.luacats.grammar.result? --- @field match fun(self, input: string): nvim.luacats.grammar.result?
local function annot(nm, pat)
if type(nm) == 'string' then
nm = P(nm)
end
if pat then
return Ct(Cg(P(nm), 'kind') * fill * pat)
end
return Ct(Cg(P(nm), 'kind'))
end
local grammar = P { local grammar = P {
rep1(P('@') * (v.ats + v.ext_ats)), rep1(P('@') * (v.ats + v.ext_ats)),
ats = v.at_param ats = annot('param', Cg(lname, 'name') * ws * v.ctype * opt_desc)
+ v.at_return + annot('return', comma1(Ct(v.ctype * opt(ws * cname))) * opt_desc)
+ v.at_type + annot('type', comma1(Ct(v.ctype)) * opt_desc)
+ v.at_cast + annot('cast', cname * ws * opt(Sf('+-')) * v.ctype)
+ v.at_generic + annot('generic', cname * opt(colon * v.ctype))
+ v.at_class + annot('class', opt_exact * opt(paren(caccess)) * fill * cname * opt_parent)
+ v.at_field + annot('field', opt(caccess * ws) * v.field_name * ws * v.ctype * opt_desc)
+ v.at_access + annot('operator', cname * opt(paren(Cg(v.ltype, 'argtype'))) * colon * v.ctype)
+ v.at_deprecated + annot(access)
+ v.at_alias + annot('deprecated')
+ v.at_enum + annot('alias', cname * opt(ws * v.ctype))
+ v.at_see + annot('enum', cname)
+ v.at_diagnostic + annot('overload', v.ctype)
+ v.at_overload + annot('see', opt(desc_delim) * desc)
+ v.at_meta, + annot('diagnostic', opt(desc_delim) * desc)
+ annot('meta'),
ext_ats = v.ext_at_note + v.ext_at_since + v.ext_at_nodoc + v.ext_at_brief,
at_param = Ct(
Cg(P('param'), 'kind')
* ws
* Cg(lname, 'name')
* ws
* parenOpt(Cg(v.ltype, 'type'))
* opt(desc_delim * Cg(rep(any), 'desc'))
),
at_return = Ct(
Cg(P('return'), 'kind')
* ws
* parenOpt(comma(Ct(Cg(v.ltype, 'type') * opt(ws * Cg(ident, 'name')))))
* opt(desc_delim * Cg(rep(any), 'desc'))
),
at_type = Ct(
Cg(P('type'), 'kind')
* ws
* parenOpt(comma(Ct(Cg(v.ltype, 'type'))))
* opt(desc_delim * Cg(rep(any), 'desc'))
),
at_cast = Ct(
Cg(P('cast'), 'kind') * ws * Cg(lname, 'name') * ws * opt(Sf('+-')) * Cg(v.ltype, 'type')
),
at_generic = Ct(
Cg(P('generic'), 'kind') * ws * Cg(ident, 'name') * opt(Pf ':' * Cg(v.ltype, 'type'))
),
at_class = Ct(
Cg(P('class'), 'kind')
* ws
* opt(P('(exact)') * ws)
* Cg(lname, 'name')
* opt(Pf(':') * Cg(lname, 'parent'))
),
at_field = Ct(
Cg(P('field'), 'kind')
* ws
* opt(Cg(Pf('private') + Pf('package') + Pf('protected'), 'access'))
* Cg(lname, 'name')
* ws
* Cg(v.ltype, 'type')
* opt(desc_delim * Cg(rep(any), 'desc'))
),
at_access = Ct(Cg(P('private') + P('protected') + P('package'), 'kind')),
at_deprecated = Ct(Cg(P('deprecated'), 'kind')),
-- Types may be provided on subsequent lines
at_alias = Ct(Cg(P('alias'), 'kind') * ws * Cg(lname, 'name') * opt(ws * Cg(v.ltype, 'type'))),
at_enum = Ct(Cg(P('enum'), 'kind') * ws * Cg(lname, 'name')),
at_see = Ct(Cg(P('see'), 'kind') * ws * opt(Pf('#')) * Cg(rep(any), 'desc')),
at_diagnostic = Ct(Cg(P('diagnostic'), 'kind') * ws * opt(Pf('#')) * Cg(rep(any), 'desc')),
at_overload = Ct(Cg(P('overload'), 'kind') * ws * Cg(v.ltype, 'type')),
at_meta = Ct(Cg(P('meta'), 'kind')),
--- Custom extensions --- Custom extensions
ext_at_note = Ct(Cg(P('note'), 'kind') * ws * Cg(rep(any), 'desc')), ext_ats = (
annot('note', desc)
+ annot('since', desc)
+ annot('nodoc')
+ annot('inlinedoc')
+ annot('brief', desc)
),
-- TODO only consume 1 line field_name = Cg(lname + (v.ty_index * opt(P('?'))), 'name'),
ext_at_since = Ct(Cg(P('since'), 'kind') * ws * Cg(rep(any), 'desc')),
ext_at_nodoc = Ct(Cg(P('nodoc'), 'kind')), ctype = parenOpt(Cg(v.ltype, 'type')),
ext_at_brief = Ct(Cg(P('brief'), 'kind') * opt(ws * Cg(rep(any), 'desc'))), ltype = parenOpt(v.ty_union),
ltype = v.ty_union + Pf '(' * v.ty_union * fill * P ')', ty_union = v.ty_opt * rep(Pf('|') * v.ty_opt),
ty_union = v.ty_opt * rep(Pf '|' * v.ty_opt),
ty = v.ty_fun + ident + v.ty_table + literal, ty = v.ty_fun + ident + v.ty_table + literal,
ty_param = Pf '<' * comma(v.ltype) * fill * P '>', ty_param = Pf('<') * comma1(v.ltype) * fill * P('>'),
ty_opt = v.ty * opt(v.ty_param) * opt(P '[]') * opt(P '?'), ty_opt = v.ty * opt(v.ty_param) * opt(P('[]')) * opt(P('?')),
ty_index = (Pf('[') * v.ltype * Pf(']')),
table_key = (Pf '[' * literal * Pf ']') + lname, table_key = v.ty_index + lname,
table_elem = v.table_key * Pf ':' * v.ltype, table_elem = v.table_key * colon * v.ltype,
ty_table = Pf '{' * comma(v.table_elem) * Pf '}', ty_table = Pf('{') * comma1(v.table_elem) * Pf('}'),
fun_param = lname * opt(colon * v.ltype),
fun_param = lname * opt(Pf ':' * v.ltype), ty_fun = Pf('fun') * paren(comma(lname * opt(colon * v.ltype))) * opt(colon * comma1(v.ltype)),
ty_fun = Pf 'fun(' * rep(comma(v.fun_param)) * fill * P ')' * opt(Pf ':' * comma(v.ltype)),
} }
return grammar --[[@as nvim.luacats.grammar]] return grammar --[[@as nvim.luacats.grammar]]

View File

@@ -19,7 +19,7 @@ local luacats_grammar = require('scripts.luacats_grammar')
--- @class nvim.luacats.parser.alias --- @class nvim.luacats.parser.alias
--- @field kind 'alias' --- @field kind 'alias'
--- @field type string --- @field type string[]
--- @field desc string --- @field desc string
--- @class nvim.luacats.parser.fun --- @class nvim.luacats.parser.fun
@@ -49,8 +49,12 @@ local luacats_grammar = require('scripts.luacats_grammar')
--- @class nvim.luacats.parser.class --- @class nvim.luacats.parser.class
--- @field kind 'class' --- @field kind 'class'
--- @field parent? string
--- @field name string --- @field name string
--- @field desc string --- @field desc string
--- @field nodoc? true
--- @field inlinedoc? true
--- @field access? 'private'|'package'|'protected'
--- @field fields nvim.luacats.parser.field[] --- @field fields nvim.luacats.parser.field[]
--- @field notes? string[] --- @field notes? string[]
@@ -64,6 +68,7 @@ local luacats_grammar = require('scripts.luacats_grammar')
--- | nvim.luacats.parser.class --- | nvim.luacats.parser.class
--- | nvim.luacats.parser.fun --- | nvim.luacats.parser.fun
--- | nvim.luacats.parser.brief --- | nvim.luacats.parser.brief
--- | nvim.luacats.parser.alias
-- Remove this when we document classes properly -- Remove this when we document classes properly
--- Some doc lines have the form: --- Some doc lines have the form:
@@ -142,22 +147,27 @@ local function process_doc_line(line, state)
} }
elseif kind == 'class' then elseif kind == 'class' then
--- @cast parsed nvim.luacats.Class --- @cast parsed nvim.luacats.Class
state.cur_obj = { cur_obj.kind = 'class'
kind = 'class', cur_obj.name = parsed.name
name = parsed.name, cur_obj.parent = parsed.parent
parent = parsed.parent, cur_obj.access = parsed.access
desc = '', cur_obj.desc = state.doc_lines and table.concat(state.doc_lines, '\n') or nil
fields = {}, state.doc_lines = nil
} cur_obj.fields = {}
elseif kind == 'field' then elseif kind == 'field' then
--- @cast parsed nvim.luacats.Field --- @cast parsed nvim.luacats.Field
if not parsed.access then parsed.desc = parsed.desc or state.doc_lines and table.concat(state.doc_lines, '\n') or nil
parsed.desc = parsed.desc or state.doc_lines and table.concat(state.doc_lines, '\n') or nil if parsed.desc then
if parsed.desc then parsed.desc = vim.trim(parsed.desc)
parsed.desc = vim.trim(parsed.desc)
end
table.insert(cur_obj.fields, parsed)
end end
table.insert(cur_obj.fields, parsed)
state.doc_lines = nil
elseif kind == 'operator' then
parsed.desc = parsed.desc or state.doc_lines and table.concat(state.doc_lines, '\n') or nil
if parsed.desc then
parsed.desc = vim.trim(parsed.desc)
end
table.insert(cur_obj.fields, parsed)
state.doc_lines = nil state.doc_lines = nil
elseif kind == 'param' then elseif kind == 'param' then
state.last_doc_item_indent = nil state.last_doc_item_indent = nil
@@ -191,6 +201,8 @@ local function process_doc_line(line, state)
cur_obj.access = 'protected' cur_obj.access = 'protected'
elseif kind == 'deprecated' then elseif kind == 'deprecated' then
cur_obj.deprecated = true cur_obj.deprecated = true
elseif kind == 'inlinedoc' then
cur_obj.inlinedoc = true
elseif kind == 'nodoc' then elseif kind == 'nodoc' then
cur_obj.nodoc = true cur_obj.nodoc = true
elseif kind == 'since' then elseif kind == 'since' then
@@ -383,11 +395,11 @@ end
--- Determine the table name used to export functions of a module --- Determine the table name used to export functions of a module
--- Usually this is `M`. --- Usually this is `M`.
--- @param filename string --- @param str string
--- @return string? --- @return string?
local function determine_modvar(filename) local function determine_modvar(str)
local modvar --- @type string? local modvar --- @type string?
for line in io.lines(filename) do for line in vim.gsplit(str, '\n') do
do do
--- @type string? --- @type string?
local m = line:match('^return%s+([a-zA-Z_]+)') local m = line:match('^return%s+([a-zA-Z_]+)')
@@ -462,17 +474,12 @@ end
local M = {} local M = {}
--- @param filename string function M.parse_str(str, filename)
--- @return table<string,nvim.luacats.parser.class> classes
--- @return nvim.luacats.parser.fun[] funs
--- @return string[] briefs
--- @return nvim.luacats.parser.obj[]
function M.parse(filename)
local funs = {} --- @type nvim.luacats.parser.fun[] local funs = {} --- @type nvim.luacats.parser.fun[]
local classes = {} --- @type table<string,nvim.luacats.parser.class> local classes = {} --- @type table<string,nvim.luacats.parser.class>
local briefs = {} --- @type string[] local briefs = {} --- @type string[]
local mod_return = determine_modvar(filename) local mod_return = determine_modvar(str)
--- @type string --- @type string
local module = filename:match('.*/lua/([a-z_][a-z0-9_/]+)%.lua') or filename local module = filename:match('.*/lua/([a-z_][a-z0-9_/]+)%.lua') or filename
@@ -485,7 +492,7 @@ function M.parse(filename)
-- Keep track of any partial objects we don't commit -- Keep track of any partial objects we don't commit
local uncommitted = {} --- @type nvim.luacats.parser.obj[] local uncommitted = {} --- @type nvim.luacats.parser.obj[]
for line in io.lines(filename) do for line in vim.gsplit(str, '\n') do
local has_indent = line:match('^%s+') ~= nil local has_indent = line:match('^%s+') ~= nil
line = vim.trim(line) line = vim.trim(line)
if vim.startswith(line, '---') then if vim.startswith(line, '---') then
@@ -518,4 +525,13 @@ function M.parse(filename)
return classes, funs, briefs, uncommitted return classes, funs, briefs, uncommitted
end end
--- @param filename string
function M.parse(filename)
local f = assert(io.open(filename, 'r'))
local txt = f:read('*all')
f:close()
return M.parse_str(txt, filename)
end
return M return M

View File

@@ -175,7 +175,11 @@ local function render_md(node, start_indent, indent, text_width, level, is_list)
error(fmt('cannot render:\n%s', vim.inspect(node))) error(fmt('cannot render:\n%s', vim.inspect(node)))
end end
for i, child in ipairs(node) do for i, child in ipairs(node) do
vim.list_extend(parts, render_md(child, start_indent, indent, text_width, level + 1, is_list)) local start_indent0 = i == 1 and start_indent or indent
vim.list_extend(
parts,
render_md(child, start_indent0, indent, text_width, level + 1, is_list)
)
if node.type ~= 'list' and i ~= #node then if node.type ~= 'list' and i ~= #node then
if (node[i + 1] or {}).type ~= 'list' then if (node[i + 1] or {}).type ~= 'list' then
parts[#parts + 1] = '\n' parts[#parts + 1] = '\n'

View File

@@ -0,0 +1,106 @@
local helpers = require('test.functional.helpers')(after_each)
local eq = helpers.eq
local parser = require('scripts/luacats_parser')
--- @param name string
--- @param text string
--- @param exp table<string,string>
local function test(name, text, exp)
exp = vim.deepcopy(exp, true)
it(name, function()
eq(exp, parser.parse_str(text, 'myfile.lua'))
end)
end
describe('luacats parser', function()
local exp = {
myclass = {
kind = 'class',
module = 'myfile.lua',
name = 'myclass',
fields = {
{ kind = 'field', name = 'myclass', type = 'integer' },
},
},
}
test(
'basic class',
[[
--- @class myclass
--- @field myclass integer
]],
exp
)
exp.myclass.inlinedoc = true
test(
'class with @inlinedoc (1)',
[[
--- @class myclass
--- @inlinedoc
--- @field myclass integer
]],
exp
)
test(
'class with @inlinedoc (2)',
[[
--- @inlinedoc
--- @class myclass
--- @field myclass integer
]],
exp
)
exp.myclass.inlinedoc = nil
exp.myclass.nodoc = true
test(
'class with @nodoc',
[[
--- @nodoc
--- @class myclass
--- @field myclass integer
]],
exp
)
exp.myclass.nodoc = nil
exp.myclass.access = 'private'
test(
'class with (private)',
[[
--- @class (private) myclass
--- @field myclass integer
]],
exp
)
exp.myclass.fields[1].desc = 'Field\ndocumentation'
test(
'class with field doc above',
[[
--- @class (private) myclass
--- Field
--- documentation
--- @field myclass integer
]],
exp
)
exp.myclass.fields[1].desc = 'Field documentation'
test(
'class with field doc inline',
[[
--- @class (private) myclass
--- @field myclass integer Field documentation
]],
exp
)
end)

View File

@@ -2,18 +2,28 @@ local helpers = require('test.functional.helpers')(after_each)
local exec_lua = helpers.exec_lua local exec_lua = helpers.exec_lua
local eq = helpers.eq local eq = helpers.eq
local function md_to_vimdoc(text) local function md_to_vimdoc(text, start_indent, indent, text_width)
return exec_lua( return exec_lua(
[[ [[
local text, start_indent, indent, text_width = ...
start_indent = start_indent or 0
indent = indent or 0
text_width = text_width or 70
local text_utils = require('scripts/text_utils') local text_utils = require('scripts/text_utils')
return text_utils.md_to_vimdoc(table.concat(..., '\n'), 0, 0, 70) return text_utils.md_to_vimdoc(table.concat(text, '\n'), start_indent, indent, text_width)
]], ]],
text text,
start_indent,
indent,
text_width
) )
end end
local function test(act, exp) local function test(what, act, exp, ...)
eq(table.concat(exp, '\n'), md_to_vimdoc(act)) local argc, args = select('#', ...), { ... }
it(what, function()
eq(table.concat(exp, '\n'), md_to_vimdoc(act, unpack(args, 1, argc)))
end)
end end
describe('md_to_vimdoc', function() describe('md_to_vimdoc', function()
@@ -21,19 +31,28 @@ describe('md_to_vimdoc', function()
helpers.clear() helpers.clear()
end) end)
it('can render para after fenced code', function() test('can render para after fenced code', {
test({ '- Para1',
'- Para1', ' ```',
' ```', ' code',
' code', ' ```',
' ```', ' Para2',
' Para2', }, {
}, { '• Para1 >',
'• Para1 >', ' code',
' code', '<',
'<', ' Para2',
' Para2', '',
'', })
})
end) test('start_indent only applies to first line', {
'para1',
'',
'para2',
}, {
'para1',
'',
' para2',
'',
}, 0, 10, 78)
end) end)