Problem:
Codebase inconsistently binds vim.api onto a or api.
Solution:
Use api everywhere. a as an identifier is too short to have at the
module level.
Problem: Clamp for height in floating windows enforced no more than
editor height - 1, disallowing full editor height floating windows when
using cmdheight=0
Solution: Clamp to full height, removing the -1. Tested to give the
intended results with cmdheight=0, 1, or more than 1. This also
inadvertently fixes a rendering error with cmdheight >1 where the
bottom border would be overlapped by the cmdline.
Semi-regression. The "ruler" behavior for a floating window
was never really specified but in practice followed the users
cursor movements in normal mode in a focused float, which seems
like a reasonable behavior to now specify.
scroll_delta contains how much the top line of a window moved since the
last time win_viewport was emitted. It is expected to be used to
implement smooth scrolling. For this purpose it only counts "virtual" or
"displayed" so folds should count as one line. Because of this it
adds extra information that cannot be computed from the topline
parameter.
Fixes#19227
Problem:
The "force" flag of win_close() complicates the code and adds edge cases
where it is not clear what the correct behavior should be.
The "free_buf" flag of win_close() is passed on to float windows when
closing the last window of a tabpage, which doesn't make much sense.
Solution:
Remove the "force" flag and always close float windows as if :close! is
used when closing the last window of a tabpage, and set the "free_buf"
flag for a float window based on whether its buffer can be freed.
As 'hidden' is on by default, this change shouldn't affect many people.
Problem:
No easy way to position a LSP hover window relative to mouse.
Solution:
Introduce another option to the `relative` key in `nvim_open_win()`.
With this PR it should be possible to override the handler and do something
similar to this https://github.com/neovim/neovim/pull/19481#issuecomment-1193248674
to have hover information displayed from the mouse.
Test case:
```lua
local util = require('vim.lsp.util')
local function make_position_param(window, offset_encoding)
window = window or 0
local buf = vim.api.nvim_win_get_buf(window)
local row, col
local mouse = vim.fn.getmousepos()
row = mouse.line
col = mouse.column
offset_encoding = offset_encoding or util._get_offset_encoding(buf)
row = row - 1
local line = vim.api.nvim_buf_get_lines(buf, row, row + 1, true)[1]
if not line then
return { line = 0, character = 0 }
end
if #line < col then
return { line = 0, character = 0 }
end
col = util._str_utfindex_enc(line, col, offset_encoding)
return { line = row, character = col }
end
local make_params = function(window, offset_encoding)
window = window or 0
local buf = vim.api.nvim_win_get_buf(window)
offset_encoding = offset_encoding or util._get_offset_encoding(buf)
return {
textDocument = util.make_text_document_params(buf),
position = make_position_param(window, offset_encoding),
}
end
local hover_timer = nil
vim.o.mousemoveevent = true
vim.keymap.set({ '', 'i' }, '<MouseMove>', function()
if hover_timer then
hover_timer:close()
end
hover_timer = vim.defer_fn(function()
hover_timer = nil
local params = make_params()
vim.lsp.buf_request(
0,
'textDocument/hover',
params,
vim.lsp.with(vim.lsp.handlers.hover, {
silent = true,
focusable = false,
relative = 'mouse',
})
)
end, 500)
return '<MouseMove>'
end, { expr = true })
```
Problem: test/functional/ui/screen.lua would be reloaded for each
*_spec.lua file, which causes an extra nvim session to be started
to get the color map each time.
solution: Mark screen.lua as a preloaded file, but defer the
loading of the color map to the first time Screen object is initialised.
Do not copy a lot of lua strings (dict keys) to just strequal() them
Just compare them directly to a dedicated hash function.
feat(generators): HASHY McHASHFACE
win_set_buf can trigger autocmds if noautocmd=false. If they close the window,
code afterwards will dereference the freed win_T* wp pointer.
This interaction became possible after commit 1def3d1542.
The reason deleting curbuf crashes, and not the buf passed to
`nvim_open_win`, is because the float initially edits curbuf (`win_init`)
until it's later set to edit buf (windows from `:new` and `:split <buf>`
behave similiarly: approx. `:split`, then `:buffer <buf>`).
`do_buffer` closes windows when their edited buffer is deleted (unless
it's the only window; N/A for floats), so the float closes when curbuf
is deleted, so we need to check `win_valid` after `win_set_buf` too.
Closes#15548