Emacs Config


Alec Barreto
posted on: 2025-05-10

Table of Contents

Note that this is for emacs 29.x with pgtk on wayland. Most here is agnostic of that but some is not.

1. Early Init

1.1. Suppress Symlink Warning

(setq vc-follow-symlinks t)

1.2. GC Optimizations

(defun restore-gc-cons-threshold ()
  (setq gc-cons-threshold 16000000
        gc-cons-percentage 0.1))

(setq gc-cons-threshold most-positive-fixnum
      gc-cons-percentage 0.6)

(add-hook 'emacs-startup-hook #'restore-gc-cons-threshold 105)

1.3. UI

Opacity / Transparency

NOTE: On wayland emacs must be pure GTK (emacs-pgtk on guix)

(add-to-list 'default-frame-alist '(alpha-background . 80))

General Cleanup

  • Startup Buffers
    (setopt initial-scratch-message nil
            inhibit-startup-screen t)
    
  • Toolbars
    (use-package scroll-bar
      :config
      (scroll-bar-mode -1))
    
    (use-package tool-bar
      :config
      (tool-bar-mode -1))
    
    (use-package menu-bar
      :config
      (menu-bar-mode -1))
    
  • Cursor
    (use-package frame
      :config
      (blink-cursor-mode -1))
    

X / Wayland Window Properties

(setopt frame-title-format "%b")
(add-to-list 'default-frame-alist '(undecorated . t))

Mode Line

(setopt mode-line-format
        '("%e"
          mode-line-front-space
          mode-line-mule-info
          mode-line-client
          mode-line-modified
          mode-line-remote
          "  "
          mode-line-buffer-identification
          "  "
          mode-line-position-column-line-format
          "  "
          (vc-mode vc-mode)
          "  "
          mode-name
          "  "
          (:eval (unless (zerop
                          (bound-and-true-p text-scale-mode-amount))
                   text-scale-mode-lighter))
          "  "
          mode-line-misc-info
          mode-line-end-spaces))

