4
4
--- @field renderer blink.cmp.Renderer
5
5
--- @field selected_item_idx ? number
6
6
--- @field context blink.cmp.Context ?
7
+ --- @field north boolean
7
8
--- @field open_emitter blink.cmp.EventEmitter< {} >
8
9
--- @field close_emitter blink.cmp.EventEmitter< {} >
9
10
--- @field position_update_emitter blink.cmp.EventEmitter< {} >
@@ -49,6 +50,7 @@ vim.api.nvim_create_autocmd({ 'CursorMovedI', 'WinScrolled', 'WinResized' }, {
49
50
function menu .open_with_items (context , items )
50
51
menu .context = context
51
52
menu .items = items
53
+ menu .north = false
52
54
menu .selected_item_idx = menu .selected_item_idx ~= nil and math.min (menu .selected_item_idx , # items ) or nil
53
55
54
56
if not menu .renderer then menu .renderer = require (' blink.cmp.completion.windows.render' ).new (config .draw ) end
76
78
function menu .close ()
77
79
menu .auto_show = config .auto_show
78
80
if not menu .win :is_open () then return end
79
-
81
+ menu . selected_item_idx = nil
80
82
menu .win :close ()
81
83
menu .close_emitter :emit ()
82
84
end
@@ -97,15 +99,30 @@ function menu.update_position()
97
99
98
100
win :update_size ()
99
101
102
+ local item = menu .items [menu .selected_item_idx ]
103
+ local prefer_north = false
104
+ -- If there are multiline text and user turns on ghost text, we should prefer opening upwards.
105
+ -- Once we go up, we don't go down again even if the text is only one line, to reduce visual interference
106
+ -- when keeps holding down <c-p>/<c-n>.
107
+ if
108
+ require (' blink.cmp.config' ).completion .ghost_text .enabled and menu .north
109
+ or (item ~= nil and item .insertText ~= nil and string.find (item .insertText , ' \n ' ) ~= nil )
110
+ then
111
+ prefer_north = true
112
+ end
113
+
100
114
local border_size = win :get_border_size ()
101
- local pos = win :get_vertical_direction_and_height (config .direction_priority )
115
+ local pos = win :get_vertical_direction_and_height (prefer_north and { ' n ' , ' s ' } or config .direction_priority )
102
116
103
117
-- couldn't find anywhere to place the window
104
118
if not pos then
105
119
win :close ()
106
120
return
107
121
end
108
122
123
+ -- record it, reset to false at next time when item changes
124
+ if prefer_north and pos .direction == ' n' then menu .north = true end
125
+
109
126
local alignment_start_col = menu .renderer :get_alignment_start_col ()
110
127
111
128
-- place the window at the start col of the current text we're fuzzy matching against
0 commit comments