mirror of
https://github.com/neovim/neovim.git
synced 2024-12-23 20:55:18 -07:00
feat(lsp): improve control over placement of floating windows (#24494)
This commit is contained in:
parent
bb38c066a9
commit
5e3cf9fb4b
@ -1580,7 +1580,8 @@ hover({_}, {result}, {ctx}, {config}) *vim.lsp.handlers.hover()*
|
||||
• {config} (table) Configuration table.
|
||||
• border: (default=nil)
|
||||
• Add borders to the floating window
|
||||
• See |nvim_open_win()|
|
||||
• See |vim.lsp.util.open_floating_preview()| for more
|
||||
options.
|
||||
|
||||
*vim.lsp.handlers.signature_help()*
|
||||
signature_help({_}, {result}, {ctx}, {config})
|
||||
@ -1599,7 +1600,8 @@ signature_help({_}, {result}, {ctx}, {config})
|
||||
• {config} (table) Configuration table.
|
||||
• border: (default=nil)
|
||||
• Add borders to the floating window
|
||||
• See |nvim_open_win()|
|
||||
• See |vim.lsp.util.open_floating_preview()| for more
|
||||
options
|
||||
|
||||
|
||||
==============================================================================
|
||||
@ -1791,6 +1793,13 @@ make_floating_popup_options({width}, {height}, {opts})
|
||||
• focusable (string or table) override `focusable`
|
||||
• zindex (string or table) override `zindex`, defaults to 50
|
||||
• relative ("mouse"|"cursor") defaults to "cursor"
|
||||
• anchor_bias ("auto"|"above"|"below") defaults to "auto"
|
||||
• "auto": place window based on which side of the cursor
|
||||
has more lines
|
||||
• "above": place the window above the cursor unless there
|
||||
are not enough lines to display the full window height.
|
||||
• "below": place the window below the cursor unless there
|
||||
are not enough lines to display the full window height.
|
||||
|
||||
Return: ~
|
||||
(table) Options
|
||||
@ -1892,8 +1901,9 @@ open_floating_preview({contents}, {syntax}, {opts})
|
||||
Parameters: ~
|
||||
• {contents} (table) of lines to show in window
|
||||
• {syntax} (string) of syntax to set for opened buffer
|
||||
• {opts} (table) with optional fields (additional keys are passed
|
||||
on to |nvim_open_win()|)
|
||||
• {opts} (table) with optional fields (additional keys are filtered
|
||||
with |vim.lsp.util.make_floating_popup_options()| before
|
||||
they are passed on to |nvim_open_win()|)
|
||||
• height: (integer) height of floating window
|
||||
• width: (integer) width of floating window
|
||||
• wrap: (boolean, default true) wrap long lines
|
||||
|
@ -120,6 +120,8 @@ The following new APIs and features were added.
|
||||
indicator to see if a server supports a feature. Instead use
|
||||
`client.supports_method(<method>)`. It considers both the dynamic
|
||||
capabilities and static `server_capabilities`.
|
||||
• Added a new `anchor_bias` option to |lsp-handlers| to aid in positioning of
|
||||
floating windows.
|
||||
|
||||
• Treesitter
|
||||
• Bundled parsers and queries (highlight, folds) for Markdown, Python, and
|
||||
|
@ -355,7 +355,7 @@ end
|
||||
---@param config table Configuration table.
|
||||
--- - border: (default=nil)
|
||||
--- - Add borders to the floating window
|
||||
--- - See |nvim_open_win()|
|
||||
--- - See |vim.lsp.util.open_floating_preview()| for more options.
|
||||
function M.hover(_, result, ctx, config)
|
||||
config = config or {}
|
||||
config.focus_id = ctx.method
|
||||
@ -442,7 +442,7 @@ M[ms.textDocument_implementation] = location_handler
|
||||
---@param config table Configuration table.
|
||||
--- - border: (default=nil)
|
||||
--- - Add borders to the floating window
|
||||
--- - See |nvim_open_win()|
|
||||
--- - See |vim.lsp.util.open_floating_preview()| for more options
|
||||
function M.signature_help(_, result, ctx, config)
|
||||
config = config or {}
|
||||
config.focus_id = ctx.method
|
||||
|
@ -1087,6 +1087,12 @@ end
|
||||
--- - focusable (string or table) override `focusable`
|
||||
--- - zindex (string or table) override `zindex`, defaults to 50
|
||||
--- - relative ("mouse"|"cursor") defaults to "cursor"
|
||||
--- - anchor_bias ("auto"|"above"|"below") defaults to "auto"
|
||||
--- - "auto": place window based on which side of the cursor has more lines
|
||||
--- - "above": place the window above the cursor unless there are not enough lines
|
||||
--- to display the full window height.
|
||||
--- - "below": place the window below the cursor unless there are not enough lines
|
||||
--- to display the full window height.
|
||||
---@return table Options
|
||||
function M.make_floating_popup_options(width, height, opts)
|
||||
validate({
|
||||
@ -1105,7 +1111,20 @@ function M.make_floating_popup_options(width, height, opts)
|
||||
or vim.fn.winline() - 1
|
||||
local lines_below = vim.fn.winheight(0) - lines_above
|
||||
|
||||
if lines_above < lines_below then
|
||||
local anchor_bias = opts.anchor_bias or 'auto'
|
||||
|
||||
local anchor_below
|
||||
|
||||
if anchor_bias == 'below' then
|
||||
anchor_below = (lines_below > lines_above) or (height <= lines_below)
|
||||
elseif anchor_bias == 'above' then
|
||||
local anchor_above = (lines_above > lines_below) or (height <= lines_above)
|
||||
anchor_below = not anchor_above
|
||||
else
|
||||
anchor_below = lines_below > lines_above
|
||||
end
|
||||
|
||||
if anchor_below then
|
||||
anchor = anchor .. 'N'
|
||||
height = math.min(lines_below, height)
|
||||
row = 1
|
||||
@ -1635,7 +1654,8 @@ end
|
||||
---
|
||||
---@param contents table of lines to show in window
|
||||
---@param syntax string of syntax to set for opened buffer
|
||||
---@param opts table with optional fields (additional keys are passed on to |nvim_open_win()|)
|
||||
---@param opts table with optional fields (additional keys are filtered with |vim.lsp.util.make_floating_popup_options()|
|
||||
--- before they are passed on to |nvim_open_win()|)
|
||||
--- - height: (integer) height of floating window
|
||||
--- - width: (integer) width of floating window
|
||||
--- - wrap: (boolean, default true) wrap long lines
|
||||
|
@ -1,4 +1,6 @@
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local Screen = require('test.functional.ui.screen')
|
||||
local feed = helpers.feed
|
||||
|
||||
local eq = helpers.eq
|
||||
local exec_lua = helpers.exec_lua
|
||||
@ -85,4 +87,98 @@ describe('vim.lsp.util', function()
|
||||
eq(expected, stylize_markdown(lines, opts))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("make_floating_popup_options", function ()
|
||||
|
||||
local function assert_anchor(anchor_bias, expected_anchor)
|
||||
local opts = exec_lua([[
|
||||
local args = { ... }
|
||||
local anchor_bias = args[1]
|
||||
return vim.lsp.util.make_floating_popup_options(30, 10, { anchor_bias = anchor_bias })
|
||||
]], anchor_bias)
|
||||
|
||||
eq(expected_anchor, string.sub(opts.anchor, 1, 1))
|
||||
end
|
||||
|
||||
local screen
|
||||
before_each(function ()
|
||||
helpers.clear()
|
||||
screen = Screen.new(80, 80)
|
||||
screen:attach()
|
||||
feed("79i<CR><Esc>") -- fill screen with empty lines
|
||||
end)
|
||||
|
||||
describe('when on the first line it places window below', function ()
|
||||
before_each(function ()
|
||||
feed('gg')
|
||||
end)
|
||||
|
||||
it('for anchor_bias = "auto"', function ()
|
||||
assert_anchor('auto', 'N')
|
||||
end)
|
||||
|
||||
it('for anchor_bias = "above"', function ()
|
||||
assert_anchor('above', 'N')
|
||||
end)
|
||||
|
||||
it('for anchor_bias = "below"', function ()
|
||||
assert_anchor('below', 'N')
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('when on the last line it places window above', function ()
|
||||
before_each(function ()
|
||||
feed('G')
|
||||
end)
|
||||
|
||||
it('for anchor_bias = "auto"', function ()
|
||||
assert_anchor('auto', 'S')
|
||||
end)
|
||||
|
||||
it('for anchor_bias = "above"', function ()
|
||||
assert_anchor('above', 'S')
|
||||
end)
|
||||
|
||||
it('for anchor_bias = "below"', function ()
|
||||
assert_anchor('below', 'S')
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('with 20 lines above, 59 lines below', function ()
|
||||
before_each(function ()
|
||||
feed('gg20j')
|
||||
end)
|
||||
|
||||
it('places window below for anchor_bias = "auto"', function ()
|
||||
assert_anchor('auto', 'N')
|
||||
end)
|
||||
|
||||
it('places window above for anchor_bias = "above"', function ()
|
||||
assert_anchor('above', 'S')
|
||||
end)
|
||||
|
||||
it('places window below for anchor_bias = "below"', function ()
|
||||
assert_anchor('below', 'N')
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('with 59 lines above, 20 lines below', function ()
|
||||
before_each(function ()
|
||||
feed('G20k')
|
||||
end)
|
||||
|
||||
it('places window above for anchor_bias = "auto"', function ()
|
||||
assert_anchor('auto', 'S')
|
||||
end)
|
||||
|
||||
it('places window above for anchor_bias = "above"', function ()
|
||||
assert_anchor('above', 'S')
|
||||
end)
|
||||
|
||||
it('places window below for anchor_bias = "below"', function ()
|
||||
assert_anchor('below', 'N')
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
end)
|
||||
|
Loading…
Reference in New Issue
Block a user