- 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.
Problem:
The documentation flow (`gen_vimdoc.py`) has several issues:
- it's not very versatile
- depends on doxygen
- doesn't work well with Lua code as it requires an awkward filter script to convert it into pseudo-C.
- The intermediate XML files and filters makes it too much like a rube goldberg machine.
Solution:
Re-implement the flow using Lua, LPEG and treesitter.
- `gen_vimdoc.py` is now replaced with `gen_vimdoc.lua` and replicates a portion of the logic.
- `lua2dox.lua` is gone!
- No more XML files.
- Doxygen is now longer used and instead we now use:
- LPEG for comment parsing (see `scripts/luacats_grammar.lua` and `scripts/cdoc_grammar.lua`).
- LPEG for C parsing (see `scripts/cdoc_parser.lua`)
- Lua patterns for Lua parsing (see `scripts/luacats_parser.lua`).
- Treesitter for Markdown parsing (see `scripts/text_utils.lua`).
- The generated `runtime/doc/*.mpack` files have been removed.
- `scripts/gen_eval_files.lua` now instead uses `scripts/cdoc_parser.lua` directly.
- Text wrapping is implemented in `scripts/text_utils.lua` and appears to produce more consistent results (the main contributer to the diff of this change).
The benefit of this is that users only pay for what they use. If e.g.
only `vim.lsp.buf_get_clients()` is called then they don't need to load
all modules under `vim.lsp` which could lead to significant startuptime
saving.
Also `vim.lsp.module` is a bit nicer to user compared to
`require("vim.lsp.module")`.
This isn't used for some nested modules such as `filetype` as it breaks
tests with error messages such as "attempt to index field 'detect'".
It's not entirely certain the reason for this, but it is likely it is
due to filetype being precompiled which would imply deferred loading
isn't needed for performance reasons.
Problem: vim.diagnostic.{underline,float,virtual_text...}.severity
will have a type warning on list-like or table (min-max) inputs,
e.g. `vim.diagnostic.config { float = { severity = { min = INFO } } }`.
Solution: Correct the typing as documented in |diagnostic-severity|.
Problem:
Currently `deepcopy` hashes every single tables it copies so it can be
reused. For tables of mostly unique items that are non recursive, this
hashing is unnecessarily expensive
Solution:
Port the `noref` argument from Vimscripts `deepcopy()`.
The below benchmark demonstrates the results for two extreme cases of
tables of different sizes. One table that uses the same table lots of
times and one with all unique tables.
| test | `noref=false` (ms) | `noref=true` (ms) |
| -------------------- | ------------------ | ----------------- |
| unique tables (50) | 6.59 | 2.62 |
| shared tables (50) | 3.24 | 6.40 |
| unique tables (2000) | 23381.48 | 2884.53 |
| shared tables (2000) | 3505.54 | 14038.80 |
The results are basically the inverse of each other where `noref` is
much more performance on tables with unique fields, and `not noref` is
more performant on tables that reuse fields.
feat(diagnostic): add `vim.diagnostic.count()`
Problem: Getting diagnostic count based on the output of
`vim.diagnostic.get()` might become costly as number of diagnostic
entries grows. This is because it returns a copy of diagnostic cache
entries (so as to not allow users to change them in place).
Getting information about diagnostic count is frequently used in
statusline, so it is important to be as fast as reasonbly possible.
Solution: Add `vim.diagnostic.count()` which computes severity
counts without making copies.
Diagnostic signs should now be configured with vim.diagnostic.config(),
but "legacy" sign definitions should go through the standard deprecation
process to minimize the impact from breaking changes.
Anonymous namespaces are more difficult to extend or hook into since
they do not appear in the output of nvim_get_namespaces(). Use named
namespaces instead.
The prefix option of the diagnostic virtual text can be a function,
but previously it was only a function of diagnostic.
This function should also have additional parameters index and total,
more consistently and similarily as in the prefix function for
`vim.diagnostic.open_float()`.
These additional parameters will be useful when there are too many
number of diagnostics in a single line.
Problem:
When enabling diagnostics, there can be diagnostics for unloaded buffer,
but some handlers nevertheless attempt to set extmarks in such buffers.
Solution:
* Exit underline/virtual_text handler if buffer is not loaded.
* Don't require is_loaded as precondition for show(), because handlers
don't necessarily depend on it.
Problem: luals returns stricter diagnostics with bundled luarc.json
Solution: Improve some function and type annotations:
* use recognized uv.* types
* disable diagnostic for global `vim` in shared.lua
* docs: don't start comment lines with taglink (otherwise LuaLS will interpret it as a type)
* add type alias for lpeg pattern
* fix return annotation for `vim.secure.trust`
* rename local Range object in vim.version (shadows `Range` in vim.treesitter)
* fix some "missing fields" warnings
* add missing required fields for test functions in eval.lua
* rename lsp meta files for consistency
* docs(lua): teach lua2dox how to table
* docs(lua): teach gen_vimdoc.py about local functions
No more need to mark local functions with @private
* docs(lua): mention @nodoc and @meta in dev-lua-doc
* fixup!
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
---------
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
- vim.diagnostic.config() now accepts a function for the virtual_text.prefix
option, which allows for rendering e.g., diagnostic severities differently.
The BufWipeout autocmd is not 100% reliable and may leave stale entries
in the cache. This is sort of a hack/workaround to ensure
`vim.diagnostic.reset` calls don't fail if there are stale cache entries
but instead clears them
Fixes errors like
Error executing vim.schedule lua callback: /usr/share/nvim/runtime/lua/vim/diagnostic.lua:1458: Invalid buffer id: 22
stack traceback:
[C]: in function 'nvim_exec_autocmds'
/usr/share/nvim/runtime/lua/vim/diagnostic.lua:1458: in function 'reset'
Some functions didn't include the `nil` case in the return type
annotation. This corrects those and also adds a Diagnostic class
definition for the diagnostic.get return type
This introduces a `suffix` option to the `virt_text` config in
`vim.diagnostic.config()`. The suffix can either be a string which is appended
to the diagnostic message or a function returning such. The function receives a
`diagnostic` argument, which is the diagnostic table of the last diagnostic (the
one whose message is rendered as virt text).
Closes#18687
This introduces a `suffix` option to `vim.diagnostic.open_float()` (and
consequently `vim.diagnostic.config()`) that appends some text to each
diagnostic in the float.
It accepts the same types as `prefix`. For multiline diagnostics, the suffix is
only appended to the last line. By default, the suffix will render the
diagnostic error code, if any.
Doing so on `BufDelete` has issues:
- `BufDelete` is also fired for listed buffers that are made unlisted.
- `BufDelete` is not fired for unlisted buffers that are deleted.
This means that diagnostics will be lost for a buffer that becomes unlisted.
It also means that if an entry exists for an unlisted buffer, deleting that
buffer later will not remove its entry from the cache (and you may see "Invalid
buffer id" errors when using diagnostic functions if it was wiped).
Instead, remove a buffer from the cache if it is wiped out.
This means simply `:bd`ing a buffer will not clear its diagnostics now.