+
+
+
Table of Contents
+
+- [Primary setup](#primary-setup)
+ - [Measure startup speed](#measure-startup-speed)
+ - [straight.el](#straight-dot-el)
+ - [use-package](#use-package)
+ - [Performance](#performance)
+ - [Garbage collection](#garbage-collection)
+ - [Run garbage collection when Emacs is unfocused](#run-garbage-collection-when-emacs-is-unfocused)
+ - [Misc](#misc)
+ - [Native compilation](#native-compilation)
+ - [Anaconda & environment](#anaconda-and-environment)
+ - [Custom file location](#custom-file-location)
+ - [Private config](#private-config)
+ - [No littering](#no-littering)
+- [Global editing configuration](#global-editing-configuration)
+ - [General keybindings stuff](#general-keybindings-stuff)
+ - [general.el](#general-dot-el)
+ - [which-key](#which-key)
+ - [dump keybindings](#dump-keybindings)
+ - [Evil mode](#evil-mode)
+ - [evil](#evil)
+ - [Addons](#addons)
+ - [evil-collection](#evil-collection)
+ - [More keybindings](#more-keybindings)
+ - [Escape key](#escape-key)
+ - [Home & end](#home-and-end)
+ - [My leader](#my-leader)
+ - [Universal argument](#universal-argument)
+ - [Profiler](#profiler)
+ - [Buffer switching](#buffer-switching)
+ - [Buffer management](#buffer-management)
+ - [xref](#xref)
+ - [Folding](#folding)
+ - [Zoom](#zoom)
+ - [Editing helpers](#editing-helpers)
+ - [Visual fill column mode](#visual-fill-column-mode)
+ - [smartparens](#smartparens)
+ - [Aggressive Indent](#aggressive-indent)
+ - [Delete trailing whitespace](#delete-trailing-whitespace)
+ - [Expand region](#expand-region)
+ - [Various settings](#various-settings)
+ - [Tabs](#tabs)
+ - [Scrolling config](#scrolling-config)
+ - [Clipboard](#clipboard)
+ - [Backups](#backups)
+ - [Undo Tree](#undo-tree)
+ - [Help](#help)
+ - [Ivy, counsel, swiper](#ivy-counsel-swiper)
+ - [ivy-rich](#ivy-rich)
+ - [prescient](#prescient)
+ - [Keybindings](#keybindings)
+ - [
OFF (OFF) Helm](#off--helm)
+ - [Treemacs](#treemacs)
+ - [Helper functions](#helper-functions)
+ - [Custom icons](#custom-icons)
+ - [Projectile](#projectile)
+ - [Company](#company)
+ - [Git & Magit](#git-and-magit)
+ - [Editorconfig](#editorconfig)
+ - [Snippets](#snippets)
+ - [Time trackers](#time-trackers)
+ - [WakaTime](#wakatime)
+ - [Fixes](#fixes)
+ - [ActivityWatch](#activitywatch)
+- [UI](#ui)
+ - [General UI & GUI Settings](#general-ui-and-gui-settings)
+ - [Theme & global stuff](#theme-and-global-stuff)
+ - [Custom theme](#custom-theme)
+ - [Font](#font)
+ - [Custom frame title](#custom-frame-title)
+ - [perspective.el](#perspective-dot-el)
+ - [Some functions](#some-functions)
+ - [
OFF (OFF) Tab bar](#off--tab-bar)
+ - [Setup](#setup)
+ - [My title](#my-title)
+ - [Modeline](#modeline)
+ - [Font stuff](#font-stuff)
+ - [Emojis](#emojis)
+ - [Ligatures](#ligatures)
+ - [Icons](#icons)
+ - [Highlight todo](#highlight-todo)
+ - [Text highlight improvements](#text-highlight-improvements)
+- [Dired](#dired)
+ - [Basic config & keybindings](#basic-config-and-keybindings)
+ - [Addons](#addons)
+ - [Subdirectories](#subdirectories)
+ - [TRAMP](#tramp)
+ - [Bookmarks](#bookmarks)
+- [Shells](#shells)
+ - [vterm](#vterm)
+ - [Configuration](#configuration)
+ - [Subterminal](#subterminal)
+ - [Dired integration](#dired-integration)
+ - [Eshell](#eshell)
+- [Org Mode](#org-mode)
+ - [Installation & basic settings](#installation-and-basic-settings)
+ - [Encryption](#encryption)
+ - [org-contrib](#org-contrib)
+ - [Integration with evil](#integration-with-evil)
+ - [Literate programing](#literate-programing)
+ - [Python & Jupyter](#python-and-jupyter)
+ - [Hy](#hy)
+ - [View HTML in browser](#view-html-in-browser)
+ - [PlantUML](#plantuml)
+ - [Setup](#setup)
+ - [Managing Jupyter kernels](#managing-jupyter-kernels)
+ - [Do not wrap the output in emacs-jupyter](#do-not-wrap-the-output-in-emacs-jupyter)
+ - [Wrap source code output](#wrap-source-code-output)
+ - [Productivity & Knowledge management](#productivity-and-knowledge-management)
+ - [Capture templates & various settings](#capture-templates-and-various-settings)
+ - [Custom agendas](#custom-agendas)
+ - [Org Journal](#org-journal)
+ - [Org Roam](#org-roam)
+ - [org-roam-ui](#org-roam-ui)
+ - [org-roam-protocol](#org-roam-protocol)
+ - [org-ref](#org-ref)
+ - [org-roam-bibtex](#org-roam-bibtex)
+ - [UI](#ui)
+ - [
OFF (OFF) Instant equations preview](#off--instant-equations-preview)
+ - [LaTeX fragments](#latex-fragments)
+ - [Better headers](#better-headers)
+ - [Org Agenda Icons](#org-agenda-icons)
+ - [Export](#export)
+ - [General settings](#general-settings)
+ - [Hugo](#hugo)
+ - [Jupyter Notebook](#jupyter-notebook)
+ - [Html export](#html-export)
+ - [LaTeX](#latex)
+ - [Keybindings & stuff](#keybindings-and-stuff)
+ - [Copy a link](#copy-a-link)
+ - [Presentations](#presentations)
+ - [TOC](#toc)
+ - [System configuration](#system-configuration)
+ - [Tables for Guix Dependencies](#tables-for-guix-dependencies)
+ - [Noweb evaluations](#noweb-evaluations)
+ - [yadm hook](#yadm-hook)
+- [
OFF (OFF) EAF](#off--eaf)
+ - [Installation](#installation)
+ - [Config](#config)
+- [Programming](#programming)
+ - [General setup](#general-setup)
+ - [LSP](#lsp)
+ - [Setup](#setup)
+ - [Integrations](#integrations)
+ - [Keybindings](#keybindings)
+ - [Flycheck](#flycheck)
+ - [Tree Sitter](#tree-sitter)
+ - [
OFF (OFF) DAP](#off--dap)
+ - [
OFF (OFF) TabNine](#off--tabnine)
+ - [
OFF (OFF) Code Compass](#off--code-compass)
+ - [Dependencies](#dependencies)
+ - [Plugin](#plugin)
+ - [
CHECK (OFF) Format-all](#off--format-all)
+ - [General additional config](#general-additional-config)
+ - [Web development](#web-development)
+ - [Emmet](#emmet)
+ - [Prettier](#prettier)
+ - [TypeScript](#typescript)
+ - [JavaScript](#javascript)
+ - [Jest](#jest)
+ - [web-mode](#web-mode)
+ - [
OFF (OFF) Vue.js](#off--vue-dot-js)
+ - [mmm-mode fix](#mmm-mode-fix)
+ - [
OFF (OFF) Svelte](#off--svelte)
+ - [SCSS](#scss)
+ - [PHP](#php)
+ - [LaTeX](#latex)
+ - [AUCTeX](#auctex)
+ - [BibTeX](#bibtex)
+ - [Import \*.sty](#import-dot-sty)
+ - [Snippets](#snippets)
+ - [Greek letters](#greek-letters)
+ - [English letters](#english-letters)
+ - [Math symbols](#math-symbols)
+ - [Section snippets](#section-snippets)
+ - [Other markup languages](#other-markup-languages)
+ - [Markdown](#markdown)
+ - [PlantUML](#plantuml)
+ - [LanguageTool](#languagetool)
+ - [Lisp](#lisp)
+ - [Meta Lisp](#meta-lisp)
+ - [Emacs Lisp](#emacs-lisp)
+ - [Package Lint](#package-lint)
+ - [General](#general)
+ - [Common lisp](#common-lisp)
+ - [Clojure](#clojure)
+ - [Hy](#hy)
+ - [Scheme](#scheme)
+ - [CLIPS](#clips)
+ - [Python](#python)
+ - [pipenv](#pipenv)
+ - [yapf](#yapf)
+ - [isort](#isort)
+ - [sphinx-doc](#sphinx-doc)
+ - [pytest](#pytest)
+ - [Fix comint buffer width](#fix-comint-buffer-width)
+ - [code-cells](#code-cells)
+ - [tensorboard](#tensorboard)
+ - [Java](#java)
+ - [Go](#go)
+ - [.NET](#dot-net)
+ - [C#](#c)
+ - [MSBuild](#msbuild)
+ - [fish](#fish)
+ - [sh](#sh)
+ - [Haskell](#haskell)
+ - [JSON](#json)
+ - [YAML](#yaml)
+ - [.env](#dot-env)
+ - [CSV](#csv)
+ - [
OFF (OFF) PDF](#off--pdf)
+ - [Docker](#docker)
+- [Apps & Misc](#apps-and-misc)
+ - [Managing dotfiles](#managing-dotfiles)
+ - [Open Emacs config](#open-emacs-config)
+ - [Open Magit for yadm](#open-magit-for-yadm)
+ - [Open a dotfile](#open-a-dotfile)
+ - [Internet & Multimedia](#internet-and-multimedia)
+ - [Notmuch](#notmuch)
+ - [Elfeed](#elfeed)
+ - [Some additions](#some-additions)
+ - [YouTube](#youtube)
+ - [EMMS](#emms)
+ - [MPD](#mpd)
+ - [MPV](#mpv)
+ - [Cache cleanup](#cache-cleanup)
+ - [Fetching lyrics](#fetching-lyrics)
+ - [Some keybindings](#some-keybindings)
+ - [EMMS & mpd Fixes](#emms-and-mpd-fixes)
+ - [EWW](#eww)
+ - [ERC](#erc)
+ - [Google Translate](#google-translate)
+ - [Reading documentation](#reading-documentation)
+ - [tldr](#tldr)
+ - [man & info](#man-and-info)
+ - [devdocs.io](#devdocs-dot-io)
+ - [Utilities](#utilities)
+ - [pass](#pass)
+ - [Docker](#docker)
+ - [Progidy](#progidy)
+ - [screenshot.el](#screenshot-dot-el)
+ - [proced](#proced)
+ - [Guix](#guix)
+ - [Productivity](#productivity)
+ - [Pomidor](#pomidor)
+ - [Calendar](#calendar)
+ - [Fun](#fun)
+ - [Discord integration](#discord-integration)
+ - [Snow](#snow)
+ - [Zone](#zone)
+- [Guix settings](#guix-settings)
+
+
+
+
+
+## Primary setup {#primary-setup}
+
+
+### Measure startup speed {#measure-startup-speed}
+
+A small function to print out the loading time and number of GCs during the loading. Can be useful as a point of data for optimizing Emacs startup time.
+
+```emacs-lisp
+(add-hook 'emacs-startup-hook
+ (lambda ()
+ (message "*** Emacs loaded in %s with %d garbage collections."
+ (format "%.2f seconds"
+ (float-time
+ (time-subtract after-init-time before-init-time)))
+ gcs-done)))
+
+;; (setq use-package-verbose t)
+```
+
+
+### straight.el {#straight-dot-el}
+
+Straight.el is my Emacs package manager of choice. Its advantages & disadvantages over other options are listed pretty thoroughly in the README file in the repo.
+
+The following is a straight.el bootstrap script.
+
+References:
+
+- [straight.el repo](https://github.com/raxod502/straight.el)
+
+
+
+```emacs-lisp
+(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))
+```
+
+
+### use-package {#use-package}
+
+A macro to simplify package specification & configuration. Integrates with straight.el.
+
+Set `use-package-verbose` to `t` to print out individual package loading time.
+
+References:
+
+- [use-package repo](https://github.com/jwiegley/use-package)
+
+
+
+```emacs-lisp
+(straight-use-package 'use-package)
+(eval-when-compile (require 'use-package))
+ ;; (setq use-package-verbose t)
+```
+
+
+### Performance {#performance}
+
+
+#### Garbage collection {#garbage-collection}
+
+Just setting `gc-cons-treshold` to a larger value.
+
+```emacs-lisp
+(setq gc-cons-threshold 80000000)
+(setq read-process-output-max (* 1024 1024))
+```
+
+
+#### Run garbage collection when Emacs is unfocused {#run-garbage-collection-when-emacs-is-unfocused}
+
+Run GC when Emacs loses focus. ~~Time will tell if that's a good idea.~~
+
+Some time has passed, and I still don't know if there is any quantifiable advantage to this, but it doesn't hurt.
+
+```emacs-lisp
+(add-hook 'emacs-startup-hook
+ (lambda ()
+ (if (boundp 'after-focus-change-function)
+ (add-function :after after-focus-change-function
+ (lambda ()
+ (unless (frame-focus-state)
+ (garbage-collect))))
+ (add-hook 'after-focus-change-function 'garbage-collect))))
+```
+
+
+#### Misc {#misc}
+
+The following variable is true when my machine is not powerful enough for some resource-heavy packages.
+
+```emacs-lisp
+(setq my/lowpower (string= (system-name) "azure"))
+```
+
+The following is true if Emacs is meant to be used with TRAMP over slow ssh.
+
+```emacs-lisp
+(setq my/slow-ssh (string= (getenv "IS_TRAMP") "true"))
+```
+
+And the following is true if Emacs is run from termux on Android.
+
+```emacs-lisp
+(setq my/is-termux (string-match-p (rx (* nonl) "com.termux" (* nonl)) (getenv "HOME")))
+```
+
+
+#### Native compilation {#native-compilation}
+
+Set number of jobs to 1 on low-power machines
+
+```emacs-lisp
+(when my/lowpower
+ (setq comp-async-jobs-number 1))
+```
+
+
+### Anaconda & environment {#anaconda-and-environment}
+
+[Anaconda](https://www.anaconda.com/) is a free package and environment manager. I currently use it to manage multiple versions of Python and Node.js
+
+The following code uses the conda package to activate the base environment on startup if Emacs is launched outside the environment.
+
+Also, some strange things are happening if vterm is launched with conda activated from Emacs, so I advise `conda-env-activate` to set an auxililary environment variable.
+
+References:
+
+- [Anaconda docs](https://docs.anaconda.com/)
+- [conda.el repo](https://github.com/necaris/conda.el)
+
+
+
+```emacs-lisp
+(use-package conda
+ :straight t
+ :if (executable-find "conda")
+ :config
+ (setq conda-anaconda-home (string-replace "/bin/conda" "" (executable-find "conda")))
+ (setq conda-env-home-directory (expand-file-name "~/.conda/"))
+ (setq conda-env-subdirectory "envs")
+ (setenv "INIT_CONDA" "true")
+ (advice-add 'conda-env-activate :after
+ (lambda (&rest _) (setenv "EMACS_CONDA_ENV" conda-env-current-name)))
+ (unless (getenv "CONDA_DEFAULT_ENV")
+ (conda-env-activate "general")))
+```
+
+Also, I sometimes need to know if a program is running inside Emacs (say, inside a terminal emulator). To do that, I set the following environment variable:
+
+```emacs-lisp
+(setenv "IS_EMACS" "true")
+```
+
+
+### Custom file location {#custom-file-location}
+
+By default, custom writes stuff to `init.el`, which is somewhat annoying. The following makes a separate file `custom.el`
+
+```emacs-lisp
+(setq custom-file (concat user-emacs-directory "custom.el"))
+(load custom-file 'noerror)
+```
+
+
+### Private config {#private-config}
+
+I have some variables which I don't commit to the repo, e.g. my current location. They are stored in `private.el`
+
+```emacs-lisp
+(let ((private-file (expand-file-name "private.el" user-emacs-directory)))
+ (when (file-exists-p private-file)
+ (load-file private-file)))
+```
+
+
+### No littering {#no-littering}
+
+By default emacs and its packages create a lot files in `.emacs.d` and in other places. [no-littering](https://github.com/emacscollective/no-littering) is a collective effort to redirect all of this to two folders in `user-emacs-directory`.
+
+```emacs-lisp
+(use-package no-littering
+ :straight t)
+```
+
+
+## Global editing configuration {#global-editing-configuration}
+
+
+### General keybindings stuff {#general-keybindings-stuff}
+
+
+#### general.el {#general-dot-el}
+
+general.el provides a convenient interface to manage Emacs keybindings.
+
+References:
+
+- [general.el repo](https://github.com/noctuid/general.el)
+
+
+
+```emacs-lisp
+(use-package general
+ :straight t
+ :config
+ (general-evil-setup))
+```
+
+
+#### which-key {#which-key}
+
+A package that displays the available keybindings in a popup.
+
+Pretty useful, as Emacs seems to have more keybindings than I can remember at any given point.
+
+References:
+
+- [which-key repo](https://github.com/justbur/emacs-which-key)
+
+
+
+```emacs-lisp
+(use-package which-key
+ :config
+ (setq which-key-idle-delay (if my/lowpower 1 0.3))
+ (setq which-key-popup-type 'frame)
+ (which-key-mode)
+ (which-key-setup-side-window-bottom)
+ (set-face-attribute 'which-key-local-map-description-face nil
+ :weight 'bold)
+ :straight t)
+```
+
+
+##### dump keybindings {#dump-keybindings}
+
+A function to dump keybindings starting with a prefix to a buffer in tree-like form.
+
+```emacs-lisp
+(defun my/dump-bindings-recursive (prefix &optional level)
+ (dolist (key (which-key--get-bindings (kbd prefix)))
+ (when level
+ (insert (make-string level ? )))
+ (insert (apply #'format "%s%s%s\n" key))
+ (when (string-match-p
+ (rx bos "+" (* nonl))
+ (substring-no-properties (elt key 2)))
+ (my/dump-bindings-recursive
+ (concat prefix " " (substring-no-properties (car key)))
+ (+ 2 (or level 0))))))
+
+(defun my/dump-bindings (prefix)
+ "Dump keybindings starting with PREFIX in tree-like form."
+ (interactive "sPrefix: ")
+ (with-current-buffer (get-buffer-create "bindings")
+ (point-max)
+ (erase-buffer)
+ (save-excursion
+ (my/dump-bindings-recursive prefix)))
+ (switch-to-buffer-other-window "bindings"))
+```
+
+
+### Evil mode {#evil-mode}
+
+A whole ecosystem of packages that emulates the main features of Vim. Probably the best vim emulator out there.
+
+The only problem is that the package name makes it hard to google anything by just typing "evil".
+
+References:
+
+- [evil repo](https://github.com/emacs-evil/evil)
+- [(YouTube) Evil Mode: Or, How I Learned to Stop Worrying and Love Emacs](https://www.youtube.com/watch?v=JWD1Fpdd4Pc)
+
+
+#### evil {#evil}
+
+Basic evil configuration.
+
+```emacs-lisp
+(use-package evil
+ :straight t
+ :init
+ (setq evil-want-integration t)
+ (setq evil-want-C-u-scroll t)
+ (setq evil-want-keybinding nil)
+ :config
+ (evil-mode 1)
+ (setq evil-search-module 'evil-search)
+ (setq evil-split-window-below t)
+ (setq evil-vsplit-window-right t)
+ ;; (setq evil-respect-visual-line-mode t)
+ (evil-set-undo-system 'undo-tree)
+ ;; (add-to-list 'evil-emacs-state-modes 'dired-mode)
+ )
+```
+
+
+#### Addons {#addons}
+
+[evil-surround](https://github.com/emacs-evil/evil-surround) emulates one of my favorite vim plugins, surround.vim. Adds a lot of parentheses management options.
+
+```emacs-lisp
+(use-package evil-surround
+ :straight t
+ :after evil
+ :config
+ (global-evil-surround-mode 1))
+```
+
+[evil-commentary](https://github.com/linktohack/evil-commentary) emulates commentary.vim.
+
+```emacs-lisp
+(use-package evil-commentary
+ :straight t
+ :after evil
+ :config
+ (evil-commentary-mode))
+```
+
+[evil-quickscope](https://github.com/blorbx/evil-quickscope) emulates quickscope.vim. It highlights the important target characters for f, F, t, T keys.
+
+```emacs-lisp
+(use-package evil-quickscope
+ :straight t
+ :after evil
+ :config
+ :hook ((prog-mode . turn-on-evil-quickscope-mode)
+ (LaTeX-mode . turn-on-evil-quickscope-mode)
+ (org-mode . turn-on-evil-quickscope-mode)))
+```
+
+[evil-numbers](https://github.com/cofi/evil-numbers) allows incrementing and decrementing numbers at the point.
+
+```emacs-lisp
+(use-package evil-numbers
+ :straight t
+ :commands (evil-numbers/inc-at-pt evil-numbers/dec-at-pt)
+ :init
+ (general-nmap
+ "g+" 'evil-numbers/inc-at-pt
+ "g-" 'evil-numbers/dec-at-pt))
+```
+
+[evil-lion](https://github.com/edkolev/evil-lion) provides alignment operators, somewhat similar to vim-easyalign.
+
+```emacs-lisp
+(use-package evil-lion
+ :straight t
+ :config
+ (setq evil-lion-left-align-key (kbd "g a"))
+ (setq evil-lion-right-align-key (kbd "g A"))
+ (evil-lion-mode))
+```
+
+[evil-matchit](https://github.com/redguardtoo/evil-matchit) makes "%" to match things like tags.
+
+```emacs-lisp
+(use-package evil-matchit
+ :straight t
+ :config
+ (global-evil-matchit-mode 1))
+```
+
+
+#### evil-collection {#evil-collection}
+
+[evil-collection](https://github.com/emacs-evil/evil-collection) is a package that provides evil bindings for a lot of different packages. One can see the whole list in the [modes](https://github.com/emacs-evil/evil-collection/tree/master/modes) folder.
+
+I don't enable the entire package, just the modes I need.
+
+```emacs-lisp
+(use-package evil-collection
+ :straight t
+ :after evil
+ :config
+ (evil-collection-init
+ '(eww
+ devdocs
+ proced
+ emms
+ pass
+ calendar
+ dired
+ debug
+ guix
+ calc
+ docker
+ ibuffer
+ geiser
+ pdf
+ info
+ elfeed
+ edebug
+ bookmark
+ company
+ vterm
+ flycheck
+ profiler
+ cider
+ explain-pause-mode
+ notmuch
+ custom
+ xref
+ eshell
+ helpful
+ compile
+ comint
+ magit
+ prodigy)))
+```
+
+
+### More keybindings {#more-keybindings}
+
+The main keybindings setup is positioned after evil mode to take the latter into account.
+
+
+#### Escape key {#escape-key}
+
+Use the escape key instead of `C-g` whenever possible.
+
+I must have copied it from somewhere, but as I googled to find out the source, I discovered quite a number of variations of the following code over time. I wonder if Richard Dawkins was inspired by something like this a few decades ago.
+
+```emacs-lisp
+(defun minibuffer-keyboard-quit ()
+ "Abort recursive edit.
+In Delete Selection mode, if the mark is active, just deactivate it;
+then it takes a second \\[keyboard-quit] to abort the minibuffer."
+ (interactive)
+ (if (and delete-selection-mode transient-mark-mode mark-active)
+ (setq deactivate-mark t)
+ (when (get-buffer "*Completions*") (delete-windows-on "*Completions*"))
+ (abort-recursive-edit)))
+
+(general-define-key
+ :keymaps '(normal visual global)
+ [escape] 'keyboard-quit)
+
+(general-define-key
+ :keymaps '(minibuffer-local-map
+ minibuffer-local-ns-map
+ minibuffer-local-completion-map
+ minibuffer-local-must-match-map
+ minibuffer-local-isearch-map)
+ [escape] 'minibuffer-keyboard-quit)
+```
+
+
+#### Home & end {#home-and-end}
+
+```emacs-lisp
+(general-def :states '(normal insert visual)
+ "