Problem: `nvim://` scheme feels more like a generalized interface that
may be requested externally, and it acts like CLI args (roughly).
This is how `vscode://` works.
Anything that behaves like an "app" or a "protocol" deserves its own
scheme. For such Nvim-owned things they will be called `nvim-xx://`.
Solution: Use `nvim-pack://confirm#<bufnr>` template for confirmation
buffer name instead of `nvim://pack-confirm#<bufnr>`.
Problem: Lockfile can become out of sync with what is actually installed
on disk when user performs (somewhat reasonable) manual actions like:
- Delete lockfile and expect it to regenerate.
- Delete plugin directory without `vim.pack.del()`.
- Manually edit lock data in a bad way.
Solution: Synchronize lockfile data with installed plugins on every
lockfile read. In particular:
1. Install immediately all missing plugins with valid lock data.
This helps with "manually delete plugin directory" case by
prompting user to figure out how to properly delete a plugin.
2. Repair lock data for properly installed plugins.
This helps with "manually deleted lockfile", "manually edited
lockfile in an unexpected way", "installation terminated due to
timeout" cases.
3. Remove unrepairable corrupted lock data and their plugins. This
includes bad lock data for missing plugins and any lock data
for corrupted plugins (right now this only means that plugin
path is not a directory, but can be built upon).
Step 1 also improves usability in case there are lazy loaded plugins
that are rarely loaded (like on `FileType` event, for example):
- Previously starting with config+lockfile on a new machine only
installs rare `vim.pack.add()` plugin after it is called (while
an entry in lockfile would still be present). This could be
problematic if there is no Internet connection, for example.
- Now all plugins from the lockfile are installed before actually
executing the first `vim.pack.add()` call in 'init.lua'. And later
they are only loaded on a rare `vim.pack.add()` call.
---
Synchronizing lockfile on its every read makes it work more robustly
if other `vim.pack` functions are called without any `vim.pack.add()`.
---
Performance for a regular startup (good lockfile, everything is
installed) is not affected and usually even increased. The bottleneck
in this area is figuring out which plugins need to be installed.
Previously the check was done by `vim.uv.fs_stat()` for every plugin
in `vim.pack.add()`. Now it is replaced with a single `vim.fs.dir()`
traversal during lockfile sync while later using lockfile data to
figure out if plugin needs to be installed.
The single `vim.fs.dir` approach scales better than `vim.uv.fs_stat`,
but might be less performant if there are many plugins that will be
not loaded via `vim.pack.add()` during startup.
Rough estimate of how long the same steps (read lockfile and normalize
plugin array) take with a single `vim.pack.add()` filled with 43
plugins benchmarking:
- Before commit: ~700 ms
- After commit: ~550 ms
Problem: Currently it is possible to have plugin in a "partial install"
state when `git clone` was successfull but `git checkout` was not.
This was done to not checkout default branch by default in these
situations (for security reasons).
The problem is that it adds complexity when both dealing with lockfile
(plugin's `rev` might be `nil`) and in how `src` and `version` are
treated (wrong `src` - no plugin on disk; wrong `version` - "partial"
plugin on disk).
Solution: Treat plugin as "installed" if both `git clone` and
`git checkout` are successful, while ensuring that not installed
plugins are not on disk and in lockfile.
This also means that if in 'init.lua' there is a `vim.pack.add()` with
bad `version`, for first install there will be an informative error
about it BUT next session will also try to install it. The solution is
the same - adjust `version` beforehand.
Problem: No example workflow of how to revert after a bad update.
Solution: Add example workflow of how to revert after a bad update.
In future this might be improved by utilizing other `vim.pack`
features or via a dedicated function (like `vim.pack.restore()` that
restores all installed plugins to a state from the lockfile).
Problem: Changing `src` of an existing plugin cleanly requires manual
`vim.pack.del()` prior to executing `vim.pack.add()` with a new `src`.
Solution: Autodetect `src` change for an existing plugin (by comparing
against lockfile data). If different - properly delete immediately and
treat this as new plugin installation.
Alternative solution might be to update `origin` remote in the
installed plugin after calling `vim.pack.update()`. Although, doable,
this 1) requires more code; and 2) works only for Git plugins (which
might be not the only type of plugins in the future). Automatic
"delete and clean install" feels more robust.
Problem: Plain `vim.pack.add()` calls (with default `opts.load`) does
not fully work if called inside 'plugin/' runtime directory. In
particular, 'plugin/' files of newly added plugins are not sourced.
This is because `opts.load` is `false` during the whole startup, which
means `:packadd!` is used (modify 'runtimepath' but not force source
newly added 'plugin/' files).
This use case is common due to users organizing their config as
separate files in '~/.config/nvim/plugin/'.
Solution: Use newly added `v:vim_did_init` to decide default `opts.load`
value instead of `v:vim_did_enter`.
Problem: Current requirement is Git>=2.36 as `--also-filter-submodules`
flag for `git clone` was introduced there. This is problematic since
default Git version on Ubuntu 22.04 is 2.34.
Solution: Relax minimal Git version to be (at least) 2.0 by selectively
applying necessary flags based on the current Git version.
As 2.0.0 was released in 2014-05-28 (almost the same age as Neovim
project itself), it is reasonable to drop any mention and checks on
minimal version altogether.
Problem:
Nvim does not recognize URI scheme with numeric characters. While rare, there
are URIs that contain numbers (e.g. [ed2k://](https://en.wikipedia.org/wiki/Ed2k_URI_scheme))
and characters like `+` (e.g. `svn+ssh`). I use it in
[distant.nvim](https://github.com/chipsenkbeil/distant.nvim) to support
multiple, distinct connections using `distant+1234://` as the scheme.
Otherwise, if you open a file with the same name & path on two different
machines from the same Nvim instance, their buffer names will conflict
when just using `distant://`.
Solution:
Adds full support for detecting URI scheme per
[RFC3986](https://www.rfc-editor.org/rfc/rfc3986#section-3.1)
Quote the special buffer names for consistency (see :help bufname()) and
so that they're not incorrectly highlighted as optional command
arguments.
closes: vim/vim#187309ab6a22c90
Co-authored-by: Doug Kearns <dougkearns@gmail.com>
Problem: confusing that there is the tag `undo-tree` (the Vim
implementation) and `undotree` (the Lua plugin for visualization).
Solution: rename tag to undotree-plugin. Mention the plugin in the docs of
|undotree|.
Problem:
- Exposing the raw config as table is a pattern not seen anywhere else
in the Nvim codebase.
- Old spellfile.vim docs still available, no new documentation
Solution:
- Exposing a `config()` function that both acts as "getter" and "setter"
is a much more common idiom (e.g. vim.lsp, vim.diagnostic).
- Add new documentation and link old docs to |spellfile.lua| instead of
|spellfile.vim|.
- :retab! line 1 and line 4 (main page heading).
- Use four columns whitespace before "by [Author]" in the user manual
heading to match the reference manual formatting.
- double space headings.
closes: vim/vim#18648542746521f
Co-authored-by: Doug Kearns <dougkearns@gmail.com>
* feat(lua): `Range:is_empty()` to check vim.range emptiness
* fix(lsp): don't overlay insertion-style inline completions
**Problem:** Some servers commonly respond with an empty inline
completion range which acts as a position where text should be inserted.
However, the inline completion module assumes that all responses with a
range are deletions + insertions that thus require an `overlay` display
style. This causes an incorrect preview, because the virtual text should
have the `inline` display style (to reflect that this is purely an
insertion).
**Solution:** Only use `overlay` for non-empty replacement ranges.
Problem: Confirmation buffer is named with `nvim-pack://` as scheme
prefix and uses buffer id (needed for in-process LSP) as one an entry
in the "hierarchical part".
Solution: Use `nvim://pack-confirm#<buf>` format with a more ubiquitous
`nvim://` prefix and buffer id at the end as the optional fragment.
Problem: In some areas plugin's revision is named "state". This might be
confusing for the users.
Solution: Consistently use "revision" to indicate "plugin's state on
disk".
Problem: A plugin does not know when startup scripts were already
triggered. This is useful to determine if a function is
called inside vimrc or after (like when sourcing 'plugin/'
files).
Solution: Add the v:vim_did_init variable (Evgeni Chasnovski)
closes: vim/vim#18668294bce21ee
Nvim has two more steps between sourcing startup scripts and loading
plugins. Set this variable after these two steps.
Co-authored-by: Evgeni Chasnovski <evgeni.chasnovski@gmail.com>
Problem: In visual mode, g<End> does not move to the last non-blank
character when the end of a line is on the same line as the
cursor (after v9.0.1753)
Solution: Move the cursor back by one position if it lands after the
line (varsidry)
fixes: vim/vim#18657closes: vim/vim#18658adc85151f3
compile time features are hot again.
Note: this changes the &term value for builtin definition from
'builtin_xterm' to just 'xterm'. It's an xterm regardless of we use an
external definition or an internal. Prior to this commit the vast
majority of POSIX users will have used external terminfo, so plugins and
scripts are only going to have checked for &term == 'xterm' or 'tmux' or
whatever.
The status of external loading is still available in "nvim -V3" output.
Problem:
Previously, the fallback logic to ".conf" was located outside of
`vim.filetype.match()` and directly within the AutoCmd definition. As a
result, `vim.filetype.match()` would return nil instead of ".conf" for
fallback cases (#30100).
Solution:
Added a boolean return value to `vim.filetype.match()` that indicates
whether the match was the result of fallback. If true, the filetype will
be set using `setf FALLBACK <ft>` instead of `setf <ft>`.
Problem:
fe4faaf81a added an invalid "redirect" item, which caused the
assert() to fail, which then caused the neovim/doc/ CI to fail:
https://github.com/neovim/doc/actions/runs/18830779387/job/53721736276 :
The previous commit e69beb9b1a tried to fix a different issue, which
has gone hidden because the "invalid tags" failure has been present on
the neovim/doc/ but was silently failing.
invalid tags: {
["g:netrw_keepdir"] = "usr_22.txt",
netrw = "vi_diff.txt",
...
plugins = "editorconfig"
}
Solution:
- Fix the invalid redirect.
- Improve the redirects assertion.
Problem: pre-inserted text not exposed in complete_info()
Solution: Add the pre-inserted text to the complete_info() Vim script
function (Girish Palya)
closes: vim/vim#18571
Feat: expose preinserted text in complete_info()
ef5bf58d8c
Co-authored-by: Girish Palya <girishji@gmail.com>
Problem: Cmdline history not updated when mapping both <Up> and <CR>.
Solution: Consider the command typed when in Cmdline mode and there is
no pending input (zeertzjq).
Although the existing behavior technically does match documentation, the
"completely come from mappings" part is a bit ambiguous, because one may
argue that the command doesn't completely come from mappings as long as
the user has typed a key in Cmdline mode. I'm not entirely sure if this
change will cause problems, but it seems unlikely.
fixes: vim/vim#2771
related: neovim/neovim#36256closes: vim/vim#1860797b6e8b424