diff --git a/README.org b/README.org index 20abef1..fc493df 100644 --- a/README.org +++ b/README.org @@ -35,7 +35,7 @@ All of the options available for configuration are defined here. They may be ove terminal passwords pinentry desktop - writing + roam agenda spelling grammar presentations website capture diff --git a/docs/tasks.org.gpg b/docs/tasks.org.gpg index 0131d75..9584e95 100644 Binary files a/docs/tasks.org.gpg and b/docs/tasks.org.gpg differ diff --git a/init.el b/init.el index 6753bbf..2f20bea 100644 --- a/init.el +++ b/init.el @@ -13,7 +13,7 @@ terminal passwords pinentry desktop - writing + roam agenda spelling grammar presentations website capture diff --git a/modules/agenda.org b/modules/agenda.org new file mode 100644 index 0000000..774b121 --- /dev/null +++ b/modules/agenda.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 diff --git a/modules/grammar.org b/modules/grammar.org new file mode 100644 index 0000000..7942ce5 --- /dev/null +++ b/modules/grammar.org @@ -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 diff --git a/modules/pinentry.org b/modules/pinentry.org index b3bd7dd..16ee41e 100644 --- a/modules/pinentry.org +++ b/modules/pinentry.org @@ -59,11 +59,4 @@ Override ~org-agenda-file-regexp~ to include =.org.gpg= files. org-agenda-file-regexp))) #+end_src -Encrypt new files from capture templates. - -#+begin_src emacs-lisp -(with-eval-after-load 'org-roam - (setq org-roam-encrypt-files t)) -#+end_src - * Footnotes diff --git a/modules/roam.org b/modules/roam.org new file mode 100644 index 0000000..acfae18 --- /dev/null +++ b/modules/roam.org @@ -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 diff --git a/modules/spelling.org b/modules/spelling.org new file mode 100644 index 0000000..0dfd500 --- /dev/null +++ b/modules/spelling.org @@ -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 diff --git a/modules/writing.org b/modules/writing.org deleted file mode 100644 index 9ad0363..0000000 --- a/modules/writing.org +++ /dev/null @@ -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