44 KiB
Doom Emacs Configuration
- Intro
- Rudimentary configuration
- Package loading
- Package configuration
- Language configuration
Let us change our traditional attitude to the construction of programs: Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do. — Donald Knuth
Intro
Customising an editor can be very rewarding … until you have to leave it. For years I have been looking for ways to avoid this pain. Then I discovered vim-anywhere, and found that it had an emacs companion, emacs-anywhere. To me, this looked most attractive.
Separately, online I have seen the following statement enough times I think it's a catchphrase
Redditor1: I just discovered this thing, isn't it cool. Redditor2: Oh, there's an emacs mode for that.
I tried out the spacemacs
distribution a bit, but it wasn't quite to my liking.
Then I heard about doom emacs
and thought I may as well give that a try.
TLDR; it's great.
Now I've discovered the wonders of literate programming, and am becoming more settled by the day. This is my config.
Rudimentary configuration
Make this file run (slightly) faster with lexical binding (see this blog post for more info).
;;; config.el -*- lexical-binding: t; -*-
Personal Information
It's useful to have some basic personal information
(setq user-full-name "tecosaur"
user-mail-address "tecosaur@gmail.com")
Apparently this is used by GPG
, and all sorts of other things.
Better defaults
Simple settings
Browsing the web and seeing angrybacon/dotemacs and comparing with the values
shown by SPC h v
and selecting what I thought looks good, I've ended up adding the following:
(setq-default
delete-by-moving-to-trash t ; Delete files to trash
tab-width 4 ; Set width for tabs
uniquify-buffer-name-style 'forward ; Uniquify buffer names
window-combination-resize t ; take new window space from all other windows (not just current)
x-stretch-cursor t) ; Stretch cursor to the glyph width
(setq undo-limit 80000000 ; Raise undo-limit to 80Mb
evil-want-fine-undo t ; By default while in insert all changes are one big blob. Be more granular
auto-save-default t) ; Nobody likes to loose work, I certainly don't
(delete-selection-mode 1) ; Replace selection when inserting text
(display-time-mode 1) ; Enable time in the mode-line
(display-battery-mode 1) ; On laptops it's nice to know how much power you have
(global-subword-mode 1) ; Iterate through CamelCase words
Fullscreen
I also like the idea of fullscreen-ing when opened by emacs
or the .desktop
file.
(if (eq initial-window-system 'x) ; if started by emacs command or desktop file
(toggle-frame-maximized)
(toggle-frame-fullscreen))
Auto-customisations
By default changes made via a customisation interface are added to init.el
.
I prefer the idea of using a separate file for this. We just need to change a
setting, and load it if it exists.
(setq-default custom-file (expand-file-name ".custom.el" doom-private-dir))
(when (file-exists-p custom-file)
(load custom-file))
Windows
I find it rather handy to be asked which buffer I want to see after splitting the window. Let's make that happen. First, we'll enter the new window
(setq evil-vsplit-window-right t
evil-split-window-below t)
Then, we'll pull up ivy
(defadvice! prompt-for-buffer (&rest _)
:after '(evil-window-split evil-window-vsplit)
(+ivy/switch-buffer))
Buffer defaults
I'd much rather have my new buffers in org-mode
than fundamental-mode
, hence
;; (setq-default major-mode 'org-mode)
For some reason this + the mixed pitch hook causes issues with hydra and so I'll
just need to resort to SPC b o
for now.
Doom configuration
Visual Settings
Font Face
'Fira Code' is nice, and 'Overpass' makes for a nice sans companion. We just need to fiddle with the font sizes a tad so that they visually match.
(setq doom-font (font-spec :family "Fira Code" :size 22)
doom-big-font (font-spec :family "Fira Code" :size 36)
doom-variable-pitch-font (font-spec :family "Overpass" :size 24))
Theme
doom-one
is nice and all, but I find the vibrant
variant nicer.
(setq doom-theme 'doom-vibrant)
However, by default red
text is used in the modeline
, so let's make that orange
so I don't feel like something's gone wrong when editing files.
(custom-set-faces!
'(doom-modeline-buffer-modified :foreground "orange"))
Miscellaneous
Relative line numbers are fantastic for knowing how far away line numbers are,
then ESC 12 <UP>
gets you exactly where you think.
(setq display-line-numbers-type 'relative)
I'd like some slightly nicer default buffer names
(setq doom-fallback-buffer-name "► Doom"
+doom-dashboard-name "► Doom")
There's a bug with the modeline in insert mode for org documents (issue), so
(custom-set-faces! '(doom-modeline-evil-insert-state :weight bold :foreground "#339CDB"))
Some helper macros
There are a few handy macros added by doom, namely
load!
for loading external.el
files relative to this oneuse-package
for configuring packagesadd-load-path!
for adding directories to theload-path
whereemacs
looks when you load packages withrequire
oruse-package
map
for binding new keys
To find more,
Other things
Editor interaction
Mouse buttons
(map! :n [mouse-8] #'better-jumper-jump-backward
:n [mouse-9] #'better-jumper-jump-forward)
Window title
I'd like to have just the buffer name, then if applicable the project folder
(setq frame-title-format
'(""
"%b"
(:eval
(let ((project-name (projectile-project-name)))
(unless (string= "-" project-name)
(format (if (buffer-modified-p) " ◉ %s" " ● %s") project-name))))))
Systemd daemon
For running a systemd service for a emacs server I have the following
[Unit]
Description=Emacs server daemon
Documentation=info:emacs man:emacs(1) https://gnu.org/software/emacs/
[Service]
Type=forking
ExecStart=/usr/bin/emacs --daemon
ExecStop=/usr/bin/emacsclient --eval "(progn (setq kill-emacs-hook nil) (kill emacs))"
Environment=SSH_AUTH_SOCK=%t/keyring/ssh
Restart=on-failure
[Install]
WantedBy=default.target
which is then enabled by
systemctl --user enable emacs.service
Package loading
This file shouldn't be byte compiled.
;; -*- no-byte-compile: t; -*-
Loading instructions
This is where you install packages, by declaring them with the package!
macro, then running doom refresh
on the command line. You'll need to
restart Emacs for your changes to take effect! Or at least, run M-x doom/reload
.
WARNING: Don't disable core packages listed in ~/.emacs.d/core/packages.el
.
Doom requires these, and disabling them may have terrible side effects.
Packages in MELPA/ELPA/emacsmirror
To install some-package
from MELPA, ELPA or emacsmirror:
(package! some-package)
Packages from git repositories
To install a package directly from a particular repo, you'll need to specify
a :recipe
. You'll find documentation on what :recipe
accepts here:
(package! another-package
:recipe (:host github :repo "username/repo"))
If the package you are trying to install does not contain a PACKAGENAME.el
file, or is located in a subdirectory of the repo, you'll need to specify
:files
in the :recipe
:
(package! this-package
:recipe (:host github :repo "username/repo"
:files ("some-file.el" "src/lisp/*.el")))
Disabling built-in packages
If you'd like to disable a package included with Doom, for whatever reason,
you can do so here with the :disable
property:
(package! builtin-package :disable t)
You can override the recipe of a built in package without having to specify
all the properties for :recipe
. These will inherit the rest of its recipe
from Doom or MELPA/ELPA/Emacsmirror:
(package! builtin-package :recipe (:nonrecursive t))
(package! builtin-package-2 :recipe (:repo "myfork/package"))
Specify a :branch
to install a package from a particular branch or tag.
This is required for some packages whose default branch isn't 'master' (which
our package manager can't deal with; see raxod502/straight.el#279)
(package! builtin-package :recipe (:branch "develop"))
General packages
Auto-complete
(package! company-tabnine ; tab9 autocomplete
:recipe (:host github :repo "TommyX12/company-tabnine"
:files ("company-tabnine.el" "fetch-binaries.sh")))
Prettification
prettify-mode
is nice and all, but adding substitutions is a little verbose.
This helps with that.
(package! prettify-utils ; simplify messing with prettify-mode
:recipe (:host github :repo "Ilazki/prettify-utils.el"))
Window management
(package! rotate)
Fun
Sometimes one just wants a little fun. XKCD comics are fun.
(package! xkcd)
Every so often, you want everyone else to know that you're typing, or just to amuse oneself. Introducing: typewriter sounds!
(package! selectric-mode)
Hey, let's get the weather in here while we're at it.
(package! wttrin)
Why not flash words on the screen. Why not — hey, it could be fun.
(package! spray)
With all our fancy emacs themes, my terminal is missing out!
(package! theme-magic)
Other
Flyspell-lazy
To alleviate some issues with flyspell
(package! flyspell-lazy)
CalcTeX
This is a nice extension to calc
(package! calctex :recipe (:host github :repo "johnbcoughlin/calctex"
:files ("*.el")))
ESS
View dataframes better with
(package! ess-view)
Language packages
Systemd
For editing systemd unit files
(package! systemd)
Org Mode
Org tables aren't the prettiest thing to look at. This package is supposed to redraw them in the buffer with box-drawing characters. Sounds like an improvement to me! Just need to get it working…
(package! org-pretty-table-mode
:recipe (:host github :repo "Fuco1/org-pretty-table"))
Because of the lovely variety in markdown implementations there isn't actually
such a thing a standard table spec … or standard anything really. Because
org-md
is a goody-two-shoes, it just uses HTML for all these non-standardised
elements (a lot of them). So ox-gfm
is handy for exporting markdown with all the
features that GitHub has. Initialised in /tec/emacs-config/src/commit/ab569e119360b01b62ffecadbc6b5c7b22aaaeff/Exporting%20to%20GFM.
(package! ox-gfm)
Now and then citations need to happen
(package! org-ref)
For automatically toggling LaTeX fragment previews there's this nice package
(package! org-fragtog)
Came across this and … it's cool
(package! org-graph-view :recipe (:host github :repo "alphapapa/org-graph-view"))
Package configuration
Centaur Tabs
We want to make the tabs a nice, comfy size (36
), with icons. The modifier
marker is nice, but the particular default Unicode one causes a lag spike, so
let's just switch to an o
, which still looks decent but doesn't cause any
issues.
A 'active-bar' is nice, so let's have one of those. If we have it under
needs us to
turn on x-underline-at-decent
though. For some reason this didn't seem to work
inside the (after! ... )
block ¯\_(ツ)_/¯.
Then let's change the font to a sans serif, but the default one doesn't fit too
well somehow, so let's switch to 'P22 Underground Book'; it looks much nicer.
(after! centaur-tabs
(setq centaur-tabs-height 36
centaur-tabs-set-icons t
centaur-tabs-modified-marker "o"
centaur-tabs-close-button "×"
centaur-tabs-set-bar 'above)
centaur-tabs-gray-out-icons 'buffer
(centaur-tabs-change-fonts "P22 Underground Book" 160))
;; (setq x-underline-at-descent-line t)
Company
It's nice to have completions almost all the time, in my opinion. Key strokes are just waiting to be saved!
(after! company
(setq company-idle-delay 0.5
company-minimum-prefix-length 2)
(setq company-show-numbers t)
(add-hook 'evil-normal-state-entry-hook #'company-abort)) ;; make aborting less annoying.
Now, the improvements from precident
are mostly from remembering history, so
let's improve that memory.
(setq-default history-length 1000)
(setq-default prescient-history-length 1000)
Plain Text
ispell
is nice, let's have it in text
, markdown
, and GFM
.
(set-company-backend! '(text-mode
markdown-mode
gfm-mode)
'(:seperate company-ispell
company-files
company-yasnippet))
The SCOWL
word list I got for VSCode
is better than the default (I think), so
let's use that.
(setq company-ispell-dictionary (file-truename "~/.config/Code/User/Custom cSpell Dictionaries/SCOWL-workdlist-au-uk-60.txt"))
Oh, and by the way, if company-ispell-dictionary
is nil
, then
ispell-complete-word-dict
is used instead.
ESS
company-dabbrev-code
is nice. Let's have it.
(set-company-backend! 'ess-r-mode '(company-R-args company-R-objects company-dabbrev-code :separate))
Emacs Anywhere configuration
It's nice to recognise GitHub (so we can use GFM
), and other apps which we know
take markdown
(defun markdown-window-p (window-title)
"Judges from WINDOW-TITLE whether the current window likes markdown"
(or (string-match-p "Pull Request" window-title)
(string-match-p "Issue" window-title)
(string-match-p "Discord" window-title)))
When the window opens, we generally want text so let's use a nice sans serif font,
a position the window below and to the left. Oh, and don't forget about checking
for GFM
, otherwise let's just use markdown
.
(defun ea-popup-handler (app-name window-title x y w h)
(set-frame-size (selected-frame) 80 12)
(interactive)
; position
(let* ((mousepos (split-string (shell-command-to-string "xdotool getmouselocation | sed -E \"s/ screen:0 window:[^ ]*|x:|y://g\"")))
(mouse-x (- (string-to-number (nth 0 mousepos)) 100))
(mouse-y (- (string-to-number (nth 1 mousepos)) 50)))
(set-frame-position (selected-frame) mouse-x mouse-y))
(set-frame-name (concat "Quick Edit ∷ " ea-app-name " — "
(truncate-string-to-width (string-trim (string-trim-right window-title (format "-[A-Za-z0-9 ]*%s" ea-app-name)) "[\s-]+" "[\s-]+") 45 nil nil "…")))
; set major mode
(cond
((markdown-window-p window-title) (gfm-mode))
(t (org-mode)) ; default major mode
)
(when (gui-get-selection 'PRIMARY) (insert (gui-get-selection 'PRIMARY)))
(evil-insert-state) ; start in insert
(when (centaur-tabs-mode) (centaur-tabs-local-mode t)) ; disable tabs
; I'm used to C-c C-c for 'completed the thing' so add that
(local-set-key (kbd "C-c C-c") (lambda () (interactive) (local-unset-key (kbd "C-c C-c")) (delete-frame))))
(add-hook 'ea-popup-hook 'ea-popup-handler)
Flyspell
At one point, typing became noticably laggy, Profiling revealed
flyspell-post-command-hook
was responsible for 47% of CPU cycles by itself!
So I'm going to make use of flyspell-lazy
(after! flyspell (require 'flyspell-lazy) (flyspell-lazy-mode 1))
Miscellaneous
wttrin
Set the default city. It's initially Taipei
but I find the IP-locating that's
done perfectly acceptable, so let's make that happen.
(setq wttrin-default-cities '(""))
spray
Let's make this suit me slightly better.
(setq spray-wpm 500
spray-height 700)
theme magic
Let's automaticly update terminals on theme change
(add-hook 'doom-load-theme-hook 'theme-magic-from-emacs)
calc
Radians are just better
(setq calc-angle-mode 'rad)
Tramp
Let's try to make tramp handle prompts better
(after! tramp
(setenv "SHELL" "/bin/bash")
(setq tramp-shell-prompt-pattern "\\(?:^\\|
\\)[^]#$%>\n]*#?[]#$%>] *\\(\\[[0-9;]*[a-zA-Z] *\\)*")) ;; defult +
Troubleshooting
In case the remote shell is misbehaving, here are some things to try
Zsh
There are some escape code you don't want, let's make it behave more considerately.
if [[ "$TERM" == "dumb" ]]; then
unset zle_bracketed_paste
unset zle
PS1='$ '
return
fi
Language configuration
File Templates
For some file types, we overwrite defaults in the snippets directory, others need to have a template assigned.
(set-file-template! "\\.tex$" :trigger "__" :mode 'latex-mode)
Org Mode
System config
Org mode isn't recognised as it's own mime type by default, but that can easily
be changed with the following file. For system-wide changes try
~/usr/share/mime/packages/org.xml
.
<?xml version="1.0" encoding="utf-8"?>
<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
<mime-type type="text/org">
<comment>Emacs Org-mode File</comment>
<glob pattern="*.org"/>
<alias type="text/org"/>
</mime-type>
</mime-info>
What's nice is that Papirus now has an icon for text/org
.
One simply needs to refresh their mime database
update-mime-database ~/.local/share/mime
Then set emacs as the default editor
xdg-mime default emacs.desktop text/org
Behaviour
(setq org-directory "~/.org" ; let's put files here
org-use-property-inheritance t ; it's convenient to have properties inherited
org-log-done 'time ; having the time a item is done sounds convininet
org-list-allow-alphabetical t ; have a. A. a) A) list bullets
org-export-in-background t ; run export processes in external emacs process
org-catch-invisible-edits 'smart) ; try not to accidently do weird stuff in invisible regions
Let's also make creating an org buffer just that little bit easier.
(evil-define-command evil-buffer-org-new (count file)
"Creates a new ORG buffer replacing the current window, optionally
editing a certain FILE"
:repeat nil
(interactive "P<f>")
(if file
(evil-edit file)
(let ((buffer (generate-new-buffer "*new org*")))
(set-window-buffer nil buffer)
(with-current-buffer buffer
(org-mode)))))
(map! :leader
(:prefix "b"
:desc "New empty ORG buffer" "o" #'evil-buffer-org-new))
I think it makes sense to have list bullets change with depth
(setq org-list-demote-modify-bullet '(("+" . "-") ("-" . "+") ("*" . "+")))
Occasionally I want to cite something.
(def-package! org-ref
:after org
:config
(setq org-ref-completion-library 'org-ref-ivy-cite))
It's also nice to be able to use cdlatex
.
(after! org (add-hook 'org-mode-hook 'turn-on-org-cdlatex))
At some point in the future it could be good to investigate splitting org blocks. Likewise this looks good for symbols.
Visuals
In editor
Font Display
Mixed pitch is great. As is +org-pretty-mode
, let's use them.
(add-hook! 'org-mode-hook #'+org-pretty-mode #'mixed-pitch-mode)
Earlier I loaded the org-pretty-table
package, let's enable it everywhere!
(setq global-org-pretty-table-mode t)
Unfortunately it doesn't seem to do anything ATM 😞.
Symbols
It's also nice to change the character used for collapsed items (by default …
),
I think ▾
is better for indicating 'collapsed section'.
and add an extra org-bullet
to the default list of four.
I've also added some fun alternatives, just commented out.
(setq org-ellipsis " ▾ "
org-bullets-bullet-list '("◉" "○" "✸" "✿" "✤")
;; org-bullets-bullet-list '("Ⅰ" "Ⅱ" "Ⅲ" "Ⅳ" "Ⅴ" "Ⅵ" "Ⅶ" "Ⅷ" "Ⅸ" "Ⅹ")
)
It's also nice to make use of the unicode characters for check boxes, and other commands.
(after! org
(appendq! +pretty-code-symbols
'(:checkbox "☐"
:pending "◼"
:checkedbox "☑"
:results "🠶"
:property "☸"
:properties "⚙"
:end "∎"
:options "⌥"
:title "𝙏"
:author "𝘼"
:date "𝘿"
:begin_quote "❮"
:end_quote "❯"
:em_dash "—"))
(set-pretty-symbols! 'org-mode
:merge t
:checkbox "[ ]"
:pending "[-]"
:checkedbox "[X]"
:results "#+RESULTS:"
:property "#+PROPERTY:"
:property ":PROPERTIES:"
:end ":END:"
:options "#+OPTIONS:"
:title "#+TITLE:"
:author "#+AUTHOR:"
:date "#+DATE:"
:begin_quote "#+BEGIN_QUOTE"
:end_quote "#+END_QUOTE"
:em_dash "---")
)
(plist-put +pretty-code-symbols :name "⁍") ; or › could be good?
We also like org-fragtog
, and that wants a hook.
(add-hook 'org-mode-hook 'org-fragtog-mode)
LaTeX Fragments
It's nice to customise the look of LaTeX fragments so they fit better in the text — like this \(\sqrt{\beta^2+3}-\sum_{\phi=1}^\infty \frac{x^\phi-1}{\Gamma(a)}\). Let's start by adding a sans font.
(setq org-format-latex-header "\\documentclass{article}
\\usepackage[usenames]{color}
\\usepackage[T1]{fontenc}
\\usepackage{mathtools}
\\usepackage{textcomp,amssymb}
\\usepackage[makeroom]{cancel}
\\pagestyle{empty} % do not remove
% The settings below are copied from fullpage.sty
\\setlength{\\textwidth}{\\paperwidth}
\\addtolength{\\textwidth}{-3cm}
\\setlength{\\oddsidemargin}{1.5cm}
\\addtolength{\\oddsidemargin}{-2.54cm}
\\setlength{\\evensidemargin}{\\oddsidemargin}
\\setlength{\\textheight}{\\paperheight}
\\addtolength{\\textheight}{-\\headheight}
\\addtolength{\\textheight}{-\\headsep}
\\addtolength{\\textheight}{-\\footskip}
\\addtolength{\\textheight}{-3cm}
\\setlength{\\topmargin}{1.5cm}
\\addtolength{\\topmargin}{-2.54cm}
% my custom stuff
\\usepackage{arev}
\\usepackage{arevmath}")
We can either render from a dvi
or pdf
file, so let's benchmark latex
and
pdflatex
.
latex time |
pdflatex time |
---|---|
135±2 ms | 215±3 ms |
On the rendering side, there are two .dvi
-to-image convertors which I am
interested in: dvipng
and dvisvgm
. Then with the a .pdf
we have pdf2svg
.
For inline preview we care about speed, while for exporting we care about file
size and preffer a vector graphic.
Using the above latex expression and benchmarking lead to the following results:
dvipng time |
dvisvgm time |
pdf2svg time |
---|---|---|
89±2 ms | 178±2 ms | 12±2 ms |
Now let's combine this to see what's best
Tool chain | Total time | Resultant file size |
---|---|---|
latex + dvipng |
226±2 ms | 7 KiB |
latex + dvisvgm |
392±4 ms | 8 KiB |
pdflatex + pdf2svg |
230±2 ms | 16 KiB |
So, let's use dvipng
for previewing LaTeX fragments in-emacs, but dvisvgm
for [[
Exporting to HTML][LaTeX Rendering]].
Unfortunately: it seems that svg sizing is annoying ATM, so let's actually not do this right now.
As well as having a sans font, there are a few other tweaks which can make them look better. Namely making sure that the colours switch when the theme does.
(after! org
;; make background of fragments transparent
;; (let ((dvipng--plist (alist-get 'dvipng org-preview-latex-process-alist)))
;; (plist-put dvipng--plist :use-xcolor t)
;; (plist-put dvipng--plist :image-converter '("dvipng -D %D -bg 'transparent' -T tight -o %O %f")))
(add-hook! 'doom-load-theme-hook
(defun +org-refresh-latex-background ()
(plist-put! org-format-latex-options
:background
(face-attribute (or (cadr (assq 'default face-remapping-alist))
'default)
:background nil t))))
)
Exporting (general)
(after! org (setq org-export-headline-levels 5)) ; I like nesting
Exporting to HTML
Custom CSS/JS
There is a fantastic exporter config (fniessen/org-html-themes) which we can setup to be used with all our org files. Since most of the syntax highlighting colours from our /tec/emacs-config/src/commit/ab569e119360b01b62ffecadbc6b5c7b22aaaeff/Theme gets used, we benefit from customising the code block style.
We also want to make the background and foreground colours of the <pre>
blocks
match out theme (they don't by default), so I scraped some code from emacs.stackexchange
.
(defun my-org-inline-css-hook (exporter)
"Insert custom inline css to automatically set the
background of code to whatever theme I'm using's background"
(when (eq exporter 'html)
(setq
org-html-head-extra
(concat
org-html-head-extra
(format "
<style type=\"text/css\">
:root {
--theme-bg: %s;
--theme-bg-alt: %s;
--theme-base0: %s;
--theme-base1: %s;
--theme-base2: %s;
--theme-base3: %s;
--theme-base4: %s;
--theme-base5: %s;
--theme-base6: %s;
--theme-base7: %s;
--theme-base8: %s;
--theme-fg: %s;
--theme-fg-alt: %s;
--theme-grey: %s;
--theme-red: %s;
--theme-orange: %s;
--theme-green: %s;
--theme-teal: %s;
--theme-yellow: %s;
--theme-blue: %s;
--theme-dark-blue: %s;
--theme-magenta: %s;
--theme-violet: %s;
--theme-cyan: %s;
--theme-dark-cyan: %s;
}
</style>"
(doom-color 'bg)
(doom-color 'bg-alt)
(doom-color 'base0)
(doom-color 'base1)
(doom-color 'base2)
(doom-color 'base3)
(doom-color 'base4)
(doom-color 'base5)
(doom-color 'base6)
(doom-color 'base7)
(doom-color 'base8)
(doom-color 'fg)
(doom-color 'fg-alt)
(doom-color 'grey)
(doom-color 'red)
(doom-color 'orange)
(doom-color 'green)
(doom-color 'teal)
(doom-color 'yellow)
(doom-color 'blue)
(doom-color 'dark-blue)
(doom-color 'magenta)
(doom-color 'violet)
(doom-color 'cyan)
(doom-color 'dark-cyan))
"
<<orgHtmlStyle>>
"
))))
(add-hook 'org-export-before-processing-hook 'my-org-inline-css-hook)
Make verbatim different to code
Since we have verbatim
and code
, let's use verbatim
for key strokes.
(setq org-html-text-markup-alist
'((bold . "<b>%s</b>")
(code . "<code>%s</code>")
(italic . "<i>%s</i>")
(strike-through . "<del>%s</del>")
(underline . "<span class=\"underline\">%s</span>")
(verbatim . "<kbd>%s</kbd>")))
Change checkbox type
We also want to use HTML checkboxes, however we want to get a bit fancier than default
(after! org
(appendq! org-html-checkbox-types '((html-span .
((on . "<span class='checkbox'></span>")
(off . "<span class='checkbox'></span>")
(trans . "<span class='checkbox'></span>")))))
(setq org-html-checkbox-type 'html-span))
- I'm yet to do this
- Work in progress
- This is done
LaTeX Rendering
On the maths side of things, I consider dvisvgm
to be a rather compelling
option. However this isn't sized very well at the moment.
;; (setq-default org-html-with-latex `dvisvgm)
Exporting to LaTeX
(with-eval-after-load 'ox-latex
(add-to-list 'org-latex-classes
'("fancy-article"
"\\documentclass{scrartcl}\n\\usepackage[T1]{fontenc}\\usepackage[osf,largesc,helvratio=0.9]{newpxtext}\\usepackage[scale=0.92]{sourcecodepro}\n\\usepackage[varbb]{newpxmath}\\usepackage[activate={true,nocompatibility},final,tracking=true,kerning=true,spacing=true,factor=2000]{microtype}"
("\\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
'("blank"
"[NO-DEFAULT-PACKAGES]
[NO-PACKAGES]
[EXTRA]"
("\\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
'("bmc-article"
"\\documentclass[article,code,maths]{bmc}
[NO-DEFAULT-PACKAGES]
[NO-PACKAGES]
[EXTRA]"
("\\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
'("bmc"
"\\documentclass[code,maths]{bmc}
[NO-DEFAULT-PACKAGES]
[NO-PACKAGES]
[EXTRA]"
("\\chapter{%s}" . "\\chapter*{%s}")
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
(setq org-latex-default-class "bmc-article")
(add-to-list 'org-latex-packages-alist '("" "minted"))
(setq org-latex-listings 'minted)
(setq org-latex-minted-options
'(("frame" "lines")
("fontsize" "\\scriptsize")
("linenos" "")
("breakanywhere" "true")
("breakautoindent" "true")
("breaklines" "true")
("autogobble" "true")
("obeytabs" "true")
("python3" "true")
("breakbefore" "\\\\\\.+")
("breakafter" "\\,")
("style" "autumn")
("breaksymbol" "\\tiny\\ensuremath{\\hookrightarrow}")
("breakanywheresymbolpre" "\\,\\footnotesize\\ensuremath{{}_{\\rfloor}}")
("breakbeforesymbolpre" "\\,\\footnotesize\\ensuremath{{}_{\\rfloor}}")
("breakaftersymbolpre" "\\,\\footnotesize\\ensuremath{{}_{\\rfloor}}")))
(setq org-latex-hyperref-template "\\hypersetup{\n pdfauthor={%a},\n pdftitle={%t},\n pdfkeywords={%k},\n pdfsubject={%d},\n pdfcreator={%c},\n pdflang={%L},\n colorlinks=true,\nlinkcolor=}\n\\urlstyle{same}\n")
(setq org-latex-pdf-process
'("latexmk -shell-escape -interaction=nonstopmode -f -pdf -output-directory=%o %f")))
Exporting to Beamer
It's nice to use a different theme
(setq org-beamer-theme "[progressbar=foot]metropolis")
Then customise it a bit
And I think that it's natural to divide a presentation into sections, e.g.
Introduction, Overview… so let's set bump up the headline level that becomes a
frame from 1
to 2
.
(setq org-beamer-frame-level 2)
Exporting to GFM
We just need to load ox-gfm
for org-mode documents
(eval-after-load "org"
'(require 'ox-gfm nil t))
Babel
Doom lazy-loads babel languages, with is lovely.
We need to tell babel to use python3. Who uses python2 anymore anyway? And why
doesn't python
refer to the latest version!?
(setq org-babel-python-command "python3")
We also like autocompletion here
(defun tec-org-python ()
(if (eq major-mode 'python-mode)
(progn (anaconda-mode t)
(company-mode t)))
)
(add-hook 'org-src-mode-hook 'tec-org-python)
ESS
We don't want R
evaluation to hang the editor, hence
(setq ess-eval-visibly 'nowait)
Syntax highlighting is nice, so let's turn all of that on
(setq ess-R-font-lock-keywords '((ess-R-fl-keyword:keywords . t)
(ess-R-fl-keyword:constants . t)
(ess-R-fl-keyword:modifiers . t)
(ess-R-fl-keyword:fun-defs . t)
(ess-R-fl-keyword:assign-ops . t)
(ess-R-fl-keyword:%op% . t)
(ess-fl-keyword:fun-calls . t)
(ess-fl-keyword:numbers . t)
(ess-fl-keyword:operators . t)
(ess-fl-keyword:delimiters . t)
(ess-fl-keyword:= . t)
(ess-R-fl-keyword:F&T . t)))
LaTeX
Once again, all hail mixed pitch mode!
(add-hook 'LaTeX-mode-hook #'mixed-pitch-mode)
Snippet value
For use in the new-file template, let's set out a nice preamble we may want to use.
\\usepackage[pdfa,unicode=true,hidelinks]{hyperref}
\\usepackage[dvipsnames,svgnames,table,hyperref]{xcolor}
\\renewcommand{\\UrlFont}{\\ttfamily\\small}
\\usepackage[a-2b]{pdfx} % why not be archival
\\usepackage[T1]{fontenc}
\\usepackage[osf,helvratio=0.9]{newpxtext} % pallatino
\\usepackage[scale=0.92]{sourcecodepro}
\\usepackage[varbb]{newpxmath}
\\usepackage{mathtools}
\\usepackage{amssymb}
\\usepackage[activate={true,nocompatibility},final,tracking=true,kerning=true,spacing=true,factor=2000]{microtype}
% microtype makes text look nicer
\\usepackage{graphicx} % include graphics
\\usepackage{grffile} % fix allowed graphicx filenames
\\usepackage{booktabs} % nice table rules
Then let's bind the content to a function, and define some nice helpers.
(setq tec/yas-latex-template-preamble "
<<latex-nice-preable>>
")
(defun tec/yas-latex-get-class-choice ()
"Prompt user for LaTeX class choice"
(setq tec/yas-latex-class-choice (ivy-read "Select document class: " '("article" "scrartcl" "bmc") :def "bmc")))
(defun tec/yas-latex-preamble-if ()
"Based on class choice prompt for insertion of default preamble"
(if (equal tec/yas-latex-class-choice "bmc") 'nil
(eq (read-char-choice "Include default preamble? [Type y/n]" '(?y ?n)) ?y)))
R
Editor Visuals
(after! ess-r-mode
(appendq! +pretty-code-symbols
'(:assign "⟵"
:multiply "×"))
(set-pretty-symbols! 'ess-r-mode
;; Functional
:def "function"
;; Types
:null "NULL"
:true "TRUE"
:false "FALSE"
:int "int"
:floar "float"
:bool "bool"
;; Flow
:not "!"
:and "&&" :or "||"
:for "for"
:in "%in%"
:return "return"
;; Other
:assign "<-"
:multiply "%*%"))
hledger
ledger-mode
is great and all, but hledger
seems to be more actively maintained.
For example, from 2018–2020, the most prolific contributor to ledger
produced
31 commits. For hledger
this statistic is 1800 commits. In addition, over the
last decade, ledger
seems to have lost steam, while hledger
seems as actively
developed as ever. From this basic comparison hledger
looks to have a more
promising outlook. It also has a few extra nicities that ledger
doesn't, but is
a little slower (haskell
vs. c++
).
Since this uses the same format, and ledger-mode
is well integrated into emacs,
and produced by John Wiegley — author of ledger
and current Emacs maintainer
— using this seems like a good idea. Thankfully we can, with a little modification.
(setq ledger-mode-should-check-version nil
ledger-report-links-in-register nil
ledger-binary-path "hledger")
Markdown
Let's use mixed pitch, because it's great
(add-hook! (gfm-mode markdown-mode) #'mixed-pitch-mode)
Most of the time when I write markdown, it's going into some app/website which will do it's own line wrapping, hence we only want to use visual line wrapping. No hard stuff.
(add-hook! (gfm-mode markdown-mode) #'visual-line-mode #'turn-off-auto-fill)
Beancount
The beancount package online has been put into ./lisp
, we just need to load and
enable it for .beancount
files.
(use-package! beancount
:load-path "~/.config/doom/lisp"
:mode ("\\.beancount\\'" . beancount-mode))