aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/lua/vim/lsp/util.lua2
-rw-r--r--src/nvim/api/vim.c4
-rw-r--r--src/nvim/window.c8
-rw-r--r--test/functional/plugin/lsp_spec.lua77
-rw-r--r--test/functional/ui/float_spec.lua287
5 files changed, 295 insertions, 83 deletions
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index e95f170427..09d0a8e62a 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -975,7 +975,7 @@ function M.make_floating_popup_options(width, height, opts)
else
anchor = anchor..'S'
height = math.min(lines_above, height)
- row = -get_border_size(opts).height
+ row = 0
end
if vim.fn.wincol() + width + (opts.offset_x or 0) <= api.nvim_get_option('columns') then
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 3be45d0cf7..8e0502e03b 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -1360,7 +1360,9 @@ void nvim_chan_send(Integer chan, String data, Error *err)
/// - `bufpos`: Places float relative to buffer text (only when
/// relative="win"). Takes a tuple of zero-indexed [line, column].
/// `row` and `col` if given are applied relative to this
-/// position, else they default to `row=1` and `col=0`
+/// position, else they default to:
+/// - `row=1` and `col=0` if `anchor` is "NW" or "NE"
+/// - `row=0` and `col=0` if `anchor` is "SW" or "SE"
/// (thus like a tooltip near the buffer text).
/// - `row`: Row position in units of "screen cell height", may be fractional.
/// - `col`: Column position in units of "screen cell width", may be
diff --git a/src/nvim/window.c b/src/nvim/window.c
index c0f537aab3..ff97eaa757 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -853,12 +853,12 @@ void ui_ext_win_position(win_T *wp)
bool east = c.anchor & kFloatAnchorEast;
bool south = c.anchor & kFloatAnchorSouth;
- int comp_row = (int)row - (south ? wp->w_height : 0);
- int comp_col = (int)col - (east ? wp->w_width : 0);
+ int comp_row = (int)row - (south ? wp->w_height_outer : 0);
+ int comp_col = (int)col - (east ? wp->w_width_outer : 0);
comp_row += grid->comp_row;
comp_col += grid->comp_col;
- comp_row = MAX(MIN(comp_row, Rows-wp->w_height_outer-1), 0);
- comp_col = MAX(MIN(comp_col, Columns-wp->w_width_outer), 0);
+ comp_row = MAX(MIN(comp_row, Rows - wp->w_height_outer - 1), 0);
+ comp_col = MAX(MIN(comp_col, Columns - wp->w_width_outer), 0);
wp->w_winrow = comp_row;
wp->w_wincol = comp_col;
bool valid = (wp->w_redr_type == 0);
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua
index 071585a437..8f9b194690 100644
--- a/test/functional/plugin/lsp_spec.lua
+++ b/test/functional/plugin/lsp_spec.lua
@@ -2022,83 +2022,6 @@ describe('LSP', function()
end)
end)
- describe('lsp.util.make_floating_popup_options', function()
- before_each(function()
- exec_lua [[
- local bufnr = vim.uri_to_bufnr("file:///fake/uri")
- local winheight = vim.fn.winheight(0)
- for i = 1, winheight do
- vim.api.nvim_buf_set_lines(bufnr, 0, 0, false, {''})
- end
- vim.api.nvim_win_set_buf(0, bufnr)
- vim.api.nvim_win_set_cursor(0, {winheight, 0})
- ]]
- end)
-
- local function popup_row(opts)
- return exec_lua([[
- return vim.lsp.util.make_floating_popup_options(...).row
- ]], 2, 2, opts)
- end
-
- local err_pattern = "^Error executing lua: %.%.%./util%.lua:0: invalid floating preview border: .*%. :help vim%.api%.nvim_open_win%(%)$"
-
- it('calculates default border height correctly', function()
- eq(0, popup_row())
- end)
-
- it('calculates string border height correctly', function()
- eq(0, popup_row({border = 'none'}))
- eq(-2, popup_row({border = 'single'}))
- eq(-2, popup_row({border = 'double'}))
- eq(-2, popup_row({border = 'rounded'}))
- eq(-2, popup_row({border = 'solid'}))
- eq(-1, popup_row({border = 'shadow'}))
- end)
-
- it('error on invalid string border', function()
- matches(err_pattern, pcall_err(popup_row, {border = ''}))
- matches(err_pattern, pcall_err(popup_row, {border = 'invalid'}))
- end)
-
- it('error on invalid array border length', function()
- matches(err_pattern, pcall_err(popup_row, {border = {}}))
- matches(err_pattern, pcall_err(popup_row, {border = {'', '', ''}}))
- matches(err_pattern, pcall_err(popup_row, {border = {'', '', '', '', ''}}))
- end)
-
- it('error on invalid array border member type', function()
- matches(err_pattern, pcall_err(popup_row, {border = {0}}))
- end)
-
- it('calculates 8-array border height correctly', function()
- eq(0, popup_row({border = {'', '', '', '', '', '', '', ''}}))
- eq(-2, popup_row({border = {'', '~', '', '~', '', '~', '', '~'}}))
- eq(-1, popup_row({border = {'', '', '', '~', '', '~', '', ''}}))
- eq(0, popup_row({border = {'', '', '', {'~', 'NormalFloat'}, '', '', '', {'~', 'NormalFloat'}}}))
- eq(-2, popup_row({border = {'', {'~', 'NormalFloat'}, '', '', '', {'~', 'NormalFloat'}, '', ''}}))
- end)
-
- it('calculates 4-array border height correctly', function()
- eq(0, popup_row({border = {'', '', '', ''}}))
- eq(-2, popup_row({border = {'', '~', '', '~'}}))
- eq(0, popup_row({border = {'', '', '', {'~', 'NormalFloat'}}}))
- eq(-2, popup_row({border = {'', {'~', 'NormalFloat'}, '', ''}}))
- end)
-
- it('calculates 2-array border height correctly', function()
- eq(0, popup_row({border = {'', ''}}))
- eq(-2, popup_row({border = {'', '~'}}))
- eq(-2, popup_row({border = {'', {'~', 'NormalFloat'}}}))
- end)
-
- it('calculates 1-array border height correctly', function()
- eq(0, popup_row({border = {''}}))
- eq(-2, popup_row({border = {'~'}}))
- eq(-2, popup_row({border = {{'~', 'NormalFloat'}}}))
- end)
- end)
-
describe('lsp.util._make_floating_popup_size', function()
before_each(function()
exec_lua [[ contents =
diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua
index ccf5f963d1..2e17aa68b2 100644
--- a/test/functional/ui/float_spec.lua
+++ b/test/functional/ui/float_spec.lua
@@ -1866,6 +1866,293 @@ describe('float window', function()
end
end)
+ it('always anchor to corner including border', function()
+ screen:try_resize(40,13)
+ meths.buf_set_lines(0, 0, -1, true, {'just some example text', 'some more example text'})
+ feed('ggeee')
+ command('below split')
+ if multigrid then
+ screen:expect([[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {5:[No Name] [+] }|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ {4:[No Name] [+] }|
+ [3:----------------------------------------]|
+ ## grid 2
+ just some example text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ |
+ ## grid 4
+ just some exampl^e text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ]])
+ else
+ screen:expect([[
+ just some example text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {5:[No Name] [+] }|
+ just some exampl^e text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {4:[No Name] [+] }|
+ |
+ ]])
+ end
+
+ local buf = meths.create_buf(false, false)
+ meths.buf_set_lines(buf, 0, -1, true, {' halloj! ',
+ ' BORDAA '})
+ local win = meths.open_win(buf, false, {relative='cursor', width=9, height=2, row=1, col=-2, border="double"})
+
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {5:[No Name] [+] }|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ {4:[No Name] [+] }|
+ [3:----------------------------------------]|
+ ## grid 2
+ just some example text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ |
+ ## grid 4
+ just some exampl^e text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 6
+ {5:╔═════════╗}|
+ {5:║}{1: halloj! }{5:║}|
+ {5:║}{1: BORDAA }{5:║}|
+ {5:╚═════════╝}|
+ ]], float_pos={
+ [6] = {{id = 1003}, "NW", 4, 1, 14, true}
+ }}
+ else
+ screen:expect([[
+ just some example text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {5:[No Name] [+] }|
+ just some exampl^e text |
+ some more exam{5:╔═════════╗} |
+ {0:~ }{5:║}{1: halloj! }{5:║}{0: }|
+ {0:~ }{5:║}{1: BORDAA }{5:║}{0: }|
+ {0:~ }{5:╚═════════╝}{0: }|
+ {4:[No Name] [+] }|
+ |
+ ]])
+ end
+
+ meths.win_set_config(win, {relative='cursor', row=0, col=-2, anchor='NE'})
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {5:[No Name] [+] }|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ {4:[No Name] [+] }|
+ [3:----------------------------------------]|
+ ## grid 2
+ just some example text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ |
+ ## grid 4
+ just some exampl^e text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 6
+ {5:╔═════════╗}|
+ {5:║}{1: halloj! }{5:║}|
+ {5:║}{1: BORDAA }{5:║}|
+ {5:╚═════════╝}|
+ ]], float_pos={
+ [6] = {{id = 1003}, "NE", 4, 0, 14, true}
+ }}
+ else
+ screen:expect([[
+ just some example text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {5:[No Name] [+] }|
+ jus{5:╔═════════╗}pl^e text |
+ som{5:║}{1: halloj! }{5:║}ple text |
+ {0:~ }{5:║}{1: BORDAA }{5:║}{0: }|
+ {0:~ }{5:╚═════════╝}{0: }|
+ {0:~ }|
+ {4:[No Name] [+] }|
+ |
+ ]])
+ end
+
+ meths.win_set_config(win, {relative='cursor', row=1, col=-2, anchor='SE'})
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {5:[No Name] [+] }|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ {4:[No Name] [+] }|
+ [3:----------------------------------------]|
+ ## grid 2
+ just some example text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ |
+ ## grid 4
+ just some exampl^e text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 6
+ {5:╔═════════╗}|
+ {5:║}{1: halloj! }{5:║}|
+ {5:║}{1: BORDAA }{5:║}|
+ {5:╚═════════╝}|
+ ]], float_pos={
+ [6] = {{id = 1003}, "SE", 4, 1, 14, true}
+ }}
+ else
+ screen:expect([[
+ just some example text |
+ some more example text |
+ {0:~ }|
+ {0:~ }{5:╔═════════╗}{0: }|
+ {0:~ }{5:║}{1: halloj! }{5:║}{0: }|
+ {5:[No║}{1: BORDAA }{5:║ }|
+ jus{5:╚═════════╝}pl^e text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {4:[No Name] [+] }|
+ |
+ ]])
+ end
+
+ meths.win_set_config(win, {relative='cursor', row=0, col=-2, anchor='SW'})
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {5:[No Name] [+] }|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ [4:----------------------------------------]|
+ {4:[No Name] [+] }|
+ [3:----------------------------------------]|
+ ## grid 2
+ just some example text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ |
+ ## grid 4
+ just some exampl^e text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 6
+ {5:╔═════════╗}|
+ {5:║}{1: halloj! }{5:║}|
+ {5:║}{1: BORDAA }{5:║}|
+ {5:╚═════════╝}|
+ ]], float_pos={
+ [6] = {{id = 1003}, "SW", 4, 0, 14, true}
+ }}
+ else
+ screen:expect([[
+ just some example text |
+ some more example text |
+ {0:~ }{5:╔═════════╗}{0: }|
+ {0:~ }{5:║}{1: halloj! }{5:║}{0: }|
+ {0:~ }{5:║}{1: BORDAA }{5:║}{0: }|
+ {5:[No Name] [+] ╚═════════╝ }|
+ just some exampl^e text |
+ some more example text |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {4:[No Name] [+] }|
+ |
+ ]])
+ end
+ end)
+
it('can be placed relative text in a window', function()
screen:try_resize(30,5)
local firstwin = meths.get_current_win().id