Files
nocal/README.md
Bernardo Magri 88d370bf99 feat: add calendar visibility picker
Derive session calendars from event metadata and apply one visibility contract to month rendering, appointment focus, and search without filtering persistence writes.

Add keyboard picker coverage, full-model save regression tests, documentation, warning-clean builds, sanitizer verification, and live PTY terminal restoration checks.
2026-07-18 09:01:27 +01:00

69 lines
3.5 KiB
Markdown

# 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](docs/PRODUCT.md),
[architecture](docs/ARCHITECTURE.md), and [roadmap](docs/ROADMAP.md).
## 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 `c` to open the calendar picker; arrows or
`j`/`k` select a calendar and `Enter` toggles its in-session visibility. 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 `/` to search titles,
descriptions, locations, and calendar IDs. Search results use arrows or
`j`/`k`; `Enter` jumps to the exact occurrence and `Esc` returns to the month.
Press `?` for help and `q` to quit.
## Build and run
```sh
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.
Search expands recurring matches within five years on either side of the
currently selected date. This finite window keeps unbounded recurrence rules
responsive while one-time and recurring results share the same chronological
result list. Hidden calendars are excluded consistently from the month grid,
appointment focus, and search. Visibility is session-only presentation state;
saves always retain events from hidden calendars.
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](docs/HYPRLAND.md).