Miscellaneous ephemera…

Syncing with khal

Following up on my post from last week, about using khal and mutt, where I covered off a couple of simple hacks to integrate command line calendaring with Mutt, I had been using the main development branch of khal which includes syncing capability. However, as I was conversing with the developer, Christian, around a bug report, he indicated that this functionality would be superseded by development in a separate branch that uses vdirsyncer to synchronise calendars.

As Christian intimated that this change would happen in the very near future, and “js” had commented on my last post to the effect that it was working well, I thought I should take a look for myself.

There are packages in the AUR for vdirsyncer-git and python2-argvard so you will just need to grab the khal branch that uses vdirsyncer as it’s syncing engine. I have thrown up a PKGBUILD gist, or—as we are only talking about a couple of simple scripts—you could install the complete set using pip, the Python package manager; in which case it would be a straightforward:

sudo pacman -S python2-pip
pip2 install --user git+https://github.com/geier/khal.git@vdir
pip2 install --user vdirsyncer

…and then remember to make sure that $HOME/.local/bin is included in your $PATH.

I wanted to have vdirsyncer manage two of my calendars, my CalDav work calendar and a simple iCalendar with all of the New Zealand public holidays. Configuring vdirsyncer to successfully do this took me a lot longer than I would like to admit: a combination of my ineptitude, a bug and a broken schema in the original holidays.ics that I wanted to use.

The collections variable in the config file merits a mention in this regard. If you choose to use it, be aware that your URL will have this value appended to it, which may throw a 404. Using the DEBUG verbosity level will identify this issue if you are struck by it.

Eventually, with the help of both Christian and Markus, the vdirsyncer developer, I got it set up and running smoothly. I then just had to create a cron job to sync my work calendar every two hours and it was done.

As you would expect with such a simple tool, there is not a lot to say, or do, with vdirsycner. It runs on a similar model to OfflineIMAP, in that it synchronises a remote and local repository. There are a couple of nice touches: it will read your credentials from $HOME/.netrc so you don’t have to worry about sensitive information in plain text in yet another file, and there is a VDIRSYNCER_CONFIG variable, so you can place the config file wherever it suits.


Elevator, a Creative Commons image on Flickr by Mykl Roventine.

Mutt and iCal

I have posted a few times now about how I use Mutt1, that most superlative of email clients. Using a variety of different tools, I have settled on an effective and satisfying workflow for managing both my personal and professional email, with one glaring exception: calendaring. This, I should stress, is not for want of trying. It is not necessarily a nagging concern in terms of my personal use of email, but professionally it is a daily frustration.

Day after day, I receive a lot of meeting invitations and, when these show up in my inbox they are, for all intents and purposes, unintelligble. Yes, with careful scrutiny you can decypher the iCalendar files, but doing so is more likely to induce a seizure than a punctual appearance at an important meeting. To get around this, I had been using a basic Awk script that would parse the most important parts of the message and print them out. This was working well enough until I started to receive invitations from people using OSX. For some god-unknown reason, Apple’s “interpretation” of the standard2 is different enough to those sent from Evolution and Thunderbird that my script wouldn’t successfully print some of the data (just the start and end times of the meeting, nothing too important).

I started to try and expand the capability of the script and then realized that I would be much better off seeing if someone else had solved this problem; satisfactorily, that is. And they had. In a further delightful coincidence, the original author of the script, Martyn Smith is an ex-colleague who, in 2004, first got me interested in Linux (thank you, Martyn). Armed with this script and entries in $HOME/.mutt/{mailcap,muttrc} now, whenever I open a calendar invitation, the pertinent details are printed out perfectly legibly. It’s a small step, but an important one.

Next I started playing around with khal, a command line calendaring application that uses CalDav to sync to calendar servers. It is described as being in “the early stages of development” and that certainly is the case. Nonetheless, it is incredibly promising as—even in this rudimentary form—it performs well and offers most of the basics that I require. khal is simple to setup, does not have too many (python2) dependencies and handles multiple calendars3. Yes, there are bugs, but nothing grievous and the developer, Christian Geier, is very responsive and helpful4.

The khal documentation gives you a pretty good idea of the current feature set. Set up your khal.conf with the calendars you want synched and then you have two modes of interaction: directly via the command line or an interactive mode invoked with ikhal. Both modes allow you to perform the basic functions of adding, editing or deleting events.

