Diamond's Emacs

Table of Contents

1. Base

1.1. Header

;;; config.el --- Configuration. -*- lexical-binding: t; -*-

;; Copyright (C) 2022 Diamond Bond

;; Author: Diamond Bond <diamondbond1@gmail.com>
;; Version: nil
;; Package-Requires: ((emacs "28.1"))
;; Keywords: emacs, configuration
;; URL: https://github.com/diamondbond/emacs

;; This file is not part of GNU Emacs.

;; This file is free software…

;;; Commentary:
;; This file provides the sanctioned configuration.

;;; Code:

1.2. Globals

1.2.1. Description

Define global variables.

1.2.2. Code

;; Set global configuration
(setq
 globals--banner-path  "img/gnusstorm-2.gif"                ; Banner
 globals--font         "DejaVu Sans Mono 14"                ; Font
 ;; globals--font         "Consolas 14"                       ; Font
 globals--name         "Diamond Bond"                       ; Name
 globals--email        "diamondbond1@gmail.com"             ; Email
 globals--irc          "diamondbond"                        ; IRC
 globals--erc          '("diamondbond" "diamondbond_")      ; ERC
 globals--auth-info    "~/.authinfo.gpg"                    ; Auth Info
 globals--auth-sources '("~/.authinfo.gpg")                 ; Auth Sources
 globals--browser      'browse-url-firefox                  ; Browser
 )

1.3. Personal

1.3.1. Identity

(setq user-full-name globals--name
      user-mail-address globals--email
      erc-nick globals--erc
      erc-nick-short globals--irc
      rcirc-default-user-name globals--irc
      rcirc-default-nick      globals--irc
      rcirc-default-full-name globals--name)

1.3.2. Authentication

Set authinfo file location and authinfo expiry to never. Configure gpg-email address & load oauth tokens.

;; load authinfo
(if (file-exists-p globals--auth-info)
    (setq auth-sources globals--auth-sources)
  (setq auth-source-cache-expiry nil))

;; ask for encryption password once
(setq epa-file-cache-passphrase-for-symmetric-encryption t)

