Organized chaos
Table of contents

Most organizations use more tools than they’d like for communication and task management. Examples of this range from GitHub issues and pull requests, to Basecamp, Jira, Notion, and Slack... the list goes on. Each one of these tools can generate tasks (sometimes as small as a Slack mention), and juggling them all quickly gets exhausting.
In a perfect world, everything would land in one place and be managed consistently. But the world isn’t black and white, and we all have to cope with these complexities from time to time. Still, there are ways to make it manageable. This post will delve into how I handle it. It’s not the only way, but it’s the way that works for me.
Org mode
I’m an Emacs(opens in a new tab) user and a big fan of Org mode(opens in a new tab).
The Org mode(opens in a new tab) taglines says it best:
Your life in plain text
This is how I work. All my TODOs, notes, and general knowledge live in .org
files.
Notifications
Let’s start with notifications. People like to say email is outdated and reserved for old (40+) grumps like me. But can you show me a better way to gather all notifications — mentions, assignments, alerts — in one place? I haven’t found one. Yes, APIs exist and can pull this information for you, but not every service has a good (or accessible) API, and this can introduce complexity.
So yes, email is still the simplest option.
The first step is to enable email notifications for all the services you use. The second step is to sort them: In Gmail, filter all incoming emails and apply appropriate labels to sort them into folders.
It shouldn’t surprise you that I read and compose emails in Emacs. More specifically, I use mu4e(opens in a new tab) and mbsync(opens in a new tab) for bidirectional synchronization. You can also use Gnus(opens in a new tab) or your preferred alternative. The important part is that I have all emails locally and can access them when I’m offline, which I use mu4e bookmarks for.
An email to a TODO
Another feature I use constantly is that of turning emails into TODOs. Say I’m reading an email with a task for me. (In the following email, there isn’t a task, so just pretend for the sake of the example that there is.)
I use a keyboard shortcut to make the capture buffer appear.
My custom capture function checks if I’m reading an email. If so, it autofills the subject as the TODO name, adds properties, and — most importantly — stores a link back to the original message.
The result is a new TODO in my agenda, scheduled and linked to the source.
Now, if I click the link, it bring me to the source email instantly.
So to recap: I enable notifications everywhere, sort them in Gmail, sync mail locally, read my email a few times a day, and capture tasks directly in Org mode with links back to the source.
Browser integration
Sometimes I want to capture a note or a TODO and link it to the page I’m currently reading. On macOS, org-mac-link(opens in a new tab) is perfect for this. However, I’m on Linux and I have to use a slightly different method.
I keep an Org: store-link bookmark in my bookmark bar:
javascript:location.href = 'javascript:location.href='org-protocol://store-link?' + new URLSearchParams({url:location.href, title:document.title});void(0);
This uses org-protocol(opens in a new tab), a custom URL scheme used to trigger actions in Emacs. I’ve configured it in the following way:
zrzka@wtf ~ % cat ~/.local/share/applications/org-protocol.desktop[Desktop Entry]Name=org-protocolComment=Intercept calls from emacsclient to trigger custom actionsCategories=Other;Keywords=org-protocol;Icon=emacsType=ApplicationExec=emacsclient -- %uTerminal=falseStartupWMClass=EmacsMimeType=x-scheme-handler/org-protocol;zrzka@wtf ~ %
Clicking the Org: store-link bookmark passes the page URL and title to Emacs, where I insert it with a custom function:
(defun rv/org-insert-link () "Insert an org link and normalize it."
(interactive "*") (org-insert-link) (rv/org-normalize-link))
The rv/org-normalize-link
function above strips out extra things from page titles so that links stay clean:
(defun rv/org-normalize-link () "Remove Jira, GitHub nonsenses from the org link description.
Search backwards for an org link element. If found, get thedescription and run a couple of matches replacements (consult thefunction body for more information)." (interactive "*") (save-excursion (while (not (org-element-link-parser)) (backward-char)) (when-let* ((link (org-element-context)) (beg (org-element-property :contents-begin link)) (end (org-element-property :contents-end link))) (save-restriction (narrow-to-region beg end) (dolist (from-to '(;; Replace [LIC-123] with LIC-123: ;; Project key is always 2+ uppercased characters ("^\\[\\(\[A-Z0-9\]\\{2,\\}-\[0-9\]+\\)\\] " . "\\1: ") ;; Jira page title suffix ("^\\(.*\\) - PSPDFKit Task Management$" . "\\1") ("^\\(.*\\) - Nutrient Task Management$" . "\\1")... you get the idea
Then, wherever I am, a keyboard shortcut inserts a nice link.
Shell
The org-protocol(opens in a new tab) approach also works in the terminal. I can open an org-protocol://
link to store the current directory, or anything else.
Here’s an example of the org-store-link
function in ZSH:
function org-store-link() { local url=$(urlencode "$1") local title=$(urlencode "$2") local link
printf -v link "org-protocol://store-link?url=%s&title=%s" "${url}" "${title}" xdg-open "${link}"}
I can also use this function to create more of them:
# Org Store Link BaseNamefunction oslbn() { local rp=$(realpath "$1") local basename=$(basename "${rp}")
local link printf -v link "file://%s" "${rp}"
org-store-link "${link}" "${basename}"}
The sky’s the limit.
Conclusion
The Grug Brained Developer(opens in a new tab) once wrote: “grug say never be not improving tooling.” Is my tooling perfect? It isn’t, and it never will be, but I keep working at improving it. If there’s anything I don’t like, I simply capture it as a TODO and tackle it later. I usually work on tiny improvements every two weeks, or once a month, when I’m in the right mood.
Should you switch to Emacs? Only if you want to; this is just what works for me. You can achieve a similar workflow in Neovim, or even Visual Studio Code. The point isn’t Emacs — it’s about saving time and improving how you work, which is just as much a part of the job as writing code itself.
On that note, I’ll close with more wisdom from Grug: “tool and control passion what separate grug from dinosaurs!” Don’t be a dinosaur!