Problem:
We can resolve the `CompletionItem.detail` field but don't advertise
this capability.
Solution:
Add `detail` to
`textDocument.completion.completionItem.resolveSupport.properties`.
Problem:
The logic for generating the complete item `info` is spread across
`_lsp_to_complete_items`, the `CompleteChanged` event handler, and
`CompletionResolver:request`. This has previously caused the `info`
shown for resolved (via `completionItem/resolve`) and unresolved items
to differ.
Solution:
Centralise the logic in a new `complete_item_info` function which is now
solely responsible for determining:
1. The `info` to show.
2. The markup kind of the `info`.
3. Whether the `info` is complete.
This simplifies the interaction between the 3 functions mentioned in the
problem:
- `_lsp_to_complete_items` calls `complete_item_info` and passes along
the markup kind and whether the item needs resolving via the complete
item's `user_data`.
- The `CompleteChanged` consumes the markup kind and whether the
item needs resolving from the complete item's `user_data`.
- `CompletionResolver:request`, like `_lsp_to_complete_items` calls
`complete_item_info` again and updates the current `info` if it's
changed.
Problem:
`CompletionItem.detail` is only shown in the info popup if the server
supports `completionItem/resolve`.
Solution:
If the server doesn't support `completionItem/resolve`, prepend the
complete item `info` with `CompletionItem.detail` in a fenced codeblock,
same as we do when the server supports `completionItem/resolve`.
To ensure that completion items are displayed in the same way,
regardless of whether the server supports `completionItem/resolve`, i've
extracted out the test logic from the `selecting an item triggers
completionItem/resolve + (snippet) preview` case so that we can run the
same tests against a server which supports `completionItem/resolve` and
one which doesn't. Hopefully this should prevent the two behaviours
diverging again.
Problem:
If `CompletionItem.documentation` is populated but `detail` is not, then
`detail` is not resolved.
Solution:
Ensure that we resolve a `CompletionItem` if either `detail` or
`documentation` are not populated.
I've also removed `detail` from the popup menu since otherwise it will
be populated in both the popup menu and the info popup after the
`CompletionItem` has been resolved. I think the info popup is the best
place for it anyway as when there is a completion item with a long popup
menu entry (when `detail` is a medium/long function signature for
instance), the whole popup menu gets widened and this steals horizontal
space that could be used to display the `documentation`. Now with
`detail` and `documentation` in the info popup, they share the same
horizontal space. This also aligns with how VSCode, nvim-cmp, blink.cmp,
and mini.nvim display `detail`.
Problem:
When a resolved `CompletionItem` with kind `Snippet` populates
`textEdit` instead of `insertText`, the contents are not previewed.
Solution:
Generate the snippet preview from `textEdit.newText` as well.
Problem: Processing of a very long message may take a long time; there
is no visual feedback of work being done, and no way to abort
processing.
Calculating text height for spill indicator inhibits
performance for very long message.
Solution: Whenever writing part of a message is taking longer than 100ms,
show the first part of the message, while checking for CTRL-C.
Calculate ('wrap'-ed) text height accurately until 'lines',
use line count beyond that.
Problem:
Potential documentation drift in `tui.txt` if fields for
`$NVIM_TERMDEFS` change.
Solution:
Generate docs for `tui.txt`. Add `brief_xform` to `gen_vimdoc.lua` to
allow transforming briefs during generation.
Problem:
`nvim_create_autocmd` is too verbose and its `callback` requires extra
"nesting".
Solution:
Introduce `nvim_on`. Start using it internally. Then we can get a feel
for how it should look before making it public.
Problem:
A benefit of the old `:LspInfo` was that it showed info related to the
"current buffer" a bit more clearly.
Solution:
Highlight the "current buffer" in the LSP checkhealth report.
Problem:
filewatcher and position-encoding info is reported after the big list of
client details.
Solution:
- report the info in the top-level, not in dedicated subsections.
text-object-define is a pattern I found in tpope's plugins (e.g.
https://github.com/tpope/vim-jdaddy) which shows an elegant way to
define a text-object. (Any mistakes in the example are my fault.)
Problem:
Our documentation is incomplete or inconsistent in several ways:
- Some public APIs lack corresponding validators.
- Some public APIs lack usage examples.
- The meaning of some return values or parameters is not clearly explained.
Solution:
Add the missing validators, examples, and clarifications.
Problem:
- To share logic, creating a `vim.Range` currently creates two `vim.Pos` values
as intermediates, which causes unnecessary table allocations.
- `pos.lua` and `range.lua` contain some overlapping logic.
Solution:
Add `vim.pos._util`, a module for handling
positions represented directly by `row` and `col`.
Problem:
- A window can only have one cursor, ranges selected by the cursor are typically
obtained by marks like ">" and "<", instead of calling get_cursor() twice.
- `vim.Range` is described as end-exclusive,
but the current `range.cursor()`/`range:to_cursor()` are end-inclusive.
- Conversion between `vim.Range` and mark-indexed range can be done by
`range.mark()`/`range:to_mark()`
Solution:
Remove `range.cursor()` and `range:to_cursor()`,
Problem: `nvim_exec_autocmds({ buf = ... })` matches the target buffer, but callbacks and modelines run with the caller buffer current rather than the target buffer.
Solution: Execute the buffered path in prepared target-buffer context and restore the caller afterward.
Problem: filetype: some html files are wrongly recognized as htmlangular
Solution: Use the \< atom to anchor ng-template and ng-content to start
of word (truffle)
Prevent false-positive htmlangular detection on words containing
'ng-template' or 'ng-content' as a substring (e.g. 'song-template',
'sing-content'). Anchor both branches with \< to require a word start,
matching the \<DTD\s\+XHTML\s idiom used five lines below.
related: neovim/neovim#39778.
closes: vim/vim#20246354ab1a69e
Co-authored-by: truffle <truffleagent@gmail.com>
Problem:
Ranges represented by marks are usually end-inclusive,
but the range utilities we provided are end-exclusive.
Solution:
Add pos:to_mark(), pos.mark(), range:to_mark(), and range.mark().
Problem:
After 767fbd8, typing trigger chars would open completion but the
chars were removed.
Solution:
Use filterText fallback so selected item respects typed trigger chars.
Problem:
- Windows users can't use terminfo to configure their terminal
capabilities. #37274
- Terminfo definitions sometimes get out of date or are simply
inaccurate.
- Eventually, we may want to drop terminfo, relying primarily on
built-in definitions. Users will still need some flexibility.
Solution:
Support $NVIM_TERMDEFS environment variable, which is JSON data that
defines "terminfo" definitions that override our builtin terminfo.
Problem:
During startup, we manually trigger a useless and misleading `OptionSet`
event, which doesn't set `v:option_*` values (this is a limitation of
`nvim_exec_autocmds`).
ad4bc2d90c/runtime/lua/vim/_core/defaults.lua (L939).
Solution:
The `nvim_exec_autocmds('OptionSet',…)` call does not serve any purpose
since 5cbb9d613b, so just drop it.
Problem:
PlainText completion items used `textEdit.newText` or `insertText` as
the completion word even when they did not match the typed prefix. This
could break popup completion behavior like 'completeopt+=longest'.
Solution:
Fall back to `filterText` when `newText` or `insertText` does not match
the typed prefix.
Problem: There is no way for a `vim.ui.input` caller to indicate for
which scope the input is. As in "This input is for something at cursor
scope". This information can be useful for `vim.ui.input`
implementation to tweak its behavior and presentation:
- Show different floating window depending on the scope. For example:
- Near cursor for "cursor" scope.
- At line start for "line" scope.
- In window corner for "buffer" and "window" scopes.
- In whole editor corner for "tabpage", "editor", "project" scopes.
- Navigate through history only for inputs with the same scope.
Solution: Document new `opts.scope` for `vim.ui.input`. Use it in the
codebase.
Problem: There is currently no convenient way to programmatically check
for new updates from plugin source. Running `vim.pack.update()` is one
approach, but it opens a confirmation buffer that requires a manual
action to close.
Solution: Add `opts.offline` to `vim.pack.get()` that will first fetch
new updates from plugin source before computing the output.
Problem: No convenient way to programmatically get the revision that
would be checked out after `vim.pack.update()` (with `offline=true`).
Doing this manually requires resolving `spec.version` which is not
trivial. This data can be useful for custom reporting of pending
updates or third party confirmation step.
Solution: Make `get()` include a new field for the revision that points
at the state after applying pending update. This is also the same as
the revision of resolved `spec.version`.
Problem:
2d795face6 added support for tab-local options ('cmdheight')
to `nvim_get_option_value`, but not to:
nvim_get_option_info2()
nvim_set_option_value(…, { tab = … })
gettabwinvar()
Solution:
- Update `options.lua` to model tab-local options. Introduce `kOptScopeTab`.
- Handle tab scope in the options layer so it works for all options APIs.
Note:
- No change to `gettabvar()`. Not sure if needed/wanted.
fix https://github.com/neovim/neovim/issues/31140
Problem: `vim.pack.get()` always uses lockfile as the source for the
`rev` field. This is fast, but may be misleading in case of
a corrupted lockfile.
Solution: Compute revision from Git repo on disk if `info=true`
(default), use lockfile otherwise. This does increase execution time
(as a result of one extra `git ...` call for every plugin), but
`info=true` is already designed to be informative and not necessarily
fast.
Problem:
No way to handle a "tab moved" event.
Use-case: tabline plugins may cache tab labels, and need to know when to
invalidate their cache.
Solution:
Add a `TabMoved` event that triggers whenever tabs are reordered via `:tabmove`
or via mouse click-and-drag.
Problem:
`make_position_params`/`get_line_byte_from_position`/`make_line_range_params`
are private functions and their functionality can be replaced by `vim.pos` now.
Solution:
Remove them, use `vim.pos` instead.