;; email to encrypt to
(setq epa-file-encrypt-to '(globals--email))

1.4. Performance

1.4.1. Garbage collect when in minibuffer

While the minibuffer is open, garbage collection will never occur, but once we make a selection, or cancel, garbage collection will kick off immediately and then revert back to the default, sensible behavior.

(defun my-minibuffer-setup-hook ()
  "Garbage collection will never occur."
  (setq gc-cons-threshold most-positive-fixnum))

(defun my-minibuffer-exit-hook ()
  "Garbage collection will kick off immediately."
  (setq gc-cons-threshold gc-cons-threshold-original))

(add-hook 'minibuffer-setup-hook #'my-minibuffer-setup-hook)
(add-hook 'minibuffer-exit-hook #'my-minibuffer-exit-hook)

1.4.2. Do not steal focus while doing async compilations

(setq warning-suppress-types '((comp)))

1.4.3. Turn off ad-redef warnings

(setq ad-redefinition-action 'accept)

1.4.4. Potentially speed up cursor operations

https://emacs.stackexchange.com/questions/28736

(setq auto-window-vscroll nil)

1.5. Files

1.5.1. Custom

Offload custom-set-variables to a separate file. This keeps your init.el clean and you have the option to gitignore your custom.el if you see fit.

;; Set default custom file
(setq-default custom-file (expand-file-name "custom.el" user-emacs-directory))

;; Write to it if it does not exist
(unless (file-exists-p custom-file)
  (write-region "" nil custom-file))

;; Load custom file. Don't hide errors. Hide success message
(load custom-file nil t)

1.5.2. Bookmarks

  1. Set file location

    Set bookmarks file location to ~/org/bookmarks.

    (when (file-directory-p "~/org")
      (if (file-exists-p "~/org/bookmarks")
          (setq bookmark-default-file "~/org/bookmarks")))
    
  2. Configure autosaving

    Everytime a bookmark is changed, auto-save. Save bookmarks when Emacs quits.

    (setq bookmark-save-flag 1)
    (setq bookmark-save-flag t)
    

1.5.3. Load custom themes

Auto-load any custom themes in ~/.emacs.d/themes.

(when (file-exists-p (expand-file-name "themes/" user-emacs-directory))
  (setq custom-safe-themes t)
  (add-to-list 'custom-theme-load-path (expand-file-name "themes/" user-emacs-directory)))

1.5.4. Don't ask for confirmation when opening symlinked file

(setq vc-follow-symlinks t)

1.5.5. Disable automatic creation of backup files

(setq make-backup-files nil)
(setq auto-save-default nil)
(setq make-backup-files nil)
(setq create-lockfiles nil)
(setq vc-make-backup-files nil)

1.5.6. Delete trailing whitespace on save

(add-hook 'before-save-hook
          'delete-trailing-whitespace)

1.6. Environment

1.6.1. Use UTF-8

UTF-8 please.

(set-language-environment "UTF-8")
(set-default-coding-systems 'utf-8)
(setq locale-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)
(prefer-coding-system 'utf-8)

1.6.2. Set default dir

(setq default-directory "~/")
(setq command-line-default-directory "~/")

1.6.3. Set pager

Essential for using shells in Emacs.

(setenv "PAGER" "cat")

1.6.4. Set GPG Agent info

(setenv "GPG_AGENT_INFO" nil)

1.6.5. Disable ring-bell

Disable the bell.

(setq ring-bell-function 'ignore)

1.6.6. Configure scrolling

  1. Enable nice-scrolling (Emacs 28+)
    (setq
     ;; If the frame contains multiple windows, scroll the one under the cursor
     ;; instead of the one that currently has keyboard focus.
     mouse-wheel-follow-mouse 't
     ;; Completely disable mouse wheel acceleration to avoid speeding away.
     mouse-wheel-progressive-speed nil
     ;; The most important setting of all! Make each scroll-event move 2 lines at
     ;; a time (instead of 5 at default). Simply hold down shift to move twice as
     ;; fast, or hold down control to move 3x as fast. Perfect for trackpads.
     mouse-wheel-scroll-amount '(2 ((shift) . 4) ((control) . 6)))
    
    (setq scroll-margin 0)
    (setq scroll-conservatively 100000)
    (setq scroll-preserve-screen-position 1)
    (setq fast-but-imprecise-scrolling t)
    
  2. Enable pixel-scroll-precision-mode (Emacs 29+)
    ;; (pixel-scroll-precision-mode)
    

1.6.7. Enable external-bound copy-pasting

(setq select-enable-clipboard t)
(setq save-interprogram-paste-before-kill t)

1.6.8. Pair matching

  1. Enable paren-mode

    Show parent parentheses.

    (setq show-paren-delay 0.1
          show-paren-style 'parenthesis
          show-paren-highlight-openparen t
          show-paren-when-point-inside-paren t
          show-paren-when-point-in-periphery t)
    (show-paren-mode 1)
    

1.6.9. Indentation

Set tabs & indents to 4sp.

(setq-default tab-width 4)
(setq-default standard-indent 4)
(setq-default indent-tabs-mode t)
(setq-default electric-indent-inhibit nil)
(setq backward-delete-char-untabify-method 'nil)
(electric-indent-mode -1) ;; Disable electric indentation

1.6.10. Set C/C++ tabs & braces

(setq c-default-style "linux")
(setq c-basic-offset tab-width)

1.6.11. Enable subword-mode

(global-subword-mode 1)
(add-hook 'c-mode-common-hook
          (lambda () (subword-mode 1)))

1.6.12. One space to end sentences

(setq sentence-end-double-space nil)

1.7. Display

1.7.1. Appearance

  1. Set font
    (add-to-list 'default-frame-alist `(font . ,globals--font))
    
  2. Set time format
    (setq-default display-time-format "%I:%M %p")
    
  3. Set fill-column
    (setq-default fill-column 80)
    
  4. Set linum format
    (setq linum-format "%4d ")
    
  5. Show trailing whitespace
    (add-hook 'prog-mode-hook
              (lambda ()
                (setq show-trailing-whitespace t)))
    
  6. Set window title

    Make window title the buffer name.

    (setq-default frame-title-format '("%b"))
    
  7. Uniquify buffer name
    (setq-default uniquify-buffer-name-style 'forward)
    
  8. Set internal border width
    (add-to-list 'default-frame-alist '(internal-border-width . 0))
    
  9. Fill space provided by WM

    Emacs will fill up the space reported by the window manager.

    (setq window-resize-pixelwise t)
    (setq frame-resize-pixelwise t)
    
  10. Disable default startup screen
    (setq inhibit-startup-message t)
    (setq initial-scratch-message "")
    
  11. Disable cursor blink
    (blink-cursor-mode -1)
    
  12. Disable gui elements

    Disable tool-bar.

    (if (fboundp 'menu-bar-mode)
        (menu-bar-mode 1))
    (if (fboundp 'tool-bar-mode)
        (tool-bar-mode -1))
    (if (fboundp 'scroll-bar-mode)
        (scroll-bar-mode 1))
    ;; (set-scroll-bar-mode 'right)
    
  13. Global mode line

    https://amodernist.com/texts/emacs-global.html

    ;; (setq tab-bar-format '(tab-bar-format-global)
    ;;    tab-bar-mode t)
    
  14. Configure fringe
    (fringe-mode nil) ;; default fringes
    (setq-default fringes-outside-margins nil)
    (setq-default indicate-buffer-boundaries nil)
    (setq-default indicate-empty-lines nil)
    (setq-default overflow-newline-into-fringe t)
    
  15. Configure default-frame-alist

    Enable right scroll-bar & set frame size.

    (add-to-list 'default-frame-alist '(width . 80))
    (add-to-list 'default-frame-alist '(height . 46))
    

1.7.2. Modes

  1. Enable column-numbers-mode

    Show column number in modeline.

    (column-number-mode 1)
    
  2. Enable global-highlight-line-mode
    (global-hl-line-mode t)
    
  3. Enable prettify-symbols-mode
    (global-prettify-symbols-mode t)
    
  4. Enable line-numbers-mode

    Emacs breaks certain modes when it has line-numbers-mode enabled, (like docview or ansi-term) so we utilize the approach of only enabling it on some major modes rather than globally.

    (add-hook 'prog-mode-hook 'display-line-numbers-mode)
    (add-hook 'text-mode-hook 'display-line-numbers-mode)
    
  5. Enable visual-line-mode

    Enable visual-line-mode in text buffers & org + md4rd.

    (add-hook 'text-mode-hook 'visual-line-mode)
    (add-hook 'org-mode-hook 'visual-line-mode)
    (add-hook 'md4rd-mode-hook 'visual-line-mode)
    

1.8. Aliases

1.8.1. Basic

Some basic aliases & transform yes-or-no into y-or-n.

(defalias 'first 'car)
(defalias 'second 'cadr)
(defalias 'third 'caddr)
(defalias 'when-not 'unless)
(defalias 'word-count 'count-words)
(defalias 'yes-or-no-p 'y-or-n-p)

1.8.2. Fit-frame

Shrinks frame to buffer contents.

(defalias 'shrink-wrap 'fit-frame-to-buffer)

1.8.3. Recentf delete

Remove items from recents list.

(defalias 'recentf-delete 'recentf-edit-list)

1.8.4. Bookmark delete

Dont accidentally delete all my bookmarks.

(defalias 'bookmark-delete-all 'bookmark-delete)

1.8.5. sync/news

Sync Elfeed feeds/atom.

(defalias 'sync/news 'elfeed-update)

1.9. Built-in

1.9.1. Configure browser

Set default browser for Unix-like environments.

(if (eq system-type 'gnu/linux)
    (setq browse-url-browser-function globals--browser))
(if (eq system-type 'darwin)
    (setq browse-url-browser-function globals--browser))

1.9.2. Configure proced

Auto-update proced every 5 seconds.

(setq proced-auto-update-flag t)
(setq proced-auto-update-interval 5)
(setq proced-descend t)
(setq proced-filter 'user)

1.9.3. Configure eshell

  1. Description

    Improve eshell prompt and assign aliases, also setup some custom helper functions for easier use.

  2. Prompt
    ;; set prompt
    (setq eshell-prompt-function
          (lambda nil
            (concat
             (if (string= (eshell/pwd) (getenv "HOME"))
                 (propertize "~" 'face `(:foreground "#2255bb"))
               (replace-regexp-in-string
                (getenv "HOME")
                (propertize "~" 'face `(:foreground "#2255bb"))
                (propertize (eshell/pwd) 'face `(:foreground "#2255bf"))))
             (if (= (user-uid) 0)
                 (propertize " α " 'face `(:foreground "#aa0000"))
               (propertize " λ " 'face `(:foreground "#68228b"))))))
    (setq eshell-prompt-regexp "^[^αλ\n]*[αλ] ")
    
    ;; do not highlight prompt
    (setq eshell-highlight-prompt nil)
    
    ;; disable global highlight
    (add-hook 'eshell-mode-hook
              (lambda () (global-hl-line-mode 0)))
    
  3. Clear
    (defun eshell/clear-scrollback ()
      "Clear the scrollback content of the eshell window."
      (let ((inhibit-read-only t))
        (erase-buffer)))
    
  4. Aliases
    (defalias 'open 'find-file-other-window)
    (defalias 'clean 'eshell/clear-scrollback)
    
  5. Open eshell in other window
    (defun eshell-other-window ()
      "Create or visit an eshell buffer."
      (interactive)
      (if (not (get-buffer "*eshell*"))
          (progn
            (split-window-sensibly (selected-window))
            (other-window 1)
            (eshell))
        (switch-to-buffer-other-window "*eshell*")))
    

2. Keybinds

2.1. z-map

;;---------------------------------------------------------------------
;; z-map definition
;;---------------------------------------------------------------------

(define-prefix-command 'z-map)
(global-set-key (kbd "C-1") 'z-map)

2.2. private-map

;;---------------------------------------------------------------------
;; private-map
;;---------------------------------------------------------------------

;; general
(define-key z-map (kbd "a") 'org-agenda)
(define-key z-map (kbd "f") 'find-file-other-frame)
(define-key z-map (kbd "g") 'golden-ratio)
(define-key z-map (kbd "h") 'global-hl-line-mode)
(define-key z-map (kbd "2") 'make-frame-command)
(define-key z-map (kbd "o") 'olivetti-mode)
(define-key z-map (kbd "m") 'magit-status)
(define-key z-map (kbd "w") 'eww)

;; os-specific
(if (eq system-type 'gnu/linux)
    (define-key z-map (kbd "v") 'vterm))
(if (eq system-type 'windows-nt)
    (define-key z-map (kbd "v") 'eshell))

;; modeline
(define-key z-map (kbd "B") 'display-battery-mode)
(define-key z-map (kbd "T") 'display-time-mode)

;; functions
(define-key z-map (kbd "*") 'quick-calc)
(define-key z-map (kbd "D") 'dashboard-refresh-buffer)
(define-key z-map (kbd "O") 'org-redisplay-inline-images)
(define-key z-map (kbd "G") 'org-mark-ring-goto)
(define-key z-map (kbd "s") 'ispell-word)
(define-key z-map (kbd "W") 'elfeed)
(define-key z-map (kbd "F") 'follow-mode)
(define-key z-map (kbd "U") 'undo-redo)
(define-key z-map (kbd "i") 'consult-imenu)

;; quick
(define-key z-map (kbd "x") 'switch-to-buffer-other-frame)
(define-key z-map (kbd "k") 'compile)
(define-key z-map (kbd "e") 'eval-region)
(define-key z-map (kbd "b") 'browse-url)

;; auxiliary
(define-key z-map (kbd "S") 'speedbar-frame-mode)
(define-key z-map (kbd "y") 'yas-minor-mode)
(define-key z-map (kbd "9") 'switch-to-qemu-and-run)
(define-key z-map (kbd "0") 'switch-to-qemu-and-paste)
(define-key z-map (kbd "C-1") 'display-buffer-other-frame)
(define-key z-map (kbd "C-c") 'calendar)
(define-key z-map (kbd "C-d") 'dired-other-frame)

;; calendar
(define-key z-map (kbd ".") 'org-date-from-calendar)

;; files
(define-key z-map (kbd "n") 'notes-edit)
(define-key z-map (kbd "c") 'config-edit)
(define-key z-map (kbd "I") 'inbox-edit)
(define-key z-map (kbd "t") 'tasks-edit)

2.3. global-map

;;---------------------------------------------------------------------
;; global-map
;;---------------------------------------------------------------------

;; function
(global-set-key (kbd "<f5>") 'revert-buffer)
(global-set-key (kbd "<f6>") 'menu-bar-mode)
(global-set-key (kbd "<f7>") 'scroll-bar-mode)
(global-set-key (kbd "<f8>") 'other-frame)
(global-set-key (kbd "<f10>") 'compile)
(global-set-key (kbd "S-<f8>") 'tool-bar-mode)
(global-set-key (kbd "S-<f9>") 'tab-bar-mode)
(global-set-key (kbd "C-S-<f9>") 'tab-line-mode)
(global-set-key (kbd "S-<f12>") 'linum-mode)

;; windows
(global-set-key (kbd "C-x w") 'elfeed)
(global-set-key (kbd "s-C-<left>") 'shrink-window-horizontally)
(global-set-key (kbd "s-C-<right>") 'enlarge-window-horizontally)
(global-set-key (kbd "s-C-<down>") 'shrink-window)
(global-set-key (kbd "s-C-<up>") 'enlarge-window)
(global-set-key (kbd "C-x x") 'window-swap-states)
(global-set-key (kbd "<s-C-return>") 'eshell-other-window)
(global-set-key (kbd "C-x C-b") #'ibuffer-list-buffers)

;; next/prev
;; (global-set-key (kbd "C-<tab>") 'next-buffer)
;; (global-set-key (kbd "C-<iso-lefttab>") 'previous-buffer)
(global-set-key (kbd "C-<tab>") 'tab-next)
(define-key global-map (kbd "C-S-n") #'next-15-lines)
(define-key global-map (kbd "C-S-p") #'previous-15-lines)

;; c-mode
;; (define-key c-mode-base-map (kbd "RET") 'newline-and-indent)
;; (global-set-key "\C-m" 'newline-and-indent)

2.4. sane-map

;;---------------------------------------------------------------------
;; sane-map
;;---------------------------------------------------------------------

;; Indent/De-indent selection by one tab length
(global-set-key (kbd "C->") 'indent-rigidly-right-to-tab-stop)
(global-set-key (kbd "C-<") 'indent-rigidly-left-to-tab-stop)

;; Kill word without copying it to your clipboard
(global-set-key (kbd "M-DEL") 'sanemacs/backward-kill-word)
(global-set-key (kbd "C-DEL") 'sanemacs/backward-kill-word)

3. Packages

3.1. Core

3.1.1. Initialize misc

  1. Description

    Elisp enhancers.

  2. Code
    (use-package fn        :demand t) ; function
    (use-package s         :demand t) ; string
    (use-package f         :demand t) ; file
    (use-package ht        :demand t) ; hash table
    (use-package dash      :demand t) ; lists
    (use-package a         :demand t) ; assoc lists
    (use-package ts        :demand t) ; timestamps
    (use-package pcre2el   :demand t) ; sane regex
    (use-package hierarchy :demand t) ; hierarchy
    

3.1.2. Initialize async

  1. Description

    Utilize asynchronous processes whenever possible.

  2. Code
    (use-package async
      :straight t
      :demand t
      :init
      (dired-async-mode 1)
      :config
      (async-bytecomp-package-mode 1)
      (add-to-list 'display-buffer-alist '("*Async Shell Command*" display-buffer-no-window (nil))))
    

3.1.3. Initialize gcmh

  1. Description

    Garbage Collector Magic Hack - enforce a sneaky Garbage Collection strategy to minimize GC interference with user activity.

  2. Code
    (use-package gcmh
      :straight t
      :init
      (setq gcmh-idle-delay 15
            gcmh-high-cons-threshold (* 16 1024 1024))  ; 16mb
      :config (gcmh-mode))
    

3.1.4. Initialize org

  1. Description

    Sensible and well-defined org-mode configuration with org-capture support & notifications.

  2. Code
    (use-package org
      :straight (:type built-in)
      :config
      ;; sensible defaults
      (setq initial-major-mode 'org-mode
            org-display-inline-images t
            org-redisplay-inline-images t
            org-image-actual-width nil
            org-startup-with-inline-images "inlineimages"
            org-catch-invisible-edits 'smart
            org-pretty-entities t)
    
      ;; indentation
      (setq org-src-preserve-indentation nil
            org-adapt-indentation nil)
    
      ;; set org directory & agenda files
      (when (file-directory-p "~/org")
        (setq org-directory "~/org"
              org-agenda-files (list "~/org/inbox.org"
                                     "~/org/tasks.org"
                                     "~/org/notes.org"
                                     "~/org/daily.org")
              org-default-notes-file "~/org/inbox.org"
              org-id-locations-file "~/org/.orgids"))
    
      ;; set org todo keywords
      (setq org-todo-keywords
            '((sequence "TODO"
                        "WIP"
                        "WAITING"
                        "|"
                        "DONE"
                        "DEFERRED"
                        "CANCELLED")))
    
      ;; persist org-clock
      (setq org-clock-persist 'history)
      ;; (org-clock-persistence-insinuate)
    
      ;; set org-refile targets
      (when (file-directory-p "~/org")
        (setq org-refile-targets
              '(("~/org/archive.org" :maxlevel . 1)
                ("~/org/tasks.org" :maxlevel . 1))))
    
      ;; save org buffers after refiling!
      (advice-add 'org-refile :after 'org-save-all-org-buffers)
    
      ;; org-src languages
      (setq org-babel-load-languages
            '((awk         . t)
              (calc        . t)
              (css         . t)
              (emacs-lisp  . t)
              (gnuplot     . t)
              (haskell     . t)
              (js          . t)
              (lisp        . t)
              (org         . t)
              (python      . t)
              (ditaa       . t)
              (jupyter     . t)
              (scheme      . t)
              (shell       . t)
              (sh          . t)
              (C           . t)
              (sql         . t)))
    
      (if (eq system-type 'gnu/linux)
          (org-babel-do-load-languages 'org-babel-load-languages))
    
      ;; org templates
      (setq org-capture-templates
            '(("w" "Default" entry (file+headline "~/org/inbox.org" "Notes")
               "* %^{Title}\n\n  Source: %u, %c\n\n  %i" :empty-lines 1)
              ("i" "Inbox" entry (file+headline "~/org/inbox.org" "Inbox")
               "* %?\n%a\nEntered on %U" :empty-lines 1)
              ("t" "Tasks" entry (file+olp+datetree "~/org/inbox.org" "Tasks")
               "* %?\n%a\nEntered on %U" :empty-lines 1)))
    
      :bind
      ("C-c c" . 'org-capture)
      ("C-c a" . 'org-agenda)
      ("C-c l" . 'org-store-link)
      ("C-<f1>" . (lambda()(interactive)(show-all))))
    
    (use-package org-contrib
      :straight t)
    
    ;; enable dnd images into org-mode & dired buffers
    (when (file-directory-p "~/org/img")
      (use-package org-download
        :straight t
        :after org
        :config
        (setq-default org-download-image-dir "~/org/img/download")
        (add-hook 'dired-mode-hook 'org-download-enable)))
    

3.1.5. Initialize dired

  1. Description

    Add icons and subtree's to dired.

  2. Code
    (use-package dired
      :straight (:type built-in)
      :commands (dired dired-jump)
      :bind ("C-x C-j" . dired-jump)
      :custom ((dired-listing-switches "-agho --group-directories-first"))
      :config
      (put 'dired-find-alternate-file 'disabled nil))
    
    (use-package all-the-icons-dired
      :straight t
      :diminish all-the-icons-dired-mode
      :config
      :hook (dired-mode . (lambda ()
                            (interactive)
                            (unless (file-remote-p default-directory)
                              (all-the-icons-dired-mode)))))
    
    (use-package dired-open
      :commands (dired dired-jump)
      :config
      (setq dired-open-extensions '(("png" . "nomacs")
                                    ("jpg" . "nomacs")
                                    ("gif" . "nomacs")
                                    ("mp4" . "mpv")
                                    ("pdf" . "zathura")
                                    ("mkv" . "mpv")
                                    ("webm" . "mpv"))))
    
    (use-package dired-hide-dotfiles
      :straight t
      :diminish dired-hide-dotfiles-mode
      :hook (dired-mode . dired-hide-dotfiles-mode))
    

3.1.6. Initialize evil

  1. Description

    Heresy; Vim keybindings in Emacs.

  2. Code
    (use-package evil
      :straight t
      :defer nil
      :init
      (setq evil-want-keybinding nil)
      (setq evil-want-C-u-scroll t)
      :config
      ;; enable evil-mode
      (evil-mode 1)
    
      ;; more granular undo with evil
      (setq evil-want-fine-undo t)
    
      ;; set evil state on a per mode basis
      ;; insert
      (evil-set-initial-state 'vterm-mode 'insert)
      ;; normal
      (evil-set-initial-state 'messages-buffer-mode 'normal)
      ;; (evil-set-initial-state 'mu4e-main-mode 'emacs)
      ;; motion
      (evil-set-initial-state 'dashboard-mode 'motion)
      (evil-set-initial-state 'debugger-mode 'motion)
      (evil-set-initial-state 'pdf-view-mode 'motion)
      ;; emacs
      (evil-set-initial-state 'nov-mode 'emacs)
      (evil-set-initial-state 'term-mode 'emacs)
      (evil-set-initial-state 'eshell-mode 'emacs)
      ;; (evil-set-initial-state 'bufler-list-mode 'emacs)
      (evil-set-initial-state 'profiler-report-mode 'emacs)
      (evil-set-initial-state 'inferior-scheme-mode 'emacs)
      ;; (evil-set-initial-state 'md4rd-mode 'emacs)
      (evil-set-initial-state 'pdf-view-mode 'emacs)
      (evil-set-initial-state 'dictionary-mode ' emacs)
      ;; e2wm
      ;; (evil-set-initial-state 'e2wm:def-plugin-history-list-mode 'emacs)
      ;; (evil-set-initial-state 'e2wm:def-plugin-files-mode 'emacs)
      ;; (evil-set-initial-state 'e2wm:def-plugin-imenu-mode 'emacs)
    
      ;; undo (requires undo-fu)
      ;; (define-key evil-normal-state-map "u" 'undo-fu-only-undo)
      ;; (define-key evil-normal-state-map "U" 'undo-fu-only-redo)
    
      ;; <tab> cycles org-mode visiblity
      (evil-define-key 'normal org-mode-map (kbd "<tab>") #'org-cycle)
    
      ;; :q kills buffer
      (evil-ex-define-cmd "q" 'delete-window))
    
    (use-package evil-collection
      :after evil
      :config
      (setq evil-collection-mode-list '(dired (custom cus-edit) (package-menu package) calc diff-mode))
      (evil-collection-init)
      ;; A few of my own overrides/customizations
      (evil-collection-define-key 'normal 'dired-mode-map
        (kbd "RET") 'dired-find-alternate-file))
    

3.1.7. Initialize smartparens

  1. Description

    Smart parentheses.

  2. Code
    (use-package smartparens
      :diminish smartparens-mode
      :defer 1
      :config
      ;; Load default smartparens rules for various languages
      (require 'smartparens-config)
      (setq sp-max-prefix-length 25)
      (setq sp-max-pair-length 4)
      (setq sp-highlight-pair-overlay nil
            sp-highlight-wrap-overlay nil
            sp-highlight-wrap-tag-overlay nil)
    
      (with-eval-after-load 'evil
        (setq sp-show-pair-from-inside t)
        (setq sp-cancel-autoskip-on-backward-movement nil)
        (setq sp-pair-overlay-keymap (make-sparse-keymap)))
    
      (let ((unless-list '(sp-point-before-word-p
                           sp-point-after-word-p
                           sp-point-before-same-p)))
        (sp-pair "'"  nil :unless unless-list)
        (sp-pair "\"" nil :unless unless-list))
    
      ;; In lisps ( should open a new form if before another parenthesis
      (sp-local-pair sp-lisp-modes "(" ")" :unless '(:rem sp-point-before-same-p))
    
      ;; Don't do square-bracket space-expansion where it doesn't make sense to
      (sp-local-pair '(emacs-lisp-mode org-mode markdown-mode gfm-mode)
                     "[" nil :post-handlers '(:rem ("| " "SPC")))
    
    
      (dolist (brace '("(" "{" "["))
        (sp-pair brace nil
                 :post-handlers '(("||\n[i]" "RET") ("| " "SPC"))
                 ;; Don't autopair opening braces if before a word character or
                 ;; other opening brace. The rationale: it interferes with manual
                 ;; balancing of braces, and is odd form to have s-exps with no
                 ;; whitespace in between, e.g. ()()(). Insert whitespace if
                 ;; genuinely want to start a new form in the middle of a word.
                 :unless '(sp-point-before-word-p sp-point-before-same-p)))
      (smartparens-global-mode t))
    

3.2. Visual

3.2.1. Initialize ef-themes

  1. Description

    Colourful and legible themes for GNU Emacs.

  2. Code
    (use-package ef-themes
      :straight (ef-themes :type git :host github :repo "protesilaos/ef-themes"))
    

3.2.2. Initialize modus-themes

  1. Description

    Accessible themes for Emacs, conforming with the highest standard for colour contrast between background and foreground values (WCAG AAA).

  2. Code
    (use-package modus-themes
      :straight (:type git :host gitlab :repo "protesilaos/modus-themes" :branch "main")
      :init
      ;; load the theme files before enabling a theme
      (modus-themes-load-themes)
      ;; :custom
      ;; (modus-themes-italic-constructs t)
      ;; (modus-themes-bold-constructs t)
      ;; (modus-themes-region '(accented bg-only no-extend))
      :config
      (modus-themes-load-operandi) ;; OR (modus-themes-load-vivendi)
      :bind ("S-<f5>" . modus-themes-toggle))
    

3.2.3. Initialize dashboard

  1. Description

    An extensible emacs startup screen.

  2. Code
    (use-package dashboard
      :straight t
      :diminish dashboard-mode
      :defer nil
      :init
      (add-hook 'dashboard-mode-hook (lambda () (setq show-trailing-whitespace nil)))
      :preface
      (defun init-edit ()
        "Edit initialization file."
        (interactive)
        (if (file-exists-p (concat user-emacs-directory "init.el"))
            (find-file (concat user-emacs-directory "init.el"))))
      (defun config-edit ()
        "Edit configuration file."
        (interactive)
        (if (file-exists-p (concat user-emacs-directory "config.org"))
            (find-file (concat user-emacs-directory "config.org"))))
      (when (file-directory-p "~/org")
        (defun notes-edit ()
          "Edit notes file."
          (interactive)
          (if (file-exists-p "~/org/notes.org")
              (find-file "~/org/notes.org")))
        (defun tasks-edit ()
          "Edit tasks file."
          (interactive)
          (if (file-exists-p "~/org/tasks.org")
              (find-file "~/org/tasks.org")))
        (defun archive-edit ()
          "Edit archive file."
          (interactive)
          (if (file-exists-p "~/org/archive.org")
              (find-file "~/org/archive.org")))
        (defun inbox-edit ()
          "Edit inbox file."
          (interactive)
          (if (file-exists-p "~/org/inbox.org")
              (find-file "~/org/inbox.org"))))
      (defun create-scratch-buffer ()
        "Create a scratch buffer."
        (interactive)
        (switch-to-buffer (get-buffer-create "*scratch*")))
      :config
      (setq initial-buffer-choice (lambda () (get-buffer "*dashboard*")))
      (setq dashboard-items '((recents . 5)))
      (setq dashboard-banner-logo-title "")
      (setq dashboard-startup-banner 'official)
      ;; (setq dashboard-startup-banner (expand-file-name globals--banner-path user-emacs-directory))
      (setq dashboard-center-content t)
      (setq dashboard-show-shortcuts nil)
      (setq dashboard-set-init-info t)
      (setq dashboard-set-footer nil)
      (setq dashboard-set-navigator t)
      (setq dashboard-set-navigator t)
    
      ;; set dashboard navigator buttons
      (when (file-directory-p "~/org")
        (setq dashboard-navigator-buttons
              `(;; line 1
                ((,nil
                  "Notes"
                  "Open Notes"
                  (lambda (&rest _) (notes-edit))
                  'default)
                 (nil
                  "Tasks"
                  "Open Tasks"
                  (lambda (&rest _) (tasks-edit))
                  'default)
                 (nil
                  "Agenda"
                  "Open Org-Agenda"
                  (lambda (&rest _) (org-agenda))
                  'default)
                 (nil
                  "Inbox"
                  "Open Inbox"
                  (lambda (&rest _) (inbox-edit))
                  'default)))))
    
      ;; setup dashboard
      (dashboard-setup-startup-hook))
    

3.2.4. Initialize diminish

  1. Description

    Diminish hides minor modes to prevent cluttering your mode line.

  2. Code
    (use-package diminish
      :straight t
      :init
      ;; diminish as mode is already loaded
      (diminish 'auto-revert-mode "")
      (diminish 'abbrev-mode "")
      (diminish 'subword-mode)
      (diminish 'visual-line-mode)
      (diminish 'outline-mode)
      (diminish 'gcmh-mode)
      :config
      ;; diminish after mode is loaded
      (eval-after-load "eldoc" '(diminish 'eldoc-mode))
      (eval-after-load "c-mode" '(diminish 'c-mode))
      (eval-after-load "c++-mode" '(diminish 'c++-mode))
      (eval-after-load "which-key" '(diminish 'which-key-mode))
      (eval-after-load "org" '(diminish 'org-indent-mode))
      (eval-after-load "ox-beamer" '(diminish 'org-beamer-mode))
      (eval-after-load "outline" '(diminish 'outline-minor-mode))
      (eval-after-load "dired" '(diminish 'dired-async-mode))
      (eval-after-load "dired" '(diminish 'dired-hide-dotfiles-mode))
      (eval-after-load "dired" '(diminish 'all-the-icons-dired-mode))
      (eval-after-load "magit" '(diminish 'auto-fill-mode ""))
      (eval-after-load "magit" '(diminish 'with-editor-mode ""))
      (eval-after-load "slime" '(diminish 'slime-autodoc-mode ""))
      (eval-after-load "evil" '(diminish 'evil-collection-unimpaired-mode ""))
      (eval-after-load "auto-revert-mode" '(diminish 'auto-revert-mode "")))
    

3.2.5. Initialize golden-ratio

  1. Description

    (1 + √5) / 2 = 1.618.

  2. Code
    (use-package golden-ratio
      :straight t)
    

3.2.6. Initialize rainbow-mode

  1. Description

    Colorize color names in buffers.

  2. Code
    (use-package rainbow-mode
      :straight t
      :diminish rainbow-mode
      :hook (prog-mode . rainbow-mode))
    

3.2.7. Initialize rainbow-delimiters

  1. Description

    Rainbow-delimiters is a "rainbow parentheses"-like mode which highlights delimiters such as parentheses, brackets or braces according to their depth.

  2. Code
    (use-package rainbow-delimiters
      :straight t
      :hook (prog-mode . rainbow-delimiters-mode))
    

3.2.8. Initialize info-variable-pitch

  1. Description

    Variable pitch text in info mode.

  2. Code
    (straight-use-package
     '(info-variable-pitch
       :type git :host github
       :repo "kisaragi-hiu/info-variable-pitch"))
    
    (add-hook 'Info-mode-hook #'info-variable-pitch-mode)
    

3.3. Tools

3.3.1. Initialize so-long

  1. Description

    So long to long lines.

  2. Code
    (use-package so-long
      :defer t
      :straight t
      :bind
      (:map so-long-mode-map
            ("C-s" . isearch-forward)
            ("C-r" . isearch-backward))
      :config (global-so-long-mode 1))
    

3.3.2. Initialize yasnippet

  1. Description

    Yasnippet provides useful snippets.

  2. Code
    (use-package yasnippet
      :straight t
      :diminish yas-minor-mode
      :hook
      ((cc-mode c-lang-common cmake-mode c++-mode c-mode conf-unix-mode
                csharp-mode css-mode emacs-lisp-mode fundamental-mode git-commit-mode
                go-mode js-mode js2-mode html-mode makefile-mode makefile-automake-mode
                markdown-mode org-mode prog-mode python-mode rjsx-mode rust-mode text-mode
                typescript-mode web-mode) . yas-minor-mode)
      :config
      (yas-reload-all))
    
    (use-package yasnippet-snippets
      :after yasnippet
      :straight t)
    
    (use-package consult-yasnippet
      :straight t
      :after (consult yasnippet)
      :bind ("C-c y" . consult-yasnippet))
    

3.3.3. Initialize xah-math-input

  1. Description

    An emacs minor mode for inputing math symbols and Unicode symbols.

  2. Code
    (use-package xah-math-input
      :straight
      ( :repo "diamondbond/xah-math-input"
        :host github
        :type git
        :files ("xah-math-input.el")))
    

3.3.4. Initialize smart-jump

  1. Description

    Smartly go to definition leveraging several methods to do so.

  2. Code
    (use-package smart-jump
      :straight t
      :bind (("M-." . smart-jump-go)
             ("M-," . smart-jump-back)
             ("M-?" . smart-jump-references)))
    

3.3.5. Initialize midnight

  1. Description

    Clean buffer list at midnight.

  2. Code
    (use-package midnight
      :init
      (midnight-mode)
      :config
      (setq clean-buffer-list-delay-general 1))
    

3.3.6. Initialize flymake

  1. Description

    Modern on-the-fly syntax checking extension.

  2. Code
    (use-package flymake
      :straight t
      :config
      ;; Message navigation bindings
      (with-eval-after-load 'flymake
        (define-key flymake-mode-map (kbd "C-c n") #'flymake-goto-next-error)
        (define-key flymake-mode-map (kbd "C-c p") #'flymake-goto-prev-error))
      :hook (prog-mode . flymake-mode))
    

3.3.7. Initialize flyspell

  1. Description

    Spell checking. Enable on the fly with M-x flyspell-mode.

  2. Code
    (use-package flyspell
      :straight t
      :config
      (add-to-list 'ispell-skip-region-alist '("~" "~"))
      (add-to-list 'ispell-skip-region-alist '("=" "="))
      (add-to-list 'ispell-skip-region-alist '("^#\\+BEGIN_SRC" . "^#\\+END_SRC"))
      (add-to-list 'ispell-skip-region-alist '("^#\\+BEGIN_EXPORT" . "^#\\+END_EXPORT"))
      (add-to-list 'ispell-skip-region-alist '("^#\\+BEGIN_EXPORT" . "^#\\+END_EXPORT"))
      (add-to-list 'ispell-skip-region-alist '(":\\(PROPERTIES\\|LOGBOOK\\):" . ":END:"))
      ;; (dolist (mode '(;; org-mode-hook ;; slows down org-mode
      ;;                  mu4e-compose-mode-hook))
      ;;    (add-hook mode (lambda () (flyspell-mode 1))))
      (if (eq system-type 'gnu/linux)
          (setq ispell-program-name "hunspell"))
      (if (eq system-type 'windows-nt)
          (setq ispell-program-name "aspell"))
      :bind (("M-<f7>" . flyspell-buffer)))
    

3.3.8. Initialize treemacs

  1. Description

    Tree layout file explorer.

  2. Code
    (use-package treemacs
      :disabled t
      :init
      (with-eval-after-load 'winum
        (define-key winum-keymap (kbd "M-0") #'treemacs-select-window))
      :config
      (progn
        (setq treemacs-collapse-dirs                 (if (executable-find "python3") 3 0)
              treemacs-deferred-git-apply-delay      0.5
              treemacs-display-in-side-window        t
              treemacs-eldoc-display                 t
              treemacs-file-event-delay              5000
              treemacs-file-follow-delay             0.2
              treemacs-follow-after-init             t
              treemacs-git-command-pipe              ""
              treemacs-goto-tag-strategy             'refetch-index
              treemacs-indentation                   2
              treemacs-indentation-string            " "
              treemacs-is-never-other-window         nil
              treemacs-max-git-entries               5000
              treemacs-missing-project-action        'ask
              treemacs-no-png-images                 nil
              treemacs-no-delete-other-windows       t
              treemacs-project-follow-cleanup        nil
              treemacs-persist-file                  (expand-file-name ".cache/treemacs-persist" user-emacs-directory)
              treemacs-recenter-distance             0.1
              treemacs-recenter-after-file-follow    nil
              treemacs-recenter-after-tag-follow     nil
              treemacs-recenter-after-project-jump   'always
              treemacs-recenter-after-project-expand 'on-distance
              treemacs-show-cursor                   nil
              treemacs-show-hidden-files             t
              treemacs-silent-filewatch              nil
              treemacs-silent-refresh                nil
              treemacs-sorting                       'alphabetic-desc
              treemacs-space-between-root-nodes      t
              treemacs-tag-follow-cleanup            t
              treemacs-tag-follow-delay              1.5
              treemacs-width                         30)
        (treemacs-resize-icons 11)
    
        (treemacs-follow-mode t)
        (treemacs-filewatch-mode t)
        (treemacs-fringe-indicator-mode t)
        (pcase (cons (not (null (executable-find "git")))
                     (not (null (executable-find "python3"))))
          (`(t . t)
           (treemacs-git-mode 'deferred))
          (`(t . _)
           (treemacs-git-mode 'simple))))
      :bind
      (:map global-map
            ("M-0"       . treemacs-select-window)
            ("C-x t 1"   . treemacs-delete-other-windows)
            ("C-x t t"   . treemacs)
            ("C-x t B"   . treemacs-bookmark)
            ("C-x t C-t" . treemacs-find-file)
            ("C-x t M-t" . treemacs-find-tag)))
    
    (use-package treemacs-evil
      :after treemacs evil
      :disabled t)
    
    (use-package treemacs-icons-dired
      :after treemacs dired
      :disabled t
      :config (treemacs-icons-dired-mode))
    

3.3.9. Initialize htmlize

  1. Description

    Used for exporting source code with syntax highlighting.

  2. Code
    (use-package htmlize
      :straight t)
    

3.3.10. Initialize vterm

  1. Description

    Emacs-libvterm (vterm) is fully-fledged terminal emulator inside GNU Emacs based on libvterm, a C library. As a result of using compiled code (instead of elisp), emacs-libvterm is fully capable, fast, and it can seamlessly handle large outputs.

  2. Code
    (if (eq system-type 'gnu/linux)
        (use-package vterm
          :straight t
          :custom (vterm-install t)
          :config
          (add-hook 'vterm-mode-hook
                    (lambda () (global-hl-line-mode 0)))
          (setq vterm-max-scrollback 10000)))
    
    (if (eq system-type 'gnu/linux)
        (use-package multi-vterm
          :straight t
          :after vterm
          :config
          (add-hook 'vterm-mode-hook
                    (lambda ()
                      ;;(setq-local evil-insert-state-cursor 'box)
                      (evil-insert-state)))))
    

3.3.11. Initialize crux

  1. Description

    A Collection of Ridiculously Useful eXtensions.

  2. Code
    (use-package crux
      :straight t)
    

3.3.12. Initialize 0x0

  1. Description

    Instant upload to 0x0.st

  2. Code
    (use-package 0x0
      :straight t
      :commands (0x0-dwim 0x0-popup 0x0-upload-file 0x0-upload-text))
    

3.3.13. Initialize clm

  1. Description

    Show event history and command history of some or all buffers.

  2. Description

    Log commands in a seperate buffer.

  3. Code
    (use-package command-log-mode
      :straight t
      :diminish command-log-mode)
    

3.3.14. Initialize hydra

  1. Description

    Hydra is a simple menu creator for keybindings.

  2. Code
    (use-package hydra
      :ensure t)
    
    (defhydra hydra-zoom ()
      "
      ^Zoom^                 ^Other
      ^^^^^^^--------------------------
      [_t_/_s_] zoom in/out  [_q_] quit
      [_0_]^^   reset zoom
      "
      ("t" text-scale-increase "zoom in")
      ("s" text-scale-decrease "zoom out")
      ("0" text-scale-adjust "reset")
      ("q" nil "finished" :exit t))
    
    (defhydra windows-adjust-size ()
      "
    ^Zoom^                                ^Other
    ^^^^^^^-----------------------------------------
    [_t_/_s_] shrink/enlarge vertically   [_q_] quit
    [_c_/_r_] shrink/enlarge horizontally
    "
      ("q" nil :exit t)
      ("c" shrink-window-horizontally)
      ("t" enlarge-window)
      ("s" shrink-window)
      ("r" enlarge-window-horizontally))
    

3.3.15. Initialize tldr

  1. Description

    tldr client within Emacs.

  2. Code
    (use-package tldr
      :straight t
      :defer 1)
    

3.3.16. Initialize grip

  1. Description

    Instant GitHub-flavored Markdown/Org preview using a grip subprocess.

  2. Code
    (use-package grip-mode
      :straight t
      :defer 1
      :bind (:map markdown-mode-command-map
                  ("g" . grip-mode)))
    

3.4. Git

3.4.1. Initialize magit

  1. Description

    The definitive Git porcelain for Emacs.

  2. Code
    (use-package magit
      :straight t
      :config
      ;; Bind the `magit-status' command to a convenient key.
      (global-set-key (kbd "C-c g") #'magit-status))
    
    ;; bindings to help improve the speed of magit
    ;; (use-package libgit :straight t)
    ;; (use-package magit-libgit :straight t)
    

3.4.2. Initialize diff-hl

  1. Description

    Indication of local VCS changes.

  2. Code
    (use-package diff-hl
      :straight t)
    

3.4.3. Initialize autorevert

  1. Description

    Autorevert hooked buffers & diminish auto-revert-mode.

  2. Code
    (use-package autorevert
      :straight t
      :after magit
      :diminish auto-revert-mode
      :init
      (setq auto-revert-verbose nil)
      :hook ((prog-mode
              text-mode
              tex-mode
              org-mode
              conf-mode) . auto-revert-mode))
    

3.5. Keys

3.5.1. Initialize dabbrev

  1. Description

    Expand the word in the buffer before point as a dynamic abbrev, by searching for words starting with that abbreviation ( dabbrev-expand ).

  2. Code
    ;; use dabbrev with Corfu!
    (use-package dabbrev
      :straight t
      ;; swap M-/ and C-M-/
      :bind (("M-/" . dabbrev-completion)
             ("C-M-/" . dabbrev-expand)))
    

3.5.2. Initialize which-key

  1. Description

    Possible completion framework with 0.3s delay.

  2. Code
    (use-package which-key
      :straight t
      :init
      (which-key-mode)
      :config
      (setq which-key-idle-delay 0.3)
      ;; (setq which-key-prefix-prefix "◉ ")
      (setq which-key-sort-order 'which-key-key-order-alpha
            which-key-min-display-lines 2
            which-key-max-display-columns 4))
    

3.5.3. Initialize switch-window

  1. Description

    C-x o and pick window (a,s,d…)

  2. Code
    (use-package switch-window
      :straight t
      :config
      (setq switch-window-input-style 'minibuffer)
      (setq switch-window-increase 4)
      (setq switch-window-threshold 2)
      (setq switch-window-shortcut-style 'qwerty)
      (setq switch-window-qwerty-shortcuts
            '("a" "s" "d" "f" "j" "k" "l"))
      :bind
      ([remap other-window] . switch-window))
    

3.6. Completion

3.6.1. Initialize corfu

  1. Description

    Completion Overlay Region FUnction - Corfu enhances completion at point with a small completion popup. The current candidates are shown in a popup below or above the point. Corfu is the minimalistic completion-in-region counterpart of the Vertico minibuffer UI.

  2. Code
    (use-package corfu
      :straight t
      :demand t
      :bind (:map corfu-map
                  ("<escape>". corfu-quit)
                  ("<return>" . corfu-insert)
                  ("C-h" . corfu-show-documentation)
                  ("M-l" . 'corfu-show-location)
                  ("RET" . nil)
                  ("TAB" . corfu-next)
                  ([tab] . corfu-next)
                  ("S-TAB" . corfu-previous)
                  ([backtab] . corfu-previous))
      :custom
      (corfu-auto t)
      (corfu-auto-prefix 3)
      (corfu-auto-delay 0)
      (corfu-echo-documentation 0)
      (corfu-preview-current nil)
      (corfu-quit-no-match 'separator)
      (corfu-separator ?\s) ;; Necessary for use with orderless
      :init (global-corfu-mode)
      :config
      ;; adapted from Corfu's manual.
      (defun contrib/corfu-enable-always-in-minibuffer ()
        "Enable Corfu in the minibuffer if Vertico is not active.
    Useful for prompts such as `eval-expression' and `shell-command'."
        (unless (bound-and-true-p vertico--input)
          (corfu-mode 1)))
      (add-hook 'minibuffer-setup-hook #'contrib/corfu-enable-always-in-minibuffer 1))
    

3.6.2. Initialize cape

  1. Description

    Completion at point extensions.

  2. Code
    (use-package cape
      :straight t
      :bind (("C-c p p" . completion-at-point)
             ("C-c p d" . cape-dabbrev)
             ("C-c p f" . cape-file)
             ("C-c p s" . cape-symbol)
             ("C-c p i" . cape-ispell))
      :config
      (setq cape-dabbrev-min-length 3)
      (dolist (backend '( cape-symbol cape-keyword cape-file cape-dabbrev))
        (add-to-list 'completion-at-point-functions backend)))
    

3.6.3. Initialize vertico

  1. Description

    Vertical Interactive Completion.

  2. Code
    ;; enable vertico
    (use-package vertico
      :straight (:files (:defaults "extensions/*"))
      :bind (:map vertico-map
                  ("C-j" . vertico-next)
                  ("C-k" . vertico-previous)
                  ("M-j" . vertico-next)
                  ("M-k" . vertico-previous)
                  ("C-f" . vertico-exit)
                  :map minibuffer-local-map
                  ("M-h" . backward-kill-word))
      :custom
      (vertico-cycle t)
      (vertico-resize t)
      :init
      (vertico-mode)
      :config
      (vertico-mouse-mode))
    
    ;; configure directory extension.
    (use-package vertico-directory
      :straight nil
      :load-path "straight/repos/vertico/extensions"
      :after vertico
      :ensure nil
      :bind (:map vertico-map
                  ("RET" . vertico-directory-enter)
                  ("DEL" . vertico-directory-delete-char)
                  ("M-DEL" . vertico-directory-delete-word)))
    

3.6.4. Initialize orderless

  1. Description

    Provides an orderless completion style that divides the pattern into space-separated components.

  2. Code
    (use-package orderless
      :straight t
      :init
      (setq completion-styles '(orderless basic)
            completion-category-defaults nil
            completion-category-overrides '((file (styles basic partial-completion)))))
    

3.6.5. Initialize marginalia

  1. Description

    Provides marginalia-mode which adds marginalia to the minibuffer completions.

  2. Code
    (use-package marginalia
      :straight t
      :after vertico
      :init
      (marginalia-mode))
    

3.6.6. Initialize consult

  1. Description

    Provides practical commands based on the Emacs completion function completing-read.

  2. Code
    (use-package consult
      :straight t
      :bind
      (;; C-c bindings (mode-specific-map)
       ("C-c h" . consult-history)
       ("C-c j" . consult-line)
    
       ;; ("C-c m" . consult-mode-command)
       ("C-c b" . consult-bookmark)
       ("C-c k" . consult-kmacro)
    
       ;; C-x bindings (ctl-x-map)
       ("C-x b" . consult-buffer)
       ("C-x M-:" . consult-complex-command)
       ("C-x 4 b" . consult-buffer-other-window)
       ("C-x 5 b" . consult-buffer-other-frame)
       ("C-x r b" . consult-bookmark)
    
       ;; M-g bindings (goto-map)
       ("M-g e" . consult-compile-error)
       ("M-g g" . consult-goto-line)
       ("M-g M-g" . consult-goto-line)
       ("M-g o" . consult-outline)
       ("M-g m" . consult-mark)
       ("M-g k" . consult-global-mark)
       ("M-g i" . consult-imenu)
       ("M-g I" . consult-imenu-multi)
    
       ;; M-s bindings (search-map)
       ("M-s f" . consult-find)
       ("M-s L" . consult-locate)
       ("M-s g" . consult-grep)
       ("M-s G" . consult-git-grep)
       ("M-s r" . consult-ripgrep)
       ("C-c f" . consult-ripgrep)
       ("M-s l" . consult-line)
       ("M-s m" . consult-multi-occur)
       ("M-s k" . consult-keep-lines)
       ("M-s u" . consult-focus-lines)
    
       ;; Custom bindings that map to ivy
       ("C-c r" . consult-recent-file)
       ("C-c o" . consult-file-externally)
       ("C-s" . consult-line)
    
       ;; Other custom bindings
       ("M-y" . consult-yank-from-kill-ring)
       ("<help> a" . consult-apropos))
    
      :init
      ;; Use Consult to select xref locations with preview
      (setq xref-show-xrefs-function #'consult-xref
            xref-show-definitions-function #'consult-xref)
    
      ;; Updating the default to include "--ignore-case"
      (setq consult-ripgrep-command "rg --null --line-buffered --color=ansi --max-columns=1000 --ignore-case --no-heading --line-number . -e ARG OPTS"))
    

3.6.7. Initialize embark

  1. Description

    Emacs Mini-Buffer Actions Rooted in Keymaps

  2. Code
    (use-package embark
      :straight t
      :bind
      (("C-." . embark-act)         ;; pick some comfortable binding
       ("C-;" . embark-dwim)        ;; good alternative: M-.
       ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'
      :init
      ;; optionally replace the key help with a completing-read interface
      (setq prefix-help-command #'embark-prefix-help-command)
      :config
      ;; hide the mode line of the Embark live/completions buffers
      (add-to-list 'display-buffer-alist
                   '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
                     nil
                     (window-parameters (mode-line-format . none))))
      :hook
      (embark-collect-mode . consult-preview-at-point-mode)
      (embark-collect-mode . embark-consult-preview-minor-mode))
    
    (use-package embark-consult
      :straight t
      :after (embark consult)
      :demand t ; only necessary if you have the hook below
      ;; if you want to have consult previews as you move around an
      ;; auto-updating embark collect buffer
      :hook
      (embark-collect-mode . consult-preview-at-point-mode))
    

3.6.8. Initialize Emacs Adjustments for Completion

  1. Description

    This is not a package but instead a set of useful configurations to be used when utilizing the aforementioned completion framework packages.

  2. Code
    ;; a few more useful configurations...
    (use-package emacs
      :init
      ;; add prompt indicator to `completing-read-multiple'.
      ;; alternatively try `consult-completing-read-multiple'.
      (defun crm-indicator (args)
        (cons (concat "[CRM] " (car args)) (cdr args)))
      (advice-add #'completing-read-multiple :filter-args #'crm-indicator)
    
      ;; do not allow the cursor in the minibuffer prompt
      (setq minibuffer-prompt-properties
            '(read-only t cursor-intangible t face minibuffer-prompt))
      (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)
    
      ;; Emacs 28: hide commands in M-x which do not work in the current mode.
      ;; Vertico commands are hidden in normal buffers.
      (setq read-extended-command-predicate
            #'command-completion-default-include-p)
    
      ;; enable recursive minibuffers
      (setq enable-recursive-minibuffers t)
    
      ;; completion ignores case
      (setq read-buffer-completion-ignore-case t
            read-file-name-completion-ignore-case t
            completion-ignore-case t)
    
      ;; allow Emacs to resize mini windows
      (setq resize-mini-windows t))
    

3.6.9. Initialize all-the-icons

  1. Description

    All the icons!

  2. Code
    (use-package all-the-icons
      :straight t
      :config
      (cl-defmacro db/all-the-icons--with(&key name)
        (let ((defun-fn (intern (concat "jf/all-the-icons--with-" name)))
              (icon-fn (intern (concat "all-the-icons-" name)))
              (docstring (concat "Displays an ICON from `all-the-icons-" name "'.")))
          `(defun ,defun-fn (icon str &optional height v-adjust)
             ,docstring
             (s-concat (,icon-fn
                        icon
                        :v-adjust (or v-adjust 0)
                        :height (or height 1))
                       " " str))))
      (db/all-the-icons--with :name "faicon")
      (db/all-the-icons--with :name "material")
      (db/all-the-icons--with :name "octicon")
      (db/all-the-icons--with :name "alltheicon"))
    
    (use-package all-the-icons-completion
      :after (marginalia all-the-icons)
      :hook (marginalia-mode . all-the-icons-completion-marginalia-setup)
      :init
      (all-the-icons-completion-mode))
    

3.6.10. Initialize kind-icon

  1. Description

    Kind icons.

  2. Code
    (use-package kind-icon
      :straight t
      :after corfu
      :custom
      (kind-icon-use-icons t)
      ;; Have background color be the same as `corfu' face background
      (kind-icon-default-face 'corfu-default)
      ;; Use midpoint color between foreground and background colors ("blended")?
      (kind-icon-blend-background nil)
      (kind-icon-blend-frac 0.08)
      :config
      (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))
    

3.7. Search

3.7.1. Initialize dictionary-mode

  1. Description

    Quick lookup in a dictionary.

  2. Code
    (use-package dictionary
      :straight t
      :commands (dictionary-search)
      :init
      (global-set-key (kbd "C-c d") #'dictionary-search)
      :config (setq dictionary-server "dict.org"))
    

3.7.2. Initialize engine-mode

  1. Description

    engine-mode is a global minor mode for Emacs that enables you to easily define search engines, bind them to keybindings, and query them from the comfort of your editor.

  2. Code
    (use-package engine-mode
      :straight t
      :config
      (defengine google "https://google.com/search?q=%s" :keybinding "g"
                 :docstring "Search Google.")
      (defengine google-images "https://www.google.com/search?tbm=isch&q=%s" :keybinding "i"
                 :docstring "Search Google Images")
      (defengine google-maps "http://maps.google.com/maps?q=%s" :keybinding "m"
                 :docstring "Search Google Maps.")
      (defengine duckduckgo "https://duckduckgo.com/?q=%s" :keybinding "d"
                 :docstring "Search DuckDuckGo.")
      (defengine qwant "https://www.qwant.com/?q=%s" :keybinding "q"
                 :docstring "Search Qwant.")
      (defengine wikipedia "https://en.wikipedia.org/wiki/Special:Search?search=%s" :keybinding "w"
                 :docstring "Search Wikipedia.")
      (defengine youtube "http://www.youtube.com/results?aq=f&oq=&search_query=%s" :keybinding "y"
                 :docstring "Search YouTube.")
      (defengine twitter "https://twitter.com/search?q=%s" :keybinding "t"
                 :docstring "Search Twitter.")
      (defengine github "https://github.com/search?ref=simplesearch&q=%s" :keybinding "G"
                 :docstring "Search GitHub.")
      (defengine melpa "https://melpa.org/#/?q=%s" :keybinding "M"
                 :docstring "Search the Milkypostman's Emacs Lisp Package Archive.")
      (defengine stack-overflow "https://stackoverflow.com/search?q=%s" :keybinding "s"
                 :docstring "Search Stack Overflow.")
      (defengine wolfram-alpha "http://www.wolframalpha.com/input/?i=%s" :keybinding "a"
                 :docstring "Search Wolfram Alpha.")
      (defengine rfcs "http://pretty-rfc.herokuapp.com/search?q=%s" :keybinding "r"
                 :docstring "Search RFC documents.")
      (defengine ctan "http://www.ctan.org/search/?x=1&PORTAL=on&phrase=%s" :keybinding "c"
                 :docstring "Search the Comprehensive TeX Archive Network")
      (defengine project-gutenberg "http://www.gutenberg.org/ebooks/search/?query=%s" :keybinding "p"
                 :docstring "Search Project Gutenberg.")
      (engine/set-keymap-prefix (kbd "C-x /"))
      (setq engine/browser-function globals--browser)
      :init
      (engine-mode t))
    

3.7.3. Initialize deadgrep

  1. Description

    Deadgrep.

  2. Code
    (use-package deadgrep
      :straight t
      :commands deadgrep)
    

3.7.4. Initialize avy

  1. Description

    M-s to jump to desired character.

  2. Code
    (use-package avy
      :straight t
      :bind
      ("M-s" . avy-goto-char))
    

3.7.5. Initialize deft

  1. Description

    Deft is included for quicksearch of entire ~/org directory.

  2. Code
    (when (file-directory-p "~/org")
      (use-package deft
        :straight t
        :config
        (setq deft-directory org-directory
              deft-recursive t
              deft-strip-summary-regexp ":PROPERTIES:\n\\(.+\n\\)+:END:\n"
              deft-use-filename-as-title t)
        :bind
        ("C-c n d" . deft)))
    

3.8. News

3.8.1. Initialize elfeed

  1. Description

    RSS reader for Emacs.

  2. Code
    (use-package elfeed
      :straight t
      :config
      (setq elfeed-feeds
            '(("https://www.archlinux.org/feeds/news/" archlinux)
              ("https://www.gnome.org/feed/" gnome)
              ("http://nullprogram.com/feed/" nullprog)
              ("https://planet.emacslife.com/atom.xml" emacs community)
              ("https://www.ecb.europa.eu/rss/press.html" economics eu)
              ("https://drewdevault.com/blog/index.xml" drew devault)
              ("https://news.ycombinator.com/rss" ycombinator news)
              ("https://www.phoronix.com/rss.php" phoronix))))
    

3.8.2. Initialize gnus

  1. Description

    Gnus, or Gnus Network User Services, is a message reader which is part of GNU Emacs.

  2. Code
    (use-package gnus
      :straight t
      :config
      ;; make Gnus startup faster
      (setq gnus-check-new-newsgroups nil
            gnus-check-bogus-newsgroups nil)
    
      ;; read feeds/atom through Gmane
      (setq gnus-select-method '(nntp "news.gmane.io"))
    
      ;; Gmail
      (setq gnus-select-method
            '(nnimap "gmail"
                     (nnimap-address "imap.gmail.com")))
    
      ;; make Gnus prettier
      (setq gnus-sum-thread-tree-indent "  ")
      (setq gnus-sum-thread-tree-root "● ")
      (setq gnus-sum-thread-tree-false-root "◯ ")
      (setq gnus-sum-thread-tree-single-indent "◎ ")
      (setq gnus-sum-thread-tree-vertical        "│")
      (setq gnus-sum-thread-tree-leaf-with-other "├─► ")
      (setq gnus-sum-thread-tree-single-leaf     "╰─► ")
      (setq gnus-summary-display-arrow t)
      (setq gnus-summary-line-format
            (concat
             "%0{%U%R%z%}"
             "%3{│%}" "%1{%d%}" "%3{│%}"
             "  "
             "%4{%-20,20f%}"
             "  "
             "%3{│%}"
             " "
             "%1{%B%}"
             "%s\n"))
    
      ;; fixing summary buffer
      ;; there’s no need to recenter the summary buffer all the time, it only slows gnus down.
      (setq gnus-auto-center-summary nil)
    
      ;; enter the summary buffer faster
      (setq gnus-nov-is-evil nil
            gnus-show-threads t
            gnus-use-cross-reference nil)
    
      ;; news check
      (defun gnus-demon-scan-news ()
        (interactive)
        (when gnus-plugged
          (let ((win (current-window-configuration))
                (gnus-read-active-file nil)
                (gnus-check-new-newsgroups nil)
                (gnus-verbose 2)
                (gnus-verbose-backends 5))
            (unwind-protect
                (save-window-excursion
                  (when (gnus-alive-p)
                    (with-current-buffer gnus-group-buffer
                      (gnus-group-get-new-news gnus-activate-level))))
              (set-window-configuration win)))))
    
      ;; configuring mail appearance
      (setq gnus-treat-strip-multiple-blank-lines t)
      (setq gnus-treat-trailing-blank-lines t)
      ;; let's see some smiles in gnus
      (setq gnus-treat-display-smileys t)
      (setq gnus-treat-emphasize 'head)
    
      ;; fetch only part of the article if we can.
      (setq gnus-read-active-file 'some)
      ;; fetch some old headers
      (setq gnus-fetch-old-headers 'some)
    
      ;; Gnus automatic scoring
      (setq gnus-use-adaptive-scoring t)
    
      ;; Gnus sorting
      (setq gnus-thread-sort-functions
            '(gnus-thread-sort-by-most-recent-date
              (not gnus-thread-sort-by-number))))
    

3.9. IRC

3.9.1. Initialize erc

  1. Description

    ERC is a powerful, modular, and extensible IRC client for Emacs.

    Server: irc.rizon.net

  2. Code
    (use-package erc
      :straight t
      :custom
      (erc-autojoin-timing 'ident)
      (erc-autojoin-channels-alist '(("irc.rizon.net" "#rice")))
      (erc-fill-function 'erc-fill-static)
      (erc-fill-static-center 22)
      (erc-hide-list '("JOIN" "PART" "QUIT"))
      (erc-lurker-hide-list '("JOIN" "PART" "QUIT"))
      (erc-lurker-threshold-time 43200)
      (erc-server-reconnect-attempts 5)
      (erc-server-reconnect-timeout 3)
      (erc-quit-reason 'erc-quit-reason-normal)
      (erc-timestamp-format "[%I:%M %p] ")
      (erc-timestamp-only-if-changed-flag nil)
      (erc-truncate-mode t)
      (erc-track-exclude-types '("JOIN" "MODE" "NICK" "PART" "QUIT"
                                 "324" "329" "332" "333" "353" "477"))
      :config
      ;; login
      (setq erc-nickserv-identify-mode 'autodetect)
      ;; interpret mIRC-style color commands in IRC chats
      (setq erc-interpret-mirc-color t)
      ;; kill buffers for channels after /part
      (setq erc-kill-buffer-on-part t)
      ;; kill buffers for private queries after quitting the server
      (setq erc-kill-queries-on-quit t)
      ;; kill buffers for server messages after quitting the server
      (setq erc-kill-server-buffer-on-quit t)
      ;; open query buffers in the current window
      (setq erc-query-display 'buffer)
      ;; configure appearance
      (setq erc-prompt " >")
      ;; load erc modules
      (add-to-list 'erc-modules 'notifications)
      (add-to-list 'erc-modules 'spelling))
    

3.9.2. Initialize rcirc

  1. Description

    Emacs' builtin irc client.

    Server: irc.libera.chat

  2. Code
    (use-package rcirc
      :defer
      :commands (irc rcirc)
      :ensure nil
      :config
      (setq rcirc-auto-authenticate-flag t)
      (setq rcirc-time-format "[%I:%M %p] ")
    
      ;; connect to Librea
      (setq rcirc-server-alist
            '(("irc.libera.chat" :channels ("#emacs")
               :port 6697 :encryption tls)))
    
      ;; enable minor mode
      (add-hook 'rcirc-mode-hook #'rcirc-track-minor-mode)
      (add-hook 'rcirc-mode-hook #'rcirc-omit-mode)
      (rcirc-track-minor-mode 1))
    

3.10. Documents

3.10.1. Initialize nov

  1. Description

    Major mode for reading EPUBs.

  2. Code
    (use-package nov
      :straight t
      :defer nil
      :config
      (defun nov-font-setup ()
        (face-remap-add-relative 'variable-pitch :family "Liberation Serif"
                                 :height 1.0)
        (text-scale-increase 2))
      :mode ("\\.epub\\'" . nov-mode)
      :hook (nov-mode . nov-font-setup))
    

3.10.2. Initialize pdf-tools

  1. Description

    PDF Tools is, among other things, a replacement of DocView for PDF files. The key difference is that pages are not pre-rendered by e.g. ghostscript and stored in the file-system, but rather created on-demand and stored in memory.

  2. Code
    (use-package pdf-tools
      :straight t
      :defer nil
      :commands (pdf-view-mode pdf-tools-install)
      :mode ("\\.[pP][dD][fF]\\'" . pdf-view-mode)
      :load-path "site-lisp/pdf-tools/lisp"
      :magic ("%PDF" . pdf-view-mode)
      :config
      ;; install pdf-tools
      (pdf-tools-install :no-query)
      ;; open pdfs scaled to fit page
      (setq-default pdf-view-display-size 'fit-page)
      ;; automatically annotate highlights
      (setq pdf-annot-activate-created-annotations t)
      (define-pdf-cache-function pagelabels)
      :hook ((pdf-view-mode-hook . (lambda () (display-line-numbers-mode -1)))
             (pdf-view-mode-hook . pdf-tools-enable-minor-modes)))
    
    (use-package pdf-view-restore
      :after pdf-tools
      :straight t
      :config
      :hook (pdf-view-mode . pdf-view-restore-mode))
    

3.10.3. Initialize ox-hugo

  1. Description

    Org exporter backend that exports Org to Hugo-compatible Markdown (Blackfriday) and also generates the front-matter (in TOML or YAML format).

  2. Code
    (use-package ox-hugo
      :straight t
      :after ox)
    

3.10.4. Initialize academic

  1. Description

    Presents you with a list of phrases organized by the topic or by the paper section that you are writing. Call M-x academic-phrases to get a list of phrases organized by topic, or call academic-phrases-by-section to browse the phrases by paper section and fill-in the blanks if required.

  2. Code
    (use-package academic-phrases
      :straight t)
    

3.10.5. Initialize writegood

  1. Description

    Minor mode to aid in finding common writing problems. Highlights text based on a set of weasel-words, passive-voice and duplicate words.

  2. Code
    (use-package writegood-mode
      :straight t)
    

3.10.6. Initialize synosaurus

  1. Description

    Synosaurus is a thesaurus frontend for Emacs with pluggable backends.

  2. Code
    (use-package synosaurus
      :straight t)
    

3.10.7. Initialize olivetti

  1. Description

    Emacs minor mode for a nice writing environment.

  2. Code
    (use-package olivetti
      :straight t
      :init
      (setq olivetti-body-width .75))
    

3.10.8. Initialize saveplace

  1. Description

    Saves cursor location in buffers.

  2. Code
    (use-package saveplace
      :straight t
      :defer nil
      :config
      (save-place-mode))
    

3.10.9. Initialize savehist

  1. Description

    Persist history over Emacs restarts. Vertico sorts by history position.

  2. Code
    (use-package savehist
      :straight t
      :init
      (savehist-mode))
    

4. Languages

4.1. LSP

4.1.1. Description

Language Server Protocol, handles the following languages:

  • C/C++
  • JS/JSX/HTML/CSS
  • Python

4.1.2. Code

(use-package lsp-mode
  :straight t
  :init
  ;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l")
  (setq lsp-keymap-prefix "C-c l")
  :hook ((c-mode          ; clangd
          c++-mode        ; clangd
          c-or-c++-mode   ; clangd
          js2-mode        ; ts-ls (tsserver wrapper)
          js-mode         ; ts-ls (tsserver wrapper)
          rjsx-mode       ; ts-ls (tsserver wrapper)
          js-jsx-mode     ; ts-ls (tsserver wrapper)
          typescript-mode ; ts-ls (tsserver wrapper)
          python-mode     ; pyright
          rust-mode       ; rust-analyzer
          ruby-mode       ; solargraph
          web-mode        ; ts-ls/HTML/CSS
          ) . lsp-deferred)
  ((lsp-mode . lsp-enable-which-key-integration))
  :commands (lsp lsp-deferred)
  :config
  (setq lsp-auto-guess-root t)
  (setq lsp-log-io nil)
  (setq lsp-restart 'auto-restart)
  (setq lsp-enable-symbol-highlighting nil)
  (setq lsp-enable-on-type-formatting nil)
  (setq lsp-signature-auto-activate nil)
  (setq lsp-signature-render-documentation nil)
  (setq lsp-eldoc-hook nil)
  (setq lsp-modeline-code-actions-enable nil)
  (setq lsp-modeline-diagnostics-enable nil)
  (setq lsp-headerline-breadcrumb-enable nil)
  (setq lsp-semantic-tokens-enable nil)
  (setq lsp-enable-folding nil)
  (setq lsp-enable-imenu nil)
  (setq lsp-enable-snippet nil)
  (setq lsp-enable-completion-at-point t)
  (setq read-process-output-max (* 1024 1024)) ;; 1MB
  (setq completion-styles '(orderless)
        completion-category-defaults nil)
  (setq lsp-idle-delay 0.5)
  (setq lsp-clients-typescript-server "typescript-language-server"
        lsp-clients-typescript-server-args '("--stdio"))
  (setq lsp-disabled-clients '(eslint)))

(use-package lsp-ui
  :straight t
  :after lsp
  :commands lsp-ui-mode
  :config
  (setq lsp-ui-doc-enable nil)
  (setq lsp-ui-doc-header t)
  (setq lsp-ui-doc-include-signature t)
  (setq lsp-ui-doc-border (face-foreground 'default))
  (setq lsp-ui-sideline-show-code-actions t)
  (setq lsp-ui-sideline-delay 0.05))

(use-package lsp-pyright
  :straight t
  :after lsp
  :hook (python-mode . (lambda () (require 'lsp-pyright) (lsp-deferred)))
  :init (when (executable-find "python3")
          (setq lsp-pyright-python-executable-cmd "python3")))

4.2. Eglot

4.2.1. Description

Language Server Protocol with eglot.

4.2.2. Code

;; LSP
(use-package eglot
  :disabled t
  :config
  ;; Enable LSP support by default in programming buffers
  (add-hook 'prog-mode-hook #'eglot-ensure))

;; Pop-up auto-completion
(use-package company
  :disabled t
  :hook (prog-mode . company-mode))

4.3. C/C++

Default C/C++ mode is sufficient. Add modern cpp syntax highlighting.

(use-package modern-cpp-font-lock
  :straight t)

4.4. C#

4.4.1. Description

CSharp mode.

4.4.2. Code

(use-package csharp-mode
  :straight t)

4.5. Go

4.5.1. Description

Go-mode.

4.5.2. Code

(use-package go-mode
  :straight t
  :mode "\\.go\\'"
  :config
  (defun db/go-mode-hook()
    (setq tab-width 2)
    (add-hook 'before-save-hook 'gofmt-before-save)
    (set (make-local-variable 'compile-command)
         "go test"))
  :hook ((go-mode . db/go-mode-hook))
  :hook ((go-mode . subword-mode)))

4.6. Rust

4.6.1. Description

Enhanced Rust mode with automatic LSP support.

4.6.2. Code

(use-package rustic
  :straight t
  :config
  (setq rustic-format-on-save nil))

4.7. Lisp

4.7.1. Common Lisp

  1. Description

    SLIME - Common Lisp REPL.

  2. Code
    (use-package slime
      :straight t
      :config
      (setq inferior-lisp-program "/usr/bin/sbcl")
      (setq slime-contribs '(slime-fancy slime-quicklisp)))
    

4.7.2. Scheme Lisp

  1. Description

    Geiser - Scheme Lisp REPL.

  2. Code
    (use-package geiser
      :straight t
      :config
      (setq geiser-active-implementations '(mit guile))
      (setq geiser-mit-binary "/usr/bin/mit-scheme")
      (setq geiser-default-implementation 'mit)
      (add-hook 'scheme-mode-hook 'geiser-mode)
      (add-to-list 'auto-mode-alist
                   '("\\.sls\\'" . scheme-mode)
                   '("\\.sc\\'" . scheme-mode)))
    
    (use-package geiser-mit
      :straight t
      :after geiser)
    
    (defun geiser-save ()
      "Save geiser repl contents to input ring."
      (interactive)
      (geiser-repl--write-input-ring))
    

4.7.3. SICP

  1. Description

    Structure & Interpretation of Computer Programs in TeXInfo format.

  2. Code
    (use-package sicp
      :straight t)
    

4.8. JSON

4.8.1. Description

Syntax highlighting for json files.

4.8.2. Code

(use-package json-mode
  :straight t
  :mode ("\\.json\\'" . json-mode))

4.9. CSV

4.9.1. Description

Major mode for editing records in a generalized CSV (character-separated values) format.

4.9.2. Code

(use-package csv-mode
  :straight t
  :mode ("\\.csv\\'" . csv-mode))

4.10. Lua

4.10.1. Description

Lua mode.

4.10.2. Code

(use-package lua-mode
  :straight t
  :config
  (setq lua-indent-level 2))

4.11. Ruby

4.11.1. Description

Ruby mode.

4.11.2. Code

(use-package ruby-mode
  :straight t)

4.12. Python

4.12.1. Description

Python mode.

4.12.2. Code

(use-package python-mode
  :straight t
  :config
  (setq python-indent-offset standard-indent)
  (setq python-indent-guess-indent-offset t)
  (setq python-indent-guess-indent-offset-verbose nil))

4.13. Jupyter

4.13.1. Description

Jupyter notebook repl & src blocks in org-mode, also provides kernel interactions integrated with Emacs's built-in features. Uses the completion-at-point interface for code completion.

4.13.2. Code

(use-package jupyter
  :straight t)

4.14. Wolfram

4.14.1. Description

xah-wolfram-mode is Major mode for editing Wolfram Language.

4.14.2. Code

(use-package xah-wolfram-mode
  :straight (:type git :host github :repo "xahlee/xah-wolfram-mode" :branch "master"))

4.15. Markdown

4.15.1. Description

Markdown-mode & enable auto fill.

4.15.2. Code

(use-package markdown-mode
  :straight t
  :mode "\\.md\\'"
  :hook ((markdown-mode . auto-fill-mode)))

4.16. LaTeX

4.16.1. Description

Auctex for LaTeX.

4.16.2. Code

(use-package auctex
  :straight t
  :config
  (setq TeX-auto-save t)
  (setq TeX-parse-self t)
  (setq-default TeX-master nil)
  ;; Enable LaTeX math support
  (add-hook 'LaTeX-mode-map #'LaTeX-math-mode))

4.17. Javascript

4.17.1. Description

Improved Javascript editing mode.

4.17.2. Code

(use-package js2-mode
  :straight t
  :custom
  (js-indent-level 2)
  (js2-basic-offset 2)
  :init
  (add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode)))

4.18. Typescript

4.18.1. Description

TypeScript support for Emacs.

4.18.2. Code

(use-package typescript-mode
  :straight t)

4.19. React JSX

4.19.1. Description

A JSX major mode.

4.19.2. Code

(use-package rjsx-mode
  :straight t)

4.20. Web

4.20.1. Description

Web editing mode.

4.20.2. Code

(use-package web-mode
  :straight t
  :custom
  (setq web-mode-markup-indent-offset 2)
  (setq web-mode-code-indent-offset 2)
  (setq web-mode-css-indent-offset 2)
  :mode (("\\.html\\'" . web-mode))
  :commands web-mode)

4.21. Prettier

4.21.1. Description

Prettier formatter for JSX & TSX.

4.21.2. Code

(use-package prettier-js
  :straight t
  :config
  (add-hook 'web-mode-hook #'(lambda ()
                               (enable-minor-mode
                                '("\\.jsx?\\'" . prettier-js-mode))
                               (enable-minor-mode
                                '("\\.tsx?\\'" . prettier-js-mode)))))

5. Functions

5.1. Helper

5.1.1. Load if exists

(defun load-if-exists (f)
  "Load file F if it exists."
  (if (file-exists-p (expand-file-name f))
      (load-file (expand-file-name f))))

5.1.2. Enable Minor mode

(defun enable-minor-mode (my-pair)
  "Enable minor mode if filename match the regexp.  MY-PAIR is a cons cell (regexp . minor-mode)."
  (if (buffer-file-name)
      (if (string-match (car my-pair) buffer-file-name)
          (funcall (cdr my-pair)))))

5.1.3. Reading mode

(defun read-mode/disable ()
  "Enable menubar & scrollbar."
  (interactive)
  (menu-bar-mode 1)
  (scroll-bar-mode 1))

(defun read-mode/enable ()
  "Disable menubar & scrollbar."
  (interactive)
  (menu-bar-mode -1)
  (scroll-bar-mode -1))

5.1.4. Erc handlers

(defun erc-start ()
  "Start ERC and connect to Rizon."
  (interactive)
  (save-current-buffer
    (erc-services-mode 1)
    (erc-update-modules)
    (erc :server "irc.rizon.net" :port "6667" :nick erc-nick-short)))

(defun erc-quit ()
  "Quit ERC."
  (interactive)
  (erc-services-mode 0)
  (erc-quit-server nil))

5.1.5. Kill async buffers

(defun kill-async-buffers ()
  "Kill all buffers matching '*Async Shell Command' regex."
  (interactive)
  (kill-matching-buffers "*Async Shell Command*" nil t))

5.1.6. Disable all themes

(defun disable-all-themes ()
  "Disable all active themes."
  (dolist (i custom-enabled-themes)
    (disable-theme i)))

5.1.7. Split and follow

(defun split-and-follow-horizontally ()
  "Split and follow horizontally."
  (interactive)
  (split-window-below)
  (balance-windows)
  (other-window 1))
(global-set-key (kbd "C-x 2") 'split-and-follow-horizontally)

(defun split-and-follow-vertically ()
  "Split and follow vertically."
  (interactive)
  (split-window-right)
  (balance-windows)
  (other-window 1))
(global-set-key (kbd "C-x 3") 'split-and-follow-vertically)

5.1.8. run-in-vterm

(if (eq system-type 'gnu/linux)
    (defun run-in-vterm-kill (process event)
      "A process sentinel.  Kill PROCESS's buffer if it is live with arg EVENT."
      (let ((b (process-buffer process)))
        (and (buffer-live-p b)
             (kill-buffer b))))

  (defun run-in-vterm (command)
    "Execute string COMMAND in a new vterm.

    Interactively, prompt for COMMAND with the current buffer's file
    name supplied.  When called from Dired, supply the name of the
    file at point.

    Like `async-shell-command`, but run in a vterm for full terminal features.

    The new vterm buffer is named in the form `*foo bar.baz*`, the
    command and its arguments in earmuffs.

    When the command terminates, the shell remains open, but when the
    shell exits, the buffer is killed."
    (interactive
     (list
      (let* ((f (cond (buffer-file-name)
                      ((eq major-mode 'dired-mode)
                       (dired-get-filename nil t))))
             (filename (concat " " (shell-quote-argument (and f (file-relative-name f))))))
        (read-shell-command "Command: "))))
    (with-current-buffer (vterm (concat "*" command "*"))
      (set-process-sentinel vterm--process #'run-in-vterm-kill)
      (vterm-send-string command)
      (vterm-send-return))))

5.1.9. Yank Whole Buffer

(defun yank-whole-buffer ()
  "Yank whole buffer."
  (interactive)
  (save-excursion
    (mark-whole-buffer)
    (call-interactively 'evil-yank)))

5.2. Config

5.2.1. config/tangle

Tangles the Emacs configuration.

(if (eq system-type 'gnu/linux)
    (defun config/tangle ()
      "Tangles this Emacs configuration."
      (interactive)
      (shell-command "~/.emacs.d/bin/tangle.sh")))

5.2.2. config/reload

Tangles & reloads the Emacs configuration.

(if (eq system-type 'gnu/linux)
    (defun config/reload ()
      "Reload this Emacs configuration."
      (interactive)
      (config/tangle)
      (load-file (concat user-emacs-directory "init.el"))))

5.2.3. config/update

Updates the Emacs configuration. This is only supported if the Emacs configuration is installed under ~/.emacs.d.

(when (file-directory-p "~/.emacs.d")
  (defun config/update ()
    "Updates this Emacs configuration."
    (interactive)
    (shell-command "cd ~/.emacs.d; git pull")
    (straight-pull-all)
    (config/reload)))

5.2.4. config/github

Opens this Emacs configuration GitHub website.

(defun config/github ()
  "Opens this configurations GitHub website."
  (interactive)
  (browse-url "https://github.com/diamondbond/emacs"))

5.2.5. auth/backup

Backup auth files.

(when (file-readable-p "~/bin/auth-backup.sh")
  (defun auth/backup ()
    "Backup auth."
    (interactive)
    (async-shell-command "~/bin/auth-backup.sh")))

5.2.6. auth/restore

Restore auth files.

(when (file-readable-p "~/bin/auth-restore.sh")
  (defun auth/restore ()
    "Restore auth."
    (interactive)
    (async-shell-command "~/bin/auth-restore.sh")))

5.2.7. sync/dotfiles

Sync dotfiles to GitHub.

(when (file-readable-p "~/bin/sync-dotfiles.sh")
  (defun sync/dotfiles ()
    "Sync dotfiles."
    (interactive)
    (async-shell-command "~/bin/sync-dotfiles.sh")))

5.2.8. sync/neocities

Sync Emacs configuration to neocities.

(when (file-readable-p "~/bin/sync-neocities.sh")
  (defun sync/neocities ()
    "Sync neocities."
    (interactive)
    (save-window-excursion
      (async-shell-command "~/bin/sync-neocities.sh"))))

5.3. Insert

5.3.1. Date

Insert date in a buffer in my preferred format

(defun get-date ()
  "Get date."
  (format-time-string "%b %d, %Y"))

(defun insert-date ()
  "Insert date."
  (interactive)
  (insert (get-date)))

5.3.2. Link

Inserts org-mode link template.

(defun insert-org-link-template ()
  "Insert org link template at point."
  (interactive)
  (setq last-command-event 91)
  (org-self-insert-command 1)
  (setq last-command-event 91)
  (org-self-insert-command 1)
  (setq last-command-event 'right)
  (right-char 1)
  (setq last-command-event 91)
  (org-self-insert-command 1))

5.3.3. Notifications

Insert WILD NOTIFIER properties template.

(defun insert-wild-notifier-template ()
  "Insert WILD_NOTIFIER_NOTIFY_BEFORE template at point."
  (interactive)
  (insert ":PROPERTIES:
:WILD_NOTIFIER_NOTIFY_BEFORE: 60 30 15 10 5
:END:"))

5.3.4. Current filename

Insert currently visiting buffer filename.

(defun insert-current-file-name-at-point (&optional full-path)
  "Insert the current filename at point.
With prefix argument, use FULL-PATH."
  (interactive "P")
  (let* ((buffer
          (if (minibufferp)
              (window-buffer
               (minibuffer-selected-window))
            (current-buffer)))
         (filename (buffer-file-name buffer)))
    (if filename
        (insert (if full-path filename (file-name-nondirectory filename)))
      (error (format "Buffer %s is not visiting a file" (buffer-name buffer))))))

5.4. Launch

5.4.1. Music

Run ncmpcpp within vterm.

(if (eq system-type 'gnu/linux)
    (defun music ()
      "Play music with ncmpcpp."
      (interactive)
      (run-in-vterm "ncmpcpp")))

5.4.2. Emacs-devel

Launches gnus and connects to news.gmane.io/emacs-devel.

(defun emacs-devel ()
  "Read the Emacs-devel mailing list."
  (interactive)
  (setq last-command-event 121)
  (gnus nil)
  (setq last-command-event 121)
  (execute-extended-command nil "gnus" "gnus")
  (setq last-command-event 13)
  (gnus-group-browse-foreign-server
   `(nntp "news.gmane.io"))
  (setq last-command-event 13)
  (consult-line)
  (setq last-command-event 13)
  (gnus-browse-select-group nil))

5.4.3. Org-agenda

(defun start-to-org-agenda ()
  "Launch shrink-wrapped 'org-agenda'."
  (interactive)
  (org-agenda nil "n")
  (delete-other-windows)
  (fit-frame-to-buffer))

5.4.4. Buffer-menu-in-new-frame

;; https://stackoverflow.com/questions/12014036/emacs-make-frame-switch-buffer
(defun get-buffer-menu-in-new-frame ()
  "Switch-to-buffer in new frame."
  (interactive)
  (switch-to-buffer (list-buffers-noselect)))

5.4.5. Shrink-wrapped-buffer-list

(defun shrink-wrapped-buffer-list ()
  "Launch frame-fitted *Buffer List*."
  (interactive)
  (switch-to-buffer (list-buffers-noselect))
  (shrink-wrap))

5.5. Markup

5.5.1. Next/Prev 15-lines

(defun next-15-lines ()
  "Move to the next 15 lines."
  (interactive)
  (forward-line 15))

(defun previous-15-lines ()
  "Move to the previous 15 lines."
  (interactive)
  (forward-line -15))

5.5.2. Upcase last word

(defun upcase-last-word ()
  "Convert last word to uppercase."
  (interactive)
  (move-end-of-line 1)
  (backward-word 1)
  (upcase-word 1)
  (move-beginning-of-line 1)
  (next-line 1 1))

5.5.3. Open new line below

(defun open-line-below ()
  "Open a new line below point."
  (interactive)
  (end-of-line)
  (newline)
  (indent-for-tab-command))

5.5.4. Open new line above

(defun open-line-above ()
  "Open a new line above point."
  (interactive)
  (beginning-of-line)
  (newline)
  (forward-line -1)
  (indent-for-tab-command))

5.5.5. Delete current line

(defun db/delete-current-line ()
  "Kill the whole line on which point is."
  (interactive)
  (beginning-of-line)
  (kill-line 1))

5.5.6. Duplicate current line

(defun db/duplicate-line()
  "Duplicate line at point."
  (interactive)
  (save-excursion
    (move-beginning-of-line 1)
    (kill-line)
    (yank)
    (open-line 1)
    (forward-line 1)
    (yank)))

5.5.7. xah-space-to-newline

(defun xah-space-to-newline ()
  "Replace space sequence to a newline char.
Works on current block or selection.

URL `http://xahlee.info/emacs/emacs/emacs_space_to_newline.html'
Version 2017-08-19"
  (interactive)
  (let* ( $p1 $p2 )
    (if (use-region-p)
        (progn
          (setq $p1 (region-beginning))
          (setq $p2 (region-end)))
      (save-excursion
        (if (re-search-backward "\n[ \t]*\n" nil "move")
            (progn (re-search-forward "\n[ \t]*\n")
                   (setq $p1 (point)))
          (setq $p1 (point)))
        (re-search-forward "\n[ \t]*\n" nil "move")
        (skip-chars-backward " \t\n" )
        (setq $p2 (point))))
    (save-excursion
      (save-restriction
        (narrow-to-region $p1 $p2)
        (goto-char (point-min))
        (while (re-search-forward " +" nil t)
          (replace-match "\n" ))))))

5.5.8. infu-bionic-reading

(defvar infu-bionic-reading-face nil "a face for `infu-bionic-reading-region'.")

(setq infu-bionic-reading-face 'error)
;; try
;; 'bold
;; 'error
;; 'warning
;; 'highlight
;; or any value of M-x list-faces-display

(defun infu-bionic-reading-buffer ()
  "Bold the first few chars of every word in current buffer.
Version 2022-05-21"
  (interactive)
  (infu-bionic-reading-region (point-min) (point-max)))

(defun infu-bionic-reading-region (Begin End)
  "Bold the first few chars of every word in region.
Version 2022-05-21"
  (interactive "r")
  (let (xBounds xWordBegin xWordEnd  )
    (save-restriction
      (narrow-to-region Begin End)
      (goto-char (point-min))
      (while (forward-word)
        ;; bold the first half of the word to the left of cursor
        (setq xBounds (bounds-of-thing-at-point 'word))
        (setq xWordBegin (car xBounds))
        (setq xWordEnd (cdr xBounds))
        (setq xBoldEndPos (+ xWordBegin (1+ (/ (- xWordEnd xWordBegin) 2))))
        (put-text-property xWordBegin xBoldEndPos
                           'font-lock-face infu-bionic-reading-face)))))

5.5.9. comment-line-dwim

;; Original idea from
;; http://www.opensubscriber.com/message/emacs-devel@gnu.org/10971693.html
(defun comment-dwim-line (&optional arg)
  "Replacement for the comment-dwim command.
  If no region is selected and current line is not blank and we are not at the end of the line,
  then comment current line.
  Replaces default behaviour of comment-dwim, when it inserts comment at the end of the line."
  (interactive "*P")
  (comment-normalize-vars)
  (if (and (not (region-active-p)) (not (looking-at "[ \t]*$")))
      (comment-or-uncomment-region (line-beginning-position) (line-end-position))
    (comment-dwim arg)))

5.5.10. camelCase to snake_case

(defun camel-to-snake-case (arg)
  "Convert a camelCase word to snake_case.

If the prefix argument ARG is non-nil, convert the text to uppercase."
  (interactive "p")
  (progn
    (let ((start (region-beginning))
          (end (region-end))
          (case-fold-search nil)
          (had-initial-underscore nil))
      (goto-char start)
      (when (looking-at "_") (setq had-initial-underscore t))
      (while (re-search-forward "\\([A-Z]\\)" end t)
        (replace-match "_\\1")
        (setq end (1+ end)))
      (if arg
          (upcase-region start end)
        (downcase-region start end))
      (goto-char start)
      (unless had-initial-underscore (delete-char 1)))))

5.5.11. sanemacs/backward-kill-word

(defun sanemacs/backward-kill-word ()
  "Kill word backwards without littering 'kill-ring'."
  (interactive )
  (push-mark)
  (backward-word)
  (delete-region (point) (mark)))

6. Footer

6.1. Goodbye

;;; config.el ends here

Author: Diamond Bond

Created: 2022-09-09 Fri 09:27

Validate