@@ -12,6 +12,7 @@ local DEFAULT_HEIGHT = 10 -- @see https://github.com/vim/vim/blob/master/src/pop
12
12
13
13
--- @class cmp.CustomEntriesView
14
14
--- @field private entries_win cmp.Window
15
+ --- @field private ghost_text_view cmp.GhostTextView
15
16
--- @field private offset integer
16
17
--- @field private active boolean
17
18
--- @field private entries cmp.Entry[]
@@ -21,7 +22,7 @@ local custom_entries_view = {}
21
22
22
23
custom_entries_view .ns = vim .api .nvim_create_namespace (' cmp.view.custom_entries_view' )
23
24
24
- custom_entries_view .new = function ()
25
+ custom_entries_view .new = function (ghost_text_view )
25
26
local self = setmetatable ({}, { __index = custom_entries_view })
26
27
27
28
self .entries_win = window .new ()
@@ -43,6 +44,7 @@ custom_entries_view.new = function()
43
44
self .active = false
44
45
self .entries = {}
45
46
self .bottom_up = false
47
+ self .ghost_text_view = ghost_text_view
46
48
47
49
autocmd .subscribe (
48
50
' CompleteChanged' ,
@@ -431,6 +433,55 @@ custom_entries_view._select = function(self, cursor, option)
431
433
0 ,
432
434
})
433
435
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
+
434
485
if is_insert then
435
486
self :_insert (self .entries [cursor ] and self .entries [cursor ]:get_vim_item (self .offset ).word or self .prefix )
436
487
end
0 commit comments