Files
dots/files/init.org
Marco Thomas 61628a5400 Updates
2022-01-13 23:38:21 +01:00

925 lines
27 KiB
Org Mode
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#+TITLE:emacs configuration
#+AUTHOR: Marco Thomas
* 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=).
To use the tangled =init.el=, I link it to =~/.emacs.d/init.el=:
#+begin_src sh :tangle no
ln -s ~/dots/files/init.el ~/.emacs.d/init.el
#+end_src
This file replaces itself with the actual configuration at first run.
#+BEGIN_SRC emacs-lisp :tangle no
(require 'org)
(find-file (concat (getenv "HOME") "/dots/files/init.org"))
(org-babel-tangle)
(load-file (concat (getenv "HOME") "/dots/files/init.el"))
#+END_SRC
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:
#+BEGIN_SRC sh :tangle no
git update-index --assume-unchanged init.el
#+END_SRC
If one wishes to make changes to the repo-version of =init.el= start
tracking again with:
#+BEGIN_SRC sh :tangle no
git update-index --no-assume-unchanged init.el
#+END_SRC
** Startup
=lexical-binding= can improve speed.
#+BEGIN_SRC emacs-lisp :tangle yes
;;; -*- lexical-binding: t -*-
#+END_SRC
** 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.
#+BEGIN_SRC emacs-lisp :tangle yes
(defun tangle-init ()
(when (equal (buffer-file-name)
(expand-file-name (concat (getenv "HOME") "/dots/files/init.org")))
;; Avoid running hooks when tangling.
(let ((prog-mode-hook nil))
(org-babel-tangle))))
(add-hook 'after-save-hook 'tangle-init)
#+END_SRC
** 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.
#+BEGIN_SRC emacs-lisp :tangle yes
(setq gc-cons-threshold most-positive-fixnum)
(add-hook 'emacs-startup-hook
(lambda ()
(setq gc-cons-threshold (* 32 1024 1024))))
#+END_SRC
* Configuration
** Performance
*** lsp-mode
Some optimization for =lsp-mode=
#+begin_src emacs-lisp :tangle yes
(setq read-process-output-max (* 3 1024 1024))
#+end_src
*** 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:
#+begin_src emacs-lisp :tangle yes
(setq-default bidi-display-reordering 'left-to-right
bidi-paragraph-direction 'left-to-right)
#+end_src
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.
#+begin_src emacs-lisp :tangle yes
(setq bidi-inhibit-bpa t)
#+end_src
Reduce rendering/line scan work for Emacs by not rendering cursors or regions
in non-focused windows.
#+begin_src emacs-lisp :tangle yes
(setq-default cursor-in-non-selected-windows nil)
(setq highlight-nonselected-windows nil)
#+end_src
Emacs "updates" its ui more often than it needs to, so slow it down slightly.
Default is 0.5.
#+begin_src emacs-lisp :tangle yes
(setq idle-update-delay 1.0)
#+end_src
Introduced in Emacs HEAD (b2f8c9f), this inhibits fontification while
receiving input, which should help a little with scrolling performance.
#+begin_src emacs-lisp :tangle yes
(setq redisplay-skip-fontification-on-input t)
#+end_src
** General
*** Super general
Some defaults, which i forget the reason of using it.
#+begin_src emacs-lisp :tangle yes
(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)
#+end_src
*** Auto revert
Automaticly revert =doc-view=-buffers when the file changes on disk.
#+BEGIN_SRC emacs-lisp :tangle yes
(add-hook 'doc-view-mode-hook 'auto-revert-mode)
#+END_SRC
*** Short yes/no
Answering /yes/ and /no/ to each question from Emacs can be tedious, a
single /y/ or /n/ will suffice.
#+BEGIN_SRC emacs-lisp :tangle yes
(fset 'yes-or-no-p 'y-or-n-p)
#+END_SRC
*** Quit prompts
Make ESC quit prompts.
#+begin_src emacs-lisp :tangle yes
(global-set-key (kbd "<escape>") 'keyboard-escape-quit)
#+end_src
*** Soft wrap
#+begin_src emacs-lisp :tangle yes
(global-visual-line-mode t)
#+end_src
** straight.el (Packages)
#+begin_src emacs-lisp :tangle yes
(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))
#+end_src
Inhibit package.el from loading, as we don't need it.
#+begin_src emacs-lisp :tangle yes
(setq package-enable-at-startup nil)
(straight-use-package 'use-package)
#+end_src
** Keybindings
*** leader key
=general= allows me to use key-binds with a leader key, just like =vim=.
#+begin_src emacs-lisp :tangle yes
(use-package general
:straight t
:init
(general-create-definer vim-leader-def :prefix "SPC"))
#+end_src
*** which-key
Show me a cool completion bar at the bottom of the screen, with all possible keybindings.
#+begin_src emacs-lisp :tangle yes
(use-package which-key
:straight t
:init
(which-key-mode)
:diminish
(which-key-mode)
:config
(setq which-key-idle-delay 1))
#+end_src
*** evil-mode
Forgive me, but I'm =evil=.
#+begin_src emacs-lisp :tangle yes
(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))
#+end_src
** Appearance
*** Fonts
I mainly use these fonts:
+ JuliaMono as main mono-spaced
+ Noto Emoji to show emojis in emacs
+ Noto JP for japanese characters
#+begin_src emacs-lisp :tangle yes
(set-face-attribute 'default nil :font "JuliaMono" :height 110)
(set-fontset-font t 'unicode "Noto Color Emoji" nil 'prepend)
(set-fontset-font t 'unicode "Noto Sans Mono CJK JP" nil 'append)
#+end_src
*** Bars
I don't need ugly ass bars.
#+begin_src emacs-lisp :tangle yes
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
#+end_src
*** Parenthesis
Show me the friend of my parenthesis.
#+begin_src emacs-lisp :tangle yes
(show-paren-mode t)
(setq show-paren-style 'paranthesis)
#+end_src
*** Line numbers
Show me relative line numbers, when in =normal= mode and absolute ones, when in =insert= mode.
#+begin_src emacs-lisp :tangle yes
(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)
#+end_src
*** Theme
Setting my beloved =ayu= light theme with some icons.
#+begin_src emacs-lisp :tangle yes
(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)
(load-theme 'doom-ayu-light t)
(doom-themes-org-config)
(doom-themes-treemacs-config))
#+end_src
*** Modeline
Use =doom-modeline= as a bar... together with icons and nyan cat!
#+begin_src emacs-lisp :tangle yes
(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))
(use-package all-the-icons
:straight t)
(use-package nyan-mode
:straight t
:init
(nyan-mode)
(nyan-start-animation)
;; (nyan-toggle-wavy-trail)
:config
(setq nyan-cat-face-number 4))
#+end_src
*** Inline colors
Show me color codes as colors!
TODO: Disable this in c/c++ mode.
#+begin_src emacs-lisp :tangle yes
(use-package rainbow-mode
:straight t
:hook
(prog-mode . rainbow-mode))
#+end_src
*** Whitespaces
Show me those pesky trailing whitespaces... I hate them. Kill them.
#+begin_src emacs-lisp :tangle yes
(global-whitespace-mode t)
(setq whitespace-style '(face trailing tabs tab-mark))
(add-hook 'before-save-hook 'whitespace-cleanup)
#+end_src
*** 80 column indicator
I only need 80 columns on my 4K display.
#+begin_src emacs-lisp :tangle yes
(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))
#+end_src
*** File bar
Sometimes I want to see all of my files.
#+begin_src emacs-lisp :tangle yes
(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 "Default")
(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 110))
: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)
#+end_src
** Mini buffers
*** ivy
Ivy - a generic completion frontend for Emacs.
Swiper - isearch with an overview, and more. Oh, man!
#+begin_src emacs-lisp :tangle yes
(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))
#+end_src
*** counsel
Spice up some of those old buffers.
#+begin_src emacs-lisp :tangle yes
(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)))
#+end_src
** ORG MODE <3
*** Setup and keys
Bootstrap =org-mode= together with keybindings.
=C-c C-t= for =org-todo=.
#+begin_src emacs-lisp :tangle yes
(use-package org
:straight t
:general
(vim-leader-def 'normal 'global
"oci" 'org-clock-in
"oco" 'org-clock-out
"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
#+end_src
*** Misc
#+begin_src emacs-lisp :tangle yes
(setq org-hidden-keywords '(title) ;; hide title
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-agenda-files (quote ("~/org")) ;; indexed files by org agenda
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-agenda-start-on-weekday nil ;; my week starts on a monday
calendar-week-start-day 1 ;; my week starts on a monday
)
#+end_src
*** org-todo faces
Which =org-todo= keywords should be used and how they look.
#+begin_src emacs-lisp :tangle yes
(setq org-todo-keywords '((sequence "TODO" "PROGRESS" "REVIEW" "|" "DONE"))
org-todo-keyword-faces '(("TODO" . "#cc241d") ("PROGRESS" . "#a6cc70") ("REVIEW" . "#b16286") ("DONE" . "#abb0b6")))
#+end_src
*** org-capture
Set some capture templates, for quick notes.
#+begin_src emacs-lisp :tangle yes
(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))))
#+end_src
*** 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).
#+begin_src emacs-lisp :tangle yes
(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)
#+end_src
*** LaTeX Export
Enable LaTeX export with =pdflatex= and use =minted= for code highlighting.
Also fix math =utf8= chars.
#+begin_src emacs-lisp :tangle yes
(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 1.5))
#+end_src
For some reason =\alert= is misinterpreted in LaTeX.
#+begin_src emacs-lisp :tangle yes
(defun mth/beamer-bold (contents backend info)
(when (eq backend 'beamer)
(replace-regexp-in-string "\\`\\\\[A-Za-z0-9]+" "\\\\textbf" contents)))
#+end_src
Use the above fix and disable creating of =.tex= files.
#+begin_src emacs-lisp :tangle yes
(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"))
#+end_src
Show math equations inline!
#+begin_src emacs-lisp :tangle yes
(use-package org-fragtog
:straight t
:hook
(org-mode . org-fragtog-mode))
#+end_src
Use graphivz to draw graphs.
#+begin_src emacs-lisp :tangle yes
(use-package graphviz-dot-mode
:straight t
:hook
(graphviz-dot-mode . (lambda () (set-input-method "math")))
:config
(setq graphviz-dot-indent-width 4))
#+end_src
*** Fonts and fancy
Some custom fonts stuff.
#+begin_src emacs-lisp :tangle yes
(set-face-attribute 'org-document-title nil :weight 'bold :inherit 'default :height 250)
(setq org-ellipsis "" ;; folding icon
;; org-hide-emphasis-markers t ;; hide markers such as *, =, _
)
#+end_src
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.
#+begin_src emacs-lisp :tangle yes
(use-package org-superstar
:straight t
:after org
:hook
(org-mode . org-superstar-mode))
#+end_src
Also the default =agenda= looks a bit messy.
#+begin_src emacs-lisp :tangle yes
(use-package org-super-agenda
:straight t
:after org
:config
(setq org-super-agenda-groups '((:auto-group t)))
(org-super-agenda-mode))
#+end_src
** General programming tools
*** Indentation
Use some magic heuristics for indentation.
#+begin_src emacs-lisp :tangle yes
(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))
#+end_src
*** Auto pairs
Auto matching pairs are reaaaaally nice.
#+begin_src emacs-lisp :tangle yes
(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))
#+end_src
*** Git
=magit= aka most convenient git client, I've ever used.
#+begin_src emacs-lisp :tangle yes
(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)
#+end_src
*** Highlight todo's
Sometimes, a big red TODO is more intimidating than one with normal text color.
#+begin_src emacs-lisp :tangle yes
(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))))
#+end_src
** Code completion
*** completion
First of all, we need a backend for our completion and analysis.
#+begin_src emacs-lisp :tangle yes
(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)))
#+end_src
Then we can sprinkle in a fancy front-end for it.
#+begin_src emacs-lisp :tangle yes
(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))
#+end_src
*** snippets
**** completion
Here I use =company= to display snippet recommendations.
#+begin_src emacs-lisp :tangle yes
(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)))
#+end_src
**** yasnippet
#+begin_src emacs-lisp :tangle yes
(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))
#+end_src
We also need the actual snippets.
#+begin_src emacs-lisp :tangle yes
(use-package yasnippet-snippets
:straight (yasnippet-snippets :type git :host github :repo "AndreaCrotti/yasnippet-snippets"
:fork (:host github
:repo "marcothms/yasnippet-snippets"))
:after yasnippet)
#+end_src
** LSP and projects
*** lsp-mode
=lsp-mode= is feature-richer than =eglot=, so I'm using this one.
#+begin_src emacs-lisp :tangle yes
(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-rust-server 'rust-analyzer
lsp-auto-guess-root t
lsp-idle-delay 1
lsp-enable-file-watchers nil)
:hook
(rust-mode . lsp)
(python-mode . lsp)
(haskell-mode . lsp)
(c++-mode . lsp))
#+end_src
In order for =lsp-mode= to work, it needs to compile code on the =fly=.
#+begin_src emacs-lisp :tangle yes
(use-package flycheck
:straight t
:after lsp)
#+end_src
*** tags
=tags= can be used to search for =tagged= entities, such as =structs= etc.
#+begin_src emacs-lisp :tangle yes
(use-package lsp-ivy
:straight t
:after lsp-mode
:bind(:map lsp-mode-map ("C-l g a" . lsp-ivy-workspace-symbol)))
#+end_src
*** projects
#+begin_src emacs-lisp :tangle yes
(use-package projectile
:straight t
:after lsp
:config
(setq projectile-completion-system 'ivy)
(projectile-mode +1))
#+end_src
*** language servers
**** rust
#+begin_src emacs-lisp :tangle yes
(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))))
#+end_src
**** haskell
#+begin_src emacs-lisp :tangle yes
(use-package haskell-mode
:straight t
:hook
(haskell-mode . interactive-haskell-mode))
(use-package lsp-haskell
:straight t
:after lsp
:hook
(haskell-mode . lsp)
(haskell-literate-mode . lsp))
#+end_src
**** python
Python's lsp has auto configuration for =lsp-mode=
** Debugging with dap-mode
#+begin_src emacs-lisp :tangle yes
(use-package dap-mode
:straight t)
#+end_src
*** python
Setup some things to use dap-mode together with python.
It depends on =ptvsd=, which can be installed via =pip=.
#+begin_src emacs-lisp :tangle yes
(require 'dap-python)
#+end_src
*** rust
TODO: add rust config for debugging
** Input methods
*** spelling
Sjoe my speling misttakes.
#+begin_src emacs-lisp :tangle yes
(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))
#+end_src
*** math
Who needs LaTeX when you can the power of unicode?
#+begin_src emacs-lisp :tangle yes
(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" ) ("\\sig" ?σ) ("\\Sig" )
("\\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)))
#+end_src