Skip to content

Commit 3b843c6

Browse files
xzbxzbdmw
authored andcommitted
Dynamic window flip
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'
1 parent b773577 commit 3b843c6

3 files changed

Lines changed: 65 additions & 3 deletions

File tree

lua/cmp/view.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ view.new = function()
2525
local self = setmetatable({}, { __index = view })
2626
self.resolve_dedup = async.dedup()
2727
self.is_docs_view_pinned = false
28-
self.custom_entries_view = custom_entries_view.new()
28+
self.ghost_text_view = ghost_text_view.new()
29+
self.custom_entries_view = custom_entries_view.new(ghost_text_view)
2930
self.native_entries_view = native_entries_view.new()
3031
self.wildmenu_entries_view = wildmenu_entries_view.new()
3132
self.docs_view = docs_view.new()
32-
self.ghost_text_view = ghost_text_view.new()
3333
self.event = event.new()
3434

3535
return self

lua/cmp/view/custom_entries_view.lua

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ local DEFAULT_HEIGHT = 10 -- @see https://github.com/vim/vim/blob/master/src/pop
1212

1313
---@class cmp.CustomEntriesView
1414
---@field private entries_win cmp.Window
15+
---@field private ghost_text_view cmp.GhostTextView
1516
---@field private offset integer
1617
---@field private active boolean
1718
---@field private entries cmp.Entry[]
@@ -21,7 +22,7 @@ local custom_entries_view = {}
2122

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

24-
custom_entries_view.new = function()
25+
custom_entries_view.new = function(ghost_text_view)
2526
local self = setmetatable({}, { __index = custom_entries_view })
2627

2728
self.entries_win = window.new()
@@ -43,6 +44,7 @@ custom_entries_view.new = function()
4344
self.active = false
4445
self.entries = {}
4546
self.bottom_up = false
47+
self.ghost_text_view = ghost_text_view
4648

4749
autocmd.subscribe(
4850
'CompleteChanged',
@@ -446,6 +448,50 @@ custom_entries_view._select = function(self, cursor, option)
446448
0,
447449
})
448450

451+
if not self.bottom_up then
452+
local info = self.entries_win:info()
453+
local border_info = info.border_info
454+
local border_offset_row = border_info.top + border_info.bottom
455+
local row = api.get_screen_cursor()[1]
456+
457+
-- This logic keeps the same as open()
458+
local height = vim.api.nvim_get_option_value('pumheight', {})
459+
height = height ~= 0 and height or #self.entries
460+
height = math.min(height, #self.entries)
461+
462+
-- If user specify 'noselect', select first entry
463+
local entry = self:get_selected_entry() or self:get_first_entry()
464+
465+
local should_move_up = self.ghost_text_view:has_multi_line(entry) and row > height + border_offset_row
466+
if should_move_up then
467+
self.bottom_up = true
468+
height = math.min(height, row - 1)
469+
row = row - height - border_offset_row - 1
470+
local completion = config.get().window.completion
471+
local new_position = {
472+
style = 'minimal',
473+
relative = 'editor',
474+
row = math.max(0, row),
475+
height = height,
476+
col = info.col,
477+
width = info.width,
478+
border = completion.border,
479+
zindex = completion.zindex or 1001,
480+
}
481+
self.entries_win:open(new_position)
482+
483+
if not self:is_direction_top_down() then
484+
local n = #self.entries
485+
for i = 1, math.floor(n / 2) do
486+
self.entries[i], self.entries[n - i + 1] = self.entries[n - i + 1], self.entries[i]
487+
end
488+
self:_select(#self.entries - cursor + 1, option)
489+
else
490+
self:_select(cursor, option)
491+
end
492+
end
493+
end
494+
449495
if is_insert then
450496
self:_insert(self.entries[cursor] and self.entries[cursor]:get_vim_item(self.offset).word or self.prefix)
451497
end

lua/cmp/view/ghost_text_view.lua

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,20 @@ ghost_text_view.hide = function(self)
157157
end
158158
end
159159

160+
ghost_text_view.has_multi_line = function(self, e)
161+
if not api.is_insert_mode() then
162+
return false
163+
end
164+
local c = config.get().experimental.ghost_text
165+
if not c then
166+
return false
167+
end
168+
169+
local _, col = unpack(vim.api.nvim_win_get_cursor(0))
170+
local line = vim.api.nvim_get_current_line()
171+
172+
local virt_lines = self.text_gen(self, line, col, e)
173+
return #virt_lines > 1
174+
end
175+
160176
return ghost_text_view

0 commit comments

Comments
 (0)