Commit Diff


commit - f7b2b6448ece01abff443194f8f0a079f5796c3e
commit + 9c43bba67ceb79cb34f77ed711a4669cf969e0d4
blob - ae2c346fd96231deab35fb488636f7d26bb9ab48
blob + b3d04c243e01df2c0d661a0edb46dbabb9d065af
--- .gitignore
+++ .gitignore
@@ -10,3 +10,6 @@
 /recentf
 /emacs-backup
 /bookmarks
+/straight
+/undo-fu-session/
+/*.elc
blob - a86726932891d104b1d7838e2ad977136097a1ca
blob + 53afeb1336026bba6cbbe77414c9460a81a9bd99
--- early-init.el
+++ early-init.el
@@ -7,6 +7,33 @@
       native-comp-async-report-warnings-errors 'silent
       inhibit-startup-echo-area-message (user-login-name)
       frame-resize-pixelwise t
+      package-enable-at-startup nil
+      straight-repository-branch "develop"
+      straight-check-for-modifications '(check-on-save find-when-checking)
+      straight-use-package-by-default nil
+      straight-vc-git-default-clone-depth 1
       default-frame-alist '((fullscreen . maximized)
-                            (ns-appearance . dark)
-                            (ns-transparent-titlebar . t)))
+                            (font . "PragmataPro Mono-14")
+                            (internal-border-width . 0)
+                            (undecorated . t)))
+
+(when (featurep 'pgtk)
+  (setq default-frame-alist
+        (append '((inhibit-double-buffering . nil)
+                  (use-native-comp . t))
+                default-frame-alist)))
+
+(defvar bootstrap-version)
+(let ((bootstrap-file
+       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
+      (bootstrap-version 6))
+  (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))
+
+(straight-use-package 'use-package)
blob - /dev/null
blob + 190800e7c5adb5f2661c0794bdcb39f6d6cf1f0b (mode 644)
--- /dev/null
+++ config.org
@@ -0,0 +1,687 @@
+:PROPERTIES:
+:header-args:emacs-lisp: :tangle init.el
+:END:
+
+#+title: Emacs Configuration
+#+date: 2026-07-20
+#+filetags: :emacs:
+
+* Early setup
+
+#+begin_src emacs-lisp :tangle early-init.el
+  ;;; early-init.el --- Early startup tweaks  -*- lexical-binding: t; -*-
+
+  (setq bedrock--initial-gc-threshold gc-cons-threshold
+        gc-cons-threshold 10000000
+        byte-compile-warnings '(not obsolete)
+        warning-suppress-log-types '((comp) (bytecomp))
+        native-comp-async-report-warnings-errors 'silent
+        inhibit-startup-echo-area-message (user-login-name)
+        frame-resize-pixelwise t
+        package-enable-at-startup nil
+        straight-repository-branch "develop"
+        straight-check-for-modifications '(check-on-save find-when-checking)
+        straight-use-package-by-default nil
+        straight-vc-git-default-clone-depth 1
+        default-frame-alist '((fullscreen . maximized)
+                              (font . "PragmataPro Mono-14")
+                              (internal-border-width . 0)
+                              (undecorated . t)))
+
+  (when (featurep 'pgtk)
+    (setq default-frame-alist
+          (append '((inhibit-double-buffering . nil)
+                    (use-native-comp . t))
+                  default-frame-alist)))
+
+  (defvar bootstrap-version)
+  (let ((bootstrap-file
+         (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
+        (bootstrap-version 6))
+    (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))
+
+  (straight-use-package 'use-package)
+#+end_src
+
+* Core settings
+
+#+begin_src emacs-lisp
+  (when (< emacs-major-version 29)
+    (error "Emacs configuration only works with Emacs 29 and newer; you have version %s"
+           emacs-major-version))
+
+  (setopt initial-major-mode 'fundamental-mode)
+  (setopt inhibit-startup-screen t)
+  (setopt initial-scratch-message nil)
+  (setopt display-time-default-load-average nil)
+
+  (setopt auto-revert-avoid-polling t)
+  (setopt auto-revert-interval 5)
+  (setopt auto-revert-check-vc-info t)
+  (global-auto-revert-mode 1)
+
+  (savehist-mode 1)
+  (recentf-mode 1)
+
+  (windmove-default-keybindings 'control)
+
+  (setopt sentence-end-double-space nil)
+
+  (when (display-graphic-p)
+    (context-menu-mode -1)
+    (tool-bar-mode -1)
+    (menu-bar-mode -1)
+    (scroll-bar-mode -1)
+    (set-frame-parameter nil 'font "PragmataPro Mono-14"))
+
+  (unless (display-graphic-p)
+    (xterm-mouse-mode 1))
+
+  (cua-mode 1)
+
+  (add-hook 'prog-mode-hook #'display-line-numbers-mode)
+  (setopt display-line-numbers-width 3)
+
+  (add-hook 'text-mode-hook #'visual-line-mode)
+
+  (dolist (hook '(text-mode-hook prog-mode-hook))
+    (add-hook hook #'hl-line-mode))
+
+  (setopt tab-bar-show 1)
+#+end_src
+
+* Backup and autosave
+
+#+begin_src emacs-lisp
+  (defun bedrock--backup-file-name (fpath)
+    "Return a backup path for FPATH, creating parent dirs if needed."
+    (let* ((backup-root-dir (concat user-emacs-directory "emacs-backup/"))
+           (file-path (replace-regexp-in-string "[A-Za-z]:" "" fpath))
+           (backup-file-path (replace-regexp-in-string
+                              "//" "/"
+                              (concat backup-root-dir file-path "~"))))
+      (make-directory (file-name-directory backup-file-path) t)
+      backup-file-path))
+  (setopt make-backup-file-name-function #'bedrock--backup-file-name)
+
+  (let ((auto-save-dir (expand-file-name "auto-saves/" "~/.cache/emacs"))
+        (lock-dir (expand-file-name "locks/" "~/.cache/emacs")))
+    (make-directory auto-save-dir t)
+    (make-directory lock-dir t)
+    (setopt auto-save-file-name-transforms `((".*" ,auto-save-dir t)))
+    (setopt lock-file-name-transforms `((".*" ,lock-dir t))))
+#+end_src
+
+* UI
+
+#+begin_src emacs-lisp
+  (use-package modus-themes
+    :straight t
+    :demand t
+    :config
+    (load-theme 'modus-operandi t))
+
+  (use-package ef-themes
+    :straight t
+    :commands ef-themes-select)
+
+  (use-package which-key
+    :straight t
+    :config (which-key-mode))
+
+  (add-to-list 'tab-bar-format 'tab-bar-format-align-right 'append)
+  (add-to-list 'tab-bar-format 'tab-bar-format-global 'append)
+  (setopt display-time-format "%a %F %T")
+  (setopt display-time-interval 1)
+  (display-time-mode 1)
+#+end_src
+
+* Scrolling
+
+#+begin_src emacs-lisp
+  (setopt mouse-wheel-tilt-scroll t)
+  (setopt mouse-wheel-flip-direction t)
+  (setopt mouse-wheel-scroll-amount '(1 ((shift) . 5) ((control) . 0)))
+  (setopt mouse-wheel-progressive-speed nil)
+
+  (blink-cursor-mode -1)
+  (pixel-scroll-precision-mode 1)
+  (setopt scroll-margin 4)
+  (setopt scroll-conservatively 101)
+  (setopt scroll-up-aggressively 0.01)
+  (setopt scroll-down-aggressively 0.01)
+  (setopt auto-window-vscroll nil)
+#+end_src
+
+* Appearance
+
+#+begin_src emacs-lisp
+  (use-package lin
+    :straight t
+    :hook ((eshell-mode . lin-mode)
+           (dired-mode . lin-mode)
+           (org-mode . lin-mode)))
+
+  (use-package pulsar
+    :straight t
+    :config
+    (pulsar-global-mode))
+
+  (use-package diff-hl
+    :straight t
+    :hook ((prog-mode . diff-hl-mode)
+           (org-mode . diff-hl-mode))
+    :config
+    (global-diff-hl-show-hunk-mouse-mode))
+#+end_src
+
+* Completion
+
+#+begin_src emacs-lisp
+  (setopt completion-cycle-threshold 3)
+  (setopt tab-always-indent 'complete)
+
+  (keymap-set minibuffer-mode-map "TAB" #'minibuffer-complete)
+
+  (use-package vertico
+    :straight t
+    :init (vertico-mode))
+
+  (with-eval-after-load 'vertico
+    (keymap-set vertico-map "M-DEL" #'vertico-directory-delete-word))
+
+  (use-package marginalia
+    :straight t
+    :config (marginalia-mode))
+
+  (use-package orderless
+    :straight t
+    :config (setopt completion-styles '(orderless)))
+
+  (use-package consult
+    :straight t
+    :bind (("C-x b" . consult-buffer)
+           ("M-y"   . consult-yank-pop)
+           ("M-s r" . consult-ripgrep)
+           ("M-s l" . consult-line)
+           ("M-s L" . consult-line-multi)
+           ("M-s o" . consult-outline)
+           :map isearch-mode-map
+           ("M-e"   . consult-isearch-history)
+           ("M-s e" . consult-isearch-history)
+           ("M-s l" . consult-line)
+           ("M-s L" . consult-line-multi))
+    :custom
+    (consult-narrow-key "<"))
+
+  (use-package embark
+    :straight t
+    :demand t
+    :after consult
+    :bind (("C-c a" . embark-act))
+    :init
+    (defun bedrock-avy-action-embark (pt)
+      "Run `embark-act' at PT, then restore the window avy jumped from."
+      (unwind-protect
+          (save-excursion
+            (goto-char pt)
+            (embark-act))
+        (select-window
+         (cdr (ring-ref avy-ring 0))))
+      t)
+    (setf (alist-get ?. avy-dispatch-alist) #'bedrock-avy-action-embark))
+
+  (use-package embark-consult
+    :straight t
+    :after (embark consult))
+
+  (use-package corfu
+    :straight t
+    :init (global-corfu-mode)
+    :bind (:map corfu-map
+                ("SPC" . corfu-insert-separator)))
+
+  (with-eval-after-load 'corfu
+    (setopt corfu-popupinfo-delay '(0.25 . 0.1)
+            corfu-popupinfo-hide nil)
+    (corfu-popupinfo-mode))
+
+  (use-package corfu-terminal
+    :straight t
+    :if (not (display-graphic-p))
+    :config (corfu-terminal-mode))
+
+  (use-package cape
+    :straight t
+    :init
+    (add-to-list 'completion-at-point-functions #'cape-dabbrev)
+    (add-to-list 'completion-at-point-functions #'cape-file))
+
+  (use-package kind-icon
+    :straight t
+    :if (display-graphic-p)
+    :after corfu
+    :config
+    (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))
+
+  (use-package wgrep
+    :straight t
+    :config (setopt wgrep-auto-save-buffer t))
+#+end_src
+
+* Movement
+
+#+begin_src emacs-lisp
+  (use-package avy
+    :straight t
+    :demand t
+    :bind (("C-c j" . avy-goto-line)
+           ("s-j"   . avy-goto-char-timer)))
+#+end_src
+
+* Evil
+
+#+begin_src emacs-lisp
+  (use-package evil
+    :straight t
+    :custom
+    (evil-want-keybinding nil)
+    (evil-respect-visual-line-mode t)
+    (evil-undo-system 'undo-redo)
+    (evil-want-C-u-scroll t)
+    :config
+    (evil-mode)
+    (add-hook 'git-commit-setup-hook #'evil-insert-state)
+    (evil-set-initial-state 'eat-mode 'emacs))
+
+  (use-package evil-collection
+    :straight t
+    :after evil
+    :config (evil-collection-init))
+
+  (use-package evil-surround
+    :straight t
+    :after evil
+    :config (global-evil-surround-mode))
+
+  (use-package evil-commentary
+    :straight t
+    :after evil
+    :config (evil-commentary-mode))
+
+  (use-package evil-org
+    :straight t
+    :after org
+    :hook (org-mode . evil-org-mode)
+    :config
+    (require 'evil-org-agenda)
+    (evil-org-agenda-set-keys))
+#+end_src
+
+* Undo
+
+#+begin_src emacs-lisp
+  (use-package undo-fu
+    :straight t
+    :custom
+    (undo-fu-allow-undo-in-region t)
+    (undo-fu-undo-command 'undo-fu-only-undo)
+    (undo-fu-redo-command 'undo-fu-only-redo)
+    :bind (("C-/" . undo-fu-only-undo)
+           ("C-?" . undo-fu-only-redo)
+           ("M-/" . undo-fu-only-redo-all)))
+
+  (use-package undo-fu-session
+    :straight t
+    :custom
+    (undo-fu-session-incompatible-files '("\\.gpg$"))
+    (undo-fu-session-directory
+     (expand-file-name "undo-fu-session/" user-emacs-directory))
+    :config
+    (undo-fu-session-global-mode))
+
+  (use-package vundo
+    :straight t
+    :bind ("C-c u" . vundo))
+
+  (with-eval-after-load 'evil
+    (keymap-set evil-normal-state-map "u" #'undo-fu-only-undo)
+    (keymap-set evil-normal-state-map "C-r" #'undo-fu-only-redo))
+#+end_src
+
+* Help
+
+#+begin_src emacs-lisp
+  (use-package helpful
+    :straight t
+    :bind (("C-h f" . helpful-callable)
+           ("C-h v" . helpful-variable)
+           ("C-h k" . helpful-key)
+           ("C-h x" . helpful-command)
+           ("C-h d" . helpful-at-point)))
+#+end_src
+
+* Terminals
+
+#+begin_src emacs-lisp
+  (use-package eshell
+    :straight (:type built-in)
+    :init
+    (defun bedrock-setup-eshell ()
+      "Bind `C-r' to `consult-history' in `eshell-mode'."
+      (keymap-set eshell-mode-map "C-r" #'consult-history))
+    :hook (eshell-mode . bedrock-setup-eshell))
+
+  (use-package eat
+    :straight t
+    :custom
+    (eat-term-name "xterm")
+    :config
+    (eat-eshell-mode)
+    (eat-eshell-visual-command-mode))
+#+end_src
+
+* Development core
+
+#+begin_src emacs-lisp
+  (setq major-mode-remap-alist
+        '((yaml-mode . yaml-ts-mode)
+          (bash-mode . bash-ts-mode)
+          (json-mode . json-ts-mode)
+          (css-mode . css-ts-mode)
+          (python-mode . python-ts-mode)))
+
+  (add-hook 'prog-mode-hook #'electric-pair-mode)
+
+  (use-package project
+    :straight (:type built-in)
+    :custom (project-mode-line t))
+
+  (use-package magit
+    :straight t
+    :bind (("C-x g" . magit-status)))
+#+end_src
+
+* Language modes
+
+#+begin_src emacs-lisp
+  (use-package yaml-mode
+    :straight t)
+
+  (use-package json-mode
+    :straight t)
+
+  (use-package nix-mode
+    :straight t
+    :mode "\\.nix\\'")
+
+  (use-package go-mode
+    :straight t)
+
+  (use-package zig-mode
+    :straight t)
+
+  (use-package rust-mode
+    :straight t)
+
+  (use-package elixir-mode
+    :straight t)
+#+end_src
+
+* LSP
+
+#+begin_src emacs-lisp
+  (use-package eglot
+    :straight (:type built-in)
+    :custom
+    (eglot-send-changes-idle-time 0.1)
+    (eglot-extend-to-xref t)
+    :config (fset #'jsonrpc--log-event #'ignore))
+#+end_src
+
+* Templates
+
+#+begin_src emacs-lisp
+  (use-package tempel
+    :straight t
+    :bind (("M-*" . tempel-insert)
+           ("M-+" . tempel-complete)
+           :map tempel-map
+           ("C-c RET"  . tempel-done)
+           ("M-<down>" . tempel-next)
+           ("M-<up>"   . tempel-previous))
+    :init
+    (defun tempel-setup-capf ()
+      "Add `tempel-expand' to `completion-at-point-functions' locally."
+      (add-hook 'completion-at-point-functions #'tempel-expand -1 'local))
+    (add-hook 'prog-mode-hook #'tempel-setup-capf)
+    (add-hook 'text-mode-hook #'tempel-setup-capf))
+#+end_src
+
+* Lisp
+
+#+begin_src emacs-lisp
+  (use-package slime
+    :straight t
+    :custom
+    (inferior-lisp-program "sbcl")
+    (slime-lisp-implementations '((sbcl ("sbcl"))))
+    :bind (:map slime-mode-map
+                ("C-c C-d C-s" . slime-describe-symbol)
+                ("C-c C-d C-a" . slime-apropos))
+    :config
+    (slime-setup '(slime-fancy slime-quicklisp slime-asdf)))
+#+end_src
+
+* Notes
+
+#+begin_src emacs-lisp
+  (setopt denote-directory (expand-file-name "~/.nb/notes"))
+
+  (use-package denote
+    :straight t
+    :custom
+    (denote-file-type 'org)
+    (denote-known-keywords '("daily" "comp" "music" "misc"))
+    (denote-infer-keywords nil)
+    :config
+    (denote-rename-buffer-mode))
+
+  (use-package denote-journal
+    :straight t
+    :after denote
+    :custom
+    (denote-journal-keyword "journal")
+    (denote-journal-file-type 'org))
+
+  (use-package denote-org
+    :straight t
+    :after denote)
+#+end_src
+
+* Org
+
+#+begin_src emacs-lisp
+  (setopt org-directory (expand-file-name "~/.nb/notes")
+          org-agenda-files (list org-directory)
+          org-default-notes-file (expand-file-name "todo.org" org-directory))
+
+  (setopt org-refile-targets '((org-agenda-files :maxlevel . 3))
+          org-refile-use-outline-path 'file
+          org-outline-path-complete-in-steps nil)
+
+  (setopt org-todo-keywords
+          '((sequence "TODO(t)" "WAITING(w@/!)" "STARTED(s!)" "|" "DONE(d!)" "OBSOLETE(o@)"))
+          org-log-done 'time
+          org-log-into-drawer t)
+
+  (setopt org-capture-templates
+          '(("t" "task" entry (file+headline org-default-notes-file "Inbox")
+             "* TODO %?\n%U\n%i")
+            ("j" "journal" plain (file denote-journal-path-to-new-or-existing-entry)
+             "%?\n%U\n%i")))
+
+  (setopt org-agenda-start-with-log-mode 'clockcheck
+          org-agenda-prefix-format
+          '((agenda . " %i %-12:c%?-12t% s")
+            (todo   . " %i %-12:c")
+            (tags   . " %i %-12:c")
+            (search . " %i %-12:c"))
+          org-agenda-time-grid
+          '((daily today require-timed)
+            (800 1000 1200 1400 1600 1800 2000)
+            " ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄")
+          org-agenda-current-time-string "◀── now")
+
+  (setopt org-special-ctrl-a/e t
+          org-special-ctrl-k t
+          org-return-follows-link t
+          org-image-actual-width nil
+          org-startup-with-inline-images t
+          org-hide-emphasis-markers t)
+
+  (setopt org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id)
+
+  (setopt org-export-with-smart-quotes t)
+
+  (use-package org
+    :straight (:type built-in)
+    :hook ((org-mode . visual-line-mode)
+           (org-mode . variable-pitch-mode))
+    :bind (:map global-map
+                ("C-c l s" . org-store-link)
+                ("C-c l i" . org-insert-link-global)
+                ("C-c a"   . org-agenda)
+                ("C-c c"   . org-capture)
+           :map org-mode-map
+                ("TAB" . org-cycle))
+    :config
+    (require 'oc-csl)
+    (add-to-list 'org-export-backends 'md)
+    (setf (alist-get 'file org-link-frame-setup) 'find-file)
+    (setopt org-startup-indented t
+            org-cycle-separator-lines 2))
+
+  (use-package org-appear
+    :straight t
+    :hook (org-mode . org-appear-mode))
+
+  (use-package org-super-agenda
+    :straight t
+    :after org
+    :config
+    (org-super-agenda-mode))
+#+end_src
+
+* Markdown
+
+#+begin_src emacs-lisp
+  (use-package markdown-mode
+    :straight t
+    :hook (markdown-mode . visual-line-mode))
+#+end_src
+
+* Key bindings
+
+#+begin_src emacs-lisp
+  (defvar-keymap file-prefix-map
+    :doc "Prefix map for file commands.")
+  (keymap-set global-map "C-c f" file-prefix-map)
+  (keymap-set file-prefix-map "f" #'project-find-file)
+  (keymap-set file-prefix-map "r" #'consult-recent-file)
+  (keymap-set file-prefix-map "g" #'consult-ripgrep)
+
+  (defvar-keymap git-prefix-map
+    :doc "Prefix map for git commands.")
+  (keymap-set global-map "C-c g" git-prefix-map)
+  (keymap-set git-prefix-map "g" #'magit-status)
+  (keymap-set git-prefix-map "d" #'xref-find-definitions)
+  (keymap-set git-prefix-map "D" #'xref-find-definitions-other-window)
+  (keymap-set git-prefix-map "i" #'eglot-find-implementation)
+  (keymap-set git-prefix-map "t" #'eglot-find-typeDefinition)
+  (keymap-set git-prefix-map "r" #'xref-find-references)
+  (keymap-set git-prefix-map "s" #'eldoc-doc-buffer)
+  (keymap-set git-prefix-map "a" #'eglot-code-actions)
+  (keymap-set git-prefix-map "l" #'consult-flymake)
+  (keymap-set git-prefix-map "p" #'flymake-goto-prev-error)
+  (keymap-set git-prefix-map "n" #'flymake-goto-next-error)
+  (keymap-set git-prefix-map "f" #'eglot-format)
+
+  (defvar-keymap refactor-prefix-map
+    :doc "Prefix map for refactor commands.")
+  (keymap-set global-map "C-c r" refactor-prefix-map)
+  (keymap-set refactor-prefix-map "r" #'eglot-rename)
+
+  (defvar-keymap tree-prefix-map
+    :doc "Prefix map for tree / navigation commands.")
+  (keymap-set global-map "C-c t" tree-prefix-map)
+  (keymap-set tree-prefix-map "r" #'consult-imenu)
+
+  (defvar-keymap denote-prefix-map
+    :doc "Prefix map for denote commands.")
+  (keymap-set global-map "C-c n" denote-prefix-map)
+  (keymap-set denote-prefix-map "n" #'denote)
+  (keymap-set denote-prefix-map "j" #'denote-journal-new-or-existing-entry)
+  (keymap-set denote-prefix-map "l" #'denote-insert-link)
+  (keymap-set denote-prefix-map "L" #'denote-add-links)
+  (keymap-set denote-prefix-map "o" #'denote-open-or-create)
+  (keymap-set denote-prefix-map "b" #'denote-backlinks)
+  (keymap-set denote-prefix-map "r" #'denote-rename-file)
+  (keymap-set denote-prefix-map "d" #'denote-sort-dired)
+  (keymap-set denote-prefix-map "t" #'org-agenda-list)
+  (keymap-set denote-prefix-map "c" #'org-capture)
+
+  (with-eval-after-load 'corfu
+    (keymap-set corfu-map "C-b"   #'corfu-scroll-down)
+    (keymap-set corfu-map "C-f"   #'corfu-scroll-up)
+    (keymap-set corfu-map "C-SPC" #'corfu-complete)
+    (keymap-set corfu-map "C-e"   #'corfu-quit)
+    (keymap-set corfu-map "RET"   #'corfu-complete))
+#+end_src
+
+* Personal extras
+
+#+begin_src emacs-lisp
+  (setopt select-enable-clipboard t
+          select-enable-primary t
+          save-interprogram-text-before-kill t)
+
+  (use-package clipetty
+    :straight t
+    :hook (after-init . clipetty-mode))
+
+  (with-eval-after-load 'eglot
+    (add-to-list 'eglot-server-programs
+                 '(purescript-mode . ("pnpx" "purescript-language-server" "--stdio")))
+    (add-to-list 'eglot-server-programs
+                 '((markdown-mode text-mode tex-mode typst-mode org-mode)
+                   . ("harper-ls" "--stdio"))))
+
+  (use-package zoom-window
+    :straight t
+    :bind ("C-x z" . zoom-window-zoom))
+#+end_src
+
+* Timers
+
+#+begin_src emacs-lisp
+  (use-package tmr
+    :straight t
+    :bind (("C-c t c" . tmr)
+           ("C-c t l" . tmr-tabulated-view)
+           ("C-c t k" . tmr-remove)
+           ("C-c t s" . tmr-stop)))
+#+end_src
+
+* Finalize
+
+#+begin_src emacs-lisp
+  (setq gc-cons-threshold (or bedrock--initial-gc-threshold 800000))
+#+end_src
blob - 1d8ed62a35ab0b8f8645176fbf50e911a277a153 (mode 644)
blob + /dev/null
--- extras/base.el
+++ /dev/null
@@ -1,112 +0,0 @@
-;;; extras/base.el --- Base enhancements  -*- lexical-binding: t; -*-
-
-(use-package avy
-  :ensure t
-  :demand t
-  :bind (("C-c j" . avy-goto-line)
-         ("s-j"   . avy-goto-char-timer)))
-
-(use-package consult
-  :ensure t
-  :bind (("C-x b" . consult-buffer)
-         ("M-y"   . consult-yank-pop)
-         ("M-s r" . consult-ripgrep)
-         ("M-s l" . consult-line)
-         ("M-s L" . consult-line-multi)
-         ("M-s o" . consult-outline)
-         :map isearch-mode-map
-         ("M-e"   . consult-isearch-history)
-         ("M-s e" . consult-isearch-history)
-         ("M-s l" . consult-line)
-         ("M-s L" . consult-line-multi))
-  :custom
-  (consult-narrow-key "<"))
-
-(use-package embark-consult
-  :ensure t)
-
-(use-package embark
-  :ensure t
-  :demand t
-  :after (avy embark-consult)
-  :bind (("C-c a" . embark-act))
-  :init
-  (defun bedrock-avy-action-embark (pt)
-    "Run `embark-act' at PT, then restore the window avy jumped from."
-    (unwind-protect
-        (save-excursion
-          (goto-char pt)
-          (embark-act))
-      (select-window
-       (cdr (ring-ref avy-ring 0))))
-    t)
-  (setf (alist-get ?. avy-dispatch-alist) #'bedrock-avy-action-embark))
-
-(use-package vertico
-  :ensure t
-  :init (vertico-mode))
-
-(use-package vertico-directory
-  :ensure nil
-  :after vertico
-  :bind (:map vertico-map
-              ("M-DEL" . vertico-directory-delete-word)))
-
-(use-package marginalia
-  :ensure t
-  :config (marginalia-mode))
-
-(use-package corfu
-  :ensure t
-  :init (global-corfu-mode)
-  :bind (:map corfu-map
-              ("SPC" . corfu-insert-separator)))
-
-(use-package corfu-popupinfo
-  :after corfu
-  :ensure nil
-  :custom
-  (corfu-popupinfo-delay '(0.25 . 0.1))
-  (corfu-popupinfo-hide nil)
-  :config (corfu-popupinfo-mode))
-
-(use-package corfu-terminal
-  :if (not (display-graphic-p))
-  :ensure t
-  :config (corfu-terminal-mode))
-
-(use-package cape
-  :ensure t
-  :init
-  (add-to-list 'completion-at-point-functions #'cape-dabbrev)
-  (add-to-list 'completion-at-point-functions #'cape-file))
-
-(use-package kind-icon
-  :if (display-graphic-p)
-  :ensure t
-  :after corfu
-  :config
-  (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))
-
-(use-package eshell
-  :init
-  (defun bedrock-setup-eshell ()
-    "Bind `C-r' to `consult-history' in `eshell-mode'."
-    (keymap-set eshell-mode-map "C-r" #'consult-history))
-  :hook (eshell-mode . bedrock-setup-eshell))
-
-(use-package eat
-  :ensure t
-  :custom
-  (eat-term-name "xterm")
-  :config
-  (eat-eshell-mode)
-  (eat-eshell-visual-command-mode))
-
-(use-package orderless
-  :ensure t
-  :config (setopt completion-styles '(orderless)))
-
-(use-package wgrep
-  :ensure t
-  :config (setopt wgrep-auto-save-buffer t))
blob - 42e3723a6920036c2193a2e122e9574e9a37385e (mode 644)
blob + /dev/null
--- extras/binds.el
+++ /dev/null
@@ -1,45 +0,0 @@
-;;; extras/binds.el --- Key bindings  -*- lexical-binding: t; -*-
-
-(defvar-keymap mine-leader-map
-  :doc "Leader key map for SPC bindings.")
-
-(with-eval-after-load 'evil
-  (evil-define-key '(normal visual) 'global (kbd "SPC") mine-leader-map))
-
-(keymap-set mine-leader-map "f f" #'project-find-file)
-(keymap-set mine-leader-map "f h" #'consult-recent-file)
-(keymap-set mine-leader-map "f g" #'consult-ripgrep)
-
-(keymap-set mine-leader-map "g g" #'magit-status)
-
-(keymap-set mine-leader-map "g d" #'xref-find-definitions)
-(keymap-set mine-leader-map "g D" #'xref-find-definitions-other-window)
-(keymap-set mine-leader-map "g i" #'eglot-find-implementation)
-(keymap-set mine-leader-map "g t" #'eglot-find-typeDefinition)
-(keymap-set mine-leader-map "g r" #'xref-find-references)
-(keymap-set mine-leader-map "g s" #'eldoc-doc-buffer)
-(keymap-set mine-leader-map "g a" #'eglot-code-actions)
-(keymap-set mine-leader-map "g l" #'consult-flymake)
-(keymap-set mine-leader-map "g p" #'flymake-goto-prev-error)
-(keymap-set mine-leader-map "g n" #'flymake-goto-next-error)
-
-(keymap-set mine-leader-map "r r" #'eglot-rename)
-(keymap-set mine-leader-map "t r" #'consult-imenu)
-
-(defun mine-eglot-format-visual ()
-  "Format the active region or current buffer via Eglot."
-  (interactive)
-  (if (use-region-p)
-      (eglot-format-region (region-beginning) (region-end))
-    (eglot-format)))
-(with-eval-after-load 'evil
-  (evil-define-key 'visual 'global (kbd "SPC g f") #'mine-eglot-format-visual))
-
-(with-eval-after-load 'corfu
-  (keymap-set corfu-map "C-b"   #'corfu-scroll-down)
-  (keymap-set corfu-map "C-f"   #'corfu-scroll-up)
-  (keymap-set corfu-map "C-SPC" #'corfu-complete)
-  (keymap-set corfu-map "C-e"   #'corfu-quit)
-  (keymap-set corfu-map "RET"   #'corfu-complete))
-
-;;; binds.el ends here
blob - aeb8cf430a74242365ef0bc3db0fc9054b3128c9 (mode 644)
blob + /dev/null
--- extras/core.el
+++ /dev/null
@@ -1,13 +0,0 @@
-;;; extras/core.el --- Core development settings  -*- lexical-binding: t; -*-
-
-(setq major-mode-remap-alist
-      '((yaml-mode . yaml-ts-mode)
-        (bash-mode . bash-ts-mode)
-        (json-mode . json-ts-mode)
-        (css-mode . css-ts-mode)
-        (python-mode . python-ts-mode)))
-
-(add-hook 'prog-mode-hook #'electric-pair-mode)
-
-(use-package project
-  :custom (project-mode-line t))
blob - 9a246f1e709f394669ced06d5499550808a77e6b (mode 644)
blob + /dev/null
--- extras/evil.el
+++ /dev/null
@@ -1,28 +0,0 @@
-;;; extras/evil.el --- Evil-mode and addons  -*- lexical-binding: t; -*-
-
-(use-package evil
-  :ensure t
-  :custom
-  (evil-want-keybinding nil)
-  (evil-respect-visual-line-mode t)
-  (evil-undo-system 'undo-redo)
-  (evil-want-C-u-scroll t)
-  :config
-  (evil-mode)
-  (add-hook 'git-commit-setup-hook #'evil-insert-state)
-  (evil-set-initial-state 'eat-mode 'emacs))
-
-(use-package evil-collection
-  :ensure t
-  :after evil
-  :config (evil-collection-init))
-
-(use-package evil-surround
-  :ensure t
-  :after evil
-  :config (global-evil-surround-mode))
-
-(use-package evil-commentary
-  :ensure t
-  :after evil
-  :config (evil-commentary-mode))
blob - f69c7c3aaa2b4423e15759f2f102a4e6f68f918d (mode 644)
blob + /dev/null
--- extras/lang.el
+++ /dev/null
@@ -1,17 +0,0 @@
-;;; extras/langs.el --- Programming language modes  -*- lexical-binding: t; -*-
-
-(use-package yaml-mode
-  :ensure t)
-
-(use-package json-mode
-  :ensure t)
-
-(use-package nix-mode
-  :ensure t
-  :mode "\\.nix\\'")
-
-(use-package go-mode
-  :ensure t)
-
-(use-package zig-mode
-  :ensure t)
blob - 1de67efe207a7b3e171760170c7fa427d89d8436 (mode 644)
blob + /dev/null
--- extras/lisp.el
+++ /dev/null
@@ -1,12 +0,0 @@
-;;; extras/lisp.el --- SLIME / Common Lisp support  -*- lexical-binding: t; -*-
-
-(use-package slime
-  :ensure t
-  :custom
-  (inferior-lisp-program "sbcl")
-  (slime-lisp-implementations '((sbcl ("sbcl"))))
-  :bind (:map slime-mode-map
-              ("C-c C-d C-s" . slime-describe-symbol)
-              ("C-c C-d C-a" . slime-apropos))
-  :config
-  (slime-setup '(slime-fancy slime-quicklisp slime-asdf)))
blob - c98160b3fa3f12f1f67a03f1b2ec36daa3957f1d (mode 644)
blob + /dev/null
--- extras/lsp.el
+++ /dev/null
@@ -1,7 +0,0 @@
-;;; extras/lsp.el --- Language server protocol  -*- lexical-binding: t; -*-
-
-(use-package eglot
-  :custom
-  (eglot-send-changes-idle-time 0.1)
-  (eglot-extend-to-xref t)
-  :config (fset #'jsonrpc--log-event #'ignore))
blob - d15ace9d1ff285628e0b7d71b3acdbf885178bd4 (mode 644)
blob + /dev/null
--- extras/magit.el
+++ /dev/null
@@ -1,5 +0,0 @@
-;;; extras/magit.el --- Magit  -*- lexical-binding: t; -*-
-
-(use-package magit
-  :ensure t
-  :bind (("C-x g" . magit-status)))
blob - c31175b9bed89681ec13eaf7086a9a669bf8d835 (mode 644)
blob + /dev/null
--- extras/markdown.el
+++ /dev/null
@@ -1,5 +0,0 @@
-;;; extras/markdown.el --- Markdown  -*- lexical-binding: t; -*-
-
-(use-package markdown-mode
-  :ensure t
-  :hook (markdown-mode . visual-line-mode))
blob - 463a9cb4dfca268234e7408ac92187d381b6396b (mode 644)
blob + /dev/null
--- extras/mine.el
+++ /dev/null
@@ -1,20 +0,0 @@
-;;; extras/mine.el --- Personal settings  -*- lexical-binding: t; -*-
-
-(setopt select-enable-clipboard t
-	select-enable-primary t
-	save-interprogram-text-before-kill t)
-
-(use-package clipetty
-  :ensure t
-  :hook (after-init . clipetty-mode))
-
-(with-eval-after-load 'eglot
-  (add-to-list 'eglot-server-programs
-               '(purescript-mode . ("pnpx" "purescript-language-server" "--stdio")))
-  (add-to-list 'eglot-server-programs
-               '((markdown-mode text-mode tex-mode typst-mode org-mode)
-                 . ("harper-ls" "--stdio"))))
-
-(use-package zoom-window
-  :ensure t
-  :bind ("C-x z" . zoom-window-zoom))
blob - 5aaef98dd33e40a045dfb166ad3d02866d827984 (mode 644)
blob + /dev/null
--- extras/notes.el
+++ /dev/null
@@ -1,16 +0,0 @@
-;;; extras/notes.el --- bare denote config  -*- lexical-binding: t; -*-
-
-(setopt denote-directory (expand-file-name "~/.nb/notes"))
-
-(use-package denote
-  :ensure t
-  :custom
-  (denote-file-type 'org)
-  :config
-  (denote-rename-buffer-mode))
-
-(use-package denote-journal
-  :ensure t
-  :after denote
-  :custom
-  (denote-journal-keyword "journal"))
blob - da70b4500bc78ec281bc4a56a42a7d43780247f6 (mode 644)
blob + /dev/null
--- extras/org.el
+++ /dev/null
@@ -1,74 +0,0 @@
-;;; extras/org.el --- Org-mode configuration  -*- lexical-binding: t; -*-
-
-(setopt org-directory (expand-file-name "~/.nb/notes")
-        org-agenda-files (list org-directory)
-        org-default-notes-file (expand-file-name "todo.org" org-directory))
-
-(setopt org-refile-targets '((org-agenda-files :maxlevel . 3))
-        org-refile-use-outline-path 'file
-        org-outline-path-complete-in-steps nil)
-
-(setopt org-todo-keywords
-        '((sequence "TODO(t)" "WAITING(w@/!)" "STARTED(s!)" "|" "DONE(d!)" "OBSOLETE(o@)"))
-        org-log-done 'time
-        org-log-into-drawer t)
-
-(setopt org-capture-templates
-        '(("c" "todo" entry (file+headline org-default-notes-file "Tasks")
-           "* TODO %?
-%U
-%i")
-          ("r" "capture" entry (file+headline org-default-notes-file "Tasks")
-           "* TODO %?
-%U
-%i
-%a")))
-
-(setopt org-agenda-start-with-log-mode 'clockcheck
-        org-agenda-prefix-format
-        '((agenda . " %i %-12:c%?-12t% s")
-          (todo   . " %i %-12:c")
-          (tags   . " %i %-12:c")
-          (search . " %i %-12:c"))
-        org-agenda-time-grid
-        '((daily today require-timed)
-          (800 1000 1200 1400 1600 1800 2000)
-          " ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄")
-        org-agenda-current-time-string "◀── now")
-
-(setopt org-special-ctrl-a/e t
-        org-special-ctrl-k t
-        org-return-follows-link t
-        org-image-actual-width nil
-        org-startup-with-inline-images t
-        org-hide-emphasis-markers t)
-
-(setopt org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id
-        org-link-abbrev-alist
-        '(("family_search" . "https://www.familysearch.org/tree/person/details/%s")))
-
-(setopt org-export-with-smart-quotes t)
-
-(use-package org
-  :hook ((org-mode . visual-line-mode)
-         (org-mode . flyspell-mode)
-         (org-mode . variable-pitch-mode))
-  :bind (:map global-map
-              ("C-c l s" . org-store-link)
-              ("C-c l i" . org-insert-link-global)
-              ("C-c a"   . org-agenda)
-              ("C-c c"   . org-capture))
-  :config
-  (require 'oc-csl)
-  (add-to-list 'org-export-backends 'md)
-  (setf (alist-get 'file org-link-frame-setup) 'find-file)
-  (setopt org-startup-indented t
-          org-cycle-separator-lines 2))
-
-(use-package evil-org
-  :ensure t
-  :after org
-  :hook (org-mode . evil-org-mode)
-  :config
-  (require 'evil-org-agenda)
-  (evil-org-agenda-set-keys))
blob - de87d08f4cdf099be90854258aff226dd27cecfb (mode 644)
blob + /dev/null
--- extras/tempel.el
+++ /dev/null
@@ -1,16 +0,0 @@
-;;; extras/tempel.el --- Templating  -*- lexical-binding: t; -*-
-
-(use-package tempel
-  :ensure t
-  :bind (("M-*" . tempel-insert)
-         ("M-+" . tempel-complete)
-         :map tempel-map
-         ("C-c RET"  . tempel-done)
-         ("M-<down>" . tempel-next)
-         ("M-<up>"   . tempel-previous))
-  :init
-  (defun tempel-setup-capf ()
-    "Add `tempel-expand' to `completion-at-point-functions' locally."
-    (add-hook 'completion-at-point-functions #'tempel-expand -1 'local))
-  (add-hook 'prog-mode-hook #'tempel-setup-capf)
-  (add-hook 'text-mode-hook #'tempel-setup-capf))
blob - d27fd0bba71c7d0fc0147e910206741317c3f134
blob + 80468f6f97a8bd2bbbdcdb5a514367f3025b6772
--- init.el
+++ init.el
@@ -1,15 +1,7 @@
-;;; init.el --- Main configuration  -*- lexical-binding: t; -*-
-
 (when (< emacs-major-version 29)
-  (error "Emacs Bedrock only works with Emacs 29 and newer; you have version %s"
+  (error "Emacs configuration only works with Emacs 29 and newer; you have version %s"
          emacs-major-version))
 
-(require 'package)
-(package-initialize)
-
-(with-eval-after-load 'package
-  (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t))
-
 (setopt initial-major-mode 'fundamental-mode)
 (setopt inhibit-startup-screen t)
 (setopt initial-scratch-message nil)
@@ -28,8 +20,27 @@
 (setopt sentence-end-double-space nil)
 
 (when (display-graphic-p)
-  (context-menu-mode))
+  (context-menu-mode -1)
+  (tool-bar-mode -1)
+  (menu-bar-mode -1)
+  (scroll-bar-mode -1)
+  (set-frame-parameter nil 'font "PragmataPro Mono-14"))
 
+(unless (display-graphic-p)
+  (xterm-mouse-mode 1))
+
+(cua-mode 1)
+
+(add-hook 'prog-mode-hook #'display-line-numbers-mode)
+(setopt display-line-numbers-width 3)
+
+(add-hook 'text-mode-hook #'visual-line-mode)
+
+(dolist (hook '(text-mode-hook prog-mode-hook))
+  (add-hook hook #'hl-line-mode))
+
+(setopt tab-bar-show 1)
+
 (defun bedrock--backup-file-name (fpath)
   "Return a backup path for FPATH, creating parent dirs if needed."
   (let* ((backup-root-dir (concat user-emacs-directory "emacs-backup/"))
@@ -41,91 +52,492 @@
     backup-file-path))
 (setopt make-backup-file-name-function #'bedrock--backup-file-name)
 
+(let ((auto-save-dir (expand-file-name "auto-saves/" "~/.cache/emacs"))
+      (lock-dir (expand-file-name "locks/" "~/.cache/emacs")))
+  (make-directory auto-save-dir t)
+  (make-directory lock-dir t)
+  (setopt auto-save-file-name-transforms `((".*" ,auto-save-dir t)))
+  (setopt lock-file-name-transforms `((".*" ,lock-dir t))))
+
+(use-package modus-themes
+  :straight t
+  :demand t
+  :config
+  (load-theme 'modus-operandi t))
+
+(use-package ef-themes
+  :straight t
+  :commands ef-themes-select)
+
 (use-package which-key
-  :ensure t
+  :straight t
   :config (which-key-mode))
 
-(setopt completion-cycle-threshold 3)
-(setopt tab-always-indent 'complete)
-
-(keymap-set minibuffer-mode-map "TAB" #'minibuffer-complete)
-
-(setopt line-number-mode t)
-(setopt column-number-mode t)
-
-(setopt x-underline-at-descent-line nil)
-(setopt switch-to-buffer-obey-display-actions t)
-
-(setopt show-trailing-whitespace nil)
-(setopt indicate-buffer-boundaries 'left)
-
-(setopt mouse-wheel-tilt-scroll t)
-(setopt mouse-wheel-flip-direction t)
-
-(blink-cursor-mode -1)
-(pixel-scroll-precision-mode 1)
-
-(cua-mode 1)
-(xterm-mouse-mode 1)
-
-(add-hook 'prog-mode-hook #'display-line-numbers-mode)
-(setopt display-line-numbers-width 3)
-
-(add-hook 'text-mode-hook #'visual-line-mode)
-
-(dolist (hook '(text-mode-hook prog-mode-hook))
-  (add-hook hook #'hl-line-mode))
-
-(setopt tab-bar-show 1)
-
-(use-package modus-themes
-  :ensure t
-  :demand t
-  :config
-  (load-theme 'modus-vivendi t))
-
 (add-to-list 'tab-bar-format 'tab-bar-format-align-right 'append)
 (add-to-list 'tab-bar-format 'tab-bar-format-global 'append)
 (setopt display-time-format "%a %F %T")
 (setopt display-time-interval 1)
 (display-time-mode 1)
 
-(let ((auto-save-dir (expand-file-name "auto-saves/" "~/.cache/emacs"))
-      (lock-dir (expand-file-name "locks/" "~/.cache/emacs")))
-  (make-directory auto-save-dir t)
-  (make-directory lock-dir t)
-  (setopt auto-save-file-name-transforms `((".*" ,auto-save-dir t)))
-  (setopt lock-file-name-transforms `((".*" ,lock-dir t))))
+(setopt mouse-wheel-tilt-scroll t)
+(setopt mouse-wheel-flip-direction t)
+(setopt mouse-wheel-scroll-amount '(1 ((shift) . 5) ((control) . 0)))
+(setopt mouse-wheel-progressive-speed nil)
 
-(dolist (file '("base"
-                "notes"
-                "core"
-                "magit"
-                "markdown"
-                "lang"
-                "lsp"
-                "tempel"
-                "evil"
-                "org"
-                "binds"
-                "mine"
-                "lisp"))
-  (load-file (expand-file-name (format "extras/%s.el" file) user-emacs-directory)))
+(blink-cursor-mode -1)
+(pixel-scroll-precision-mode 1)
+(setopt scroll-margin 4)
+(setopt scroll-conservatively 101)
+(setopt scroll-up-aggressively 0.01)
+(setopt scroll-down-aggressively 0.01)
+(setopt auto-window-vscroll nil)
 
+(use-package lin
+  :straight t
+  :hook ((eshell-mode . lin-mode)
+         (dired-mode . lin-mode)
+         (org-mode . lin-mode)))
+
+(use-package pulsar
+  :straight t
+  :config
+  (pulsar-global-mode))
+
+(use-package diff-hl
+  :straight t
+  :hook ((prog-mode . diff-hl-mode)
+         (org-mode . diff-hl-mode))
+  :config
+  (global-diff-hl-show-hunk-mouse-mode))
+
+(setopt completion-cycle-threshold 3)
+(setopt tab-always-indent 'complete)
+
+(keymap-set minibuffer-mode-map "TAB" #'minibuffer-complete)
+
+(use-package vertico
+  :straight t
+  :init (vertico-mode))
+
+(with-eval-after-load 'vertico
+  (keymap-set vertico-map "M-DEL" #'vertico-directory-delete-word))
+
+(use-package marginalia
+  :straight t
+  :config (marginalia-mode))
+
+(use-package orderless
+  :straight t
+  :config (setopt completion-styles '(orderless)))
+
+(use-package consult
+  :straight t
+  :bind (("C-x b" . consult-buffer)
+         ("M-y"   . consult-yank-pop)
+         ("M-s r" . consult-ripgrep)
+         ("M-s l" . consult-line)
+         ("M-s L" . consult-line-multi)
+         ("M-s o" . consult-outline)
+         :map isearch-mode-map
+         ("M-e"   . consult-isearch-history)
+         ("M-s e" . consult-isearch-history)
+         ("M-s l" . consult-line)
+         ("M-s L" . consult-line-multi))
+  :custom
+  (consult-narrow-key "<"))
+
+(use-package embark
+  :straight t
+  :demand t
+  :after consult
+  :bind (("C-c a" . embark-act))
+  :init
+  (defun bedrock-avy-action-embark (pt)
+    "Run `embark-act' at PT, then restore the window avy jumped from."
+    (unwind-protect
+        (save-excursion
+          (goto-char pt)
+          (embark-act))
+      (select-window
+       (cdr (ring-ref avy-ring 0))))
+    t)
+  (setf (alist-get ?. avy-dispatch-alist) #'bedrock-avy-action-embark))
+
+(use-package embark-consult
+  :straight t
+  :after (embark consult))
+
+(use-package corfu
+  :straight t
+  :init (global-corfu-mode)
+  :bind (:map corfu-map
+              ("SPC" . corfu-insert-separator)))
+
+(with-eval-after-load 'corfu
+  (setopt corfu-popupinfo-delay '(0.25 . 0.1)
+          corfu-popupinfo-hide nil)
+  (corfu-popupinfo-mode))
+
+(use-package corfu-terminal
+  :straight t
+  :if (not (display-graphic-p))
+  :config (corfu-terminal-mode))
+
+(use-package cape
+  :straight t
+  :init
+  (add-to-list 'completion-at-point-functions #'cape-dabbrev)
+  (add-to-list 'completion-at-point-functions #'cape-file))
+
+(use-package kind-icon
+  :straight t
+  :if (display-graphic-p)
+  :after corfu
+  :config
+  (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))
+
+(use-package wgrep
+  :straight t
+  :config (setopt wgrep-auto-save-buffer t))
+
+(use-package avy
+  :straight t
+  :demand t
+  :bind (("C-c j" . avy-goto-line)
+         ("s-j"   . avy-goto-char-timer)))
+
+(use-package evil
+  :straight t
+  :custom
+  (evil-want-keybinding nil)
+  (evil-respect-visual-line-mode t)
+  (evil-undo-system 'undo-redo)
+  (evil-want-C-u-scroll t)
+  :config
+  (evil-mode)
+  (add-hook 'git-commit-setup-hook #'evil-insert-state)
+  (evil-set-initial-state 'eat-mode 'emacs))
+
+(use-package evil-collection
+  :straight t
+  :after evil
+  :config (evil-collection-init))
+
+(use-package evil-surround
+  :straight t
+  :after evil
+  :config (global-evil-surround-mode))
+
+(use-package evil-commentary
+  :straight t
+  :after evil
+  :config (evil-commentary-mode))
+
+(use-package evil-org
+  :straight t
+  :after org
+  :hook (org-mode . evil-org-mode)
+  :config
+  (require 'evil-org-agenda)
+  (evil-org-agenda-set-keys))
+
+(use-package undo-fu
+  :straight t
+  :custom
+  (undo-fu-allow-undo-in-region t)
+  (undo-fu-undo-command 'undo-fu-only-undo)
+  (undo-fu-redo-command 'undo-fu-only-redo)
+  :bind (("C-/" . undo-fu-only-undo)
+         ("C-?" . undo-fu-only-redo)
+         ("M-/" . undo-fu-only-redo-all)))
+
+(use-package undo-fu-session
+  :straight t
+  :custom
+  (undo-fu-session-incompatible-files '("\\.gpg$"))
+  (undo-fu-session-directory
+   (expand-file-name "undo-fu-session/" user-emacs-directory))
+  :config
+  (undo-fu-session-global-mode))
+
+(use-package vundo
+  :straight t
+  :bind ("C-c u" . vundo))
+
+(with-eval-after-load 'evil
+  (keymap-set evil-normal-state-map "u" #'undo-fu-only-undo)
+  (keymap-set evil-normal-state-map "C-r" #'undo-fu-only-redo))
+
+(use-package helpful
+  :straight t
+  :bind (("C-h f" . helpful-callable)
+         ("C-h v" . helpful-variable)
+         ("C-h k" . helpful-key)
+         ("C-h x" . helpful-command)
+         ("C-h d" . helpful-at-point)))
+
+(use-package eshell
+  :straight (:type built-in)
+  :init
+  (defun bedrock-setup-eshell ()
+    "Bind `C-r' to `consult-history' in `eshell-mode'."
+    (keymap-set eshell-mode-map "C-r" #'consult-history))
+  :hook (eshell-mode . bedrock-setup-eshell))
+
+(use-package eat
+  :straight t
+  :custom
+  (eat-term-name "xterm")
+  :config
+  (eat-eshell-mode)
+  (eat-eshell-visual-command-mode))
+
+(setq major-mode-remap-alist
+      '((yaml-mode . yaml-ts-mode)
+        (bash-mode . bash-ts-mode)
+        (json-mode . json-ts-mode)
+        (css-mode . css-ts-mode)
+        (python-mode . python-ts-mode)))
+
+(add-hook 'prog-mode-hook #'electric-pair-mode)
+
+(use-package project
+  :straight (:type built-in)
+  :custom (project-mode-line t))
+
+(use-package magit
+  :straight t
+  :bind (("C-x g" . magit-status)))
+
+(use-package yaml-mode
+  :straight t)
+
+(use-package json-mode
+  :straight t)
+
+(use-package nix-mode
+  :straight t
+  :mode "\\.nix\\'")
+
+(use-package go-mode
+  :straight t)
+
+(use-package zig-mode
+  :straight t)
+
+(use-package rust-mode
+  :straight t)
+
+(use-package elixir-mode
+  :straight t)
+
+(use-package eglot
+  :straight (:type built-in)
+  :custom
+  (eglot-send-changes-idle-time 0.1)
+  (eglot-extend-to-xref t)
+  :config (fset #'jsonrpc--log-event #'ignore))
+
+(use-package tempel
+  :straight t
+  :bind (("M-*" . tempel-insert)
+         ("M-+" . tempel-complete)
+         :map tempel-map
+         ("C-c RET"  . tempel-done)
+         ("M-<down>" . tempel-next)
+         ("M-<up>"   . tempel-previous))
+  :init
+  (defun tempel-setup-capf ()
+    "Add `tempel-expand' to `completion-at-point-functions' locally."
+    (add-hook 'completion-at-point-functions #'tempel-expand -1 'local))
+  (add-hook 'prog-mode-hook #'tempel-setup-capf)
+  (add-hook 'text-mode-hook #'tempel-setup-capf))
+
+(use-package slime
+  :straight t
+  :custom
+  (inferior-lisp-program "sbcl")
+  (slime-lisp-implementations '((sbcl ("sbcl"))))
+  :bind (:map slime-mode-map
+              ("C-c C-d C-s" . slime-describe-symbol)
+              ("C-c C-d C-a" . slime-apropos))
+  :config
+  (slime-setup '(slime-fancy slime-quicklisp slime-asdf)))
+
+(setopt denote-directory (expand-file-name "~/.nb/notes"))
+
+(use-package denote
+  :straight t
+  :custom
+  (denote-file-type 'org)
+  (denote-known-keywords '("daily" "comp" "music" "misc"))
+  (denote-infer-keywords nil)
+  :config
+  (denote-rename-buffer-mode))
+
+(use-package denote-journal
+  :straight t
+  :after denote
+  :custom
+  (denote-journal-keyword "journal")
+  (denote-journal-file-type 'org))
+
+(use-package denote-org
+  :straight t
+  :after denote)
+
+(setopt org-directory (expand-file-name "~/.nb/notes")
+        org-agenda-files (list org-directory)
+        org-default-notes-file (expand-file-name "todo.org" org-directory))
+
+(setopt org-refile-targets '((org-agenda-files :maxlevel . 3))
+        org-refile-use-outline-path 'file
+        org-outline-path-complete-in-steps nil)
+
+(setopt org-todo-keywords
+        '((sequence "TODO(t)" "WAITING(w@/!)" "STARTED(s!)" "|" "DONE(d!)" "OBSOLETE(o@)"))
+        org-log-done 'time
+        org-log-into-drawer t)
+
+(setopt org-capture-templates
+        '(("t" "task" entry (file+headline org-default-notes-file "Inbox")
+           "* TODO %?\n%U\n%i")
+          ("j" "journal" plain (file denote-journal-path-to-new-or-existing-entry)
+           "%?\n%U\n%i")))
+
+(setopt org-agenda-start-with-log-mode 'clockcheck
+        org-agenda-prefix-format
+        '((agenda . " %i %-12:c%?-12t% s")
+          (todo   . " %i %-12:c")
+          (tags   . " %i %-12:c")
+          (search . " %i %-12:c"))
+        org-agenda-time-grid
+        '((daily today require-timed)
+          (800 1000 1200 1400 1600 1800 2000)
+          " ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄")
+        org-agenda-current-time-string "◀── now")
+
+(setopt org-special-ctrl-a/e t
+        org-special-ctrl-k t
+        org-return-follows-link t
+        org-image-actual-width nil
+        org-startup-with-inline-images t
+        org-hide-emphasis-markers t)
+
+(setopt org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id)
+
+(setopt org-export-with-smart-quotes t)
+
+(use-package org
+  :straight (:type built-in)
+  :hook ((org-mode . visual-line-mode)
+         (org-mode . variable-pitch-mode))
+  :bind (:map global-map
+              ("C-c l s" . org-store-link)
+              ("C-c l i" . org-insert-link-global)
+              ("C-c a"   . org-agenda)
+              ("C-c c"   . org-capture)
+              :map org-mode-map
+              ("TAB" . org-cycle))
+  :config
+  (require 'oc-csl)
+  (add-to-list 'org-export-backends 'md)
+  (setf (alist-get 'file org-link-frame-setup) 'find-file)
+  (setopt org-startup-indented t
+          org-cycle-separator-lines 2))
+
+(use-package org-appear
+  :straight t
+  :hook (org-mode . org-appear-mode))
+
+(use-package org-super-agenda
+  :straight t
+  :after org
+  :config
+  (org-super-agenda-mode))
+
+(use-package markdown-mode
+  :straight t
+  :hook (markdown-mode . visual-line-mode))
+
+(defvar-keymap file-prefix-map
+  :doc "Prefix map for file commands.")
+(keymap-set global-map "C-c f" file-prefix-map)
+(keymap-set file-prefix-map "f" #'project-find-file)
+(keymap-set file-prefix-map "r" #'consult-recent-file)
+(keymap-set file-prefix-map "g" #'consult-ripgrep)
+
+(defvar-keymap git-prefix-map
+  :doc "Prefix map for git commands.")
+(keymap-set global-map "C-c g" git-prefix-map)
+(keymap-set git-prefix-map "g" #'magit-status)
+(keymap-set git-prefix-map "d" #'xref-find-definitions)
+(keymap-set git-prefix-map "D" #'xref-find-definitions-other-window)
+(keymap-set git-prefix-map "i" #'eglot-find-implementation)
+(keymap-set git-prefix-map "t" #'eglot-find-typeDefinition)
+(keymap-set git-prefix-map "r" #'xref-find-references)
+(keymap-set git-prefix-map "s" #'eldoc-doc-buffer)
+(keymap-set git-prefix-map "a" #'eglot-code-actions)
+(keymap-set git-prefix-map "l" #'consult-flymake)
+(keymap-set git-prefix-map "p" #'flymake-goto-prev-error)
+(keymap-set git-prefix-map "n" #'flymake-goto-next-error)
+(keymap-set git-prefix-map "f" #'eglot-format)
+
+(defvar-keymap refactor-prefix-map
+  :doc "Prefix map for refactor commands.")
+(keymap-set global-map "C-c r" refactor-prefix-map)
+(keymap-set refactor-prefix-map "r" #'eglot-rename)
+
+(defvar-keymap tree-prefix-map
+  :doc "Prefix map for tree / navigation commands.")
+(keymap-set global-map "C-c t" tree-prefix-map)
+(keymap-set tree-prefix-map "r" #'consult-imenu)
+
+(defvar-keymap denote-prefix-map
+  :doc "Prefix map for denote commands.")
+(keymap-set global-map "C-c n" denote-prefix-map)
+(keymap-set denote-prefix-map "n" #'denote)
+(keymap-set denote-prefix-map "j" #'denote-journal-new-or-existing-entry)
+(keymap-set denote-prefix-map "l" #'denote-insert-link)
+(keymap-set denote-prefix-map "L" #'denote-add-links)
+(keymap-set denote-prefix-map "o" #'denote-open-or-create)
+(keymap-set denote-prefix-map "b" #'denote-backlinks)
+(keymap-set denote-prefix-map "r" #'denote-rename-file)
+(keymap-set denote-prefix-map "d" #'denote-sort-dired)
+(keymap-set denote-prefix-map "t" #'org-agenda-list)
+(keymap-set denote-prefix-map "c" #'org-capture)
+
+(with-eval-after-load 'corfu
+  (keymap-set corfu-map "C-b"   #'corfu-scroll-down)
+  (keymap-set corfu-map "C-f"   #'corfu-scroll-up)
+  (keymap-set corfu-map "C-SPC" #'corfu-complete)
+  (keymap-set corfu-map "C-e"   #'corfu-quit)
+  (keymap-set corfu-map "RET"   #'corfu-complete))
+
+(setopt select-enable-clipboard t
+        select-enable-primary t
+        save-interprogram-text-before-kill t)
+
+(use-package clipetty
+  :straight t
+  :hook (after-init . clipetty-mode))
+
+(with-eval-after-load 'eglot
+  (add-to-list 'eglot-server-programs
+               '(purescript-mode . ("pnpx" "purescript-language-server" "--stdio")))
+  (add-to-list 'eglot-server-programs
+               '((markdown-mode text-mode tex-mode typst-mode org-mode)
+                 . ("harper-ls" "--stdio"))))
+
+(use-package zoom-window
+  :straight t
+  :bind ("C-x z" . zoom-window-zoom))
+
+(use-package tmr
+  :straight t
+  :bind (("C-c t c" . tmr)
+         ("C-c t l" . tmr-tabulated-view)
+         ("C-c t k" . tmr-remove)
+         ("C-c t s" . tmr-stop)))
+
 (setq gc-cons-threshold (or bedrock--initial-gc-threshold 800000))
-(custom-set-variables
- ;; custom-set-variables was added by Custom.
- ;; If you edit it by hand, you could mess it up, so be careful.
- ;; Your init file should contain only one such instance.
- ;; If there is more than one, they won't work right.
- '(package-selected-packages
-   '(avy cape clipetty corfu-terminal denote-journal eat eglot embark-consult
- 	 evil-collection evil-commentary evil-org evil-surround go-mode json-mode
- 	 kind-icon magit marginalia markdown-mode modus-themes nix-mode orderless
- 	 slime tempel vertico wgrep yaml-mode zig-mode zoom-window)))
-(custom-set-faces
- ;; custom-set-faces was added by Custom.
- ;; If you edit it by hand, you could mess it up, so be careful.
- ;; Your init file should contain only one such instance.
- ;; If there is more than one, they won't work right.
- )