BREAKING CHANGE: When using a Funcref converted from a Lua function as
a method in Vim script, the result of the base expression is now passed
as the first argument instead of being ignored.
vim-patch:8.2.5117: crash when calling a Lua callback from a :def function
Problem: Crash when calling a Lua callback from a :def function. (Bohdan
Makohin)
Solution: Handle FC_CFUNC in call_user_func_check(). (closesvim/vim#10587)
7d149f899d
Makes it possible to use `vim.fs.find` to find files where only a
substring is known.
This is useful for `vim.lsp.start` to get the `root_dir` for languages
where the project-file is only known by its extension, not by the full
name.
For example in .NET projects there is usually a `<projectname>.csproj`
file in the project root.
Example:
vim.fs.find(function(x) return vim.endswith(x, '.csproj') end, { upward = true })
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.
These were just added to avoid churn when changing the default
of 'display'. To simplify message handling logic, we might want
to remove support for printing messages in default_grid later on.
This would allow things like printing error messages safely in the
middle of redraw, or a future graduation of the 'multigrid' feature.
This enables vim.filetype.match to match based on a buffer (most
accurate) or simply a filename or file contents, which are less accurate
but may still be useful for some scenarios.
When matching based on a buffer, the buffer's name and contents are both
used to do full filetype matching. When using a filename, if the file
exists the file is loaded into a buffer and full filetype detection is
performed. If the file does not exist then filetype matching is only
performed against the filename itself. Content-based matching does the
equivalent of scripts.vim, and matches solely based on file contents
without any information from the name of the file itself (e.g. for
shebangs).
BREAKING CHANGE: use `vim.filetype.match({buf = bufnr})` instead
of `vim.filetype.match(name, bufnr)`
global-local window options need to be handled specially. When `win` is
given but `scope` is not, then we want to set the local version of the
option but not the global one, therefore we need to force
`scope='local'`.
Note this does not apply to window-local only options (e.g. 'number')
Example:
nvim_set_option_value('scrolloff', 10, {}) -- global-local window option; set global value
nvim_set_option_value('scrolloff', 20, {win=0}) -- global-local window option; set local value
nvim_set_option_value('number', true, {}) -- local window option
is now equivalent to:
nvim_set_option_value('scrolloff', 10, {})
nvim_set_option_value('scrolloff', 20, {win=0, scope='local'}) -- changed from before
nvim_set_option_value('number', true, {win=0}) -- unchanged from before
Only the global-local option with a `win` provided gets forced to local
scope.
`nvim_get_option_value` and `nvim_set_option_value` better handle
unsetting local options. For instance, this is currently not possible:
vim.bo.tagfunc = nil
This does not work because 'tagfunc' is marked as "local to buffer" and
does not have a fallback global option. However, using :setlocal *does*
work as expected
:setlocal tagfunc=
`nvim_set_option_value` behaves more like :set and :setlocal (by
design), so using these as the underlying API functions beneath vim.bo
and vim.wo makes those two tables act more like :setlocal. Note that
vim.o *already* uses `nvim_set_option_value` under the hood, so that
vim.o behaves like :set.
Steps to reproduce:
1. setting `vim.highlight.on_yank`
```
vim.api.nvim_create_autocmd({ "TextYankPost" }, {
pattern = { "*" },
callback = function()
vim.highlight.on_yank({ timeout = 200 })
end,
})
```
2. repeat typing `yeye` ...
3. causes the following error.
```
Error executing vim.schedule lua callback: vim/_editor.lua:0: handle 0x01e96970 is already closing
stack traceback:
[C]: in function 'close'
vim/_editor.lua: in function ''
vim/_editor.lua: in function <vim/_editor.lua:0>
```
📝 Test result before fix:
[----------] Global test environment setup.
[----------] Running tests from test/functional/lua/highlight_spec.lua
[ RUN ] vim.highlight.on_yank does not show errors even if buffer is wiped before timeout: 15.07 ms OK
[ RUN ] vim.highlight.on_yank does not show errors even if executed between timeout and clearing highlight: 15.07 ms ERR
test/helpers.lua:73: Expected objects to be the same.
Passed in:
(string) 'Error executing vim.schedule lua callback: vim/_editor.lua:0: handle 0x02025260 is already closing
stack traceback:
[C]: in function 'close'
vim/_editor.lua: in function ''
vim/_editor.lua: in function <vim/_editor.lua:0>'
Expected:
(string) ''
There can be other places that access window buffer info (e.g.
`tabpagebuflist()`), so checking `w_closing` in `win_findbuf()` doesn't
solve the crash in all cases, and may also cause Nvim's behavior to
diverge from Vim.
Fix#14998
Many filetypes from filetype.vim set buffer-local variables, meaning
vim.filetype.match cannot be used without side effects. Instead of
setting these buffer-local variables in the filetype detection functions
themselves, have vim.filetype.match return an optional function value
that, when called, sets these variables. This allows vim.filetype.match
to work without side effects.
`vim.keymap.del` takes an `opts` parameter that lets caller refer to and
delete buffer-local mappings. For some reason the implementation of
`vim.keymap.del` mutates the table that is passed in, setting
`opts.buffer` to `nil`. This is wrong and also undocumented.
vim.tbl_get takes a table with subsequent string arguments (variadic) that
index into the table. If the value pointed to by the set of keys exists,
the function returns the value. If the set of keys does not exist, the
function returns nil.