Emacs org-mode for Developers

Feb. 8, 2020

Emacs org-mode for Developers

tldr; I have created a Github Gist that captures the setup and configuration, key-binds, formatting, and GTD chart if you just want a reference.

Table of contents

Setup and configuration

The thing about Emacs is that it's not a one size fits all editor. I'm not even sure you can call it an editor out of the box. It's basically a box of parts that you can configure into your vision of what a text editor should be. No two instances of Emacs should ever be the same. So in order to utilize org-mode to its fullest potential you need to configure some things first. Also Emacs is self referential. I highly recommend you read the documentation not only for org-mode but for Emacs itself. <C-h i> will get you to the info page that contains documentation for both. You'll want to setup some hotkeys for quick access when you need it and you'll need to give org-mode some default locations for where to capture and look for it's data. Add these lines to your init.el Emacs configuration.

;; first setup a key-bind to access org-agenda, we'll talk more about what this is in a moment
(global-set-key (kbd "C-c a") 'org-agenda)
;; next setup a key-bind to enable you to quickly capture ideas
(global-set-key (kbd "C-c c") 'org-capture)

;; these next items are purely optional or comsmetic
;; TODO and DONE are the default states
(setq org-todo-keywords '("TODO" "STARTED" "WAITING" "DONE"))
;; set this to include entries from the Emacs diary into org-mode agenda
(defvar org-agenda-include-diary t)
;; make source code look better
(defvar org-src-fontify-natively t)

;; these next two are kind of important
;; the files to be used in the agenda display
(setq org-agenda-files (directory-files-recursively "~/org/agenda" "org$"))
;; default target for storing notes
(setq org-default-notes-file "~/org/agenda/organizer.org")
Remember, Emacs is highly customizable, you can set your key-binds and paths to whatever you like, these are only suggestions.

Back to top

Formatting

org-mode is text based so while it does have some formatting, some of it is for when you render it to a richer format like PDF. Exporting to other formats is out of the scope of this article. Speaking of richer formats however, one thing you may not be aware of is that Github will render your org files similar to way it would say a markdown file. So instead of making a README.md for example, you could make a README.org and will parse its markup and render it accordingly. One thing to be aware of though is that if you publish to NPM, npm will not recognize your README.org, it is specifically looking for a README.md which is quite unfortunate :( You can also create Github Gist's in org-mode as well. That said this won't be an exhaustive list of formatting markup, rather the things I find useful for my own documents. If you would like to learn even more please reference the documentation.


_underline_

/italics/

*bold*

=verbatim=

+strike-through+

- unorded list foo
- unorded list bar
- unorded list baz
  
+ unorded list foo
+ unorded list bar
+ unorded list baz
  
1. first item
2. second item
3. third item

#+BEGIN_VERSE
Great clouds overhead
Tiny black birds rise and fall
Snow covers Emacs

-- AlexSchroeder
#+END_VERSE

#+BEGIN_QUOTE
Everything should be made as simple as possible,
but not any simpler -- Albert Einstein
#+END_QUOTE

#+BEGIN_CENTER
Everything should be made as simple as possible, \\
but not any simpler
#+END_CENTER

#+BEGIN_SRC javascript
function foo() {
    console.log('bar');
}
#+END_SRC

Back to top

Key-Binds

One of the reasons to choose an editor like Emacs or VIM is for it's rich set of key-binds. org-mode has no shortage of key-binds and again I don't even begin to scratch the surface of what all is available but here is a set that I find useful:

Key-BindingFunction
<C-c C-l>Insert a link
<C-c C-o>Follow a link
<C-return>Insert heading
<C-c C-b>Back a heading
<C-c C-f>Forward a heading
<TAB>Expand current heading
<S-TAB>Expand all headings
<C-c C-e l p>Org export as Latex and convert to PDF
Table
<C-c pipe>Convert or edit a table
<pipe-dash-tab>Insert a horizontal rule
<C-^>Sort column
<M-(left-right)>Move column left or right
<M-(up-down)>Move row up or down
<M-S down>Insert row
<M-x org-table-insert-column>Insert column
<M-S up>Delete row
<M-x org-table-delete-column>Delete column
<C-c }>Toggle the display of Row/Column numbers in tables
Agenda
<C-c a a> (<C-c a> custom mapping)List all tasks (agenda)
<C-c a t>List all tasks (todo)
<C-c C-s>Schedule task
<C-c C-d>Create a deadline
<0-3 r>Review tasks by TODO status, list will be at top
<F>Put list in “follow-mode”
<S-(right-left arrow)>Toggle todo
<C-c C-t>Create or toggle a todo
Code block
<<-s-TAB>start a code block
<C-c C-c>execute code block
<C-c '>edit in prog-mode
Time tracking
<C-c C-x TAB>org-clock-in
<C-c C-x C-o>org-clock-out
<C-c C-x C-d>org-clock-display

Back to top

Knowledge Base

OK, whew, now that you have made some configuration, learned a little about formatting and a few key-binds we're finally ready to learn how to make org-mode useful to someone who writes code either as a hobby at home in your spare time or as your daily profession. One thing you probably want is a place to store knowledge that you've learned over time that you might not use every day. Before I started using Emacs I was a hardcore VIM user and in VIM I used a plugin called "vimwiki" (https://github.com/vimwiki/vimwiki) to hold my knowledge base. What vimwiki did that I really liked was sort of emulate a wiki right from with VIM. So you could use markdown or its own syntax, vimwiki, and create links to other documents, then you could use a hotkey to navigate to them just like clicking a link in a web page. You can replicate this behavior in org-mode. So what I do is create an index page that has links to all of my other documents, then I make a hotkey that will take me directly to this page from right within Emacs.

(set-register ?o '(file . "~/org/agenda/organizer.org"))
This takes advantage of Emacs registers and the hotkey is <C-x r j (register-index)> where "register-index" is "o" in this case for "organizer". Again this is the path to my file, you can make your path whatever you like. Once you are in your "organizer.org" or whatever you decide to call yours, you can create a new link with <C-c C-l>. Then choose the "file:" protocol and give it the path to your file, and finally it will prompt you for a label and it will insert the label into the document. Now you can navigate to the linked document by placing your point in the linked text and keying <C-c C-o>.

Whenever I'm learning something new this is how I do it. I start using whatever it is and the first time I have to research how to do something I open up my organizer.org file, create the link, navigate to the new file, then write it down. Then the next time I need to do this same thing over again instead of searching for it, I look here first because its just a hotkey away and so much faster. Eventually I remember whatever it is and don't have to navigate as often but if some time goes by and I forget again, I know where to find it.

Back to top

Note taking

You may have used, or currently still use other note taking apps like One Note or Evernote. However, as a developer, sometimes fantastic ideas will pop into your head, or you'll remember something important that you need to do and it would be nice to be able to capture that knowledge quickly without breaking your flow. That's what org-capture does for us. We made a key-bind for it <C-c c> up in the Setup and configuration section of this article. So imagine a scenario where you're deep in the middle of fixing a bug or implementing a feature on one of your projects when this great idea for a new app enters your consciousness. Just key <C-c c> and a window will popup prompting you to create a task that it is going to save to your organizer.org file that we also setup in the Setup and configuration section of this article. You key "t" to create the task, enter the information about it, key <C-c C-c> and the information is saved to your organizer.org file, the window goes away and you're back in the buffer where you're working on your bug. Emacs captures your idea, then gets out of your way. Later you can filter through your organizer.org file and break your idea down into more detail, maybe even creating it's own org file for it in a projects folder or something so you can flesh the idea out a little more, create tasks, etc... The ability to capture ideas quickly and get out of your way is a subtle but very valuable feature of Emacs. I highly recommend you give it a try.

Back to top

Agenda

As I mentioned in the beginning, org-mode is many things. Not only is it really good at capturing information, formatting it, and making it accessible through key-binds, it has the ability to "tag" information, timestamp it, create a schedule, and create deadlines. These features are extracted into a special buffer called the "agenda". We made a hotkey for this in the Setup and configuration section <C-c a a> As a programmer one thing you might want to do is create an org file for each project you are working on. Then you can enumerate tasks that you need to work through by prefixing each with the TODO keyword and assign a schedule or deadline for each item. Now you can run the file through the org-agenda and get a list you can filter by TODO type. The default types are TODO and DONE, but in the Setup and configuration section of this article we added 2 others, STARTED and WAITING. You can add whatever states best fit your workflow or just leave the defaults if that works for you. So a workflow might look something like this.

  1. Create an org file to track a project.
  2. Create a heading <C-return> and enter a description for a set of tasks. At the end of the description place the following [/] and key <C-c C-c>. This will let you track the progress of all of the completed tasks.
  3. Key <C-return> to create another heading, this time add a second * to make it a sub-heading, enter the text for the task to work on.
  4. Make the item a TODO <C-c C-t>.
  5. Schedule a time for this work to be completed <C-c C-s>.
  6. Repeat steps 3-5 until you have a complete list of tasks.
  7. Using the agenda view, pick a task to begin working on <C-c a> key < to scope agenda to the current org file, then choose t to filter by the TODO list.
  8. Track how long it takes to complete <C-c C-x TAB>. (starts a clock to time how long your task takes)
  9. When you've completed the task stop the time tracker <C-c C-x C-o>, and toggle it as complete <S->>.
Now as you complete tasks the heading will show a count of completed tasks, [1/3] for example. You can also key <C-c C-x C-d> to get a summary of how long it took you to complete all of your tasks. When you're done it will look something like this:
* Set of tasks to complete [1/3]

** DONE task 1
   SCHEDULED: <2020-02-09 Sun>
   :LOGBOOK:
   CLOCK: [2020-02-09 Sun 08:33]--[2020-02-09 Sun 08:36] =>  0:03
   :END:

** TODO task 2

** TODO task 3

Back to top

GTD (bonus)

I call this a bonus section because while its an interesting practice, its not really specific to developers. GTD stands for "getting things done" and is a set of practices for tracking and actually completing tasks. It has nothing to do with org-mode but I'm going to share with you how you can use org-mode to practice GTD.

PhaseGTDOrg
CollectCapture everything you need to do.Collect everything into the inbox
ProcessActionable?Put tasks on list, track delegated
Yes: do, delegate or defer;
no: file, throw or incubate
OrganizeNext actions, projects, waiting for, someday/maybeTag tasks, view tasks by tag
ReviewDaily, weekly, etc…Agenda view
DoActually do the workSadly Emacs can’t do this
So there are 5 phases to completing tasks, collect them, process them, organize them, review them, and then the hard part...do them! How can you use Emacs to help with this process? In the Setup and configuration section of this article we setup a hotkey for capturing tasks and ideas <C-c c>. We also setup a file to store these ideas called organizer.org, but you might want to call it inbox.org to fit the paradigm. The idea is you collect everything in its raw form into an inbox of sorts. Then you go through and "process" those ideas or tasks into actions that you can either do yourself or delegate to someone else. Next you tag the tasks so that you can view them by "tag" a feature of the "agenda". Now you can review them in the agenda which you will help you decide which tasks to do next...then you have to do them, which Emacs can't do for you unfortunately. You can read more about GTD here.

To make this work you need to learn about how to tag information, then use the agenda-view to filter through it. Here is how you might go about that:

  1. <C-return> to create a heading
  2. <C-c C-q> to tag that heading
  3. repeat steps 1 and 2 until you have everything captured
  4. <C-c a m> to enter the agenda by tag, enter the tag to filter on
Now you will have a list of items filtered by a specific tag that you can process through.

I hope you enjoyed the article. If I've made any mistakes, left out crucial information, or you would just like to comment please do so in the comment section below, I would love to hear from you.