mirror of
https://github.com/neovim/neovim.git
synced 2026-09-08 23:18:59 +00:00
build: replace LuaLS with EmmyLua
Problem: LuaLS struggles with the generics used in Nvim's runtime, requiring broad diagnostic suppressions. Indexing is also slow. Solution: Use EmmyLua for type checks in the build and CI. It offers more sophisticated type checking, substantially better support for generics, and much better flow analysis. Correct the affected annotations. Use `@internal`, supported directly by EmmyLua, instead of `@nodoc` for shared internal declarations, and support it in the help parser. AI-assisted
This commit is contained in:
committed by
Lewis Russell
parent
cd52c77cd5
commit
65ef6fdaee
46
.emmyrc.json
46
.emmyrc.json
@@ -1,5 +1,19 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/EmmyLuaLs/emmylua-analyzer-rust/refs/heads/main/crates/emmylua_code_analysis/resources/schema.json",
|
||||
"$schema": "https://raw.githubusercontent.com/EmmyLuaLs/emmylua-analyzer-rust/0.25.1/crates/emmylua_code_analysis/resources/schema.json",
|
||||
"runtime": {
|
||||
"version": "LuaJIT"
|
||||
},
|
||||
"workspace": {
|
||||
"ignoreDir": [
|
||||
".deps",
|
||||
"build"
|
||||
],
|
||||
"ignoreGlobs": [
|
||||
"**/example_init.lua",
|
||||
"test/**/fixtures/**"
|
||||
],
|
||||
"preloadFileSize": 1000
|
||||
},
|
||||
"format": {
|
||||
"externalTool": {
|
||||
"program": "stylua",
|
||||
@@ -12,9 +26,35 @@
|
||||
},
|
||||
"diagnostics": {
|
||||
"disable": [
|
||||
"annotation-usage-error",
|
||||
"assign-type-mismatch",
|
||||
"await-in-sync",
|
||||
"call-non-callable",
|
||||
"code-style-check",
|
||||
"deprecated",
|
||||
"global-in-non-module",
|
||||
"incomplete-signature-doc",
|
||||
"invert-if",
|
||||
"iter-variable-reassign",
|
||||
"missing-fields",
|
||||
"missing-global-doc",
|
||||
"need-check-nil",
|
||||
"non-literal-expressions-in-assert",
|
||||
"param-type-mismatch",
|
||||
"preferred-local-alias",
|
||||
"unnecessary-if"
|
||||
]
|
||||
"redefined-label",
|
||||
"redefined-local",
|
||||
"return-type-mismatch",
|
||||
"undefined-field",
|
||||
"unknown-doc-tag",
|
||||
"unnecessary-assert",
|
||||
"unnecessary-if",
|
||||
"unreachable-code",
|
||||
"unused"
|
||||
],
|
||||
"severity": {
|
||||
"duplicate-require": "warning"
|
||||
}
|
||||
},
|
||||
"codeAction": {
|
||||
"insertSpace": true
|
||||
|
||||
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
@@ -105,8 +105,8 @@ jobs:
|
||||
run: cmake --build build --target lintlua-stylua
|
||||
|
||||
- if: success() || failure() && steps.abort_job.outputs.status == 'success'
|
||||
name: luals
|
||||
run: cmake --build build --target luals
|
||||
name: emmylua
|
||||
run: cmake --build build --target emmylua-check
|
||||
|
||||
- if: success() || failure() && steps.abort_job.outputs.status == 'success'
|
||||
name: lintsh
|
||||
|
||||
56
.luarc.json
56
.luarc.json
@@ -1,32 +1,34 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
|
||||
"runtime": {
|
||||
"version": "LuaJIT"
|
||||
},
|
||||
"workspace": {
|
||||
"ignoreDir": [
|
||||
"/lua/vim/async.lua",
|
||||
".deps",
|
||||
"build"
|
||||
],
|
||||
"ignoreGlobs": [
|
||||
"test/**/fixtures/**"
|
||||
],
|
||||
"preloadFileSize": 1000,
|
||||
"checkThirdParty": "Disable"
|
||||
},
|
||||
"diagnostics": {
|
||||
"groupFileStatus": {
|
||||
"strict": "Opened",
|
||||
"strong": "Opened"
|
||||
"$comment": "Keep LuaLS settings under Lua so EmmyLua ignores them.",
|
||||
"Lua": {
|
||||
"runtime": {
|
||||
"version": "LuaJIT"
|
||||
},
|
||||
"groupSeverity": {
|
||||
"strong": "Warning",
|
||||
"strict": "Warning"
|
||||
"workspace": {
|
||||
"ignoreDir": [
|
||||
"/lua/vim/async.lua",
|
||||
".deps",
|
||||
"build"
|
||||
],
|
||||
"ignoreGlobs": [
|
||||
"test/**/fixtures/**"
|
||||
],
|
||||
"preloadFileSize": 1000,
|
||||
"checkThirdParty": "Disable"
|
||||
},
|
||||
"unusedLocalExclude": [ "_*" ],
|
||||
"disable": [
|
||||
"luadoc-miss-see-name"
|
||||
]
|
||||
"diagnostics": {
|
||||
"groupFileStatus": {
|
||||
"strict": "Opened",
|
||||
"strong": "Opened"
|
||||
},
|
||||
"groupSeverity": {
|
||||
"strong": "Warning",
|
||||
"strict": "Warning"
|
||||
},
|
||||
"unusedLocalExclude": [ "_*" ],
|
||||
"disable": [
|
||||
"luadoc-miss-see-name"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,21 +331,34 @@ ExternalProject_Add(uncrustify
|
||||
EXCLUDE_FROM_ALL TRUE
|
||||
${EXTERNALPROJECT_OPTIONS})
|
||||
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "arm|aarch")
|
||||
set(LUALS_ARCH arm64)
|
||||
if (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "arm|aarch|ARM")
|
||||
set(EMMYLUA_ARCH arm64)
|
||||
else()
|
||||
set(LUALS_ARCH x64)
|
||||
set(EMMYLUA_ARCH x64)
|
||||
endif()
|
||||
|
||||
set(LUALS_VERSION 3.15.0)
|
||||
set(LUALS "lua-language-server-${LUALS_VERSION}-${CMAKE_SYSTEM_NAME}-${LUALS_ARCH}")
|
||||
set(LUALS_TARBALL ${LUALS}.tar.gz)
|
||||
set(LUALS_URL https://github.com/LuaLS/lua-language-server/releases/download/${LUALS_VERSION}/${LUALS_TARBALL})
|
||||
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} EMMYLUA_SYSTEM)
|
||||
set(EMMYLUA_ARCHIVE_EXT tar.gz)
|
||||
set(EMMYLUA_EXE_EXT "")
|
||||
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
|
||||
if(EMMYLUA_ARCH STREQUAL "arm64")
|
||||
set(EMMYLUA_ARCH aarch64)
|
||||
endif()
|
||||
string(APPEND EMMYLUA_ARCH "-glibc.2.17")
|
||||
elseif(CMAKE_HOST_WIN32)
|
||||
set(EMMYLUA_SYSTEM win32)
|
||||
set(EMMYLUA_ARCHIVE_EXT zip)
|
||||
set(EMMYLUA_EXE_EXT .exe)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(download_luals
|
||||
URL ${LUALS_URL}
|
||||
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/luals
|
||||
SOURCE_DIR ${DEPS_BIN_DIR}/luals
|
||||
set(EMMYLUA_VERSION 0.25.1)
|
||||
set(EMMYLUA_ARCHIVE "emmylua_check-${EMMYLUA_SYSTEM}-${EMMYLUA_ARCH}.${EMMYLUA_ARCHIVE_EXT}")
|
||||
set(EMMYLUA_URL https://github.com/EmmyLuaLs/emmylua-analyzer-rust/releases/download/${EMMYLUA_VERSION}/${EMMYLUA_ARCHIVE})
|
||||
|
||||
ExternalProject_Add(download_emmylua
|
||||
URL ${EMMYLUA_URL}
|
||||
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/emmylua
|
||||
SOURCE_DIR ${DEPS_BIN_DIR}/emmylua
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
@@ -353,13 +366,13 @@ ExternalProject_Add(download_luals
|
||||
DOWNLOAD_NO_PROGRESS TRUE
|
||||
CMAKE_CACHE_ARGS ${DEPS_CMAKE_CACHE_ARGS})
|
||||
|
||||
file(GLOB_RECURSE LUAFILES runtime/*.lua)
|
||||
add_target(luals
|
||||
COMMAND ${DEPS_BIN_DIR}/luals/bin/lua-language-server
|
||||
--configpath=${PROJECT_SOURCE_DIR}/.luarc.json
|
||||
--check=${PROJECT_SOURCE_DIR}/runtime
|
||||
--checklevel=Hint
|
||||
DEPENDS ${LUAFILES}
|
||||
CUSTOM_COMMAND_ARGS USES_TERMINAL)
|
||||
add_custom_target(emmylua-check
|
||||
COMMAND ${DEPS_BIN_DIR}/emmylua/emmylua_check${EMMYLUA_EXE_EXT}
|
||||
${PROJECT_SOURCE_DIR}/runtime
|
||||
--config ${PROJECT_SOURCE_DIR}/.emmyrc.json
|
||||
--warnings-as-errors
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
USES_TERMINAL
|
||||
VERBATIM)
|
||||
|
||||
add_dependencies(luals download_luals)
|
||||
add_dependencies(emmylua-check download_emmylua)
|
||||
|
||||
@@ -300,9 +300,12 @@ If you need to modify or debug the documentation flow, these are the main files:
|
||||
|
||||
### Lua docstrings
|
||||
|
||||
Use [LuaLS] annotations in Lua docstrings to annotate parameter types, return
|
||||
Use [LuaCATS] annotations in Lua docstrings to annotate parameter types, return
|
||||
types, etc. See [:help dev-lua-doc][dev-lua-doc].
|
||||
|
||||
Run `make emmylua-check` to check the runtime with [EmmyLua]. The build downloads
|
||||
the pinned checker automatically. Settings are in `.emmyrc.json`.
|
||||
|
||||
Third-party dependencies
|
||||
------------------------
|
||||
|
||||
@@ -353,7 +356,8 @@ as context, use the `-W` argument as well.
|
||||
[conventional_commits]: https://www.conventionalcommits.org
|
||||
[dev-doc-guide]: https://neovim.io/doc/user/dev.html#dev-doc
|
||||
[dev-lua-doc]: https://neovim.io/doc/user/dev.html#dev-lua-doc
|
||||
[LuaLS]: https://luals.github.io/wiki/annotations/
|
||||
[LuaCATS]: https://luals.github.io/wiki/annotations/
|
||||
[EmmyLua]: https://github.com/EmmyLuaLs/emmylua-analyzer-rust
|
||||
[gcc-warnings]: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
|
||||
[gh]: https://cli.github.com/
|
||||
[git-bisect]: http://git-scm.com/book/en/v2/Git-Tools-Debugging-with-Git
|
||||
@@ -362,7 +366,6 @@ as context, use the `-W` argument as well.
|
||||
[github-issues]: https://github.com/neovim/neovim/issues
|
||||
[include-what-you-use-install]: https://github.com/include-what-you-use/include-what-you-use#how-to-install
|
||||
[include-what-you-use]: https://github.com/include-what-you-use/include-what-you-use#using-with-cmake
|
||||
[lua-language-server]: https://github.com/sumneko/lua-language-server/
|
||||
[nvim-lspconfig/clangd]: https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#clangd
|
||||
[pr-draft]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request
|
||||
[pr-ready]: https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-stage-of-a-pull-request
|
||||
|
||||
8
Makefile
8
Makefile
@@ -147,7 +147,7 @@ functionaltest-lua: | nvim
|
||||
$(CMAKE) --build build --target functionaltest
|
||||
|
||||
FORMAT=formatc formatlua formatquery format
|
||||
LINT=lintlua lintsh lintc clang-analyzer lintcommit lintdoc lintdocurls lint luals lintquery linterrcodes
|
||||
LINT=lintlua lintsh lintc clang-analyzer lintcommit lintdoc lintdocurls lint emmylua-check lintquery linterrcodes
|
||||
TEST=functionaltest unittest
|
||||
generated-sources benchmark $(FORMAT) $(LINT) $(TEST) doc: | build/.ran-cmake
|
||||
$(CMAKE) --build build --target $@
|
||||
@@ -194,9 +194,3 @@ appimage-%:
|
||||
bash scripts/genappimage.sh $*
|
||||
|
||||
.PHONY: test clean distclean nvim libnvim cmake deps install appimage checkprefix benchmark $(FORMAT) $(LINT) $(TEST)
|
||||
|
||||
.PHONY: emmylua-check
|
||||
emmylua-check:
|
||||
-emmylua_check runtime/lua \
|
||||
--config .luarc.json \
|
||||
--config .emmyrc.json
|
||||
|
||||
@@ -249,9 +249,11 @@ Docstring format:
|
||||
- See scripts/util.lua for the mapping of api-level to Nvim version.
|
||||
- Use `@deprecated` to mark deprecated functions.
|
||||
- Use `@nodoc` to prevent documentation generation.
|
||||
- Use `@private` if the function is internal or otherwise non-public.
|
||||
- Use `@private` for private functions.
|
||||
- Naming a function with an underscore prefix ("_foo", not "foo") implies
|
||||
`@nodoc` and `@private`.
|
||||
- Use `@internal` for non-public functions shared across Nvim modules, or
|
||||
`@class (internal)` for shared internal types. Both hide generated docs.
|
||||
- Use `@inlinedoc` to inline `@class` blocks into `@param` blocks.
|
||||
E.g. >lua
|
||||
--- Object with fields:
|
||||
|
||||
@@ -419,14 +419,15 @@ Example: https://github.com/neovim/neovim/pull/35768
|
||||
|
||||
FIXING LINT FAILURES
|
||||
|
||||
`make lint` (and `make lintlua`) runs [LuaLS](https://github.com/LuaLS/lua-language-server/wiki/Annotations)
|
||||
on the test code.
|
||||
`make emmylua-check` runs EmmyLua on the runtime Lua code, using `.emmyrc.json`.
|
||||
The checker is downloaded automatically. Enable more checks incrementally by
|
||||
removing codes from `diagnostics.disable` and fixing the resulting diagnostics.
|
||||
|
||||
If a LuaLS/EmmyLS warning must be ignored, specify the warning code. Example: >lua
|
||||
If an EmmyLua warning must be ignored, specify the warning code. Example: >lua
|
||||
|
||||
---@diagnostic disable-next-line: unused-vararg
|
||||
---@diagnostic disable-next-line: unused
|
||||
|
||||
https://github.com/LuaLS/lua-language-server/wiki/Annotations#diagnostic
|
||||
https://github.com/EmmyLuaLs/emmylua-analyzer-rust
|
||||
|
||||
Ignore the smallest applicable scope (e.g. inside a function, not at the top of
|
||||
the file).
|
||||
|
||||
@@ -1650,19 +1650,19 @@ Ringbuf:peek() *Ringbuf:peek()*
|
||||
Returns the first unread item without removing it
|
||||
|
||||
Return: ~
|
||||
(`any?`)
|
||||
(`T?`)
|
||||
|
||||
Ringbuf:pop() *Ringbuf:pop()*
|
||||
Removes and returns the first unread item
|
||||
|
||||
Return: ~
|
||||
(`any?`)
|
||||
(`T?`)
|
||||
|
||||
Ringbuf:push({item}) *Ringbuf:push()*
|
||||
Adds an item, overriding the oldest item if the buffer is full.
|
||||
|
||||
Parameters: ~
|
||||
• {item} (`any`)
|
||||
• {item} (`T`)
|
||||
|
||||
vim.deep_equal({a}, {b}) *vim.deep_equal()*
|
||||
Deep compare values for equality
|
||||
@@ -2034,7 +2034,7 @@ vim.ringbuf({size}) *vim.ringbuf()*
|
||||
• {size} (`integer`)
|
||||
|
||||
Return: ~
|
||||
(`vim.Ringbuf`) ringbuf
|
||||
(`vim.Ringbuf<any>`) ringbuf
|
||||
|
||||
vim.spairs({t}) *vim.spairs()*
|
||||
Enumerates key-value pairs of a table, ordered by key.
|
||||
@@ -2982,7 +2982,7 @@ vim.fs.slug({path}, {opts}) *vim.fs.slug()*
|
||||
|
||||
Parameters: ~
|
||||
• {path} (`string`) Filepath (or other identity string).
|
||||
• {opts} (`table?`)
|
||||
• {opts} (`{ maxlen?: integer }?`)
|
||||
• maxlen: (integer, default: 180) Max length (bytes) of the
|
||||
result.
|
||||
|
||||
@@ -3573,7 +3573,7 @@ Iter:totable() *Iter:totable()*
|
||||
Since: 0.10.0
|
||||
|
||||
Overloads: ~
|
||||
• `fun<T>(self: vim.Iter<T>): T[]`
|
||||
• `fun<T>(self: vim.Iter<T, never>): T[]`
|
||||
• `fun<V1, V2, V...>(self: vim.Iter<V1, V2, V...>): [V1, V2, V...][]`
|
||||
|
||||
Return: ~
|
||||
|
||||
@@ -6,7 +6,7 @@ local api = vim.api
|
||||
local M = {}
|
||||
|
||||
--- An entry rendered as one line in a listing buffer.
|
||||
---@class (private) nvim.dir.Entry
|
||||
---@class (internal) nvim.dir.Entry
|
||||
---@field name string
|
||||
---@field dir boolean
|
||||
|
||||
|
||||
@@ -493,9 +493,8 @@ vim.cmd = setmetatable({}, {
|
||||
--- @param t table<string,function>
|
||||
__index = function(t, cmd)
|
||||
t[cmd] = function(...)
|
||||
local opts --- @type vim.api.keyset.cmd
|
||||
local opts --- @type vim.api.keyset.cmd & { [integer]: any }
|
||||
if select('#', ...) == 1 and type(select(1, ...)) == 'table' then
|
||||
--- @type vim.api.keyset.cmd
|
||||
opts = select(1, ...)
|
||||
|
||||
-- Move indexed positions in opts to opt.args
|
||||
@@ -506,7 +505,6 @@ vim.cmd = setmetatable({}, {
|
||||
break
|
||||
end
|
||||
opts.args[i] = opts[i]
|
||||
--- @diagnostic disable-next-line: no-unknown
|
||||
opts[i] = nil
|
||||
end
|
||||
end
|
||||
@@ -565,7 +563,7 @@ end
|
||||
---@param bufnr integer Buffer number, or 0 for current buffer
|
||||
---@param pos1 integer[]|string Start of region as a (line, column) tuple or |getpos()|-compatible string
|
||||
---@param pos2 integer[]|string End of region as a (line, column) tuple or |getpos()|-compatible string
|
||||
---@param regtype string [setreg()]-style selection type
|
||||
---@param regtype string # [setreg()]-style selection type
|
||||
---@param inclusive boolean Controls whether the ending column is inclusive (see also 'selection').
|
||||
---@return table region Dict of the form `{linenr = {startcol,endcol}}`. `endcol` is exclusive, and
|
||||
---whole lines are returned as `{startcol,endcol} = {0,-1}`.
|
||||
|
||||
@@ -1331,11 +1331,11 @@ end
|
||||
|
||||
do
|
||||
---@class vim.Ringbuf<T>
|
||||
---@field private _items table[]
|
||||
---@field private _items table<integer, T?>
|
||||
---@field private _idx_read integer
|
||||
---@field private _idx_write integer
|
||||
---@field private _size integer
|
||||
---@overload fun(self): table?
|
||||
---@overload fun(self: vim.Ringbuf<T>): T?
|
||||
local Ringbuf = {}
|
||||
|
||||
--- Clear all items
|
||||
@@ -1346,7 +1346,6 @@ do
|
||||
end
|
||||
|
||||
--- Adds an item, overriding the oldest item if the buffer is full.
|
||||
---@generic T
|
||||
---@param item T
|
||||
function Ringbuf.push(self, item)
|
||||
self._items[self._idx_write] = item
|
||||
@@ -1357,7 +1356,6 @@ do
|
||||
end
|
||||
|
||||
--- Removes and returns the first unread item
|
||||
---@generic T
|
||||
---@return T?
|
||||
function Ringbuf.pop(self)
|
||||
local idx_read = self._idx_read
|
||||
@@ -1371,7 +1369,6 @@ do
|
||||
end
|
||||
|
||||
--- Returns the first unread item without removing it
|
||||
---@generic T
|
||||
---@return T?
|
||||
function Ringbuf.peek(self)
|
||||
if self._idx_read == self._idx_write then
|
||||
@@ -1407,7 +1404,7 @@ do
|
||||
--- - |Ringbuf:clear()|
|
||||
---
|
||||
---@param size integer
|
||||
---@return vim.Ringbuf ringbuf
|
||||
---@return vim.Ringbuf<any> ringbuf
|
||||
function vim.ringbuf(size)
|
||||
local ringbuf = {
|
||||
_items = {},
|
||||
|
||||
@@ -33,10 +33,10 @@ local M = {
|
||||
},
|
||||
virt = { -- Stored virt_text state.
|
||||
last = { {}, {}, {}, {} }, ---@type MsgContent[] status in last cmdline row.
|
||||
cmd = { {}, {} }, ---@type MsgContent[] [(x)] indicators in cmd window.
|
||||
msg = { {}, {} }, ---@type MsgContent[] [(x)] indicators in msg window.
|
||||
top = { {} }, ---@type MsgContent[] [+x] top indicator in dialog window.
|
||||
bot = { {} }, ---@type MsgContent[] [+x] bottom indicator in dialog window.
|
||||
cmd = { {}, {} }, ---@type MsgContent[] # [(x)] indicators in cmd window.
|
||||
msg = { {}, {} }, ---@type MsgContent[] # [(x)] indicators in msg window.
|
||||
top = { {} }, ---@type MsgContent[] # [+x] top indicator in dialog window.
|
||||
bot = { {} }, ---@type MsgContent[] # [+x] bottom indicator in dialog window.
|
||||
idx = { mode = 1, search = 2, cmd = 3, ruler = 4, spill = 1, dupe = 2 },
|
||||
ids = {}, ---@type { ['last'|'cmd'|'msg'|'top'|'bot']: integer? } Table of mark IDs.
|
||||
delayed = false, -- Whether placement of 'last' virt_text is delayed.
|
||||
|
||||
@@ -288,7 +288,7 @@ function M.timeout(duration, task)
|
||||
timed_out = true
|
||||
task:close()
|
||||
end)
|
||||
--- @diagnostic disable-next-line: invisible
|
||||
--- @diagnostic disable-next-line: access-invisible
|
||||
timer._hidden = true
|
||||
|
||||
local result = F.pack_len(M.pawait(task))
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
-- LuaLS cannot model the generic annotations used by this vendored implementation.
|
||||
---@diagnostic disable: no-unknown, undefined-doc-name, luadoc-miss-symbol, missing-return, missing-return-value, param-type-mismatch, return-type-mismatch, redundant-return-value, undefined-field, need-check-nil, await-in-sync
|
||||
|
||||
local util = require('vim._core.util')
|
||||
local future = require('vim.async._future')
|
||||
local runtime = require('vim.async._runtime')
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
-- LuaLS cannot model the generic annotations used by this vendored implementation.
|
||||
---@diagnostic disable: no-unknown, undefined-doc-name, luadoc-miss-symbol, missing-return, missing-return-value, param-type-mismatch, return-type-mismatch, redundant-return-value, undefined-field, need-check-nil, await-in-sync
|
||||
|
||||
local async = require('vim.async._core')
|
||||
local runtime = require('vim.async._runtime')
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
-- LuaLS cannot model the generic annotations used by this vendored implementation.
|
||||
---@diagnostic disable: no-unknown, undefined-doc-name, luadoc-miss-symbol, missing-return, missing-return-value, param-type-mismatch, return-type-mismatch, redundant-return-value, undefined-field, need-check-nil, await-in-sync
|
||||
|
||||
local F = vim.F
|
||||
local util = require('vim._core.util')
|
||||
|
||||
--- @class (internal) vim.async.Future<R>
|
||||
--- @field private _callbacks table<integer, fun(err?: any, ...: R...)>
|
||||
--- @field private _callback_pos integer
|
||||
--- @field private _err? any
|
||||
--- @field private _result? R[] & { n: integer }
|
||||
local Future = {}
|
||||
Future.__index = Future
|
||||
|
||||
@@ -22,6 +24,8 @@ function Future:result()
|
||||
end
|
||||
end
|
||||
|
||||
--- @param callback fun(err?: any, ...: R...)
|
||||
--- @return fun()
|
||||
function Future:on_complete(callback)
|
||||
if self:completed() then
|
||||
-- Already completed or closed
|
||||
@@ -42,6 +46,8 @@ function Future:on_complete(callback)
|
||||
end
|
||||
end
|
||||
|
||||
--- @param err? any
|
||||
--- @param ... R...
|
||||
function Future:complete(err, ...)
|
||||
if self:completed() then
|
||||
error('Future is already completed', 2)
|
||||
@@ -69,6 +75,7 @@ function Future:complete(err, ...)
|
||||
end
|
||||
end
|
||||
|
||||
--- @return vim.async.Future<any>
|
||||
return function()
|
||||
return setmetatable({
|
||||
_callbacks = {},
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
-- LuaLS cannot model the generic annotations used by this vendored implementation.
|
||||
---@diagnostic disable: no-unknown, undefined-doc-name, luadoc-miss-symbol, missing-return, missing-return-value, param-type-mismatch, return-type-mismatch, redundant-return-value, undefined-field, need-check-nil, await-in-sync
|
||||
|
||||
local new_event = require('vim.async._event')
|
||||
|
||||
--- An optionally bounded FIFO queue for passing values between async tasks.
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
-- LuaLS cannot model the generic annotations used by this vendored implementation.
|
||||
---@diagnostic disable: no-unknown, undefined-doc-name, luadoc-miss-symbol, missing-return, missing-return-value, param-type-mismatch, return-type-mismatch, redundant-return-value, undefined-field, need-check-nil, await-in-sync
|
||||
|
||||
local validate = vim.validate
|
||||
|
||||
--- @class vim.async.Timer: vim.async.Closable
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
-- LuaLS cannot model the generic annotations used by this vendored implementation.
|
||||
---@diagnostic disable: no-unknown, undefined-doc-name, luadoc-miss-symbol, missing-return, missing-return-value, param-type-mismatch, return-type-mismatch, redundant-return-value, undefined-field, need-check-nil, await-in-sync
|
||||
|
||||
local F = vim.F
|
||||
local new_event = require('vim.async._event')
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ local fn = vim.fn
|
||||
|
||||
local M = {}
|
||||
|
||||
--- @alias vim.filetype.mapfn fun(path:string,bufnr:integer, ...):string?, fun(b:integer)?
|
||||
--- @alias vim.filetype.mapfn fun(path:string,bufnr:integer, ...):string?, fun(b:integer)?, boolean?
|
||||
--- @alias vim.filetype.mapopts { priority: number }
|
||||
--- @alias vim.filetype.maptbl [string|vim.filetype.mapfn, vim.filetype.mapopts]
|
||||
--- @alias vim.filetype.mapping.value string|vim.filetype.mapfn|vim.filetype.maptbl
|
||||
|
||||
@@ -173,7 +173,7 @@ end
|
||||
---
|
||||
---@since 15
|
||||
---@param path string Filepath (or other identity string).
|
||||
---@param opts? table
|
||||
---@param opts? { maxlen?: integer } #
|
||||
--- - maxlen: (integer, default: 180) Max length (bytes) of the result.
|
||||
---@return string # Filesystem-safe, mnemonic slug.
|
||||
function M.slug(path, opts)
|
||||
|
||||
@@ -64,13 +64,11 @@
|
||||
--- -- { "a", "b" }
|
||||
--- ```
|
||||
|
||||
-- LuaLS cannot model the variadic EmmyLua generics used by this module.
|
||||
---@diagnostic disable: no-unknown, undefined-doc-name, luadoc-miss-symbol, missing-return, missing-return-value, param-type-mismatch, return-type-mismatch, redundant-return-value, undefined-field
|
||||
|
||||
-- `never` represents an empty tail for single-value iterators.
|
||||
--- @nodoc
|
||||
--- @class vim.IterModule
|
||||
--- @operator call: vim.Iter<any, any...>
|
||||
--- @overload fun<T>(src: T[]): vim.IterArray<T>
|
||||
--- @overload fun<T>(src: T[]): vim.IterArray<T, never>
|
||||
--- @overload fun<K, V>(src: table<K, V>): vim.Iter<K, V>
|
||||
--- @overload fun(src: table, ...): vim.Iter<any, any...>
|
||||
--- @overload fun(src: function, ...): vim.Iter<any, any...>
|
||||
@@ -468,7 +466,7 @@ end
|
||||
---
|
||||
---
|
||||
--- @since 12
|
||||
--- @overload fun<T>(self: vim.Iter<T>): T[]
|
||||
--- @overload fun<T>(self: vim.Iter<T, never>): T[]
|
||||
--- @overload fun<V1, V2, V...>(self: vim.Iter<V1, V2, V...>): [V1, V2, V...][]
|
||||
--- @return any[]
|
||||
function Iter:totable()
|
||||
@@ -486,7 +484,7 @@ function Iter:totable()
|
||||
end
|
||||
|
||||
--- @nodoc
|
||||
--- @overload fun<T>(self: vim.IterArray<T>): T[]
|
||||
--- @overload fun<T>(self: vim.IterArray<T, never>): T[]
|
||||
--- @overload fun<V1, V2, V...>(self: vim.IterArray<V1, V2, V...>): [V1, V2, V...][]
|
||||
--- @return any[]
|
||||
function IterArray:totable()
|
||||
@@ -1250,7 +1248,7 @@ end
|
||||
--- @generic R1, R...
|
||||
--- @param src table<R1, R>|fun(s: table, v: any): R1, R... Table or iterator to drain values from
|
||||
--- @return vim.Iter<R1, R...>
|
||||
--- @overload fun<T>(src: T[]): vim.IterArray<T>
|
||||
--- @overload fun<T>(src: T[]): vim.IterArray<T, never>
|
||||
--- @overload fun<K, V>(src: table<K, V>): vim.Iter<K, V>
|
||||
--- @private
|
||||
function Iter.new(src, ...)
|
||||
|
||||
@@ -60,7 +60,7 @@ local stats = { find = { total = 0, time = 0, not_found = 0 } }
|
||||
--- @type table<string, uv.fs_stat.result>?
|
||||
local fs_stat_cache
|
||||
|
||||
--- @type table<string, table<string,vim.loader.ModuleInfo>>
|
||||
--- @type table<string, table<string,vim.loader.ModuleInfo>?>
|
||||
local indexed = {}
|
||||
|
||||
--- @param path string
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
---@field private filename string
|
||||
---
|
||||
--- Internal state for the log file handle. `nil` until the file is opened.
|
||||
---@field private logfile file*?
|
||||
---@field private logfile file?
|
||||
---
|
||||
--- Internal state for the log file open error.
|
||||
---@field private openerr string?
|
||||
|
||||
@@ -48,10 +48,8 @@ local buf_capabilities = {}
|
||||
local M = {}
|
||||
M.__index = M
|
||||
|
||||
---@generic T : vim.lsp.Capability
|
||||
---@param self T
|
||||
---@param bufnr integer
|
||||
---@return T
|
||||
---@return self
|
||||
function M:new(bufnr)
|
||||
-- `self` in the `new()` function refers to the concrete type (i.e., the metatable).
|
||||
-- `Class` may be a subtype of `Capability`, as it supports inheritance.
|
||||
|
||||
@@ -203,6 +203,7 @@ end
|
||||
---@return vim.lsp.folding_range.State
|
||||
function State:new(bufnr)
|
||||
self = Capability.new(self, bufnr)
|
||||
---@cast self vim.lsp.folding_range.State
|
||||
self.lang = vim.treesitter.language.get_lang(vim.bo[self.bufnr].filetype)
|
||||
self.row_level = {}
|
||||
self.row_kinds = {}
|
||||
@@ -325,8 +326,8 @@ end
|
||||
--- Split `line` into highlighted virt_text chunks from `spans`.
|
||||
---
|
||||
---@param line string
|
||||
---@param spans [integer, integer, string][] [start_col, end_col, highlight]
|
||||
---@return [string, string[]?][] [text, highlight[]?][]
|
||||
---@param spans [integer, integer, string][] # [start_col, end_col, highlight]
|
||||
---@return [string, string[]?][] # [text, highlight[]?][]
|
||||
local function spans_to_virt_text(line, spans)
|
||||
local boundaries = { 0, #line }
|
||||
for _, span in ipairs(spans) do
|
||||
|
||||
@@ -174,7 +174,7 @@ local G = P({
|
||||
--- @param input string
|
||||
--- @return vim.snippet.Node<vim.snippet.SnippetData>
|
||||
function M.parse(input)
|
||||
return assert(G:match(input), 'snippet parsing failed')
|
||||
return (assert(G:match(input), 'snippet parsing failed'))
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
@@ -675,14 +675,15 @@ function M.format(opts)
|
||||
return util.make_given_range_params(r.start, r['end'], bufnr, client.offset_encoding).range
|
||||
end
|
||||
|
||||
local ret = params --[[@as lsp.DocumentFormattingParams|lsp.DocumentRangeFormattingParams|lsp.DocumentRangesFormattingParams]]
|
||||
--- @type lsp.DocumentFormattingParams|lsp.DocumentRangeFormattingParams|lsp.DocumentRangesFormattingParams
|
||||
local ret = params
|
||||
if passed_multiple_ranges then
|
||||
--- @cast range {start:[integer,integer],end:[integer, integer]}[]
|
||||
ret = params --[[@as lsp.DocumentRangesFormattingParams]]
|
||||
--- @cast ret lsp.DocumentRangesFormattingParams
|
||||
ret.ranges = vim.tbl_map(to_lsp_range, range)
|
||||
elseif range then
|
||||
--- @cast range {start:[integer,integer],end:[integer, integer]}
|
||||
ret = params --[[@as lsp.DocumentRangeFormattingParams]]
|
||||
--- @cast ret lsp.DocumentRangeFormattingParams
|
||||
ret.range = to_lsp_range(range)
|
||||
end
|
||||
return ret
|
||||
|
||||
@@ -416,7 +416,7 @@ function Client.create(config)
|
||||
local id = client_index
|
||||
local name = get_name(id, config)
|
||||
|
||||
--- @class vim.lsp.Client
|
||||
--- @type vim.lsp.Client
|
||||
local self = {
|
||||
id = id,
|
||||
config = config,
|
||||
|
||||
@@ -428,7 +428,7 @@ end
|
||||
|
||||
--- |lsp-handler| for the method `workspace/codeLens/refresh`
|
||||
---
|
||||
---@private
|
||||
---@internal
|
||||
---@type lsp.Handler
|
||||
function M.on_refresh(err, _, ctx)
|
||||
if err then
|
||||
|
||||
@@ -511,7 +511,7 @@ function M._lsp_to_complete_items(
|
||||
return {}
|
||||
end
|
||||
|
||||
---@type fun(item: lsp.CompletionItem, item_prefix: string):boolean
|
||||
---@type fun(item: lsp.CompletionItem, item_prefix: string): boolean, integer?
|
||||
local matches
|
||||
if not prefix:find('%w') then
|
||||
matches = function(_, _)
|
||||
|
||||
@@ -384,7 +384,7 @@ end
|
||||
|
||||
--- |lsp-handler| for the method `workspace/diagnostic/refresh`
|
||||
---@param ctx lsp.HandlerContext
|
||||
---@private
|
||||
---@internal
|
||||
function M.on_refresh(err, _, ctx)
|
||||
if err then
|
||||
return vim.NIL
|
||||
|
||||
@@ -137,7 +137,7 @@ end
|
||||
--- Store hints for a specific buffer and client
|
||||
---@param result lsp.InlayHint[]?
|
||||
---@param ctx lsp.HandlerContext
|
||||
---@private
|
||||
---@internal
|
||||
function M.on_inlayhint(err, result, ctx)
|
||||
local bufnr = assert(ctx.bufnr)
|
||||
local provider = InlayHint.active[bufnr]
|
||||
@@ -223,7 +223,7 @@ end
|
||||
|
||||
--- |lsp-handler| for the method `workspace/inlayHint/refresh`
|
||||
---@param ctx lsp.HandlerContext
|
||||
---@private
|
||||
---@internal
|
||||
function M.on_refresh(err, _, ctx)
|
||||
if err then
|
||||
return vim.NIL
|
||||
|
||||
@@ -42,7 +42,7 @@ M._self = log
|
||||
--- Returns the log filename.
|
||||
---@return string log filename
|
||||
function M.get_filename()
|
||||
---@diagnostic disable-next-line: invisible
|
||||
---@diagnostic disable-next-line: access-invisible
|
||||
return log.filename
|
||||
end
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ local uv = vim.uv
|
||||
local M = {}
|
||||
|
||||
--- @param border string|(string|[string,string])[]
|
||||
--- @return never
|
||||
local function border_error(border)
|
||||
error(
|
||||
string.format(
|
||||
@@ -69,8 +70,7 @@ local function get_border_size(opts)
|
||||
-- border specified as a list of border characters
|
||||
return e
|
||||
end
|
||||
--- @diagnostic disable-next-line:missing-return
|
||||
border_error(border)
|
||||
return border_error(border)
|
||||
end
|
||||
|
||||
--- @param e string
|
||||
@@ -179,7 +179,7 @@ function M.apply_text_edits(text_edits, bufnr, position_encoding, change_annotat
|
||||
local function apply_text_edits()
|
||||
-- Fix reversed range and indexing each text_edits
|
||||
for index, text_edit in ipairs(text_edits) do
|
||||
--- @cast text_edit lsp.TextEdit|{_index: integer}
|
||||
--- @cast text_edit lsp.TextEdit & { _index?: integer }
|
||||
-- XXX: Preserve existing _index to avoid surprises if the same edit is reapplied. #39344
|
||||
if text_edit._index == nil then
|
||||
text_edit._index = index
|
||||
@@ -668,7 +668,11 @@ function M.convert_signature_help_to_markdown_lines(signature_help, ft, triggers
|
||||
if active_signature >= #signature_help.signatures or active_signature < 0 then
|
||||
active_signature = 0
|
||||
end
|
||||
local signature = vim.deepcopy(signature_help.signatures[active_signature + 1])
|
||||
local signature = signature_help.signatures[active_signature + 1]
|
||||
if not signature then
|
||||
return
|
||||
end
|
||||
signature = vim.deepcopy(signature)
|
||||
local label = signature.label
|
||||
if ft then
|
||||
-- wrap inside a code block for proper rendering
|
||||
@@ -1410,7 +1414,7 @@ function M._make_floating_popup_size(contents, opts)
|
||||
local title_length = 0
|
||||
local chunks = type(opts.title) == 'string' and { { opts.title } } or opts.title or {}
|
||||
for _, chunk in
|
||||
ipairs(chunks --[=[@as [string, string][]]=])
|
||||
ipairs(chunks --[=[@as [string, string][] ]=])
|
||||
do
|
||||
title_length = title_length + vim.fn.strdisplaywidth(chunk[1])
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@ local strbuffer = require('vim._core.stringbuffer')
|
||||
|
||||
--- Interface for transport implementations.
|
||||
---
|
||||
--- @class (private, exact) vim.net.Transport
|
||||
--- @class (internal, exact) vim.net.Transport
|
||||
--- @field listen fun(self: vim.net.Transport, on_read: fun(err: any, data: string), on_exit: fun(code: integer, signal: integer))
|
||||
--- @field write fun(self: vim.net.Transport, msg: string)
|
||||
--- @field is_closing fun(self: vim.net.Transport): boolean
|
||||
@@ -101,7 +101,7 @@ end
|
||||
--- These messages are buffered in `msgbuf`.
|
||||
--- @field private connected boolean
|
||||
--- @field private closing boolean
|
||||
--- @field private msgbuf vim.Ringbuf
|
||||
--- @field private msgbuf vim.Ringbuf<string>
|
||||
--- @field private on_exit? fun(code: integer, signal: integer)
|
||||
--- @field new fun(host_or_path: string, port?: integer, log: vim.Log): vim.net.TransportConnect
|
||||
local TransportConnect = {}
|
||||
@@ -193,7 +193,7 @@ end
|
||||
--- `nil` means it needs more transport data.
|
||||
--- decoder errors are reported through `on_error`.
|
||||
---
|
||||
---@class (private, exact) vim.net.MessageStream
|
||||
---@class (internal, exact) vim.net.MessageStream
|
||||
---@field private strbuf string.buffer
|
||||
---@field private decode fun(strbuf: string.buffer): string?
|
||||
---@field private on_read fun(err: string?, data: string?)
|
||||
|
||||
@@ -113,7 +113,8 @@ function M.new(...)
|
||||
if start.buf ~= end_.buf then
|
||||
error('start and end positions must belong to the same buffer')
|
||||
end
|
||||
start_row, start_col, end_row, end_col, buf = start[1], start[2], end_[1], end_[2], start.buf
|
||||
start_row, start_col, end_row, end_col, buf =
|
||||
start.row, start.col, end_.row, end_.col, start.buf
|
||||
elseif nargs == 5 then
|
||||
---@type integer, integer, integer, integer, integer
|
||||
buf, start_row, start_col, end_row, end_col = ...
|
||||
@@ -225,8 +226,8 @@ function M.has(outer, inner)
|
||||
|
||||
if getmetatable(inner) == vim.pos then
|
||||
---@cast inner -vim.Range
|
||||
return util.cmp_pos.le(outer[1], outer[2], inner[1], inner[2])
|
||||
and util.cmp_pos.ge(outer[3], outer[4], inner[1], inner[2])
|
||||
return util.cmp_pos.le(outer[1], outer[2], inner.row, inner.col)
|
||||
and util.cmp_pos.ge(outer[3], outer[4], inner.row, inner.col)
|
||||
end
|
||||
---@cast inner -vim.Pos
|
||||
|
||||
|
||||
@@ -314,6 +314,8 @@ end
|
||||
---@return integer
|
||||
---@package
|
||||
function TSTreeView:iter()
|
||||
-- TODO(lewis6991): EmmyLua 0.25.1's ipairs annotation omits the table and initial index.
|
||||
--- @diagnostic disable-next-line: missing-return-value
|
||||
return ipairs(self.opts.anon and self.nodes or self.named)
|
||||
end
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ local TSCallbackNames = {
|
||||
---@field private _num_valid_regions integer Number of valid regions
|
||||
---@field private _is_entirely_valid boolean Whether the entire tree (excluding children) is valid.
|
||||
---@field private _logger? fun(logtype: string, msg: string)
|
||||
---@field private _logfile? file*
|
||||
---@field private _logfile? file
|
||||
local LanguageTree = {}
|
||||
|
||||
---Optional arguments:
|
||||
@@ -139,7 +139,7 @@ function LanguageTree.new(source, lang, opts)
|
||||
|
||||
local injections = opts.injections or {}
|
||||
|
||||
--- @class vim.treesitter.LanguageTree
|
||||
--- @type vim.treesitter.LanguageTree
|
||||
local self = {
|
||||
_source = source,
|
||||
_lang = lang,
|
||||
|
||||
@@ -548,6 +548,7 @@ local predicate_handlers = {
|
||||
return impl['contains'](match, source, predicate, true)
|
||||
end,
|
||||
|
||||
--- @param predicate any[] & { string_set?: table<string, boolean> }
|
||||
['any-of?'] = function(match, _, source, predicate)
|
||||
local nodes = match[predicate[2]]
|
||||
if not nodes or #nodes == 0 then
|
||||
@@ -559,7 +560,7 @@ local predicate_handlers = {
|
||||
|
||||
-- Since 'predicate' will not be used by callers of this function, use it
|
||||
-- to store a string set built from the list of words to check against.
|
||||
local string_set = predicate['string_set'] --- @type table<string, boolean>
|
||||
local string_set = predicate['string_set']
|
||||
if not string_set then
|
||||
string_set = {}
|
||||
for i = 3, #predicate do
|
||||
|
||||
@@ -10,7 +10,7 @@ local M = {}
|
||||
---
|
||||
---@param payload string Sequence to send via nvim_ui_send(). Use empty string ('') to just register
|
||||
--- a listener (no sending).
|
||||
---@param opts? { timeout?: integer, on_timeout?: fun(), group?: integer|string, chan?: integer }
|
||||
---@param opts? { timeout?: integer, on_timeout?: fun(), group?: integer|string, chan?: integer } #
|
||||
--- - `timeout` (default: 1000) ms to wait before giving up, or 0 for never (caller must remove the autocmd).
|
||||
--- - `on_timeout` optional fn called when the timeout fires.
|
||||
--- - `group`: augroup for the TermResponse autocmd.
|
||||
|
||||
@@ -465,8 +465,7 @@ local function styletable_treesitter(state)
|
||||
query:iter_captures(root, buf_highlighter.bufnr, state.start - 1, state.end_)
|
||||
do
|
||||
local srow, scol, erow, ecol = node:range()
|
||||
--- @diagnostic disable-next-line: invisible
|
||||
local c = q._query.captures[capture]
|
||||
local c = query.captures[capture]
|
||||
if c ~= nil then
|
||||
local hlid = register_hl(state, '@' .. c .. '.' .. tree:lang())
|
||||
if metadata.conceal and state.opt.conceallevel ~= 0 then
|
||||
|
||||
@@ -69,7 +69,7 @@ def_autocmd({ 'FileWriteCmd', 'FileAppendCmd' }, {}, function(ev)
|
||||
vim.fn.getline(
|
||||
math.min(vim.fn.line("'["), vim.fn.line("']")),
|
||||
math.max(vim.fn.line("'["), vim.fn.line("']"))
|
||||
) --[=[@as string[]]=]
|
||||
) --[=[@as string[] ]=]
|
||||
),
|
||||
ev.file,
|
||||
ev.event == 'FileAppendCmd' and 'ab' or 'b'
|
||||
|
||||
@@ -91,14 +91,14 @@ local v = setmetatable({}, {
|
||||
--- @field generics? string[]
|
||||
--- @field parent? string
|
||||
--- @field parent_generics? string[]
|
||||
--- @field access? 'private'|'protected'|'package'
|
||||
--- @field access? 'private'|'protected'|'package'|'internal'
|
||||
|
||||
--- @class nvim.luacats.Field
|
||||
--- @field kind 'field'
|
||||
--- @field name string
|
||||
--- @field type string
|
||||
--- @field desc? string
|
||||
--- @field access? 'private'|'protected'|'package'
|
||||
--- @field access? 'private'|'protected'|'package'|'internal'
|
||||
|
||||
--- @class nvim.luacats.Note
|
||||
--- @field desc? string
|
||||
@@ -173,7 +173,7 @@ local function generic_opt(name)
|
||||
return (Pf('<') * Cg(Ct(comma1(typedef)), name) * Plf('>')) + -Plf('<')
|
||||
end
|
||||
|
||||
local access = P('private') + P('protected') + P('package')
|
||||
local access = P('private') + P('protected') + P('package') + P('internal')
|
||||
local caccess = Cg(access, 'access')
|
||||
local cattr = Cg(comma(access + P('exact')), 'access')
|
||||
local desc_delim = Sf '#:' + ws
|
||||
|
||||
@@ -25,7 +25,7 @@ local luacats_grammar = require('gen.luacats_grammar')
|
||||
--- @field overloads string[]
|
||||
--- @field returns nvim.luacats.parser.return[]
|
||||
--- @field desc string
|
||||
--- @field access? 'private'|'package'|'protected'
|
||||
--- @field access? 'private'|'package'|'protected'|'internal'
|
||||
--- @field class? string
|
||||
--- @field module? string
|
||||
--- @field modvar? string
|
||||
@@ -198,6 +198,8 @@ local function process_doc_line(line, state)
|
||||
cur_obj.access = 'package'
|
||||
elseif kind == 'protected' then
|
||||
cur_obj.access = 'protected'
|
||||
elseif kind == 'internal' then
|
||||
cur_obj.access = 'internal'
|
||||
elseif kind == 'deprecated' then
|
||||
cur_obj.deprecated = true
|
||||
elseif kind == 'inlinedoc' then
|
||||
|
||||
@@ -12,8 +12,9 @@ describe('vim.lsp._snippet_grammar', function()
|
||||
before_each(n.clear)
|
||||
|
||||
local parse = function(...)
|
||||
local res = exec_lua('return require("vim.lsp._snippet_grammar").parse(...)', ...)
|
||||
return res.data.children
|
||||
local results = exec_lua('return { require("vim.lsp._snippet_grammar").parse(...) }', ...)
|
||||
eq(1, #results)
|
||||
return results[1].data.children
|
||||
end
|
||||
|
||||
it('parses only text', function()
|
||||
|
||||
@@ -107,6 +107,28 @@ describe('luacats parser', function()
|
||||
exp
|
||||
)
|
||||
|
||||
for _, access in ipairs({ 'internal', 'internal, exact' }) do
|
||||
it('tracks internal visibility with (' .. access .. ')', function()
|
||||
local classes, funs = parser.parse_str(
|
||||
dedent([[
|
||||
--- @class (%s) vim.MyClass
|
||||
--- @field internal value string
|
||||
local MyClass = {}
|
||||
|
||||
--- @internal
|
||||
function MyClass.get() end
|
||||
|
||||
return MyClass
|
||||
]]):format(access),
|
||||
'runtime/lua/vim/myclass.lua'
|
||||
)
|
||||
|
||||
eq(access, classes['vim.MyClass'].access)
|
||||
eq('internal', classes['vim.MyClass'].fields[1].access)
|
||||
eq('internal', funs[1].access)
|
||||
end)
|
||||
end
|
||||
|
||||
it('tracks class member declaration style', function()
|
||||
local classes, funs = parser.parse_str(
|
||||
dedent([[ --- @class vim.MyClass
|
||||
|
||||
Reference in New Issue
Block a user