449 lines
13 KiB
Org Mode
449 lines
13 KiB
Org Mode
#+title: Emacs Custom Configuration File
|
|
#+PROPERTY: header-args:emacs-lisp :tangle ~/dotfiles/.config/doom/config.el :mkdirp yes :lexical yes
|
|
|
|
* Preface
|
|
|
|
This document contains the fundamental elements of my Emacs configuration. Changes made to this file will reflect in init.el.
|
|
|
|
* Doom Startup Configuration
|
|
|
|
I need to test that I can remove this still.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; Some functionality uses this to identify you, e.g. GPG configuration, email
|
|
;; clients, file templates and snippets.
|
|
(setq user-full-name "Ry"
|
|
user-mail-address "ry@opal.sh")
|
|
|
|
;; There are two ways to load a theme. Both assume the theme is installed and
|
|
;; available. You can either set `doom-theme' or manually load a theme with the
|
|
;; `load-theme' function. This is the default:
|
|
(setq doom-theme 'modus-operandi)
|
|
|
|
;; If you use `org' and don't want your org files in the default location below,
|
|
;; change `org-directory'. It must be set before org loads!
|
|
(setq org-directory "~/org/")
|
|
|
|
;; This determines the style of line numbers in effect. If set to `nil', line
|
|
;; numbers are disabled. For relative line numbers, set this to `relative'.
|
|
(setq display-line-numbers-type t)
|
|
|
|
#+end_src
|
|
|
|
* General Configuration
|
|
** User Interface
|
|
|
|
#+begin_src emacs-lisp
|
|
|
|
;; Set visible bell
|
|
(setq visible-bell t)
|
|
|
|
(dolist (mode '(org-mode-hook
|
|
term-mode-hook
|
|
shell-mode-hook
|
|
eshell-mode-hook))
|
|
(add-hook mode (lambda () (display-line-numbers-mode 0))))
|
|
|
|
#+end_src
|
|
|
|
* Theme Configuration
|
|
I am using [[https://protesilaos.com/modus-themes/][Modus Themes]], by [[https://protesilaos.com/][Protesilaos Stavrou]] as they are minimal, pleasant to the eye, and conform to accessibility standards as outlined in [[https://www.w3.org/WAI/WCAG2AAA-Conformance][WCAG AAA]].
|
|
|
|
** Modus Theme Configuration
|
|
|
|
#+begin_src emacs-lisp
|
|
|
|
;; Configure Modus theme
|
|
(use-package modus-themes
|
|
:init
|
|
(setq modus-themes-italic-constructs t
|
|
modus-themes-bold-constructs nil
|
|
modus-themes-region '(accented bg-only no-extend)
|
|
modus-themes-org-blocks 'greyscale
|
|
modus-themes-paren-match 'intense
|
|
modus-themes-mixed-fonts t)
|
|
|
|
;; Load the theme files before enabling a theme
|
|
(modus-themes-load-themes)
|
|
:config
|
|
|
|
(modus-themes-load-vivendi) ;; OR (modus-themes-load-operandi)
|
|
:bind ("<f5>" . modus-themes-toggle))
|
|
|
|
#+end_src
|
|
|
|
** Font Configuration
|
|
|
|
Using [[https://github.com/tonsky/FiraCode][Fira Code]] + Fira Code Retina.
|
|
|
|
#+begin_src emacs-lisp
|
|
|
|
;; Set fonts
|
|
(set-face-attribute 'default nil :font "Fira Code" :height 125 :weight 'medium)
|
|
(set-face-attribute 'variable-pitch nil :font "Fira Sans" :height 1.0 :weight 'regular)
|
|
(set-face-attribute 'fixed-pitch nil :font "Fira Code" :height 1.0 :weight 'medium)
|
|
|
|
#+end_src
|
|
|
|
* Org Mode Configuration
|
|
|
|
** Set Fonts and Symbols
|
|
Here we are setting general font configuration in order to make editing in org mode a bit more streamlined to look at.
|
|
|
|
*** Set bullets instead of dashes
|
|
|
|
#+begin_src emacs-lisp
|
|
|
|
(defun rymacs/org-font-setup ()
|
|
;; Replace list hyphen with dot
|
|
(font-lock-add-keywords 'org-mode
|
|
'(("^ *\\([-]\\) "
|
|
(0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "•"))))))
|
|
|
|
;; Set faces for heading 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.1)
|
|
(org-level-6 . 1.1)
|
|
(org-level-7 . 1.1)
|
|
(org-level-8 . 1.1)))
|
|
(set-face-attribute (car face) nil :font "Cantarell" :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))
|
|
|
|
#+end_src
|
|
|
|
** General Configuration
|
|
|
|
Main Org/Agenda configuration.
|
|
|
|
#+begin_src emacs-lisp
|
|
|
|
(defun rymacs/org-mode-setup ()
|
|
(org-indent-mode)
|
|
(variable-pitch-mode 1)
|
|
(visual-line-mode 1)
|
|
(setq org-startup-folded t))
|
|
|
|
(use-package org
|
|
:commands (org-capture org-agenda)
|
|
:hook (org-mode . rymacs/org-mode-setup)
|
|
:config
|
|
(setq org-ellipsis " ▾")
|
|
|
|
(setq org-agenda-start-with-log-mode t)
|
|
(setq org-log-done 'time)
|
|
(setq org-log-into-drawer t)
|
|
|
|
(setq org-agenda-files
|
|
'("~/org/planner"
|
|
"~/org/projects"
|
|
"~/org/archive"
|
|
"~/org/notes"))
|
|
|
|
(require 'org-habit)
|
|
(add-to-list 'org-modules 'org-habit)
|
|
(setq org-habit-graph-column 60)
|
|
|
|
(setq org-todo-keywords
|
|
'((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d!)")
|
|
(sequence "BACKLOG(b)" "PLAN(p)" "READY(r)" "ACTIVE(a)" "REVIEW(v)" "WAIT(w@/!)" "HOLD(h)" "|" "COMPLETED(c)" "CANC(k@)")))
|
|
|
|
(setq org-refile-targets
|
|
'(("archive.org" :maxlevel . 1)
|
|
("planner.org" :maxlevel . 1)))
|
|
|
|
;; Save Org buffers after refiling!
|
|
(advice-add 'org-refile :after 'org-save-all-org-buffers)
|
|
|
|
(setq org-tag-alist
|
|
'((:startgroup)
|
|
; Put mutually exclusive tags here
|
|
(:endgroup)
|
|
("@errand" . ?E)
|
|
("@home" . ?H)
|
|
("@work" . ?W)
|
|
("agenda" . ?a)
|
|
("planning" . ?p)
|
|
("publish" . ?P)
|
|
("batch" . ?b)
|
|
("note" . ?n)
|
|
("idea" . ?i)))
|
|
|
|
;; Configure custom agenda views
|
|
(setq org-agenda-custom-commands
|
|
'(("d" "Dashboard"
|
|
((agenda "" ((org-deadline-warning-days 7)))
|
|
(todo "NEXT"
|
|
((org-agenda-overriding-header "Next Tasks")))
|
|
(tags-todo "agenda/ACTIVE" ((org-agenda-overriding-header "Active Projects")))))
|
|
|
|
("n" "Next Tasks"
|
|
((todo "NEXT"
|
|
((org-agenda-overriding-header "Next Tasks")))))
|
|
|
|
;; Low-effort next actions
|
|
("e" tags-todo "+TODO=\"NEXT\"+Effort<15&+Effort>0"
|
|
((org-agenda-overriding-header "Low Effort Tasks")
|
|
(org-agenda-max-todos 20)
|
|
(org-agenda-files org-agenda-files)))))
|
|
|
|
(setq org-capture-templates
|
|
`(("t" "Tasks")
|
|
("tt" "Task" entry (file+olp "~/org/planner/tasks.org" "Inbox")
|
|
"* TODO %?\n %U\n %a\n %i" :empty-lines 1)
|
|
|
|
("p" "Projects")
|
|
("pp" "Project File" entry (file+olp "~/org/projects/auto-infra-overview.org" "Inbox")
|
|
"* TODO %?\n %U\n %a\n %i" :empty-lines 1)
|
|
|
|
("j" "Journal Entries")
|
|
("jj" "Journal" entry
|
|
(file+olp+datetree "~/org/planner/journal.org")
|
|
"\n* %<%I:%M %p> - Journal :journal:\n\n%?\n\n"
|
|
:clock-in :clock-resume
|
|
:empty-lines 1)))
|
|
|
|
(rymacs/org-font-setup))
|
|
|
|
#+end_src
|
|
|
|
|
|
** Better Heading Bullets
|
|
|
|
#+begin_src emacs-lisp
|
|
|
|
;; Change default pretty bullets to circles
|
|
(use-package org-bullets
|
|
:after org
|
|
:hook (org-mode . org-bullets-mode)
|
|
:custom
|
|
(org-bullets-bullet-list '("◉" "○" "●" "○" "●" "○" "●")))
|
|
|
|
#+end_src
|
|
|
|
** Center Org Buffers
|
|
|
|
#+begin_src emacs-lisp
|
|
|
|
(defun rymacs/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
|
|
:hook (org-mode . rymacs/org-mode-visual-fill))
|
|
|
|
#+end_src
|
|
|
|
** Org Babel
|
|
|
|
Org Babel allows us to evaluate source code blocks within org mode. With this functionality, we can tell org babel to insert the content of the source block codes into any file specified by using the org-babel-tangle function.
|
|
|
|
*** Babel Languages
|
|
|
|
#+begin_src emacs-lisp
|
|
|
|
;; Load languages for babel code blocks.
|
|
(with-eval-after-load 'org
|
|
(org-babel-do-load-languages
|
|
'org-babel-load-languages
|
|
'((emacs-lisp . t)
|
|
(python .t)))
|
|
|
|
(push '("conf-unix" . conf-unix) org-src-lang-modes))
|
|
|
|
#+end_src
|
|
|
|
|
|
*** Soure Block Creation Shortcuts
|
|
|
|
Here we use a package called org-tempo.
|
|
|
|
#+begin_src emacs-lisp
|
|
|
|
;; Make shortcuts to easily create babel source code blocks.
|
|
(with-eval-after-load 'org
|
|
(require 'org-tempo)
|
|
|
|
(add-to-list 'org-structure-template-alist '("sh" . "src shell"))
|
|
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
|
|
(add-to-list 'org-structure-template-alist '("py" . "src python")))
|
|
|
|
#+end_src
|
|
|
|
|
|
*** Babel Configuration File Automation Hook
|
|
|
|
TODO: This needs to be fixed, or find an equiv.
|
|
Since we don't want to have to manually use the org-babel-tangle function everytime we make changes to the corresponding .org file, we create an automation hook that executes the function every time we save.
|
|
|
|
#+begin_src emacs-lisp
|
|
|
|
;; ;; Define a function that automatically executes rymacs/org-babel-tangle-config (a wrapper around org-babel-tangle) when saving this file.
|
|
;; (defun rymacs/org-babel-tangle-config ()
|
|
;; (when (string-equal (file-name-directory (buffer-file-name))
|
|
;; (expand-file-name "~/.dotfiles/.config/doom"))
|
|
|
|
;; (let ((org-confirm-babel-evaluate nil))
|
|
;; (org-babel-tangle))))
|
|
|
|
;; (add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook #'rymacs/org-babel-tangle-config)))
|
|
|
|
#+end_src
|
|
|
|
* Org Roam Configuration
|
|
|
|
#+begin_src emacs-lisp
|
|
|
|
(use-package org-roam
|
|
:init
|
|
(setq org-roam-v2-ack t)
|
|
:custom
|
|
(org-roam-directory "~/roam")
|
|
(org-roam-completion-everywhere t)
|
|
(org-roam-capture-templates
|
|
'(("d" "default" plain
|
|
"%?"
|
|
:if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
|
|
:unnarrowed t)
|
|
("r" "def+resources" plain
|
|
(file "~/roam/templates/resource-template.org")
|
|
:if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
|
|
:unnarrowed t)))
|
|
: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 I" . org-roam-node-insert-immediate)
|
|
("C-c n p" . my/org-roam-find-project)
|
|
:map org-mode-map
|
|
("C-M-i" . completion-at-point)
|
|
:map org-roam-dailies-map
|
|
("Y" . org-roam-dailies-capture-yesterday)
|
|
("T" . org-roam-dailies-capture-tomorrow))
|
|
:bind-keymap
|
|
("C-c n d" . org-roam-dailies-map)
|
|
:config
|
|
(require 'org-roam-dailies) ;; Ensure the keymap is available
|
|
(org-roam-db-autosync-mode))
|
|
|
|
(defun org-roam-node-insert-immediate (arg &rest args)
|
|
(interactive "P")
|
|
(let ((args (cons arg args))
|
|
(org-roam-capture-templates (list (append (car org-roam-capture-templates)
|
|
'(:immediate-finish t)))))
|
|
(apply #'org-roam-node-insert args)))
|
|
|
|
#+end_src
|
|
|
|
** Deft Configuration
|
|
|
|
Deft is a package that helps browse and filter plain text files. I use it to search through org-roam notes.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package deft
|
|
:after org
|
|
:bind
|
|
("C-c n d" . deft)
|
|
:custom
|
|
(deft-recursive t)
|
|
(deft-use-filter-string-for-filename t)
|
|
(deft-default-extension "org")
|
|
(deft-directory org-roam-directory))
|
|
#+end_src
|
|
|
|
* Mu4e (E-mail)
|
|
** Important Account information:
|
|
*** Opal.sh
|
|
- IMAP: imap.opal.sh -- 993
|
|
- SMTP smtp.opal.sh -- 587
|
|
- Username: ry@opal.sh
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package mu4e
|
|
:config
|
|
;; This is set to 't' to avoid mail syncing issues when using mbsync
|
|
(setq mu4e-change-filenames-when-moving t)
|
|
|
|
;; Refresh mail using isync every 5 minutes
|
|
(setq mu4e-update-interval (* 5 60))
|
|
(setq mu4e-get-mail-command "mbsync -a -c ~/dotfiles/.config/mbsync/mbsyncrc")
|
|
(setq mu4e-maildir "~/mail")
|
|
|
|
(setq mu4e-contexts
|
|
(list
|
|
;; Opal.sh
|
|
(make-mu4e-context
|
|
:name "Opal.sh"
|
|
:match-func
|
|
(lambda (msg)
|
|
(when msg
|
|
(string-prefix-p "/opal.sh" (mu4e-message-field msg :maildir))))
|
|
|
|
:vars '((user-mail-address . "ry@opal.sh")
|
|
(user-full-name . "Opal.sh")
|
|
(mu4e-drafts-folder . "/opal.sh/Drafts")
|
|
(mu4e-sent-folder . "/opal.sh/Sent")
|
|
(mu4e-trash-folder . "/opal.sh/Trash")))))
|
|
|
|
(setq mu4e-maildir-shortcuts
|
|
'(("/opal.sh/Inbox" . ?i)
|
|
("/opal.sh/Sent" . ?s)
|
|
("/opal.sh/Trash" . ?t)
|
|
("/opal.sh/Drafts" . ?d))))
|
|
#+end_src
|
|
* ERC (IRC)
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq erc-server "irc.libera.chat" ;sets default server
|
|
erc-nick "libry" ; Sets nick
|
|
erc-user-full-name "ry"
|
|
erc-track-shorten-start 8
|
|
erc-autojoin-channels-alist '(("irc.libera.chat" "#guix" "#emacs" "#systemcrafters"))
|
|
erc-kill-buffer-on-part t
|
|
erc-auto-query 'bury
|
|
erc-fill-column 120
|
|
erc-fill-function 'erc-fill-static
|
|
erc-fill-static-center 20
|
|
erc-track-visibility nil
|
|
erc-interpret-mirc-color t
|
|
erc-rename-buffers t
|
|
erc-track-exclude-server-buffer t)
|
|
#+end_src
|
|
* Elfeed (RSS)
|
|
|
|
#+begin_src emacs-lisp
|
|
(global-set-key (kbd "C-x w") 'elfeed) ; set elfeed keybind
|
|
|
|
(setq elfeed-feeds
|
|
'(; websites
|
|
"https://landchad.net/rss.xml"
|
|
"http://stallman.org/rss/rss.xml"
|
|
"https://guix.gnu.org/feeds/blog.atom"
|
|
; twitter/nitter
|
|
"https://nitter.net/fsf/rss"
|
|
; tube
|
|
"https://odysee.com/$/rss/@AlphaNerd:8")
|
|
#+end_src
|
|
* Magit (Git)
|
|
|
|
#+begin_src emacs-lisp
|
|
|
|
|
|
|
|
|
|
#+end_src
|