Skip to content

Commit

Permalink
perf: calculate layout in one run and make sure it's idempotent
Browse files Browse the repository at this point in the history
  • Loading branch information
folke committed Jun 14, 2024
1 parent ab3f712 commit 7ab14cd
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 16 deletions.
28 changes: 23 additions & 5 deletions lua/edgy/edgebar.lua
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,26 @@ function M:on_hide(win)
real[1]:show()
end

function M.__tostring(self)
local lines = { "Edgy.Edgebar(" .. self.pos .. ")" }
for _, view in ipairs(self.views) do
for _, l in ipairs(vim.split(tostring(view), "\n")) do
table.insert(lines, " " .. l)
end
end
return table.concat(lines, "\n")
end

---@param wins table<string, number[]>
---@return boolean updated if the edgebar was updated
function M:update(wins)
local before = tostring(self)

self.visible = 0
local updated = false
local current = {} ---@type table<Edgy.View, Edgy.Window[]>
for _, view in ipairs(self.views) do
if view:update(wins[view.ft] or {}) then
updated = true
end
current[view] = view.wins
view:update(wins[view.ft] or {})
self.visible = self.visible + #view.wins
wins[view.ft] = vim.tbl_filter(function(w)
for _, win in ipairs(view.wins) do
Expand All @@ -150,7 +161,14 @@ function M:update(wins)
end, wins[view.ft] or {})
end
self:_update({ check = true })
return updated

-- check if the layout changed
for _, view in ipairs(self.views) do
if not vim.deep_equal(current[view], view.wins) then
return true
end
end
return false
end

---@param opts? {check: boolean}
Expand Down
23 changes: 15 additions & 8 deletions lua/edgy/view.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ local Util = require("edgy.util")

---@class Edgy.View.Opts
---@field ft string
---@field filter? fun(buf:buffer, win:window):boolean?
---@field filter? fun(buf:number, win:number):boolean?
---@field title? string
---@field size? Edgy.Size
-- When a view is pinned, it will always be shown
Expand Down Expand Up @@ -35,15 +35,21 @@ function M.new(opts, edgebar)
return self
end

---@param wins window[]
---@return boolean updated Whether the view was updated
function M:__tostring()
local lines = { "Edgy.View(" .. self.title .. ")" }
for _, win in ipairs(self.wins) do
table.insert(lines, " " .. tostring(win))
end
return table.concat(lines, "\n")
end

---@param wins number[]
function M:update(wins)
---@type table<window, Edgy.Window>
---@type table<number, Edgy.Window>
local index = {}
for _, w in ipairs(self.wins) do
index[w.win] = w
end
local old = self.wins
self.wins = {}
for _, win in ipairs(wins) do
local buf = vim.api.nvim_win_get_buf(win)
Expand All @@ -54,15 +60,16 @@ function M:update(wins)
if #self.wins > 0 then
self.opening = false
end
return not vim.deep_equal(old, self.wins)
end

---@param opts? {check: boolean}
function M:layout(opts)
if #self.wins == 1 and self.wins[1] == self.pinned_win then
local is_pinned = #self.wins == 1 and self.wins[1] == self.pinned_win

if is_pinned then
self.wins = {}
end
if self.edgebar.visible > 0 and self.pinned and #self.wins == 0 then
if self.edgebar.visible > 0 and self.pinned and (#self.wins == 0) then
self:show_pinned(opts)
else
self:hide_pinned(opts)
Expand Down
10 changes: 7 additions & 3 deletions lua/edgy/window.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ local Config = require("edgy.config")
---@class Edgy.Window
---@field visible boolean
---@field view Edgy.View
---@field win window
---@field win number
---@field width? number
---@field height? number
---@field idx integer
local M = {}
M.__index = M

---@type table<window, Edgy.Window>
---@type table<number, Edgy.Window>
M.cache = setmetatable({}, { __mode = "v" })

---@param win window
---@param win number
---@param view Edgy.View
function M.new(win, view)
local self = setmetatable({}, M)
Expand Down Expand Up @@ -59,6 +59,10 @@ function M.new(win, view)
return self
end

function M:__tostring()
return "Edgy.Window(" .. (self:is_pinned() and "pinned:" or "") .. self.win .. ")"
end

---@param dim "width" | "height"
function M:dim(dim)
return vim.w[self.win]["edgy_" .. dim] or self.view.size[dim]
Expand Down

0 comments on commit 7ab14cd

Please sign in to comment.