cmc/cleberg.net
My personal web garden & blog.
clone: git clone https://gitbay.org/cmc/cleberg.net.git
main: content/blog/2024-03-13-doom-emacs.org · raw
1#+date: [2024-03-13 Wed 00:00:00]
2#+title: Doom Emacs and Org Mode Setup
3#+description: How I set up Doom Emacs and Org Mode for notes and task management.
4#+slug: doom-emacs
5#+filetags: :emacs:
6
7** Screenshots
8
9These screenshots are showing a project opened with projectile, a treemacs side
10pane open with the project contents, multiple buffers tiled next to each other,
11and the help pane open at the bottom.
12
13The themes are =doom-homage-white= and =doom-homage-black=.
14
15#+caption: Doom Emacs Light Mode
16#+attr_html: :alt An example of the doom-homage-white theme on the Doom dashboard.
17[[https://img.cleberg.net/blog/20240314-doom-emacs/light.webp]]
18
19#+caption: Doom Emacs Dark Mode
20#+attr_html: :alt An example of the doom-homage-black theme on the Doom dashboard.
21[[https://img.cleberg.net/blog/20240314-doom-emacs/dark.webp]]
22
23** Getting Started
24
25I have been switching back and forth between [[https://en.wikipedia.org/wiki/Markdown][markdown]] and [[https://en.wikipedia.org/wiki/Org-mode][org-mode]] recently for
26my personal note taking, wiki, and even this blog. As a result, I have been
27stumbling further into the world of Emacs and found myself at a point where I
28now prefer to do most of my basic editing within Emacs.
29
30I'll leave the markdown vs. org-mode debate for another post, but I love
31org-mode's extensibility and interactive nature within Emacs, but it becomes
32very unwieldy in any other client implementation of org-mode - especially on
33iOS. On the flip side, markdown is limited in functionality and fractured into
34different standards, but it's simple and popular enough that there are a
35plethora of great clients to choose from that will get the job done.
36
37For now, I want to focus on how I have been using Emacs and some of the things
38that would have helped me learn it faster had I known where to start.
39
40*** Installation
41
42This post focuses on [[https://github.com/doomemacs/doomemacs][Doom Emacs]], which is an Emacs framework that provides an
43alternative experience to the vanilla [[https://www.gnu.org/software/emacs/][GNU Emacs]].
44
45The [[https://github.com/doomemacs/doomemacs/blob/master/docs/getting_started.org][Getting Started Guide]] has an extremely detailed walkthrough of installation
46for all systems, so please refer to that guide for up-to-date instructions.
47
48I chose to install on macOS, using the Homebrew option with the
49=railwaycat/emacsmacport= version of Emacs.
50
51Once the program is installed, you can run the program by typing =emacs= in a
52terminal. If you installed a version of Emacs that supports both a GUI and TUI,
53you will have to run =emacs -nw= to get the TUI instead of the default GUI.
54
55*** Configuration
56
57Once installed, you can configure Doom by editing the files within the
58=~/.doom.d/= directory. This directory holds four files:
59
601. =config.el= - Personal configuration file
612. =custom.el= - Custom set variables
623. =init.el= - Doom modules and load order, must run =doom sync= after modifying
634. =packages.el= - Declare packages to install in this file, then run =doom
64 sync= to install
65
66I only needed a few customizations for my configuration, so I'll list them
67below.
68
69#+begin_src lisp
70;; ~/.doom.d/config.el
71(setq doom-theme 'doom-homage-black)
72(setq display-line-numbers-type t)
73(setq org-directory "~/Documents/Notes/")
74
75;; lengthy org-publish directives at the bottom of the file
76#+end_src
77
78#+begin_src lisp
79;; ~/.doom.d/init.el
80(doom! :input
81 :completion
82 company ; the ultimate code completion backend
83 vertico ; the search engine of the future
84
85 :ui
86 doom ; what makes DOOM look the way it does
87 doom-dashboard ; a nifty splash screen for Emacs
88 (emoji +unicode) ; 🙂
89 hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
90 minimap ; show a map of the code on the side
91 modeline ; snazzy, Atom-inspired modeline, plus API
92 ophints ; highlight the region an operation acts on
93 (popup +defaults) ; tame sudden yet inevitable temporary windows
94 tabs ; a tab bar for Emacs
95 treemacs ; a project drawer, like neotree but cooler
96 (vc-gutter +pretty) ; vcs diff in the fringe
97 vi-tilde-fringe ; fringe tildes to mark beyond EOB
98 workspaces ; tab emulation, persistence & separate workspaces
99
100 :editor
101 (evil +everywhere); come to the dark side, we have cookies
102 file-templates ; auto-snippets for empty files
103 fold ; (nigh) universal code folding
104 snippets ; my elves. They type so I don't have to
105
106 :emacs
107 dired ; making dired pretty [functional]
108 electric ; smarter, keyword-based electric-indent
109 undo ; persistent, smarter undo for your inevitable mistakes
110 vc ; version-control and Emacs, sitting in a tree
111
112 :term
113 term ; basic terminal emulator for Emacs
114
115 :checkers
116 syntax ; tasing you for every semicolon you forget
117
118 :tools
119 (eval +overlay) ; run code, run (also, repls)
120 lookup ; navigate your code and its documentation
121 magit ; a git porcelain for Emacs
122
123 :os
124 (:if (featurep :system 'macos) macos) ; improve compatibility with macOS
125
126 :lang
127 common-lisp ; if you've seen one lisp, you've seen them all
128 emacs-lisp ; drown in parentheses
129 markdown ; writing docs for people to ignore
130 org ; organize your plain life in plain text
131 python ; beautiful is better than ugly
132 sh ; she sells {ba,z,fi}sh shells on the C xor
133
134 :app
135 irc ; how neckbeards socialize
136 (rss +org) ; emacs as an RSS reader
137
138 (default +bindings +smartparens))
139#+end_src
140
141If you're editing these files within Doom directly, remember to run =SPC h r r=
142to reload the configuration. Also remember to run =doom sync= for any changes to
143the =init.el= or =packages.el= files.
144
145** Basic Functionality
146
147I kept a cheat sheet note open at first with all of the basic functions typed
148out, copied as I went through the tutorial. After a little while, I no longer
149needed it. I highly recommend writing down the most applicable shortcuts for
150your preferred functionality and refer back to it until you've memorized it.
151
152Memorizing the shortcuts will differ based on the type of Emacs framework being
153used. Personally, migrating from vanilla Emacs to Doom Emacs simplified
154everything by a large factor and instantly enabled me to start working on my
155projects, eliminating most of the hurdles I was running into. The vanilla emacs
156hotkeys became obnoxious and I actually stopped using Emacs entirely for about a
157month before trying Doom.
158
159For me, the first logical step is to interact with the local filesystem. To do
160this, I needed to know how to open directories, open files, save files, discard
161changes, close files, and switch between open files. Here are some example
162shortcuts I've written down in order to accomplish file-based actions.
163
164| Doom Hotkey | Emacs Hotkey | Description |
165|-----------------+---------------+----------------------------------------|
166| =SPC := | =C-x= | Run functions |
167| =SPC f f= | =C-x f= | Open file in buffer |
168| =SPC f d= | =C-x d= | Open directory with =dired= |
169| =i= | =C-x C-q= | Edit current buffer (insert mode) |
170| =q= | =C-x C-q= | Quit out of insert mode |
171| =SPC f s= | =C-x s= | Save current buffer |
172| =SPC b k= | =C-x k= | Kill current buffer |
173| =SPC w h/j/k/l= | =C-x o=[fn:2] | Move left/down/up/right to next buffer |
174
175In general, when in Doom, you can press =SPC= and wait a second for the help
176pane to appear with all available hotkey options. For example, you can press
177=SPC=, wait for the help pane, and then select a key such as =g= to enter the
178git help pane and explore further command options.
179
180** Editing
181
182Next in my process is to dive into editing for any languages I'm currently
183using. In this post, I will just cover Markdown and Org-Mode but I have also
184been slowly adoping some Python and general web dev tools as well.
185
186*** Markdown
187
188#+caption: Markdown Preview
189#+attr_html: :alt An editing buffer opened to a markdown file.
190[[https://img.cleberg.net/blog/20240314-doom-emacs/markdown.webp]]
191
192Markdown is fairly simple as the syntax is limited, so just make sure the
193=~/.doom.d/init.el= includes the =markdown= declaration in the =:lang= section.
194
195This package includes the following hotkey menus. The insert and toggle menu
196expands further, allowing you to insert various markdown elements and toggle
197things like link hiding.
198
199| Doom Hotkey | Function |
200|------------------------------+--------------------------|
201| =SPC m '= | markdown-edit-code-block |
202| =SPC m e= | markdown-export |
203| =SPC m i= | +insert |
204| =SPC m o= | markdown-open |
205| =SPC m p= | markdown-preview |
206| =SPC m t= | +toggle |
207| =SPC : markdown-table-align= | markdown-table-align |
208
209*** Org-Mode
210
211#+caption: Org-Mode Preview
212#+attr_html: :alt An editing buffer opened to an org-mode file.
213[[https://img.cleberg.net/blog/20240314-doom-emacs/org.webp]]
214
215Similar to the markdown section above, ensure that the =~/.doom.d/init.el=
216includes the =org= declaration in the =:lang= section.
217
218There are a few hot keys, but a quick search with =SPC : org= shows that there
219are 865 possible org-related functions you can run. I won't possibly be able to
220list them all, so I will simply cover a few of the basic commands I use myself.
221
222| Doom Hotkey | Function |
223|----------------+---------------------------------------|
224| =SPC m t= | org-todo |
225| =SPC n t= | org-todo-list |
226| =SPC o A= | org-agenda |
227| =SPC X= | org-capture |
228| =SPC m p p= | org-priority |
229| =SPC m d s= | org-schedule |
230| =TAB= | org-cycle |
231| =SHIFT TAB= | Collapse/open all headings in buffer |
232| =M-q= | Format/wrap current section |
233| =M-Left/Right= | Demote/promote current heading |
234| =M-Down/Up= | Shift current heading section down/up |
235
2361. Org-Publish
237
238 Org includes a [[https://orgmode.org/manual/Publishing.html][publishing management system]] by default that allows you to
239 export org files to Org, iCalendar, HTML, LaTex, Markdown, ODT, and Plain
240 Text. Most of these can be exported into another buffer and opened, or simply
241 to an external file.
242
243 While inside an org file, simply run =SPC m e= or =M-x org-export-dispatch=
244 to open the export menu. This menu will show all options and ask you to
245 select an option. If you want to export to HTML, simply press =h= and then
246 =H= (As HTML buffer), =h= (As HTML file), or =o= (As HTML file and open).
247
2482. Projects
249
250 Some publishing options are easier with a defined project in Emacs. To create
251 a project within Emacs, I use two methods:
252
253 1. Add the project via the projectile command =SPC p a=. Does not always work
254 for me.
255 2. Add an empty =.projectile= file in the project root.
256
257 Once a project has been created, you can create custom publishing actions
258 within your =~/.doom.d/config.el= file. For example, here's a test project I
259 created to try and convert this blog to org-mode recently.
260
261 #+begin_src lisp
262 ;; org-publish
263 (require 'ox-publish)
264
265 (defun my/org-sitemap-date-entry-format (entry style project) "Format ENTRY in
266 org-publish PROJECT Sitemap format ENTRY ENTRY STYLE format that includes
267 date." (let ((filename (org-publish-find-title entry project))) (if (= (length
268 filename) 0) (format "*%s*" entry) (format "{{{timestamp(%s)}}}
269 [[file:%s][%s]]" (format-time-string "%Y-%m-%d" (org-publish-find-date entry
270 project)) entry filename))))
271
272 (setq org-export-global-macros '(("timestamp" . "@@html:<time datetime='[$1]'
273 class='timestamp'>[$1]</time>@@")))
274
275 (setq org-publish-project-alist
276 `(("blog"
277 :base-directory "~/Source/cleberg.net/"
278 :base-extension "org"
279 :recursive t
280 :publishing-directory "~/Source/cleberg.net/public/"
281 :publishing-function org-html-publish-to-html
282 ;; HTML5
283 :html-doctype "html5"
284 :html-html5-fancy t
285 ;; Disable some Org's HTML defaults
286 :html-head-include-scripts nil
287 :html-head-include-default-style nil
288 :section-numbers nil
289 :with-title nil
290 ;; Sitemap
291 :auto-sitemap t
292 :sitemap-title: "Sitemap"
293 :sitemap-sort-files anti-chronologically
294 ; :sitemap-function my/org-sitemap-date-entry-format
295 ;; Customize HTML output
296 :html-divs ((preamble "header" "preamble")
297 (content "main" "content")
298 (postamble "footer" "postamble"))
299 :html-head "<meta name='theme-color' content='#111' media='(prefers-color-scheme: dark)'>
300 <meta name='theme-color' content='#fff' media='(prefers-color-scheme: light)'>
301 <link rel='stylesheet' href='/syntax-theme-dark.css' media='(prefers-color-scheme: dark)'>
302 <link rel='stylesheet' href='/syntax-theme-light.css' media='(prefers-color-scheme: light)'>
303 <link rel='stylesheet' href='/styles.css' type='text/css'>"
304 :html-preamble "<nav class='site-nav' aria-label='site-nav' role='navigation'>
305 <ul>
306 <li><a href='/'>Home</a></li>
307 <li><a href='/blog/'>Blog</a></li>
308 <li><a href='/services/'>Services</a></li>
309 <li><a href='/wiki/'>Wiki</a></li>
310 </ul></nav>
311 <h1>%t</h1>
312 <time datetime='%d'>%d</time>"
313 :html-postamble "
314 <p>Last build: %T</p>
315 <p>Created with %c</p>"
316 )
317
318 ("static"
319 :base-directory "~/Source/cleberg.net/static/"
320 :base-extension "css\\|txt\\|jpg\\|gif\\|png"
321 :recursive t
322 :publishing-directory "~/Source/cleberg.net/public/"
323 :publishing-function org-publish-attachment)
324
325 ("cleberg.net" :components ("blog" "static"))))
326 #+end_src
327
328** General Thoughts
329
330I have enjoyed Doom Emacs (far more than GNU Emacs) and will likely continue to
331use it as my main editor for the time being. Org-Mode is certainly the largest
332factor here, as I far prefer it over Markdown due to its inherent features and
333detailed markup options. However, working with org-mode on iOS has been a pain
334and I will have to see if there's an easier way to resolve those issues or if
335going back to separate Markdown, Reminders, and Calendar apps is easier to work
336with than an all-in-one org solution.
337
338[fn:1] Doom's evil-window functionality is a bit different from GNU Emacs, but
339 you can always switch to the "other" buffer with =C-x o= or =C-x b= to
340 get a list of buffers to select.
341
342[fn:2] Doom's evil-window functionality is a bit different from GNU Emacs, but
343 you can always switch to the "other" buffer with =C-x o= or =C-x b= to
344 get a list of buffers to select.