fix(lsp): handle relative='editor' in make_floating_popup_options() #39320

Problem:  With `vim.g.health = { style = 'float' }`, running
          `:checkhealth` from a `:help` buffer placed the float in the
          top-left corner instead of centered.
          make_floating_popup_options() picks the NW/NE/SW/SE anchor
          and the available height from cursor-relative metrics
          (winline(), wincol(), winheight()). When the caller passes
          relative='editor', those metrics are meaningless, so the
          function could flip to an 'E' anchor and clamp the float
          off-screen.
Solution: When relative='editor', treat the whole editor area as
          available space (lines_above=0, lines_below=&lines,
          wincol=0). This makes the NW anchor the natural choice and
          keeps the float position stable regardless of where the
          cursor is in the current window.

AI-assisted: Claude Code
This commit is contained in:
Daigo Yamashita
2026-04-26 12:41:13 -07:00
committed by GitHub
parent 834047cb14
commit 8308544fe5
2 changed files with 29 additions and 4 deletions

View File

@@ -922,9 +922,19 @@ function M.make_floating_popup_options(width, height, opts)
local anchor = ''
local lines_above = opts.relative == 'mouse' and vim.fn.getmousepos().line - 1
or vim.fn.winline() - 1
local lines_below = vim.fn.winheight(0) - lines_above
local lines_above --- @type integer
local lines_below --- @type integer
if opts.relative == 'mouse' then
lines_above = vim.fn.getmousepos().line - 1
lines_below = vim.fn.winheight(0) - lines_above
elseif opts.relative == 'editor' then
-- No cursor to anchor against; treat the whole editor as space below.
lines_above = 0
lines_below = vim.o.lines
else
lines_above = vim.fn.winline() - 1
lines_below = vim.fn.winheight(0) - lines_above
end
local anchor_bias = opts.anchor_bias or 'auto'
@@ -951,7 +961,14 @@ function M.make_floating_popup_options(width, height, opts)
row = 0
end
local wincol = opts.relative == 'mouse' and vim.fn.getmousepos().column or vim.fn.wincol()
local wincol --- @type integer
if opts.relative == 'mouse' then
wincol = vim.fn.getmousepos().column
elseif opts.relative == 'editor' then
wincol = 0
else
wincol = vim.fn.wincol()
end
if wincol + width + (opts.offset_x or 0) <= vim.o.columns then
anchor = anchor .. 'W'