First Elisp Function


org-store-link

During the last year, I started noticing that I had a problem keeping track of tasks that came up during phone calls and emails. I used my inbox as a to-do list, but I had over 100 emails in it and no idea what was urgent, what was done, and what was still to-do. I tried to move down to "Inbox Zero," but had trouble capturing long-term items that needed more time to respond or were scheduled for a future date. I found John Wiegley's excellent guide for how he implemented a GTD strategy with org-mode (link seems to be down.) This was great for handling the tasks, but in my quest to move more of my workflow into Emacs I decided to start reading my mail in Emacs with mu4e. I started by updating my org-capture todo template to:

(setq org-capture-templates '(("t" "todo" entry (file+headline "~/todo.org" "Tasks")
                                        "* TODO [#A] %?
 SCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\")) %a")))

which uses the "%a" format to store a link to the current file. This works great with mu4e since the file link points back to the original email so the full context is available when you start working on the task. I had some issues with it occasionally throwing an error when run in mu4e, however, and found the links often were not useful in other files since I usually use org-capture to enter a quick to-do item when interrupted working on another task. First, I wrote a second template which had a link but still ran into occasional mu4e issues, so I decided to write an elisp function for opening a capture with a link to the current file:

(defun org-capture-link ()
    "Capture with a link"
    (interactive)
    (org-store-link (buffer-file-name))
    (org-capture nil "t")
    (let ((link (plist-get org-store-link-plist ':annotation)))
      (save-excursion
        (newline)
        (insert link))))

This almost exactly does what I used to do by hand. Line by line:

  • interactive: tells Emacs this can be called via M-x
  • org-store-link: pushes a link to the current buffer
  • (org-capture nil "t"): opens the capture template with key "t"
  • org-store-link-plist: variable where org stores the link captured
  • save-excursion: Emacs macro to save the current buffer and point
  • newline, insert: add the link to the file

It's a fairly trivial function, but I was really surprised how easy it was to get up and running with Emacs lisp, and how similar it was to the workflow I used to do by hand.