Files
dots/files/emacs/.emacs.d/init.org
2022-03-11 15:58:47 +01:00

30 KiB
Raw Blame History

#+TITLE:emacs configuration

Meta

init.el vs init.org

All changes to the configuration should be done in init.org, not in init.el. Any changes in the init.el will be overwritten by saving init.org. The init.el in this repo should not be tracked by git, and is replaced the first time Emacs is started (assuming it has been renamed to ~/.emacs.d).

This file replaces itself with the actual configuration at first run.

(require 'org)
(find-file (concat (getenv "HOME") "/.dots/files/emacs/.emacs.d/init.org"))
(org-babel-tangle)
(load-file (concat (getenv "HOME") "/.dots/files/emacs/.emacs.d/init.el"))

It tangles the org-file, so that this file is overwritten with the actual configuration.

There is no reason to track the init.el that is generated; by running the following command git will not bother tracking it:

git update-index --assume-unchanged init.el

If one wishes to make changes to the repo-version of init.el start tracking again with:

git update-index --no-assume-unchanged init.el

Startup

lexical-binding can improve speed.

;;; -*- lexical-binding: t -*-

Tangle

The init.el should (after the first run) mirror the source blocks in the init.org. We can use C-c C-v t to run org-babel-tangle, which extracts the code blocks from the current file into a source-specific file (in this case a .el-file).

To avoid doing this each time a change is made we can add a function to the after-save-hook ensuring to always tangle and byte-compile the org-document after changes.

(defun tangle-init ()
  (when (equal (buffer-file-name)
               (expand-file-name (concat (getenv "HOME") "/.dots/files/emacs/.emacs.d/init.org")))
    ;; Avoid running hooks when tangling.
    (let ((prog-mode-hook nil))
      (org-babel-tangle))))

(add-hook 'after-save-hook 'tangle-init)

Performance for start-up

A common optimization is to temporarily disable garbage collection during initialization. Here, we set the gc-cons-threshold to a ridiculously large number, and restore the default value after initialization.

(setq gc-cons-threshold most-positive-fixnum)
(add-hook 'emacs-startup-hook
  (lambda ()
    (setq gc-cons-threshold (* 32 1024 1024))))

Configuration

Performance

lsp-mode

Some optimization for lsp-mode

(setq read-process-output-max (* 3 1024 1024))

Scrolling

Disable bidirectional text scanning for a modest performance boost. I've set this to nil in the past, but the bidi-display-reordering's docs say that is an undefined state and suggest this to be just as good:

(setq-default bidi-display-reordering 'left-to-right
              bidi-paragraph-direction 'left-to-right)

Disabling the BPA makes redisplay faster, but might produce incorrect display reordering of bidirectional text with embedded parentheses and other bracket characters whose paired-bracket Unicode property is non-nil. Emacs 27+ only.

(setq bidi-inhibit-bpa t)

Reduce rendering/line scan work for Emacs by not rendering cursors or regions in non-focused windows.

(setq-default cursor-in-non-selected-windows nil)
(setq highlight-nonselected-windows nil)

Emacs "updates" its ui more often than it needs to, so slow it down slightly. Default is 0.5.

(setq idle-update-delay 1.0)

Introduced in Emacs HEAD (b2f8c9f), this inhibits fontification while receiving input, which should help a little with scrolling performance.

(setq redisplay-skip-fontification-on-input t)

General

Super general

Some defaults, which i forget the reason of using it.

(setq make-backup-files nil
      auto-mode-case-fold nil
      auto-save-default nil
      inhibit-startup-screen t
      tramp-default-method "ssh"
      initial-major-mode 'fundamental-mode
      initial-scratch-message nil
      fast-but-imprecise-scrolling t)

Auto revert

Automaticly revert doc-view-buffers when the file changes on disk.

(add-hook 'doc-view-mode-hook 'auto-revert-mode)

Short yes/no

Answering yes and no to each question from Emacs can be tedious, a single y or n will suffice.

(fset 'yes-or-no-p 'y-or-n-p)

Quit prompts

Make ESC quit prompts.

(global-set-key (kbd "<escape>") 'keyboard-escape-quit)

Soft wrap

(global-visual-line-mode t)

straight.el (Packages)

(setq straight-check-for-modifications 'live)
(defvar bootstrap-version)

(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

Inhibit package.el from loading, as we don't need it.

(setq package-enable-at-startup nil)
(straight-use-package 'use-package)

Keybindings

leader key

general allows me to use key-binds with a leader key, just like vim.

(use-package general
  :straight t
  :init
  (general-create-definer vim-leader-def :prefix "SPC"))

which-key

Show me a cool completion bar at the bottom of the screen, with all possible keybindings.

(use-package which-key
  :straight t
  :init
  (which-key-mode)
  :diminish
  (which-key-mode)
  :config
  (setq which-key-idle-delay 1))

evil-mode

Forgive me, but I'm evil.

(use-package evil
  :straight t
  :bind
  (:map evil-motion-state-map
        ("C-y" . nil))
  (:map evil-insert-state-map
        ("C-y" . nil))
  :init
  ;; so C-z works for background
  (setq evil-toggle-key "C-~"
        evil-want-C-d-scroll t
        evil-want-C-u-scroll t
        evil-want-integration t
        evil-want-keybinding nil)
  :config
  (evil-mode))

(use-package evil-collection
  :straight t
  :after evil
  :config
  (evil-collection-init))

(use-package evil-matchit
  :straight t
  :after evil
  :config
  (global-evil-matchit-mode 1))

Appearance

Fonts

I mainly use these fonts:

  • JuliaMono as main mono-spaced
  • Noto Emoji to show emojis in emacs
  • Noto JP for japanese characters
(set-face-attribute 'default nil :font "JuliaMono" :height 100)
(set-fontset-font t 'unicode "Noto Color Emoji" nil 'prepend)
(set-fontset-font t 'unicode "Noto Sans Mono CJK JP" nil 'append)

Use non-monospace font for org-mode! Blocks will still be mono-spaced.

(set-face-attribute 'variable-pitch nil :family "Roboto")
(set-face-attribute 'fixed-pitch nil :family "JuliaMono")

(use-package mixed-pitch
  :straight t
  :hook
  (text-mode . mixed-pitch-mode)
  (org-agenda-mode . mixed-pitch-mode))

Bars

I don't need ugly ass bars.

(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)

Parenthesis

Show me the friend of my parenthesis.

(show-paren-mode t)
(setq show-paren-style 'paranthesis)

Line numbers

Show me relative line numbers, when in normal mode and absolute ones, when in insert mode.

(setq-default display-line-numbers 'relative
              display-line-numbers-widen t
              ;; this is the default
              display-line-numbers-current-absolute t)

;; Display absolute numbers, when in normal mode
(defun noct:relative ()
  (setq-local display-line-numbers 'relative))

(defun noct:absolute ()
  (setq-local display-line-numbers t))

(add-hook 'evil-insert-state-entry-hook #'noct:absolute)
(add-hook 'evil-insert-state-exit-hook #'noct:relative)

Show me both line and column counter in my bar.

(line-number-mode)
(column-number-mode)

Theme

Setting my beloved light theme with some icons.

(use-package doom-themes
  :straight (doom-themes :type git :host github :repo "hlissner/emacs-doom-themes"
                                :fork (:host github :repo "CramMK/emacs-doom-themes"))
  :config
  (setq doom-themes-enable-bold t
        doom-themes-enable-italic t
        doom-solarized-light-padded-modeline nil)
  (load-theme 'doom-solarized-light t)
  (doom-themes-org-config)
  (doom-themes-treemacs-config))

Modeline

Use doom-modeline as a bar… together with icons and nyan cat!

(use-package doom-modeline
  :straight t
  :config
  (doom-modeline-mode 1)
  (setq doom-modeline-indent-info t
        doom-modeline-buffer-file-name-style 'file-name
        doom-modeline-height 1))

(use-package all-the-icons
  :straight t)

(use-package nyan-mode
  :straight t
  :init
  ;; (nyan-mode)
  ;; (nyan-start-animation)
  :config
  (setq nyan-cat-face-number 4))

Inline colors

Show me color codes as colors! TODO: Disable this in c/c++ mode.

(use-package rainbow-mode
  :straight t
  :hook
  (prog-mode . rainbow-mode)
  (org-mode . rainbow-mode))

Whitespaces

Show me those pesky trailing whitespaces… I hate them. Kill them.

(global-whitespace-mode t)
(setq whitespace-style '(face trailing tabs tab-mark))
(add-hook 'before-save-hook 'whitespace-cleanup)

80 column indicator

Show me a nice column indicator line.

(use-package fill-column-indicator
  :straight t
  :defer 1
  :diminish
  (fci-mode)
  :config
  (setq fci-rule-width 1
        fci-rule-column 80
        fci-rule-color "#A6CC70")
  :hook
  (prog-mode . fci-mode)
  (markdown-mode . fci-mode))

Highlight indentation

Show me indentation markers.

(use-package highlight-indent-guides
  :straight t
  :config
  (setq highlight-indent-guides-method 'character
        highlight-indent-guides-responsive 'top)
  :hook
  (prog-mode . highlight-indent-guides-mode))

File bar

Sometimes I want to see all of my files.

(use-package treemacs
  :straight t
  :defer t
  :config
  (setq treemacs-follow-after-init t
        treemacs-persist-file (expand-file-name ".cache/treemacs-persist" user-emacs-directory)
        treemacs-width 50
        treemacs-project-follow-cleanup t
        treemacs-tag-follow-cleanup t
        treemacs-expand-after-init nil
        treemacs-recenter-after-file-follow t
        treemacs-recenter-after-tag-follow t
        treemacs-tag-follow-delay 1)
  (treemacs-follow-mode t)
  (treemacs-load-theme "doom-colors")
  (dolist (face '(treemacs-root-face
                  treemacs-git-unmodified-face
                  treemacs-git-modified-face
                  treemacs-git-renamed-face
                  treemacs-git-ignored-face
                  treemacs-git-untracked-face
                  treemacs-git-added-face
                  treemacs-git-conflict-face
                  treemacs-directory-face
                  treemacs-directory-collapsed-face
                  treemacs-file-face
                  treemacs-tags-face))
    (set-face-attribute face nil :family "JuliaMono" :height 80))
  :bind
  (:map global-map
    ("C-x t t" . treemacs)))

;; C-c C-p -> projectile
;; C-c C-w -> workspace

(use-package treemacs-evil
  :after (treemacs evil)
  :straight t)

Mini buffers

ivy

Ivy - a generic completion frontend for Emacs. Swiper - isearch with an overview, and more. Oh, man!

(use-package ivy
  :straight t
  :diminish
  :bind (("C-s" . swiper)
         :map ivy-minibuffer-map
         ("TAB" . ivy-alt-done)
         ("C-l" . ivy-alt-done)
         ("C-j" . ivy-next-line)
         ("C-k" . ivy-previous-line)
         :map ivy-switch-buffer-map
         ("C-k" . ivy-previous-line)
         ("C-l" . ivy-done)
         ("C-d" . ivy-switch-buffer-kill)
         :map ivy-reverse-i-search-map
         ("C-k" . ivy-previous-line)
         ("C-d" . ivy-reverse-i-search-kill))
  :config
  (ivy-mode 1))

counsel

Spice up some of those old buffers.

(use-package counsel
  :straight t
  :bind (("M-x" . counsel-M-x)
         ("C-x b" . counsel-ibuffer)
         ("C-x C-f" . counsel-find-file)
         ("C-x C-g" . counsel-git)
         :map minibuffer-local-map
         ("C-r" . 'counsel-minibuffer-history)))

ORG MODE <3

Setup and keys

Bootstrap org-mode together with keybindings. C-c C-t for org-todo.

(use-package org
  :straight t
  :general
  (vim-leader-def 'normal 'global
    "oci" 'org-clock-in
    "oco" 'org-clock-out
    "ocd" 'org-clock-display
    "oa"  'org-agenda
    "oca" 'org-capture
    "oes" 'org-edit-src-code
    "oti" 'org-toggle-inline-images
    "odi" 'org-display-inline-images)
  :hook
  (org-mode . (lambda () (electric-indent-local-mode -1)))   ;; dont make real spaces at the start of a line
  (org-mode . org-indent-mode)                               ;; add virtual spaces
  :config
  (define-key evil-normal-state-map (kbd "TAB") 'org-cycle)) ;; use TAB to FOLD in every evil-mode

Misc

(setq org-startup-with-inline-images t       ;; start with inline images enabled
      org-image-actual-width nil             ;; rescale inline images
      org-directory "~/org"                  ;; set org file directory
      org-edit-src-content-indentation 0     ;; don't indent stupidly in org-edit-src-code
      org-log-done nil                       ;; just mark DONE without a time stamp
      org-log-repeat nil                     ;; don't set a time after marking sth DONE
)

org-todo faces

Which org-todo keywords should be used and how they look.

(setq org-todo-keywords '((sequence "TODO" "PROGRESS" "REVIEW" "|" "DONE"))
      org-todo-keyword-faces '(("TODO" . "#cc241d") ("PROGRESS" . "#a6cc70") ("REVIEW" . "#b16286") ("DONE" . "#abb0b6")))

org-capture

Set some capture templates, for quick notes.

(setq org-capture-templates
  (quote (("w" "Work" entry (file "~/org/work.org") "* TODO %?\n" :empty-lines-before 1)
          ("u" "University" entry (file "~/org/uni.org") "* TODO %?\n" :empty-lines-before 1)
          ("p" "Personal" entry (file "~/org/personal.org") "* TODO %?\n" :empty-lines-before 1))))

org-babel

Executing code inline is just a breeze. Firstly tho, they must be enabled here. Also be careful with haskell recursion, it can lead to system crashes (at least for me).

(org-babel-do-load-languages 'org-babel-load-languages '((python . t)
                                                         (shell . t)
                                                         (haskell . t)
                                                         (C . t)
                                                         (dot . t)))

(use-package sage-shell-mode
  :straight t)

(use-package ob-sagemath
  :straight t)

org-agenda

The default agenda looks a bit messy.

(use-package org-super-agenda
  :straight t
  :after org
  :config
  (setq org-super-agenda-groups '((:auto-outline-path t)))
  (org-super-agenda-mode))

Setup some stuff for agenda

(setq org-agenda-files (quote ("~/org"))     ;; indexed files by org agenda
      org-agenda-start-on-weekday nil        ;; my week starts on a monday
      calendar-week-start-day 1              ;; my week starts on a monday
)

I need my hjkl :(

(define-key org-agenda-mode-map (kbd "h") 'org-agenda-earlier)
(define-key org-agenda-mode-map (kbd "l") 'org-agenda-later)
(define-key org-agenda-mode-map (kbd "j") 'org-agenda-next-line)
(define-key org-agenda-mode-map (kbd "k") 'org-agenda-previous-line)
(define-key org-agenda-mode-map (kbd "t") 'org-agenda-goto-today)

(define-key org-super-agenda-header-map (kbd "h") 'org-agenda-earlier)
(define-key org-super-agenda-header-map (kbd "l") 'org-agenda-later)
(define-key org-super-agenda-header-map (kbd "j") 'org-agenda-next-line)
(define-key org-super-agenda-header-map (kbd "k") 'org-agenda-previous-line)
(define-key org-super-agenda-header-map (kbd "t") 'org-agenda-goto-today)

LaTeX Export

Enable LaTeX export with pdflatex and use minted for code highlighting. Also fix math utf8 chars.

(setq org-latex-listings 'minted
      org-latex-packages-alist '(("" "minted"))
      org-latex-pdf-process
      '("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
        "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
        "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f")
      org-latex-inputenc-alist '(("utf8" . "utf8x"))
      org-latex-default-packages-alist (cons '("mathletters" "ucs" nil) org-latex-default-packages-alist)
      org-format-latex-options (plist-put org-format-latex-options :scale 0.5))

For some reason \alert is misinterpreted in LaTeX.

(defun mth/beamer-bold (contents backend info)
  (when (eq backend 'beamer)
    (replace-regexp-in-string "\\`\\\\[A-Za-z0-9]+" "\\\\textbf" contents)))

Use the above fix and disable creating of .tex files.

(use-package ox
  :after org
  :config
  (add-to-list 'org-export-filter-bold-functions 'mth/beamer-bold)
  (add-to-list 'org-latex-logfiles-extensions "tex"))

Show math equations inline!

(use-package org-fragtog
  :straight t
  :hook
  (org-mode . org-fragtog-mode))

Use graphivz to draw graphs.

(use-package graphviz-dot-mode
  :straight t
  :hook
  (graphviz-dot-mode . (lambda () (set-input-method "math")))
  :config
  (setq graphviz-dot-indent-width 4))

Fonts and fancy

Some custom fonts stuff.

(setq org-ellipsis " ⮷"                    ;; folding icon
      ;; org-hide-emphasis-markers t          ;; hide markers such as *, =, _
)

I want my org-bullets to look fancy, so I'm using some UTF8 chars. Use (setq inhibit-compacting-font-caches t), if performance is low.

(use-package org-superstar
  :straight t
  :after org
  :hook
  (org-mode . org-superstar-mode)
  :config
  (setq org-superstar-remove-leading-stars t
        org-superstar-headline-bullets-list '(9673 10061 10040)))

General programming tools

Indentation

Use some magic heuristics for indentation.

(use-package dtrt-indent
  :straight t
  :hook
  (prog-mode . dtrt-indent-mode)
  (text-mode . dtrt-indent-mode)
  (org-mode . dtrt-indent-mode)
  (markdown-mode . dtrt-indent-mode))

Auto pairs

Auto matching pairs are reaaaaally nice.

(use-package electric-pair
  :config
  (setq electric-pair-open-newline-between-pairs nil)
  :hook
  (prog-mode . electric-pair-mode)
  (text-mode . electric-pair-mode)
  (org-mode . electric-pair-mode)
  (markdown-mode . electric-pair-mode))

Git

magit aka most convenient git client, I've ever used.

(use-package magit
  :straight t
  :general
  (vim-leader-def 'normal 'global
    "gb" 'magit-branch
    "gc" 'magit-checkout
    "gc" 'magit-commit
    "gd" 'magit-diff
    "gg" 'counsel-git-grep
    "gi" 'magit-gitignore-in-topdir
    "gj" 'magit-blame
    "gl" 'magit-log
    "gp" 'magit-push
    "gs" 'magit-status
    "gu" 'magit-pull))

(use-package treemacs-magit
  :after (treemacs magit)
  :straight t)

Highlight todo's

Sometimes, a big red TODO is more intimidating than one with normal text color.

(use-package hl-todo
  :straight t
  :hook
  (prog-mode . hl-todo-mode)
  :config
  (defface hl-todo-TODO
    '((t :background "#cc241d" :foreground "#ffffff"))
    "TODO Face")
  (setq hl-todo-highlight-punctuation ":"
        hl-todo-color-background t
        hl-todo-keyword-faces '(("TODO"  . hl-todo-TODO)
                                ("XXX"   . hl-todo-TODO)
                                ("FIXME" . hl-todo-TODO))))

Code completion

completion

First of all, we need a backend for our completion and analysis.

(use-package company
  :straight t
  :hook
  (lsp-mode . company-mode)
  (prog-mode . company-mode)
  (LaTeX-mode . company-mode)
  (org-mode . company-mode)
  :custom
  (company-minimum-prefix-length 3)
  (company-idle-delay 0.5)
  :bind (:map company-active-map
              ("C-j" . company-select-next-or-abort)
              ("C-k" . company-select-previous-or-abort)
              ("C-l" . company-complete-selection)))

Then we can sprinkle in a fancy front-end for it.

(use-package company-box
  :straight t
  :config
  (setq company-box-doc-delay 2.0
        company-box-max-candidates 10)
  :hook
  (company-mode . company-box-mode))

snippets

completion

Here I use company to display snippet recommendations.

(defun company-mode/backend-with-yas (backend)
  (if (and (listp backend) (member 'company-yasnippet backend))
      backend
    (append (if (consp backend) backend (list backend))
            '(:with company-yasnippet))))

(defun company-mode/add-yasnippet ()
  (setq company-backends (mapcar #'company-mode/backend-with-yas company-backends)))
yasnippet
(use-package yasnippet
  :straight t
  :init
  :bind (:map yas-minor-mode-map
              ("C-y" . yas-expand))
  :hook
  (company-mode . yas-minor-mode)
  (company-mode . company-mode/add-yasnippet))

We also need the actual snippets.

(use-package yasnippet-snippets
  :straight (yasnippet-snippets :type git :host github :repo "AndreaCrotti/yasnippet-snippets"
                                :fork (:host github
                                             :repo "marcothms/yasnippet-snippets"))
  :after yasnippet)

LSP and projects

lsp-mode

lsp-mode is feature-richer than eglot, so I'm using this one.

(use-package lsp-mode :straight t
  :commands (lsp lsp-deferred)
  :init
  (setq lsp-keymap-prefix "C-l")
  :config
  (lsp-enable-which-key-integration t)
  (setq lsp-auto-guess-root t
        lsp-idle-delay 1
        lsp-enable-file-watchers nil
        lsp-headerline-breadcrumb-icons-enable nil)
  :hook
  (rust-mode . lsp)
  (python-mode . lsp)
  (haskell-mode . lsp)
  (c++-mode . lsp))

In order for lsp-mode to work, it needs to compile code on the fly.

(use-package flycheck
  :straight t
  :after lsp)

tags

tags can be used to search for tagged entities, such as structs etc.

(use-package lsp-ivy
  :straight t
  :after lsp-mode
  :bind(:map lsp-mode-map ("C-l g a" . lsp-ivy-workspace-symbol)))

projects

(use-package projectile
  :straight t
  :after lsp
  :config
  (setq projectile-completion-system 'ivy)
  (projectile-mode +1))

language servers

rust

Basic rust-mode with some fancy characters.

(use-package rust-mode
  :straight t
  :hook
  (rust-mode . prettify-symbols-mode)
  (rust-mode . (lambda ()
                 (push '("->" . ?→) prettify-symbols-alist)
                 (push '("=>" . ?⇒) prettify-symbols-alist)
                 (push '("!=" . ?≠) prettify-symbols-alist)
                 (push '("<=" . ?≤) prettify-symbols-alist)
                 (push '(">=" . ?≥) prettify-symbols-alist))))

I want to use rust-analyzer and see inlay type hints for variables.

(setq lsp-rust-server 'rust-analyzer
      lsp-rust-analyzer-server-display-inlay-hints t)
(add-hook 'rust-mode 'lsp-rust-analyzer-inlay-hints-mode)
haskell
(use-package haskell-mode
  :straight t
  :hook
  (haskell-mode . interactive-haskell-mode)
  (haskell-mode . prettify-symbols-mode)
  (haskell-mode . (lambda ()
                    (push '("->" . ?→) prettify-symbols-alist)
                    (push '("<-" . ?←) prettify-symbols-alist)
                    (push '("=>" . ?⇒) prettify-symbols-alist)
                    )))

(use-package lsp-haskell
  :straight t
  :after lsp
  :hook
  (haskell-mode . lsp)
  (haskell-literate-mode . lsp))
python

Python's lsp has auto configuration for lsp-mode

Debugging with dap-mode

(use-package dap-mode
  :straight t)

python

Setup some things to use dap-mode together with python. It depends on ptvsd, which can be installed via pip.

(require 'dap-python)

rust

TODO: add rust config for debugging

Input methods

spelling

Sjoe my speling misttakes.

(use-package ispell
  :straight t
  :if (executable-find "hunspell")
  :config
  (setq ispell-program-name "hunspell"
        ispell-dictionary "de_DE,en_GB,en_US")
  (ispell-set-spellchecker-params)
  (ispell-hunspell-add-multi-dic "de_DE,en_GB,en_US")
  :hook
  (org-mode . flyspell-mode)
  (markdown-mode . flyspell-mode)
  (text-mode . flyspell-mode))

math

Who needs LaTeX when you can have the power of unicode?

(use-package math-symbol-lists
  :straight t
  :config
  (quail-define-package "math" "UTF-8" "Ω" t)
  (quail-define-rules
   ; Equality and order
   ("<=" ?≤) (">=" ?≥) ("\\prec" ?≺) ("\\preceq" ?≼) ("\\succ" ?≻)
   ("\\succeq" ?≽)
   ("/=" ?≠) ("\\neq" ?≠) ("\\=n" ?≠)("\\equiv" ?≡) ("\\nequiv" ?≢)
   ("\\approx" ?≈) ("\\~~" ?≈) ("\\t=" ?≜) ("\\def=" ?≝)

   ; Set theory
   ("\\sub" ?⊆) ("\\subset" ?⊂) ("\\subseteq" ?⊆) ("\\in" ?∈)
   ("\\inn" ?∉) ("\\:" ?∈) ("\\cap" ?∩) ("\\inter" ?∩)
   ("\\cup" ?) ("\\uni" ?) ("\\emptyset" ?∅) ("\\empty" ?∅)
   ("\\times" ?×) ("\\x" ?×)

   ; Number stuff
   ("\\mid" ?) ("\\infty" ?∞) ("\\sqrt" ?√) ("\\Im" ?) ("\\Re" ?)

   ; Logic
   ("\\/" ?) ("\\and" ?∧) ("/\\" ?∧) ("\\or" ?) ("~" ) ("\neg" )
   ("|-" ?⊢) ("|-n" ?⊬) ("\\bot" ?⊥) ("\\top" ?)
   ("\\r" ?→) ("\\lr" ?↔)
   ("\\R" ?⇒) ("\\Lr" ?⇔)
   ("\\qed" ?∎)

   ; Predicate logic
   ("\\all" ?∀) ("\\ex" ?∃) ("\\exn" ?∄)

   ; functions
   ("\\to" ?→) ("\\mapsto" ?↦) ("\\circ" ?∘) ("\\comp" ?∘) ("\\integral" ?∫)
   ("\\fun" )

   ; Sets of numbers
   ("\\nat" ?) ("\\N" ?) ("\\int" ?) ("\\Z" ?) ("\\rat" ?) ("\\Q" ?)
   ("\\real" ?) ("\\R" ?) ("\\complex" ?) ("\\C" ?) ("\\prime" ?)
   ("\\P" ?)

   ; Complexity
   ("\\bigo" ?𝒪)

   ; Greek
   ("\\Ga" ?α) ("\\GA" ?Α) ("\\a" ?α)
   ("\\Gb" ) ("\\GB" ?Β) ("\\b" )
   ("\\Gg" ?γ) ("\\GG" ) ("\\g" ?γ) ("\\Gamma" )
   ("\\Gd" ) ("\\GD" ) ("\\delta" ) ("\\Delta" )
   ("\\Ge" ) ("\\GE" ?Ε) ("\\epsilon" )
   ("\\Gz" ) ("\\GZ" ?Ζ)
   ("\\Gh" ) ("\\Gh" ?Η) ("\\mu" )
   ("\\Gth" ) ("\\GTH" ) ("\\theta" ) ("\\Theta" )
   ("\\Gi" ?ι) ("\\GI" ?Ι) ("\\iota" ?ι)
   ("\\Gk" ) ("\\GK" ?Κ)
   ("\\Gl" ) ("\\GL" ) ("\\lam" )
   ("\\Gm" ) ("\\GM" Μ) ("\\mu" )
   ("\\Gx" ) ("\\GX" ) ("\\xi" ) ("\\Xi" )
   ("\\Gp" ) ("\\GP" ) ("\\pi" ) ("\\Pi" )
   ("\\Gr" ?ρ) ("\\GR" ?Ρ) ("\\rho" ?ρ)
   ("\\Gs" ?σ) ("\\GS" ) ("\\sigma" ?σ) ("\\Sigma" )
   ("\\Gt" ) ("\\GT" ?Τ) ("\\tau" )
   ("\\Gph" ) ("\\GPH" ) ("\\phi" ) ("\\Phi" )
   ("\\Gc" ) ("\\GC" ?Χ) ("\\chi" )
   ("\\Gp" ) ("\\GP" ) ("\\psi" )
   ("\\Go" ) ("\\GO" ) ("\\omega" ) ("\\Omega" )
  )
  (mapc (lambda (x)
          (if (cddr x)
              (quail-defrule (cadr x) (car (cddr x)))))
        (append math-symbol-list-superscripts
                math-symbol-list-subscripts)))

PDF

pdf-tools

Built-in DocView isn't too nice to use. pdf-tools offers smoother scrolling and a nicer search. isearch-forward-regexp replaces swiper in this mode, as swiper would regexp in the PDF source. Keybinds:

  • C-s: search, just as in swiper
  • C-s (again): forward search
  • C-r: backward search
(use-package pdf-tools
  :straight t
  :config
  (define-key pdf-view-mode-map [remap swiper] 'isearch-forward-regexp)
  (define-key pdf-view-mode-map [remap evil-ex] 'pdf-view-goto-page)
  (setq-default pdf-view-display-size 'fit-page)
  (setq pdf-view-resize-factor 1.1))

;; load necessary things, when a PDF gets opened
(pdf-tools-install)