While the interactive mode is very simple and straightforward, what I am most excited about is the ability to add events from the command line, as per the example in the documentation:

khal --new 25.10. 16:00 18:00 Another Event :: with Alice and Bob

I just needed to figure out a way to extract the relevant fields from the iCal file and pass them to khal. My first attempt is unashamedly ugly, both in conception and execution. However, I don’t know Perl (and at this stage of my life I have run out of time to learn it), and it actually works. I modified Martyn’s script to write to a temp file and then, for iCal events I want to import to khal, I bound a key sequence in Mutt to a simple Awk script5:

#!/usr/bin/awk -f
# read from ical_filter.pl and then send ical invitation details 
# in mutt to khal

/^Summary/   { for (i=1; i<=NF-2; i++) $i = $(i+2); NF-=2; summ = $0 }
/^Location/  { for (i=1; i<=NF-2; i++) $i = $(i+2); NF-=2; meet = $0 }
/^Dtstart/   { date_st = $3; time_st = $4 }
/^Dtend/     { time_nd = $4 }

END          { print  date_st" "time_st" "time_nd" "summ }

In $HOME/.mutt/muttrc, I have Ctrlk in pager view trigger the script like so:

# save iCal to khal
macro pager \Ck  "!/usr/bin/khal --new $(~/Scripts/mutt2khal ~/.mutt/temp/caldata)" "Saving Calendar event"

Neither elegant nor imaginative, I know; but for a first attempt, it gets the job done. If I did know any Perl, I am sure I would be able to avoid the additional temp file and the need to reread the information before handing it off to khal, but you work with the skills (or lack thereof) that you have. Needless to say, patches are welcomed.


  1. See all my mutt posts:
  2. Yes, I understand how special Apple is but this is particularly annoying…
  3. There is a package in AUR.
  4. I logged a bug and it was fixed in a matter of hours.
  5. The script is in my bitbucket repo.

Creative Commons image, Calendar by Angela Mabray.

Autotext Function

Once you have your environment set up; your window manager patched exactly the way you want, same for your editor and even your kernel builds automated, then you either start from scratch and learn a whole lot more, or you start to focus on the really small details. The endless polishing that is bred of a mania for automation and customisation and the liberating freedom of using software that allows, and even encourages, this approach.

Since I started using a couple of basic functions for managing my note taking, I have been conscious of the way I can use this tool to make my workflow a little less onerous.

One of the things I find myself doing a lot is reusing the same snippets of text; either prose in work documents, or links to relevant articles on the Arch Wiki and Forums. It is simple enough to add this material to my ~/.notes, but retrieval has always been—for the text I reuse frequently—unwieldy.

How many times do you really want to open the file, search for the relevant excerpt, highlight it and then copy it to the system clipboard before closing the file and pasting it into your email or a web form? I must have logged several thousand before I finally decided to do something about it.

I now have a couple of different files in ~/.notes/ depending upon the context; the example I’ll use is the one for the Arch Forums kept, naturally enough, at $HOME/Sync/notes/arch (I symlink to ~/.notes so that the directory is synched using BitTorrent Sync).

This is just a simple text file with all of the links, guidance and wisdom that I generously share with those people, mostly new to the community, who have yet to embrace the opportunity to commit the Forum Etiquette to memory. The format of each file is the same and is pretty basic:

# rules sticky

# smart questions
[url=http://www.catb.org/esr/faqs/smart-questions.html]How To Ask Questions The Smart Way[/url]

# arch only

I use the commented title to identify the desired piece of text and then just copy it to the clipboard, ready to pasted into a post that will undoubtedly be gratefully received by the infractor:

# board snippets
bbs() {
  if (( $# == 1 )); then
    local opt="$1"
    awk -v line="$opt" 'index($0, line) { getline; print }' "$file" | xsel -b
    awk '/^# /' "$file"

So, on the rare occasion that I need to remind someone that on the Arch boards we only support Arch Linux (I know, quite the revelation…), I just open a scratchpad and enter bbs only and then Shift+Insert the text into the post and I am done. Not passing an argument just prints the commented titles in the file in the event that I forget what the damn thing is called.

I have a similar setup for work, with a couple of files that feature longer pieces of text that I find myself reusing for proposals, email responses and other administrivia. It’s a simple enough approach, but it works well and does lend a certain satisfaction to the otherwise tedious business of writing boilerplate.


Flickr Creative Commons image how many cans by shrapnel1