Skip to content

Commit

Permalink
Dynamic window flip
Browse files Browse the repository at this point in the history
add support for all selection order

if top space is not enough, do not flip window

take border into consider

set every possible winconfig

see if it is multiline  for 'noselect'
  • Loading branch information
xzb authored and xzbdmw committed Oct 22, 2024
1 parent b773577 commit 6755b51
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 3 deletions.
4 changes: 2 additions & 2 deletions lua/cmp/view.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ view.new = function()
local self = setmetatable({}, { __index = view })
self.resolve_dedup = async.dedup()
self.is_docs_view_pinned = false
self.custom_entries_view = custom_entries_view.new()
self.ghost_text_view = ghost_text_view.new()
self.custom_entries_view = custom_entries_view.new(ghost_text_view)
self.native_entries_view = native_entries_view.new()
self.wildmenu_entries_view = wildmenu_entries_view.new()
self.docs_view = docs_view.new()
self.ghost_text_view = ghost_text_view.new()
self.event = event.new()

return self
Expand Down
46 changes: 45 additions & 1 deletion lua/cmp/view/custom_entries_view.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ local DEFAULT_HEIGHT = 10 -- @see https://github.com/vim/vim/blob/master/src/pop

---@class cmp.CustomEntriesView
---@field private entries_win cmp.Window
---@field private ghost_text_view cmp.GhostTextView
---@field private offset integer
---@field private active boolean
---@field private entries cmp.Entry[]
Expand All @@ -21,7 +22,7 @@ local custom_entries_view = {}

custom_entries_view.ns = vim.api.nvim_create_namespace('cmp.view.custom_entries_view')

custom_entries_view.new = function()
custom_entries_view.new = function(ghost_text_view)
local self = setmetatable({}, { __index = custom_entries_view })

self.entries_win = window.new()
Expand All @@ -43,6 +44,7 @@ custom_entries_view.new = function()
self.active = false
self.entries = {}
self.bottom_up = false
self.ghost_text_view = ghost_text_view

autocmd.subscribe(
'CompleteChanged',
Expand Down Expand Up @@ -446,6 +448,48 @@ custom_entries_view._select = function(self, cursor, option)
0,
})

if not self.bottom_up then
-- This logic keeps the same as open()
local info = self.entries_win:info()
local border_info = info.border_info
local border_offset_row = border_info.top + border_info.bottom
local row = api.get_screen_cursor()[1]
local height = vim.api.nvim_get_option_value('pumheight', {})
height = height ~= 0 and height or #self.entries
height = math.min(height, #self.entries)

-- If user specify 'noselect', select first entry
local entry = self:get_selected_entry() or self:get_first_entry()
local should_move_up = self.ghost_text_view:has_multi_line(entry) and row > height + border_offset_row
if should_move_up then
self.bottom_up = true
height = math.min(height, row - 1)
row = row - height - border_offset_row - 1
local completion = config.get().window.completion
local new_position = {
style = 'minimal',
relative = 'editor',
row = math.max(0, row),
height = height,
col = info.col,
width = info.width,
border = completion.border,
zindex = completion.zindex or 1001,
}
self.entries_win:open(new_position)

if not self:is_direction_top_down() then
local n = #self.entries
for i = 1, math.floor(n / 2) do
self.entries[i], self.entries[n - i + 1] = self.entries[n - i + 1], self.entries[i]
end
self:_select(#self.entries - cursor + 1, option)
else
self:_select(cursor, option)
end
end
end

if is_insert then
self:_insert(self.entries[cursor] and self.entries[cursor]:get_vim_item(self.offset).word or self.prefix)
end
Expand Down
16 changes: 16 additions & 0 deletions lua/cmp/view/ghost_text_view.lua
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,20 @@ ghost_text_view.hide = function(self)
end
end

ghost_text_view.has_multi_line = function(self, e)
if not api.is_insert_mode() then
return false
end
local c = config.get().experimental.ghost_text
if not c then
return false
end

local _, col = unpack(vim.api.nvim_win_get_cursor(0))
local line = vim.api.nvim_get_current_line()

local virt_lines = self.text_gen(self, line, col, e)
return #virt_lines > 1
end

return ghost_text_view

0 comments on commit 6755b51

Please sign in to comment.