diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-18 15:29:35 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-18 15:29:35 +0200 |
| commit | 48fa63ff5d0e12edf86db7f01def635aa0aaa9fb (patch) | |
| tree | 28bdd13bf12cf51464b01975ee4e9eef08596f85 | |
| parent | e81d0c6f7e975b1b98f1adf84299ba921093d100 (diff) | |
| download | conky-theme-udt-48fa63ff5d0e12edf86db7f01def635aa0aaa9fb.tar.gz conky-theme-udt-48fa63ff5d0e12edf86db7f01def635aa0aaa9fb.zip | |
fix(calendar): mark events past this week on the month grid
The sampler asked khal for 8 days only, so the grid never coloured an
event later in the month. Sample through the month's end instead, and
cut the event table back to the coming week with calendar_upcoming().
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| -rw-r--r-- | README.md | 3 | ||||
| -rwxr-xr-x | bin/calendar-sample.sh | 10 | ||||
| -rw-r--r-- | lib/data.lua | 15 | ||||
| -rw-r--r-- | test/test_data.lua | 8 | ||||
| -rw-r--r-- | widgets/calendar.lua | 13 |
5 files changed, 42 insertions, 7 deletions
@@ -122,7 +122,8 @@ for, including ones with nothing on this week: it is a colour key, not a second list of what is coming. Events come from a cache file written by `bin/calendar-sample.sh`, which shells -out to `khal`. The card shows as many rows as the cell affords and ends with +out to `khal` for the rest of the month (at least 8 days), so the grid marks +every remaining day with an event while the rows stay the coming week. The card shows as many rows as the cell affords and ends with `+N more` when the week does not fit, since a card that silently drops the rest of the week defeats its own purpose. A cell too short for even one row draws the grid alone, without the legend, rather than a clipped half-row. diff --git a/bin/calendar-sample.sh b/bin/calendar-sample.sh index af583f6..a0fb87e 100755 --- a/bin/calendar-sample.sh +++ b/bin/calendar-sample.sh @@ -45,9 +45,17 @@ trap 'rm -f "$TMP"' EXIT # 8d, not 7d: khal's range is exclusive of the final day in practice for # all-day events, and one extra day costs nothing but avoids a birthday # vanishing from the card on the morning it matters. +# +# The range runs to the end of the month when that is further out, because +# the month grid colours every day with an event, not just this week's. The +# widget cuts the event table back to the 8 days itself. khal's Nd covers day +# offsets 0..N-1, so the month's last day needs last - today + 1. +LAST=$(date -d "$(date +%Y-%m-01) +1 month -1 day" +%-d) +DAYS=$(( LAST - $(date +%-d) + 1 )) +[ "$DAYS" -lt 8 ] && DAYS=8 EVENTS=$(khal list --day-format '' \ --format '{start-date-long}|{start-time}|{end-time}|{calendar}|{title}' \ - --notstarted today 8d 2>/dev/null) + --notstarted today "${DAYS}d" 2>/dev/null) # khal's exit status is 0 even with no calendars configured, so emptiness is # not distinguishable from failure by status alone. The widget treats a missing diff --git a/lib/data.lua b/lib/data.lua index 1b4c64f..818bbf1 100644 --- a/lib/data.lua +++ b/lib/data.lua @@ -131,6 +131,21 @@ function M.calendar_month_days(events, year, month) return out end +-- The events falling within `days` days of `today` ({ y, m, d }), today +-- included. The cache spans the rest of the month so the grid can mark it, +-- while the event table under the grid stays a week's view. +function M.calendar_upcoming(events, today, days) + local out = {} + if type(events) ~= 'table' or type(today) ~= 'table' then return out end + local t0 = os.time({ year = today[1], month = today[2], day = today[3], + hour = 12 }) + for _, e in ipairs(events) do + local t = os.time({ year = e.y, month = e.m, day = e.d, hour = 12 }) + if (t - t0) / 86400 < days then out[#out + 1] = e end + end + return out +end + -- Days in a month, and the weekday its 1st falls on. -- -- os.time/os.date rather than a leap-year rule: the C library already knows, diff --git a/test/test_data.lua b/test/test_data.lua index 9066241..01a55cc 100644 --- a/test/test_data.lua +++ b/test/test_data.lua @@ -109,6 +109,14 @@ assert(days[18] == 'personal', 'first event of the day owns it, got ' assert(days[24] == 'work' and days[26] == 'birthdays', 'later days marked') assert(days[2] == nil, 'October event does not mark September') +-- upcoming: the table's week out of a month-long cache, across a month end. +local up = data.calendar_upcoming({ { y = 2026, m = 10, d = 18 }, + { y = 2026, m = 10, d = 25 }, { y = 2026, m = 10, d = 26 }, + { y = 2026, m = 10, d = 29 } }, { 2026, 10, 18 }, 8) +assert(#up == 2 and up[2].d == 25, 'eight days from the 18th end on the 25th') +assert(#data.calendar_upcoming({ { y = 2026, m = 11, d = 2 } }, + { 2026, 10, 28 }, 8) == 1, 'week crosses into next month') + -- month_shape: September 2026 has 30 days and starts on a Tuesday. -- Monday = 1, so Tuesday = 2. local ndays, first = data.month_shape(2026, 9) diff --git a/widgets/calendar.lua b/widgets/calendar.lua index 11dcb63..5e08a7b 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -209,7 +209,10 @@ function M.draw(cr, rect, colors) local ey = grid_bottom + ev_size * 1.1 - if #cal.events == 0 then + -- The cache spans the month for the grid; the table is the week ahead. + local events = data.calendar_upcoming(cal.events, today, 8) + + if #events == 0 then card.font(cr, card.FONT_UI, ev_size, false) card.rgba(cr, colors.label, 0.8) card.text(cr, inner.x, ey, 'nothing this week') @@ -225,7 +228,7 @@ function M.draw(cr, rect, colors) -- 'all day' is wider than '13:00'. card.font(cr, card.FONT_MONO, ev_size, false) local time_w = 0 - for _, e in ipairs(cal.events) do + for _, e in ipairs(events) do local w = card.advance(cr, when(e)) if w > time_w then time_w = w end end @@ -253,16 +256,16 @@ function M.draw(cr, rect, colors) local probe = ey while probe <= floor_y do room = room + 1; probe = probe + ev_step end - local shown = #cal.events + local shown = #events -- The overflow line costs a row, so it is only worth taking when it reports -- more than the row it displaces. if room < shown then shown = (room >= 2) and (room - 1) or room end - local hidden = #cal.events - shown + local hidden = #events - shown for i = 1, shown do - local e = cal.events[i] + local e = events[i] if ey > floor_y then break end local colour = cal_colour(e.calendar, colors, cal.colors) |