(setopt mode-line-compact 'long)

(use-package time
  :custom
  (display-time-format "%R")
  (display-time-default-load-average nil)
  :config
  (display-time-mode 1))

Lines

(global-visual-line-mode 1)

(use-package hl-line
  :config
  (global-hl-line-mode 1)
  (dolist (hook '(comint-mode-hook eshell-mode-hook))
    (add-hook hook (lambda () (setq-local global-hl-line-mode nil)))))

(use-package display-line-numbers
  :custom
  (display-line-numbers-type t)
  :config
  (dolist (hook '(conf-mode-hook nxml-mode-hook prog-mode-hook))
    (add-hook hook 'display-line-numbers-mode)))

Fonts

(use-package font-lock)

(use-package faces
  :config
  (set-face-attribute 'default nil
                      :family "DejaVu Sans Mono"
                      :height 130)

  (set-face-attribute 'fixed-pitch nil
                      :family "DejaVu Sans Mono"
                      :height 130)

  (set-face-attribute 'variable-pitch nil
                      :family "DejaVu Serif"
                      :height 160))

(use-package face-remap
  :config
  (defun my/remap-pitch-faces (_enable)
    (face-remap--remap-face 'fixed-pitch)
    (face-remap--remap-face 'variable-pitch))

  (advice-add 'text-scale-mode :after #'my/remap-pitch-faces))

(defun my/enable-variable-pitch-mode (&optional exceptions)
  "Enable `variable-pitch-mode' only in sensible major modes."
  (unless (derived-mode-p 'html-mode 'nxml-mode 'org-mode 'markdown-mode)
    (variable-pitch-mode 1)))

(use-package text-mode
  :defer t
  :config
  (add-hook 'text-mode-hook #'my/enable-variable-pitch-mode))
  • Icons

    You may need to call (nerd-icons-install-fonts)

    (use-package nerd-icons-dired
      :hook
      (dired-mode . nerd-icons-dired-mode)
      :after dired)
    

Themes

(use-package ef-themes
  :custom
  (ef-themes-mixed-fonts t)
  (ef-themes-to-toggle '(ef-eagle ef-autumn))
  :config
  (defun my/adjust-opacity (&optional theme)
    "Make sure opacity is correct for a given theme."
    (interactive)
    (let ((theme (if theme theme (ef-themes--current-theme))))
      (set-frame-parameter nil 'alpha-background
                           (if (member theme ef-themes-light-themes)
                               100
                             80))))

  (advice-add 'ef-themes-load-theme :after #'my/adjust-opacity)

  (with-eval-after-load 'server
    (add-hook 'server-after-make-frame-hook
              (lambda ()
                (ef-themes-load-theme (ef-themes--current-theme)))))

  (with-eval-after-load 'markdown-mode
    (add-hook 'markdown-mode-hook #'variable-pitch-mode))

  (with-eval-after-load 'org
    (advice-add 'ef-themes-load-theme :after #'my/fontify-org-buffers)
    (add-hook 'org-mode-hook #'variable-pitch-mode))

  (ef-themes-select-dark 'ef-autumn))

2. Files / Directories

2.1. Paths

(setopt default-directory "~/")

(defvar personal-data (expand-file-name "personal.el" user-emacs-directory))
(load personal-data)

2.2. Custom File

(use-package cus-edit
  :defer t
  :custom
  (custom-file null-device))

2.3. File Options

(use-package files
  :custom
  (large-file-warning-threshold 10000000)
  (backup-by-copying t)
  :config
  (add-to-list 'backup-directory-alist
               `("." . ,(expand-file-name "backups" user-emacs-directory))))

Revert File-Buffers on Change

(use-package autorevert
  :config
  (global-auto-revert-mode 1))

Revisiting Files

Have emacs remember both what files you recently visited and your position in them

(use-package saveplace
  :config
  (save-place-mode 1))

(use-package savehist
  :config
  (savehist-mode 1))

(use-package recentf
  :config
  (recentf-mode 1))

File Encoding

(setopt buffer-file-coding-system 'utf-8-unix)

2.4. File Management

Dired

(use-package dired
  :commands dired
  :hook
  (dired-mode . dired-hide-details-mode)
  :custom
  (dired-listing-switches "-Ahl --group-directories-first")
  (dired-kill-when-opening-new-dired-buffer t)
  (dired-dwim-target t)
  :config
  (defun my/dired-run-command (command)
    "Run COMMAND on files marked in `dired'."
    (interactive "Crun on marked files: ")
    (let ((file-buffers (cl-remove-if-not #'buffer-file-name (buffer-list))))
      (save-excursion
        (dolist (marked-file (dired-get-marked-files))
          (find-file marked-file)
          (funcall command)
          (unless (member (current-buffer) file-buffers)
            (save-buffer)
            (kill-buffer)))))))
  • Extra Colors
    (use-package diredfl
      :after dired
      :config
      (diredfl-global-mode 1))
    

GPG

Fix bug causing hangups upon re-encryption of files

(use-package epg
  :config
  (fset 'epg-wait-for-status 'ignore))

Trash For Deletion

(setopt delete-by-moving-to-trash t)

(use-package trashed
  :commands trashed
  :custom
  (trashed-sort-key '("Date deleted" . t))
  (trashed-date-format "%Y-%m-%d %H:%M:%S")
  (trashed-use-header-line t))

3. Keybindings

(use-package keymap
  :config
  (defvar my/keybinds '(("M-<tab>" . next-buffer)
                        ("M-<iso-lefttab>" . previous-buffer)
                        ("M-0" . delete-window)
                        ("M-1" . delete-other-windows)
                        ("M-2" . split-window-right)
                        ("M-3" . split-window-below)
                        ("M-]" . next-window-any-frame)
                        ("M-[" . previous-window-any-frame)
                        ("M-#" . dictionary-lookup-definition)
                        ("C-x b" . consult-buffer)
                        ("C-c y" . consult-yank-from-kill-ring)
                        ("C-c r s" . consult-register-store)
                        ("C-c r l" . consult-register-load)
                        ("C-c t" . ef-themes-toggle)
                        ("C-c b k" . kill-buffer-and-window)
                        ("C-c b h" . my/hide-buffer)
                        ("C-c b u" . my/unhide-buffer)
                        ("C-c m v" . my/mpv)
                        ("C-c m a" . my/play-album)))

  (defun my/activate-keybinds (&optional local)
    "Activate personal keybinds stored in `my/keybinds'.
If LOCAL is nil set globally with `keymap-global-set'.
Otherwise set locally with `keymap-local-set'."
    (interactive "P")
    (let ((setter-function (if local 'keymap-local-set 'keymap-global-set)))
      (dolist (key-and-function my/keybinds)
        (funcall setter-function (car key-and-function) (cdr key-and-function)))))

  (my/activate-keybinds))

3.1. Discover Bindings

(use-package which-key
  :if
  (>= emacs-major-version 30)
  :config
  (which-key-mode 1))

3.2. Sticky Keys

(use-package repeat
  :config
  (repeat-mode 1))

4. Completion

4.1. Fuzzy Finding

(use-package orderless 
  :custom
  (completion-styles '(orderless basic))
  (completion-category-defaults nil)
  (completion-category-overrides nil))

4.2. Main Buffer

(use-package corfu 
  :init
  (setopt pgtk-wait-for-event-timeout 0)
  :custom
  (corfu-auto t)
  (corfu-auto-delay 0.2)
  (corfu-auto-prefix 2)
  (corfu-count 8)
  (corfu-popupinfo-delay '(1.5 . 0.5))
  :config
  (add-to-list 'corfu--frame-parameters '(alpha-background . 100))
  (global-corfu-mode 1)
  (corfu-popupinfo-mode 1)

  (with-eval-after-load 'savehist
    (corfu-history-mode 1)
    (add-to-list 'savehist-additional-variables 'corfu-history)))

4.3. Minibuffer

(use-package vertico
  :config
  (vertico-mode 1))

(setopt use-short-answers t)

4.4. Annotations

(use-package marginalia
  :config
  (marginalia-mode 1)
  :after vertico)

5. Navigation

5.1. Consult

(use-package consult
  :custom
  (consult-buffer-sources '(consult--source-hidden-buffer
                            consult--source-modified-buffer
                            consult--source-buffer
                            consult--source-bookmark
                            consult--source-recent-file
                            consult--source-file-register
                            consult--source-project-buffer-hidden
                            consult--source-project-recent-file-hidden
                            consult--source-project-root-hidden)))

5.2. Search

(use-package isearch
  :commands (isearch-forward isearch-backward)
  :custom
  (isearch-lazy-count t))

5.3. Scrolling

(setopt scroll-conservatively 10000
        auto-window-vscroll nil)

5.4. Mouse

Disable the mouse

(use-package disable-mouse
  :custom
  (global-disable-mouse-mode-lighter . nil)
  :hook
  (after-init . global-disable-mouse-mode))

5.5. Buffers

Create a list of "hidden" buffers which are ignored by next-buffer and previous-buffer, but not ignored by e.g. switch-to-buffer.

(unless (boundp '*hidden-buffers*)
  (defvar *hidden-buffers* ()
    "List of buffer names to be ignored by `next-buffer' and `previous-buffer'.
See also `my/hide-buffer' and `hidden-buffer-p'."))

(with-eval-after-load 'savehist
  (add-to-list 'savehist-additional-variables '*hidden-buffers*))

(defun hidden-buffer-p (_window buffer _bury-or-kill)
  "Hide buffers with name in `*hidden-buffers*'.
See also `switch-to-prev-buffer-skip'."
  (cl-find (buffer-name buffer) *hidden-buffers* :test #'string=))

(setopt switch-to-prev-buffer-skip 'hidden-buffer-p)

(defun my/hide-buffer (&optional buffer-name)
  "Adds BUFFER-NAME to `*hidden-buffers*'.
If BUFFER-NAME is nil then the current buffer name is used via `buffer-name'.
See also `my/unhide-buffer'."
  (interactive)
  (cl-pushnew (if buffer-name buffer-name (buffer-name))
              *hidden-buffers*
              :test #'string=))

(defun my/unhide-buffer (&optional buffer-name)
  "Removes BUFFER-NAME from `*hidden-buffers*'.
If BUFFER-NAME is nil then the current buffer name is used via `buffer-name'.
See also `my/hide-buffer'."
  (interactive)
  (setf *hidden-buffers*
        (remove (if buffer-name buffer-name (buffer-name))
                *hidden-buffers*)))

5.6. Windows

(setopt split-width-threshold 90)

5.7. Frames

(use-package server
  :commands server-start)

6. Writing

6.1. Selection

Replace text in active region on insert

(use-package delsel
  :config
  (delete-selection-mode 1))

Narrowing

Enable narrowing commands

(put 'narrow-to-defun  'disabled nil)
(put 'narrow-to-region 'disabled nil)
(put 'narrow-to-page 'disabled nil)

6.2. Dictionary

(use-package ispell
  :custom
  (ispell-personal-dictionary "~/documents/personal-dictionary"))

6.3. Writeroom

(use-package writeroom-mode
  :custom
  (writeroom-width 80)
  (writeroom-fullscreen-effect 'maximized)
  (writeroom-major-modes '(text-mode))
  (writeroom-major-modes-exceptions '(mhtml-mode nxml-mode))
  :config
  (global-writeroom-mode 1))

6.4. Programming

(use-package prog-mode
  :config
  (global-prettify-symbols-mode 1))

Tabs

(setopt indent-tabs-mode nil
        tab-width 4)
  • (un)Tabify Multiple Files
    (use-package tabify
      :config
      (with-eval-after-load 'dired
        (defun my/dired-tabify-files (&optional untabify)
          "Run eitheir `tabify' or `untabify' on marked files in dired.
    See `my/dired-run-command'."
          (interactive "P")
          (let ((tab-function (if untabify #'untabify #'tabify)))
            (my/dired-run-command
             (lambda ()
               (funcall tab-function (point-min) (point-max))))))))
    

LSP

  • Eglot

    Speed up performance (bug?)

    (use-package jsonrpc
      :config
      (fset #'jsonrpc--log-event #'ignore))
    

Compiling

Compile without showing compile buffer

(use-package compile
  :config
  (defun my/compile ()
    (interactive)
    (save-buffer)
    (save-window-excursion (compile compile-command)))

  (defun my/set-compile-command (command)
    (set (make-local-variable 'compile-command)
         command)))

Lisp

  • Parenthesis
    • Balance
      (use-package paredit
        :hook
        ((lisp-mode emacs-lisp-mode scheme-mode) . paredit-mode))
      
    • Rainbow Coloring
      (use-package rainbow-delimiters
        :hook
        ((lisp-mode emacs-lisp-mode scheme-mode) . rainbow-delimiters-mode))
      
    • Indentation
      (use-package aggressive-indent
        :hook
        ((lisp-mode emacs-lisp-mode scheme-mode) . aggressive-indent-mode))
      
  • Emacs Lisp
    (use-package elisp-mode
      :bind
      (:map lisp-interaction-mode-map
            ("C-c C-c" . eval-print-last-sexp)))
    
    (use-package nadvice
      :config
      (defun my/remove-all-advice (sym)
        "Remove all advice from function designated by symbol SYM."
        (interactive)
        (advice-mapc (lambda (advice _props)
                       (advice-remove sym advice))
                     sym)))
    
  • Guile
    (use-package geiser)
    
    (use-package geiser-guile
      :commands geiser-guile
      :custom
      (geiser-guile-load-init-file t)
      :after geiser)
    
  • Common Lisp
    (use-package sly
      :commands sly
      :custom
      (inferior-lisp-program "sbcl")
      (sly-mrepl-history-file-
       (expand-file-name "sly/sly-mrepl-history" user-emacs-directory))
      :config
      (with-eval-after-load 'rainbow-delimiters
        (add-hook 'sly-mrepl-mode-hook 'rainbow-delimiters-mode)))
    

Agda

See agda-unimath for more details.

(use-package agda2-mode
  :defer t
  :init
  (add-to-list 'auto-mode-alist '("\\.lagda.md$" . agda2-mode)))

Go

(use-package go-mode
  :defer t
  :bind
  (:map go-mode-map
        ("C-c C-r" . my/go-run))
  :config
  (defun my/go-run ()
    (interactive)
    (shell-command "go run"))

  (with-eval-after-load 'compile
    (defun my/set-go-compile ()
      (my/set-compile-command "go build"))

    (add-hook 'go-mode-hook #'my/set-go-compile)
    (keymap-set 'go-mode-map "C-c C-c" #'my/compile))  )

6.5. Org

(use-package org
  :defer t
  :hook
  (org-mode . org-indent-mode)
  :bind
  (:map org-mode-map
        ("C-c l" . org-cycle-list-bullet))
  :custom
  (org-directory "~/documents/org/")
  (org-default-notes-file (expand-file-name "notes.org" org-directory))
  (org-agenda-files (list (expand-file-name "agenda/" org-directory)))

  (org-startup-folded t)
  (org-M-RET-may-split-line '((default . nil)))
  (org-insert-heading-respect-content t)
  (org-image-actual-width '(300))

  (org-log-done 'time)
  (org-log-into-drawer t)
  (org-todo-keywords
   '((sequence "TODO(t)" "BLOCKED(b)" "|" "CANCELED(c)" "DONE(d)")))

  (org-edit-src-content-indentation 0)
  (org-babel-python-command "python3")
  :config
  (with-eval-after-load 'font-lock
    (defun my/fontify-org-buffers (&optional _theme)
      "Fontify all org buffers.
Helpful advice for face changing functions."
      (interactive)
      (save-current-buffer
        (dolist (buffer (buffer-list))
          (set-buffer buffer)
          (when (eq major-mode 'org-mode)
            (font-lock-fontify-buffer))))))

  (add-to-list 'org-structure-template-alist '("m" . "src emacs-lisp"))

  (org-babel-do-load-languages
   'org-babel-load-languages
   '((emacs-lisp . t)
     (scheme . t)
     (python . t)
     (shell . t)
     (eshell . t)))

  (defvar my/org-cycle-list-bullet-repeat-keymap
    (define-keymap "l" #'org-cycle-list-bullet))

  (put #'org-cycle-list-bullet 'repeat-map
       'my/org-cycle-list-bullet-repeat-keymap))

Aesthetic Bullets

(use-package org-bullets
  :hook
  (org-mode . org-bullets-mode)
  :after org)

Export

  • Beamer

    Export to pdf presentations via LaTeX beamer

    (use-package ox-beamer
      :after org)
    
  • Publish
    (use-package ox-publish
      :commands org-publish
      :config
      (use-package org-publish-rss
        :custom
        (org-publish-rss-publish-immediately t))
    
      (load (expand-file-name "org-publish.el" user-emacs-directory))
      :after jack)
    

6.6. Markdown

(use-package markdown-mode
  :defer t)

6.7. LaTeX

Compilation

(use-package latex
  :defer t
  :hook
  (LaTeX-mode . my/set-latex-compile)
  :bind
  (:map LaTeX-mode-map
        ("C-c C-c" . my/compile))
  :config
  (defun my/set-latex-compile ()
    (my/set-compile-command (format "pdflatex %s" (buffer-file-name)))))

6.8. Meow (Modal Editing)

(use-package meow
  :disabled t
  :custom
  (meow-expand-hint-remove-delay 0)
  :config
  (defun meow-setup ()
    (setopt meow-cheatsheet-layout meow-cheatsheet-layout-dvorak)
    (meow-leader-define-key
     '("1" . meow-digit-argument)
     '("2" . meow-digit-argument)
     '("3" . meow-digit-argument)
     '("4" . meow-digit-argument)
     '("5" . meow-digit-argument)
     '("6" . meow-digit-argument)
     '("7" . meow-digit-argument)
     '("8" . meow-digit-argument)
     '("9" . meow-digit-argument)
     '("0" . meow-digit-argument)
     '("/" . meow-keypad-describe-key)
     '("?" . meow-cheatsheet))
    (meow-motion-overwrite-define-key
     ;; custom keybinding for motion state
     '("<escape>" . ignore))
    (meow-normal-define-key
     '("0" . meow-expand-0)
     '("9" . meow-expand-9)
     '("8" . meow-expand-8)
     '("7" . meow-expand-7)
     '("6" . meow-expand-6)
     '("5" . meow-expand-5)
     '("4" . meow-expand-4)
     '("3" . meow-expand-3)
     '("2" . meow-expand-2)
     '("1" . meow-expand-1)
     '("-" . negative-argument)
     '(";" . meow-reverse)
     '("," . meow-inner-of-thing)
     '("." . meow-bounds-of-thing)
     '("<" . meow-beginning-of-thing)
     '(">" . meow-end-of-thing)
     '("{" . backward-paragraph)
     '("}" . forward-paragraph)
     '("a" . meow-append)
     '("A" . meow-open-below)
     '("b" . meow-back-word)
     '("B" . meow-back-symbol)
     '("c" . meow-change)
     '("d" . meow-delete)
     '("D" . meow-backward-delete)
     '("e" . meow-line)
     '("E" . meow-goto-line)
     '("f" . meow-find)
     '("F" . meow-find-expand)
     '("g" . meow-cancel-selection)
     '("G" . meow-grab)
     '("h" . meow-left)
     '("H" . meow-left-expand)
     '("i" . meow-insert)
     '("I" . meow-open-above)
     '("j" . meow-join)
     '("k" . meow-kill)
     '("l" . meow-till)
     '("L" . meow-till-expand)
     '("m" . meow-mark-word)
     '("M" . meow-mark-symbol)
     '("n" . meow-next)
     '("N" . meow-next-expand)
     '("o" . meow-block)
     '("O" . meow-to-block)
     '("p" . meow-prev)
     '("P" . meow-prev-expand)
     '("q" . meow-quit)
     '("Q" . meow-goto-line)
     '("r" . meow-replace)
     '("R" . meow-swap-grab)
     '("s" . meow-search)
     '("t" . meow-right)
     '("T" . meow-right-expand)
     '("u" . meow-undo)
     '("U" . meow-undo-in-selection)
     '("v" . meow-visit)
     '("w" . meow-next-word)
     '("W" . meow-next-symbol)
     '("x" . meow-save)
     '("X" . meow-sync-grab)
     '("y" . meow-yank)
     '("z" . meow-pop-selection)
     '("'" . repeat)
     '("<escape>" . ignore)))

  (meow-setup)
  (meow-global-mode 1)
  (meow--remove-modeline-indicator)
  (meow-setup-indicator)

  (with-eval-after-load 'hl-line
    (global-hl-line-mode -1)))

7. System Administration

7.1. Shell / Terminal

Shell

  • Eshell
    (use-package eshell
      :commands eshell
      :hook
      (eshell-mode . (lambda ()
                       (keymap-set eshell-mode-map "C-c M-o" 'my/eshell-clear)))
      :custom
      (eshell-prompt-function
       (lambda ()
         (if (featurep 'ef-themes)
             (let* ((palette (ef-themes--current-theme-palette))
                    (orange (cadr (assoc 'yellow-warmer palette)))
                    (green (cadr (assoc 'green-warmer palette))))
               (format "\n %s\n %s "
                       (propertize (eshell/pwd)
                                   'face `(:foreground ,orange :weight bold))
                       (propertize (if (zerop (user-uid)) "#" "λ")
                                   'face `(:foreground ,green :weight bold))))
           (format "\n %s\n λ " (eshell/pwd)))))
      (eshell-prompt-regexp ".* λ ")
      :config
      (defun my/eshell-clear ()
        (interactive)
        (eshell/clear-scrollback)
        (insert "fastfetch")
        (eshell-send-input)))
    
  • Sudo Shell Command
    (defun my/sudo-shell-command (command)
      "Run COMMAND as root via Tramp."
      (interactive "MShell command (root): ")
      (with-temp-buffer
        (cd "/sudo::/")
        (async-shell-command command)))
    
  • Environment
    (use-package buffer-env
      :commands
      (buffer-env-update buffer-env-reset))
    

Terminal

Allow eshell to run within eat terminals.

(use-package eat
  :commands eat
  :hook
  (eshell-load . eat-eshell-mode))

7.2. Version Control

Magic git frontend

(use-package magit
  :commands magit
  :hook
  (magit-mode . (lambda () (my/activate-keybinds :local))))

7.3. Pinentry

(use-package pinentry
  :custom
  (epg-pinentry-mode 'loopback)
  :config
  (pinentry-start))

7.4. Bluetooth

(use-package bluetooth
  :commands bluetooth-list-devices)

7.5. Documentation

(use-package tldr
  :commands
  (tldr tldr-update-docs))

7.6. Grep

(use-package wgrep
  :commands wgrep)

8. Websites

8.1. HTML Generation

(use-package htmlize)
(use-package jack)

8.2. Personal

See Org Publish section and org-publish.el.

8.3. EWW

(use-package eww
  :defer t
  :commands eww
  :custom
  (eww-default-download-directory "~/downloads"))

9. Messaging

9.1. Mail

Mu4e

(use-package mu4e
  :commands mu4e
  :custom
  (mu4e-drafts-folder "/Drafts")
  (mu4e-sent-folder "/Sent")
  (mu4e-trash-folder "/Trash")

  (mail-user-agent 'mu4e-user-agent)
  (mu4e-get-mail-command (format "INSIDE_EMACS=%s mbsync -a"
                                 emacs-version))

  (mu4e-modeline-support nil))

9.2. RSS

(defun my/make-youtube-feed (channel-url)
  "Create RSS feed url from youtube channel url CHANNEL-URL
and save an appropriate entry for `elfeed-feeds' to the kill ring."
  (interactive "Mchannel url: ")
  (let ((channel-id (car (last (string-split channel-url "/")))))
    (with-temp-buffer
      (print  (list (format "https://www.youtube.com/feeds/videos.xml?channel_id=%s"
                            channel-id)
                    'video)
              (current-buffer))
      (backward-kill-sexp))))

Elfeed

(use-package elfeed
  :commands elfeed
  :custom
  (elfeed-db-directory (expand-file-name "elfeed-db" user-emacs-directory))
  (elfeed-search-filter "@6-months-ago +unread")
  :config
  (defun my/kill-elfeed-search-buffer ()
    (kill-buffer "*elfeed-search*"))

  (load (expand-file-name "feeds.el" user-emacs-directory))
  (advice-add 'elfeed-search-quit-window :after #'my/kill-elfeed-search-buffer))

9.3. Gnus

(use-package gnus
  :defer t)

(use-package gnus-start
  :defer t
  :custom
  (gnus-use-dribble-file nil)
  :after gnus)

10. Media

10.1. Albums

See *-music scripts at mrh dotfiles for more info.

(defun my/play-album ()
  "Play album in directory at point via mpv.

Opens a socket at =/tmp/mpv-socket= to which mpv commands can be sent
(such as pause, play, next, etc.).

Directory name must be the name of the album, contain the song files,
and contain a file =<album-name>--Album.txt= which lists the song files
in desired playing order, separated by newlines.

See https://codeberg.org/mrh/dotfiles/dot-local/bin/ for more info."
  (interactive)
  (let* ((album-path (dired-get-filename))
         (album-name (shell-quote-argument (file-name-nondirectory album-path))))
    (call-process-shell-command
     (format "exec mpv --wayland-app-id=mpv-album --input-ipc-server=/tmp/mpv-socket --playlist=%s/%s--Album.txt"
             album-path album-name)
     nil
     0)))

10.2. Videos

(defun my/mpv (&optional mpv-command)
  "Run custom mpv command on file or url at point."
  (interactive)
  (let ((audio (if (eq major-mode 'dired-mode)
                   (dired-get-filename)
                 (thing-at-point 'url))))
    (call-process-shell-command
     (if mpv-command
         mpv-command
       (format "mpv --profile=1600p --force-window=immediate --pause %s"
               (shell-quote-argument audio)))
     nil
     0)))

Creative Commons License
wumpus.pizza by Alec Barreto is licensed under a Creative Commons Attribution-ShareAlike 4.0 License.