├── README.md
├── README.org
├── images
├── agenda-basic-screenshot.png
├── agenda-super-view-screenshot.png
├── agenda-todo-view-screenshot.png
├── enhanced-agenda-view-screenshot.png
├── general-tasks-screenshot.png
├── meeting-capture-screenshot.png
├── meeting-clock-time-overview-screenshot.png
├── meeting-detailed-clock-screenshot.png
├── meeting-details-screenshot.png
├── meeting-in-progress-screenshot.png
├── meeting-with-tags-screenshot.png
├── meetings-by-day-overview-screenshot.png
├── meetings-by-week-screenshot.png
├── meetings-clock-report-screenshot.png
├── random-notes-screenshot.png
└── work-log-screenshot.png
└── org-mode-config.el
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Table of Contents
3 |
4 | 1. [The Beautiful Nightmare that is Org Mode](#org56377d5)
5 | 1. [Why learning Org Mode is so hard](#org2b559c9)
6 | 2. [How to use this guide](#orgbac8993)
7 | 2. [Workflows](#orgf85f151)
8 | 1. [How this guide is trying to solve these problems](#org1f67048)
9 | 2. [Understanding workflows](#org15e744d)
10 | 1. [Personal Workflow Example](#org541b337)
11 | 2. [Understanding your workflow options](#org32de651)
12 | 3. [Figuring out your first workflow](#orga715fba)
13 | 3. [Configuring Capture Templates](#org866128a)
14 | 1. [Before you start](#orgae38c5c)
15 | 2. [Default settings](#orga70c740)
16 | 3. [Packages to install](#org10e3376)
17 | 4. [Configuration #1 - Work Log](#org6797146)
18 | 1. [Capture Template](#org0e0da60)
19 | 5. [Configuration #2 - Simple Note](#org505909e)
20 | 1. [Capture Template](#orgd5926ae)
21 | 6. [Configuration #3 - General TODO](#org06c21b3)
22 | 1. [Components of the TODO Item](#orgc154e4e)
23 | 2. [Explanation of the TODO Workflow](#orgc49466d)
24 | 3. [Capture Template](#org3710007)
25 | 4. [Org States](#org8459920)
26 | 7. [Configuration #4 - Programmer TODO](#org5da7e10)
27 | 1. [Tracking Bugs](#orgda9fe3a)
28 | 2. [Capture Template](#org18aea34)
29 | 8. [Configuration #5 - Meetings](#org6a3fcac)
30 | 1. [Capture Template](#org3ff207a)
31 | 2. [Clock Reports](#orga7aacf3)
32 | 4. [Tags](#orgc157736)
33 | 1. [Create groups of tags](#orgc6378e0)
34 | 2. [Start small](#org70101df)
35 | 3. [Multiple tags are better than a super descriptive tag](#org1848405)
36 | 4. [Defining tags](#org0a2450b)
37 | 5. [Colorizing tags](#orga63a848)
38 | 5. [Basic Agenda Usage](#orga8e42aa)
39 | 1. [Agenda Weekly View](#org9cb5aae)
40 | 2. [Agenda TODO View](#org1054d10)
41 | 6. [Enhanced Agenda #1](#orgf000a42)
42 | 1. [Agenda Enhanced View](#org366fcab)
43 | 2. [Agenda Custom Command](#orgd080503)
44 | 7. [Enhanced Agenda #2](#orge87093a)
45 | 1. [Agenda Custom Command](#org0342fb0)
46 | 8. [Final Thoughts](#org6533bf2)
47 |
48 |
49 |
50 |
51 | # The Beautiful Nightmare that is Org Mode
52 |
53 | This document is a walkthrough for new Org Mode users that will show how to create an initial configuration that is both productive and easy to understand. This is the guide I wish I had found when I first started learning Org Mode. I needed an explanation that tied together a user's workflow, the Org Mode features that support that workflow, a screenshot of what that looks like, and the code to make it all happen. Hopefully this guide will help you in your journey of mastering Org Mode.
54 |
55 |
56 |
57 |
58 | ## Why learning Org Mode is so hard
59 |
60 | Learning Org Mode is so challenging because its complexity easily becomes overwhelming. In learning about Org Mode I've found that it is often presented to new users as an impenetrable whole with no obvious starting point. The intro guides frequently describe basic functionality and then reference custom configurations by advanced users that are breathtaking in their scope and complexity. No path is given to go from novice to expert other than vague advice and useless platitudes. Most often you will hear variations on "just play with it until it makes sense".
61 |
62 | That sentiment is, to put it bluntly, bullshit.
63 |
64 | Other tools might have a setup wizard, sample configurations, or other tutorials to ease you into the software. However Org Mode is designed to be an open ended framework within which you the user can construct your ideal workflow. In this regards it is simpler to think of Org Mode as a programming language within Emacs. It is no wonder that adoption of this tool is so difficult. If you aren't already a programmer (one with lisp experience no less) you will find Org Mode has a brutal learning curve.
65 |
66 |
67 |
68 |
69 | ## How to use this guide
70 |
71 | If you are new to Org Mode, I would highly recommend reading the Workflows section first. Once you feel like you understand what your own needs are, then read through the various configurations. At that point, I would highly recommend putting some of that code into your own configuration file and experimenting with Org Mode. Look at how it functions and start to get a feel for what might work for you. Once you have a more solid grasp on the basics, then come back and read up on Tags and Agendas.
72 |
73 | There is a lot here and this is only a small fraction of what Org Mode is capable of. Take small steps and don't get discouraged. Good luck.
74 |
75 |
76 |
77 |
78 | # Workflows
79 |
80 | The part that everyone skips over. Org Mode was so difficult for me to learn because I started this process backwards. I started trying to use it before having any idea of what I actually wanted it to do.
81 |
82 |
83 |
84 |
85 | ## How this guide is trying to solve these problems
86 |
87 | Understanding org mode is a two fold process. The first step is developing a tentative workflow that works for you. The second step is figuring out what parts of org mode will support that workflow.
88 |
89 | This guide tries to help you discover a workflow that best suits you. Then a few common org configurations will be given to show how they can support different parts of a work flow. Finally everything will be modular so that a new user can pick and choose what they want to incorporate into their system. This is not meant to be a comprehensive list of every possible workflow or feature, but rather some common examples for new users to build on.
90 |
91 | So, let's dig into the problem.
92 |
93 |
94 |
95 |
96 | ## Understanding workflows
97 |
98 | Most websites with Org primers offer a very detailed org configuration that supports their very specific workflow. And this is great for them, but not for your average user who might only care about 10% of that particular setup. But since it is presented as one unified whole, it can be difficult to separate out which pieces you want vs which pieces will break things for you. So before we can start writing any configuration code we need to step back and ask ourselves, what should our workflow look like?
99 |
100 | I'm going to use this term "workflow" a lot in this document and to prevent any confusion, let's clearly define it now. A workflow is the sum of all the steps you take to complete a task. These steps typically involve processing information, tracking your status, organizing important details, and otherwise arranging resources in a useful and coherent manner.
101 |
102 | At this point you already have existing workflows that possibly involve email clients, calendars, sticky notes, notebooks, text messages, Word documents, or anything else you use to organize your life. Org isn't a magical fix for the complexity of life, however it does make it easier to manage that complexity. Hopefully by the end of this guide you will discover a way to integrate Org Mode into your existing routines.
103 |
104 | To better illustrate workflows, here is an example from my personal life.
105 |
106 |
107 |
108 |
109 | ### Personal Workflow Example
110 |
111 | I want to track home projects such as furniture I want to build, home renovations, general handy work, and future tools to buy. The usual progression of such projects tends to look something like this:
112 |
113 | `create project -> add details -> add notes -> research it -> start work on project -> finish project`
114 |
115 | So if I am going to build a new kitchen table I would create an entry on the project, add details like the dimensions, required seating, etc. Then do some research on styles (farm house vs modern) and on lumber (oak vs walnut prices). Finally once I had all the information I can create some steps (buy the lumber, dimension it, cut it, assemble it, dry fit, sand, stain, seal) so I can get a feel for how long this will take (many weekends) and then start working it.
116 |
117 |
118 |
119 |
120 | ### Understanding your workflow options
121 |
122 | So here we are. You want to use Org Mode to do…something. You aren't totally sure what but a lot of really smart people seem to think it is useful so you want to give it a try. And so you did what most new users do. You read the startup guide, you skim the docs, you realize you don't understand anything, and shortly thereafter you gave up in despair.
123 |
124 | But not today. Today is going to be different.
125 |
126 | So let's start off the right way by first brainstorming some ideas on how you want this whole thing to work. Initially you should focus only on establishing the simplest version of your own workflow. Go into this assuming that this is going to change and that nothing here is set in stone. Instead, treat this as a first draft that will get thrown away, redesigned, or heavily modified as you further understand what it is you really hope to get out of Org Mode. Look through the following list and see if any of these things are something you would want to integrate into your new Org Mode workflow.
127 |
128 | **Common Workflow Components**
129 |
130 | - handling emails
131 | - recording meeting notes
132 | - tracking time sensitive events
133 | - tracking reoccurring events
134 | - general to-do items
135 | - journals
136 | - work logs
137 | - prioritizing tasks
138 | - tracking your time
139 | - generating reports
140 | - outlining presentations
141 | - outlining a book
142 | - tracking JIRA tickets
143 | - tracking bugs in code
144 | - exporting documents to common formats
145 |
146 | And so on and so on.
147 |
148 | As a side note, something that took me a while to wrap my head around was that not everything has to be interconnected. So if you want to keep a journal, there is no reason that it has to be integrated into anything else. Where as you might want to keep your meetings in one file, your TODOs in another, and reference both of them in your agenda view.
149 |
150 |
151 |
152 |
153 | ### Figuring out your first workflow
154 |
155 | So at this point you should take a look at the list above (which is by no means meant to be taken as comprehensive) and decide what pieces you want to implement. I'm not going to implement every one of these examples (that would be a small book and I'm not *that* committed to this enterprise) but I am going to implement several of the more important ones and hopefully that will serve as a foundation on which to build your own workflow.
156 |
157 | Once you figure out what you want to do, starting thinking of the simplest way that you would like to reorganize your workflow to incorporate org mode. For example, don't do this:
158 |
159 | *"what are all the steps required to interface with my email client, import my emails, tag them, create TODO's from them, and then sort them in my Agenda View…"*
160 |
161 | and instead do this:
162 |
163 | *"I want to make TODOs based on my email"*
164 |
165 | Note that the second one doesn't require any fancy configuration. Of course, this means that there are going to be a lot of manual steps, BUT THAT IS OK! So in this example, imagine that you come up with the following work flow:
166 |
167 | **New possible workflow**
168 |
169 | - open gmail in my web browser
170 | - look at my unread messages
171 | - open up emacs
172 | - create a new Email TODO
173 | - fill in all the details by copy and pasting into emacs
174 | - do this for a week
175 | - live my best life
176 |
177 | Now I get what you are thinking. This is a lot of work. This is boring. This isn't leveraging anything! Where is the magic I was promised?
178 |
179 | I feel you, I really do. But we aren't there yet. This step is all about seeing if this prototype workflow is actually going to be useful. If it is then great! You can go down the road of turning emacs into your own email sorting hub. But you might do this for a few days and realize that you really don't get that many TODOs from your email, but instead you get them from meetings and then people just email you later to confirm details. So maybe making your emails the center point of this workflow isn't what you really need.
180 |
181 | Unfortunately there is no shortcut here. You just have to try a bunch of things out and see what clicks for you. Everyone has different needs and this is most definitely not a one-size-fits-all type of solution. But the key here is to try different approaches, do it all manually so you have minimal investment (think of how frustrating it would have been to spend 10 hours configuring your mail settings only to never use it), and then refine the parts that work for you.
182 |
183 |
184 |
185 |
186 | # Configuring Capture Templates
187 |
188 | In this section you will find five different configurations that support some of the workflow elements mentioned previously. These are all similar enough to show the common design behind how Org Mode operates, while hopefully being different enough to show off some of Org's most useful features.
189 |
190 | Now we get to the heart of things. Listed below are a series of steps that should, at the very least, be read in order. Not every configuration depends on the ones before it, but many do. So while I've tried to encapsulate these as much as possible, you should still read through everything first before you begin modifying your configuration.
191 |
192 |
193 |
194 |
195 | ## Before you start
196 |
197 | So you have looked at my list, maybe picked a few pieces out you want to try, thought about how your own workflow should work and now you are ready to configure org. Ok, let's do this. First, if you have not done so, you should check out [Org Mode Quickstart Guide](https://orgmode.org/quickstart.html). It's ok if you haven't memorized all of this yet, just keep that page open in your browser and reference it until things start to make more sense. Also, it is really going to help if you have some working knowledge of emacs configuration. You can muscle your way through this if this is your first time, but this is definitely not the package you want to be your introduction to Emacs.
198 |
199 |
200 |
201 |
202 | ## Default settings
203 |
204 | Listed below are some default settings that I use for Org Mode to make my life easier. You can find all of my settings in the .emacs file that is in this repo if you are curious. There are lots more that I will cover later, but for now here are some basic ones to get you started. Copy these lines into your .emacs file or where ever you keep your configurations.
205 |
206 | **Default Org Mode Settings**
207 |
208 | ;; Setup use-package just in case everything isn't already installed
209 | (unless (package-installed-p 'use-package)
210 | (package-refresh-contents)
211 | (package-install 'use-package))
212 |
213 | ;; Enable use-package
214 | (eval-when-compile
215 | (require 'use-package))
216 | (setq use-package-always-ensure t)
217 | (use-package org
218 | :pin gnu)
219 |
220 | ;; Must do this so the agenda knows where to look for my files
221 | (setq org-agenda-files '("~/org"))
222 |
223 | ;; When a TODO is set to a done state, record a timestamp
224 | (setq org-log-done 'time)
225 |
226 | ;; Follow the links
227 | (setq org-return-follows-link t)
228 |
229 | ;; Associate all org files with org mode
230 | (add-to-list 'auto-mode-alist '("\\.org\\'" . org-mode))
231 |
232 | ;; Make the indentation look nicer
233 | (add-hook 'org-mode-hook 'org-indent-mode)
234 |
235 | ;; Remap the change priority keys to use the UP or DOWN key
236 | (define-key org-mode-map (kbd "C-c ") 'org-priority-up)
237 | (define-key org-mode-map (kbd "C-c ") 'org-priority-down)
238 |
239 | ;; Shortcuts for storing links, viewing the agenda, and starting a capture
240 | (define-key global-map "\C-cl" 'org-store-link)
241 | (define-key global-map "\C-ca" 'org-agenda)
242 | (define-key global-map "\C-cc" 'org-capture)
243 |
244 | ;; When you want to change the level of an org item, use SMR
245 | (define-key org-mode-map (kbd "C-c C-g C-r") 'org-shiftmetaright)
246 |
247 | ;; Hide the markers so you just see bold text as BOLD-TEXT and not *BOLD-TEXT*
248 | (setq org-hide-emphasis-markers t)
249 |
250 | ;; Wrap the lines in org mode so that things are easier to read
251 | (add-hook 'org-mode-hook 'visual-line-mode)
252 |
253 | **Optional Org Mode Settings**
254 |
255 | I really like how this makes my layout look, but your mileage may vary so that's why I'm tagging this as optional.
256 |
257 | (let* ((variable-tuple
258 | (cond ((x-list-fonts "ETBembo") '(:font "ETBembo"))
259 | ((x-list-fonts "Source Sans Pro") '(:font "Source Sans Pro"))
260 | ((x-list-fonts "Lucida Grande") '(:font "Lucida Grande"))
261 | ((x-list-fonts "Verdana") '(:font "Verdana"))
262 | ((x-family-fonts "Sans Serif") '(:family "Sans Serif"))
263 | (nil (warn "Cannot find a Sans Serif Font. Install Source Sans Pro."))))
264 | (base-font-color (face-foreground 'default nil 'default))
265 | (headline `(:inherit default :weight bold :foreground ,base-font-color)))
266 |
267 | (custom-theme-set-faces
268 | 'user
269 | `(org-level-8 ((t (,@headline ,@variable-tuple))))
270 | `(org-level-7 ((t (,@headline ,@variable-tuple))))
271 | `(org-level-6 ((t (,@headline ,@variable-tuple))))
272 | `(org-level-5 ((t (,@headline ,@variable-tuple))))
273 | `(org-level-4 ((t (,@headline ,@variable-tuple :height 1.1))))
274 | `(org-level-3 ((t (,@headline ,@variable-tuple :height 1.2))))
275 | `(org-level-2 ((t (,@headline ,@variable-tuple :height 1.3))))
276 | `(org-level-1 ((t (,@headline ,@variable-tuple :height 1.5))))
277 | `(org-document-title ((t (,@headline ,@variable-tuple :height 1.6 :underline nil))))))
278 |
279 | Change the height multipliers to suite your own tastes. This is what works for me, but you may want them larger or smaller. Either way, put all of that into your .emacs file, relaunch emacs and let's roll.
280 |
281 |
282 |
283 |
284 | ## Packages to install
285 |
286 | I am using a variety of packages to make all of this work so here is a list if you want to install them manually:
287 |
288 | - org-super-agenda
289 | - comment-tags
290 |
291 |
292 |
293 |
294 | ## Configuration #1 - Work Log
295 |
296 | I find it very helpful to keep a daily log of what I accomplish at work. Before we get too deep into this, it is important to point out that this is not a journal. There are already tutorials and packages on how to use Org Mode as a journal. So if that is what you are actually looking for, go ahead and skip this one.
297 |
298 | In this case a journal contains daily entries that are typically several paragraphs of text while a work log is several bullet points of accomplishments with additional detail as needed.
299 |
300 | So here is what I want:
301 |
302 | 
303 |
304 | And here is the code that needed to make this work:
305 |
306 |
307 |
308 |
309 | ### Capture Template
310 |
311 | When the capture template is initiated the capture key should be "j". I set it to "j" because I use a journal at home and I wanted to just associate the "j" key with "write a log of my thoughts" regardless of whether I'm at home or at work. But if you wanted to change this to a "w" I won't hold it against you.
312 |
313 | (setq org-capture-templates
314 | '(
315 | ("j" "Work Log Entry"
316 | entry (file+datetree "~/org/work-log.org")
317 | "* %?"
318 | :empty-lines 0)
319 | ))
320 |
321 | This is going to save all of my work logs into the `work-log.org` file using the date structure shown in the picture above. For details on how to modify that structure look up `org-capture-templates` in the manual.
322 |
323 |
324 |
325 |
326 | ## Configuration #2 - Simple Note
327 |
328 | This is my dumping ground for trivial pieces of information. Things like the password for the supply closet door, where I left that obscure part that I will need one day, or some important piece of trivia that I keep having to look up. There are no tags, filtering, or automatic-anything here. This is the most basic Org Mode example I can think of and I'm including it here mainly for reference.
329 |
330 | 
331 |
332 | Here is the capture template:
333 |
334 |
335 |
336 |
337 | ### Capture Template
338 |
339 | If you wanted to use this along with the work log capture template from above, then you would only need to copy in the small subsection, not the entire chunk starting with `(setq org-capture...` in case that was not clear. Otherwise, here is the template for a basic note.
340 |
341 | (setq org-capture-templates
342 | '(
343 | ("n" "Note"
344 | entry (file+headline "~/org/notes.org" "Random Notes")
345 | "** %?"
346 | :empty-lines 0)
347 | ))
348 |
349 | No date structure needed here, just a long list of random notes. If you wanted to use the same file but add another heading called "Door Codes" you could then configure another capture template like so:
350 |
351 | (setq org-capture-templates
352 | '(
353 | ("n" "Note"
354 | entry (file+headline "~/org/notes.org" "Random Notes")
355 | "** %?"
356 | :empty-lines 0)
357 |
358 | ("d" "Door Codes"
359 | entry (file+headline "~/org/notes.org" "Door Codes")
360 | "** %?"
361 | :empty-lines 0)
362 | ))
363 |
364 | And then all of the notes captured from that would go into that heading.
365 |
366 |
367 |
368 |
369 | ## Configuration #3 - General TODO
370 |
371 | Now we are getting to the heart of what makes Org Mode so amazing, the ability to track TODO items! To fully explore this feature is going to require several configurations, however I am going to start off with a simple "General To-Do" item and then layer more functionality onto it in later steps. In the Agenda section we will review how to organize all of our TODOs, but right now we are focusing on simply creating them.
372 |
373 | 
374 |
375 | We are going to look at one TODO in particular.
376 |
377 | * OBE [#B] Talk to Mike and ask about broken restores
378 | CLOSED: [2021-11-15 Mon 13:09]
379 | - State "OBE" from "IN-PROGRESS" [2021-11-15 Mon 13:09]
380 | - State "IN-PROGRESS" from "TODO" [2021-11-09 Tue 15:13] \\
381 | Wrapping this into CCRS-4453.
382 |
383 | Namely, what do do when a restore fails. Do we just leave it in whatever state it is in?
384 |
385 | There is a lot going on here so I'm going to break it down in the various components. Here is what this TODO is comprised of:
386 |
387 | * STATE [#PRIORITY] TITLE
388 | - STATE CHANGE 2 TIMESTAMP
389 | - STATE CHANGE 1 TIMESTAMP
390 | NOTE ABOUT STAGE CHANGE 1
391 |
392 | NOTE ABOUT TODO
393 |
394 |
395 |
396 |
397 | ### Components of the TODO Item
398 |
399 | Let's look at each piece one at a time.
400 |
401 | **STATE**
402 | In this TODO it is set to `OBE` (overcome by events). Other TODOs are set to `DONE`, `TODO`, or `IN-PROGRESS`. We will setup these states in just a minute, but for the moment all you need to know is that each TODO can cycle through several states.
403 |
404 | **PRIORITY**
405 | Each TODO can have a priority. You can create your own set of priorities such as [DEFCON 1, TROUBLE, MILDLY-BAD,SAFELY-IGNORE] but the defaults of [A,B,C] work just fine and it is what we will be using here. In this case `A` is the highest priority and `C` is the lowest. Don't worry too much about this yet, this will make more sense once we get to the agenda view.
406 |
407 | **TITLE**
408 | This is the name of your TODO that is entered from the capture menu.
409 |
410 | **STATE CHANGE 2**
411 | The latest state change. As we see it went from `IN-PROGRESS` to `OBE` and a timestamp was recorded when this occurred.
412 |
413 | **STATE CHANGE 1**
414 | The initial state change. The TODO went from in the `TODO` state to `IN-PROGRESS` and a timestamp was recorded when this occurred too.
415 |
416 | **STAGE CHANGE 1 NOTE**
417 | When work was started on this TODO and the state changed, a note was added as a form of documentation.
418 |
419 | **NOTE**
420 | And here is where all the details go. This could be much more involved, but for this example it was reduced to a single line.
421 |
422 |
423 |
424 |
425 | ### Explanation of the TODO Workflow
426 |
427 | The general idea behind all of this is to capture a TODO item, assign it a priority, and save a detailed description of what needs to be done. Once that is recorded we can revisit this TODO at a later date and begin working on it. Once work has begun the state changes to `IN-PROGRESS`. When that happens the user is prompted to write a small note (this is not required, you could leave it blank) and a timestamp is recorded of when the state change happened. Finally, once the work has been completed, the note can be set to a done state. In these examples the done states are `DONE`, `OBE`, and `WONT-DO`. But we are getting ahead of ourselves. First let's look at how this was accomplished.
428 |
429 |
430 |
431 |
432 | ### Capture Template
433 |
434 | A general TODO item is captured with a `g` from the capture template buffer. All of the TODOs are saved to the `todos.org` file under the `General Tasks` heading. You can see that the initial state is set to `TODO` and the initial priority is set to `B`. Along with all of this I've added an additional field called `Created:` which adds a timestamp for when this TODO was created. We can filter on that later, but it is simply an optional piece of meta data that you might want to include.
435 |
436 | (setq org-capture-templates
437 | '(
438 | ("g" "General To-Do"
439 | entry (file+headline "~/org/todos.org" "General Tasks")
440 | "* TODO [#B] %?\n:Created: %T\n "
441 | :empty-lines 0)
442 | ))
443 |
444 |
445 |
446 |
447 | ### Org States
448 |
449 | By default Org only sets up two states, `TODO` and `DONE`, which by and large isn't very useful. There are so many more nuances we could capture! In fact, we shall do so now. Here are the states I've setup for my workflow (and remember I'm a programmer, not all of these will apply to you) that I find very handy.
450 |
451 | ;; TODO states
452 | (setq org-todo-keywords
453 | '((sequence "TODO(t)" "PLANNING(p)" "IN-PROGRESS(i@/!)" "VERIFYING(v!)" "BLOCKED(b@)" "|" "DONE(d!)" "OBE(o@!)" "WONT-DO(w@/!)" )
454 | ))
455 |
456 | So as you can see here I've got eight different states setup. Five of these states are active states with the final three being inactive. The idea behind this is that a task is created, work is begun, and finally it concludes. Along the way the work could require verification (possibly from someone else) or be blocked completely. Eventually it will reach an end state and become inactive. Ideally the task will have been successfully completed and we can mark it as `DONE` but it may be that in the course of working this it no longer becomes a priority. At which point it can be marked `OBE`. Finally, it is possible that after further review, you decide you don't want to work on this. Maybe it no longer matters, it is someone else's job, or you just changed your mind. Either way, you never want to just delete something because you always want a log of what you've been working on. Thus it gets set to `WONT-DO`.
457 |
458 | If you are curious about the extra characters in the parens then you can look in the documentation for the exact details as well as other configuration options. But the short version is that they signify to Org which key to use for shortcuts, some prompt the user for a note, and some record a timestamp. In this example, when you set it to `IN-PROGRESS` it prompts you to record a note and then records a timestamp. As it is possible that when you start a new task you want to record some initial thought however setting it to the `VERIFYING` state does not because it is assumed no note is required. Likewise when you set it to `DONE` it just records a timestamp, but setting it to `OBE` or `WONT-DO` requires a note because you should explain why you aren't going to complete this task.
459 |
460 | Finally, if you have been following along, editing your own config file to match my changes, you might start to notice some differences. Your files look flat and my examples all look nice and sexy. What is going on? Well I've decided to add some color to my life to improve my Org experience. Don't worry, you can easily spice things up by telling Org that you want to set custom colors for your TODO states. Simply add this in to your config and tweak the colors as needed:
461 |
462 | ;; TODO colors
463 | (setq org-todo-keyword-faces
464 | '(
465 | ("TODO" . (:foreground "GoldenRod" :weight bold))
466 | ("PLANNING" . (:foreground "DeepPink" :weight bold))
467 | ("IN-PROGRESS" . (:foreground "Cyan" :weight bold))
468 | ("VERIFYING" . (:foreground "DarkOrange" :weight bold))
469 | ("BLOCKED" . (:foreground "Red" :weight bold))
470 | ("DONE" . (:foreground "LimeGreen" :weight bold))
471 | ("OBE" . (:foreground "LimeGreen" :weight bold))
472 | ("WONT-DO" . (:foreground "LimeGreen" :weight bold))
473 | ))
474 |
475 | That is it for TODOs. Save your config, reload, and test everything out. Tweak things until you like the colors and such. Now that we've gotten all the easy stuff out of the way, let's move on to more complex things.
476 |
477 |
478 |
479 |
480 | ## Configuration #4 - Programmer TODO
481 |
482 | I'm including this as a separate section because I don't want to confuse people who came here looking for help but aren't themselves programmers. I was going to include this in the previous section but I felt that had already grown too long as it is. With that in mind, here are some features that really only other programmers will care about.
483 |
484 |
485 |
486 |
487 | ### Tracking Bugs
488 |
489 | As a programmer I do all my development in Emacs. Regardless of the language, I have it open at all times. And so there are plenty of times that I will be scanning through some source code and see something that I want to fix. If it is relatively trivial I will just leave a comment in the code with a note saying someone should come back and fix this in the future. However, frequently I'll see something that is considerably more involved. Maybe I just found an edge case that wasn't previously being handled or some tricky chunk of code that I just spent 20 min figuring out and I don't want to have to go through all of that again in 3 months when I finally get a chance to refactor it. It is in cases like this where it is extremely handy to capture the location of the bug and store it inside my TODO item. Here is what I mean.
490 |
491 |
492 |
493 |
494 | ### Capture Template
495 |
496 | A code specific TODO
497 |
498 | (setq org-capture-templates
499 | '(
500 | ("c" "Code To-Do"
501 | entry (file+headline "~/org/todos.org" "Code Related Tasks")
502 | "* TODO [#B] %?\n:Created: %T\n%i\n%a\nProposed Solution: "
503 | :empty-lines 0)
504 | ))
505 |
506 | This capture must be executed on the line of code you want to link to. When you create a code TODO you are generating a new TODO item, but you are also linking that TODO to that specific line of code. You can then easily visit that link to see what exactly you were referencing.
507 |
508 | Of course you could do this with any text file, not just code. If you were writing a book and wanted to mark a particular passage that you wanted to come back to later and rewrite, this would do nicely for you.
509 |
510 |
511 |
512 |
513 | ## Configuration #5 - Meetings
514 |
515 | There are two distinct parts to capturing meeting data. There is the "scheduling/tracking/people" side of it and there is the "note taking/action item/what next" side of it.
516 |
517 | For the first part, the planning and all that, I just use Microsoft's Outlook. Now I hate Outlook, but everyone uses it. They schedule meetings through it, I get email reminders through it, I get system notifications of upcoming meetings through it, and then when we do the meeting, it gives me the Teams link to join. That functionality already exists, everyone in my company uses it, and so for our purposes here, there is no need to try and replicate that. Just let Microsoft win this round and move on.
518 |
519 | However the second part, that is something that Org excels at. Org supports adding a `DEADLINE` or a `SCHEDULED` tag that has some interesting use cases, however I have not found these features very useful in my own workflows. I rarely schedule meetings in advance so those features don't really help me. Instead I have several meetings a day from coworkers who need to talk about something for 20 min or a manager who wants to discuss a possible change in direction. These meetings frequently contain very useful information as well as action items that I need to accomplish. So, to fill that need I've created a capture template that combines TODOs and tags to ensure that my meetings are always properly recorded.
520 |
521 | Shown below is an overview of a portion of my meetings. They have been automatically organized by week and minimized for easier reading. I personally prefer them grouped by week since it makes it easier for me to read though past meetings.
522 |
523 | 
524 |
525 | Here I have expanded the view one level deep. Now you can see the title of each meeting held on each day. The colored words are tags, but that will be discussed below.
526 |
527 | 
528 |
529 | Finally we see all the details of Thursday's meetings. Lots to unpack here. There is a `LOGBOOK` of meta data, timestamp of creation, a `CLOCK` value showing the total time the meeting took, who attended, notes, and Action Items! Lots to unpack.
530 |
531 | 
532 |
533 | But as always, let's start with the capture template.
534 |
535 |
536 |
537 |
538 | ### Capture Template
539 |
540 | (setq org-capture-templates
541 | '(
542 | ("m" "Meeting"
543 | entry (file+datetree "~/org/meetings.org")
544 | "* %? :meeting:%^g \n:Created: %T\n** Attendees\n*** \n** Notes\n** Action Items\n*** TODO [#A] "
545 | :tree-type week
546 | :clock-in t
547 | :clock-resume t
548 | :empty-lines 0)
549 | ))
550 |
551 | Clearly this capture template is the most complex yet, so let's go line by line and see what is happening. The `entry` value sets up how the structure of the file will be saved. The next line describes the template for how the meeting will be recorded. It also contains some predefined Org special characters such as `%T` which will give us a timestamp. This line also contains a tag called `:meeting:` (which we will use later) as well as a subsection called `Action Items` which is prepopulated with an empty TODO.
552 |
553 | This is what you should see when you start the capture template and hit "m". In the mini buffer you will see the option to add additional tags. You don't have to add any tags and you can always add more tags later, but this is where you would add some initially.
554 |
555 | 
556 |
557 | In this example I decided to add another tag called `:james` since this meeting is all about me. After I select that tag and hit return, I get something like this:
558 |
559 | 
560 |
561 | This looks a little bit more promising. The empty space beside the `*` is for the title of this meeting. There are two tags (`meeting` and `james`), a `LOGBOOK` entry (which is used for clocking time), a custom piece of metadata called `:Created:` (more on that in the Agenda section), a list for attendees, notes, and finally action items. So the meeting has started, you've activated your meeting capture template, and now you are filling in data. I've taken the liberty of filling out my own meeting so you can see what it would look like.
562 |
563 | 
564 |
565 | When the capture is over and everything gets saved to the file, you can revisit the meeting and see that length of the meeting was recorded. The clock started as soon as the meeting capture template was activated and ended when you closed it out. Now you can go back and review past meetings and see how much time your coworkers have stolen from you.
566 |
567 | A key takeaway from all of this is that tags are applied at the base level of this meeting and that everything that is part of that meeting inherits those tags. So the TODO item I made inherits the tags `:meeting:` as well as `:james:`. If I wanted to add an addition tag to one of the TODOs under `Action Items` then that TODO would have 3 tags while the meeting would only have 2. Speaking of tags, I should probably explain that next.
568 |
569 |
570 |
571 |
572 | ### Clock Reports
573 |
574 | One very useful aspect of Org Mode is the ability to clock in and out of tasks to track time. In the capture template for a meeting the clock-in value has been set to true which starts the clock when the meeting is created and ends when the capture template is closed and the meeting is presumably over. This metadata is saved in the `:LOGBOOK:` section of the meeting. Having this data allows us to track our time visually using two commands, `org-clock-report` and `org-clock-display`.
575 |
576 | 1. Clock Report
577 |
578 | A clock report gets generated with `org-clock-report` and inserted into your file. This value is not dynamic but rather is set when the command is executed. This is useful for viewing metrics of past events as it allows you to easily summarize the time spent in meetings. This feature of Org Mode is useful when you require more concrete metrics on how your time is spent. Perhaps you need to track time for billing or time allocation for a project. If so, this feature can make your life much easier. Here is an example of a clock report for three weeks of my meetings.
579 |
580 | 
581 |
582 | 2. Clock Display
583 |
584 | A clock display is just an overlay for quickly viewing how much time has been spent on various entries and can be viewed by executing `org-clock-display`. It looks like this:
585 |
586 | 
587 |
588 | And with more details:
589 |
590 | 
591 |
592 | This is a quick and easy way to keep track of how much time is being spent on various meetings.
593 |
594 |
595 |
596 |
597 | # Tags
598 |
599 | Before moving on to the Agenda I need to take a moment and explain tags. I've mentioned them several times previously but now I need to go into more depth on how to set them up and use them. You don't want to create too many tags or you won't use them effectively. You don't want too few or else you won't get the full impact of their use in your Agenda. Here are some general guidelines I've found for using tags effectively.
600 |
601 |
602 |
603 |
604 | ## Create groups of tags
605 |
606 | Creating groups of tags that make sense. For example, if you are keeping track of what chores each person in your household needs to accomplish in a week, make a tag for each person's name. If you are keeping track of recipes, make a tag for type of dish, i.e. German, French, Vietnamese, etc.
607 |
608 | Additionally you can create exclusive groups where only one tag from the group can be used at a time. To keep with our recipe example, your group could contain (breakfast, meal, dessert, drink). Which would indicate that the recipe in question must be one, and only one, of those tags. The tag does not have to be used, but if it is used, only one can be used at a time.
609 |
610 |
611 |
612 |
613 | ## Start small
614 |
615 | It is better to start with a small selection of tags and expand as you go, rather than start with 20 tags and then try to see what you don't need. Start with broad groups and see where natural subdivisions occur. Also remember that this isn't tagging for the sake of tagging. You want to eventually filter on these tags or search for them in some manner. So if you aren't ever planning on using a tag, then there is no point in creating one.
616 |
617 | Beating this food analogy to death, you could create tags like `:requires_open_flame:` but if you never plan on needing to filter recipes that require flambe, then what is the point?
618 |
619 |
620 |
621 |
622 | ## Multiple tags are better than a super descriptive tag
623 |
624 | Think of ways of combining tags to make a descriptive notation rather than relying on overly specific tags that will eventually be too constraining. If you are creating TODOs based on incoming emails, don't use a tag called `:future_project_with_kevin:` but instead do `:future_project:kevin:`. I'm sorry if that sounds obvious, but when you are first starting out with Org Mode you can find yourself slipping into bad habits because you aren't sure yet what you need and the instinct can be to just throw everything against the wall and see what sticks.
625 |
626 |
627 |
628 |
629 | ## Defining tags
630 |
631 | Here are the tags I'm using for the workflow examples in this document.
632 |
633 | ;; Tags
634 | (setq org-tag-alist '(
635 | ;; Ticket types
636 | (:startgroup . nil)
637 | ("@bug" . ?b)
638 | ("@feature" . ?u)
639 | ("@spike" . ?j)
640 | (:endgroup . nil)
641 |
642 | ;; Ticket flags
643 | ("@write_future_ticket" . ?w)
644 | ("@emergency" . ?e)
645 | ("@research" . ?r)
646 |
647 | ;; Meeting types
648 | (:startgroup . nil)
649 | ("big_sprint_review" . ?i)
650 | ("cents_sprint_retro" . ?n)
651 | ("dsu" . ?d)
652 | ("grooming" . ?g)
653 | ("sprint_retro" . ?s)
654 | (:endgroup . nil)
655 |
656 | ;; Code TODOs tags
657 | ("QA" . ?q)
658 | ("backend" . ?k)
659 | ("broken_code" . ?c)
660 | ("frontend" . ?f)
661 |
662 | ;; Special tags
663 | ("CRITICAL" . ?x)
664 | ("obstacle" . ?o)
665 |
666 | ;; Meeting tags
667 | ("HR" . ?h)
668 | ("general" . ?l)
669 | ("meeting" . ?m)
670 | ("misc" . ?z)
671 | ("planning" . ?p)
672 |
673 | ;; Work Log Tags
674 | ("accomplishment" . ?a)
675 | ))
676 |
677 | Note that the Ticket Types and the Meeting Types are both exclusive groups. A ticket can be a bug or a feature or a spike. Likewise a meeting can only have one major type. However, the rest of the tags can be combined as needed. Generally I've broken the tags into two categories, those that go on TODO items and those that do not. So a meeting might get tagged with `:meeting:backend:` because I'm having a meeting about the backend, however within that meeting I might create a TODO with the tag `:CRITICAL:@bug:` because I've just found a critical bug that needs to be fixed right away. Also the "@" you see in the tags has no special Org related significance, that is strictly something for me.
678 |
679 |
680 |
681 |
682 | ## Colorizing tags
683 |
684 | If it is worth doing it is worth making it pretty. That is one of my odder mottoes to be sure, nonetheless we are going to make our tags sexy!
685 |
686 | ;; Tag colors
687 | (setq org-tag-faces
688 | '(
689 | ("planning" . (:foreground "mediumPurple1" :weight bold))
690 | ("backend" . (:foreground "royalblue1" :weight bold))
691 | ("frontend" . (:foreground "forest green" :weight bold))
692 | ("QA" . (:foreground "sienna" :weight bold))
693 | ("meeting" . (:foreground "yellow1" :weight bold))
694 | ("CRITICAL" . (:foreground "red1" :weight bold))
695 | )
696 | )
697 |
698 | Doing this allows our tags to take on different colors and weights. In my opinion this is one of the most useful enhancements I have made to my setup. I find that colorful tags really helps me take in info at a glance and otherwise makes drab TODOs much more interesting.
699 |
700 |
701 |
702 |
703 | # Basic Agenda Usage
704 |
705 | Before we go down this rabbit hole, and make no mistake this is a rabbit hole like no other, you should be aware that strictly speaking you don't *need* to use the Agenda view. Oh it will make your life much easier (eventually) but if you don't use it right away, that's perfectly ok. Learning all of this can be quite overwhelming and there is no shame in coming back to this once you are ready.
706 |
707 | Having said all that, let's dig into the core pieces of the Agenda View. At its simplest you will use the Agenda for two primary things, to view items with timestamps in the date view and to view TODO items in the tasking view. Everything else, all the other features, filters, enhancements, etc. are all just sitting on top of those two core pieces. Here are some examples to show you what I mean.
708 |
709 |
710 |
711 |
712 | ## Agenda Weekly View
713 |
714 | Here is the basic view you get when you invoke the Agenda view with `C-c a` and then hit `a` for the very first option in the list, the Agenda for current week or day.
715 |
716 | 
717 |
718 | You can see that I had a bunch of meetings that week. As a side note, those meetings and TODOs are only showing up in this view because each of them have a timestamp in the `:Created:` field. Go back and look at Configuration #5 if you missed it. But it is important to remember that only things with timestamps show up here. I could have used the deadline or scheduled fields and that would have worked too. But that is something that can trip you up, so keep that in mind.
719 |
720 | You will notice that each entry has a label to the left of it. That is the file that the entry was found in. That can be replaced with the category name if set, but since I didn't bother with that, it just defaulted to the file name. On the far right you will see some tags, they will be useful later. Now let's take a look at the TODOs view.
721 |
722 |
723 |
724 |
725 | ## Agenda TODO View
726 |
727 | When selecting the `List all TODO entries` filter in the Agenda you get something like this:
728 |
729 | 
730 |
731 | Where you can clearly see all of the TODOs, ordered by priority then by file (or category). A lot of these TODOs contain tags with many containing multiple tags. The default view tries to organize things for us, but with lots of TODOs it is a bit difficult to read. There is a lot of information here to process. At a glance you have the following pieces of data being displayed:
732 |
733 | - the file the TODO came from (meetings, todos, or tickets)
734 | - the state of the TODO (`TODO`, `IN-PROGRESS`, `PLANNING`, `VERIFYING`, or `BLOCKED`)
735 | - the priority (`A`, `B`, or `C`)
736 | - the title of the TODO
737 | - any tags associated with it (planning, backend, or CRITICAL among others)
738 |
739 | So clearly there is a lot going on here. And while you can filter this view in a variety of ways (look it up in the manual, there is too much to discuss here) to help in managing this complexity, it can still be a bit overwhelming. Let's try to make this a bit more readable.
740 |
741 |
742 |
743 |
744 | # Enhanced Agenda #1
745 |
746 | This next view is a modified version of one that I copied from [Aaron Bieber](https://github.com/aaronbieber/dotfiles/blob/master/configs/emacs.d/lisp/init-org.el). I honestly don't recall how I ended up looking at his github config files, but he has some good stuff and I would encourage you to look at his setup at some point. Aaron, if you ever stumble across this, you rock. Thanks for the inspiration. Here is what my version looks like:
747 |
748 |
749 |
750 |
751 | ## Agenda Enhanced View
752 |
753 | 
754 |
755 | So right away we notice that this is much easier to read. Our highest priority items are at the top, the weekly Agenda view has been incorporated as well, and over all this makes for a much more readable experience. Let's look at the code that supports this.
756 |
757 |
758 |
759 |
760 | ## Agenda Custom Command
761 |
762 | To add this view there are a couple of pieces required.
763 |
764 | ;; Agenda View "d"
765 | (defun air-org-skip-subtree-if-priority (priority)
766 | "Skip an agenda subtree if it has a priority of PRIORITY.
767 |
768 | PRIORITY may be one of the characters ?A, ?B, or ?C."
769 | (let ((subtree-end (save-excursion (org-end-of-subtree t)))
770 | (pri-value (* 1000 (- org-lowest-priority priority)))
771 | (pri-current (org-get-priority (thing-at-point 'line t))))
772 | (if (= pri-value pri-current)
773 | subtree-end
774 | nil)))
775 |
776 | (setq org-agenda-skip-deadline-if-done t)
777 |
778 | (setq org-agenda-custom-commands
779 | '(
780 | ;; Daily Agenda & TODOs
781 | ("d" "Daily agenda and all TODOs"
782 |
783 | ;; Display items with priority A
784 | ((tags "PRIORITY=\"A\""
785 | ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
786 | (org-agenda-overriding-header "High-priority unfinished tasks:")))
787 |
788 | ;; View 7 days in the calendar view
789 | (agenda "" ((org-agenda-span 7)))
790 |
791 | ;; Display items with priority B (really it is view all items minus A & C)
792 | (alltodo ""
793 | ((org-agenda-skip-function '(or (air-org-skip-subtree-if-priority ?A)
794 | (air-org-skip-subtree-if-priority ?C)
795 | (org-agenda-skip-if nil '(scheduled deadline))))
796 | (org-agenda-overriding-header "ALL normal priority tasks:")))
797 |
798 | ;; Display items with pirority C
799 | (tags "PRIORITY=\"C\""
800 | ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
801 | (org-agenda-overriding-header "Low-priority Unfinished tasks:")))
802 | )
803 |
804 | ;; Don't compress things (change to suite your tastes)
805 | ((org-agenda-compact-blocks nil)))
806 | ))
807 |
808 | Now when you bring up the Agenda selection dialog you should see the `Daily agenda and all TODOs` option that can be selected with `d`. This is a much better option than the default view and was my go-to view for a long while. However, it is still really busy and it can be difficult to find certain items as they can be buried if your list grows too long. So let's look at another solution.
809 |
810 |
811 |
812 |
813 | # Enhanced Agenda #2
814 |
815 | For this next Agenda configuration I'm using a packaged called [Org Super Agenda](https://github.com/alphapapa/org-super-agenda). If you are new to Org Mode, this is definitely overkill. So there is no shame in slowly backing away from this one if you feel you aren't ready yet. However, once you feel like you want to expand your setup beyond the defaults, this is an awesome package to try out. Let's take a look at what my previous view would look like with the Super Agenda.
816 |
817 | 
818 |
819 | Well this is wild, isn't it? Things are sorted into logical groups, there aren't tags cluttering everything up, and the grouping seems more logical than just filtering by priority. What sorcery is this, you say? Well this is what the Super Agenda gives you. Read more at the link above to get the full documentation, but the gist is that you setup filters and then the super agenda applies them to your TODO items in the order you defined the filters. So in my case I set this up to filter all the critical tasks into the first bucket. If one of those critical tasks also matched a later filter (like say it required additional research or was a blocker) it would still only show up in the first bucket. Since that first bucket takes priority. If I removed the `:CRITICAL:` tag then it would filter down into a lower bucket. At the end it will display all the TODOs that don't have a filter. If there is a filter with no TODOs matching its criteria, then it just doesn't display it. So you aren't seeing my "Movies to Watch" bucket because I'm all caught up on my preferred cinema at the moment. But as soon as Marvel releases another movie, that bucket with appear. Sounds easy right? Well…actually yeah, it is pretty straight forward once you see how it is done. Let's look at my configuration file.
820 |
821 |
822 |
823 |
824 | ## Agenda Custom Command
825 |
826 | Here are the pieces you will need for this:
827 |
828 | (setq org-agenda-custom-commands
829 | '(
830 | ;; James's Super View
831 | ("j" "James's Super View"
832 | (
833 | (agenda ""
834 | (
835 | (org-agenda-remove-tags t)
836 | (org-agenda-span 7)
837 | )
838 | )
839 |
840 | (alltodo ""
841 | (
842 | ;; Remove tags to make the view cleaner
843 | (org-agenda-remove-tags t)
844 | (org-agenda-prefix-format " %t %s")
845 | (org-agenda-overriding-header "CURRENT STATUS")
846 |
847 | ;; Define the super agenda groups (sorts by order)
848 | (org-super-agenda-groups
849 | '(
850 | ;; Filter where tag is CRITICAL
851 | (:name "Critical Tasks"
852 | :tag "CRITICAL"
853 | :order 0
854 | )
855 | ;; Filter where TODO state is IN-PROGRESS
856 | (:name "Currently Working"
857 | :todo "IN-PROGRESS"
858 | :order 1
859 | )
860 | ;; Filter where TODO state is PLANNING
861 | (:name "Planning Next Steps"
862 | :todo "PLANNING"
863 | :order 2
864 | )
865 | ;; Filter where TODO state is BLOCKED or where the tag is obstacle
866 | (:name "Problems & Blockers"
867 | :todo "BLOCKED"
868 | :tag "obstacle"
869 | :order 3
870 | )
871 | ;; Filter where tag is @write_future_ticket
872 | (:name "Tickets to Create"
873 | :tag "@write_future_ticket"
874 | :order 4
875 | )
876 | ;; Filter where tag is @research
877 | (:name "Research Required"
878 | :tag "@research"
879 | :order 7
880 | )
881 | ;; Filter where tag is meeting and priority is A (only want TODOs from meetings)
882 | (:name "Meeting Action Items"
883 | :and (:tag "meeting" :priority "A")
884 | :order 8
885 | )
886 | ;; Filter where state is TODO and the priority is A and the tag is not meeting
887 | (:name "Other Important Items"
888 | :and (:todo "TODO" :priority "A" :not (:tag "meeting"))
889 | :order 9
890 | )
891 | ;; Filter where state is TODO and priority is B
892 | (:name "General Backlog"
893 | :and (:todo "TODO" :priority "B")
894 | :order 10
895 | )
896 | ;; Filter where the priority is C or less (supports future lower priorities)
897 | (:name "Non Critical"
898 | :priority<= "C"
899 | :order 11
900 | )
901 | ;; Filter where TODO state is VERIFYING
902 | (:name "Currently Being Verified"
903 | :todo "VERIFYING"
904 | :order 20
905 | )
906 | )
907 | )
908 | )
909 | )
910 | ))
911 | ))
912 |
913 | This is a good sampling of the different ways you can combine the filters to produce exactly what you are looking for. I would highly recommend you check out the Org Super Agenda documentation for further refinements, because it is a very slick tool.
914 |
915 |
916 |
917 |
918 | # Final Thoughts
919 |
920 | Hopefully this document has been of some use to you. Learning Org Mode has been a rewarding experience for me and I hope it is for you as well. Good luck with your journey fellow Emacs user and God speed!
921 |
922 | Oh and this entire document was written in Org Mode and exported to Markdown. Which just goes to show that if you try hard enough, you can use Emacs for just about anything.
923 |
924 |
--------------------------------------------------------------------------------
/README.org:
--------------------------------------------------------------------------------
1 | * The Beautiful Nightmare that is Org Mode
2 | This document is a walkthrough for new Org Mode users that will show how to create an initial configuration that is both productive and easy to understand. This is the guide I wish I had found when I first started learning Org Mode. I needed an explanation that tied together a user's workflow, the Org Mode features that support that workflow, a screenshot of what that looks like, and the code to make it all happen. Hopefully this guide will help you in your journey of mastering Org Mode.
3 |
4 | ** Why learning Org Mode is so hard
5 | Learning Org Mode is so challenging because its complexity easily becomes overwhelming. In learning about Org Mode I've found that it is often presented to new users as an impenetrable whole with no obvious starting point. The intro guides frequently describe basic functionality and then reference custom configurations by advanced users that are breathtaking in their scope and complexity. No path is given to go from novice to expert other than vague advice and useless platitudes. Most often you will hear variations on "just play with it until it makes sense".
6 |
7 | That sentiment is, to put it bluntly, bullshit.
8 |
9 | Other tools might have a setup wizard, sample configurations, or other tutorials to ease you into the software. However Org Mode is designed to be an open ended framework within which you the user can construct your ideal workflow. In this regards it is simpler to think of Org Mode as a programming language within Emacs. It is no wonder than adoption of this tool is so difficult. If you aren't already a programmer (one with lisp experience no less) you will find Org Mode has a brutal learning curve.
10 |
11 | ** How to use this guide
12 | If you are new to Org Mode, I would highly recommend reading the Workflows section first. Once you feel like you understand what your own needs are, then read through the various configurations. At that point, I would highly recommend putting some of that code into your own configuration file and experimenting with Org Mode. Look at how it functions and start to get a feel for what might work for you. Once you have a more solid grasp on the basics, then come back and read up on Tags and Agendas.
13 |
14 | There is a lot here and this is only a small fraction of what Org Mode is capable of. Take small steps and don't get discouraged. Good luck.
15 |
16 | * Workflows
17 | The part that everyone skips over. Org Mode was so difficult for me to learn because I started this process backwards. I started trying to use it before having any idea of what I actually wanted it to do.
18 |
19 | ** How this guide is trying to solve these problems
20 | Understanding org mode is a two fold process. The first step is developing a tentative workflow that works for you. The second step is figuring out what parts of org mode will support that workflow.
21 |
22 | This guide tries to help you discover a workflow that best suits you. Then a few common org configurations will be given to show how they can support different parts of a work flow. Finally everything will be modular so that a new user can pick and choose what they want to incorporate into their system. This is not meant to be a comprehensive list of every possible workflow or feature, but rather some common examples for new users to build on.
23 |
24 | So, let's dig into the problem.
25 |
26 | ** Understanding workflows
27 | Most websites with Org primers offer a very detailed org configuration that supports their very specific workflow. And this is great for them, but not for your average user who might only care about 10% of that particular setup. But since it is presented as one unified whole, it can be difficult to separate out which pieces you want vs which pieces will break things for you. So before we can start writing any configuration code we need to step back and ask ourselves, what should our workflow look like?
28 |
29 | I'm going to use this term "workflow" a lot in this document and to prevent any confusion, let's clearly define it now. A workflow is the sum of all the steps you take as you take to complete a task. These steps typically involve processing information, tracking your status, organizing important details, and otherwise arranging resources in a useful and coherent manner.
30 |
31 | At this point you already have existing workflows that possibly involve email clients, calendars, sticky notes, notebooks, text messages, Word documents, or anything else you use to organize your life. Org isn't a magical fix for the complexity of life, however it does make it easier to manage that complexity. Hopefully by the end of this guide you will discover a way to integrate Org Mode into your existing routines.
32 |
33 | To better illustrate workflows, here is an example from my personal life.
34 |
35 | *** Personal Workflow Example
36 | I want to track home projects such as furniture I want to build, home renovations, general handy work, and future tools to buy. The usual progression of such projects tends to look something like this:
37 |
38 | ~create project -> add details -> add notes -> research it -> start work on project -> finish project~
39 |
40 | So if I am going to build a new kitchen table I would create an entry on the project, add details like the dimensions, required seating, etc. Then do some research on styles (farm house vs modern) and on lumber (oak vs walnut prices). Finally once I had all the information I can create some steps (buy the lumber, dimension it, cut it, assemble it, dry fit, sand, stain, seal) so I can get a feel for how long this will take (many weekends) and then start working it.
41 |
42 | *** Understanding your workflow options
43 | So here we are. You want to use Org Mode to do...something. You aren't totally sure what but a lot of really smart people seem to think it is useful so you want to give it a try. And so you did what most new users do. You read the startup guide, you skim the docs, you realize you don't understand anything, and shortly thereafter you gave up in despair.
44 |
45 | But not today. Today is going to be different.
46 |
47 | So let's start off the right way by first brainstorming some ideas on how you want this whole thing to work. Initially you should focus only on establishing the simplest version of your own workflow. Go into this assuming that this is going to change and that nothing here is set in stone. Instead, treat this as a first draft that will get thrown away, redesigned, or heavily modified as you further understand what it is you really hope to get out of Org Mode. Look through the following list and see if any of these things are something you would want to integrate into your new Org Mode workflow.
48 |
49 | *Common Workflow Components*
50 | - handling emails
51 | - recording meeting notes
52 | - tracking time sensitive events
53 | - tracking reoccurring events
54 | - general to-do items
55 | - journals
56 | - work logs
57 | - prioritizing tasks
58 | - tracking your time
59 | - generating reports
60 | - outlining presentations
61 | - outlining a book
62 | - tracking JIRA tickets
63 | - tracking bugs in code
64 | - exporting documents to common formats
65 |
66 | And so on and so on.
67 |
68 | As a side note, something that took me a while to wrap my head around was that not everything has to be interconnected. So if you want to keep a journal, there is no reason that it has to be integrated into anything else. Where as you might want to keep your meetings in one file, your TODOs in another, and reference both of them in your agenda view.
69 |
70 | *** Figuring out your first workflow
71 | So at this point you should take a look at the list above (which is by no means meant to be taken as comprehensive) and decide what pieces you want to implement. I'm not going to implement every one of these examples (that would be a small book and I'm not /that/ committed to this enterprise) but I am going to implement several of the more important ones and hopefully that will serve as a foundation on which to build your own workflow.
72 |
73 | Once you figure out what you want to do, starting thinking of the simplest way that you would like to reorganize your workflow to incorporate org mode. For example, don't do this:
74 |
75 | /"what are all the steps required to interface with my email client, import my emails, tag them, create TODO's from them, and then sort them in my Agenda View..."/
76 |
77 | and instead do this:
78 |
79 | /"I want to make TODOs based on my email"/
80 |
81 | Note that the second one doesn't require any fancy configuration. Of course, this means that there are going to be a lot of manual steps, BUT THAT IS OK! So in this example, imagine that you come up with the following work flow:
82 |
83 | *New possible workflow*
84 | - open gmail in my web browser
85 | - look at my unread messages
86 | - open up emacs
87 | - create a new Email TODO
88 | - fill in all the details by copy and pasting into emacs
89 | - do this for a week
90 | - live my best life
91 |
92 | Now I get what you are thinking. This is a lot of work. This is boring. This isn't leveraging anything! Where is the magic I was promised?
93 |
94 | I feel you, I really do. But we aren't there yet. This step is all about seeing if this prototype workflow is actually going to be useful. If it is then great! You can go down the road of turning emacs into your own email sorting hub. But you might do this for a few days and realize that you really don't get that many TODOs from your email, but instead you get them from meetings and then people just email you later to confirm details. So maybe making your emails the center point of this workflow isn't what you really need.
95 |
96 | Unfortunately there is no shortcut here. You just have to try a bunch of things out and see what clicks for you. Everyone has different needs and this is most definitely not a one-size-fits-all type of solution. But the key here is to try different approaches, do it all manually so you have minimal investment (think of how frustrating it would have been to spend 10 hours configuring your mail settings only to never use it), and then refine the parts that work for you.
97 |
98 | * Configuring Capture Templates
99 | In this section you will find five different configurations that support some of the workflow elements mentioned previously. These are all similar enough to show the common design behind how Org Mode operates, while hopefully being different enough to show off some of Org's most useful features.
100 |
101 | Now we get to the heart of things. Listed below are a series of steps that should, at the very least, be read in order. Not every configuration depends on the ones before it, but many do. So while I've tried to encapsulate these as much as possible, you should still read through everything first before you begin modifying your configuration.
102 |
103 | ** Before you start
104 | So you have looked at my list, maybe picked a few pieces out you want to try, thought about how your own workflow should work and now you are ready to configure org. Ok, let's do this. First, if you have not done so, you should check out [[https://orgmode.org/quickstart.html][Org Mode Quickstart Guide]]. It's ok if you haven't memorized all of this yet, just keep that page open in your browser and reference it until things start to make more sense. Also, it is really going to help if you have some working knowledge of emacs configuration. You can muscle your way through this if this is your first time, but this is definitely not the package you want to be your introduction to Emacs.
105 |
106 | ** Default settings
107 | Listed below are some default settings that I use for Org Mode to make my life easier. You can find all of my settings in the .emacs file that is in this repo if you are curious. There are lots more that I will cover later, but for now here are some basic ones to get you started. Copy these lines into your .emacs file or where ever you keep your configurations.
108 |
109 | *Default Org Mode Settings*
110 |
111 | #+begin_src emacs-lisp
112 | ;; Setup use-package just in case everything isn't already installed
113 | (unless (package-installed-p 'use-package)
114 | (package-refresh-contents)
115 | (package-install 'use-package))
116 |
117 | ;; Enable use-package
118 | (eval-when-compile
119 | (require 'use-package))
120 | (setq use-package-always-ensure t)
121 | (use-package org
122 | :pin gnu)
123 |
124 | ;; Must do this so the agenda knows where to look for my files
125 | (setq org-agenda-files '("~/org"))
126 |
127 | ;; When a TODO is set to a done state, record a timestamp
128 | (setq org-log-done 'time)
129 |
130 | ;; Follow the links
131 | (setq org-return-follows-link t)
132 |
133 | ;; Associate all org files with org mode
134 | (add-to-list 'auto-mode-alist '("\\.org\\'" . org-mode))
135 |
136 | ;; Make the indentation look nicer
137 | (add-hook 'org-mode-hook 'org-indent-mode)
138 |
139 | ;; Remap the change priority keys to use the UP or DOWN key
140 | (define-key org-mode-map (kbd "C-c ") 'org-priority-up)
141 | (define-key org-mode-map (kbd "C-c ") 'org-priority-down)
142 |
143 | ;; Shortcuts for storing links, viewing the agenda, and starting a capture
144 | (define-key global-map "\C-cl" 'org-store-link)
145 | (define-key global-map "\C-ca" 'org-agenda)
146 | (define-key global-map "\C-cc" 'org-capture)
147 |
148 | ;; When you want to change the level of an org item, use SMR
149 | (define-key org-mode-map (kbd "C-c C-g C-r") 'org-shiftmetaright)
150 |
151 | ;; Hide the markers so you just see bold text as BOLD-TEXT and not *BOLD-TEXT*
152 | (setq org-hide-emphasis-markers t)
153 |
154 | ;; Wrap the lines in org mode so that things are easier to read
155 | (add-hook 'org-mode-hook 'visual-line-mode)
156 | #+end_src
157 |
158 | *Optional Org Mode Settings*
159 |
160 | I really like how this makes my layout look, but your mileage may vary so that's why I'm tagging this as optional.
161 |
162 | #+begin_src emacs-lisp
163 | (let* ((variable-tuple
164 | (cond ((x-list-fonts "ETBembo") '(:font "ETBembo"))
165 | ((x-list-fonts "Source Sans Pro") '(:font "Source Sans Pro"))
166 | ((x-list-fonts "Lucida Grande") '(:font "Lucida Grande"))
167 | ((x-list-fonts "Verdana") '(:font "Verdana"))
168 | ((x-family-fonts "Sans Serif") '(:family "Sans Serif"))
169 | (nil (warn "Cannot find a Sans Serif Font. Install Source Sans Pro."))))
170 | (base-font-color (face-foreground 'default nil 'default))
171 | (headline `(:inherit default :weight bold :foreground ,base-font-color)))
172 |
173 | (custom-theme-set-faces
174 | 'user
175 | `(org-level-8 ((t (,@headline ,@variable-tuple))))
176 | `(org-level-7 ((t (,@headline ,@variable-tuple))))
177 | `(org-level-6 ((t (,@headline ,@variable-tuple))))
178 | `(org-level-5 ((t (,@headline ,@variable-tuple))))
179 | `(org-level-4 ((t (,@headline ,@variable-tuple :height 1.1))))
180 | `(org-level-3 ((t (,@headline ,@variable-tuple :height 1.2))))
181 | `(org-level-2 ((t (,@headline ,@variable-tuple :height 1.3))))
182 | `(org-level-1 ((t (,@headline ,@variable-tuple :height 1.5))))
183 | `(org-document-title ((t (,@headline ,@variable-tuple :height 1.6 :underline nil))))))
184 | #+end_src
185 |
186 | Change the height multipliers to suite your own tastes. This is what works for me, but you may want them larger or smaller. Either way, put all of that into your .emacs file, relaunch emacs and let's roll.
187 |
188 | ** Packages to install
189 | I am using a variety of packages to make all of this work so here is a list if you want to install them manually:
190 | - org-super-agenda
191 | - comment-tags
192 |
193 | ** Configuration #1 - Work Log
194 | I find it very helpful to keep a daily log of what I accomplish at work. Before we get too deep into this, it is important to point out that this is not a journal. There are already tutorials and packages on how to use Org Mode as a journal. So if that is what you are actually looking for, go ahead and skip this one.
195 |
196 | In this case a journal contains daily entries that are typically several paragraphs of text while a work log is several bullet points of accomplishments with additional detail as needed.
197 |
198 | So here is what I want:
199 |
200 | ![[file:images/work-log-screenshot.png][work log screenshot]]
201 |
202 | And here is the code that needed to make this work:
203 |
204 | *** Capture Template
205 | When the capture template is initiated the capture key should be "j". I set it to "j" because I use a journal at home and I wanted to just associate the "j" key with "write a log of my thoughts" regardless of whether I'm at home or at work. But if you wanted to change this to a "w" I won't hold it against you.
206 |
207 | #+begin_src emacs-lisp
208 | (setq org-capture-templates
209 | '(
210 | ("j" "Work Log Entry"
211 | entry (file+datetree "~/org/work-log.org")
212 | "* %?"
213 | :empty-lines 0)
214 | ))
215 | #+end_src
216 |
217 | This is going to save all of my work logs into the ~work-log.org~ file using the date structure shown in the picture above. For details on how to modify that structure look up ~org-capture-templates~ in the manual.
218 |
219 | ** Configuration #2 - Simple Note
220 | This is my dumping ground for trivial pieces of information. Things like the password for the supply closet door, where I left that obscure part that I will need one day, or some important piece of trivia that I keep having to look up. There are no tags, filtering, or automatic-anything here. This is the most basic Org Mode example I can think of and I'm including it here mainly for reference.
221 |
222 | ![[file:images/random-notes-screenshot.png][random notes screenshot]]
223 |
224 | Here is the capture template:
225 |
226 | *** Capture Template
227 | If you wanted to use this along with the work log capture template from above, then you would only need to copy in the small subsection, not the entire chunk starting with ~(setq org-capture...~ in case that was not clear. Otherwise, here is the template for a basic note.
228 |
229 | #+begin_src emacs-lisp
230 | (setq org-capture-templates
231 | '(
232 | ("n" "Note"
233 | entry (file+headline "~/org/notes.org" "Random Notes")
234 | "** %?"
235 | :empty-lines 0)
236 | ))
237 | #+end_src
238 |
239 | No date structure needed here, just a long list of random notes. If you wanted to use the same file but add another heading called "Door Codes" you could then configure another capture template like so:
240 |
241 | #+begin_src emacs-lisp
242 | (setq org-capture-templates
243 | '(
244 | ("n" "Note"
245 | entry (file+headline "~/org/notes.org" "Random Notes")
246 | "** %?"
247 | :empty-lines 0)
248 |
249 | ("d" "Door Codes"
250 | entry (file+headline "~/org/notes.org" "Door Codes")
251 | "** %?"
252 | :empty-lines 0)
253 | ))
254 | #+end_src
255 |
256 | And then all of the notes captured from that would go into that heading.
257 |
258 | ** Configuration #3 - General TODO
259 | Now we are getting to the heart of what makes Org Mode so amazing, the ability to track TODO items! To fully explore this feature is going to require several configurations, however I am going to start off with a simple "General To-Do" item and then layer more functionality onto it in later steps. In the Agenda section we will review how to organize all of our TODOs, but right now we are focusing on simply creating them.
260 |
261 | ![[file:images/general-tasks-screenshot.png][general tasks screenshot]]
262 |
263 | We are going to look at one TODO in particular.
264 |
265 | #+begin_src
266 | * OBE [#B] Talk to Mike and ask about broken restores
267 | CLOSED: [2021-11-15 Mon 13:09]
268 | - State "OBE" from "IN-PROGRESS" [2021-11-15 Mon 13:09]
269 | - State "IN-PROGRESS" from "TODO" [2021-11-09 Tue 15:13] \\
270 | Wrapping this into CCRS-4453.
271 |
272 | Namely, what do do when a restore fails. Do we just leave it in whatever state it is in?
273 |
274 | #+end_src
275 |
276 | There is a lot going on here so I'm going to break it down in the various components. Here is what this TODO is comprised of:
277 |
278 | #+begin_src
279 | * STATE [#PRIORITY] TITLE
280 | - STATE CHANGE 2 TIMESTAMP
281 | - STATE CHANGE 1 TIMESTAMP
282 | NOTE ABOUT STAGE CHANGE 1
283 |
284 | NOTE ABOUT TODO
285 | #+end_src
286 |
287 | *** Components of the TODO Item
288 | Let's look at each piece one at a time.
289 |
290 | *STATE*
291 | In this TODO it is set to ~OBE~ (overcome by events). Other TODOs are set to ~DONE~, ~TODO~, or ~IN-PROGRESS~. We will setup these states in just a minute, but for the moment all you need to know is that each TODO can cycle through several states.
292 |
293 | *PRIORITY*
294 | Each TODO can have a priority. You can create your own set of priorities such as [DEFCON 1, TROUBLE, MILDLY-BAD,SAFELY-IGNORE] but the defaults of [A,B,C] work just fine and it is what we will be using here. In this case ~A~ is the highest priority and ~C~ is the lowest. Don't worry too much about this yet, this will make more sense once we get to the agenda view.
295 |
296 | *TITLE*
297 | This is the name of your TODO that is entered from the capture menu.
298 |
299 | *STATE CHANGE 2*
300 | The latest state change. As we see it went from ~IN-PROGRESS~ to ~OBE~ and a timestamp was recorded when this occurred.
301 |
302 | *STATE CHANGE 1*
303 | The initial state change. The TODO went from in the ~TODO~ state to ~IN-PROGRESS~ and a timestamp was recorded when this occurred too.
304 |
305 | *STAGE CHANGE 1 NOTE*
306 | When work was started on this TODO and the state changed, a note was added as a form of documentation.
307 |
308 | *NOTE*
309 | And here is where all the details go. This could be much more involved, but for this example it was reduced to a single line.
310 |
311 | *** Explanation of the TODO Workflow
312 | The general idea behind all of this is to capture a TODO item, assign it a priority, and save a detailed description of what needs to be done. Once that is recorded we can revisit this TODO at a later date and begin working on it. Once work has begun the state changes to ~IN-PROGRESS~. When that happens the user is prompted to write a small note (this is not required, you could leave it blank) and a timestamp is recorded of when the state change happened. Finally, once the work has been completed, the note can be set to a done state. In these examples the done states are ~DONE~, ~OBE~, and ~WONT-DO~. But we are getting ahead of ourselves. First let's look at how this was accomplished.
313 |
314 | *** Capture Template
315 | A general TODO item is captured with a ~g~ from the capture template buffer. All of the TODOs are saved to the ~todos.org~ file under the ~General Tasks~ heading. You can see that the initial state is set to ~TODO~ and the initial priority is set to ~B~. Along with all of this I've added an additional field called ~Created:~ which adds a timestamp for when this TODO was created. We can filter on that later, but it is simply an optional piece of meta data that you might want to include.
316 |
317 | #+begin_src emacs-lisp
318 | (setq org-capture-templates
319 | '(
320 | ("g" "General To-Do"
321 | entry (file+headline "~/org/todos.org" "General Tasks")
322 | "* TODO [#B] %?\n:Created: %T\n "
323 | :empty-lines 0)
324 | ))
325 | #+end_src
326 |
327 | *** Org States
328 | By default Org only sets up two states, ~TODO~ and ~DONE~, which by and large isn't very useful. There are so many more nuances we could capture! In fact, we shall do so now. Here are the states I've setup for my workflow (and remember I'm a programmer, not all of these will apply to you) that I find very handy.
329 |
330 | #+begin_src emacs-lisp
331 | ;; TODO states
332 | (setq org-todo-keywords
333 | '((sequence "TODO(t)" "PLANNING(p)" "IN-PROGRESS(i@/!)" "VERIFYING(v!)" "BLOCKED(b@)" "|" "DONE(d!)" "OBE(o@!)" "WONT-DO(w@/!)" )
334 | ))
335 | #+end_src
336 |
337 | So as you can see here I've got eight different states setup. Five of these states are active states with the final three being inactive. The idea behind this is that a task is created, work is begun, and finally it concludes. Along the way the work could require verification (possibly from someone else) or be blocked completely. Eventually it will reach an end state and become inactive. Ideally the task will have been successfully completed and we can mark it as ~DONE~ but it may be that in the course of working this it no longer becomes a priority. At which point it can be marked ~OBE~. Finally, it is possible that after further review, you decide you don't want to work on this. Maybe it no longer matters, it is someone else's job, or you just changed your mind. Either way, you never want to just delete something because you always want a log of what you've been working on. Thus it gets set to ~WONT-DO~.
338 |
339 | If you are curious about the extra characters in the parens then you can look in the documentation for the exact details as well as other configuration options. But the short version is that they signify to Org which key to use for shortcuts, some prompt the user for a note, and some record a timestamp. In this example, when you set it to ~IN-PROGRESS~ it prompts you to record a note and then records a timestamp. As it is possible that when you start a new task you want to record some initial thought however setting it to the ~VERIFYING~ state does not because it is assumed no note is required. Likewise when you set it to ~DONE~ it just records a timestamp, but setting it to ~OBE~ or ~WONT-DO~ requires a note because you should explain why you aren't going to complete this task.
340 |
341 | Finally, if you have been following along, editing your own config file to match my changes, you might start to notice some differences. Your files look flat and my examples all look nice and sexy. What is going on? Well I've decided to add some color to my life to improve my Org experience. Don't worry, you can easily spice things up by telling Org that you want to set custom colors for your TODO states. Simply add this in to your config and tweak the colors as needed:
342 |
343 | #+begin_src emacs-lisp
344 | ;; TODO colors
345 | (setq org-todo-keyword-faces
346 | '(
347 | ("TODO" . (:foreground "GoldenRod" :weight bold))
348 | ("PLANNING" . (:foreground "DeepPink" :weight bold))
349 | ("IN-PROGRESS" . (:foreground "Cyan" :weight bold))
350 | ("VERIFYING" . (:foreground "DarkOrange" :weight bold))
351 | ("BLOCKED" . (:foreground "Red" :weight bold))
352 | ("DONE" . (:foreground "LimeGreen" :weight bold))
353 | ("OBE" . (:foreground "LimeGreen" :weight bold))
354 | ("WONT-DO" . (:foreground "LimeGreen" :weight bold))
355 | ))
356 | #+end_src
357 |
358 | That is it for TODOs. Save your config, reload, and test everything out. Tweak things until you like the colors and such. Now that we've gotten all the easy stuff out of the way, let's move on to more complex things.
359 | ** Configuration #4 - Programmer TODO
360 | I'm including this as a separate section because I don't want to confuse people who came here looking for help but aren't themselves programmers. I was going to include this in the previous section but I felt that had already grown too long as it is. With that in mind, here are some features that really only other programmers will care about.
361 |
362 | *** Tracking Bugs
363 | As a programmer I do all my development in Emacs. Regardless of the language, I have it open at all times. And so there are plenty of times that I will be scanning through some source code and see something that I want to fix. If it is relatively trivial I will just leave a comment in the code with a note saying someone should come back and fix this in the future. However, frequently I'll see something that is considerably more involved. Maybe I just found an edge case that wasn't previously being handled or some tricky chunk of code that I just spent 20 min figuring out and I don't want to have to go through all of that again in 3 months when I finally get a chance to refactor it. It is in cases like this where it is extremely handy to capture the location of the bug and store it inside my TODO item. Here is what I mean.
364 |
365 | *** Capture Template
366 | A code specific TODO
367 |
368 | #+begin_src emacs-lisp
369 | (setq org-capture-templates
370 | '(
371 | ("c" "Code To-Do"
372 | entry (file+headline "~/org/todos.org" "Code Related Tasks")
373 | "* TODO [#B] %?\n:Created: %T\n%i\n%a\nProposed Solution: "
374 | :empty-lines 0)
375 | ))
376 | #+end_src
377 |
378 | This capture must be executed on the line of code you want to link to. When you create a code TODO you are generating a new TODO item, but you are also linking that TODO to that specific line of code. You can then easily visit that link to see what exactly you were referencing.
379 |
380 | Of course you could do this with any text file, not just code. If you were writing a book and wanted to mark a particular passage that you wanted to come back to later and rewrite, this would do nicely for you.
381 |
382 | ** Configuration #5 - Meetings
383 | There are two distinct parts to capturing meeting data. There is the "scheduling/tracking/people" side of it and there is the "note taking/action item/what next" side of it.
384 |
385 | For the first part, the planning and all that, I just use Microsoft's Outlook. Now I hate Outlook, but everyone uses it. They schedule meetings through it, I get email reminders through it, I get system notifications of upcoming meetings through it, and then when we do the meeting, it gives me the Teams link to join. That functionality already exists, everyone in my company uses it, and so for our purposes here, there is no need to try and replicate that. Just let Microsoft win this round and move on.
386 |
387 | However the second part, that is something that Org excels at. Org supports adding a ~DEADLINE~ or a ~SCHEDULED~ tag that has some interesting use cases, however I have not found these features very useful in my own workflows. I rarely schedule meetings in advance so those features don't really help me. Instead I have several meetings a day from coworkers who need to talk about something for 20 min or a manager who wants to discuss a possible change in direction. These meetings frequently contain very useful information as well as action items that I need to accomplish. So, to fill that need I've created a capture template that combines TODOs and tags to ensure that my meetings are always properly recorded.
388 |
389 | Shown below is an overview of a portion of my meetings. They have been automatically organized by week and minimized for easier reading. I personally prefer them grouped by week since it makes it easier for me to read though past meetings.
390 |
391 | ![[file:images/meetings-by-week-screenshot.png][high level look at meetings]]
392 |
393 | Here I have expanded the view one level deep. Now you can see the title of each meeting held on each day. The colored words are tags, but that will be discussed below.
394 |
395 | ![[file:images/meetings-by-day-overview-screenshot.png][meetings by day]]
396 |
397 | Finally we see all the details of Thursday's meetings. Lots to unpack here. There is a ~LOGBOOK~ of meta data, timestamp of creation, a ~CLOCK~ value showing the total time the meeting took, who attended, notes, and Action Items! Lots to unpack.
398 |
399 | ![[file:images/meeting-details-screenshot.png][meeting details]]
400 |
401 | But as always, let's start with the capture template.
402 |
403 | *** Capture Template
404 | #+begin_src emacs-lisp
405 | (setq org-capture-templates
406 | '(
407 | ("m" "Meeting"
408 | entry (file+datetree "~/org/meetings.org")
409 | "* %? :meeting:%^g \n:Created: %T\n** Attendees\n*** \n** Notes\n** Action Items\n*** TODO [#A] "
410 | :tree-type week
411 | :clock-in t
412 | :clock-resume t
413 | :empty-lines 0)
414 | ))
415 | #+end_src
416 |
417 | Clearly this capture template is the most complex yet, so let's go line by line and see what is happening. The ~entry~ value sets up how the structure of the file will be saved. The next line describes the template for how the meeting will be recorded. It also contains some predefined Org special characters such as ~%T~ which will give us a timestamp. This line also contains a tag called ~:meeting:~ (which we will use later) as well as a subsection called ~Action Items~ which is prepopulated with an empty TODO.
418 |
419 | This is what you should see when you start the capture template and hit "m". In the mini buffer you will see the option to add additional tags. You don't have to add any tags and you can always add more tags later, but this is where you would add some initially.
420 |
421 | ![[file:images/meeting-capture-screenshot.png][capturing a meeting]]
422 |
423 | In this example I decided to add another tag called ~:james~ since this meeting is all about me. After I select that tag and hit return, I get something like this:
424 |
425 | ![[file:images/meeting-with-tags-screenshot.png][ready to fill out a meeting]]
426 |
427 | This looks a little bit more promising. The empty space beside the ~*~ is for the title of this meeting. There are two tags (~meeting~ and ~james~), a ~LOGBOOK~ entry (which is used for clocking time), a custom piece of metadata called ~:Created:~ (more on that in the Agenda section), a list for attendees, notes, and finally action items. So the meeting has started, you've activated your meeting capture template, and now you are filling in data. I've taken the liberty of filling out my own meeting so you can see what it would look like.
428 |
429 | ![[file:images/meeting-in-progress-screenshot.png][a meeting in progress]]
430 |
431 | When the capture is over and everything gets saved to the file, you can revisit the meeting and see that length of the meeting was recorded. The clock started as soon as the meeting capture template was activated and ended when you closed it out. Now you can go back and review past meetings and see how much time your coworkers have stolen from you.
432 |
433 | A key takeaway from all of this is that tags are applied at the base level of this meeting and that everything that is part of that meeting inherits those tags. So the TODO item I made inherits the tags ~:meeting:~ as well as ~:james:~. If I wanted to add an addition tag to one of the TODOs under ~Action Items~ then that TODO would have 3 tags while the meeting would only have 2. Speaking of tags, I should probably explain that next.
434 |
435 | *** Clock Reports
436 | One very useful aspect of Org Mode is the ability to clock in and out of tasks to track time. In the capture template for a meeting the clock-in value has been set to true which starts the clock when the meeting is created and ends when the capture template is closed and the meeting is presumably over. This metadata is saved in the ~:LOGBOOK:~ section of the meeting. Having this data allows us to track our time visually using two commands, ~org-clock-report~ and ~org-clock-display~.
437 |
438 | **** Clock Report
439 | A clock report gets generated with ~org-clock-report~ and inserted into your file. This value is not dynamic but rather is set when the command is executed. This is useful for viewing metrics of past events as it allows you to easily summarize the time spent in meetings. This feature of Org Mode is useful when you require more concrete metrics on how your time is spent. Perhaps you need to track time for billing or time allocation for a project. If so, this feature can make your life much easier. Here is an example of a clock report for three weeks of my meetings.
440 |
441 | ![[file:images/meetings-clock-report-screenshot.png][clock report]]
442 |
443 | **** Clock Display
444 | A clock display is just an overlay for quickly viewing how much time has been spent on various entries and can be viewed by executing ~org-clock-display~. It looks like this:
445 |
446 | ![[file:images/meeting-clock-time-overview-screenshot.png][clock overview]]
447 |
448 | And with more details:
449 |
450 | ![[file:images/meeting-detailed-clock-screenshot.png][detailed clock view]]
451 |
452 | This is a quick and easy way to keep track of how much time is being spent on various meetings.
453 |
454 | * Tags
455 | Before moving on to the Agenda I need to take a moment and explain tags. I've mentioned them several times previously but now I need to go into more depth on how to set them up and use them. You don't want to create too many tags or you won't use them effectively. You don't want too few or else you won't get the full impact of their use in your Agenda. Here are some general guidelines I've found for using tags effectively.
456 |
457 | ** Create groups of tags
458 | Creating groups of tags that make sense. For example, if you are keeping track of what chores each person in your household needs to accomplish in a week, make a tag for each person's name. If you are keeping track of recipes, make a tag for type of dish, i.e. German, French, Vietnamese, etc.
459 |
460 | Additionally you can create exclusive groups where only one tag from the group can be used at a time. To keep with our recipe example, your group could contain (breakfast, meal, dessert, drink). Which would indicate that the recipe in question must be one, and only one, of those tags. The tag does not have to be used, but if it is used, only one can be used at a time.
461 |
462 | ** Start small
463 | It is better to start with a small selection of tags and expand as you go, rather than start with 20 tags and then try to see what you don't need. Start with broad groups and see where natural subdivisions occur. Also remember that this isn't tagging for the sake of tagging. You want to eventually filter on these tags or search for them in some manner. So if you aren't ever planning on using a tag, then there is no point in creating one.
464 |
465 | Beating this food analogy to death, you could create tags like ~:requires_open_flame:~ but if you never plan on needing to filter recipes that require flambe, then what is the point?
466 |
467 | ** Multiple tags are better than a super descriptive tag
468 | Think of ways of combining tags to make a descriptive notation rather than relying on overly specific tags that will eventually be too constraining. If you are creating TODOs based on incoming emails, don't use a tag called ~:future_project_with_kevin:~ but instead do ~:future_project:kevin:~. I'm sorry if that sounds obvious, but when you are first starting out with Org Mode you can find yourself slipping into bad habits because you aren't sure yet what you need and the instinct can be to just throw everything against the wall and see what sticks.
469 |
470 | ** Defining tags
471 | Here are the tags I'm using for the workflow examples in this document.
472 |
473 | #+begin_src emacs-lisp
474 | ;; Tags
475 | (setq org-tag-alist '(
476 | ;; Ticket types
477 | (:startgroup . nil)
478 | ("@bug" . ?b)
479 | ("@feature" . ?u)
480 | ("@spike" . ?j)
481 | (:endgroup . nil)
482 |
483 | ;; Ticket flags
484 | ("@write_future_ticket" . ?w)
485 | ("@emergency" . ?e)
486 | ("@research" . ?r)
487 |
488 | ;; Meeting types
489 | (:startgroup . nil)
490 | ("big_sprint_review" . ?i)
491 | ("cents_sprint_retro" . ?n)
492 | ("dsu" . ?d)
493 | ("grooming" . ?g)
494 | ("sprint_retro" . ?s)
495 | (:endgroup . nil)
496 |
497 | ;; Code TODOs tags
498 | ("QA" . ?q)
499 | ("backend" . ?k)
500 | ("broken_code" . ?c)
501 | ("frontend" . ?f)
502 |
503 | ;; Special tags
504 | ("CRITICAL" . ?x)
505 | ("obstacle" . ?o)
506 |
507 | ;; Meeting tags
508 | ("HR" . ?h)
509 | ("general" . ?l)
510 | ("meeting" . ?m)
511 | ("misc" . ?z)
512 | ("planning" . ?p)
513 |
514 | ;; Work Log Tags
515 | ("accomplishment" . ?a)
516 | ))
517 | #+end_src
518 |
519 | Note that the Ticket Types and the Meeting Types are both exclusive groups. A ticket can be a bug or a feature or a spike. Likewise a meeting can only have one major type. However, the rest of the tags can be combined as needed. Generally I've broken the tags into two categories, those that go on TODO items and those that do not. So a meeting might get tagged with ~:meeting:backend:~ because I'm having a meeting about the backend, however within that meeting I might create a TODO with the tag ~:CRITICAL:@bug:~ because I've just found a critical bug that needs to be fixed right away. Also the "@" you see in the tags has no special Org related significance, that is strictly something for me.
520 |
521 | ** Colorizing tags
522 | If it is worth doing it is worth making it pretty. That is one of my odder mottoes to be sure, nonetheless we are going to make our tags sexy!
523 |
524 | #+begin_src emacs-lisp
525 | ;; Tag colors
526 | (setq org-tag-faces
527 | '(
528 | ("planning" . (:foreground "mediumPurple1" :weight bold))
529 | ("backend" . (:foreground "royalblue1" :weight bold))
530 | ("frontend" . (:foreground "forest green" :weight bold))
531 | ("QA" . (:foreground "sienna" :weight bold))
532 | ("meeting" . (:foreground "yellow1" :weight bold))
533 | ("CRITICAL" . (:foreground "red1" :weight bold))
534 | )
535 | )
536 | #+end_src
537 |
538 | Doing this allows our tags to take on different colors and weights. In my opinion this is one of the most useful enhancements I have made to my setup. I find that colorful tags really helps me take in info at a glance and otherwise makes drab TODOs much more interesting.
539 | * Basic Agenda Usage
540 | Before we go down this rabbit hole, and make no mistake this is a rabbit hole like no other, you should be aware that strictly speaking you don't /need/ to use the Agenda view. Oh it will make your life much easier (eventually) but if you don't use it right away, that's perfectly ok. Learning all of this can be quite overwhelming and there is no shame in coming back to this once you are ready.
541 |
542 | Having said all that, let's dig into the core pieces of the Agenda View. At its simplest you will use the Agenda for two primary things, to view items with timestamps in the date view and to view TODO items in the tasking view. Everything else, all the other features, filters, enhancements, etc. are all just sitting on top of those two core pieces. Here are some examples to show you what I mean.
543 |
544 | ** Agenda Weekly View
545 | Here is the basic view you get when you invoke the Agenda view with ~C-c a~ and then hit ~a~ for the very first option in the list, the Agenda for current week or day.
546 |
547 | ![[file:images/agenda-basic-screenshot.png][basic agenda view for the week]]
548 |
549 | You can see that I had a bunch of meetings that week. As a side note, those meetings and TODOs are only showing up in this view because each of them have a timestamp in the ~:Created:~ field. Go back and look at Configuration #5 if you missed it. But it is important to remember that only things with timestamps show up here. I could have used the deadline or scheduled fields and that would have worked too. But that is something that can trip you up, so keep that in mind.
550 |
551 | You will notice that each entry has a label to the left of it. That is the file that the entry was found in. That can be replaced with the category name if set, but since I didn't bother with that, it just defaulted to the file name. On the far right you will see some tags, they will be useful later. Now let's take a look at the TODOs view.
552 |
553 | ** Agenda TODO View
554 | When selecting the ~List all TODO entries~ filter in the Agenda you get something like this:
555 |
556 | ![[file:images/agenda-todo-view-screenshot.png][a view of the TODOs]]
557 |
558 | Where you can clearly see all of the TODOs, ordered by priority then by file (or category). A lot of these TODOs contain tags with many containing multiple tags. The default view tries to organize things for us, but with lots of TODOs it is a bit difficult to read. There is a lot of information here to process. At a glance you have the following pieces of data being displayed:
559 |
560 | - the file the TODO came from (meetings, todos, or tickets)
561 | - the state of the TODO (~TODO~, ~IN-PROGRESS~, ~PLANNING~, ~VERIFYING~, or ~BLOCKED~)
562 | - the priority (~A~, ~B~, or ~C~)
563 | - the title of the TODO
564 | - any tags associated with it (planning, backend, or CRITICAL among others)
565 |
566 | So clearly there is a lot going on here. And while you can filter this view in a variety of ways (look it up in the manual, there is too much to discuss here) to help in managing this complexity, it can still be a bit overwhelming. Let's try to make this a bit more readable.
567 |
568 | * Enhanced Agenda #1
569 | This next view is a modified version of one that I copied from [[https://github.com/aaronbieber/dotfiles/blob/master/configs/emacs.d/lisp/init-org.el][Aaron Bieber]]. I honestly don't recall how I ended up looking at his github config files, but he has some good stuff and I would encourage you to look at his setup at some point. Aaron, if you ever stumble across this, you rock. Thanks for the inspiration. Here is what my version looks like:
570 |
571 | ** Agenda Enhanced View
572 |
573 | ![[file:images/enhanced-agenda-view-screenshot.png][enhanced agenda view]]
574 |
575 | So right away we notice that this is much easier to read. Our highest priority items are at the top, the weekly Agenda view has been incorporated as well, and over all this makes for a much more readable experience. Let's look at the code that supports this.
576 |
577 | ** Agenda Custom Command
578 | To add this view there are a couple of pieces required.
579 |
580 | #+begin_src emacs-lisp
581 | ;; Agenda View "d"
582 | (defun air-org-skip-subtree-if-priority (priority)
583 | "Skip an agenda subtree if it has a priority of PRIORITY.
584 |
585 | PRIORITY may be one of the characters ?A, ?B, or ?C."
586 | (let ((subtree-end (save-excursion (org-end-of-subtree t)))
587 | (pri-value (* 1000 (- org-lowest-priority priority)))
588 | (pri-current (org-get-priority (thing-at-point 'line t))))
589 | (if (= pri-value pri-current)
590 | subtree-end
591 | nil)))
592 |
593 | (setq org-agenda-skip-deadline-if-done t)
594 |
595 | (setq org-agenda-custom-commands
596 | '(
597 | ;; Daily Agenda & TODOs
598 | ("d" "Daily agenda and all TODOs"
599 |
600 | ;; Display items with priority A
601 | ((tags "PRIORITY=\"A\""
602 | ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
603 | (org-agenda-overriding-header "High-priority unfinished tasks:")))
604 |
605 | ;; View 7 days in the calendar view
606 | (agenda "" ((org-agenda-span 7)))
607 |
608 | ;; Display items with priority B (really it is view all items minus A & C)
609 | (alltodo ""
610 | ((org-agenda-skip-function '(or (air-org-skip-subtree-if-priority ?A)
611 | (air-org-skip-subtree-if-priority ?C)
612 | (org-agenda-skip-if nil '(scheduled deadline))))
613 | (org-agenda-overriding-header "ALL normal priority tasks:")))
614 |
615 | ;; Display items with pirority C
616 | (tags "PRIORITY=\"C\""
617 | ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
618 | (org-agenda-overriding-header "Low-priority Unfinished tasks:")))
619 | )
620 |
621 | ;; Don't compress things (change to suite your tastes)
622 | ((org-agenda-compact-blocks nil)))
623 | ))
624 | #+end_src
625 |
626 | Now when you bring up the Agenda selection dialog you should see the ~Daily agenda and all TODOs~ option that can be selected with ~d~. This is a much better option than the default view and was my go-to view for a long while. However, it is still really busy and it can be difficult to find certain items as they can be buried if your list grows too long. So let's look at another solution.
627 | * Enhanced Agenda #2
628 | For this next Agenda configuration I'm using a packaged called [[https://github.com/alphapapa/org-super-agenda][Org Super Agenda]]. If you are new to Org Mode, this is definitely overkill. So there is no shame in slowly backing away from this one if you feel you aren't ready yet. However, once you feel like you want to expand your setup beyond the defaults, this is an awesome package to try out. Let's take a look at what my previous view would look like with the Super Agenda.
629 |
630 | ![[file:images/agenda-super-view-screenshot.png][agenda super view]]
631 |
632 | Well this is wild, isn't it? Things are sorted into logical groups, there aren't tags cluttering everything up, and the grouping seems more logical than just filtering by priority. What sorcery is this, you say? Well this is what the Super Agenda gives you. Read more at the link above to get the full documentation, but the gist is that you setup filters and then the super agenda applies them to your TODO items in the order you defined the filters. So in my case I set this up to filter all the critical tasks into the first bucket. If one of those critical tasks also matched a later filter (like say it required additional research or was a blocker) it would still only show up in the first bucket. Since that first bucket takes priority. If I removed the ~:CRITICAL:~ tag then it would filter down into a lower bucket. At the end it will display all the TODOs that don't have a filter. If there is a filter with no TODOs matching its criteria, then it just doesn't display it. So you aren't seeing my "Movies to Watch" bucket because I'm all caught up on my preferred cinema at the moment. But as soon as Marvel releases another movie, that bucket with appear. Sounds easy right? Well...actually yeah, it is pretty straight forward once you see how it is done. Let's look at my configuration file.
633 |
634 | ** Agenda Custom Command
635 | Here are the pieces you will need for this:
636 |
637 | #+begin_src emacs-lisp
638 | (setq org-agenda-custom-commands
639 | '(
640 | ;; James's Super View
641 | ("j" "James's Super View"
642 | (
643 | (agenda ""
644 | (
645 | (org-agenda-remove-tags t)
646 | (org-agenda-span 7)
647 | )
648 | )
649 |
650 | (alltodo ""
651 | (
652 | ;; Remove tags to make the view cleaner
653 | (org-agenda-remove-tags t)
654 | (org-agenda-prefix-format " %t %s")
655 | (org-agenda-overriding-header "CURRENT STATUS")
656 |
657 | ;; Define the super agenda groups (sorts by order)
658 | (org-super-agenda-groups
659 | '(
660 | ;; Filter where tag is CRITICAL
661 | (:name "Critical Tasks"
662 | :tag "CRITICAL"
663 | :order 0
664 | )
665 | ;; Filter where TODO state is IN-PROGRESS
666 | (:name "Currently Working"
667 | :todo "IN-PROGRESS"
668 | :order 1
669 | )
670 | ;; Filter where TODO state is PLANNING
671 | (:name "Planning Next Steps"
672 | :todo "PLANNING"
673 | :order 2
674 | )
675 | ;; Filter where TODO state is BLOCKED or where the tag is obstacle
676 | (:name "Problems & Blockers"
677 | :todo "BLOCKED"
678 | :tag "obstacle"
679 | :order 3
680 | )
681 | ;; Filter where tag is @write_future_ticket
682 | (:name "Tickets to Create"
683 | :tag "@write_future_ticket"
684 | :order 4
685 | )
686 | ;; Filter where tag is @research
687 | (:name "Research Required"
688 | :tag "@research"
689 | :order 7
690 | )
691 | ;; Filter where tag is meeting and priority is A (only want TODOs from meetings)
692 | (:name "Meeting Action Items"
693 | :and (:tag "meeting" :priority "A")
694 | :order 8
695 | )
696 | ;; Filter where state is TODO and the priority is A and the tag is not meeting
697 | (:name "Other Important Items"
698 | :and (:todo "TODO" :priority "A" :not (:tag "meeting"))
699 | :order 9
700 | )
701 | ;; Filter where state is TODO and priority is B
702 | (:name "General Backlog"
703 | :and (:todo "TODO" :priority "B")
704 | :order 10
705 | )
706 | ;; Filter where the priority is C or less (supports future lower priorities)
707 | (:name "Non Critical"
708 | :priority<= "C"
709 | :order 11
710 | )
711 | ;; Filter where TODO state is VERIFYING
712 | (:name "Currently Being Verified"
713 | :todo "VERIFYING"
714 | :order 20
715 | )
716 | )
717 | )
718 | )
719 | )
720 | ))
721 | ))
722 | #+end_src
723 |
724 | This is a good sampling of the different ways you can combine the filters to produce exactly what you are looking for. I would highly recommend you check out the Org Super Agenda documentation for further refinements, because it is a very slick tool.
725 | * Final Thoughts
726 | Hopefully this document has been of some use to you. Learning Org Mode has been a rewarding experience for me and I hope it is for you as well. Good luck with your journey fellow Emacs user and God speed!
727 |
728 | Oh and this entire document was written in Org Mode and exported to Markdown. Which just goes to show that if you try hard enough, you can use Emacs for just about anything.
729 |
730 |
--------------------------------------------------------------------------------
/images/agenda-basic-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/james-stoup/emacs-org-mode-tutorial/01fcb6d4cc2aa09ad901815cf091fc37bdc543e9/images/agenda-basic-screenshot.png
--------------------------------------------------------------------------------
/images/agenda-super-view-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/james-stoup/emacs-org-mode-tutorial/01fcb6d4cc2aa09ad901815cf091fc37bdc543e9/images/agenda-super-view-screenshot.png
--------------------------------------------------------------------------------
/images/agenda-todo-view-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/james-stoup/emacs-org-mode-tutorial/01fcb6d4cc2aa09ad901815cf091fc37bdc543e9/images/agenda-todo-view-screenshot.png
--------------------------------------------------------------------------------
/images/enhanced-agenda-view-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/james-stoup/emacs-org-mode-tutorial/01fcb6d4cc2aa09ad901815cf091fc37bdc543e9/images/enhanced-agenda-view-screenshot.png
--------------------------------------------------------------------------------
/images/general-tasks-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/james-stoup/emacs-org-mode-tutorial/01fcb6d4cc2aa09ad901815cf091fc37bdc543e9/images/general-tasks-screenshot.png
--------------------------------------------------------------------------------
/images/meeting-capture-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/james-stoup/emacs-org-mode-tutorial/01fcb6d4cc2aa09ad901815cf091fc37bdc543e9/images/meeting-capture-screenshot.png
--------------------------------------------------------------------------------
/images/meeting-clock-time-overview-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/james-stoup/emacs-org-mode-tutorial/01fcb6d4cc2aa09ad901815cf091fc37bdc543e9/images/meeting-clock-time-overview-screenshot.png
--------------------------------------------------------------------------------
/images/meeting-detailed-clock-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/james-stoup/emacs-org-mode-tutorial/01fcb6d4cc2aa09ad901815cf091fc37bdc543e9/images/meeting-detailed-clock-screenshot.png
--------------------------------------------------------------------------------
/images/meeting-details-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/james-stoup/emacs-org-mode-tutorial/01fcb6d4cc2aa09ad901815cf091fc37bdc543e9/images/meeting-details-screenshot.png
--------------------------------------------------------------------------------
/images/meeting-in-progress-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/james-stoup/emacs-org-mode-tutorial/01fcb6d4cc2aa09ad901815cf091fc37bdc543e9/images/meeting-in-progress-screenshot.png
--------------------------------------------------------------------------------
/images/meeting-with-tags-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/james-stoup/emacs-org-mode-tutorial/01fcb6d4cc2aa09ad901815cf091fc37bdc543e9/images/meeting-with-tags-screenshot.png
--------------------------------------------------------------------------------
/images/meetings-by-day-overview-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/james-stoup/emacs-org-mode-tutorial/01fcb6d4cc2aa09ad901815cf091fc37bdc543e9/images/meetings-by-day-overview-screenshot.png
--------------------------------------------------------------------------------
/images/meetings-by-week-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/james-stoup/emacs-org-mode-tutorial/01fcb6d4cc2aa09ad901815cf091fc37bdc543e9/images/meetings-by-week-screenshot.png
--------------------------------------------------------------------------------
/images/meetings-clock-report-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/james-stoup/emacs-org-mode-tutorial/01fcb6d4cc2aa09ad901815cf091fc37bdc543e9/images/meetings-clock-report-screenshot.png
--------------------------------------------------------------------------------
/images/random-notes-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/james-stoup/emacs-org-mode-tutorial/01fcb6d4cc2aa09ad901815cf091fc37bdc543e9/images/random-notes-screenshot.png
--------------------------------------------------------------------------------
/images/work-log-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/james-stoup/emacs-org-mode-tutorial/01fcb6d4cc2aa09ad901815cf091fc37bdc543e9/images/work-log-screenshot.png
--------------------------------------------------------------------------------
/org-mode-config.el:
--------------------------------------------------------------------------------
1 | (unless (package-installed-p 'use-package)
2 | (package-refresh-contents)
3 | (package-install 'use-package))
4 |
5 | ;; Enable use-package
6 | (eval-when-compile
7 | (require 'use-package))
8 |
9 | (setq use-package-always-ensure t)
10 |
11 | (use-package org
12 | :pin gnu)
13 |
14 | ;; Must do this so the agenda knows where to look for my files
15 | (setq org-agenda-files '("~/org"))
16 |
17 | ;; When a TODO is set to a done state, record a timestamp
18 | (setq org-log-done 'time)
19 |
20 | ;; Follow the links
21 | (setq org-return-follows-link t)
22 |
23 | ;; Associate all org files with org mode
24 | (add-to-list 'auto-mode-alist '("\\.org\\'" . org-mode))
25 |
26 | ;; Make the indentation look nicer
27 | (add-hook 'org-mode-hook 'org-indent-mode)
28 |
29 | ;; Remap the change priority keys to use the UP or DOWN key
30 | (define-key org-mode-map (kbd "C-c ") 'org-priority-up)
31 | (define-key org-mode-map (kbd "C-c ") 'org-priority-down)
32 |
33 | ;; Shortcuts for storing links, viewing the agenda, and starting a capture
34 | (define-key global-map "\C-cl" 'org-store-link)
35 | (define-key global-map "\C-ca" 'org-agenda)
36 | (define-key global-map "\C-cc" 'org-capture)
37 |
38 | ;; When you want to change the level of an org item, use SMR
39 | (define-key org-mode-map (kbd "C-c C-g C-r") 'org-shiftmetaright)
40 |
41 | ;; Hide the markers so you just see bold text as BOLD-TEXT and not *BOLD-TEXT*
42 | (setq org-hide-emphasis-markers t)
43 |
44 | ;; Wrap the lines in org mode so that things are easier to read
45 | (add-hook 'org-mode-hook 'visual-line-mode)
46 |
47 | (let* ((variable-tuple
48 | (cond ((x-list-fonts "ETBembo") '(:font "ETBembo"))
49 | ((x-list-fonts "Source Sans Pro") '(:font "Source Sans Pro"))
50 | ((x-list-fonts "Lucida Grande") '(:font "Lucida Grande"))
51 | ((x-list-fonts "Verdana") '(:font "Verdana"))
52 | ((x-family-fonts "Sans Serif") '(:family "Sans Serif"))
53 | (nil (warn "Cannot find a Sans Serif Font. Install Source Sans Pro."))))
54 | (base-font-color (face-foreground 'default nil 'default))
55 | (headline `(:inherit default :weight bold :foreground ,base-font-color)))
56 |
57 | (custom-theme-set-faces
58 | 'user
59 | `(org-level-8 ((t (,@headline ,@variable-tuple))))
60 | `(org-level-7 ((t (,@headline ,@variable-tuple))))
61 | `(org-level-6 ((t (,@headline ,@variable-tuple))))
62 | `(org-level-5 ((t (,@headline ,@variable-tuple))))
63 | `(org-level-4 ((t (,@headline ,@variable-tuple :height 1.1))))
64 | `(org-level-3 ((t (,@headline ,@variable-tuple :height 1.2))))
65 | `(org-level-2 ((t (,@headline ,@variable-tuple :height 1.3))))
66 | `(org-level-1 ((t (,@headline ,@variable-tuple :height 1.5))))
67 | `(org-document-title ((t (,@headline ,@variable-tuple :height 1.6 :underline nil))))))
68 |
69 | (setq org-capture-templates
70 | '(
71 | ("j" "Work Log Entry"
72 | entry (file+datetree "~/org/work-log.org")
73 | "* %?"
74 | :empty-lines 0)
75 |
76 | ("n" "Note"
77 | entry (file+headline "~/org/notes.org" "Random Notes")
78 | "** %?"
79 | :empty-lines 0)
80 |
81 | ("n" "Note"
82 | entry (file+headline "~/org/notes.org" "Random Notes")
83 | "** %?"
84 | :empty-lines 0)
85 |
86 | ("d" "Door Codes"
87 | entry (file+headline "~/org/notes.org" "Door Codes")
88 | "** %?"
89 | :empty-lines 0)
90 |
91 | ("g" "General To-Do"
92 | entry (file+headline "~/org/todos.org" "General Tasks")
93 | "* TODO [#B] %?\n:Created: %T\n "
94 | :empty-lines 0)
95 |
96 | ("m" "Meeting"
97 | entry (file+datetree "~/org/meetings.org")
98 | "* %? :meeting:%^g \n:Created: %T\n** Attendees\n*** \n** Notes\n** Action Items\n*** TODO [#A] "
99 | :tree-type week
100 | :clock-in t
101 | :clock-resume t
102 | :empty-lines 0)
103 |
104 | ("c" "Code To-Do"
105 | entry (file+headline "~/org/todos.org" "Code Related Tasks")
106 | "* TODO [#B] %?\n:Created: %T\n%i\n%a\nProposed Solution: "
107 | :empty-lines 0)
108 |
109 | ))
110 |
111 | (setq org-todo-keywords
112 | '((sequence "TODO(t)" "PLANNING(p)" "IN-PROGRESS(i@/!)" "VERIFYING(v!)" "BLOCKED(b@)" "|" "DONE(d!)" "OBE(o@!)" "WONT-DO(w@/!)" )
113 | ))
114 |
115 | (setq org-todo-keyword-faces
116 | '(
117 | ("TODO" . (:foreground "GoldenRod" :weight bold))
118 | ("PLANNING" . (:foreground "DeepPink" :weight bold))
119 | ("IN-PROGRESS" . (:foreground "Cyan" :weight bold))
120 | ("VERIFYING" . (:foreground "DarkOrange" :weight bold))
121 | ("BLOCKED" . (:foreground "Red" :weight bold))
122 | ("DONE" . (:foreground "LimeGreen" :weight bold))
123 | ("OBE" . (:foreground "LimeGreen" :weight bold))
124 | ("WONT-DO" . (:foreground "LimeGreen" :weight bold))
125 | ))
126 |
127 |
128 | ;; Tags
129 | (setq org-tag-alist '(
130 | ;; Ticket types
131 | (:startgroup . nil)
132 | ("@bug" . ?b)
133 | ("@feature" . ?u)
134 | ("@spike" . ?j)
135 | (:endgroup . nil)
136 |
137 | ;; Ticket flags
138 | ("@write_future_ticket" . ?w)
139 | ("@emergency" . ?e)
140 | ("@research" . ?r)
141 |
142 | ;; Meeting types
143 | (:startgroup . nil)
144 | ("big_sprint_review" . ?i)
145 | ("cents_sprint_retro" . ?n)
146 | ("dsu" . ?d)
147 | ("grooming" . ?g)
148 | ("sprint_retro" . ?s)
149 | (:endgroup . nil)
150 |
151 | ;; Code TODOs tags
152 | ("QA" . ?q)
153 | ("backend" . ?k)
154 | ("broken_code" . ?c)
155 | ("frontend" . ?f)
156 |
157 | ;; Special tags
158 | ("CRITICAL" . ?x)
159 | ("obstacle" . ?o)
160 |
161 | ;; Meeting tags
162 | ("HR" . ?h)
163 | ("general" . ?l)
164 | ("meeting" . ?m)
165 | ("misc" . ?z)
166 | ("planning" . ?p)
167 |
168 | ;; Work Log Tags
169 | ("accomplishment" . ?a)
170 | ))
171 |
172 |
173 | ;; Tag colors
174 | (setq org-tag-faces
175 | '(
176 | ("planning" . (:foreground "mediumPurple1" :weight bold))
177 | ("backend" . (:foreground "royalblue1" :weight bold))
178 | ("frontend" . (:foreground "forest green" :weight bold))
179 | ("QA" . (:foreground "sienna" :weight bold))
180 | ("meeting" . (:foreground "yellow1" :weight bold))
181 | ("CRITICAL" . (:foreground "red1" :weight bold))
182 | )
183 | )
184 |
185 |
186 | ;; Agenda View "d"
187 | (defun air-org-skip-subtree-if-priority (priority)
188 | "Skip an agenda subtree if it has a priority of PRIORITY.
189 |
190 | PRIORITY may be one of the characters ?A, ?B, or ?C."
191 | (let ((subtree-end (save-excursion (org-end-of-subtree t)))
192 | (pri-value (* 1000 (- org-lowest-priority priority)))
193 | (pri-current (org-get-priority (thing-at-point 'line t))))
194 | (if (= pri-value pri-current)
195 | subtree-end
196 | nil)))
197 |
198 | (setq org-agenda-skip-deadline-if-done t)
199 |
200 | (setq org-agenda-custom-commands
201 | '(
202 |
203 | ;; Daily Agenda & TODOs
204 | ("d" "Daily agenda and all TODOs"
205 |
206 | ;; Display items with priority A
207 | ((tags "PRIORITY=\"A\""
208 | ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
209 | (org-agenda-overriding-header "High-priority unfinished tasks:")))
210 |
211 | ;; View 7 days in the calendar view
212 | (agenda "" ((org-agenda-span 7)))
213 |
214 | ;; Display items with priority B (really it is view all items minus A & C)
215 | (alltodo ""
216 | ((org-agenda-skip-function '(or (air-org-skip-subtree-if-priority ?A)
217 | (air-org-skip-subtree-if-priority ?C)
218 | (org-agenda-skip-if nil '(scheduled deadline))))
219 | (org-agenda-overriding-header "ALL normal priority tasks:")))
220 |
221 | ;; Display items with pirority C
222 | (tags "PRIORITY=\"C\""
223 | ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
224 | (org-agenda-overriding-header "Low-priority Unfinished tasks:")))
225 | )
226 |
227 | ;; Don't compress things (change to suite your tastes)
228 | ((org-agenda-compact-blocks nil)))
229 |
230 | ;; James's Super View
231 | ("j" "James's Super View"
232 | (
233 | (agenda ""
234 | (
235 | (org-agenda-remove-tags t)
236 | (org-agenda-span 7)
237 | )
238 | )
239 |
240 | (alltodo ""
241 | (
242 | ;; Remove tags to make the view cleaner
243 | (org-agenda-remove-tags t)
244 | (org-agenda-prefix-format " %t %s")
245 | (org-agenda-overriding-header "CURRENT STATUS")
246 |
247 | ;; Define the super agenda groups (sorts by order)
248 | (org-super-agenda-groups
249 | '(
250 | ;; Filter where tag is CRITICAL
251 | (:name "Critical Tasks"
252 | :tag "CRITICAL"
253 | :order 0
254 | )
255 | ;; Filter where TODO state is IN-PROGRESS
256 | (:name "Currently Working"
257 | :todo "IN-PROGRESS"
258 | :order 1
259 | )
260 | ;; Filter where TODO state is PLANNING
261 | (:name "Planning Next Steps"
262 | :todo "PLANNING"
263 | :order 2
264 | )
265 | ;; Filter where TODO state is BLOCKED or where the tag is obstacle
266 | (:name "Problems & Blockers"
267 | :todo "BLOCKED"
268 | :tag "obstacle"
269 | :order 3
270 | )
271 | ;; Filter where tag is @write_future_ticket
272 | (:name "Tickets to Create"
273 | :tag "@write_future_ticket"
274 | :order 4
275 | )
276 | ;; Filter where tag is @research
277 | (:name "Research Required"
278 | :tag "@research"
279 | :order 7
280 | )
281 | ;; Filter where tag is meeting and priority is A (only want TODOs from meetings)
282 | (:name "Meeting Action Items"
283 | :and (:tag "meeting" :priority "A")
284 | :order 8
285 | )
286 | ;; Filter where state is TODO and the priority is A and the tag is not meeting
287 | (:name "Other Important Items"
288 | :and (:todo "TODO" :priority "A" :not (:tag "meeting"))
289 | :order 9
290 | )
291 | ;; Filter where state is TODO and priority is B
292 | (:name "General Backlog"
293 | :and (:todo "TODO" :priority "B")
294 | :order 10
295 | )
296 | ;; Filter where the priority is C or less (supports future lower priorities)
297 | (:name "Non Critical"
298 | :priority<= "C"
299 | :order 11
300 | )
301 | ;; Filter where TODO state is VERIFYING
302 | (:name "Currently Being Verified"
303 | :todo "VERIFYING"
304 | :order 20
305 | )
306 | )
307 | )
308 | )
309 | )
310 | ))
311 | ))
312 |
313 |
--------------------------------------------------------------------------------