9.2 KiB
Org is a package that allows you to create files like this one that look nice while also being able to run code. In this file, the code being run is stored in code blocks and all other text is disregarded.
Org Setup
This installs the org package and creates a setup function to enable/disable certain functionalities.
;; Setup org mode
(defun jm/org-mode-setup ()
(org-indent-mode)
(flyspell-mode)
(variable-pitch-mode 1)
(visual-line-mode 1)
(add-to-list 'org-link-frame-setup '(file . find-file))) ; Open link in current window not other window.
(use-package org
:hook (org-mode . jm/org-mode-setup)
:config
(setq org-ellipsis " ▾"
org-hide-emphasis-markers t
org-src-preserve-indentation t
;; Default export configuration
org-export-with-toc nil
org-export-with-section-numbers nil
org-export-with-sub-superscripts nil
;; Org agenda timestamp formatting
org-display-custom-times t
org-time-stamp-custom-formats '("%m-%d-%y %a" . "%m-%d-%y %a %I:%M %p"))
(jm/leader-keys
"oa" '(org-agenda :which-key "Org agenda")))
Evil Org
By default, many of the org specific keybindings do not feel intuitive when using evil mode. evil-org
is a package that attempts to fix this by rebinding many of the default org keybindings to work better with Evil mode.
(use-package evil-org
:after org
:hook (org-mode . (lambda () evil-org-mode))
:config
(require 'evil-org-agenda)
(evil-org-agenda-set-keys))
Org Agenda
Org mode by default contains an agenda system which is like a basic calendar that allows you to schedule todo items from org documents. All of the todo items from each org document are stored in a central area to allow for a formation of an agenda.
(setq org-agenda-start-with-log-mode t)
(setq org-log-done 'time)
(setq org-log-into-drawer t)
(setq org-priority-default ?D)
(setq org-priority-lowest ?D)
Refresh Org Agenda Files
Creates a function to refresh the org-agenda-files
variable to be set to include all org roam notes files.
(defun jm/org-roam-refresh-agenda-list ()
(interactive)
(setq org-agenda-files
(seq-uniq (mapcar
#'org-roam-node-file
(org-roam-node-list)))))
Custom States
Adds custom states to tasks such as IN PROGRESS
, CANCELLED
, etc. I've also added some changes to the color of the todo items based on the status. For example, turning the task face orange if it is in progress.
(setq org-todo-keyword-faces '(("IN PROGRESS" . (:foreground "orange" :weight bold))
("WAITING" . (:foreground "yellow" :weight bold))))
(setq org-todo-keywords '((sequence "TODO(t)" "IN PROGRESS(i)" "WAITING(w)" "|" "DONE(d)" "CANCELLED(c)")))
Refresh Checkboxes
Adds a hook to repeated tasks in org agenda that, when repeated, checkboxes will be reset to an unchecked state.
(add-hook 'org-todo-repeat-hook #'org-reset-checkbox-state-subtree)
Cosmetics
Org-Bullets
Org-bullets is a package that adds bullets to each heading instead of asterisks. It just makes org files nicer to look at.
; Org-bullets for better headings
(use-package org-bullets
:after org
:hook (org-mode . org-bullets-mode)
:custom
(org-bullets-bullet-list '("◉" "○" "●" "○" "●" "○" "●")))
Add List Dots
By default lists are started with a hyphen, though this doesn't really match the aesthetic of the rest of the org file. Due to that, I added this line which replaces the hyphen with a dot.
- Bullet point 1
- Bullet point 2
- Bullet point 3
; Replace - lists with a dot
(font-lock-add-keywords 'org-mode
'(("^ *\\([-]\\) "
(0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "•"))))))
Font Changes
Org-faces changes the font size of the headings to make them bigger in the org file. Though this code also changes the font to a variable-pitch font. To make it so that only fixed-pitch fonts are used in things like code blocks, set-face-attribute is used below.
(with-eval-after-load 'org-faces
; Set faces for heading size levels
(dolist (face '((org-level-1 . 1.2)
(org-level-2 . 1.1)
(org-level-3 . 1.05)
(org-level-4 . 1.0)
(org-level-5 . 1.0)
(org-level-6 . 1.0)
(org-level-7 . 1.0)
(org-level-8 . 1.0)))
(set-face-attribute (car face) nil :font "Fira Code Light" :weight 'regular :height (cdr face)))
; Ensure that anything that should be fixed-pitch in Org files appears that way
(set-face-attribute 'org-block nil :foreground nil :inherit 'fixed-pitch)
(set-face-attribute 'org-table nil :inherit 'fixed-pitch)
(set-face-attribute 'org-formula nil :inherit 'fixed-pitch)
(set-face-attribute 'org-code nil :inherit '(shadow fixed-pitch))
(set-face-attribute 'org-table nil :inherit '(shadow fixed-pitch))
(set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch))
(set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch))
(set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch))
(set-face-attribute 'org-checkbox nil :inherit 'fixed-pitch)
(set-face-attribute 'line-number nil :inherit 'fixed-pitch)
(set-face-attribute 'line-number-current-line nil :inherit 'fixed-pitch))
Visual Fill Column
Visual fill column is a package that allows you to center text and add borders to the sides of an org file. By default org files are displayed completely to the left side of the page like normal text files.
; Set left-right margins with visual-fill-column
(defun jm/org-mode-visual-fill ()
(setq visual-fill-column-width 100
visual-fill-column-center-text t)
(visual-fill-column-mode 1))
(use-package visual-fill-column
:after org
:hook (org-mode . jm/org-mode-visual-fill))
Org Roam
Org-roam is a plain-text knowledge management system. It brings some of Roam's more powerful features into the Org-mode ecosystem such as org-file linking, etc.
(use-package org-roam
:demand t
:custom
(org-roam-directory (file-truename "~/Dropbox/org"))
:bind (("C-c n l" . org-roam-buffer-toggle)
("C-c n f" . org-roam-node-find)
("C-c n i" . org-roam-node-insert)
("C-c n c" . org-roam-capture)
("C-c n o" . org-id-get-create)
;; Dailies
("C-c n j" . org-roam-dailies-capture-today)
("C-c n k" . org-roam-dailies-capture-tomorrow))
:config
;; Config for org-roam capture templates.
(setq jm/org-roam-templates-directory (expand-file-name "templates" org-roam-directory)
org-roam-capture-templates
`(("d" "Default" plain "%?"
:target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
:unnarrowed t)
("p" "Project" plain
(file ,(expand-file-name "project.org" jm/org-roam-templates-directory))
:target (file+head "%<%Y%m%d%H%M%S>-${slug}.org"
"#+title: ${title}\n")
:unnarrowed t)))
(setq org-roam-dailies-capture-templates
`(("d" "Default" entry "* %?" :target
(file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n"))
("t" "Daily Todos" entry
(file ,(expand-file-name "daily.org" jm/org-roam-templates-directory))
:target (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n")
:unnarrowed t)))
;; Create org roam directory and templates directory if not found.
(unless (file-directory-p org-roam-directory)
(make-directory org-roam-directory))
(unless (file-directory-p jm/org-roam-templates-directory)
(make-directory jm/org-roam-templates-directory))
(setq org-roam-node-display-template (concat "${title:*} " (propertize "${tags:10}" 'face 'org-tag)))
(require 'org-roam-dailies)
(org-roam-db-autosync-mode)
(jm/org-roam-refresh-agenda-list))
Fix Snippets
This is required as of org 9.2 as snippets such as <s
don't work. Without this fix, you are required to manually type out structures like code blocks.
(require 'org-tempo)
Ispell
Configure Ispell
to not spell check certain org mode specific keywords. By default, Ispell
doesn't have a default dictionary selected. This can be changed by running ispell-change-dictionary
. If no dictionaries are found, you can install them from the hunspell-en_us
pacman package.
(add-to-list 'ispell-skip-region-alist '(":\\(PROPERTIES\\|LOGBOOK\\):" . ":END:")) ;
(add-to-list 'ispell-skip-region-alist '("#\\+BEGIN_SRC" . "#\\+END_SRC"))
(add-to-list 'ispell-skip-region-alist '("~" . "~"))
(add-to-list 'ispell-skip-region-alist '("\\[\\[" . "\\]"))