This is version 2 of my Emacs Writing Setup, following my adoption of Doom Emacs. You can find the legacy version here: EmacsWritingTips.org
My Doom config can be found here: https://github.com/ballantony/doom-emacs-config
This document was written due to the interest generated by a post on my blog entitled Writing Tools.
The document is not an Emacs Tutorial, nor is it an exhortation to learn Emacs, but rather a description of how I use Emacs org-mode to help me write fiction (see TonyBallantyne.com for more). My tech blog, Tony Ballantyne Tech, contains more Emacs materials including tips and tricks (The Emacs Workout) and a brief ELisp tutorial (Just Enough Emacs Lisp)
Many of the ideas on the use of org-mode were taken from Bernt Hansen’s excellent document Org Mode Organize Your Life in Plain Text!, as was the format of this document itself. Some of the Emacs tricks came from the Emacs Wiki and Xah Lee’s Emacs tutorial.
- TonyBallantyne.com: My website
- blog.tonyballantyne.com: My Blog
- Emacs Tutorial: Emacs Tutorial for Writers
- Tips on How to Write: More tips for writers
Copyright (C) 2022 Tony Ballantyne. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
Code in this document is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
I think of Emacs as a text editors’ tool. As I spend most of my life working with text, either programming or writing, I want to do it as efficiently as possible.
It first struck me when I was editing my novel Divergence just how inefficient I was being in pressing the arrow key and waiting for the cursor to get to where I wanted. That got me thinking about the time spent deleting text, transposing words, moving around paragraphs… I realised there must be a quicker way.
And then I remembered Emacs.
It makes sense for someone who spends most of their time manipulating text to learn a group of obscure key combinations. It saves time and increases productivity. Learning to use Emacs properly reminds me of playing Jazz on the piano. I’ve learnt all those chords and runs and fills so that I can use them without thinking when I’m improvising. Likewise, I’ve practised using Emacs key strokes such as M-f, M–M-c and C-M-<Space> so often I use them without thinking when editing. I rely on M-/ to complete words, and I can’t do without M-h and C-e to select and move around text.
I practice using Emacs because it makes me a more productive writer. If you’re interested, I’ve written up some of those tips and exercises on my Emacs Workout.
Emacs is incredibly configurable. I can choose, for example, the shape and contents of my agenda, the completion engine I use and even such things as the colour of my Todos.
And that’s a problem. Emacs allows me to configure many things that, if I’m honest, I really don’t care about.
It’s very easy to fall into the Emacs trap of sending time configuring the system rather than doing any actual work. I don’t want to think about how many hours I’ve spent experimenting with new packages and thinking of the perfect key bindings when I could have been writing stories instead. GTD can be a powerful procrastinator.
That’s why I’m happy to let someone else do it for me.
Enter Doom Emacs. So what if the TODOs are a different colour to the ones I use, and the capture templates aren’t quite the ones I was using, they’re still good. The key bindings may be different, but they’re far more extensive than any I’ve ever set up and I could probably finish a short story in the time it would take me to replicate them (and I can always override the few I really care about: C-e for example).
Most of all, Henrik Lissner knows so much more about Emacs than I. I’ve learned so much simply tracking through his code. I wasn’t aware of Vertico until it turned up in the Doom config. I don’t have the time or inclination to try out all new Emacs packages. It’s great that someone else is doing this, and if I don’t like their choices, well, Doom is flexible enough for me to change them.
One final observation. Doom Emacs is fast to load. This is important to me. I like to take notes or begin writing when inspiration strikes. I can open Doom Emacs (or Orgzly on my mobile phone) and take a note in the time it takes apps such as Evernote or Notion to load.
Instructions on how to set up Emacs and Org-mode appear on the Emacs Setup Section of my website Tony Ballantyne Tech
Doom Emacs provides comprehensive installation instructions here: https://github.com/hlissner/doom-emacs#install
I begin a story by creating an org mode file with something like the following structure:
* Captured * Meta * Outline * Styles * Ideas * Characters * EKs * Worldbuilding * Scenes * Story
The above structure has evolved over the years. I imagine it will continue to change in the future.
- Captured is a list of things to be refiled later, captured to the buffer using this function.
- Meta contains such things as themes, notes for blurbs, possible quotations for publicity, title ideas
- Outline contains the shape of the story as it is at the time. This gets rewritten as I go on. It also acts as a reminder of what I’ve done so far
- Styles are there to remind me just how I wrote things out e.g. Daddy Bear, not Daddy bear.
- Ideas are ideas that may or may not be included in the story.
- Characters I don’t make extensive character notes as I believe characters should grow organically. I do keep reminders about details such as age, partner’s name
- EKs Eyeball Kicks
- Worldbuilding Everything from cities to buildings to alien races
- Scenes Scenes that may be included in the story
- Story The story itself
Here’s an example of what a story might look like. Different types of stories have different sections. My Penrose novels (The Penrose Series), for example, have sections dealing with Robot physiology.
* Captured
* Meta
** Goldilocks gets away with it again
** Links to Fairy Tales world
* Outline
** Bears make porridge, go into woods
** Goldilocks arrives, eats the porridge, falls asleep
** Bears return. Find Goldilocks, threaten to eat her
** Big Bad Wolf saves the day
* Styles
** Daddy Bear
* Ideas
** Bears have an invisible motorbike
** Daddy Bear once served time in prison for bearslaughter
* Characters
** Daddy Bear (38)
- Brown fur, brown eyes.
- Biggest bear. Gruff.
** Mummy Bear (39)
- Black fur, golden eyes.
- Clever, sarcastic
* Worldbuilding
** Hundred Hectare Wood
*** Elm trees rising above the oaks.
** Cabin
*** Built of wood. Three rooms. Enter directly into main room, no hallway.
* Scenes
** Who's been eating my porridge?
** Then I'll huff and I'll puff and I'll blow your greenhouse down
* Story
** Episode 1
Once upon a time there were three bears. Mummy Bear, Daddy Bear, Baby Bear etc...
Some things to note:
- I always write down the age of my characters: it helps to fix them in my mind
- I try to keep the outline section up to date as I write. It helps to remind me of any changes I’ve made.
Like any writer I’m always capturing ideas. I used to carry a notebook everywhere, now I capture ideas on my phone using either orgzly or Evernote.
When working in Emacs I use org-capture.
GTD means capturing ideas quickly. I used to have templates to capture to different locations, I realised that this was an unnecessary step. Now I either capture everything as a TODO, either directly to my gtd file, or directly to the story file I’m currently working on.
As org-capture requires you to select a template I wrote the following two functions. The first calls org-capture with the ‘t’ template preselected, the second does the same but uses let* to change org-capture-templates to the current buffer for the current capture only.
(defun tb/capture ()
"Capture to do without options"
(interactive)
(org-capture nil "t"))
(defun tb/capture-to-this-buffer ()
"Capture note to this buffer"
(interactive)
(cond ((not (eq major-mode 'org-mode))
(message "Can't capture to non org-mode buffer"))
(t
(let* ((this-file buffer-file-name)
(org-capture-templates
`(("t" "Todo" entry (file+headline ,this-file "Captured")
"** TODO %?"))))
(org-capture)))))
org-refile makes it easy to refile notes, particularly with a completion system like Vertico. On Doom Emacs this means hitting SPC m r r
I used to use scriv-mode to keep track of my notes whilst writing. I now use Workspaces and Projects instead.
Workspaces are similar to Linux Workspaces or Microsoft’s multiple desktops.
Projects are collections of files, originally intended for programming projects. I find projects ideal for writing projects. You can turn a directory into a project either adding version control such as git, or by adding an empty file named .projectile.
Projects and Workspaces go together: open each project in its own workspace and then you can switch between projects/workspaces as you work.
This document is part of a git project called emacs-writing which is ultimately pushed to GitHub.
I don’t like using git for my fiction writing, so I simply add an empty file called .projectile to my writing folder to turn it into a projectile project.
Once I’ve opened my writing project the following keybindings are useful:
SPC SPC
Find file in projectSPC s p
helper function that does project wide consult-line searchSPC u SPC f d
dired in a projectSPC p i
Invalidate project cache (remove deleted files from project cache)
I wrote the following function to restrict the agenda to the current project. Bind the function to a key that calls org-agenda. You can see an example in my config.el file
(defun tb/agenda-restrict-this-project ()
"Restrict agenda to current project"
(interactive)
(let ((org-agenda-files (list (projectile-project-root))))
(org-agenda)))
I rely a lot on this function. When writing I hit SPC j p p
(my keybinding) to see the TODOs and IN PROGRESSes for this project only.
Doom Emacs opens new projects in their own workspaces. Hitting SPC SPC when you first open Doom Emacs will look for a project, not a file.
Useful keybindings:
SPC SPC
find file in the current projectSPC , or SPC b b
Helper function to switch to another buffer in the same workspace.SPC TAB TAB
to see workspaces currently openSPC TAB <num>
to switch to workspace <num>
The above might seem a bit complicated, so here’s an example of how I might work.
- Open Emacs
SPC P P
to bring up a list of projects~/projects/emacs-writing ~/projects/example ~/projects/writing
- Choose example project
SPC j p p
to show the agenda for the example projectTodo: penrose: TODO Penrose Love penrose: TODO Armour Scene threebears: TODO Who's been eating my porridge? ========================================================================== In Progress: penrose: IN PROGRESS Penrose 3 threebears: IN PROGRESS Episode 1
- Choose a TODO or INPROGRESS and go to work.
One of the confusing things about Doom Emacs is knowing which command to use: Henrik has written a number of helper functions that modify the behaviour of familiar commands.
I find it helpful to think about where I want to apply the command. For example, when I call find file do I want to look in the current project or everywhere?
I’ve listed a few useful commands below:
SPC f f
orSPC .
Find fileC-x d
diredSPC f d
default/dired helper function that calls dired in a project if you call it with an argumentSPC b B
orC-x b consult-buffer
More information than SPC b b. This will list buffers, a file history and bookmarks. Filter down to files with F SPC, b SPC for buffers, p SPC for projectsSPC RET
orC-x r b consult-bookmark
SPC b i
iBuffer
SPC s s
+default/search-buffer helper function that does consult-line search for the current file- leave a space to search for two words any order
- cow.*see to search in that order
SPC s j
+vertico/jump-list helper function that goes to entry in evil’s jump list
This section repeats things mentioned in previous sections. I’ve collected the notes here for convenience.
A big part of writing is putting the notes I’ve made into some sort of order. I spend a lot of time joining notes together to make scenes and then rearranging those scenes. Scrivener is good at the rearranging part (I’ve written about this here.) Where Scrivener falls down is the flexibility of search. Emacs allows me to home in on a scene, an idea or a sentence almost instantly.
I copied some of my writing process from Scrivener’s model, even going as far as writing a simple Emacs Scrivener mode. Doom Emacs has rendered that unnecessary. Tools like ripgrep and consult make it far quicker to find what I’m looking for. If you’re unfamliar with the following commands, try them out. You’ll be pleased that you did.
One last thing. Doom Emacs calls different commands depending on which completion engine you’re using. This means the search syntax may vary. I use the default (vertico at the time of writing) which means that searching for apples oranges will return lines containing apples and oranges. In other words: when searching, type one word for an initial selection, then a second to narrow it down.
SPC SPC
find file in projectSPC s p
search project for textSPC s P
search another project for textSPC s d
search files in directory for text
SPC s s
helper function search for text in current buffer. Matches are displayed in another window.SPC s j
helper function that goes to entry in evil’s jump listSPC m .
Jump to org heading (uses consult-org-heading)
And don’t forget
C-c C-j
org-goto
SPC s o
Search online. t will search online dictionary, T thesaurus- Find an unmatched quote using this regex
^[^"]*"[^"]*$
For a more flexible search try consult-ripgrep. It’s worth reading the documentation, but here’s a taste:
#alpha beta
Search for alpha and beta in any order.#alpha.*beta
Search for alpha before beta.#\(alpha\|beta\)
Search for alpha or beta (Note Emacs syntax!)#word -- -C3
Search for word, include 3 lines as context#first#second
Search for first, quick filter for second.
I’ve experimented with all sorts of arrangements of windows over the years including those featured in scriv-mode
Now I prefer to keep Emacs small (It’s 80 columns wide for a reason). As I keep everything about a story in one file I will often clone the buffer and then narrow to appropriate part. This means that - whether working on a laptop or a big screen - I tend to only have two windows open.
The following keybindings are useful when working with two windows
SPC b C
orC-x 4 c
Clone current buffer: have two views on the same fileSPC m s b
orC-c C-x b
Open headline in different window, or kill if already there.
I use the following functions to quickly change the frame and font size.
(defun tb/set-small-screen ()
"Set the screen to something like regular emacs size."
(set-frame-size (selected-frame) 81 43))
(defun tb/set-large-screen ()
"Set the screen to something like double regular emacs width."
(set-frame-size (selected-frame) 180 53))
(defun tb/preferred-screen-size ()
"Set my preferred screen size."
(interactive)
(if (< (frame-width) 85)
(tb/set-large-screen)
(tb/set-small-screen)))
(defun tb/set-font-size-big ()
(interactive)
"Set font to Courier 16"
(setq doom-font "Courier New-16")
(doom/reload-font)
(tb/set-small-screen))
(defun tb/set-font-size-small ()
(interactive)
"Set font to Courier 14"
(setq doom-font "Courier New-14")
(doom/reload-font))