Christopher James Hayward
4 years ago
9 changed files with 269 additions and 249 deletions
-
2README.org
-
BINdocs/tasks.org.gpg
-
2init.el
-
38modules/agenda.org
-
30modules/grammar.org
-
7modules/pinentry.org
-
167modules/roam.org
-
32modules/spelling.org
-
240modules/writing.org
@ -0,0 +1,38 @@ |
|||||
|
#+TITLE: Agenda |
||||
|
#+AUTHOR: Christopher James Hayward |
||||
|
#+EMAIL: chris@chrishayward.xyz |
||||
|
|
||||
|
#+PROPERTY: header-args:emacs-lisp :tangle agenda.el :comments org |
||||
|
#+PROPERTY: header-args :results silent :eval no-export :comments org |
||||
|
|
||||
|
#+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil |
||||
|
#+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil |
||||
|
|
||||
|
Agenda integrations for ~org-mode~. |
||||
|
|
||||
|
* Config |
||||
|
|
||||
|
Integrate the ~org-agenda~ with the ~org-roam~ database, and the rest of the ~org-mode~ contexts throughout the repository: |
||||
|
|
||||
|
#+begin_src emacs-lisp |
||||
|
(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/")) |
||||
|
#+end_src |
||||
|
|
||||
|
* Shortcuts |
||||
|
|
||||
|
Open an agenda buffer with =SPC a=: |
||||
|
|
||||
|
#+begin_src emacs-lisp |
||||
|
(dotfiles/leader |
||||
|
"a" '(org-agenda :which-key "Agenda")) |
||||
|
#+end_src |
||||
|
|
||||
|
* Footnotes |
@ -0,0 +1,30 @@ |
|||||
|
#+TITLE: Grammar |
||||
|
#+AUTHOR: Christopher James Hayward |
||||
|
#+EMAIL: chris@chrishayward.xyz |
||||
|
|
||||
|
#+PROPERTY: header-args:emacs-lisp :tangle grammar.el :comments org |
||||
|
#+PROPERTY: header-args :results silent :eval no-export :comments org |
||||
|
|
||||
|
#+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil |
||||
|
#+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil |
||||
|
|
||||
|
Real time checking and one-shot methods to check and correct common grammatical errors. |
||||
|
|
||||
|
* Config |
||||
|
|
||||
|
Use ~writegood-mode~ to find common writing problems such as cliches, and poor wording. Grammarly for the peons! |
||||
|
|
||||
|
#+begin_src emacs-lisp |
||||
|
(use-package writegood-mode |
||||
|
:after org |
||||
|
:config (writegood-mode)) |
||||
|
#+end_src |
||||
|
|
||||
|
* Shortcuts |
||||
|
|
||||
|
Toggle ~writegood-mode~ with =SPC t w=: |
||||
|
|
||||
|
#+begin_src emacs-lisp |
||||
|
(dotfiles/leader |
||||
|
"tw" '(writegood-mode :which-key "Grammar")) |
||||
|
#+end_src |
@ -0,0 +1,167 @@ |
|||||
|
#+TITLE: Roam |
||||
|
#+AUTHOR: Christopher James Hayward |
||||
|
#+EMAIL: chris@chrishayward.xyz |
||||
|
|
||||
|
#+PROPERTY: header-args:emacs-lisp :tangle roam.el :comments org |
||||
|
#+PROPERTY: header-args :results silent :eval no-export :comments org |
||||
|
|
||||
|
#+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil |
||||
|
#+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil |
||||
|
|
||||
|
Plain-text knowledge management system. |
||||
|
|
||||
|
* Setup |
||||
|
|
||||
|
Make sure ~sqlite~ is available on your system: |
||||
|
|
||||
|
#+begin_src shell |
||||
|
RUN apt install sqlite |
||||
|
#+end_src |
||||
|
|
||||
|
* Config |
||||
|
|
||||
|
Configure ~org-roam~, a plain-text knowledge management system for Emacs built on top of ~org-mode~. Here's a quick recap of the main principles: |
||||
|
|
||||
|
+ Notes can be arbitrarily referened |
||||
|
+ Contexts created by linking topics and notes |
||||
|
|
||||
|
#+begin_src emacs-lisp |
||||
|
(use-package org-roam |
||||
|
:hook (after-init . org-roam-mode) ;; Lauch roam at startup, big performance cost. |
||||
|
:custom (org-roam-encrypt-files t) ;; Encrypt all roam captures. |
||||
|
(org-roam-directory org-directory) |
||||
|
(org-roam-capture-templates '()) |
||||
|
(org-roam-dailies-capture-templates '())) |
||||
|
#+end_src |
||||
|
|
||||
|
** Files |
||||
|
|
||||
|
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~ |
||||
|
|
||||
|
#+begin_src emacs-lisp |
||||
|
(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) |
||||
|
#+end_src |
||||
|
|
||||
|
** Visualizer |
||||
|
|
||||
|
Use the ~org-roam-server~ web application to visualize the ~org-roam~ database. It's available whenever the editor is running at http://localhost:8080. |
||||
|
|
||||
|
#+begin_src emacs-lisp |
||||
|
(use-package org-roam-server |
||||
|
:after org-roam |
||||
|
:hook (org-roam-mode . org-roam-server-mode)) |
||||
|
#+end_src |
||||
|
|
||||
|
** Dailies |
||||
|
|
||||
|
Use the ~daily~ note feature of ~org-roam~ to capture daily notes. Create the default capture template with some preconfigured headers. |
||||
|
|
||||
|
#+begin_src emacs-lisp |
||||
|
(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 |
||||
|
")) |
||||
|
#+end_src |
||||
|
|
||||
|
* Templates |
||||
|
|
||||
|
Collection of capture templates for various contexts. Here is one for a generic document. |
||||
|
|
||||
|
#+begin_src emacs-lisp |
||||
|
(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 |
||||
|
")) |
||||
|
#+end_src |
||||
|
|
||||
|
** Course |
||||
|
|
||||
|
Capture template for a new course. Capture with =SPC r c c=. |
||||
|
|
||||
|
#+begin_src emacs-lisp |
||||
|
(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 |
||||
|
")) |
||||
|
#+end_src |
||||
|
|
||||
|
* Shortcuts |
||||
|
|
||||
|
Configure custom keybindings for ~org-roam~ behind =SPC r=: |
||||
|
|
||||
|
+ Find with =f= |
||||
|
+ Insert with =i= |
||||
|
+ Buffer with =b= |
||||
|
+ Capture with =c= |
||||
|
|
||||
|
#+begin_src emacs-lisp |
||||
|
(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")) |
||||
|
#+end_src |
||||
|
|
||||
|
Place keybindings for daily notes behind =SPC r d=: |
||||
|
|
||||
|
+ Date with =d= |
||||
|
+ Today with =t= |
||||
|
+ Tomorrow with =m= |
||||
|
+ Yesterday with =y= |
||||
|
|
||||
|
#+begin_src emacs-lisp |
||||
|
(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")) |
||||
|
#+end_src |
||||
|
|
||||
|
* Footnotes |
@ -0,0 +1,32 @@ |
|||||
|
#+TITLE: Spelling |
||||
|
#+AUTHOR: Christopher James Hayward |
||||
|
#+EMAIL: chris@chrishayward.xyz |
||||
|
|
||||
|
#+PROPERTY: header-args:emacs-lisp :tangle spelling.el :comments org |
||||
|
#+PROPERTY: header-args :results silent :eval no-export :comments org |
||||
|
|
||||
|
#+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil |
||||
|
#+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil |
||||
|
|
||||
|
Real time checking and one-shot methods to check and correct common spelling mistakes. |
||||
|
|
||||
|
* Config |
||||
|
|
||||
|
Configure ~ispell~ as a back-end with ~flyspell~ for real-time checking and highlighting of spelling mistakes. |
||||
|
|
||||
|
#+begin_src emacs-lisp |
||||
|
(use-package ispell |
||||
|
:after org |
||||
|
:custom (ispell-dictionary dotfiles/lang)) |
||||
|
#+end_src |
||||
|
|
||||
|
* Shortcuts |
||||
|
|
||||
|
Toggle highlighting within buffer specific contexts with =SPC t s=: |
||||
|
|
||||
|
#+begin_src emacs-lisp |
||||
|
(dotfiles/leader |
||||
|
"ts" '(flyspell-buffer :which-key "Spelling")) |
||||
|
#+end_src |
||||
|
|
||||
|
* Footnotes |
@ -1,240 +0,0 @@ |
|||||
#+TITLE: Writing |
|
||||
#+AUTHOR: Christopher James Hayward |
|
||||
#+EMAIL: chris@chrishayward.xyz |
|
||||
|
|
||||
#+PROPERTY: header-args:emacs-lisp :tangle writing.el :comments org |
|
||||
#+PROPERTY: header-args :results silent :eval no-export :comments org |
|
||||
|
|
||||
#+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil |
|
||||
#+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil |
|
||||
|
|
||||
#+ATTR_ORG: :width 420px |
|
||||
#+ATTR_HTML: :width 420px |
|
||||
#+ATTR_LATEX: :width 420px |
|
||||
[[../docs/images/2021-02-13-example-roam.png]] |
|
||||
|
|
||||
I am using *Org mode*[fn:1] extensively throughout my writing. Most of the improvements are done in the [[file:core.org][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 |
|
||||
|
|
||||
Configure *InteractiveSpell*[fn:2] as a backend with *FlySpell*[fn:3] for real time checking and highlighting. |
|
||||
|
|
||||
#+begin_src emacs-lisp |
|
||||
(use-package ispell |
|
||||
:after org |
|
||||
:custom (ispell-dictionary dotfiles/lang)) |
|
||||
#+end_src |
|
||||
|
|
||||
Toggle highlighting within buffers with =SPC t s=. |
|
||||
|
|
||||
#+begin_src emacs-lisp |
|
||||
(dotfiles/leader |
|
||||
"ts" '(flyspell-buffer :which-key "Spelling")) |
|
||||
#+end_src |
|
||||
|
|
||||
** Grammar |
|
||||
|
|
||||
I use *Writegood*[fn:4] to find common writing problems such as cliches and poor wording. Grammarly for the peons! |
|
||||
|
|
||||
#+begin_src emacs-lisp |
|
||||
(use-package writegood-mode |
|
||||
:after org |
|
||||
:config (writegood-mode)) |
|
||||
#+end_src |
|
||||
|
|
||||
Toggle *Writegood* mode with =SPC t w=. |
|
||||
|
|
||||
#+begin_src emacs-lisp |
|
||||
(dotfiles/leader |
|
||||
"tw" '(writegood-mode :which-key "Grammar")) |
|
||||
#+end_src |
|
||||
|
|
||||
* Knowledge base |
|
||||
|
|
||||
Download and install *Org roam*[fn:5], a plain text knowledge management system for Emacs built on top of *Org mode*[fn:1]. |
|
||||
|
|
||||
+ 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= |
|
||||
|
|
||||
#+begin_src emacs-lisp |
|
||||
(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"))) |
|
||||
#+end_src |
|
||||
|
|
||||
** 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~ |
|
||||
|
|
||||
#+begin_src emacs-lisp |
|
||||
(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)) |
|
||||
#+end_src |
|
||||
|
|
||||
** Web visualizer |
|
||||
|
|
||||
Including the extension *Org roam server*[fn:6] will run a web application that visualizes the *Org roam*[fn:5] 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. |
|
||||
|
|
||||
#+begin_src emacs-lisp |
|
||||
(use-package org-roam-server |
|
||||
:hook (org-roam-mode . org-roam-server-mode)) |
|
||||
#+end_src |
|
||||
|
|
||||
** Daily note taking |
|
||||
|
|
||||
Use the =daily= note feature of *Org roam*[fn:5] to capture daily notes. Create the default capture template with some preconfigured headers. |
|
||||
|
|
||||
#+begin_src emacs-lisp |
|
||||
(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 |
|
||||
"))) |
|
||||
|
|
||||
#+end_src |
|
||||
|
|
||||
Place keybindings behind =SPC r d=. |
|
||||
|
|
||||
+ Date with =d= |
|
||||
+ Today with =t= |
|
||||
+ Tomorrow with =m= |
|
||||
+ Yesterday with =y= |
|
||||
|
|
||||
#+begin_src emacs-lisp |
|
||||
(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")) |
|
||||
#+end_src |
|
||||
|
|
||||
** Capture templates |
|
||||
|
|
||||
+ Capture template for generic documents |
|
||||
|
|
||||
#+begin_src emacs-lisp |
|
||||
(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 |
|
||||
"))) |
|
||||
#+end_src |
|
||||
|
|
||||
Custom capture template for courses. |
|
||||
|
|
||||
+ Capture a new buffer with =SPC r c c= |
|
||||
|
|
||||
#+begin_src emacs-lisp |
|
||||
(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 |
|
||||
"))) |
|
||||
#+end_src |
|
||||
|
|
||||
** Agenda integration |
|
||||
|
|
||||
#+ATTR_ORG: :width 420px |
|
||||
#+ATTR_HTML: :width 420px |
|
||||
#+ATTR_LATEX: :width 420px |
|
||||
[[../docs/images/2021-02-13-example-agenda.gif]] |
|
||||
|
|
||||
More capture templates for *Org roam*[fn:5] are defined here in the context of specific domains and topics. |
|
||||
|
|
||||
+ Configure agenda sources |
|
||||
|
|
||||
#+begin_src emacs-lisp |
|
||||
(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/")) |
|
||||
#+end_src |
|
||||
|
|
||||
+ Open an agenda buffer with =SPC a= |
|
||||
|
|
||||
#+begin_src emacs-lisp |
|
||||
(dotfiles/leader |
|
||||
"a" '(org-agenda :which-key "Agenda")) |
|
||||
#+end_src |
|
||||
|
|
||||
* Footnotes |
|
||||
|
|
||||
[fn:1] https://orgmode.org |
|
||||
|
|
||||
[fn:2] https://emacswiki.org/emacs/InteractiveSpell |
|
||||
|
|
||||
[fn:3] https://emacswiki.org/emacs/FlySpell |
|
||||
|
|
||||
[fn:4] https://github.com/bnbeckwith/writegood-mode |
|
||||
|
|
||||
[fn:5] https://github.com/org-roam/org-roam |
|
||||
|
|
||||
[fn:6] https://github.com/org-roam/org-roam-server |
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue