1046 lines
29 KiB
Org Mode
1046 lines
29 KiB
Org Mode
#+TITLE:emacs configuration
|
||
#+AUTHOR: Marco Thomas
|
||
#+PROPERTY: header-args :tangle "~/.emacs.d/init.el"
|
||
|
||
* Meta
|
||
** init.el vs init.org
|
||
All changes to the configuration should be done in =init.org=, *not* in
|
||
=init.el=.
|
||
|
||
This is what the initial =init.el= should look like.
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(require 'org)
|
||
(find-file (concat (getenv "HOME") "/.dots/files/emacs/init.org"))
|
||
(org-babel-tangle)
|
||
(load-file (concat (getenv "HOME") "/.emacs.d/init.el"))
|
||
#+END_SRC
|
||
|
||
|
||
** Startup
|
||
=lexical-binding= can improve speed.
|
||
#+BEGIN_SRC emacs-lisp
|
||
;;; -*- 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
|
||
(defun tangle-init ()
|
||
(when (equal (buffer-file-name)
|
||
(expand-file-name (concat (getenv "HOME") "/.dots/files/emacs/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
|
||
(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
|
||
(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
|
||
(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
|
||
(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
|
||
(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
|
||
(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
|
||
(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
|
||
(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
|
||
(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
|
||
(fset 'yes-or-no-p 'y-or-n-p)
|
||
#+END_SRC
|
||
|
||
*** Quit prompts
|
||
Make ESC quit prompts.
|
||
#+begin_src emacs-lisp
|
||
(global-set-key (kbd "<escape>") 'keyboard-escape-quit)
|
||
#+end_src
|
||
|
||
*** Soft wrap
|
||
#+begin_src emacs-lisp
|
||
(global-visual-line-mode t)
|
||
#+end_src
|
||
|
||
|
||
** straight.el (Packages)
|
||
#+begin_src emacs-lisp
|
||
(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
|
||
(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
|
||
(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
|
||
(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
|
||
(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:
|
||
+ =SFMono Nerd Font Mono= as main mono-spaced (+ Icons)
|
||
+ =JuliaMono= for all other characters
|
||
+ =Noto Emoji= to show emojis in emacs
|
||
+ =Noto JP= for japanese characters
|
||
#+begin_src emacs-lisp
|
||
(set-face-attribute 'default nil :font "SFMono Nerd Font" :height 110 :weight 'medium)
|
||
;; (set-face-attribute 'default nil :font "JuliaMono" :height 110 :weight 'medium)
|
||
(set-fontset-font t 'unicode "JuliaMono" nil 'prepend)
|
||
(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
|
||
(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
|
||
(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
|
||
(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
|
||
|
||
Show me both line and column counter in my bar.
|
||
#+begin_src emacs-lisp
|
||
(line-number-mode)
|
||
(column-number-mode)
|
||
#+end_src
|
||
|
||
*** Theme
|
||
Setting my beloved light theme with some icons.
|
||
#+begin_src emacs-lisp
|
||
(use-package doom-themes
|
||
:straight (doom-themes :type git :host github :repo "hlissner/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))
|
||
#+end_src
|
||
|
||
*** Modeline
|
||
Use =doom-modeline= as a bar... together with icons and nyan cat!
|
||
#+begin_src emacs-lisp
|
||
(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
|
||
nyan-minimum-window-width 120))
|
||
#+end_src
|
||
|
||
Show me the time!
|
||
#+begin_src emacs-lisp
|
||
(display-time-mode)
|
||
#+end_src
|
||
|
||
*** Inline colors
|
||
Show me color codes as colors!
|
||
#+begin_src emacs-lisp
|
||
(use-package rainbow-mode
|
||
:straight t
|
||
:hook
|
||
(prog-mode . rainbow-mode)
|
||
(org-mode . rainbow-mode)
|
||
(c-mode . (lambda() (rainbow-mode -1))))
|
||
#+end_src
|
||
|
||
*** Whitespaces and indentation
|
||
Show me those pesky trailing whitespaces... I hate them. Kill them.
|
||
#+begin_src emacs-lisp
|
||
(global-whitespace-mode t)
|
||
(setq whitespace-style '(face trailing tabs tab-mark))
|
||
(add-hook 'before-save-hook 'whitespace-cleanup)
|
||
#+end_src
|
||
|
||
Show me indentation markers.
|
||
#+begin_src emacs-lisp :tangle no
|
||
(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))
|
||
#+end_src
|
||
|
||
*** 80 column indicator
|
||
Show me a nice column indicator line.
|
||
#+begin_src emacs-lisp :tangle no
|
||
(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
|
||
(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)
|
||
#+end_src
|
||
|
||
*** ivy
|
||
Ivy - a generic completion frontend for Emacs.
|
||
Swiper - isearch with an overview, and more. Oh, man!
|
||
#+begin_src emacs-lisp
|
||
(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
|
||
(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
|
||
(use-package org
|
||
:straight t
|
||
:general
|
||
(vim-leader-def 'normal 'global
|
||
"os" 'org-attach-screenshot
|
||
"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
|
||
#+end_src
|
||
|
||
*** Misc
|
||
#+begin_src emacs-lisp
|
||
(setq org-startup-with-inline-images nil ;; start with inline images disabled
|
||
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-descriptive-links t ;; Always show plain links
|
||
)
|
||
#+end_src
|
||
|
||
*** org-todo faces
|
||
Which =org-todo= keywords should be used and how they look.
|
||
#+begin_src emacs-lisp
|
||
(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
|
||
(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
|
||
(org-babel-do-load-languages 'org-babel-load-languages '((python . t)
|
||
(shell . t)
|
||
(haskell . t)
|
||
(C . t)
|
||
(dot . t)
|
||
(octave . t)))
|
||
|
||
(use-package sage-shell-mode
|
||
:straight t)
|
||
|
||
(use-package ob-sagemath
|
||
:straight t)
|
||
#+end_src
|
||
|
||
*** org-agenda
|
||
The default =agenda= looks a bit messy.
|
||
#+begin_src emacs-lisp
|
||
(use-package org-super-agenda
|
||
:straight t
|
||
:after org
|
||
:config
|
||
(setq org-super-agenda-groups '((:auto-outline-path t)))
|
||
(org-super-agenda-mode))
|
||
#+end_src
|
||
|
||
Setup some stuff for =agenda=
|
||
#+begin_src emacs-lisp
|
||
(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
|
||
)
|
||
#+end_src
|
||
|
||
I need my =hjkl= :(
|
||
#+begin_src emacs-lisp
|
||
(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)
|
||
#+end_src
|
||
|
||
*** org-ref
|
||
#+begin_src emacs-lisp
|
||
(use-package org-ref
|
||
:straight t
|
||
:after org
|
||
:init
|
||
(setq org-ref-completion-library 'org-ref-ivy-cite))
|
||
#+end_src
|
||
|
||
*** org-screenshot
|
||
#+begin_src emacs-lisp :tangle no
|
||
(use-package org-attach-screenshot
|
||
:straight t
|
||
:config (setq ;org-attach-screenshot-command-line "gnome-screenshot -a -f %f"
|
||
org-attach-screenshot-auto-refresh "never"
|
||
org-attach-screenshot-insertfunction
|
||
(lambda (linkfilename)
|
||
(insert (concat
|
||
"#+caption:\n#+label: fig:"
|
||
(if
|
||
(string-match ".*\/\\(.*\\)\.png" linkfilename)
|
||
(match-string 1 linkfilename)
|
||
)
|
||
"\n#+attr_latex: :width 200"
|
||
"\n[[file:" linkfilename "]]\n\n")))))
|
||
#+end_src
|
||
|
||
*** org-alert
|
||
#+begin_src emacs-lisp
|
||
(use-package org-alert
|
||
:straight t
|
||
:config
|
||
(setq alert-default-style 'libnotify)
|
||
(org-alert-enable))
|
||
#+end_src
|
||
|
||
*** LaTeX Export
|
||
Enable LaTeX export with =pdflatex= and use =minted= for code highlighting.
|
||
Also fix math =utf8= chars.
|
||
#+begin_src emacs-lisp
|
||
(setq org-latex-listings 'minted
|
||
org-latex-minted-options '(("breaklines" "true")
|
||
("breakanywhere" "true"))
|
||
org-latex-pdf-process
|
||
'("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
|
||
"bibtex %b"
|
||
"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))
|
||
#+end_src
|
||
|
||
For some reason =\alert= is misinterpreted in LaTeX.
|
||
#+begin_src emacs-lisp
|
||
(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
|
||
(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")
|
||
(add-to-list 'org-latex-logfiles-extensions "bbl"))
|
||
#+end_src
|
||
|
||
Show math equations inline!
|
||
#+begin_src emacs-lisp :tangle no
|
||
(use-package org-fragtog
|
||
:straight t
|
||
:hook
|
||
(org-mode . org-fragtog-mode))
|
||
#+end_src
|
||
|
||
Use graphivz to draw graphs.
|
||
#+begin_src emacs-lisp
|
||
(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
|
||
(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
|
||
(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)))
|
||
#+end_src
|
||
|
||
|
||
** General programming tools
|
||
*** Indentation
|
||
Use some magic heuristics for indentation.
|
||
#+begin_src emacs-lisp
|
||
(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
|
||
(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
|
||
(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
|
||
(use-package hl-todo
|
||
:straight t
|
||
:hook
|
||
(prog-mode . hl-todo-mode)
|
||
:config
|
||
(defface hl-todo-TODO
|
||
'((t :background "#cc241d" :foreground "#ffffff"))
|
||
"TODO Face")
|
||
(defface hl-todo-UNUSED
|
||
'((t :background "#B58900" :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)
|
||
("UNUSED" . hl-todo-UNUSED))))
|
||
#+end_src
|
||
|
||
*** iedit
|
||
Easily rename occurrences, even without =lsp-rename=
|
||
#+begin_src emacs-lisp
|
||
(use-package iedit
|
||
:straight t
|
||
:general
|
||
(vim-leader-def 'normal 'global
|
||
"r" 'iedit-mode))
|
||
#+end_src
|
||
|
||
*** Code style
|
||
#+begin_src emacs-lisp
|
||
(setq ; c-default-style "bsd"
|
||
c-basic-offset 4)
|
||
(setq-default indent-tabs-mode nil)
|
||
#+end_src
|
||
|
||
|
||
** Code completion
|
||
*** completion
|
||
First of all, we need a backend for our completion and analysis.
|
||
#+begin_src emacs-lisp
|
||
(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)
|
||
(conpany-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. (only works in GUI emacs)
|
||
#+begin_src emacs-lisp
|
||
(use-package company-box
|
||
:straight t
|
||
:config
|
||
(setq company-box-doc-delay 1.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
|
||
(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
|
||
(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
|
||
(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
|
||
(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)
|
||
(c++-mode . lsp))
|
||
#+end_src
|
||
|
||
#+begin_src emacs-lisp
|
||
(use-package lsp-ui
|
||
:straight t
|
||
:after lsp)
|
||
#+end_src
|
||
|
||
In order for =lsp-mode= to work, it needs to compile code on the =fly=.
|
||
#+begin_src emacs-lisp
|
||
(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
|
||
(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
|
||
(use-package projectile
|
||
:straight t
|
||
:after lsp
|
||
:config
|
||
(setq projectile-completion-system 'ivy)
|
||
(projectile-mode +1))
|
||
#+end_src
|
||
|
||
*** language server configurations
|
||
**** rust
|
||
Basic =rust-mode= with some fancy characters.
|
||
#+begin_src emacs-lisp
|
||
(use-package rust-mode
|
||
:straight t)
|
||
#+end_src
|
||
|
||
I want to use =rust-analyzer= and see inlay type hints for variables.
|
||
Warning: If inlay hints don't work, make sure to use the lastest:
|
||
+ rust version
|
||
+ =rust-analyzer=
|
||
+ =rust-mode=
|
||
+ =lsp-mode=
|
||
#+begin_src emacs-lisp
|
||
(setq lsp-rust-server 'rust-analyzer
|
||
lsp-rust-analyzer-server-display-inlay-hints t)
|
||
(add-hook 'rust-mode 'lsp-rust-analyzer-inlay-hints-mode)
|
||
#+end_src
|
||
|
||
**** haskell
|
||
=ghcup install hls=
|
||
and
|
||
=cabal install stylish-haskell=
|
||
are required.
|
||
#+begin_src emacs-lisp
|
||
(use-package haskell-mode
|
||
:straight t
|
||
:config
|
||
(setq haskell-stylish-on-save 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
|
||
|
||
*** octave
|
||
#+begin_src emacs-lisp
|
||
(use-package octave-mode
|
||
:mode ("\\.m\\'" . octave-mode)
|
||
:hook
|
||
(octave-mode . company-mode))
|
||
#+end_src
|
||
|
||
|
||
** Input methods
|
||
*** spelling
|
||
Sjoe my speling misttakes.
|
||
#+begin_src emacs-lisp
|
||
(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 have the power of unicode?
|
||
#+begin_src emacs-lisp
|
||
(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)))
|
||
#+end_src
|
||
|
||
|
||
** 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
|
||
#+begin_src emacs-lisp
|
||
(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)
|
||
:hook
|
||
(pdf-misc-minor-mode . auto-revert-mode))
|
||
|
||
|
||
;; load necessary things, when a PDF gets opened
|
||
(pdf-tools-install)
|
||
#+end_src
|