diff --git a/README.md b/README.md index 820e296..cd2ede1 100644 --- a/README.md +++ b/README.md @@ -138,6 +138,7 @@ return function() entries = { name = 'custom', selection_order = 'top_down', + vertical_positioning = 'below', follow_cursor = false, }, docs = { diff --git a/lua/cmp/config/default.lua b/lua/cmp/config/default.lua index 302cb70..baa1862 100644 --- a/lua/cmp/config/default.lua +++ b/lua/cmp/config/default.lua @@ -98,6 +98,7 @@ return function() entries = { name = 'custom', selection_order = 'top_down', + vertical_positioning = 'below', follow_cursor = false, }, docs = { diff --git a/lua/cmp/types/cmp.lua b/lua/cmp/types/cmp.lua index 3ed713e..748b575 100644 --- a/lua/cmp/types/cmp.lua +++ b/lua/cmp/types/cmp.lua @@ -188,6 +188,7 @@ cmp.ItemField = { ---@class cmp.CustomEntriesViewConfig ---@field name 'custom' ---@field selection_order 'top_down'|'near_cursor' +---@field vertical_positioning 'below'|'above' ---@field follow_cursor boolean ---@class cmp.NativeEntriesViewConfig diff --git a/lua/cmp/view.lua b/lua/cmp/view.lua index 013727b..d7af7fb 100644 --- a/lua/cmp/view.lua +++ b/lua/cmp/view.lua @@ -193,7 +193,8 @@ view.open_docs = function(self) if not self:visible() then return end - self.docs_view:open(e, self:_get_entries_view():info()) + local bottom_up = self.custom_entries_view.bottom_up + self.docs_view:open(e, self:_get_entries_view():info(), bottom_up) end))) end end @@ -297,7 +298,8 @@ view.on_entry_change = async.throttle(function(self) return end if self.is_docs_view_pinned or config.get().view.docs.auto_open then - self.docs_view:open(e, self:_get_entries_view():info()) + local bottom_up = self.custom_entries_view.bottom_up + self.docs_view:open(e, self:_get_entries_view():info(), bottom_up) end end))) else diff --git a/lua/cmp/view/custom_entries_view.lua b/lua/cmp/view/custom_entries_view.lua index 3ee069c..36493ea 100644 --- a/lua/cmp/view/custom_entries_view.lua +++ b/lua/cmp/view/custom_entries_view.lua @@ -17,6 +17,7 @@ local DEFAULT_HEIGHT = 10 -- @see https://github.com/vim/vim/blob/master/src/pop ---@field private active boolean ---@field private entries cmp.Entry[] ---@field private column_width any +---@field private bottom_up boolean ---@field public event cmp.Event local custom_entries_view = {} @@ -134,7 +135,8 @@ custom_entries_view.is_direction_top_down = function(self) end custom_entries_view.open = function(self, offset, entries) - local completion = config.get().window.completion + local c = config.get() + local completion = c.window.completion assert(completion, 'config.get() must resolve window.completion with defaults') self.offset = offset @@ -193,12 +195,21 @@ custom_entries_view.open = function(self, offset, entries) local border_info = window.get_border_info({ style = completion }) local border_offset_row = border_info.top + border_info.bottom local border_offset_col = border_info.left + border_info.right - 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 + + local prefers_above = c.view.entries.vertical_positioning == 'above' + local cant_fit_at_bottom = vim.o.lines - row - border_offset_row <= math.min(DEFAULT_HEIGHT, height) + local cant_fit_at_top = row - border_offset_row <= math.min(DEFAULT_HEIGHT, height) + local should_position_above = cant_fit_at_bottom or (prefers_above and not cant_fit_at_top) + + if should_position_above then + self.bottom_up = true height = math.min(height, row - 1) row = row - height - border_offset_row - 1 if row < 0 then height = height + row end + else + self.bottom_up = false end if math.floor(vim.o.columns * 0.5) <= col + border_offset_col and vim.o.columns - col - border_offset_col <= width then width = math.min(width, vim.o.columns - 1) @@ -208,12 +219,6 @@ custom_entries_view.open = function(self, offset, entries) end end - if pos[1] > row then - self.bottom_up = true - else - self.bottom_up = false - end - if not self:is_direction_top_down() then local n = #self.entries for i = 1, math.floor(n / 2) do @@ -247,9 +252,9 @@ custom_entries_view.open = function(self, offset, entries) -- Always set cursor when starting. It will be adjusted on the call to _select vim.api.nvim_win_set_cursor(self.entries_win.win, { 1, 0 }) - if preselect_index > 0 and config.get().preselect == types.cmp.PreselectMode.Item then + if preselect_index > 0 and c.preselect == types.cmp.PreselectMode.Item then self:_select(preselect_index, { behavior = types.cmp.SelectBehavior.Select, active = false }) - elseif not string.match(config.get().completion.completeopt, 'noselect') then + elseif not string.match(c.completion.completeopt, 'noselect') then if self:is_direction_top_down() then self:_select(1, { behavior = types.cmp.SelectBehavior.Select, active = false }) else @@ -457,7 +462,7 @@ custom_entries_view._select = function(self, cursor, option) 0, }) - if not self.bottom_up then + if not self.bottom_up and config.get().view.entries.vertical_positioning == 'below' then local info = self.entries_win:info() local border_info = info.border_info local border_offset_row = border_info.top + border_info.bottom diff --git a/lua/cmp/view/docs_view.lua b/lua/cmp/view/docs_view.lua index 27fb846..4dbbc41 100644 --- a/lua/cmp/view/docs_view.lua +++ b/lua/cmp/view/docs_view.lua @@ -26,7 +26,7 @@ end ---Open documentation window ---@param e cmp.Entry ---@param view cmp.WindowStyle -docs_view.open = function(self, e, view) +docs_view.open = function(self, e, view, bottom_up) local documentation = config.get().window.documentation if not documentation then return @@ -106,6 +106,8 @@ docs_view.open = function(self, e, view) return self:close() end + local row = bottom_up and math.max(view.row - (height + border_info.vert - view.height), 1) or view.row + -- Render window. self.window:option('winblend', documentation.winblend) self.window:option('winhighlight', documentation.winhighlight) @@ -114,7 +116,7 @@ docs_view.open = function(self, e, view) style = 'minimal', width = width, height = height, - row = view.row, + row = row, col = col + documentation.col_offset, border = documentation.border, zindex = documentation.zindex or 50, diff --git a/merged.md b/merged.md index 2960600..9cefb18 100644 --- a/merged.md +++ b/merged.md @@ -14,7 +14,7 @@ ### Fix -- fix: some symbols can't be mapped correctly #2081 +- fix: some symbols can't be mapped correctly [#2081](https://github.com/hrsh7th/nvim-cmp/pull/2081) - support cpying self-referenced table [#2076](https://github.com/hrsh7th/nvim-cmp/pull/2076) - fix: make work again [#2073](https://github.com/hrsh7th/nvim-cmp/pull/2073) - fix: use \<\* notation for keymap.normalize ([#2069](https://github.com/hrsh7th/nvim-cmp/pull/2069)) @@ -42,6 +42,7 @@ - @ Multiline snippet ghost text with dynamic window position flip [#1955](https://github.com/hrsh7th/nvim-cmp/pull/1955) - @ Allow comparators access to the complete list of entries [#1894](https://github.com/hrsh7th/nvim-cmp/pull/1894) - @ Add option to not reverse select_next_item on bottom_up list ([#1346](https://github.com/hrsh7th/nvim-cmp/pull/1346)) [#1711](https://github.com/hrsh7th/nvim-cmp/pull/1711) +- @ feat: config.view.entries.vertical_positioning = 'above'|'below' [#1701](https://github.com/hrsh7th/nvim-cmp/pull/1701) (integrated with [#1955](https://github.com/hrsh7th/nvim-cmp/pull/1955) from above) - @ feat: add col_offset option for doc view [#1528](https://github.com/hrsh7th/nvim-cmp/pull/1528) - @ feat: enabled for sources [#1314](https://github.com/hrsh7th/nvim-cmp/pull/1314)