8.0 KiB
Writing
I am using Org mode1 extensively throughout my writing. Most of the improvements are done in the Core module, but all of the management, encryption, synchronization, and organization of all of my writing happens here.
Improvements
Real time checking and one-shot methods to check and correct common spelling and grammatical errors.
Spelling
Grammar
I use Writegood4 to find common writing problems such as cliches and poor wording. Grammarly for the peons!
(use-package writegood-mode :after org :config (writegood-mode))
Toggle Writegood mode with SPC t w
.
(dotfiles/leader "tw" '(writegood-mode :which-key "Grammar"))
Knowledge base
Download and install Org roam5, a plain text knowledge management system for Emacs built on top of Org mode1.
-
Notes can be arbitrarily referenced
-
Contexts created by linking topics and notes
-
Install dependencies on Debian/Ubuntu systems
-
Configure custom keybindings for roam behind
SPC r
-
Find with
f
-
Insert with
i
-
Buffer with
b
-
Capture with
c
-
(use-package org-roam :hook (after-init . org-roam-mode) :custom (org-roam-directory org-directory) (org-roam-capture-templates '()) (org-roam-dailies-capture-templates '()) :config (dotfiles/leader "r" '(:ignore t :which-key "Roam") "ri" '(org-roam-insert :which-key "Insert") "rf" '(org-roam-find-file :which-key "Find") "rc" '(org-roam-capture :which-key "Capture") "rb" '(org-roam-buffer-toggle-display :which-key "Buffer")))
File slugs
The default behaviour of org-roam
when creating a title slug is to replace any non alpha numerical (whitespace) to _
. I wanted to change this to use _
and have done so here in my own definition. The only substantial difference from the original definition is the character used.
-
Define a new
title-to-slug
function -
Override
org-roam-title-to-slug-function
(with-eval-after-load 'org-roam (require 'cl-lib) (defun dotfiles/title-to-slug (title) "Convert TITLE to a filename-suitable slug." (cl-flet* ((nonspacing-mark-p (char) (eq 'Mn (get-char-code-property char 'general-category))) (strip-nonspacing-marks (s) (apply #'string (seq-remove #'nonspacing-mark-p (ucs-normalize-NFD-string s)))) (cl-replace (title pair) (replace-regexp-in-string (car pair) (cdr pair) title))) (let* ((pairs `(("[^[:alnum:][:digit:]]" . "-") ;; Convert anything not alphanumeric. ("--*" . "-") ;; Remove sequential dashes. ("^-" . "") ;; Remove starting dashes. ("-$" . ""))) ;; Remove ending dashes. (slug (-reduce-from #'cl-replace (strip-nonspacing-marks title) pairs))) (downcase slug)))) (setq org-roam-title-to-slug-function #'dotfiles/title-to-slug))
Web visualizer
Including the extension Org roam server6 will run a web application that visualizes the Org roam5 database. Available whenever the editor is running at https://localhost:8080. The image at the top of this page is an example of the application running.
(use-package org-roam-server :hook (org-roam-mode . org-roam-server-mode))
Daily note taking
Use the daily
note feature of Org roam5 to capture daily notes. Create the default capture template with some preconfigured headers.
(with-eval-after-load 'org-roam (add-to-list 'org-roam-dailies-capture-templates '("d" "Default" entry (function org-roam-capture--get-point) "* %?" :file-name "docs/daily/%<%Y-%m-%d>" :head " ,#+TITLE: %<%Y-%m-%d> ,#+AUTHOR: Christopher James Hayward ,#+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil ,#+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil ")))
Place keybindings behind SPC r d
.
-
Date with
d
-
Today with
t
-
Tomorrow with
m
-
Yesterday with
y
(dotfiles/leader "rd" '(:ignore t :which-key "Dailies") "rdd" '(org-roam-dailies-find-date :which-key "Date") "rdt" '(org-roam-dailies-find-today :which-key "Today") "rdm" '(org-roam-dailies-find-tomorrow :which-key "Tomorrow") "rdy" '(org-roam-dailies-find-yesterday :which-key "Yesterday"))
Capture templates
-
Capture template for generic documents
(with-eval-after-load 'org-roam (add-to-list 'org-roam-capture-templates '("d" "Default" entry (function org-roam-capture--get-point) "%?" :file-name "docs/${slug}" :unnarrowed t :head " ,#+TITLE: ${title} ,#+AUTHOR: Christopher James Hayward ,#+EMAIL: chris@chrishayward.xyz ")))
Custom capture template for courses.
-
Capture a new buffer with
SPC r c c
(with-eval-after-load 'org-roam (add-to-list 'org-roam-capture-templates '("c" "Course" plain (function org-roam-capture--get-point) "%?" :file-name "docs/courses/${slug}" :unnarrowed t :head " ,#+TITLE: ${title} ,#+SUBTITLE: ,#+AUTHOR: Christopher James Hayward ,#+EMAIL: chris@chrishayward.xyz ,#+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil ,#+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil ")))
Agenda integration
More capture templates for Org roam5 are defined here in the context of specific domains and topics.
-
Configure agenda sources
(setq org-agenda-files '("~/.emacs.d/" "~/.emacs.d/docs/" "~/.emacs.d/docs/courses/" "~/.emacs.d/docs/daily/" "~/.emacs.d/docs/notes/" "~/.emacs.d/docs/posts/" "~/.emacs.d/docs/slides/" "~/.emacs.d/hosts/" "~/.emacs.d/modules/"))
-
Open an agenda buffer with
SPC a
(dotfiles/leader "a" '(org-agenda :which-key "Agenda"))
Navigation and search
Use Deft to search and navigate the knowledge base with text filtering.
(use-package deft :after org-roam :custom (deft-recursive t) (deft-directory org-directory) (deft-default-extension "org") (deft-use-filter-string-for-filename t) :config (dotfiles/leader "rs" '(deft :which-key "Search (deft)")))