doom/config.org
J S 591c565087
feat[all] Added and removed many things
I changed the theme to doom-homage.
I removed funny stuff to slim down a bit.
I changed the org-capture keybinds and added a category for school.
I added org-super-agenda and corrected agenda keybinds.
I added lilypond editing.
I removed calfw calendar view.
I removed extraneous weblorg settings.
I removed org-roam-ui settings that were unecessary.
I added vterm and multipe-cursors.
2024-04-08 12:01:27 -04:00

1437 lines
47 KiB
Org Mode

#+TITLE: Doom-emacs config
#+AUTHOR: Judah Sotomayor
#+STARTUP: overview
Welcome to my configuration!
I hope you enjoy your time here :)
It's not all very well documented, but I have done my best to split everything into a logical order.
Perhaps in 10 years I will still be using it, but who knows.
* Task List
** TODO Reorganize into use-cases rather than packages
* Setting Basics
** Packages
#+begin_src emacs-lisp :tangle "packages.el"
;; -*- no-byte-compile: t; -*-
#+end_src
** Set name, org-roam-directory, etc.
Some basic settings for Emacs
#+begin_src emacs-lisp
(setq tab-always-indent t)
(setq org-roam-directory "~/org/")
(setq user-full-name "Judah Sotomayor"
user-mail-address "")
#+end_src
#+begin_src emacs-lisp :tangle "packages.el"
(package! noCtrlC
:recipe (:host nil :type git :repo "https://git.freedomland.xyz/judahsotomayor/noctrlc"))
#+end_src
* Theme and Font
Set the theme.
/Use something dark/
+I also prefer relative line numbers because of *evil* mode+
Relative line numbers don't seem to work, because of folding in Org-mode.
#+begin_src emacs-lisp
(setq doom-theme 'doom-oksolar-dark)
(condition-case nil
(setq doom-font (font-spec :family "Hack Nerd Font Mono" :size 16 :weight 'medium))
(error (set-face-attribute 'default nil :height 130)))
(setq auto-save-default nil) ;I don't like autosaving. Let me do it myself.
#+end_src
#+RESULTS:
** Doom splash screen
I really don't like the widgets, and I think it takes longer to load so I get rid of them
#+begin_src emacs-lisp
(remove-hook '+doom-dashboard-functions #'doom-dashboard-widget-shortmenu)
(remove-hook '+doom-dashboard-functions #'doom-dashboard-widget-footer)
#+end_src
Set a sweet splash image
#+begin_src emacs-lisp
(setq fancy-splash-image (concat doom-private-dir "emacs.png"))
#+end_src
* Evil configuration
I want a non-ESC way to get back to normal mode:
#+begin_src emacs-lisp
(map! :desc "Switch to normal mode" :i "C-c" #'evil-normal-state)
(after! org-mode (map! :desc "Delete previous character in insert mode" :i "C-h" #'evil-delete-backward-char))
(map! :desc "Increment number below or after cursor" :n "C-a" #'evil-numbers/inc-at-pt)
(map! :desc "Decrement number below or after cursor" :n "C-x" #'evil-numbers/dec-at-pt)
(map! :n "g j" #'evil-next-visual-line)
(map! :n "g k" #'evil-previous-visual-line)
#+end_src
* Terminal setup
I like to just use bash:
#+begin_src emacs-lisp
(defun bash nil
"Lauch term with /bin/bash"
(interactive)
(term "/bin/bash"))
(defun dash nil
"Lauch term with /bin/dash"
(interactive)
(term "/bin/dash"))
(defun zsh nil
"Lauch term with /bin/zsh"
(interactive)
(term "/bin/zsh"))
#+end_src
#+RESULTS:
: zsh
** Shell mappings
#+begin_src emacs-lisp
(map! :leader (:prefix ("k" . "shell")
:desc "Start a bash shell"
:n "b" #'bash
:desc "Start a dash shell"
:n "d" #'dash
:desc "Start a zsh shell"
:n "z" #'zsh
:desc "Start an elisp repl"
:n "e" #'+emacs-lisp/open-repl
:desc "Start a python repl"
:n "j" #'+python/open-repl))
#+end_src
#+RESULTS:
,#+RESULTS:
I don't like the modeline in the terminal.
,#+begin_src emacs-lisp
(add-hook 'term-mode-hook 'hide-mode-line-mode)
#+end_src
* Sage-math
#+begin_src emacs-lisp
(use-package! sage-shell-mode
:defer)
;; Ob-sagemath supports only evaluating with a session.
(setq org-babel-default-header-args:sage '((:session . t)
(:results . "output")))
;; C-c c for asynchronous evaluating (only for SageMath code blocks).
(with-eval-after-load "org"
(define-key org-mode-map (kbd "C-c c") 'ob-sagemath-execute-async))
#+end_src
I like to have a shortcut for calc as well, for simpler calculations
#+begin_src emacs-lisp
(map! :leader
:desc "The Emacs Calculator"
"C" #'calc)
#+end_src
* Beancount
** FavaGTK :outdated:
I want to launch favagtk more easily. Let's do that here:
#+begin_src emacs-lisp
(defun fava ()
(interactive)
(async-shell-command "flatpak run org.gnome.gitlab.johannesjh.favagtk"))
(map! :leader
:desc "Start favagtk"
"r b" #'fava)
#+end_src
* Useful Functions
** Get the date from the shell
I want to grab the current date and put it in the buffer.
Because I sometimes use Fish or another shell, it's good to make sure bash is running the command using the src_bash{`-c`} flag.
#+begin_src emacs-lisp
(defun current-date () (interactive)
(shell-command-to-string " bash -c 'echo -n $(date +%Y-%m-%d)'"))
(defun insert-current-date () (interactive)
(insert (current-date)))
(map! :leader
:desc "Insert the current date into the buffer"
"i d" #'insert-current-date)
#+end_src
** Convert regex strings to rx
#+begin_src elisp :tangle packages.el
(package! xr)
#+end_src
#+begin_src elisp
(use-package! xr)
#+end_src
* Creating Diagrams and graphs
** TODO set default values using org-babel's features for that.
* Securing Sensitive Files
** Age.el
#+begin_src emacs-lisp :tangle "packages.el"
(package! age)
#+end_src
*** Config
#+begin_src emacs-lisp
(use-package! age
:ensure t
:demand t
:custom
(age-program "age")
(age-default-identity "~/.age/personal")
(age-default-recipient "~/.age/personal.pub")
:config
(age-file-enable))
#+end_src
*** Preprocessor
:PROPERTIES:
:CUSTOM_ID: ripgrep-pre
:END:
This preprocessor script allows me to use Ripgrep with Age to filter agenda files.
You can see the configuration for that in [[#agenda-efficient][this section]].
#+begin_src zsh :tangle "/home/user/age-preprocessor.zsh"
#!/usr/bin/env zsh
case "$1" in
*.age)
# The -s flag ensures that the file is non-empty.
if [ -s "$1" ]; then
exec /usr/bin/age --decrypt -i ~/.age/personal $1
else
exec cat
fi
;;
*)
;;
esac
#+end_src
** Org-mode security settings
These mostly concern limiting evaluation of code-blocks without confirmation.
The final two lines concern local variables, which may try to evaluate code.
Emacs has better default values now, so it will ask to evaluate local variables.
#+begin_src emacs-lisp
(setq org-confirm-babel-evaluate t)
(setq org-link-shell-confirm-function t)
(setq org-link-elisp-confirm-function t)
(setq enable-local-variables t)
(setq enable-local-eval 'maybe)
#+end_src
#+begin_src emacs-lisp
(setq templates/post-capture-props "#+date: [%<%Y-%m-%d %a>]\n#+lastmod:\n#+categories[]:\n#+tags[]:\n#+images[]: ")
(setq templates/post-capture-title "#+TITLE: ${title}\n")
(setq templates/post-capture-template (concat templates/post-capture-title templates/post-capture-props))
#+end_src
* Org-mode for a great todo list
** Making the Agenda features more efficient
Using ripgrep we can automatically narrow org-agenda files.
*** Finding Files with Ripgrep
:PROPERTIES:
:CUSTOM_ID: agenda-efficient
:END:
This piece of code will allow us to capture all the agenda files using the preprocessor we wrote [[#ripgrep-pre][here]]
#+name: search-agenda-files
#+begin_src sh :exports code :tangle no
rg --type-add 'aorg:*.org.age' \
-torg -taorg \
--pre ~/age-preprocessor.zsh --pre-glob '*.age' -l TODO /home/user/org
#+end_src
Now, of course, this code is not useful as it is--after all, we can't tangle a ~.sh~ script into [[file:config.el]].
*** Adding results to agenda files
The rubber hits the road here.
I'll call that shell command to set the agenda files correctly.
#+begin_src emacs-lisp
(defun set-org-agenda-files-ripgrep ()
(setq org-agenda-files (split-string (shell-command-to-string "rg --type-add \'aorg:*.org.age\' -torg -taorg --pre ~/age-preprocessor.zsh --pre-glob \'*.age\' -l TODO /home/user/org "))))
#+end_src
And then we want to call this before building the agenda:
#+begin_src emacs-lisp
(add-hook 'org-agenda-mode-hook 'set-org-agenda-files-ripgrep)
#+end_src
*** Filtering the agenda
I don't want scheduled items to duplicate if the deadline is up.
#+begin_src emacs-lisp
(after! org
(setq org-agenda-skip-scheduled-if-deadline-is-shown t))
;(setq org-agenda-start-day "-8d")
;(setq org-agenda-span 9)
;(setq org-agenda-todo-ignore-deadlines 'far)
;(setq org-agenda-tags-todo-honor-ignore-options t))
#+end_src
#+RESULTS:
: t
** Basic settings
#+begin_src emacs-lisp
(setq org-log-done 'time)
(after! org
(setq org-log-done 'time)
(setq org-archive-location "~/org/archive.org")
(setq org-hide-emphasis-markers nil))
(setq org-directory "~/org/")
(setq org-roam-directory org-directory)
#+end_src
*** Keymap
#+begin_src emacs-lisp
(map!
:map org-agenda-keymap
"j" #'evil-next-line
"k" #'evil-previous-line)
(map!
:map org-super-agenda-header-map
"j" #'evil-next-line
"k" #'evil-previous-line)
#+end_src
#+RESULTS:
** Appearances
*** Images Preferences
We want to show images when loading a file, and also after evaluating code blocks.
#+begin_src emacs-lisp
(setq org-startup-with-inline-images t)
;; Show images after evaluating code blocks.
(add-hook 'org-babel-after-execute-hook 'org-display-inline-images)
#+end_src
*** Org-super-agenda
Super-agenda allows many nice configurations to the agenda buffer.
#+begin_src emacs-lisp :tangle "packages.el"
(package! org-super-agenda)
#+end_src
Configure the Super Agenda to neatly organize everything.
#+begin_src emacs-lisp
(setq org-super-agenda-groups
'(;; Each group has an implicit boolean OR operator between its selectors.
(:name "Calendar"
:and (:todo nil :not (:scheduled (before "2024-03-17")) :not (:deadline (before "2024-03-17")))
:order 10)
(:name "Today" ; Optionally specify section name
:time-grid t ; Items that appear on the time grid
:todo "TODAY") ; Items that have this TODO keyword
(:name "Important"
;; Single arguments given alone
:tag "bills"
:priority<= "A")
(:name "Active Projects"
:and (:todo "PROJ"
:not (:scheduled (after "2024-03-17"))
:deadline (after "2024-03-17")))
(:name "School"
:tag "school" )
;; Set order of multiple groups at once
(:order-multi (2 (:name "Shopping in town"
;; Boolean AND group matches items that match all subgroups
:and (:tag "shopping" :tag "@town"))
(:name "Food-related"
;; Multiple args given in list with implicit OR
:tag ("food" "dinner"))
(:name "Habits"
:habit t
:tag "personal")
(:name "Space-related (non-moon-or-planet-related)"
;; Regexps match case-insensitively on the entire entry
:and (:regexp ("space" "NASA")
;; Boolean NOT also has implicit OR between selectors
:not (:regexp "moon" :tag "planet")))))
;; Groups supply their own section names when none are given
(:todo "WAITING" :order 8) ; Set order of this section
(:todo ("SOMEDAY" "TO-READ" "CHECK" "TO-WATCH" "WATCHING")
;; Show this group at the end of the agenda (since it has the
;; highest number). If you specified this group last, items
;; with these todo keywords that e.g. have priority A would be
;; displayed in that group instead, because items are grouped
;; out in the order the groups are listed.
:order 9)
(:priority<= "B"
;; Show this section after "Today" and "Important", because
;; their order is unspecified, defaulting to 0. Sections
;; are displayed lowest-number-first.
:order 1)
;; After the last group, the agenda will display items that didn't
;; match any of these groups, with the default order position of 99
))
#+end_src
** org-edna
#+begin_src emacs-lisp :tangle "packages.el"
(package! org-edna)
#+end_src
Edna allows better dependency handling for todos and the like.
#+begin_src emacs-lisp
(use-package! org-edna)
(org-edna-mode)
#+end_src
** Org-habit
#+begin_src emacs-lisp
(use-package org-habit
:custom
(org-habit-graph-column 1)
(org-habit-preceding-days 10)
(org-habit-following-days 1)
(org-habit-show-habits-only-for-today t))
#+end_src
** Anki editing in org-mode
Anki editor is a good one for large cards that need high complexity.
#+begin_src emacs-lisp :tangle packages.el
(package! anki-editor)
#+end_src
*** inline-anki
Inline anki is far better for small cards, and where it is best to maintain a /single source of truth/.
#+begin_src emacs-lisp :tangle packages.el
(package! asyncloop)
(package! inline-aki
:recipe (:host github :repo "meedstrom/inline-anki"))
#+end_src
#+begin_src emacs-lisp
(setq inline-anki-note-type "Katex and Markdown Cloze")
(setq inline-anki-use-tags t)
#+end_src
**** Inline Anki symbol
By default, [[*inline-anki][Inline-anki]] uses _underscore_ to specify the card type.
This is okay, but I'd rather find something that isn't already used.
#+begin_src emacs-lisp
(add-to-list 'org-emphasis-alist '("." nil))
(setq inline-anki-emphasis-type "_")
#+end_src
#+RESULTS:
: _
** calfw Calendar View :ARCHIVE:
#+begin_src emacs-lisp :tangle "packages.el"
(package! calfw
:recipe (:host github :type git :repo "haji-ali/emacs-calfw"))
#+end_src
* Programming Items
** Editorconfig
I need to make sure some different files work with
#+begin_src emacs-lisp
(after! editorconfig-mode
(add-to-list 'editorconfig-mode-alist
'(cpp-mode . "cpp")))
#+end_src
** LSP
In order for editorconfig to do its thing, indentation by the lsp must be disabled.
#+begin_src emacs-lisp
(setq lsp-enable-indentation nil)
#+end_src emacs-lisp
* Website
** Capture template
#+begin_src emacs-lisp
(setq templates/post-capture-props "#+date: [%<%Y-%m-%d %a>]\n#+lastmod:\n#+categories[]:\n#+tags[]:\n#+images[]: ")
(setq templates/post-capture-title "#+TITLE: ${title}\n")
(setq templates/post-capture-template (concat templates/post-capture-title templates/post-capture-props))
#+end_src
** Hugo base directory
#+begin_src emacs-lisp
(setq org-hugo-base-dir (concat org-directory (file-name-as-directory "website")))
(setq org-hugo-default-section-directory "posts")
#+end_src
* Crafting a Writing Environment
For writing I like to automate as much as possible.
This means creating an environment that does citations and such /for/ me.
** Export settings
*** Ox-latex
#+begin_src emacs-lisp
(after! org
;; Import ox-latex to get org-latex-classes and other funcitonality
;; for exporting to LaTeX from org
(use-package! ox-latex
:init
:config
(setq org-latex-with-hyperref nil) ;; stop org adding hypersetup{author..} to latex export
;; (setq org-latex-prefer-user-labels t)
(setq org-latex-logfiles-extensions
(quote ("lof" "lot" "tex~" "aux" "idx" "log" "out" "toc" "nav" "snm" "vrb" "dvi" "fdb_latexmk" "blg" "brf" "fls" "entoc" "ps" "spl" "bbl" "xmpi" "run.xml" "bcf" "acn" "acr" "alg" "glg" "gls" "ist")))
(unless (boundp 'org-latex-classes)
(setq org-latex-classes nil))))
#+end_src
*** Lualatex as PDF Processor
I've found that lualatex does a good job processing PDFs. $hi$
#+begin_src emacs-lisp
(after! ox-latex
(setq org-latex-pdf-process
'("lualatex --output-directory=/home/user/Documents -shell-escape -interaction nonstopmode %f")))
#+end_src
$x + 1 = 3$
#+RESULTS:
: luamagick
#+begin_src emacs-lisp
(setq-default org-html-with-latex 'verbatim)
(unless (boundp 'org-latex-classes)
(setq org-latex-classes nil))
(add-to-list 'org-latex-classes
'("ethz"
"\\documentclass[a4paper,11pt,titlepage]{memoir}
\\usepackage[utf8]{inputenc}
\\usepackage[T1]{fontenc}
\\usepackage{fixltx2e}
\\usepackage{graphicx}
\\usepackage{longtable}
\\usepackage{float}
\\usepackage{wrapfig}
\\usepackage{rotating}
\\usepackage[normalem]{ulem}
\\usepackage{amsmath}
\\usepackage{textcomp}
\\usepackage{marvosym}
\\usepackage{wasysym}
\\usepackage{amssymb}
\\usepackage[hidelinks]{hyperref}
\\usepackage{mathpazo}
\\usepackage{color}
\\usepackage{enumerate}
\\definecolor{bg}{rgb}{0.95,0.95,0.95}
\\tolerance=1000
[NO-DEFAULT-PACKAGES]
[PACKAGES]
[EXTRA]
\\linespread{1.1}
\\hypersetup{pdfborder=0 0 0}"
("\\chapter{%s}" . "\\chapter*{%s}")
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
(add-to-list 'org-latex-classes
'("article"
"\\documentclass[11pt,a4paper]{article}
\\usepackage[utf8]{inputenc}
\\usepackage[T1]{fontenc}
\\usepackage{fixltx2e}
\\usepackage{graphicx}
\\usepackage{longtable}
\\usepackage{float}
\\usepackage{wrapfig}
\\usepackage{rotating}
\\usepackage[normalem]{ulem}
\\usepackage{amsmath}
\\usepackage{textcomp}
\\usepackage{marvosym}
\\usepackage{wasysym}
\\usepackage{amssymb}
\\usepackage[hidelinks]{hyperref}
\\usepackage{mathpazo}
\\usepackage{color}
\\usepackage{enumerate}
\\definecolor{bg}{rgb}{0.95,0.95,0.95}
\\tolerance=1000
[NO-DEFAULT-PACKAGES]
[PACKAGES]
[EXTRA]
\\linespread{1.1}
\\hypersetup{pdfborder=0 0 0}"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")))
(add-to-list 'org-latex-classes '("ebook"
"\\documentclass[11pt, oneside]{memoir}
\\setstocksize{9in}{6in}
\\settrimmedsize{\\stockheight}{\\stockwidth}{*}
\\setlrmarginsandblock{2cm}{2cm}{*} % Left and right margin
\\setulmarginsandblock{2cm}{2cm}{*} % Upper and lower margin
\\checkandfixthelayout
% Much more laTeX code omitted
"
("\\chapter{%s}" . "\\chapter*{%s}")
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")))
#+end_src
#+RESULTS:
| mcdowellcv | \documentclass[]{mcdowellcv} |
*** COMMENT Fixing dvipng image handling
#+begin_src emacs-lisp
(defun +org-refresh-latex-images-previews-h ()
(dolist (buffer (doom-buffers-in-mode 'org-mode (buffer-list)))
(with-current-buffer buffer
(+org--toggle-inline-images-in-subtree (point-min) (point-max) 'refresh)
(unless (eq org-latex-preview-default-process 'dvisvgm)
(org-clear-latex-preview (point-min) (point-max))
(org--latex-preview-region (point-min) (point-max))))))
(add-hook 'doom-load-theme-hook #'+org-refresh-latex-images-previews-h)
#+end_src
*** Export Function
#+begin_src emacs-lisp
(defun eww-open-this-file ()
(set 'directory (file-name-directory buffer-file-name))
(set 'filename (file-name-sans-extension buffer-file-name))
(set 'extension ".html")
(set 'filename (format "%s%s" filename extension))
(eww-open-file filename)
(evil-window-left)
)
(defun org-export-and-open-eww ()
"Export current file to html and open in eww"
(interactive)
(org-html-export-to-html)
(if (equal (file-name-extension buffer-file-name) "org")
(eww-open-this-file)
(message "Failed")
)
)
#+end_src
We'll want a handy shortcut for this.
#+begin_src emacs-lisp
(map! :leader
:desc "Export to html and diplay with eww"
"r E" #'org-export-and-open-eww)
#+end_src
#+RESULTS:
: /home/user/.config/doom/
*** Delete links from inline anki
#+begin_src elisp
(defun inline-anki-link-filter (link backend info)
"Rewrite links in export to preserve link text only"
(if (eq backend 'inline-anki--ox-anki-html-backend)
(save-match-data ; is usually a good idea
(and (string-match "\\[(?:\\[([^\\]\\[]*)\\])(?:\\[(.*)\\])?\\]" link)
(match-string 2 link)))))
#+end_src
#+RESULTS:
: inline-anki-link-filter
#+begin_src elisp
(add-to-list 'org-export-filter-link-functions
'inline-anki-link-filter)
#+end_src
#+begin_src elisp
#+end_src
#+RESULTS:
| inline-anki-link-filter |
** Automatic Citations with *citar* and *org-cite*
:PROPERTIES:
:custom_id: citation-settings
:END:
Citar is a sweet little package for managing citations.
We want a general [[file:~/org/references.bib][bibliography file]], a [[file:~/Zotero/styles/][styles directory]],
and a default set of styles.
*** Citar setup
First of all, we must configure citar.
#+begin_src emacs-lisp
(use-package! citar
:ensure t
:demand t
:custom
(citar-bibliography "~/org/references.bib")
(citar-file-note-extensions '(".org"))
(org-cite-global-bibliography '("~/org/references.bib"))
(org-cite-csl-styles-dir
(expand-file-name "~/Zotero/styles/"))
(org-cite-export-processors
'((t . (csl "apa.csl")) ))
:hook
(LaTeX-mode . citar-capf-setup)
(org-mode . citar-capf-setup))
(citar-org-roam-mode)
#+end_src
*** Icons for some prettification
#+begin_src emacs-lisp
(after! citar
(setq citar-indicator-files-icons
(citar-indicator-create
:symbol (nerd-icons-faicon
"nf-fa-file_o"
:face 'nerd-icons-green
:v-adjust -0.1)
:function #'citar-has-files
:padding " " ; need this because the default padding is too low for these icons
:tag "has:files"))
(setq citar-indicator-links-icons
(citar-indicator-create
:symbol (nerd-icons-faicon
"nf-fa-link"
:face 'nerd-icons-orange
:v-adjust 0.01)
:function #'citar-has-links
:padding " "
:tag "has:links"))
(setq citar-indicator-notes-icons
(citar-indicator-create
:symbol (nerd-icons-codicon
"nf-cod-note"
:face 'nerd-icons-blue
:v-adjust -0.3)
:function #'citar-has-notes
:padding " "
:tag "has:notes"))
(setq citar-indicator-cited-icons
(citar-indicator-create
:symbol (nerd-icons-faicon
"nf-fa-circle_o"
:face 'nerd-icon-green)
:function #'citar-is-cited
:padding " "
:tag "is:cited"))
(setq citar-indicators
(list citar-indicator-files-icons
citar-indicator-links-icons
citar-indicator-notes-icons
citar-indicator-cited-icons)))
#+end_src
** Scholarly Writing Environment with Org-mode
I like to keep formatting simple.
Let's use a package or two to set a decent document class:
#+begin_src emacs-lisp
(add-to-list 'org-latex-classes
'("student-apa7"
"\\documentclass[stu]{apa7}
\\usepackage[]{multicol}
\\usepackage{mathptmx}
[NO-DEFAULT-PACKAGES]
[NO-PACKAGES]"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
(add-to-list 'org-latex-classes
'("student-turabian"
"\\documentclass{turabian-researchpaper}
\\usepackage[]{multicol}
\\usepackage{mathptmx}
[NO-PACKAGES]
"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}")
("\\usepackage{biblatex-chicago}")))
(add-to-list 'org-latex-classes
'("student-mla"
"\\documentclass[stu]{mla}
\\hypersetup{hidelinks}
\\usepackage[]{multicol}
\\usepackage{mathptmx} "
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
;; org-latex-compilers = ("pdflatex" "xelatex" "lualatex"), which are the possible values for %latex
#+end_src
*** Engraving Faces
Ever wonder why code export sucks with \LaTeX ? Me neither! Let's fix it!
#+begin_src emacs-lisp :tangle "packages.el"
(package! engrave-faces)
#+end_src
#+begin_src emacs-lisp
(use-package! engrave-faces)
(setq org-latex-listings 'engraved)
#+end_src
** Zettelkasten environment with org-roam
Org-roam enables features essential to a Zettelkasten such as inter-ID linking.
#+begin_src emacs-lisp
(use-package! org-roam
:after md-roam
:init (setq org-roam-directory "~/org/")) :custom
#+end_src
I use several capture templates to make it easy to get notes into my various sections.
I only use [[#md-roam-config][Markdown]] in the team wiki, so I have it set to that.
I also have a capture template form my [[Website]]
#+begin_src emacs-lisp
(after! org-roam
:ensure t
:custom
(setq org-roam-capture-templates
`(
("d" "default" plain "%?"
:target (file+head "%<%Y%m%d-%H%M%S>.org"
"#+TITLE: ${title}\n")
:unnarrowed t)
("s" "school" plain "%?"
:target (file+head "liberty/${title}.org"
"#+TITLE: ${title}\n")
:unnarrowed t)
("e" "encrypted" plain "%?"
:target (file+head "%<%Y%m%d-%H%M%S>.sec.org.age"
"#+TITLE: ${title}\n#+FILETAGS: :secure:noexport:\n\n* No Export Below This Line")
:unnarrowed t)
("c" "CCDC Wiki" plain ""
:target
(file+head "training-resources/content/${title}.md"
"---\ntitle: ${title}\nid: %<%Y-%m-%dT%H%M%S>\ncategory: \n---\n")
:unnarrowed t)
("w" "Website" plain "%?"
:target
(file+head "website/src/posts/%<%Y%m%d-%H%M%S>.org"
"#+TITLE: ${title}\n#+DRAFT: true\n")
:unnarrowed t))))
#+end_src
#+RESULTS:
| d | default | plain | %? | :target | (file+head %<%Y%m%d-%H%M%S>.org #+TITLE: ${title} |
*** Keybinds
Org-roam has many commands, of which I have bound the most important below.
This entails creating a local leader.
I use =r= for this purpose. It is close and goes well with *roam*.
#+begin_src emacs-lisp
(after! org-roam (map! :leader (:prefix ("r" . "roam")
:desc "Search for a node in org-roam files"
"f" #'org-roam-node-find
:desc "Insert the link to a node from org-roam"
"i" #'org-roam-node-insert
:desc "Rescan org-roam files and add new nodes to database"
"s" #'org-roam-db-sync
:desc "Jump to a random node"
"r" #'org-roam-node-random
:desc "Capture inside an existing or new node"
"c" #'org-roam-capture
:desc "Go to or create a daily note"
"d" #'org-roam-dailies-goto-today
:desc "Seek a daily note"
"D" #'org-roam-dailies-goto-date
:desc "Extract a subtree to a new file"
"e" #'org-roam-extract-subtree))
(map!
:desc "Alternative keybind to insert a roam link while in insert mode"
:i "M-[" #'org-roam-node-insert))
#+end_src
*** Nice UI to access Zettelkasten notes with Org-roam ui
**** Package
#+begin_src emacs-lisp :tangle packages.el
(package! org-roam-ui)
#+end_src
#+begin_src emacs-lisp
(use-package! websocket
:after org-roam)
(use-package! org-roam-ui
:after org-roam ;; or :after org
;; normally we'd recommend hooking orui after org-roam, but since org-roam does not have
;; a hookable mode anymore, you're advised to pick something yourself
;; if you don't care about startup time, use
;; :hook (after-init . org-roam-ui-mode)
:config
(setq org-roam-ui-sync-theme t
org-roam-ui-follow t
org-roam-ui-update-on-save t
org-roam-ui-open-on-start t))
(after! org-roam-ui (map! :leader (:prefix ("r" . "roam") (:prefix ("u" . "roam-ui")
:desc "focus the current node in org-roam-ui view"
"f" #'org-roam-ui-node-zoom
:desc "focus the current node's local graph in org-roam-ui view"
"l" #'org-roam-ui-node-local
:desc "begin org-roam ui mode"
"u" #'open-org-roam-ui
))))
#+END_SRC
*** Default Browser for Export
#+begin_src emacs-lisp
(setq browse-url-browser-function 'browse-url-generic
browse-url-generic-program "surf")
#+end_src
** Journal Environment with org-roam
#+begin_src emacs-lisp
(after! org-roam
(setq org-roam-dailies-capture-templates
`(("d" "default" entry
"* %?"
:target (file+head "%<%Y-%m-%d>.sec.org.age"
"#+title: %<%Y-%m-%d>\n")))))
#+end_src
*** Property getters and setters
These are to fulfill my need to get property values for generating my [[id:6672f401-32a1-49ef-8004-ac77ece67f5b][journal index]].
#+begin_src emacs-lisp
(require 'cl-lib)
(defun org-global-props-key-re (key)
"Construct a regular expression matching key and an optional plus and eating the spaces behind.
Test for existence of the plus: (match-beginning 1)"
(concat "^" (regexp-quote key) "\\(\\+\\)?[[:space:]]+"))
(defun org-global-props (&optional buffer)
"Get the plists of global org properties of current buffer."
(with-current-buffer (or buffer (current-buffer))
(org-element-map (org-element-parse-buffer) 'keyword (lambda (el) (when (string-equal (org-element-property :key el) "PROPERTY") (nth 1 el))))))
(defun org-global-prop-value (key)
"Get global org property KEY of current buffer.
Adding up values for one key is supported."
(let ((key-re (org-global-props-key-re key))
(props (org-global-props))
ret)
(cl-loop with val for prop in props
when (string-match key-re (setq val (plist-get prop :value))) do
(setq
val (substring val (match-end 0))
ret (if (match-beginning 1)
(concat ret " " val)
val)))
ret))
#+end_src
** Resume setup for a stellar CV
*** ox-extra for ":ignore:" tags
I want to be able to ignore headings on export.
#+begin_src emacs-lisp
(use-package! ox-extra
:after (org)
:config
(ox-extras-activate '(latex-header-blocks ignore-headlines)))
#+end_src
*** McDowell Resume Template
This template is supposed to be the standard.
#+begin_src emacs-lisp
(add-to-list 'org-latex-classes
'("mcdowellcv"
"\\documentclass[]{mcdowellcv}
\\usepackage{amsmath}
\\usepackage[]{multicol}
\\usepackage[hidelinks]{hyperref}
[NO-DEFAULT-PACKAGES]
[NO-PACKAGES]"
("\\begin{cvsection}{%s}" "\\end{cvsection}")
("\\begin{cvsubsection}{%s}" "\\end{cvsubsection}")))
#+end_src
*** Altacv template :ARCHIVE:
This is no longer really used.
#+begin_src emacs-lisp
(add-to-list 'org-latex-classes
'("altacv" "\\documentclass[10pt,a4paper,ragged2e,withhyper]{altacv}
\\usepackage[rm]{roboto}
\\usepackage[defaultsans]{lato}
\\usepackage{paracol}
[NO-DEFAULT-PACKAGES]
[NO-PACKAGES]
% Change the page layout if you need to
\\geometry{left=1.25cm,right=1.25cm,top=1.5cm,bottom=1.5cm,columnsep=1.2cm}
% Use roboto and lato for fonts
\\renewcommand{\\familydefault}{\\sfdefault}
% Change the colours if you want to
\\definecolor{SlateGrey}{HTML}{2E2E2E}
\\definecolor{LightGrey}{HTML}{666666}
\\definecolor{DarkPastelRed}{HTML}{450808}
\\definecolor{PastelRed}{HTML}{8F0D0D}
\\definecolor{GoldenEarth}{HTML}{E7D192}
\\colorlet{name}{black}
\\colorlet{tagline}{black}
\\colorlet{heading}{black}
\\colorlet{headingrule}{black}
\\colorlet{subheading}{black}
\\colorlet{accent}{black}
\\colorlet{emphasis}{SlateGrey}
\\colorlet{body}{LightGrey}
% Change some fonts, if necessary
\\renewcommand{\\namefont}{\\Huge\\rmfamily\\bfseries}
\\renewcommand{\\personalinfofont}{\\footnotesize}
\\renewcommand{\\cvsectionfont}{\\LARGE\\rmfamily\\bfseries}
\\renewcommand{\\cvsubsectionfont}{\\large\\bfseries}
% Change the bullets for itemize and rating marker
% for \cvskill if you want to
\\renewcommand{\\itemmarker}{{\\small\\textbullet}}
\\renewcommand{\\ratingmarker}{\\faCircle}
"
("\\cvsection{%s}" . "\\cvsection*{%s}")
("\\cvevent{%s}" . "\\cvevent*{%s}")))
#+end_src
* Company-mode for great autocompletes
I don't really want company-mode to run on timeouts.
I want VIM-like autocompletion, where =C-x o= and friends gives me my autocompletion.
#+begin_src emacs-lisp
(after! company-mode
(setq company-idle-delay nil))
(setq company-idle-delay nil)
#+end_src
* Initializing shell environment variables
** Package
#+begin_src emacs-lisp :tangle "packages.el"
(package! exec-path-from-shell)
#+end_src
** Config
We need to bring in the correct SSH agent values, so that Emacs is aware of where it is running.
#+begin_src emacs-lisp
(use-package! exec-path-from-shell)
(after! exec-path-from-shell
(dolist (var '("SSH_AUTH_SOCK" "SSH_AGENT_PID" "GPG_AGENT_INFO"))
(add-to-list 'exec-path-from-shell-variables var))
(exec-path-from-shell-initialize)
)
#+end_src
* Md-roam
:PROPERTIES:
:CUSTOM_ID: md-roam-config
:END:
** Packages
#+begin_src emacs-lisp :tangle "packages.el"
(package! md-roam
:recipe (:host github :repo "nobiot/md-roam"))
#+end_src
** Config
#+begin_src emacs-lisp
;; file-truename is optional; it seems required when you use symbolic
;; links, which Org-roam does not resolve
(use-package! md-roam
:config
(setq org-roam-file-extensions '("org" "md")) ; enable Org-roam for a markdown extension
(setq md-roam-file-extension "md") ; default "md". Specify an extension such as "markdown"
(md-roam-mode 1)
(setq md-roam-file-extension-single "md")
(setq md-roam-use-org-extract-ref nil)
(org-roam-db-autosync-mode 1))
#+end_src
* Misc.
#+begin_src emacs-lisp
(add-to-list 'org-tags-exclude-from-inheritance "hastodos")
(add-to-list 'org-tags-exclude-from-inheritance "ignore")
#+end_src
* Graphics in org-mode
** Org Plot[fn:1]
Org-plot can be enabled by a flag in the init file.
We can use some of the variables in =org-plot= to use the current doom theme
colours.
#+begin_src emacs-lisp
(defvar +org-plot-term-size '(1050 . 650)
"The size of the GNUPlot terminal, in the form (WIDTH . HEIGHT).")
(after! org-plot
(defun +org-plot-generate-theme (_type)
"Use the current Doom theme colours to generate a GnuPlot preamble."
(format "
fgt = \"textcolor rgb '%s'\" # foreground text
fgat = \"textcolor rgb '%s'\" # foreground alt text
fgl = \"linecolor rgb '%s'\" # foreground line
fgal = \"linecolor rgb '%s'\" # foreground alt line
# foreground colors
set border lc rgb '%s'
# change text colors of tics
set xtics @fgt
set ytics @fgt
# change text colors of labels
set title @fgt
set xlabel @fgt
set ylabel @fgt
# change a text color of key
set key @fgt
# line styles
set linetype 1 lw 2 lc rgb '%s' # red
set linetype 2 lw 2 lc rgb '%s' # blue
set linetype 3 lw 2 lc rgb '%s' # green
set linetype 4 lw 2 lc rgb '%s' # magenta
set linetype 5 lw 2 lc rgb '%s' # orange
set linetype 6 lw 2 lc rgb '%s' # yellow
set linetype 7 lw 2 lc rgb '%s' # teal
set linetype 8 lw 2 lc rgb '%s' # violet
# border styles
set tics out nomirror
set border 3
# palette
set palette maxcolors 8
set palette defined ( 0 '%s',\
1 '%s',\
2 '%s',\
3 '%s',\
4 '%s',\
5 '%s',\
6 '%s',\
7 '%s' )
"
(doom-color 'fg)
(doom-color 'fg-alt)
(doom-color 'fg)
(doom-color 'fg-alt)
(doom-color 'fg)
;; colours
(doom-color 'red)
(doom-color 'blue)
(doom-color 'green)
(doom-color 'magenta)
(doom-color 'orange)
(doom-color 'yellow)
(doom-color 'teal)
(doom-color 'violet)
;; duplicated
(doom-color 'red)
(doom-color 'blue)
(doom-color 'green)
(doom-color 'magenta)
(doom-color 'orange)
(doom-color 'yellow)
(doom-color 'teal)
(doom-color 'violet)))
(defun +org-plot-gnuplot-term-properties (_type)
(format "background rgb '%s' size %s,%s"
(doom-color 'bg) (car +org-plot-term-size) (cdr +org-plot-term-size)))
(setq org-plot/gnuplot-script-preamble #'+org-plot-generate-theme)
(setq org-plot/gnuplot-term-extra #'+org-plot-gnuplot-term-properties))
#+end_src
** Mermaid.js
Mermaid.js requires the mmcli executable from npm.
Mermaid is a tool that allows you to graph many kinds of entities:
- Relationship diagrams
- Flowcharts
- Gantt diagrams
There's other kinds too.
The package on ELPA is perfect. Needs no config, fits right in with Babel.
*** Package
#+begin_src emacs-lisp :tangle "packages.el"
(package! ob-mermaid)
#+end_src
*** Config
#+begin_src emacs-lisp
(use-package! ob-mermaid)
#+end_src
** SVGBob
SVGBob is an ASCII art renderer. It can do all kinds of nifty things with just a few basic .------./\
*** Package
#+begin_src emacs-lisp :tangle "packages.el"
(package! ob-svgbob
:recipe (:host nil :type git :repo "https://git.tecosaur.net/tec/ob-svgbob"))
#+end_src
*** Configuration
#+begin_src emacs-lisp
(use-package! ob-svgbob)
(setq org-svgbob-executable "svgbob_cli")
(setq org-babel-svgbob--parameters
'(:background transparent))
#+end_src
* Archiving
#+begin_src emacs-lisp
(setq org-archive-location "/home/user/org/archive.org::")
#+end_src
* Init.el
I like to have all my config in one place.
#+begin_src emacs-lisp :tangle "init.el"
;;; init.el -*- lexical-binding: t; -*-
;; This file controls what Doom modules are enabled and what order they load
;; in. Remember to run 'doom sync' after modifying it!
;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's
;; documentation. There you'll find a link to Doom's Module Index where all
;; of our modules are listed, including what flags they support.
;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or
;; 'C-c c k' for non-vim users) to view its documentation. This works on
;; flags as well (those symbols that start with a plus).
;;
;; Alternatively, press 'gd' (or 'C-c c d') on a module to browse its
;; directory (for easy access to its source code).
(doom! :input
;;bidi ; (tfel ot) thgir etirw uoy gnipleh
;;chinese
;;japanese
;;layout ; auie,ctsrnm is the superior home row
:completion
company ; the ultimate code completion backend
;;helm
;;ido
;;ivy
vertico ; the search engine of the future
:ui
;;deft ; notational velocity for Emacs
doom ; what makes DOOM look the way it does
doom-dashboard ; a nifty splash screen for Emacs
;;doom-quit ; DOOM quit-message prompts when you quit Emacs
;;(emoji +unicode) ; 🙂
hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
;;hydra
indent-guides ; highlighted indent columns
ligatures ; ligatures and symbols to make your code pretty again
;;minimap ; show a map of the code on the side
modeline ; snazzy, Atom-inspired modeline, plus API
nav-flash ; blink cursor line after big motions
;;neotree ; a project drawer, like NERDTree for vim
ophints ; highlight the region an operation acts on
(popup +defaults) ; tame sudden yet inevitable temporary windows
;;tabs ; a tab bar for Emacs
treemacs ; a project drawer, like neotree but cooler
;;unicode ; extended unicode support for various languages
(vc-gutter +pretty) ; vcs diff in the fringe
vi-tilde-fringe ; fringe tildes to mark beyond EOB
window-select ; visually switch windows
;;workspaces ; tab emulation, persistence & separate workspaces
zen ; distraction-free coding or writing
:editor
(evil +everywhere); come to the dark side, we have cookies
file-templates ; auto-snippets for empty files
fold ; (nigh) universal code folding
(format ) ; automated prettiness
;;god ; run Emacs commands without modifier keys
;;lispy ; vim for lisp, for people who don't like vim
multiple-cursors ; editing in many places at once
;;objed ; text object editing for the innocent
;;parinfer ; turn lisp into python, sort of
;;rotate-text ; cycle region at point between text candidates
snippets ; my elves. They type so I don't have to
word-wrap ; soft wrapping with language-aware indent
:emacs
(dired +icons) ; making dired pretty [functional]
electric ; smarter, keyword-based electric-indent
ibuffer ; interactive buffer management
undo ; persistent, smarter undo for your inevitable mistakes
vc ; version-control and Emacs, sitting in a tree
:term
;;eshell ; the elisp shell that works everywhere
;;shell ; simple shell REPL for Emacs
term ; basic terminal emulator for Emacs
vterm ; the best terminal emulation in Emacs
:checkers
(syntax +flymake ) ; tasing you for every semicolon you forget
(spell +flyspell +everywhere) ; tasing you for misspelling mispelling
grammar ; tasing grammar mistake every you make
:tools
;;ansible
(biblio +icons) ; Writes a PhD for you (citation needed)
;;debugger ; FIXME stepping through code, to help you add bugs
;;direnv
;;docker
editorconfig ; let someone else argue about tabs vs spaces
;;ein ; tame Jupyter notebooks with emacs
(eval +overlay) ; run code, run (also, repls)
;;gist ; interacting with github gists
(lookup +dictionary +offline) ; navigate your code and its documentation
(lsp +eglot) ; M-x vscode
magit ; a git porcelain for Emacs
;;make ; run make tasks from Emacs
;;pass ; password manager for nerds
pdf ; pdf enhancements
;;prodigy ; FIXME managing external services & code builders
;;rgb ; creating color strings
;;taskrunner ; taskrunner for all your projects
;;terraform ; infrastructure as code
;;tmux ; an API for interacting with tmux
;;tree-sitter ; syntax and parsing, sitting in a tree...
;;upload ; map local to remote projects via ssh/ftp
:os
;;(:if IS-MAC macos) ; improve compatibility with macOS
;;tty ; improve the terminal Emacs experience
:lang
;;agda ; types of types of types of types...
(beancount +lsp) ; mind the GAAP
(cc +lsp) ; C > C++ == 1
;;clojure ; java with a lisp
;;common-lisp ; if you've seen one lisp, you've seen them all
;;coq ; proofs-as-programs
;;crystal ; ruby at the speed of c
;;csharp ; unity, .NET, and mono shenanigans
data ; config/data formats
;;(dart +flutter) ; paint ui and not much else
;;dhall
;;elixir ; erlang done right
;;elm ; care for a cup of TEA?
emacs-lisp ; drown in parentheses
;;erlang ; an elegant language for a more civilized age
;;ess ; emacs speaks statistics
;;factor
;;faust ; dsp, but you get to keep your soul
;;fortran ; in FORTRAN, GOD is REAL (unless declared INTEGER)
;;fsharp ; ML stands for Microsoft's Language
;;fstar ; (dependent) types and (monadic) effects and Z3
;;gdscript ; the language you waited for
;;(go +lsp) ; the hipster dialect
;;(graphql +lsp) ; Give queries a REST
;;(haskell +lsp) ; a language that's lazier than I am
;;hy ; readability of scheme w/ speed of python
;;idris ; a language you can depend on
;;json ; At least it ain't XML
;;(java +lsp) ; the poster child for carpal tunnel syndrome
;;javascript ; all(hope(abandon(ye(who(enter(here))))))
;;julia ; a better, faster MATLAB
;;kotlin ; a better, slicker Java(Script)
(latex +lsp +cdlatex +fold) ; writing papers in Emacs has never been so fun
;;lean ; for folks with too much to prove
;;ledger ; be audit you can be
lua ; one-based indices? one-based indices
markdown ; writing docs for people to ignore
;;nim ; python + lisp at the speed of c
;;nix ; I hereby declare "nix geht mehr!"
;;ocaml ; an objective camel
(org +roam2 +gnuplot +hugo +pomodoro +noter +present +pretty) ; organize your plain life in plain text
;;php ; perl's insecure younger brother
;;plantuml ; diagrams for confusing people more
;;purescript ; javascript, but functional
python ; beautiful is better than ugly
;;qt ; the 'cutest' gui framework ever
;;racket ; a DSL for DSLs
;;raku ; the artist formerly known as perl6
;;rest ; Emacs as a REST client
;;rst ; ReST in peace
;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
(rust +lsp) ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
;;scala ; java, but good
;;(scheme +guile) ; a fully conniving family of lisps
sh ; she sells {ba,z,fi}sh shells on the C xor
;;sml
;;solidity ; do you need a blockchain? No.
;;swift ; who asked for emoji variables?
;;terra ; Earth and Moon in alignment for performance.
web ; the tubes
;;yaml ; JSON, but readable
;zig ; C, but simpler
:email
;;(mu4e +org +gmail)
;;notmuch
;;(wanderlust +gmail)
:app
;;calendar
;;emmgs
;;everywhere ; *leave* Emacs!? You must be joking
;;irc ; how neckbeards socialize
;;(rss +org) ; emacs as an RSS reader
;;twitter ; twitter client https://twitter.com/vnought
:config
literate
(default +bindings +smartparens)
)
#+end_src
* Footnotes
[fn:1] Stolen from Tecosaur's [[https://git.tecosaur.net/tec/emacs-config][config]]
* Other Editing
** Lillypond
*** ob-lilypond
**** package
#+begin_src emacs-lisp :tangle "packages.el"
(package! ob-lilypond
:recipe (:host github :type git :repo "mjago/ob-lilypond"))
#+end_src
**** config
#+begin_src emacs-lisp
(use-package! ob-lilypond)
(setq ly-arrange-mode t)
#+end_src