khalel
: Interacting through Emacs with locally-stored calendars via the
console application khal
and syncing with remote CalDAV calendars using
vdirsyncer
.
khalel
allows to access calendars stored in .ics
files and provides means of
listing existing events, edit them as well as to create new ones largely through
an org-mode interface.
Please note: This code is in an early state. khalel
shares limitations of
khal
especially when it comes to calendar entry fields that are not handled at
the moment by either khalel
, khal
or org-mode’s .ics
exporter. Simple
scheduling of events works fine but do not expect features found in more complex
PIM applications such as invitees or even time zone support.
On the other hand, it is all text files, so hack away! :)
khal
is a simple and fast way to read, create and edit calendar entries. It
does, however, have a limited feature set. If you need to deal with many shared
calendar invites and want to edit events with complicated repeat patterns, this
might not be the right tool. If you have a “simple” CalDAV calendar for your own
needs or just want to see upcoming calendar events pop up in the org-mode
agenda in Emacs, then read ahead. Also check out khal
’s features and
limitations in its online documentation and the additional list of limitations
below.
Adjusting the output of khal
slightly, one can quite easily get something that already resembles an
org-mode file (link to the online documentation: khal usuage):
khal list --format "* {title} \n <{start-date} {start-time}-{end-time}> \n {location} \n {description}" --day-format "" today 10d
This is showing the events in the coming 10 days from now. This gives us
something to work with and means we don’t have to touch the .ics
files
directly. khalel
takes this a step further and imports a configurable range of
events into a nicely-formated org-mode file.
Furthermore, khalel
provides a wrapper around khal
and org-mode
export
functionality to create new events via org-mode capture templates. Even editing
existing events is possible through a console-interface to khal
.
I sync my remote CalDAV calendars using vdirsyncer which mirrors all events from
my locally. This calendar store can be accessed through khal
and khalel
. I
am mostly interested in seeing upcoming events in the org-mode agenda and to
quickly create new events with the familiar org-capture mechanism.
This requires a small chain of steps: most notably, in my setup, events created
through khalel
require an additional import step to be visible in org-mode.
+-------+ +----------+ +-------+ +-------+ +---------+
| |--->| |--->| |--->| |--->| |
| remote| |vdirsyncer| | khal | |khalel | | org mode|
| |<===| |<===| |===>| |===>| |
+-------+ +----------+ +-------+ +-------+ +---------+
^
:
:
+----------+ +--------+
| | | | --> existing events
| org mode |===>| khalel |
| | | | ==> new events
+----------+ +--------+
Of course, the synchronization and update of the imported org-file can be done in one go! In fact, within the org-file, clickable links allow to either edit a given event or sync & update all – of course, without ever leaving Emacs!
Advantages with the approach:
- integrates neatly into my personal, Emacs-centric work-flow relying heavily on org-mode
- easy to customize with some elisp
- local calendar stores can easily be backed up (or even edited)
- synchronization can be done manually (when online) or automatized via cron job or from within Emacs
Disadvantages:
- several steps requiring different tools
- more initial set-up work
- currently, many features of =.ics=/CalDAV are not supported:
- no timezones
- no organizers/invitees
- …
- code in early state, use at own risk!
Besides calendars, this setup can be extended to contacts using:
- vdirsyncer (again) to mirror contacts from CardDAV server locally,
- khard to access them via the command line, and
- khardel for integration into Emacs (not by me).
Follow the installation instructions at https://github.com/pimutils/vdirsyncer.
The configuration is explained in detail in the online manual including a tutorial and minimal example.
When done with the configuration, run vdirsyncer discover
to test the setup
and then vdirsyncer sync
to run the synchronization for the first time.
Simply download the package for your preferred distribution or follow the installation instructions.
You can create a configuration interactively by running khal configure
or
simply use the one below and save it to ~/.config/khal/config
:
[calendars]
[[my_calendar_local]]
path = ~/.calendar/*
type = discover
[locale]
timeformat = %H:%M
dateformat = %Y-%m-%d
longdateformat = %Y-%m-%d %a
datetimeformat = %Y-%m-%d %H:%M
longdatetimeformat = %Y-%m-%d %H:%M
Make sure that the longdateformat
includes the day of the week in short form
(%a
) as this makes sure that org-mode recognizes the time stamps correctly
when importing. You can test the settings by running
khal printformats
The weekday’s short form will appear in your configured local language.
You might want to set up a default calendar as well or do that in the khalel
configuration step below.
The source code can be found at https://gitlab.com/hperrey/khalel
First, make sure that the right khal
and vdirsyncer
executables will be used, e.g.
(setq khalel-khal-command "~/.local/bin/khal")
(setq khalel-vdirsyncer-command "vdirsyncer")
You might want to customize the values for default calendar, capture template key and import file for khalel:
(setq khalel-default-calendar "privat")
(setq khalel-capture-key "e")
(setq khalel-import-org-file (concat org-directory "calendar.org"))
calendar.org
is also in my list of agenda files. There the new events will end up in after the next sync.
Warning: calendar.org
is being overwritten on each import to avoid collecting duplicates inside the file! The default is therefore to set the file up in read-only mode. The confirmation prompt for overwriting the file can be disabled via:
(setq khalel-import-org-file-confirm-overwrite nil)
And I never plan too long into the future, so the next 30 days will be more than enough to fill my agenda view:
(setq khalel-import-time-delta "30d")
Using these settings, we can now set up a capture template using a helper routine:
(khalel-add-capture-template)
Put this into your Emacs configuration file. The above command will also register an export hook that is run when the capture is finalized to trigger the export to khal
.
You can import upcoming events through khalel-import-upcoming-events
or create
new ones through org-capture
and pressing e
(default key) for a new calendar
event.
You might want to consider adding the org file with the imported events
(calendar.org
in the above example) to your org agenda.
If you visit the org file with the imported events, you will notice links below
each event: using these (or by calling khalel-edit-calendar-event
) you can
edit existing events through khal
from within Emacs.
To synchronize new, edited or remote events use either the links in the imported
calendar org file or call khalel-run-vdirsyncer
.