From 11728180627a2608070f9abbc23062047f1865a4 Mon Sep 17 00:00:00 2001 From: hermione Date: Sat, 24 Jan 2026 17:18:32 -0800 Subject: [PATCH] feat(emacs): add org-caldav integration for Nextcloud calendar sync - Enable org-caldav package in packages.el - Configure base org-caldav settings (URL, timezone, sync behavior) - Add Personal calendar two-way sync (~/org/personal-calendar.org) - Add Tasks calendar one-way sync from todo.org - Add keybinding SPC o C for manual sync - Document setup requirements in config comments Note: Conflict resolution is 'Org always wins' (org-caldav limitation). User needs to create Nextcloud app password and ~/.authinfo.gpg. Refs: x-5tb, x-5tb.1, x-5tb.2, x-5tb.3 --- home/roles/emacs/doom/config.el | 65 ++++++++++++++++++++++++++----- home/roles/emacs/doom/packages.el | 2 +- 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/home/roles/emacs/doom/config.el b/home/roles/emacs/doom/config.el index 537391f..f1c1ad8 100644 --- a/home/roles/emacs/doom/config.el +++ b/home/roles/emacs/doom/config.el @@ -83,15 +83,62 @@ "d" #'org-agenda-day-view "w" #'org-agenda-week-view)) -;; (use-package! org-caldav -;; :defer t -;; :config -;; (setq org-caldav-url "https://nextcloud.johnogle.info/remote.php/dav/calendars/johno" -;; org-caldav-calendar-id "personal" -;; org-icalendar-timezone "America/Los_Angeles" -;; org-caldav-inbox "~/org/calendar.org" -;; org-caldav-files nil -;; org-caldav-sync-direction 'cal->org)) +;; org-caldav: Sync Org entries with Nextcloud CalDAV +;; Setup requirements: +;; 1. Create Nextcloud app password: Settings -> Security -> Devices & sessions +;; 2. Store in rbw: rbw add nextcloud-caldav (username in notes, app password as secret) +;; 3. Run: doom sync +;; 4. Test: M-x org-caldav-sync +;; +;; Note: Conflict resolution is "Org always wins" - treat Org as source of truth +;; for entries that originated in Org. +(use-package! org-caldav + :after org + :commands (org-caldav-sync) + :init + (map! :leader + :desc "Sync calendar" "o C" #'org-caldav-sync) + :config + ;; Nextcloud CalDAV base URL + (setq org-caldav-url "https://nextcloud.johnogle.info/remote.php/dav/calendars/johno") + + ;; Timezone for iCalendar export + (setq org-icalendar-timezone "America/Los_Angeles") + + ;; Sync state storage (in org directory for multi-machine sync) + (setq org-caldav-save-directory (expand-file-name ".org-caldav/" org-directory)) + + ;; Backup file for entries before modification + (setq org-caldav-backup-file (expand-file-name ".org-caldav/backup.org" org-directory)) + + ;; Sync behavior: bidirectional by default + (setq org-caldav-sync-direction 'twoway) + + ;; What changes from calendar sync back to Org (conservative: title and timestamp only) + (setq org-caldav-sync-changes-to-org 'title-and-timestamp) + + ;; Deletion handling: ask before deleting + (setq org-caldav-delete-calendar-entries 'ask) + (setq org-caldav-delete-org-entries 'ask) + + ;; Enable TODO/VTODO sync + (setq org-icalendar-include-todo 'all) + (setq org-caldav-sync-todo t) + + ;; Calendar-specific configuration + (setq org-caldav-calendars + '(;; Personal calendar: two-way sync with family-shared Nextcloud calendar + (:calendar-id "personal" + :inbox "~/org/personal-calendar.org" + :files ("~/org/personal-calendar.org")) + + ;; Tasks calendar: one-way sync (org → calendar only) + ;; SCHEDULED/DEADLINE items from todo.org push to private Tasks calendar. + ;; No inbox = no download from calendar (effectively one-way). + ;; Note: Create 'tasks' calendar in Nextcloud first, keep it private. + (:calendar-id "tasks" + :files ("~/org/todo.org")))) + ) (defun my/get-rbw-password (alias) "Return the password for ALIAS via rbw, unlocking the vault only if needed." diff --git a/home/roles/emacs/doom/packages.el b/home/roles/emacs/doom/packages.el index b1630c5..bdc1ef0 100644 --- a/home/roles/emacs/doom/packages.el +++ b/home/roles/emacs/doom/packages.el @@ -49,7 +49,7 @@ ;; ...Or *all* packages (NOT RECOMMENDED; will likely break things) ;; (unpin! t) -;; (package! org-caldav) +(package! org-caldav) ;; Note: Packages with custom recipes must be pinned for nix-doom-emacs-unstraightened ;; to build deterministically. Update pins when upgrading packages.