Skip to content

Commit

Permalink
feat: smart positioning of the hover window. Make sure to update Nui …
Browse files Browse the repository at this point in the history
…as well to use this.
  • Loading branch information
folke committed Oct 26, 2022
1 parent 07465b3 commit 5bd6e30
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 6 deletions.
1 change: 1 addition & 0 deletions lua/noice/config/views.lua
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ M.defaults = {
view = "popup",
relative = "cursor",
enter = false,
anchor = "auto",
size = {
width = "auto",
height = "auto",
Expand Down
3 changes: 3 additions & 0 deletions lua/noice/types/nui.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@
---@class NuiBaseOptions: _.NuiBaseOptions
---@field relative "'cursor'"|"'editor'"|"'win'"|NuiRelative

---@alias NuiAnchor "NW"|"NE"|"SW"|"SE"

---@class _.NuiPopupOptions: _.NuiBaseOptions
---@field position { row: number|string, col: number|string}
---@field size { width: number|string, height: number|string, max_width:number, max_height:number}
---@field border? _.NuiBorder
---@field anchor? NuiAnchor|"auto"
---@field focusable boolean
---@field zindex? number

Expand Down
19 changes: 19 additions & 0 deletions lua/noice/util/nui.lua
Original file line number Diff line number Diff line change
Expand Up @@ -216,4 +216,23 @@ function M.get_layout(dim, _opts)
return { size = size, position = position, relative = opts.relative }
end

function M.anchor(width, height)
local anchor = ""
local lines_above = vim.fn.screenrow() - 1
local lines_below = vim.fn.winheight(0) - lines_above

if height < lines_below then
anchor = anchor .. "N"
else
anchor = anchor .. "S"
end

if vim.go.columns - vim.fn.screencol() > width then
anchor = anchor .. "W"
else
anchor = anchor .. "E"
end
return anchor
end

return M
34 changes: 28 additions & 6 deletions lua/noice/view/nui.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,25 @@ function NuiView:update_options()
}, self._opts, self:get_layout())

self._opts = Util.nui.normalize(self._opts)
if self._opts.anchor == "auto" then
if self._opts.type == "popup" and self._opts.size then
local width = self._opts.size.width
local height = self._opts.size.height
if type(width) == "number" and type(height) == "number" then
local col = self._opts.position and self._opts.position.col
local row = self._opts.position and self._opts.position.row
self._opts.anchor = Util.nui.anchor(width, height)
if self._opts.anchor:find("S") and row then
self._opts.position.row = -row + 1
end
if self._opts.anchor:find("E") and col then
self._opts.position.col = -col
end
end
else
self._opts.anchor = "NW"
end
end
end

-- Check if other floating windows are overlapping and move out of the way
Expand Down Expand Up @@ -90,7 +109,7 @@ function NuiView:create()

self._nui:mount()

self._nui:update_layout(self:get_layout())
self:update_layout()
self._scroll = Scrollbar({
winnr = self._nui.winid,
border_size = Util.nui.get_border_size(self._opts.border),
Expand Down Expand Up @@ -122,7 +141,7 @@ function NuiView:reset(old, new)
self._nui = nil
self._visible = false
elseif layout then
self._nui:update_layout(self:get_layout())
self:update_layout()
end
end
end
Expand Down Expand Up @@ -166,7 +185,7 @@ function NuiView:get_layout()
height = height + math.max(1, (math.ceil(l:width() / layout.size.width)))
end
end
return Util.nui.get_layout({ width = self:width(), height = height }, self._opts)
layout = Util.nui.get_layout({ width = self:width(), height = height }, self._opts)
end
end
return layout
Expand Down Expand Up @@ -194,6 +213,10 @@ function NuiView:fix_border()
end
end

function NuiView:update_layout()
self._nui:update_layout(self:get_layout())
end

function NuiView:show()
if self._loading then
return
Expand All @@ -209,13 +232,12 @@ function NuiView:show()

self._nui:show()
self:set_win_options(self._nui.winid)
self:tag()
if not self._visible then
self._nui:update_layout(self:get_layout())
self:update_layout()
self:smart_move()
end

self:tag()

vim.bo[self._nui.bufnr].modifiable = true
self:render(self._nui.bufnr)
vim.bo[self._nui.bufnr].modifiable = false
Expand Down

0 comments on commit 5bd6e30

Please sign in to comment.