Skip to content

Commit 1002d1c

Browse files
xzbxzbdmw
xzb
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 ec28d39 commit 1002d1c

File tree

3 files changed

+70
-3
lines changed

3 files changed

+70
-3
lines changed

lua/cmp/view.lua

+2-2
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

+52-1
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',
@@ -431,6 +433,55 @@ custom_entries_view._select = function(self, cursor, option)
431433
0,
432434
})
433435

436+
if not self.bottom_up then
437+
local info = self.entries_win:info()
438+
local border_info = info.border_info
439+
local border_offset_row = border_info.top + border_info.bottom
440+
local row = api.get_screen_cursor()[1]
441+
442+
-- If user specify 'noselect', select first entry
443+
local entry = self:get_selected_entry() or self:get_first_entry()
444+
local should_move_up = self.ghost_text_view:has_multi_line(entry) and row > self.entries_win:get_content_height() + border_offset_row
445+
446+
if should_move_up then
447+
self.bottom_up = true
448+
449+
-- This logic keeps the same as open()
450+
local height = vim.api.nvim_get_option_value('pumheight', {})
451+
height = height ~= 0 and height or #self.entries
452+
height = math.min(height, #self.entries)
453+
height = math.min(height, row - 1)
454+
455+
row = row - height - border_offset_row - 1
456+
if row < 0 then
457+
height = height + row
458+
end
459+
460+
local completion = config.get().window.completion
461+
local new_position = {
462+
style = 'minimal',
463+
relative = 'editor',
464+
row = math.max(0, row),
465+
height = height,
466+
col = info.col,
467+
width = info.width,
468+
border = completion.border,
469+
zindex = completion.zindex or 1001,
470+
}
471+
self.entries_win:open(new_position)
472+
473+
if not self:is_direction_top_down() then
474+
local n = #self.entries
475+
for i = 1, math.floor(n / 2) do
476+
self.entries[i], self.entries[n - i + 1] = self.entries[n - i + 1], self.entries[i]
477+
end
478+
self:_select(#self.entries - cursor + 1, option)
479+
else
480+
self:_select(cursor, option)
481+
end
482+
end
483+
end
484+
434485
if is_insert then
435486
self:_insert(self.entries[cursor] and self.entries[cursor]:get_vim_item(self.offset).word or self.prefix)
436487
end

lua/cmp/view/ghost_text_view.lua

+16
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,20 @@ ghost_text_view.hide = function(self)
155155
end
156156
end
157157

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

0 commit comments

Comments
 (0)