My Emacs Configuration
Table of Contents
Copyright
Copyright 2025 Harry Thompson
This file is part of the Ox Ranch.
The Ox Ranch is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
The Ox Ranch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
You should have received a copy of the GNU General Public License along with the Ox Ranch. If not, see https://www.gnu.org/licenses/.
Introduction
Welcome to my Emacs config. This is literate configuration written in Org-mode using source code blocks tangled with a collection of .el files. These files include various modules, custom libraries, an early-init.el file and an init.el file. The setup is modular: modules are made up of use-package macros for the purposes of standardisation and autoloading. These modules are loaded by the init.el file at startup along with any necessary libraries.
To learn more about literate programming in Org-mode, or indeed literate programming in general, visit https://orgmode.org/manual/Working-with-Source-Code.html (Accessed: 29 April 2025) or read Literate Programming by Donald Knuth.
Startup
Early Initialisation
Prior to searching for a .emacs, .emacs.el or a init.el file in the user’s .emacs.d directory or their home directory, Emacs will search for an early-init.el file in the .emacs.d directory, or in ~/.config/emacs/. Note that there are no alternative files for which Emacs will search for in the home directory.
The early-init.el file is meant for essential configuration prior to the initialisation of Emacs’ GUI; hence the follow source block is rather compact and primarily deals with ensuring that various GUI features remain disabled. Perhaps most interestingly, config-early-init sets the garbage collection threshold to an arbitrarily high number whilst ensuring that an anonymous function lowers the threshold back to its default value is added to emacs-startup-hook.
(package-initialize)
(setopt gc-cons-threshold most-positive-fixnum)
(add-hook 'emacs-startup-hook
(lambda ()
(setopt gc-cons-threshold 800000
gc-cons-percentage 0.2)))
(setopt frame-resize-pixelwise t
frame-title-format "🏺 %b - ScholarMacs - %M 🏺"
frame-inhibit-implied-resize t
use-dialog-box t
initial-buffer-choice t
menu-bar-mode nil
scroll-bar-mode nil
tool-bar-mode nil)
Initialisation
;;; Package Management
(setopt package-archives
'(("gnu" . "https://elpa.gnu.org/packages/")
("nongnu" . "https://elpa.nongnu.org/nongnu/")
("melpa" . "https://melpa.org/packages/")))
(setopt package-archive-priorities
'(("gnu" . 20)
("nongnu" . 10)
("melpa" . -1)))
;; use-package settings
(use-package use-package-ensure-system-package)
;;; Module Loading
(add-to-list 'load-path "~/.emacs.d/Harry-libraries/")
(add-to-list 'load-path "~/.emacs.d/Harry-modules/")
(require 'harry-bibliography)
(require 'harry-header-line)
(require 'harry-language)
(require 'harry-mode-line)
(require 'harry-themes)
(require 'harry-org)
(require 'harry-packaging-module)
(require 'harry-bibliography-module)
(require 'harry-completion-module)
(require 'harry-dired-module)
(require 'harry-essentials-module)
(require 'harry-header-line-module)
(require 'harry-language-module)
(require 'harry-media-module)
(require 'harry-mode-line-module)
(require 'harry-news-module)
(require 'harry-org-module)
(require 'harry-shell-module)
(require 'harry-themes-module)
(require 'harry-version-control-module)
(require 'harry-web-module)
(require 'harry-window-module)
(require 'harry-maths-and-logic-module)
(setq custom-file "~/.emacs.d/emacs-custom.el")
(load custom-file)
Configuration Modules
Bibliography
Biblio
(use-package biblio :ensure t :after ebib :pin melpa :custom (biblio-bibtex-use-autokey t))
Bibtex Mode
(use-package bibtex
:ensure nil
:custom
(bibtex-dialect 'biblatex)
(bibtex-user-optional-fields
'(("keywords" "Keywords to describe the entry" "")
("file" "Link to a document file." "" )
("annote" "Personal annotation (ignored)")))
(bibtex-align-at-equal-sign t))
Ebib
What does this package do?
This is an Emacs-based bibliography manager for .bib files, written by Joost Kremmers, who has authored an extensive accompanying manual. It supports both the BibTeX and BibLaTeX dialects and is well integrated with org-mode. You can find out more at http://joostkremers.github.io/ebib (Accessed: 19 April 2025).
Custom settings
This block sets a variety of user options and aesthetic tweaks. Its most interesting facet is its referencing of a custom function for setting the vertical or horizontal split (harry-set-ebib-window-split), which is invoked when Ebib is entered via the keybind C-c e. It would, of course, be more sensible to attach this directly to one of Ebib’s hooks; however, Ebib lacks a startup hook, and ebib-index-mode-hook is run only as a final step, after the variable controlling the window layout (ebib-window-layout-vertical-split) has already been set.
(use-package ebib
:ensure t
:pin melpa
:custom
(ebib-preload-bib-files '("~/Documents/Bibliography/my.bib"))
(ebib-file-associations
'(("pdf" . find-file)
("xopp" . "xournalpp")))
(ebib-keywords "~/Documents/Bibliography/keywords")
(ebib-file-search-dirs '("~/Documents/Bibliography/PDFs+XOPPs"))
(ebib-bibtex-dialect 'biblatex)
(ebib-notes-storage 'one-file-per-note)
(ebib-notes-directory "~/Documents/Bibliography/Entry Notes/")
(ebib-reading-list-file "~/Documents/Bibliography/Reading List.org")
(ebib-reading-list-template
"** %M %T :ReadingList:\n:PROPERTIES:\n:KEY: %K\n:END:\n")
(ebib-autogenerate-keys t)
(ebib-use-timestamp t)
(ebib-modified-char "Δ") ;
(ebib-reading-list-symbol "🔖")
(ebib-notes-symbol "🗒️")
(ebib-index-columns
'(("Author/Editor" 40 t)
("Year" 6 t)
("Title" 50 t)))
:bind
(("C-c e" . ebib)))
Ebib-biblio
(use-package ebib-biblio
:after (ebib biblio)
:bind (:map ebib-index-mode-map
("B" . ebib-biblio-import-doi)
:map biblio-selection-mode-map
("e" . ebib-biblio-selection-import)))
Completion
Cape
(use-package cape :ensure t :pin gnu :init (add-hook 'completion-at-point-functions #'cape-file))
Completion Preview
(use-package completion-preview :ensure nil :custom (completion-preview-minimum-symbol-length 2) :hook (prog-mode . completion-preview-mode) (text-mode . completion-preview-mode) (comint-mode . completion-preview-mode) (eshell-mode . completion-preview-mode))
Consult
What does this package do?
Consult adds a rich set of search and navigation commands which allow for easy buffer previews, both inter and intra-file navigation, among many other features.
Custom Settings
For the time being I have used the maintainer’s recommendations.
(use-package consult
:ensure t
:pin gnu
;; Replace bindings. Lazily loaded by `use-package'.
:bind (;; C-c bindings in `mode-specific-map'
("C-c M-x" . consult-mode-command)
("C-c h" . consult-history)
("C-c k" . consult-kmacro)
("C-c m" . consult-man)
("C-c i" . consult-info)
([remap Info-search] . consult-info)
;; C-x bindings in `ctl-x-map'
("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command
("C-x b" . consult-buffer) ;; orig. switch-to-buffer
("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame
("C-x t b" . consult-buffer-other-tab) ;; orig. switch-to-buffer-other-tab
("C-x r b" . consult-bookmark) ;; orig. bookmark-jump
("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer
;; Custom M-# bindings for fast register access
("M-#" . consult-register-load)
("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated)
("C-M-#" . consult-register)
;; Other custom bindings
("M-g a" . consult-theme)
("M-y" . consult-yank-pop) ;; orig. yank-pop
;; M-g bindings in `goto-map'
("M-g e" . consult-compile-error)
("M-g f" . consult-flymake) ;; Alternative: consult-flycheck
("M-g g" . consult-goto-line) ;; orig. goto-line
("M-g M-g" . consult-goto-line) ;; orig. goto-line
("M-g o" . consult-outline) ;; Alternative: consult-org-heading
("M-g j" . consult-org-heading)
("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 in `search-map'
("M-s d" . consult-find) ;; Alternative: consult-fd
("M-s c" . consult-locate)
("M-s g" . consult-grep)
("M-s G" . consult-git-grep)
("M-s r" . consult-ripgrep)
("M-s l" . consult-line)
("M-s L" . consult-line-multi)
("M-s k" . consult-keep-lines)
("M-s u" . consult-focus-lines)
;; Isearch integration
("M-s e" . consult-isearch-history)
:map isearch-mode-map
("M-e" . consult-isearch-history) ;; orig. isearch-edit-string
("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string
("M-s l" . consult-line) ;; needed by consult-line to detect isearch
("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch
;; Minibuffer history
:map minibuffer-local-map
("M-s" . consult-history) ;; orig. next-matching-history-element
("M-r" . consult-history)) ;; orig. previous-matching-history-element
;; Enable automatic preview at point in the *Completions* buffer. This is
;; relevant when you use the default completion UI.
:hook (completion-list-mode . consult-preview-at-point-mode)
;; The :init configuration is always executed (Not lazy)
:init
;; Tweak the register preview for `consult-register-load',
;; `consult-register-store' and the built-in commands. This improves the
;; register formatting, adds thin separator lines, register sorting and hides
;; the window mode line.
(advice-add #'register-preview :override #'consult-register-window)
(setq register-preview-delay 0.5)
;; Use Consult to select xref locations with preview
(setq xref-show-xrefs-function #'consult-xref
xref-show-definitions-function #'consult-xref)
;; Configure other variables and modes in the :config section,
;; after lazily loading the package.
:config
;; Optionally configure preview. The default value
;; is 'any, such that any key triggers the preview.
;; (setq consult-preview-key 'any)
;; (setq consult-preview-key "M-.")
;; (setq consult-preview-key '("S-<down>" "S-<up>"))
;; For some commands and buffer sources it is useful to configure the
;; :preview-key on a per-command basis using the `consult-customize' macro.
(consult-customize
consult-theme :preview-key '(:debounce 0.2 any)
consult-ripgrep consult-git-grep consult-grep consult-man
consult-bookmark consult-recent-file consult-xref
consult--source-bookmark consult--source-file-register
consult--source-recent-file consult--source-project-recent-file
;; :preview-key "M-."
:preview-key '(:debounce 0.4 any))
;; Optionally configure the narrowing key.
;; Both < and C-+ work reasonably well.
(setq consult-narrow-key "<")) ;; "C-+"
;; Optionally make narrowing help available in the minibuffer.
;; You may want to use `embark-prefix-help-command' or which-key instead.
;; (keymap-set consult-narrow-map (concat consult-narrow-key " ?") #'consult-narrow-help)
Consult-Denote
(use-package consult-denote
:ensure t
:pin gnu
:bind
(("C-c n f" . consult-denote-find)
("C-c n g" . consult-denote-grep))
:config
(consult-denote-mode 1))
Ecomplete
(use-package ecomplete :ensure nil :defer t :config (ecomplete-setup))
Embark
What does this package do?
Embark has been described as adding a feature-rich ’right-click’ to Emacs, but this does not capture its power. Embark allows for the easy collection and export of candidates to a suitable major mode (e.g. dired), among other features.
Custom Settings
For the time being I have used the maintainer’s recommendations.
(use-package embark
:ensure t
:pin gnu
:bind
(("M-o" . embark-act)
("M-p" . embark-dwim)
("M-[" . embark-export)
("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'
: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)))))
Embark-Consult
What does this package do?
This package is required to make Embark and Consult compatible.
(use-package embark-consult :ensure t :hook (embark-collect-mode . consult-preview-at-point-mode))
Marginalia
What does this package do?
Marginalia provides brief marks of annotations at the margin of the minibuffer for completion candidates in order to convey more information about files and functions.
(use-package marginalia
:ensure t
:pin gnu
:bind (:map minibuffer-local-map
("M-A" . marginalia-cycle))
:hook
(vertico-mode . marginalia-mode))
Orderless
What does this package do?
Orderless is a completion style which matches search candidates based on fuzzy search of space-separated components
(use-package orderless :ensure t :pin gnu :custom (completion-styles '(orderless basic)) (completion-category-overrides '((file (styles basic partial-completion))))) ;; Correct wrapping of the list
Vertico
What does this package do?
Vertico, or VERTical Interactive Completion, is a completion UI which replaces Emacs’ builtin completion framework with a more minimalist design based on Emacs’ built-in functions. Vertico is highly modular and can be extended with a variety of complementary packages such as Orderless and Marginalia.
(use-package vertico :ensure t :pin gnu :custom (vertico-cycle t) (vertico-scroll-margin 0) (vertico-count 5) (vertico-resize t) :hook (after-init . vertico-mode))
Vertico-posframe
(use-package vertico-posframe
:ensure t
:pin gnu
:after vertico
:custom
vertico-posframe-truncate-lines nil
vertico-multiform-commands
:config
(setq vertico-multiform-commands
'((consult-line
posframe
(vertico-posframe-poshandler . posframe-poshandler-frame-top-center)
(vertico-posframe-border-width . 10)
;; NOTE: This is useful when emacs is used in both in X and
;; terminal, for posframe do not work well in terminal, so
;; vertico-buffer-mode will be used as fallback at the
;; moment.
(vertico-posframe-fallback-mode . vertico-buffer-mode))
(consult-outline
posframe
(vertico-posframe-poshandler . posframe-poshandler-frame-top-center)
(vertico-posframe-border-width . 10)
;; NOTE: This is useful when emacs is used in both in X and
;; terminal, for posframe do not work well in terminal, so
;; vertico-buffer-mode will be used as fallback at the
;; moment.
(vertico-posframe-fallback-mode . vertico-buffer-mode))
(consult-org-heading
posframe
(vertico-posframe-poshandler . posframe-poshandler-frame-top-center)
(vertico-posframe-border-width . 10)
;; NOTE: This is useful when emacs is used in both in X and
;; terminal, for posframe do not work well in terminal, so
;; vertico-buffer-mode will be used as fallback at the
;; moment.
(vertico-posframe-fallback-mode . vertico-buffer-mode))
(consult-org-agenda
posframe
(vertico-posframe-poshandler . posframe-poshandler-frame-top-center)
(vertico-posframe-border-width . 10)
;; NOTE: This is useful when emacs is used in both in X and
;; terminal, for posframe do not work well in terminal, so
;; vertico-buffer-mode will be used as fallback at the
;; moment.
(vertico-posframe-fallback-mode . vertico-buffer-mode))
(consult-buffer
posframe
(vertico-posframe-poshandler . posframe-poshandler-frame-top-center)
(vertico-posframe-border-width . 10)
;; NOTE: This is useful when emacs is used in both in X and
;; terminal, for posframe do not work well in terminal, so
;; vertico-buffer-mode will be used as fallback at the
;; moment.
(vertico-posframe-fallback-mode . vertico-buffer-mode))
(t posframe)))
(vertico-multiform-mode 1)
:hook
(vertico-mode . vertico-posframe-mode))
undo-tree
(use-package undo-tree
:ensure t
:pin gnu
:bind ("C-x u" . undo-tree-visualize)
:hook (after-init . global-undo-tree-mode))
Which-key
(use-package which-key :ensure nil :config (which-key-setup-side-window-right) :hook (after-init . which-key-mode))
Dired
Dired-preview
(use-package dired-preview
:ensure t
:pin gnu
:custom
(dired-preview-delay 0.7)
(dired-preview-max-size (expt 2 20))
(dired-preview-ignored-extensions-regexp
(concat "\\."
"\\(gz\\|"
"zst\\|"
"tar\\|"
"xz\\|"
"rar\\|"
"zip\\|"
"iso\\|"
"epub"
"\\)"))
:config
(when (string-equal system-type "windows-nt")
(setq dired-listing-switches "/A:H /O:NG"))
:bind
(:map dired-mode-map
("M-g q" . dired-preview-mode))
:hook (dired-load . dired-preview-global-mode))
Dired
(use-package dired
:ensure nil
:custom
(dired-omit-files "^\\.[^.]+")
:bind
("M-g w" . wdired-change-to-wdired-mode)
("M-g b" . dired-omit-mode)
("M-g d" . dired-hide-details-mode)
:hook ((dired-mode . dired-hide-details-mode)
(dired-mode . dired-omit-mode)
(dired-mode . turn-on-gnus-dired-mode)
(dired-mode . hl-line-mode)))
Essentials
(use-package emacs
:ensure nil
:custom
(delete-by-moving-to-trash t) ; Delete files to trash
(window-combination-resize t) ; Take new window space from all other windows (not just current)
(cursor-type 'bar) ; Sets cursor to the more conventional, narrow line type
(sentence-end-double-space nil) ; Make Emacs view sentences as a series of words prior to a fullstop and a single space, rather than a double space
(doc-view-continuous t) ; The document viewer shows content continuously, so you don’t have to flip between pages.
(recentf-max-menu-items 10) ; Set the maximum number of items to remember
(line-spacing 0.1)
(use-short-answers t)
(pixel-scroll-precision-mode t) ; Make scrolling bearable
(pixel-scroll-precision-interpolate-page t)
(scroll-conservatively 101)
(scroll-margin 3)
(scroll-preserve-screen-position t)
(touch-screen-display-keyboard t)
(mouse-wheel-progressive-speed nil)
(mouse-wheel-scroll-amount '(3 ((shift) . 1)))
(history-length 25)
(shr-inhibit-images t) ; Disable images in eww
(shr-max-width fill-column)
(browse-url-browser-function 'browse-url-default-browser)
(recentf-mode t)
(warning-minimum-level :emergency "Don't show warnings in buffer")
(native-comp-async-report-warnings-errors 'silent)
(default-input-method "greek-babel")
(message-truncate-lines t)
(confirm-kill-emacs #'yes-or-no-p)
(keymap-substitute global-map #'suspend-frame #'quit-window)
(tab-bar-show nil)
(auto-save-interval 20)
(auto-save-timeout 20)
:config
(defun toggle-frame-decoration ()
"Toggle frame decoration on/off."
(interactive)
(let ((undecorated (frame-parameter nil 'undecorated)))
(modify-frame-parameters nil
`((undecorated . ,(not undecorated))))
(message "Frame decoration %s" (if (not undecorated) "disabled" "enabled"))))
(subword-mode 1) ; Navigate camelcase words properly
(which-function-mode 1)
(auto-fill-mode 1)
(savehist-mode 1)
(global-auto-revert-mode 1)
(save-place-mode 1)
(global-visual-line-mode 1)
;;; Mac-specific settings
(when (string-equal system-type "darwin")
(setopt mac-command-key-is-meta nil
mac-command-modifier 'super
mac-option-key-is-meta t
mac-option-modifier 'meta)
(global-unset-key (kbd "s-w"))
(global-unset-key (kbd "s-q")))
(put 'narrow-to-region 'disabled nil)
(put 'narrow-to-page 'disabled nil)
:bind
(("C-<" . undo-redo)
("C-x <up>" . toggle-frame-fullscreen)
("C-x ," . recentf-open-files)
("C-c o f" . harry-toggle-frame-transparency)
("C-c o d" . harry-toggle-frame-decoration)
("C-c o a" . harry-autumn-screensaver)
("C-c o p" . (lambda () (interactive) (dired "~/Documents/Bibliography/PDFs+XOPPs/")))
("C-c o v" . variable-pitch-mode)
("<f12>" . org-mode)))
This block does a number of things:
- It disables the:
- menu-bar
- tool-bar
- scroll-bar
- Renames the frame
- Directs Emacs to put deleted items in the wastebasket rather than deleting them outright
- Enables proportional resizing of window combinations
- Changes the cursor to the more conventional, narrow type
- Enables subword-mode for better navigating camel case words
- Directs Emacs to view a sentence as a string of words before a full stop and a single space a sentence, rather than a double space
- Enables continuous viewing mode in Emacs’ document viewer
- Sets up a toggleable full screen mode
- Enables recentf mode and binds it to ’C-x’ ,
- Enables save-place-mode
- Sets line spacing to 2
- Enables pixel-scroll-precision-mode for smoother scrolling
- Adds margins
- Enables savehist-mode
- Enables global-auto-revert-mode
- Disables images in eww (for security purposes)
- Enables auto-fill-mode
- Enables spell-checking in the built-in commit message editor
- Sets ’C-<’ as redo
- Enables hl-line-mode in Dired and Org-agenda
- Enables Whichkey mode
- Defines a separate terminal function called ’ox-term’ which is identical to the default terminal function, except it loads /bin/bash by default (this is then bound to ’M-g t’)
Essentials: Cleanup keybind documentation
I might want to remove the listings for individual keybinds and instead simply state that the blocks sets up a number of keybinds.
Header Line
(use-package harry-header-line
:ensure nil
:bind ("C-c o z" . harry-header-line-mode))
Language
Citeproc
(use-package citeproc :ensure t :pin melpa :defer t :after (ox))
Delsel
What does this package do?
This package provides delete-selection-mode for more intuitive editing
Custom Settings
This macro adds delete-selection-mode to the after-init hook, which incidentally defers the loading of delsel.
(use-package delsel :ensure nil :hook (after-init . delete-selection-mode))
Denote
(use-package denote
:ensure t
:custom
(denote-directory (expand-file-name "~/Documents/notes/"))
;; Do not read keywords from files. The only source is the `denote-known-keywords'.
(denote-infer-keywords t)
;; Automatically rename Denote buffers when opening them so that
;; instead of their long file name they have, for example, a literal
;; "[D]" followed by the file's title. Read the doc string of
;; `denote-rename-buffer-format' for how to modify this.
(denote-rename-buffer-mode 1)
(denote-templates
`((lecture . ,(concat "* Introduction"
"\n\n"
"* Main Points"
"\n\n"
"* Summary"
"\n\n"
"* Further Reading"))))
:hook (dired-mode . denote-dired-mode)
:bind
(("C-c n n" . denote)
("C-c n r" . denote-rename-file)
("C-c n l" . denote-link)
("C-c n b" . denote-backlinks)
("C-c n d" . denote-dired)
("C-c n g" . denote-grep)))
Ispell
(use-package ispell :ensure nil :defer t :custom (ispell-program-name "aspell") (ispell-dictionary "en_GB"))
jinx
(use-package jinx
:ensure t
:pin gnu
:hook (emacs-startup . global-jinx-mode)
:bind (("M-$" . jinx-correct)
("C-M-$" . jinx-languages)))
Logos
(use-package logos
:ensure t
:pin gnu
:custom
(logos-outlines-are-pages t)
(logos-hide-cursor nil)
(logos-hide-mode-line t)
(logos-hide-header-line t)
(logos-hide-buffer-boundaries nil)
(logos-outline-regexp-alist '((emacs-lisp-mode . "^;;;+ ") (org-mode . "^\\*+ +")
(markdown-mode . "^\\#+ +") (ibuffer-mode . "^.*$")
(dired-mode . "^.*$")))
:bind (("C-c o l" . logos-focus-mode)
([remap narrow-to-region] . logos-narrow-dwim)
([remap forward-page] . logos-forward-page-dwim)
([remap backward-page] . logos-backward-page-dwim))
:hook ((text-mode . logos-focus-mode)
(prog-mode . logos-focus-mode)
(pdf-view-mode . logos-focus-mode)
(dired-mode . logos-focus-mode)
(wdired-mode . logos-focus-mode)
(image-mode . logos-focus-mode)
(eww-mode . logos-focus-mode)
(eshell-mode . logos-focus-mode)
(term-mode . logos-focus-mode)
(eat-mode . logos-focus-mode)
(shell-mode . logos-focus-mode)
(ibuffer-mode . logos-focus-mode)
(Info-mode . logos-focus-mode)
(doc-view-mode . logos-focus-mode)
(org-mode . logos-focus-mode)
(gnus-mode . logos-focus-mode)
(emms-playlist-mode . logos-focus-mode)
(emms-browser-mode . logos-focus-mode)
(logos-focus-mode . (lambda ()
(if (eq major-mode 'org-mode)
(setopt logos-olivetti t)
(setopt logos-olivetti nil))))))
Lorem-ipsum
(use-package lorem-ipsum :pin nongnu :ensure t :defer t)
Olivetti
What does this package do?
Olivetti provides a simple minor mode which sets the window’s margins automatically according to the user’s preference.
Custom Settings
This block configures the widths of the margins set by Olivetti and ensures that visual-line-mode’s entry state is recalled. I have also set olivetti-style to fancy, though I am not entirely sure what this does.
(use-package olivetti
:ensure t
:pin melpa
:custom
(olivetti-body-width 75)
(olivetti-minimum-body-width 70)
(olivetti-recall-visual-line-mode-entry-state nil)
(olivetti-style nil)
:hook
(message-mode . olivetti-mode)
(emms-playlist-mode . olivetti-mode)
(emms-browser-mode . olivetti-mode)
(gnus-mode . olivetti-mode)
(dired-mode . olivetti-mode)
(eshell-mode . olivetti-mode)
:bind
("C-c o o" . olivetti-mode))
Pdf-Tools
(use-package pdf-tools :pin nongnu :ensure t :defer 2 :custom (pdf-cache-image-limit 125) :config (pdf-tools-install) :hook (pdf-view-mode . pdf-view-themed-minor-mode))
writegood-mode
(use-package writegood-mode
:ensure t
:pin nongnu
:custom
(writegood-weasel-words
(append writegood-weasel-words
'("arguably" "essentially" "various" "certain"))) ; Add philosophy
:bind ("C-c w" . writegood-mode))
Maths & Logic
calc
(use-package calc
:ensure nil
:bind ("C-c o ~" . calc))
cdlatex
(use-package cdlatex :pin nongnu :ensure :defer t)
Media
EMMS
(use-package emms
:ensure-system-package (vlc mpv yt-dlp)
:ensure t
:pin gnu
:custom
(emms-player-list '(emms-player-vlc emms-player-ogg123))
(emms-info-functions '(emms-info-native emms-info-ogginfo))
(emms-player-vlc-parameters '("--intf=rc" "--no-dbus"))
(emms-source-file-default-directory "~/Music/")
(emms-browser-covers #'emms-browser-cache-thumbnail-async)
(emms-browser-thumbnail-small-size 64)
(emms-browser-thumbnail-medium-size 128)
(emms-player-list '(emms-player-mpv emms-player-vlc)) ; Add mpv
(emms-player-mpv-parameters '("--quiet" "--really-quiet" "--no-audio-display"))
:config
(emms-all)
(emms-mpris-enable)
:bind
(("<f8>" . emms-pause)
("C-c C-= g" . emms-playlist-mode-go)
("C-c C-= b" . emms-browser)
("<f9>" . emms-next)
("<f7>" . emms-previous)
("C-c C-= s" . emms-show)
("C-c C-= r" . emms-toggle-repeat-track)))
Mode Line
Mode Line
The block defines the mode-line format by using the variables defined in harry-modeline.el.
(use-package harry-mode-line
:ensure nil
:custom
(mode-line-format
'(:eval
(list
"%e 🍵✒️ "
;; The first part is the left-aligned portion with padding
my-mode-line-buffer-name
" "
my-mode-line-file-position
" "
my-mode-line-file-delta-status
" | "
my-mode-line-lambda
my-mode-line-mode
(or (cdr (assoc major-mode my-major-mode-line-mode-indicators)) "")
" | "
(if which-function-mode
(if (which-function)
(propertize (which-function)
'face '(:weight bold)))
(concat "which-function mode is disabled 👎🏻 | "))))))
TMR
(use-package tmr
:ensure t
:pin gnu
:defer t
:config
(define-key global-map (kbd "C-c t") #'tmr-prefix-map)
(setq tmr-sound-file "/usr/share/sounds/freedesktop/stereo/alarm-clock-elapsed.oga"
tmr-notification-urgency 'normal
tmr-description-list 'tmr-description-history)
:hook
(org-mode . tmr-mode-line-mode))
News
SMTP
(use-package emacs
:ensure nil
:custom
(message-signature "Harry G. Thompson")
(user-mail-address "harrygthompson@posteo.net")
(user-full-name "Harry G. Thompson")
(mail-user-agent 'gnus-user-agent)
:config
;; SMTP (TLS)
(setq smtpmail-servers-requiring-authorization "posteo.de")
(setq send-mail-function 'smtpmail-send-it
smtpmail-smtp-server "posteo.de"
smtpmail-stream-type 'ssl
smtpmail-smtp-service 465
smtpmail-auth-credentials "~/.authinfo.gpg"
smtpmail-smtp-user "harrygthompson@posteo.net"
smtpmail-debug-info t))
; (setq mml-secure-openpgp-signers '("7DF8F8E0A52926AA9FB45CB3976A0BDD15B89B7C")) )
;(add-hook 'message-send-hook 'mml-secure-message-sign-pgpmime))
Gnus
- Gnus Startup
(autoload 'gnus "gnus" "Start Gnus" t) (with-eval-after-load 'gnus (require 'gnus-notifications)) (global-set-key (kbd "C-c o g") 'gnus) (setopt gnus-init-file "~/.emacs.d/Gnus/.gnus") (setopt gnus-inhibit-startup-message t)
- Gnus
(setopt gnus-summary-default-high-score 3000 gnus-summary-default-low-score 2000 gnus-use-dribble-file nil gnus-select-method '(nnnil "")) ;;; IMAP (TLS) (setopt gnus-secondary-select-methods '((nnimap "posteo.de" (nnimap-address "imap.posteo.de") (nnimap-server-port 993) (nnimap-stream ssl) (nnimap-authinfo-file "~/.authinfo.gpg") (nnimap-inbox "INBOX") ; "Inbox" folder (nnimap-sent "Sent") ; "Sent" folder (nnimap-drafts "Drafts") ; "Drafts" folder (nnimap-trash "Trash")))) ; "Deleted Items" folder ;; Archive outgoing email in Sent folder (setq gnus-message-archive-method '(nnimap "posteo.de") gnus-message-archive-group "Sent") ;; Set email expiry target to Trash on Posteo and wait for 30 days (setopt nnmail-expiry-target "nnimap+posteo:Trash") (setopt nnmail-expiry-wait 7) ; A moo moo week 🐂 (setq nnimap-expunge t) (setq nnimap-record-commands t) ;;; startup (setopt gnus-activate-level 2) (add-hook 'gnus-group-mode-hook 'gnus-topic-mode) (add-hook 'gnus-summary-mode-hook 'hl-line-mode) ;;; Demon (gnus-demon-add-handler 'gnus-demon-scan-mail 1 t) (gnus-demon-init) (add-hook 'gnus-after-getting-new-news-hook 'gnus-notifications) (setq gnus-use-full-window nil) ; Don't take over entire frame (setq gnus-summary-line-format "%U%R%z %(%&user-date; %-15,15f %B%s%)\n") (setq gnus-user-date-format-alist '((t . "%Y-%m-%d %H:%M"))) ; Clean date format (setq gnus-summary-thread-gap-function 'gnus-summary-insert-dummy-line) (setq gnus-summary-ignore-thread '("^Re:" "^Fwd:")) ; Clean up thread prefixes ;; Simplified group line format (setq gnus-group-line-format "%M%S%p%P%5y: %(%g%)\n")
Message
(use-package message :ensure nil :defer t :custom (message-mail-alias-type 'ecomplete) (message-self-insert-commands nil) (message-expand-name-standard-ui t) :hook (message-sent . message-put-addresses-in-ecomplete))
Org
org-cite-overlay
(use-package org-cite-overlay :ensure nil :pin melpa :hook (org-mode . org-cite-overlay-mode))
org-fragtog
(use-package org-fragtog :ensure nil :pin melpa :hook (org-mode . org-fragtog-mode))
Org Transclusion
(use-package org-transclusion :ensure t :pin gnu :after org)
Org General Tweaks
(use-package org
:ensure-system-package zip
:ensure nil
:custom
;;; Capture
(org-capture-templates
'(("t" "Todo" entry (file+headline "~/Documents/Personal Files/Personal Todo.org" "Tasks")
"* TODO %?\n %i\nCreated: %U")
("j" "Learning Journal" entry (file+datetree "~/Documents/Personal Files/Learning Journal.org")
"* %?\nEntered on %U\n %i\n %a")
("J" "Personal Journal" entry (file+datetree "~/Documents/Personal Files/Personal Journal.org")
"* %?\nEntered on %U\n %i\n ")))
;;; Clock
(org-clock-idle-time 5)
;;; Org bibliographic and exporter settings
(org-export-default-language "en-gb")
(org-cite-global-bibliography '("/home/Harry/Documents/Bibliography/my.bib")) ; Set your .bib file here
(org-cite-csl-styles-dir "~/Documents/Bibliography/CSLFiles/") ; Set the CSL styles directory (path to where your .csl files are located)
(org-cite-csl-locales-dir "/home/Harry/Documents/Bibliography/CSLFiles/locales/")
(org-cite-export-processors
'((t csl)))
(org-format-latex-options
'(:foreground default :background default :scale 0.5 :html-foreground
"Black" :html-background "Transparent" :html-scale
1.0 :matchers ("begin" "$1" "$" "$$" "\\(" "\\[")))
(TeX-command-default "LaTeX")
(TeX-clean-confirm nil) ; Automatically clean without confirmation
(org-odt-preferred-output-format "docx")
(org-cite-csl-link-cites t)
(org-latex-hyperref-template
"\\hypersetup{
pdfauthor={%a},
pdftitle={%t},
pdfkeywords={%k},
pdfsubject={%d},
pdfcreator={%c},
pdflang={%L},
colorlinks=false,
linkcolor=black,
urlcolor=black,
citecolor=black,
pdfborder={0 0 0}
}")
;;; Org editing and visual tweaks
(org-pretty-entities t)
(org-use-sub-superscripts "{}")
(org-support-shift-select t)
(org-hide-emphasis-markers t)
(org-startup-with-inline-images nil)
(org-tags-column 0)
(org-src-window-setup 'current-window)
; (org-auto-align-tags nil)
;;; Export settings
(org-export-with-toc nil) ; No table of contents
(org-export-with-section-numbers nil) ; No section numbers
(org-export-with-smart-quotes t) ; Use smart quotes
;;; misc
(org-log-into-drawer t)
(org-log-done 'time)
:config
(require 'oc-csl)
(add-to-list 'org-modules 'org-habit)
;;; Org-babel
;; active Babel languages
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(shell . t)
(gnuplot . t)))
:bind (("C-c 9" . org-capture)
("M-+" . org-word-counter))
:hook ((org-mode . variable-pitch-mode)
(org-babel-post-tangle . harry-post-tangle-headers-elisp)
(org-babel-post-tangle . harry-post-tangle-headers-shell)))
Org Agenda
(use-package org-agenda
:ensure nil
:custom
(org-agenda-tags-column -77)
(org-agenda-files '("~/Documents/Open University/Org mode notes/A350.org"
"~/Documents/Open University/Org mode notes/A340.org"
"~/Documents/Personal Files/Personal Todo.org"
"~/Documents/Bibliography/Reading List.org"
"~/GNU-Ranch/Literate-configs/Emacs-config.org"
))
(org-agenda-custom-commands
'(("d" "Daily Agenda"
((agenda "" ((org-agenda-span 'day)))))))
(org-agenda-remove-tags t)
(org-agenda-scheduled-leaders
'("[S] : " "[S] x%3d d.: "))
(org-agenda-deadline-leaders
'("[D] : " "[D] +%3d d.: " "[D] -%3d d.: "))
:config
(add-to-list 'display-buffer-alist '("\\*Agenda Commands\\*" (display-buffer-in-side-window) (side . right) (window-width . 0.4)))
(add-to-list 'display-buffer-alist '("\\*Org Agenda\\*" (display-buffer-in-side-window) (side . right) (window-width . 0.5)))
(setq org-latex-create-formula-image-program 'dvisvgm)
:bind
(("C-c a" . org-agenda)
("C-c t" . (lambda()
(interactive)
(org-agenda nil "a"))))
:hook (org-agenda-mode . hl-line-mode))
Org Crypt
(use-package org-crypt
:ensure nil
:custom
(org-tags-exclude-from-inheritance '("crypt"))
(org-crypt-key "976A0BDD15B89B7C")
:config
(org-crypt-use-before-save-magic)
;; Auto-saving does not cooperate with org-crypt.el: so you need to
;; turn it off if you plan to use org-crypt.el quite often. Otherwise,
;; you'll get an (annoying) message each time you start Org.
;; To turn it off only locally, you can insert this:
;;
;; # -*- buffer-auto-save-file-name: nil; -*-
:bind (("C-c o q" . org-decrypt-entry)
("C-c o w" . org-encrypt-entry)))
Org Habit
(use-package org-habit :ensure nil :defer t)
Org-modern
What does this package do?
Org-modern adjusts Org’s various elements (heading markers, agenda faces and the tables) in order to make them appear more modern and visually appealing.
Custom Settings
For the time being the settings are identical to the defaults except for the heading icons which are set to stars, rather than folding indicators
(use-package org-modern
:ensure t
:pin gnu
:custom
(org-modern-star 'replace)
(org-modern-tag-faces (quote (("OU" :background "light blue"
:foreground "black")
("Life" :background "medium spring green" :foreground "black")
("MA" :background "black" :foreground "white")
("Latin" :background "salmon" :foreground "black")
("Gym" :background "medium aquamarine" :foreground "black"))))
:hook
(org-mode . global-org-modern-mode))
Org Remark
(use-package org-remark-global-tracking-mode
:ensure nil
:hook after-init
:config
(use-package org-remark-info :ensure nil :after info :config
(org-remark-info-mode +1))
(use-package org-remark-eww :ensure nil :after eww :config
(org-remark-eww-mode +1)))
(use-package org-remark
:pin gnu
:ensure t
:bind (("C-c n m" . org-remark-mark)
("C-c n l" . org-remark-mark-line)
:map org-remark-mode-map
("C-c n o" . org-remark-open)
("C-c n ]" . org-remark-view-next)
("C-c n [" . org-remark-view-prev)
("C-c n r" . org-remark-remove)
("C-c n d" . org-remark-delete)))
Packaging
(use-package system-packages :ensure t :pin gnu)
Shells
Eat
(use-package eat :ensure t :defer t :pin nongnu :hook (eshell-first-time-mode . eat-eshell-visual-command-mode) (eshell-first-time-mode . eat-eshell-mode))
Eshell
- Aliases
alias u cd .. alias docs cd ~/Documents alias ranch cd ~/GNU-Ranch alias ll ls -l $@* alias autumnbonsailive cbonsai -l -k 202,3,214,11 alias autumnbonsai cbonsai -k 202,3,214,11 alias autumnscreensaver cbonsai -S -k 202,3,214,11 alias autumnscreensaverslow cbonsai -S -k 202,3,214,11 -t 2
- General
(use-package eshell :ensure nil :custom (eshell-bad-command-tolerance 10) :bind ("M-g u" . eshell))
Term
(use-package term
:ensure nil
:defer t
:bind ("M-g t" . (lambda () (interactive) (term "/bin/bash"))))
Shell
(use-package shell
:ensure nil
:bind ("M-g y" . shell))
Themes
Doric-themes
(use-package doric-themes :ensure t :pin gnu :defer nil :config (doric-themes-select 'doric-obsidian))
Ef-themes
What does this package do?
This package provides a set of themes similar to Modus, but with a good deal more flair.
Custom Settings
The themes have been configured to bring them in line with the configurations for Modus Themes (see Modus Themes)
(use-package ef-themes
:ensure nil
:pin gnu
:defer t
:custom
(ef-themes-mixed-fonts t)
(ef-themes-variable-pitch-ui t)
(ef-themes-disable-other-themes t)
(ef-themes-headings
(quote ((1 variable-pitch 1.4)
(2 variable-pitch 1.3)
(3 variable-pitch 1.2)
(4 variable-pitch 1.1)
(t light variable-pitch 1.1)
((agenda-date) 1.3)
((agenda-structure-variable-pitch light 1.8))))))
Fontaine
(use-package fontaine
:ensure t
:pin gnu
:custom
(fontaine-presets
'((regular
:default-family "Dejavu Sans Mono"
:default-weight normal
:default-height 140
:fixed-pitch-family "Dejavu Sans Mono"
:fixed-pitch-weight normal
:fixed-pitch-height 140
:fixed-pitch-serif-family "DejaVu Sans Mono"
:fixed-pitch-serif-weight normal
:fixed-pitch-serif-height 100
:variable-pitch-family "Dejavu Sans"
:variable-pitch-weight normal
:variable-pitch-height 1.12
:mode-line-active-family "Dejavu Sans"
:mode-line-inactive-family "Dejavu Sans"
:bold-family nil
:bold-weight bold
:italic-family nil
:italic-slant italic
:line-spacing 2)
(regular-serif
:inherit regular
:variable-pitch-family "Dejavu Serif")
(libertine
:inherit regular
:variable-pitch-family "Linux Libertine O")
(biolinum
:inherit regular
:variable-pitch-family "Linux Biolinum O")
(ioesvka
:default-family "Iosevka"
:default-weight normal
:default-height 140
:fixed-pitch-family "Iosevka"
:fixed-pitch-weight normal
:fixed-pitch-height 140
:fixed-pitch-serif-family "Iosevka"
:fixed-pitch-serif-weight normal
:fixed-pitch-serif-height 100
:variable-pitch-height 1.12
:mode-line-active-family "Iosevka"
:mode-line-inactive-family "Iosevka"
:bold-family nil
:bold-weight bold
:italic-family nil
:italic-slant italic
:line-spacing 2)
(libertine/ioesvka
:inherit ioesvka
:variable-pitch-family "Linux Libertine O")
(biolinum/ioesvka
:inherit ioesvka
:variable-pitch-family "Linux Biolinum O")))
:hook
((after-init . fontaine-mode)
(after-init . (lambda ()
(fontaine-set-preset (or (fontaine-restore-latest-preset) 'regular)))))
:bind (("C-c o i" . fontaine-set-preset)
("C-c o ," . fontaine-toggle-preset)))
Modus Themes
(use-package emacs
:ensure nil
:custom
(modus-themes-italic-constructs t)
(modus-themes-mixed-fonts t)
(modus-themes-variable-pitch-ui t)
(modus-themes-headings
'((0 . (1.75))
(1 . (variable-pitch 1.4))
(2 . (variable-pitch 1.3))
(3 . (variable-pitch 1.2))
(4 . (variable-pitch 1.1))
(t . (variable-pitch light 1.1))
((agenda-date) 1.3)
((agenda-structure-variable-pitch light 1.8))))
(modus-themes-to-toggle '(modus-operandi modus-vivendi))
(modus-themes-disable-other-themes t)
;;; Overrides
;; Slightly nicer looking mode line
(modus-operandi-tinted-palette-overrides
'((bg-mode-line-active bg-ochre)
(fg-mode-line-active fg-main)))
;; Invisible Fringe and source blocks
(modus-themes-common-palette-overrides
'((bg-prose-block-contents unspecified)
(bg-prose-block-delimiter unspeficied)
(fg-prose-block-delimiter fg-dim)
(fringe unspecified)))
; :config
; (load-theme 'modus-operandi)
:bind ("<f5>" . modus-themes-toggle))
Show Font
(use-package show-font
:ensure t
:pin gnu
:bind
(("C-c s f" . show-font-select-preview)
("C-c s t" . show-font-tabulated)))
Spacious Padding
What does this package do?
This package adds a global-minor-mode which increases the padding of Emacs’ UI elements.
Custom Settings
The widths have been altered slightly—largely to minimise internal-border-widths. I have also defined an interactive function which toggles spacious-padding-subtle-mode-line before refreshing spacious-padding-mode; this function is bound to ’C-c o t’.
(use-package spacious-padding
:ensure t
:pin gnu
:custom
(spacious-padding-subtle-mode-line t)
(spacious-padding-widths
'( :internal-border-width 15
:header-line-width 4
:mode-line-width 6
:tab-width 4
:right-divider-width 30
:scroll-bar-width 8
:fringe-width 8))
:bind (("C-c o t" . set-spacious-padding-subtle-mode-line)
("C-c o s" . spacious-padding-mode))
:hook (after-init . spacious-padding-mode))
Splash Screen
Here the default scratch buffer is replaced with a splash screen featuring a tasteful ASCII art GNU—credited to Vijay Kumar Bagavath Singh—and a welcome message. Both the art and the message are set to clear upon user input.
(use-package harry-splash-screen
:ensure nil
:hook ((emacs-startup . my-ascii-art)
(emacs-startup . olivetti-mode)
(post-command . clear-scratch-buffer-on-input)))
Version Control
VC
(use-package vc :ensure nil :ensure-system-package git :defer t :hook (vc-git-log-edit-mode . auto-fill-mode))
Web
Window
Ibuffer
(use-package ibuffer
:ensure nil
:bind ("M-g ," . ibuffer))
Libraries
Bibliography Library
Ebib
(defun harry-set-ebib-window-split ()
"Set `ebib-window-vertical-split' based on window width."
(if (< (window-width) 130)
(progn
(setq ebib-window-vertical-split nil)
(setq ebib-index-window-size 20))
(progn
(setq ebib-window-vertical-split t)
(setq ebib-index-window-size 110))))
Header Line Library
This block adds a header line which displays the current file path and vc branch. It can be enabled and disabled with ’M-x harry-header-line-mode’ or ’M-g h’.
(define-minor-mode harry-header-line-mode
"A minor mode which displays a header line with the current file path and vc branch."
:lighter " Harry's Header Line"
(if harry-header-line-mode
(setq header-line-format
'(:eval
(list
(abbreviate-file-name default-directory)
" "
(when vc-mode "🪵")
vc-mode)
()))
(setq-local header-line-format nil)))
Language Library
Logos
(defun harry-logos-hide-mode-line ()
"Hides or shows the mode line while in logos-focus-mode."
(interactive)
logos-set-mode-arg '
(if logos-focus-mode
(if logos-hide-mode-line
(progn
(setq-local logos-hide-mode-line nil)
(logos-focus-mode -1)
(logos-focus-mode 1))
(setq-local logos-hide-mode-line t)
(logos-focus-mode -1)
(logos-focus-mode 1))))
Mode Line Library
Mode Line Indicators
This block defines the basic variables to be used as indicators within the mode-line.
(defvar my-mode-line-buffer-name (propertize "%b" 'face 'bold)
"The format for the buffer name in the mode line.")
(defvar my-mode-line-file-position (propertize "(%o)" 'face 'shadow)
"The format for the file position in the mode line.")
(defvar my-mode-line-file-delta-status (propertize "Δ: %&" 'face 'shadow))
(defvar my-mode-line-lambda (propertize "λ " 'face 'shadow)
"The format for the lambda symbol in the mode line.")
(defvar my-mode-line-mode (propertize "%m" 'face 'bold)
"The format for the major mode in the mode line.")
(defvar my-mode-line-global-string (propertize " %M" 'face 'bold)
"The format for the global status in the mode line.")
(dolist (construct '(my-mode-line-buffer-name
my-mode-line-file-position
my-mode-line-file-delta-status
my-mode-line-lambda
my-mode-line-mode
my-major-mode-line-mode-indicators))
(put construct 'risky-local-variable t))
Mode Line Major Mode Icons
This block defines a list of UTF emojis to be associated with various major modes.
(defvar my-major-mode-line-mode-indicators
'((org-mode . " 📚")
(org-agenda-mode . " 🗓️")
(bibtex-mode . " 📜")
(lisp-mode . " 🍯")
(python-mode . " 🐍")
(java-mode . " ☕")
(perl-mode . " 🐫")
(c-mode . " 👴🏼")
(c++-mode . " 👴🏼")
(eww-mode . " 🧭")
(emms-playlist-mode . " 🎹")
(emms-browser-mode . " 💽")
(gnus-group-mode . " 📫")
(gnus-summary-mode . " 📬")
(gnus-article-mode . " 📰")
(message-mode . " 📧")
(dired-mode . " 💾")
(ibuffer-mode . " 🪟")
"A list of mode-specific indicators for the mode line."))
Themes Library
Cbonsai
(defun harry-autumn-screensaver (&optional size)
"Split frame with eshell on right running autumn screensaver.
SIZE sets the approximate width percentage for the right window (default 35)."
(interactive "P")
(let* ((default-size 27)
(size-percent (or (and size (prefix-numeric-value size)) default-size))
(left-width (round (* (frame-width) (- 1 (/ size-percent 100.0)))))
(buffer-name "*Autumn Screensaver*"))
;; Kill existing Autumn Screensaver buffer if it exists
(when (get-buffer buffer-name)
(message "Killing existing Autumn Screensaver buffer...")
(kill-buffer buffer-name))
(delete-other-windows)
(split-window-horizontally left-width)
(other-window 1)
;; Error handling for eshell creation
(condition-case err
(progn
(eshell)
(rename-buffer buffer-name)
(eshell-return-to-prompt)
(insert "autumnscreensaverslow")
(eshell-send-input)
(other-window -1)
(message "Autumn screensaver started successfully!"))
(error
(message "Error starting autumn screensaver: %s" (error-message-string err))
(other-window -1)
(delete-window (get-buffer-window buffer-name))))))
Frame Transparency
This block adds a setting which makes the frame transparent
(defvar harry-frame-transparency 86 "Transparency value for the frame when toggled.")
(defun harry-toggle-frame-transparency ()
"Toggle frame transparency between transparent and opaque."
(interactive)
(if (eq (frame-parameter nil 'alpha-background) harry-frame-transparency)
(progn
(set-frame-parameter nil 'alpha-background 100) ; Opaque
(message "Frame is now opaque."))
(progn
(set-frame-parameter nil 'alpha-background harry-frame-transparency) ; Transparent
(message "Frame is now transparent."))))
Frame Decoration
(defun harry-toggle-frame-decoration ()
"Toggle frame decoration on/off."
(interactive)
(let ((undecorated (frame-parameter nil 'undecorated)))
(modify-frame-parameters nil
`((undecorated . ,(not undecorated))))
(message "Frame decoration %s" (if (not undecorated) "disabled" "enabled"))))
Spacious Padding
(defun set-spacious-padding-subtle-mode-line ()
"Toggles spacious-padding-subtle-mode-line"
(interactive)
(setq spacious-padding-subtle-mode-line
(not spacious-padding-subtle-mode-line))
(spacious-padding-mode -1)
(spacious-padding-mode 1))
Splash Screen
(defun center-text (text)
"Center TEXT within the entire Emacs window width."
(let* ((window-width (window-body-width)) ; Get the width of the window
(ascii-width (apply 'max (mapcar 'length (split-string text "\n"))))) ; Max length of any line in the ASCII art
(if (> window-width ascii-width)
(let ((padding (max 0 (/ (- window-width ascii-width) 2)))) ; Calculate padding
(mapconcat (lambda (line)
(concat (make-string padding ?\ ) line)) ; Add padding to each line
(split-string text "\n" t)
"\n"))
text))) ; If the text is wider than the window, just return it unmodified
(defun my-ascii-art ()
"Insert custom ASCII art into the *scratch* buffer."
(flymake-mode 0)
(interactive)
(let ((ascii-art "
_-`````-, ,- '- .\n
.' .- - | | - -. `.\n
/.' / `. \n
:/ : _... ..._ `` :\n
:: : /._ .`:'_.._\\. || :\n
:: `._ ./ ,` : \\ . _.'' .\n
`:. / | -. \\-. \\\\_ /\n
\:._ _/ .' .@) \\@) ` `\\ ,.'\n
_/,--' .- .\\,-.`--`.\n
,'/'' (( \\ ` )
/'/' \\ `-' (
'/'' `._,-----'\n
''/' .,---'\n
''/' ;:\n
''/'' ''/\n
''/''/''\n
'/'/'\n
`;"))
(let ((welcome-message "\nWelcome to Harry's Emacs! Press any key to clear this scratch buffer. Credit for the art goes to Vijay Kumar Bagavath Singh <3"))
(with-current-buffer "*scratch*"
(erase-buffer)
(insert (center-text ascii-art)) ; Centered ASCII art
(insert (center-text welcome-message)) ; Center the welcome message
(goto-char (point-min))))))
;; Automatically clear *scratch* buffer when you start typing
(defvar my-scratch-cleared nil "Flag to check if *scratch* has been cleared.")
(defun clear-scratch-buffer-on-input ()
"Clear the *scratch* buffer when you start typing."
(when (and (eq (current-buffer) (get-buffer "*scratch*"))
(not my-scratch-cleared)
(not (= (point) (point-min)))) ; Only clear if you are not at the beginning (start typing)
(erase-buffer)
(setq my-scratch-cleared t))) ; Flag to prevent multiple clears
Org Library
General
- An Org Friendly Word Counter
(defun org-word-counter () "Count words in region/buffer, estimate pages, and reading time. Excludes lines beginning with * or #. Prints result in echo area. Credit goes to Chris Maiorana" (interactive) (let* ((start (if (use-region-p) (region-beginning) (point-min))) (end (if (use-region-p) (region-end) (point-max))) (word-count (save-excursion (goto-char start) (let ((count 0) (inhibit-field-text-motion t)) (while (< (point) end) (beginning-of-line) (unless (looking-at-p "^[*#<]") (let ((line-end (line-end-position))) (while (re-search-forward "\\w+\\W*" line-end t) (setq count (1+ count))))) (forward-line 1)) count))) (words-per-page 400) (reading-speed 215) (page-count (/ (+ word-count words-per-page -1) words-per-page)) (reading-time (/ (+ word-count reading-speed -1) reading-speed))) (message "%d words, ~%d pages, ~%d min read" word-count page-count reading-time)))
Babel
- Post-tangle Headers
(defun harry-post-tangle-headers-elisp () (message "running in %s" (buffer-file-name)) (cond ((f-ext? (buffer-file-name) "el") (goto-char (point-min)) (insert ";;; -*- lexical-binding: t -*- ;; Copyright (C) 2025 by Harry G. Thompson ;; This file is part of the Ox Ranch. ;; The Ox Ranch is free software: you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as ;; published by the Free Software Foundation, either version 3 of ;; the License, or (at your option) any later version. ;; The Ox Ranch is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;; General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with the Ox Ranch. If not, see <https://www.gnu.org/licenses/>.\n\n")) (t nil)) (save-buffer)) (defun harry-post-tangle-headers-shell () (message "running in %s" (buffer-file-name)) (cond ((f-ext? (buffer-file-name) "sh") (goto-char (point-min)) (forward-line 1) (open-line 2) (insert " # Copyright 2025 Harry Thompson # This file is part of the Ox Ranch. # The Ox Ranch is free software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of # the License, or (at your option) any later version. # The Ox Ranch is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # You should have received a copy of the GNU General Public License # along with the Ox Ranch. If not, see <https://www.gnu.org/licenses/>.\n\n")) (t nil)) (save-buffer))