# Usage and Configuration ## Quick Start ```sh # Build nix-shell --run 'meson setup build && meson compile -C build' # Run with demo appointments ./build/nocal --demo # Run with your calendar file ./build/nocal ~/.local/share/nocal/calendar.ics ``` Nocal reads `$XDG_DATA_HOME/nocal/calendar.ics` by default (falls back to `~/.local/share/nocal/calendar.ics`). Pass a different `.ics` path as the positional argument. ## Keyboard Controls ### Month View | Key | Action | |---|---| | `Arrow keys` / `h j k l` | Navigate between days | | `PageUp` / `PageDown` / `p` / `n` | Change month | | `t` | Jump to today | | `Enter` (on day with events) | Open appointment reader | | `Tab` / `Shift-Tab` | Move focus through appointments on a day | | `a` | Add appointment | | `e` (on focused event) | Edit appointment | | `d` (on focused event) | Delete appointment | | `g` | Open 42-day agenda | | `c` | Calendar picker (toggle calendar visibility) | | `/` | Search events | | `L` | Linear view (screen-reader friendly) | | `u` | Undo last mutation | | `Ctrl-R` | Redo | | `?` | Help | | `q` | Quit | ### Agenda View | Key | Action | |---|---| | `j` / `k` / `Arrow keys` | Navigate occurrences | | `Tab` / `Shift-Tab` | Move between day and event | | `Enter` | Return to month at selected occurrence | | `PageUp` / `PageDown` / `p` / `n` | Shift agenda by 42 days | | `g` / `Esc` | Return to month without changing selection | | `c` | Calendar picker | | `/` | Search | ### Appointment Reader | Key | Action | |---|---| | `Arrow keys` / `h j k l` / `Tab` | Browse day's appointments | | `Esc` | Return to month view | ### Editor Forms | Key | Action | |---|---| | `Tab` / `Shift-Tab` / `Arrows` | Move between fields | | `Space` | Toggle all-day / cycle recurrence frequency | | `Ctrl-S` | Save | | `Esc` | Cancel | ## Calendar File Format Nocal uses standard iCalendar (RFC 5545) files. Create your calendar: ```sh mkdir -p ~/.local/share/nocal touch ~/.local/share/nocal/calendar.ics ``` ### Importing Events ```sh # Merge source into target nocal --import source.ics --calendar target.ics # Export validated calendar nocal --export destination.ics --calendar source.ics ``` ### Supported Recurrence Nocal handles: daily, weekly, monthly, and yearly rules with interval, count or until, common BYDAY/BYMONTH selectors, floating times, UTC, and system IANA TZID names. Events with unsupported features remain browsable but read-only. ### Backup and Recovery Every successful replacement keeps `calendar.ics.bak`. To restore: ```sh nocal --restore-backup ~/.local/share/nocal/calendar.ics ``` ## Remote Synchronization Nocal supports remote providers through the SQLite sync cache, separate from the interactive `.ics` file. Credentials are stored in the system Secret Service (gnome-keyring, kde-wallet, or secret-service). ### Office 365 (Microsoft 365) Nocal uses the OAuth 2.0 authorization code flow with PKCE. **Prerequisites:** - A Microsoft Entra (Azure AD) application registration - Mobile & desktop application type - Redirect URI: `http://localhost/nocal/oauth/callback` - Delegated permissions: `User.Read`, `Calendars.Read` **Setup:** ```sh # Set your client ID (required — placeholder is not functional) export NOCAL_MICROSOFT_CLIENT_ID="your-client-id-here" # Connect account (opens browser for OAuth consent) nocal account connect microsoft # Sync nocal sync ``` The client ID is required because Nocal cannot embed one — each Microsoft application registration is tenant-scoped. Register at https://portal.azure.com → Azure Active Directory → App registrations. **What happens during connect:** 1. Nocal opens your browser for Microsoft OAuth consent 2. A loopback server receives the authorization code 3. Nocal exchanges the code for tokens with PKCE verification 4. Tokens are stored in Secret Service 5. Account identity is fetched from `/me` 6. The account is upserted in the sync cache **Token storage:** Tokens live only in Secret Service, never in SQLite, logs, or environment variables. If your keyring is locked, sync will fail until unlocked. ### CalDAV (Nextcloud, Radicale, iCloud, etc.) Nocal supports CalDAV servers via basic authentication. **Prerequisites:** - A CalDAV server (Nextcloud, Radicale, etc.) - Username and password **Setup:** ```sh # Connect CalDAV account nocal account connect caldav \ --server https://cloud.example.com/remote.php/dav \ --user your_username \ --pass your_password # Sync nocal sync ``` **What happens during connect:** 1. Nocal sends PROPFIND to discover your principal URL 2. Nocal discovers the calendar-home-set 3. Nocal lists all calendars under your home-set 4. Calendars are upserted in the sync cache **What happens during sync:** 1. Nocal uses CalDAV sync-collection for delta sync 2. Only changed events are fetched 3. Events are parsed from iCalendar and stored in the sync cache 4. Sync tokens are persisted for incremental updates **Server compatibility:** - **Nextcloud**: Full support. Use `https://cloud.example.com/remote.php/dav` as the server URL. - **Radicale**: Full support. - **iCloud**: Requires a CalDAV-compatible client (e.g., via Apple's CalDAV endpoint or a bridge). - **SOGo**: Supported. - **SABREDAV-based servers**: Generally supported. ### Google Calendar Google Calendar support is planned. Google does not offer CalDAV for writes, so Nocal will use the Google Calendar API directly. **Expected workflow:** 1. OAuth 2.0 flow with PKCE (same as Microsoft) 2. `calendar.events.list` with sync token for delta sync 3. Local caching in the sync database ## Configuration ### Environment Variables | Variable | Purpose | |---|---| | `NO_COLOR` | Disable ANSI colors (keeps text readable) | | `XDG_DATA_HOME` | Base directory for calendar files (default: `~/.local/share`) | | `NOCAL_MICROSOFT_CLIENT_ID` | OAuth client ID for Microsoft connect | ### Week Start Day ```sh nocal --week-start monday # default nocal --week-start sunday # Any day: monday, tuesday, wednesday, thursday, friday, saturday, sunday ``` This is display-only and does not affect stored events or recurrence. ### Print Mode ```sh nocal --print # Non-interactive frame output ``` ## Hyprland Integration For popup calendar binding, see [Hyprland integration](HYPRLAND.md). ```sh nocal --print | some-renderer ``` The `nocal-hyprland` script provides a ready-made binding. ## File Locations | Path | Purpose | |---|---| | `~/.local/share/nocal/calendar.ics` | Default local calendar | | `~/.local/share/nocal/calendar.ics.bak` | Backup of previous version | | `~/.local/share/nocal/nocal.db` | Sync cache (SQLite) | | Secret Service | OAuth tokens and credentials | ## Troubleshooting ### Sync fails with "authentication failed" Ensure your keyring is unlocked. Check with: ```sh secret-tool lookup nocal account ``` If the token is missing, reconnect: ```sh nocal account connect microsoft # or caldav nocal sync ``` ### Calendar appears read-only Your calendar file may contain unsupported features (RDATE periods, ordinal BYDAY, embedded VTIMEZONE, alarms, etc.). These are browsable but not editable to prevent data loss. Use `--export` to create a clean copy. ### Import rejected Import validates before writing. Check: - No empty UIDs - No duplicate UIDs - No invalid recurrence intervals - UID collisions with different events are rejected ### Events not showing after sync Check which calendars are visible with `c` (calendar picker). Synced calendars may be hidden by default. Toggle visibility with `Enter` in the picker. ## Development ```sh # Build nix-shell --run 'meson setup build && meson compile -C build' # Run all tests nix-shell --run 'meson test -C build --print-errorlogs' # Run specific test nix-shell --run 'meson test -C build nocal:caldav-xml' ``` See [architecture](ARCHITECTURE.md) for design decisions and [roadmap](ROADMAP.md) for planned features.