From dc821c2588cc5088fc397c1fd16ad0f3056a4241 Mon Sep 17 00:00:00 2001 From: Liam Dyer Date: Tue, 8 Oct 2024 09:57:39 -0400 Subject: [PATCH] fix: autocomplete window positioning with borders Closes #29 --- lua/blink/cmp/windows/autocomplete.lua | 2 +- lua/blink/cmp/windows/documentation.lua | 28 ++++++++++++++++++------- lua/blink/cmp/windows/lib/init.lua | 16 +++++++------- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/lua/blink/cmp/windows/autocomplete.lua b/lua/blink/cmp/windows/autocomplete.lua index 06d84591..22e37b3b 100644 --- a/lua/blink/cmp/windows/autocomplete.lua +++ b/lua/blink/cmp/windows/autocomplete.lua @@ -105,7 +105,7 @@ function autocomplete.update_position(context) -- detect if there's space above/below the cursor -- todo: should pick the largest space if both are false and limit height of the window - local is_space_below = screen_height - (cursor_row - screen_scroll_range.start_line) >= height + local is_space_below = screen_height - (cursor_row - screen_scroll_range.start_line) > height local is_space_above = cursor_row - screen_scroll_range.start_line > height -- default to the user's preference but attempt to use the other options diff --git a/lua/blink/cmp/windows/documentation.lua b/lua/blink/cmp/windows/documentation.lua index c127ade1..9bf1949c 100644 --- a/lua/blink/cmp/windows/documentation.lua +++ b/lua/blink/cmp/windows/documentation.lua @@ -100,6 +100,9 @@ function docs.update_position() local autocomplete_winnr = autocomplete.win:get_win() if not autocomplete_winnr then return end local autocomplete_win_config = vim.api.nvim_win_get_config(autocomplete_winnr) + local autocomplete_win_width = autocomplete.win:get_width() + local autocomplete_win_height = autocomplete.win:get_height() + local autocomplete_border_size = autocomplete.win:get_border_size() local screen_width = vim.api.nvim_win_get_width(0) local screen_height = vim.api.nvim_win_get_height(0) @@ -113,9 +116,9 @@ function docs.update_position() local width = docs.win:get_width() local space_above = autocomplete_win_config.row - 1 > height - local space_below = screen_height - autocomplete_win_config.height - autocomplete_win_config.row > height + local space_below = screen_height - autocomplete_win_height - autocomplete_win_config.row > height local space_left = autocomplete_win_config.col > width - local space_right = screen_width - autocomplete_win_config.width - autocomplete_win_config.col > width + local space_right = screen_width - autocomplete_win_width - autocomplete_win_config.col > width local function set_config(opts) vim.api.nvim_win_set_config(winnr, { relative = 'win', win = autocomplete_winnr, row = opts.row, col = opts.col }) @@ -123,23 +126,32 @@ function docs.update_position() for _, direction in ipairs(direction_priority) do if direction == 'n' and space_above then if autocomplete_win_is_up then - set_config({ row = -height, col = 0 }) + set_config({ row = -height - autocomplete_border_size.top, col = -autocomplete_border_size.left }) else - set_config({ row = -1 - height, col = 0 }) + set_config({ row = -1 - height - autocomplete_border_size.top, col = -autocomplete_border_size.left }) end return elseif direction == 's' and space_below then if autocomplete_win_is_up then - set_config({ row = 1 + autocomplete_win_config.height, col = 0 }) + set_config({ + row = 1 + autocomplete_win_height - autocomplete_border_size.top, + col = -autocomplete_border_size.left, + }) else - set_config({ row = autocomplete_win_config.height, col = 0 }) + set_config({ + row = autocomplete_win_height - autocomplete_border_size.top, + col = -autocomplete_border_size.left, + }) end return elseif direction == 'e' and space_right then - set_config({ row = 0, col = autocomplete_win_config.width }) + set_config({ + row = -autocomplete_border_size.top, + col = autocomplete_win_config.width + autocomplete_border_size.left, + }) return elseif direction == 'w' and space_left then - set_config({ row = 0, col = -1 - width }) + set_config({ row = -autocomplete_border_size.top, col = -width - autocomplete_border_size.left }) return end end diff --git a/lua/blink/cmp/windows/lib/init.lua b/lua/blink/cmp/windows/lib/init.lua index 8a24d1b9..7f725890 100644 --- a/lua/blink/cmp/windows/lib/init.lua +++ b/lua/blink/cmp/windows/lib/init.lua @@ -111,19 +111,19 @@ function win:get_content_height() return vim.api.nvim_win_text_height(self:get_win(), {}).all end ---- @return { vertical: number, horizontal: number } +--- @return { vertical: number, horizontal: number, left: number, right: number, top: number, bottom: number } function win:get_border_size() - if not self:is_open() then return { vertical = 0, horizontal = 0 } end + if not self:is_open() then return { vertical = 0, horizontal = 0, left = 0, right = 0, top = 0, bottom = 0 } end local border = self.config.border if border == 'none' then - return { vertical = 0, horizontal = 0 } + return { vertical = 0, horizontal = 0, left = 0, right = 0, top = 0, bottom = 0 } elseif border == 'padded' then - return { vertical = 0, horizontal = 1 } + return { vertical = 0, horizontal = 1, left = 1, right = 0, top = 0, bottom = 0 } elseif border == 'shadow' then - return { vertical = 1, horizontal = 1 } + return { vertical = 1, horizontal = 1, left = 0, right = 1, top = 0, bottom = 1 } elseif type(border) == 'string' then - return { vertical = 2, horizontal = 2 } + return { vertical = 2, horizontal = 2, left = 1, right = 1, top = 1, bottom = 1 } elseif type(border) == 'table' and border ~= nil then -- borders can be a table of strings and act differently with different # of chars -- so we normalize it: https://neovim.io/doc/user/api.html#nvim_open_win() @@ -139,10 +139,10 @@ function win:get_border_size() local bottom = resolved_border[6] == '' and 0 or 1 local left = resolved_border[8] == '' and 0 or 1 local right = resolved_border[4] == '' and 0 or 1 - return { vertical = top + bottom, horizontal = left + right } + return { vertical = top + bottom, horizontal = left + right, left = left, right = right, top = top, bottom = bottom } end - return { vertical = 0, horizontal = 0 } + return { vertical = 0, horizontal = 0, left = 0, right = 0, top = 0, bottom = 0 } end --- @return number