@@ -117,7 +117,8 @@ custom_entries_view.is_direction_top_down = function(self)
117117end
118118
119119custom_entries_view .open = function (self , offset , entries )
120- local completion = config .get ().window .completion
120+ local c = config .get ()
121+ local completion = c .window .completion
121122 self .offset = offset
122123 self .entries = {}
123124 self .column_width = { abbr = 0 , kind = 0 , menu = 0 }
@@ -161,12 +162,25 @@ custom_entries_view.open = function(self, offset, entries)
161162 local border_info = window .get_border_info ({ style = completion })
162163 local border_offset_row = border_info .top + border_info .bottom
163164 local border_offset_col = border_info .left + border_info .right
164- if math.floor (vim .o .lines * 0.5 ) <= row + border_offset_row and vim .o .lines - row - border_offset_row <= math.min (DEFAULT_HEIGHT , height ) then
165+
166+ local prefers_above = c .view .entries .vertical_positioning == ' above'
167+ local prefers_auto = c .view .entries .vertical_positioning == ' auto'
168+ local cant_fit_at_bottom = vim .o .lines - row - border_offset_row <= math.min (DEFAULT_HEIGHT , height )
169+ local cant_fit_at_top = row - border_offset_row <= math.min (DEFAULT_HEIGHT , height )
170+ local is_in_top_half = math.floor (vim .o .lines * 0.5 ) > row + border_offset_row
171+ local should_position_above =
172+ cant_fit_at_bottom or
173+ (prefers_above and not cant_fit_at_top ) or
174+ (prefers_auto and is_in_top_half )
175+ if should_position_above then
176+ self .bottom_up = true
165177 height = math.min (height , row - 1 )
166178 row = row - height - border_offset_row - 1
167179 if row < 0 then
168180 height = height + row
169181 end
182+ else
183+ self .bottom_up = false
170184 end
171185 if math.floor (vim .o .columns * 0.5 ) <= col + border_offset_col and vim .o .columns - col - border_offset_col <= width then
172186 width = math.min (width , vim .o .columns - 1 )
@@ -176,12 +190,6 @@ custom_entries_view.open = function(self, offset, entries)
176190 end
177191 end
178192
179- if pos [1 ] > row then
180- self .bottom_up = true
181- else
182- self .bottom_up = false
183- end
184-
185193 if not self :is_direction_top_down () then
186194 local n = # self .entries
187195 for i = 1 , math.floor (n / 2 ) do
@@ -208,9 +216,9 @@ custom_entries_view.open = function(self, offset, entries)
208216 })
209217 -- always set cursor when starting. It will be adjusted on the call to _select
210218 vim .api .nvim_win_set_cursor (self .entries_win .win , { 1 , 0 })
211- if preselect_index > 0 and config . get () .preselect == types .cmp .PreselectMode .Item then
219+ if preselect_index > 0 and c .preselect == types .cmp .PreselectMode .Item then
212220 self :_select (preselect_index , { behavior = types .cmp .SelectBehavior .Select , active = false })
213- elseif not string.match (config . get () .completion .completeopt , ' noselect' ) then
221+ elseif not string.match (c .completion .completeopt , ' noselect' ) then
214222 if self :is_direction_top_down () then
215223 self :_select (1 , { behavior = types .cmp .SelectBehavior .Select , active = false })
216224 else
0 commit comments