Emacs as gtd assistant
Table of Contents
Description
The following notebook aims to show how to implement a "Getting thing done" (GTD) workflow in emacs.
Set-up indications
To load the current file,
add
site-lisptoload-path;; (add-to-list 'load-path (concat user-emacs-directory "site-lisp")) (add-to-list 'load-path (concat (getenv "HOME") "/.emacs.d/site-lisp"))then, load the configuration file
(load "gtd-management" t t)
"Getting thing done" (GTD) in a nutshell
"Getting Things Done" (GTD) is a productivity methodology developed by David Allen, designed to help individuals and teams organize tasks, reduce stress, and achieve mind-like-water clarity. At its core, GTD is built on the principle that the human brain is ill-suited for storing and managing an ever-growing list of tasks, ideas, and commitments. Instead of relying on memory, GTD advocates for capturing everything—tasks, projects, ideas, and references—into an external system, freeing the mind to focus on execution rather than retention. This external system acts as a trusted repository, ensuring that nothing falls through the cracks and that priorities are always clear.
The GTD methodology is structured around five key steps: Capture, Clarify, Organize, Reflect, and Engage. The process begins with capturing every task, idea, or commitment into an inbox, whether it’s a physical tray, a digital app, or a plain text file. Once captured, each item is clarified to determine its nature: Is it actionable? If not, it may be reference material, trash, or something to incubate for later. If it is actionable, the next step is to define the very next physical action required to move it forward. These actions are then organized into contexts (e.g., @home, @work, @computer) or projects, which are collections of related tasks. Regular reflection—typically through a weekly review—ensures the system remains up-to-date and aligned with goals, while the final step, engage, involves choosing what to work on based on context, time, and energy.
What makes GTD particularly powerful is its adaptability. It doesn’t prescribe a specific tool or format, allowing users to implement it in notebooks, apps, or even Emacs with Org mode. By externalizing tasks and breaking them down into actionable steps, GTD transforms overwhelming to-do lists into manageable systems, enabling users to focus on what matters most without the mental clutter. Whether you’re managing personal projects, professional responsibilities, or long-term goals, GTD provides a framework for turning chaos into clarity.
(Written with the help of Mistral)
Workflow description
- Capture idea in inbox, i.e.
org-captureorC-c X - Clarify the task from inbox (later or on time) (maybe/projects/singles/references/archives/etc)
- Organize the task by adding a context (work, home, etc.)
- Reflect on the task (weekly?)
- Engage by selecting a task during a context to work
Configuration
;;; -*- lexical-binding: t; -*-
General variables
;; Mono-file scheme
;; (setopt gtd/gtd-file-path (concat org-directory "/gtd.org"))
;; Multi-files scheme
(setopt gtd/gtd-directory (concat org-directory "/gtd"))
(setopt gtd/inbox-file-path (concat gtd/gtd-directory "/inbox.org")
gtd/maybe_someday-file-path (concat gtd/gtd-directory "/maybe_someday.org")
gtd/singles-file-path (concat gtd/gtd-directory "/singles.org")
gtd/projects-file-path (concat gtd/gtd-directory "/projects.org")
gtd/references-file-path (concat gtd/gtd-directory "/references.org"))
Capture management
Base configurations
(setopt org-capture-templates `(("i" "Inbox" entry (file ,gtd/inbox-file-path) ,(concat "* TODO %?" "\n" ":PROPERTIES:" "\n" ":CREATED: %U" "\n" ":END:" "\n"))
("m" "Maybe/Someday" entry (file ,gtd/maybe_someday-file-path) ,(concat "* TODO %?" "\n" ":PROPERTIES:" "\n" ":CREATED: %U" "\n" ":END:" "\n"))
("s" "Single" entry (file ,gtd/singles-file-path) ,(concat "* TODO %? %^g" "\n" ":PROPERTIES:" "\n" ":CREATED: %U" "\n" ":END:" "\n"))
("r" "Reference" entry (file ,gtd/references-file-path) ,(concat "* TODO %?" "\n" ":PROPERTIES:" "\n" ":CREATED: %U" "\n" ":END:" "\n"))
))
Keybindings
(keymap-set global-map "C-c X" #'org-capture)
Projects specifics
(defun user/gtd-return-project-list ()
"Return the list of projects in the gtd/projects-file-path."
(with-temp-buffer
(insert-file-contents gtd/projects-file-path)
(goto-char (point-min))
(let ((headers '())
(header nil))
;; Collect all level 1 headers
(while (re-search-forward "^\\* \\(.*\\) \\:" nil t)
(push (match-string 1) headers))
(if (not headers)
(progn
(message "No level 1 Org headers found in %s" file-path)
nil)
(setq header (completing-read "Select header: " headers nil t))
header))))
(defun user/gtd-return-project-journal ()
`(,(user/gtd-return-project-list) "Journal")
)
(defun user/gtd-return-project-inbox ()
`(,(user/gtd-return-project-list) "Inbox")
)
(add-to-list 'org-capture-templates '("p" "Projects") t)
(add-to-list 'org-capture-templates `("pi" "Inbox" entry (file+olp ,gtd/projects-file-path user/gtd-return-project-inbox) ,(concat "** TODO %?" "\n" ":PROPERTIES:" "\n" ":CREATED: %U" "\n" ":END:" "\n")) t)
(add-to-list 'org-capture-templates `("pj" "Journal" entry (file+olp ,gtd/projects-file-path user/gtd-return-project-journal) ,(concat "%U" "\n" "%?") :prepend t) t)
(add-to-list 'org-capture-templates `("pn" "New Project" entry (file ,gtd/projects-file-path) ,(concat "* %? %^g" "\n" "%^{CATEGORY}p" "** Inbox" "\n" "** Journal")))
Refiling tasks
(setopt org-refile-targets `((,gtd/inbox-file-path :maxlevel . 3)
(,gtd/maybe_someday-file-path :maxlevel . 3)
(,gtd/singles-file-path :maxlevel . 3)
(,gtd/projects-file-path :maxlevel . 3)
(,gtd/references-file-path :maxlevel . 3)))
(setopt org-refile-use-outline-path 'file)
;; (setopt org-refile-use-outline-path t)
(setopt org-outline-path-complete-in-steps nil)
(setopt org-refile-use-cache t)
Agenda view
Configurations
(setopt user/org-agenda-files
`(,gtd/inbox-file-path
,gtd/maybe_someday-file-path
,gtd/singles-file-path
,gtd/projects-file-path
,gtd/references-file-path))
(setopt org-agenda-todo-keyword-format " %-6s")
(setopt org-agenda-prefix-format
'((agenda . " %i %-18:c%?-12t% s") (todo . " %i %-4:c")
(tags . " %i %-12:c") (search . " %i %-12:c")))
Keybindings
(keymap-set global-map "C-c o a" #'org-agenda)
TODOs configurations
(setopt org-todo-keywords '((sequence "TODO(t)" "NEXT(n)" "WAIT(w@/!)" "|" "DONE(d!)" "CNCL(c@/!)")))
(setopt org-use-fast-todo-selection 'expert)
Task movement
(setopt org-imenu-depth 2)
Set-up
(let ((file-paths user/org-agenda-files))
(dolist (file-path file-paths)
(unless (file-exists-p file-path)
(write-region "" nil file-path))
))