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.