2.8 KiB
Nocal
Nocal is a fast, local-first C++20 month calendar designed for the Linux terminal and Hyprland. It presents appointments inside a six-week month grid and inherits its colors from your terminal theme.
This repository currently contains the first local-calendar vertical slice: date/domain logic, guarded atomic iCalendar persistence, add/edit/delete forms, a responsive ANSI terminal UI, tests, and Linux launch integration. See the product specification, architecture, and roadmap.
Controls
Use arrow keys or h j k l to move, PageUp/PageDown or p/n to change
month, and t for today. On a day with appointments, Tab and Shift-Tab
move focus through them and Enter opens the appointment reader. In the
reader, arrows/Vim keys or Tab variants browse the day's appointments and
Esc returns to the month. Press a to add an appointment. Focus an
appointment and press e to edit it or d to delete it. Forms use Tab and
Shift-Tab (or arrows) between fields, Space for the all-day toggle,
Ctrl-S to save, and Esc to cancel. Back in the calendar, u undoes the
last successful mutation and Ctrl-R redoes it. Press ? for help and q to
quit.
Build and run
nix-shell --run 'meson setup build && meson compile -C build'
./build/nocal --demo
Run the tests with meson test -C build --print-errorlogs. Nocal reads
$XDG_DATA_HOME/nocal/calendar.ics by default (falling back to
~/.local/share/nocal/calendar.ics), or accepts another .ics path as its
positional argument. --demo adds a few unsaved sample appointments and
--print emits a non-interactive frame.
Nocal expands and safely round-trips a focused iCalendar recurrence subset:
daily, weekly, monthly, and yearly rules with interval, count or until, common
weekly/monthly/yearly selectors, EXDATE, floating times, UTC, and system IANA
TZID names. Recurring instances are individually navigable; edit and delete
clearly operate on the entire series.
Calendars containing features this version cannot preserve—such as RDATE,
detached recurrence overrides, ordinal BYDAY, embedded VTIMEZONE
definitions, alarms, or attendees—remain browsable but read-only. This guard
prevents a local edit from silently discarding unknown data.
Every replacement checks that the source has not changed since it was loaded.
If another Nocal instance or an external editor changes the file, the mutation
is rejected and the in-memory change is rolled back. Successful replacements
retain the immediately previous bytes as calendar.ics.bak. Run
nocal --restore-backup [CALENDAR.ics] for an explicit, atomic recovery; the
backup itself is kept so recovery can be repeated.
For a popup calendar binding and version-specific Hyprland rules, see Hyprland integration.