Emacs is a fantastic editor/ide/etc. To call it simply an editor is a disservice for this tool. For those that are unaware, Emacs was developed starting in the 1970s [1], and is still developed today. Emacs is one of the two legacy editors that has been the source for debates [2] for many, many years.

While I won’t go into the debate, I can explain some of why Emacs is so powerful:

  1. ELisp - The language that can drive much of the functionality within Emacs, and can be extended upon [3].
  2. Org-Mode - A “personal wiki”, and GTD system for Emacs [4].
  3. IDE-like Support - Many languages have plugins/extensions available within Emacs, some including full debugging support.

One of the nicest parts about Emacs is the first item - you can write your own code to extend Emacs to fit your needs.

Problem Statement

To best illustrate how you can write extensions, it’s good to explain the problem I was recently attempting to solve, and why.

I’m a big GTD freak, and I host my own systems for keeping track of my tasks. I’ve used org-mode for years as a wiki system, but off and on as a GTD tool. Part of this is due to the desire to get a specific numeric id for future references. For that, I moved over to Open Project. Over time, I found Open Project to be much more heavy weight than I was desiring. While I could access it on any system, it felt a chore to add quick tasks. So, I started moving back to Emacs org-mode. My reasoning for this was to keep my GTD items close to the rest of my notes (which I take in Emacs org-mode), even if the numeric id wasn’t easily achieved.

As I was entering items into Org-Mode, I started realizing that there was some structure that I desired for each item. For example, a section for Jira references, my written journal, and a link to more verbose notes, and so on. A large part of this started with the question: “Where do I store my notes for a task?”, because inside the main org file is not feasible for anything more than a few lines.

Automating some of this is what I wanted to solve.

Enter ELisp

ELisp, as mentioned above, is a language that much of functionality within Emacs is built off of. It stands for “Emacs Lisp”, and is similar to one of my favorite programming languages, Common Lisp.

While it’s been years since I’ve done ELisp last, it didn’t take me long to write something up:

(defun add-ufg-todo ()
  (setq title (read-string "Enter a TODO Title: "))
  (setq curtime (shell-command-to-string "echo -n $(date +%Y-%m-%d)"))
  (setq filename (format "notes/" curtime (replace-regexp-in-string " " "" title)))
  (setq org-todo (format "** TODO %s\n- Date Added: %s\n- Jira References\n- Journal References\n- [[file:%s][Detailed Notes]]\n" title curtime filename))
  (insert org-todo)

So what does all this do:

  • line 1: Defines a function, called add-ufg-todo
  • line 2: Allows this to be invoked using M-x add-ufg-todo
  • line 3: Prompts the user for a title, saves it to the variable title
  • line 4: Gets the current time from shell in format: YYYY-MM-DD, e.g. 2021-11-28
  • line 5: Sets the filename for the detailed notes, which are stored in a sub-folder called notes with the date and title used. The replace-regexp-in-string simply replaces the spaces with nothing for the title.
  • line 6: Sets the TODO block text. I wanted to keep track of the date I added it, a block for Jira references, my journal (written) pages, and a link to the detailed notes.
  • line 7: Goes to the end of my file (in this case, I’d be in my file).
  • line 8: Inserts the text from the variable org-todo at that point (adding a new block)

Overall, fairly easy to read code that performs a specific purpose and would shorten typing for me.

Loading the ELisp

All configuration in Emacs is held in ~/.emacs, with supporting files, by default, stored in ~/.emacs.d. So to load this new functionality (and any I add to this file), I can simply add the following to the ~/.emacs file:

(add-to-list 'load-path "~/.emacs.d/extensions")
(require 'add-ufg-todo "org-gtd.el")

Other Potential Extensions

The above is a very simple example of how I’m using ELisp, but there’s a lot of other options available:

  1. Add this in relation to capture templates [5].
  2. Modify the clock in/out to automatically start/stop a timer in Kimai (my time tracking system).
  3. Push tags from the parent (after added) to the detailed notes file.

There are many other options, too including interactions with Jira (pull down my tasks into my org file), and push detailed notes into a Jira ticket (if needed).


ELisp is quite powerful. It’s not the end-all-be-all, but this combined with normal shell scripts (and invoking from Emacs), makes this a very powerful tool for integration. I generally prefer to limit my tool choices, and standardize to a handful of tools. Much of this is the learning of multiple tools is tiresome, and inefficient. Learning how to extend a tool to meet needs, such as my workplace’s tool-set, is helpful for my efficiency.


David Thole

David Thole
Senior Software Architect, Developer, Instructor. Reads/studies a lot and enjoys all things technology

Local Artificial Intelligence Tools

# IntroductionI was in a recent meeting when the presenter of the meeting spoke about running LLMs in the cloud, and how expensive it can...… Continue reading

Effective prompting with AI

Published on January 09, 2024

Creating Flashcards with Generative AI

Published on January 02, 2024