Skip to content

Commit

Permalink
fix: autocomplete window positioning with borders
Browse files Browse the repository at this point in the history
Closes Saghen#29
  • Loading branch information
Saghen authored and lopi-py committed Oct 10, 2024
1 parent aea27c0 commit dc821c2
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 17 deletions.
2 changes: 1 addition & 1 deletion lua/blink/cmp/windows/autocomplete.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
28 changes: 20 additions & 8 deletions lua/blink/cmp/windows/documentation.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -113,33 +116,42 @@ 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 })
end
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
Expand Down
16 changes: 8 additions & 8 deletions lua/blink/cmp/windows/lib/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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
Expand Down

0 comments on commit dc821c2

Please sign in to comment.