@@ -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
2223custom_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
0 commit comments