CalDAV syncing for Emacs diary files (and thus, Calendar)

#2 Add event fields with completion

~sebasmonia filed ticket on cdsync.el todo

a month ago

#1 cdsync diary files open in dairy-mode

~sebasmonia filed ticket on cdsync.el todo

a month ago
CalDAV Sync for Emacs diary files

With cdsync, you can subscribe to an online calendar and see its
events locally. You can also edit them, or add new ones, and send them
back to the online calendar. Then the changes will be visible on your
phone and other apps connected to the same calendar.

This package converts events in CalDAV online calendars to the format
used by Emacs' diary files. This in in turn makes them visible in the
built in Calendar. Check out
for the official docs on these two features.

Contact info

The project lives in https://sr.ht/~sebasmonia/cdsync.el/
There's a mailing list at ~sebasmonia/cdsync@lists.sr.ht
You can also contact the author directly: code@sebasmonia.com

Notes for version 1.0

1. I have only tested this package with Fastmail. If there are any
   quirks on its implementation of CalDAV, then this package also has
   them. It is a long term goal for the features offered to work with
   all providers.

2. There's a plan to provide an info manual for this package.

3. NEVER edit the UID of an event. If there's no UID, cdsync will
   create one for you.

Auth setup

Create an entry in your authinfo file (or any other authentication
backend supported by Emacs' auth-source) that contains the username
and password/app password for your account. Example:

machine caldav-credentials login me@mydomain.com password s3cr3t

The "machine" value is what we'll need to configure cdsync.

Sample configuration

Assuming you will clone the repo for this package somewhere in your
disk, here is an example use-package based configuration:

(use-package cdsync :load-path "/path/to/repo/cdsync"
  :demand t
  (cdsync-auth-source-host "caldav-credentials") ;; see auth setup
  ("C-c C-o" cdsync-open-diary)

We'll go over the commands later in this README.
There are a few more customization options, check out the "cdsync"
group if you are curious.

The function cdsync-setup-calendar-integration configures values in
the built-ins diary-lib and calendar to integrate cdsync. It is
recommended, but not required. Read the function's docstring for

Initial setup

You need to know the address of your CalDAV server. For Fastmail,
according to the help documents it is
but discovery doesn't work as expected with it. Instead you have to
use the URL
    https://caldav.fastmail.com/dav/calendars/user/{your @fastmail.com username here}
for reasons I am still not clear about.

Use this server URL to call the command cdsync-list-calendars. It
will show in a buffer the calendars on the server, plus the URL of
each one. You can then use this specific calendar URL to call
cdsync-subscribe-calendar providing:

- A local name for the calendar. It must be unique in your config, and
  can differ from the remote one. Example: the calendar that in the
  server is called "work" can be imported as "office-work"
- The calendar's URL, as reported in the listing from cdsync-list-calendars
- Path to a diary file to keep the local copy of the events

This will get ALL the calendar events, and convert them to diary

There's a message at the end of the process so you don't forget to
"#include" the newly created file in your regular diary. After doing
so, the calendar's events will be marked in the Emacs calendar.

Updating from the server

You can get updated/new/deleted events via the commands
cdsync-update-all-calendars or cdsync-update-calendar. If you are
subscribed to a single calendar, both are equivalent.

NOTE: when you pull changes from the server, the relevant diary file
is re-generated from scratch.

Visiting a diary

You can get to a cdsync-managed diary file via the command
cdsync-open-diary, which prompts for a local calendar name (unless you
only have one, then it will Do The Right Thing).

You can also use the buttons in the diary fancy view, if you set the
option diary-goto-entry-function to the function
cdsync-diary-goto-entry (or used the setup function like in the sample

The diary file will open in cdsync-diary-mode, a major mode derived
from the built in diary. This mode TRIES to handhold the user through
making changes, but you still might break the diary file. If that
happens, the easiest way to get back on track is to force-pull from
the remote calendar to regenerate the diary file, by calling
cdsync-update-calendar with a prefix arg (bound to C-c C-u in

You can get a listing of the bindings in a cdsync diary in the mode's
help (C-h m while visiting the file). The basic workflow is:

1. Create a new entry (C-c C-n) or edit the one at point (C-c C-e)
2. The buffer narrows to the relevant area. Make changes to the event.
3a. Press C-c C-c to confirm. This will send the new/updated event to the server.
3b. Press C-c C-k to discard all edits in progress.
4. The buffer widens again.

You can also kick off changes from the calendar, see the next section.

Additional bindings in Calendar

Calling cdsync-setup-calendar-integration will add cdsync versions of
the insert-*****-entry commands to the calendar keymap under the
prefix "c".
Example: the usual "i b" (to insert a block entry) or "i d" (new
entry on date at cursor) become "c b" and "c d" respectively. Again,
you are prompted for which of the subscribed calendars to use.

Supported fields (or, how to write entries)

The way to format the entries must match what the built-in icalendar
package supports. Unless you customized it, see below the expected

When creating a new entry, use the usual diary format:

2019/12/01 19:00 Get ready for next year!!!

Any text after the date/time will become your event's SUMMARY. From
there on, each additional field must be written as " FieldName:

Supported fields are: Location, Organizer, Status, UID (more on this
next), Desc, URL, Class. Check the icalendar documentation for details.
A more complex entry:

2010/12/24 03:00-04:00 Look for people stuck
 Desc: We don't want to keep the guy in the chimney all night, he has things to do!!!
 Location: Chimney
 UID: e07cf9d4-42e4-2ad6-a529-ca046ba32603

VERY IMPORTANT: cdsync uses the (mandatory) UID property to track
events. Do not change it if there's one already. You SHOULD NOT create
one either, cdsync does so for you. In fact, this is how the package
knows you are submitting a new event!