Emacs config in progress
My Emacs config is now literate; here’s the core.
Variable Definitions
;; TODO: use an actual variable
(setq-default my-sync-dir (expand-file-name "~/Sync"))
Package Management
straight
handles package management.
Bootstrap straight
;;;;;
;; STRAIGHT
;; bootstrap the pkg manager
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name
"straight/repos/straight.el/bootstrap.el"
(or (bound-and-true-p straight-base-dir)
user-emacs-directory)))
(bootstrap-version 7))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))
Configure straight
;; Fetch use-package from straight
(straight-use-package 'use-package)
;; Configure use-package to install pkgs using straight
(setq straight-use-package-by-default t)
Utility Packages
(use-package a)
;; file manipulation
(use-package f)
;; string manipulation
(use-package s)
;; other helpers
(use-package dash)
Editor Config
;; hide warnings, only let errors through
(setq warning-minimum-level :error)
;; auto-close delimiters
(electric-pair-mode 1)
;; no menu bar
(when (fboundp 'menu-bar-mode)
(menu-bar-mode -1))
;; and no tool bar
(when (fboundp 'tool-bar-mode)
(tool-bar-mode -1))
Backup Files
Backup and temporary files are stored in
$XDG_CACHE_HOME/emacs/backups
if the env variable $XDG_CACHE_HOME
is defined, else they’re stored in ~/.cache/emacs/backups
.
(let ((backup-dir (expand-file-name "emacs/backups"
(or (getenv "XDG_CACHE_HOME") "~/.cache"))))
(setq backup-directory-alist `(("." . ,backup-dir)))
(setq auto-save-file-name-transforms `((".*" ,backup-dir t))))
Theme and Font
(use-package dracula-theme
:config (load-theme 'dracula t))
;; WARNING: Depends on Fira Code being installed!
(set-frame-font "Fira Code" nil t)
Evil vim
(use-package evil
:init
(setq evil-want-keybinding nil)
(setq evil-want-integration t)
:config
(evil-mode 1))
(use-package evil-collection
:after (evil)
:custom
(evil-collection-setup-minibuffer t)
(evil-collection-calendar-want-org-bindings t)
:straight (evil-collection :type git
:host github
:repo "emacs-evil/evil-collection"))
;; Surround: wrap selections with delimiters
;; https://github.com/emacs-evil/evil-surround
(use-package evil-surround
:ensure t
:config
(global-evil-surround-mode t))
General leader keybindings
;; helpers
(defmacro my-launchers (&rest args)
"Add global app launchers defined by ARGS under `SPC-o`"
`(general-nmap
:prefix "SPC o" ,@args))
(use-package general
:config
(general-evil-setup)
;; global top-level bindings
(general-nmap
:prefix "SPC"
"SPC" 'switch-to-buffer
":" 'counsel-M-x
"u" 'universal-argument)
;; global app launchers
(my-launchers
"e" 'eshell)
;; global window keybindings
(general-nmap
:prefix "SPC w"
"d" 'delete-window
"s" 'split-window-below
"v" 'split-window-right
"h" 'windmove-left
"j" 'windmove-down
"k" 'windmove-up
"l" 'windmove-right)
;; global buffer keybindings
(general-nmap
:prefix "SPC b"
"b" 'switch-to-buffer
"d" 'kill-this-buffer
"D" 'kill-buffer)
;; global file keybindings
(general-nmap
:prefix "SPC f"
"f" 'find-file
;; SPC-f-r: open recent files
"r" 'recentf-open
"s" 'save-buffer
"d" 'delete-file)
;; global help keybindings
(general-nmap
:prefix "SPC h"
"v" 'describe-variable
"f" 'describe-function
"k" 'describe-key)
;; TODO per-lang evals
(general-nmap
:prefix ", e"
"b" 'eval-buffer
"f" 'eval-defun
"s" 'eval-last-sexp))
Command pallete
The command pallete selector is ivy
with counsel
shims:
(use-package ivy
:custom
(ivy-use-virtual-buffers t)
(enable-recursive-minibuffer t)
(ivy-count-format "(%d/%d) ")
(ivy-wrap t)
:config
(define-key ivy-minibuffer-map (kbd "C-j") 'ivy-next-line)
(define-key ivy-minibuffer-map (kbd "C-k") 'ivy-previous-line)
(ivy-mode))
(use-package counsel
:after (ivy)
:config
(counsel-mode))
Autocompletion
;; COMPLETION
(use-package corfu
:init
(setq tab-always-indent 'complete)
:config
(define-key corfu-map (kbd "C-j") 'corfu-next)
(define-key corfu-map (kbd "C-k") 'corfu-previous)
(corfu-mode 1))
Snippets
yasnippet
provides snippets.
Use the global normal mode binding SPC i s
to insert a snippet via
yas-insert-snippet
.
;; setup yasnippet
(use-package yasnippet
:init
(general-nmap
:prefix "SPC i"
"s" #'yas-insert-snippet)
(yas-minor-mode 1))
;; and all the snippets
(use-package yasnippet-snippets
:after (yasnippet))
Window Management
Popup handling
popper
keeps popup windows like eshell
or Warnings from getting
out of hand.
(use-package popper
:init
(setq popper-reference-buffers
'("\\*Messages\\*"
"\\*eshell\\*"
"\\*Deft\\*"
"Output\\*$"
"\\*Async Shell Command\\*"
"\\*chatgpt\\*"
"\\*Warnings\\*"
help-mode
compilation-mode))
(popper-mode +1)
(popper-echo-mode +1)
:config
(general-nmap
:prefix "SPC"
"~" 'popper-toggle)
(general-nmap
:prefix "SPC P"
"P" 'popper-toggle
"p" 'popper-cycle
"t" 'popper-toggle-type))