aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/cache.lua
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-17 12:27:28 +0200
committerDanilo M. <danix@danix.xyz>2026-09-17 12:27:28 +0200
commit5013893b4cbb63277b2a4c92a0dc8b851816aa93 (patch)
treea0cd680dccee25b41e9f3b6a51c5ba284b7d7669 /widgets/cache.lua
parentd9c68ef7a62b45527cfb87d61e51866c5e2931a3 (diff)
downloadconky-theme-udt-5013893b4cbb63277b2a4c92a0dc8b851816aa93.tar.gz
conky-theme-udt-5013893b4cbb63277b2a4c92a0dc8b851816aa93.zip
feat: add the disks and cache cards
disks draws a ring per filesystem from the df sample, with the NFS server address read from the device field and a labelled-bar fallback when the rings would be too small to read. cache shows the ~/.cache total and its four largest children from the du sample. card.ring now resets the cairo path first: a preceding card.text() leaves a current point, and cairo_arc() joins to it with a straight line, so the disks rings were drawn with stray chords. The ring primitive had no caller until now, which is why it went unnoticed.
Diffstat (limited to 'widgets/cache.lua')
-rw-r--r--widgets/cache.lua63
1 files changed, 63 insertions, 0 deletions
diff --git a/widgets/cache.lua b/widgets/cache.lua
new file mode 100644
index 0000000..a1a42e3
--- /dev/null
+++ b/widgets/cache.lua
@@ -0,0 +1,63 @@
+-- Cache: ~/.cache total and its four largest subdirectories.
+--
+-- Reads a cache file written by bin/cache-sample.sh. du walks the tree and
+-- costs about 100ms, which cannot happen on a 2-second draw.
+
+local card = require 'lib.card'
+local data = require 'lib.data'
+
+local CACHE = (os.getenv('XDG_CACHE_HOME') or (os.getenv('HOME') .. '/.cache'))
+ .. '/udt/cachesize.txt'
+
+local M = {}
+
+function M.draw(cr, rect, colors)
+ local inner = card.card(cr, rect, colors)
+ local function clamp(v, lo, hi) return math.max(lo, math.min(hi, v)) end
+ local label_size = clamp(inner.w * 0.030, 10, 16)
+ local big_size = clamp(inner.w * 0.075, 22, 46)
+
+ card.font(cr, card.FONT_MONO, label_size, false)
+ card.rgba(cr, colors.label)
+ card.text(cr, inner.x, inner.y + label_size, 'CACHE')
+
+ local c = data.du_parse(data.slurp(CACHE) or '')
+ if not c then
+ card.rgba(cr, colors.label)
+ card.font(cr, card.FONT_UI, label_size * 1.2, true)
+ card.text(cr, inner.x, inner.y + label_size * 3.4, 'no cache data')
+ card.font(cr, card.FONT_MONO, label_size, false)
+ card.text(cr, inner.x, inner.y + label_size * 5, 'bin/cache-sample.sh')
+ return
+ end
+
+ card.font(cr, card.FONT_HEAVY, big_size, false)
+ card.rgba(cr, colors.body)
+ card.text(cr, inner.x, inner.y + label_size + big_size, c.total.label)
+
+ local ey = inner.y + label_size + big_size + label_size * 2
+ local step = label_size * 2.2
+
+ card.font(cr, card.FONT_MONO, label_size, false)
+ for i, e in ipairs(c.items) do
+ if ey + step > inner.y + inner.h then break end
+ -- The biggest offender is the point of the card, so it carries colour:
+ -- critical when it is over half the total, warning otherwise. The rest
+ -- stay in the ordinary value colour so the eye lands on the one to delete.
+ local colour = colors.value
+ if i == 1 then
+ local share = c.total.bytes > 0 and (e.bytes / c.total.bytes) or 0
+ colour = share > 0.5 and colors.critical or colors.warning
+ end
+ card.rgba(cr, colors.label)
+ -- Long names are truncated rather than allowed to collide with the size.
+ local name = e.name
+ if #name > 18 then name = name:sub(1, 17) .. '\u{2026}' end
+ card.text(cr, inner.x, ey, name)
+ card.rgba(cr, colour)
+ card.text_right(cr, inner.x + inner.w, ey, e.label)
+ ey = ey + step
+ end
+end
+
+return M