about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.emacs.d/init.el68
-rw-r--r--.emacs.d/lisp/init-compile.el4
-rw-r--r--.emacs.d/lisp/init-completion.el9
-rw-r--r--.emacs.d/lisp/init-editor.el34
-rw-r--r--.emacs.d/lisp/init-emacs-lisp.el11
-rw-r--r--.emacs.d/lisp/init-git.el9
-rw-r--r--.emacs.d/lisp/init-kill.el42
-rw-r--r--.emacs.d/lisp/init-minibuffer.el43
-rw-r--r--.emacs.d/lisp/init-misc.el2
-rw-r--r--.emacs.d/lisp/init-modeline.el4
-rw-r--r--.emacs.d/lisp/init-navigation.el4
-rw-r--r--.emacs.d/lisp/init-packages.el96
-rw-r--r--.emacs.d/lisp/init-project.el2
-rw-r--r--.emacs.d/lisp/init-smartparens.el12
-rw-r--r--.emacs.d/lisp/init-ui.el44
-rw-r--r--.emacs.d/lisp/init-web.el6
-rw-r--r--.emacs.d/lisp/init-windows.el14
17 files changed, 205 insertions, 199 deletions
diff --git a/.emacs.d/init.el b/.emacs.d/init.el
index a8734ec..422b2ab 100644
--- a/.emacs.d/init.el
+++ b/.emacs.d/init.el
@@ -19,11 +19,11 @@
 (add-to-list 'load-path (expand-file-name "lisp" user-emacs-directory))
 (add-to-list 'load-path (expand-file-name "contrib" user-emacs-directory))
 
-(add-hook 'emacs-startup-hook
-          (lambda ()
-            (message "%s packages loaded in %0.1f seconds"
-                     (hash-table-count straight--profile-cache)
-                     (string-to-number (emacs-init-time)))))
+(defun display-startup-echo-area-message ()
+  "Custom version of `display-startup-echo-area-message'."
+  (message "%s packages loaded in %0.1f seconds"
+           (cdar elpaca--status-counts)
+           (string-to-number (emacs-init-time))))
 
 (add-hook 'after-init-hook #'(lambda ()
                                (setq gc-cons-threshold (* 100 1024 1024)
@@ -37,34 +37,34 @@
       (load (prin1-to-string feature) noerror nil nil t)
     (require feature filename noerror)))
 
-(require! 'init-packages)
-(require! 'init-ui)
-(require! 'init-compile)
-(require! 'init-editor)
-(require! 'init-search)
-(require! 'init-windows)
-(require! 'init-project)
-(require! 'init-modeline)
-(require! 'init-completion)
-(require! 'init-minibuffer)
-(require! 'init-navigation)
-(require! 'init-kill)
-(require! 'init-dired)
-(require! 'init-smartparens)
-(require! 'init-emacs-lisp)
-(require! 'init-clojure)
-(require! 'init-crux)
-(require! 'init-lsp)
-(require! 'init-git)
-(require! 'init-shell)
-(require! 'init-nix)
-(require! 'init-org)
-;;(require! 'init-latex)
-(require! 'init-xml)
-(require! 'init-web)
-(require! 'init-misc)
-(require! 'init-tramp)
-(require! 'init-sql)
-(require! 'init-local nil t)
+(require 'init-packages)
+(require 'init-ui)
+(require 'init-compile)
+(require 'init-editor)
+(require 'init-search)
+(require 'init-windows)
+(require 'init-project)
+(require 'init-modeline)
+(require 'init-completion)
+(require 'init-minibuffer)
+(require 'init-navigation)
+(require 'init-kill)
+(require 'init-dired)
+(require 'init-smartparens)
+(require 'init-emacs-lisp)
+(require 'init-clojure)
+(require 'init-crux)
+(require 'init-lsp)
+(require 'init-git)
+(require 'init-shell)
+(require 'init-nix)
+(require 'init-org)
+;;(require 'init-latex)
+(require 'init-xml)
+(require 'init-web)
+(require 'init-misc)
+(require 'init-tramp)
+(require 'init-sql)
+(require 'init-local nil t)
 
 ;;; init.el ends here
diff --git a/.emacs.d/lisp/init-compile.el b/.emacs.d/lisp/init-compile.el
index 47405eb..42a2539 100644
--- a/.emacs.d/lisp/init-compile.el
+++ b/.emacs.d/lisp/init-compile.el
@@ -3,14 +3,14 @@
 ;; Based on code from prelude-editor.el
 ;;; Code:
 
-(use-package compile
+(use-feature compile
   :custom
   (compilation-ask-about-save nil)
   (compilation-always-kill t)
   (compilation-scroll-output 'first-error))
 
 ;; http://stackoverflow.com/a/3072831/355252
-(use-package ansi-color
+(use-feature ansi-color
   :hook
   (compilation-filter . (lambda ()
                           (when (eq major-mode 'compilation-mode)
diff --git a/.emacs.d/lisp/init-completion.el b/.emacs.d/lisp/init-completion.el
index 839bd67..8b6ba16 100644
--- a/.emacs.d/lisp/init-completion.el
+++ b/.emacs.d/lisp/init-completion.el
@@ -45,7 +45,7 @@
   (advice-add #'fancy-dabbrev--on-exit :after #'fancy-dabbrev-popup-exit-advice)
   :bind ("M-/" . fancy-dabbrev-expand))
 
-(use-package emacs
+(use-feature emacs
   :init
   (setq completion-cycle-threshold 3)
   (setq tab-always-indent 'complete))
@@ -130,8 +130,8 @@ no words in between, beginning with the first word."
 
 ;; code completion - corfu
 (use-package corfu
-  :straight (corfu :files (:defaults "extensions/*")
-                   :includes (corfu-indexed corfu-quick corfu-history corfu-info corfu-popupinfo))
+  :elpaca (corfu :files (:defaults "extensions/*")
+                 :includes (corfu-indexed corfu-quick corfu-history corfu-info corfu-popupinfo))
   :custom
   (corfu-cycle t)
   :bind (:map corfu-map
@@ -139,7 +139,7 @@ no words in between, beginning with the first word."
               ([tab] . corfu-next)
               ("S-TAB" . corfu-previous)
               ([backtab] . corfu-previous))
-  :hook (emacs-startup . global-corfu-mode))
+  :hook (elpaca-after-init . global-corfu-mode))
 
 (use-extension corfu corfu-indexed
   :config (corfu-indexed-mode 1))
@@ -150,6 +150,7 @@ no words in between, beginning with the first word."
               ("M-'" . corfu-quick-exit)))
 
 (use-extension corfu corfu-history
+  :after savehist
   :config
   (corfu-history-mode 1)
   (add-to-list 'savehist-additional-variables 'corfu-history))
diff --git a/.emacs.d/lisp/init-editor.el b/.emacs.d/lisp/init-editor.el
index 9c58691..ed2cf4e 100644
--- a/.emacs.d/lisp/init-editor.el
+++ b/.emacs.d/lisp/init-editor.el
@@ -3,21 +3,21 @@
 ;; based on prelude-editor.el
 ;;; Code:
 
-(use-package emacs
+(use-feature emacs
   :bind
   ("C-x \\" . align-regexp)
   ("C-+" . text-scale-increase)
   ("C--" . text-scale-decrease)
   :hook
   (after-save . executable-make-buffer-file-executable-if-script-p)
-  (emacs-startup . (lambda ()
-                     (save-place-mode 1)
-                     (delete-selection-mode t)
-                     (global-auto-revert-mode 1)
-                     (set-terminal-coding-system 'utf-8)
-                     (set-keyboard-coding-system 'utf-8)
-                     (set-selection-coding-system 'utf-8)
-                     (prefer-coding-system 'utf-8)))
+  (elpaca-after-init . (lambda ()
+                         (save-place-mode 1)
+                         (delete-selection-mode t)
+                         (global-auto-revert-mode 1)
+                         (set-terminal-coding-system 'utf-8)
+                         (set-keyboard-coding-system 'utf-8)
+                         (set-selection-coding-system 'utf-8)
+                         (prefer-coding-system 'utf-8)))
   ;; (text-mode . whitespace-cleanup)
 
   :config
@@ -67,12 +67,12 @@
   ("M-z" . zop-up-to-char)
   ("M-Z" . zop-to-char))
 
-(use-package savehist
+(use-feature savehist
   :custom
   (savehist-additional-variables '(search-ring regexp-search-ring))
   (savehist-autosave-interval 60)
   (savehist-file (expand-file-name "savehist" save-dir))
-  :hook (after-init . savehist-mode))
+  :hook (elpaca-after-init . savehist-mode))
 
 (use-package super-save
   :defer 5
@@ -84,7 +84,7 @@
   (add-to-list 'super-save-triggers 'ace-window)
   (add-to-list 'super-save-hook-triggers 'find-file-hook))
 
-(use-package recentf
+(use-feature recentf
   :config
   (add-to-list 'recentf-exclude (expand-file-name "elpa" user-emacs-directory))
   (add-to-list 'recentf-exclude (expand-file-name "straight" user-emacs-directory))
@@ -93,7 +93,7 @@
   (recentf-max-saved-items 300)
   (recentf-max-menu-items 20)
   (recentf-auto-cleanup (* 60 60))
-  :hook (after-init . recentf-mode))
+  :hook (elpaca-after-init . recentf-mode))
 
 (use-package flycheck
   :config
@@ -107,12 +107,12 @@
 ;  (text-mode . (lambda () (flyspell-mode +1)))
 ;  (prog-mode . (lambda () (flyspell-prog-mode))))
 
-(use-package bookmark
+(use-feature bookmark
   :custom
   (bookmark-default-file (expand-file-name "bookmarks" save-dir))
   (bookmark-save-flag 1))
 
-(use-package midnight)
+(use-feature midnight)
 
 (use-package undo-tree
   :defer 5
@@ -132,7 +132,7 @@
   (prog-mode . abbrev-mode)
   (cider-repl-mode . abbrev-mode))
 
-(use-package subword
+(use-feature subword
   :diminish)
 
 (use-package markdown-mode
@@ -208,7 +208,7 @@
 (use-package editorconfig
   :diminish
   :custom (editorconfig-trim-whitespaces-mode 'ws-butler-mode)
-  :hook (emacs-startup . editorconfig-mode))
+  :hook (elpaca-after-init . editorconfig-mode))
 
 (use-package titlecase
   ;; TODO find a better binding
diff --git a/.emacs.d/lisp/init-emacs-lisp.el b/.emacs.d/lisp/init-emacs-lisp.el
index 3def7f2..a22afd0 100644
--- a/.emacs.d/lisp/init-emacs-lisp.el
+++ b/.emacs.d/lisp/init-emacs-lisp.el
@@ -9,7 +9,7 @@
 (use-package elisp-slime-nav
   :diminish)
 
-(use-package emacs
+(use-feature emacs
   :config
   (defun eval-region-or-defun (edebug-it)
     "Call eval-region, if one is selected, or eval-defun otherwise."
@@ -48,16 +48,12 @@ Start `ielm' if it's not already running."
   :hook
   (ielm-mode . (lambda ()
                  (eldoc-mode +1)
-                 (rainbow-delimiters-mode +1)
                  (ielm-init-history)
                  (advice-add 'ielm-send-input :after 'ielm-write-history)))
   (emacs-lisp-mode . (lambda ()
                        (eldoc-mode +1)
-                       (rainbow-mode +1)
-                       (rainbow-delimiters-mode +1)
                        (setq mode-name "EL")
-                       (recompile-init-lisp-on-save)
-                       (define-key emacs-lisp-mode-map "\C-c\C-v" erefactor-map)))
+                       (recompile-init-lisp-on-save)))
   :bind
   (:map emacs-lisp-mode-map
         (("C-c C-z" . visit-ielm)
@@ -75,7 +71,8 @@ Start `ielm' if it's not already running."
   :hook
   (emacs-lisp-mode . eros-mode))
 
-(use-package erefactor)
+(use-package erefactor
+  :hook (emacs-lisp-mode . (lambda () (define-key emacs-lisp-mode-map "\C-c\C-v" erefactor-map))))
 
 (use-package flycheck-package
   :hook
diff --git a/.emacs.d/lisp/init-git.el b/.emacs.d/lisp/init-git.el
index c88a020..011750c 100644
--- a/.emacs.d/lisp/init-git.el
+++ b/.emacs.d/lisp/init-git.el
@@ -2,13 +2,13 @@
 ;;; Commentary:
 ;;; Code:
 
-(use-package ediff
+(use-feature ediff
   :custom
   (ediff-setup-windows-plain 'ediff-setup-windows-plain))
 
 (use-package diff-hl
   :hook
-  (emacs-startup . global-diff-hl-mode)
+  (elpaca-after-init . global-diff-hl-mode)
   (dired-mode . diff-hl-dired-mode)
   (magit-post-refresh . diff-hl-magit-post-refresh))
 
@@ -19,7 +19,7 @@
   :bind
   ("C-x v t" . git-timemachine-toggle))
 
-(use-package vc
+(use-feature vc
   :bind
   (("C-x v C-r" . my/vc-refresh-state)
    ("C-x v C-m" . my/update-git-master))
@@ -328,8 +328,7 @@ GitHub/Bitbucket/GitLab/... The URL will be added to the kill ring.  If
   ("C-c g c" . git-link-commit)
   ("C-c g b" . git-link-branch))
 
-(use-package git-related
-  :straight nil
+(use-feature git-related
   :defer 10)
 
 (provide 'init-git)
diff --git a/.emacs.d/lisp/init-kill.el b/.emacs.d/lisp/init-kill.el
index f442fda..37103e3 100644
--- a/.emacs.d/lisp/init-kill.el
+++ b/.emacs.d/lisp/init-kill.el
@@ -15,32 +15,32 @@
   ("C-=" . easy-mark)
   (:map easy-kill-base-map ("C-=" . easy-kill-expand)))
 
-(use-package emacs
+(use-feature emacs
   :hook
-  (emacs-startup . (lambda ()
-                     ;; Based on code in prelude-editor.el
-                     (defun yank-advised-indent-function (beg end)
-                       "Do indentation, as long as the region isn't too large."
-                       (if (<= (- end beg) 10000)
-                           (indent-region beg end nil)))
+  (elpaca-after-init . (lambda ()
+                         ;; Based on code in prelude-editor.el
+                         (defun yank-advised-indent-function (beg end)
+                           "Do indentation, as long as the region isn't too large."
+                           (if (<= (- end beg) 10000)
+                               (indent-region beg end nil)))
 
-                     (defmacro advise-commands (advice-name commands class &rest body)
-                       "Apply advice named ADVICE-NAME to multiple COMMANDS.
+                         (defmacro advise-commands (advice-name commands class &rest body)
+                           "Apply advice named ADVICE-NAME to multiple COMMANDS.
 
 The body of the advice is in BODY."
-                       `(progn
-                          ,@(mapcar (lambda (command)
-                                      `(defadvice ,command (,class ,(intern (concat (symbol-name command) "-" advice-name)) activate)
-                                         ,@body))
-                                    commands)))
+                           `(progn
+                              ,@(mapcar (lambda (command)
+                                          `(defadvice ,command (,class ,(intern (concat (symbol-name command) "-" advice-name)) activate)
+                                             ,@body))
+                                        commands)))
 
-                     (advise-commands "indent" (yank yank-pop) after
-                                      (if (and (not (ad-get-arg 0))
-                                               (not (member major-mode '(conf-mode coffee-mode haml-mode python-mode slim-mode yaml-mode)))
-                                               (or (derived-mode-p 'prog-mode)
-                                                   (member major-mode '(LaTeX-mode TeX-mode))))
-                                          (let ((transient-mark-mode nil))
-                                            (yank-advised-indent-function (region-beginning) (region-end))))))))
+                         (advise-commands "indent" (yank yank-pop) after
+                                          (if (and (not (ad-get-arg 0))
+                                                   (not (member major-mode '(conf-mode coffee-mode haml-mode python-mode slim-mode yaml-mode)))
+                                                   (or (derived-mode-p 'prog-mode)
+                                                       (member major-mode '(LaTeX-mode TeX-mode))))
+                                              (let ((transient-mark-mode nil))
+                                                (yank-advised-indent-function (region-beginning) (region-end))))))))
 
 (provide 'init-kill)
 ;;; init-kill.el ends here
diff --git a/.emacs.d/lisp/init-minibuffer.el b/.emacs.d/lisp/init-minibuffer.el
index c192e28..55c6dcb 100644
--- a/.emacs.d/lisp/init-minibuffer.el
+++ b/.emacs.d/lisp/init-minibuffer.el
@@ -6,9 +6,9 @@
 ;;; Code:
 
 (use-package vertico
-  :straight (vertico :files (:defaults "extensions/*")
-                     :includes (vertico-directory vertico-repeat vertico-indexed vertico-quick))
-  :hook (emacs-startup . vertico-mode)
+  :elpaca (vertico :files (:defaults "extensions/*")
+                   :includes (vertico-directory vertico-repeat vertico-indexed vertico-quick))
+  :hook (elpaca-after-init . vertico-mode)
   :custom (vertico-cycle t)
   :config
   ;; Do not allow the cursor in the minibuffer prompt
@@ -43,20 +43,6 @@
                    "  ")
                  cand)))
 
-  (defun define-vertico-key (key &rest defs)
-    "Define KEY conditionally in the vertico keymap.
-DEFS is a plist associating completion categories to commands."
-    (let ((default-command (lookup-key vertico-map (kbd key))))
-      (define-key vertico-map (kbd key)
-        (list 'menu-item nil defs :filter
-              (lambda (d)
-                (or (plist-get d (completion-metadata-get
-                                  (completion-metadata (minibuffer-contents)
-                                                       minibuffer-completion-table
-                                                       minibuffer-completion-predicate)
-                                  'category))
-                    default-command))))))
-
   (defun down-from-outside ()
     "Move to next candidate in minibuffer, even when minibuffer isn't selected."
     (interactive)
@@ -95,8 +81,7 @@ DEFS is a plist associating completion categories to commands."
          ("C-M-S-g" . minibuffer-really-quit)
          (:map vertico-map ("M-RET" . minibuffer-force-complete-and-exit))))
 
-(use-feature vertico-directory
-  :after vertico
+(use-extension vertico vertico-directory
   :config
   (defvar switching-project nil)
   (defun vertico-directory-enter-or-select-project ()
@@ -124,6 +109,21 @@ DEFS is a plist associating completion categories to commands."
       (apply orig args)))
   (advice-add 'project-prompt-project-dir :around
               'read-project)
+
+  ;; TODO this should be part of the vertico config
+  (defun define-vertico-key (key &rest defs)
+    "Define KEY conditionally in the vertico keymap.
+DEFS is a plist associating completion categories to commands."
+    (let ((default-command (lookup-key vertico-map (kbd key))))
+      (define-key vertico-map (kbd key)
+        (list 'menu-item nil defs :filter
+              (lambda (d)
+                (or (plist-get d (completion-metadata-get
+                                  (completion-metadata (minibuffer-contents)
+                                                       minibuffer-completion-table
+                                                       minibuffer-completion-predicate)
+                                  'category))
+                    default-command))))))
   (define-vertico-key "/"
     'file #'vertico-directory-slash
     'project-file #'vertico-directory-slash)
@@ -142,7 +142,8 @@ DEFS is a plist associating completion categories to commands."
   ;; Tidy shadowed file names
   :hook (rfn-eshadow-update-overlay . vertico-directory-tidy))
 
-(use-feature vertico-repeat
+(use-extension vertico vertico-repeat
+  :after savehist
   :bind
   ("C-\\" . vertico-repeat)
   ("C-|" . vertico-repeat-select)
@@ -442,7 +443,7 @@ DEFS is a plist associating completion categories to commands."
 (use-package consult-project-extra)
 
 (use-package marginalia
-  :hook (emacs-startup . marginalia-mode)
+  :hook (elpaca-after-init . marginalia-mode)
   :config
   ;; crux-recentf-find-file
   (add-to-list 'marginalia-prompt-categories '("Choose recent file" . file)))
diff --git a/.emacs.d/lisp/init-misc.el b/.emacs.d/lisp/init-misc.el
index c3cc371..d5e06a3 100644
--- a/.emacs.d/lisp/init-misc.el
+++ b/.emacs.d/lisp/init-misc.el
@@ -12,7 +12,7 @@
 
 (use-package envrc
   :diminish
-  :hook (after-init . envrc-global-mode))
+  :hook (elpaca-after-init . envrc-global-mode))
 
 (use-package restclient
   :mode (("\\.http\\'" . restclient-mode)))
diff --git a/.emacs.d/lisp/init-modeline.el b/.emacs.d/lisp/init-modeline.el
index 26f753d..dc1f01e 100644
--- a/.emacs.d/lisp/init-modeline.el
+++ b/.emacs.d/lisp/init-modeline.el
@@ -7,10 +7,10 @@
 ;(size-indication-mode t) ; TODO
 
 (use-feature which-func
-  :hook (after-init . which-function-mode))
+  :hook (elpaca-after-init . which-function-mode))
 
 (use-package simple-modeline
-  :hook (after-init . simple-modeline-mode)
+  :hook (elpaca-after-init . simple-modeline-mode)
   :custom
   (simple-modeline-segments
    '((simple-modeline-segment-modified
diff --git a/.emacs.d/lisp/init-navigation.el b/.emacs.d/lisp/init-navigation.el
index 0a82115..95076fe 100644
--- a/.emacs.d/lisp/init-navigation.el
+++ b/.emacs.d/lisp/init-navigation.el
@@ -55,7 +55,7 @@
   (dolist (mode smartscan-exclude-modes)
     (add-hook (intern (concat (symbol-name mode) "-hook")) #'turn-off-smartscan-mode))
   :hook
-  (after-init . global-smartscan-mode)
+  (elpaca-after-init . global-smartscan-mode)
   :bind (:map smartscan-map
               ("C-M-'" . smartscan-symbol-replace)))
 
@@ -115,7 +115,7 @@ Or remove all highlighted symbols in the current buffer (with`ARG')."
 (use-package goto-last-point
   :diminish
   :custom (goto-last-point-max-length 100)
-  :hook (emacs-startup . goto-last-point-mode)
+  :hook (elpaca-after-init . goto-last-point-mode)
   :config
   (defvar goto-last-point-repeat-map
     (let ((map (make-sparse-keymap)))
diff --git a/.emacs.d/lisp/init-packages.el b/.emacs.d/lisp/init-packages.el
index e480c3a..89bca95 100644
--- a/.emacs.d/lisp/init-packages.el
+++ b/.emacs.d/lisp/init-packages.el
@@ -2,37 +2,65 @@
 ;;; Commentary:
 ;;; Code:
 
-(setq straight-use-package-by-default t
-      straight-vc-git-default-clone-depth 1
-      straight-check-for-modifications '(find-when-checking check-on-save)
-      use-package-always-defer t
-      package-native-compile t)
+(defvar elpaca-installer-version 0.4)
+(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory))
+(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
+(defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory))
+(defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git"
+                              :ref nil
+                              :files (:defaults (:exclude "extensions"))
+                              :build (:not elpaca--activate-package)))
+(let* ((repo  (expand-file-name "elpaca/" elpaca-repos-directory))
+       (build (expand-file-name "elpaca/" elpaca-builds-directory))
+       (order (cdr elpaca-order))
+       (default-directory repo))
+  (add-to-list 'load-path (if (file-exists-p build) build repo))
+  (unless (file-exists-p repo)
+    (make-directory repo t)
+    (when (< emacs-major-version 28) (require 'subr-x))
+    (condition-case-unless-debug err
+        (if-let ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*"))
+                 ((zerop (call-process "git" nil buffer t "clone"
+                                       (plist-get order :repo) repo)))
+                 ((zerop (call-process "git" nil buffer t "checkout"
+                                       (or (plist-get order :ref) "--"))))
+                 (emacs (concat invocation-directory invocation-name))
+                 ((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch"
+                                       "--eval" "(byte-recompile-directory \".\" 0 'force)")))
+                 ((require 'elpaca))
+                 ((elpaca-generate-autoloads "elpaca" repo)))
+            (kill-buffer buffer)
+          (error "%s" (with-current-buffer buffer (buffer-string))))
+      ((error) (warn "%s" err) (delete-directory repo 'recursive))))
+  (unless (require 'elpaca-autoloads nil t)
+    (require 'elpaca)
+    (elpaca-generate-autoloads "elpaca" repo)
+    (load "./elpaca-autoloads")))
+(add-hook 'after-init-hook #'elpaca-process-queues)
+(elpaca `(,@elpaca-order))
 
-(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))
+;; Install use-package support
+(elpaca elpaca-use-package
+  ;; Enable :elpaca use-package keyword.
+  (elpaca-use-package-mode)
+  ;; Assume :elpaca t unless otherwise specified.
+  (setq elpaca-use-package-by-default t
+        use-package-always-defer t
+        package-native-compile t))
 
-(straight-use-package 'use-package)
+(elpaca diminish)
+
+;; Block until current queue processed.
+(elpaca-wait)
 
 ;; https://github.com/radian-software/radian/blob/e3aad124c8e0cc870ed09da8b3a4905d01e49769/emacs/radian.el#L352
 (defmacro use-feature (name &rest args)
-  "Like `use-package', but with `straight-use-package-by-default' disabled.
+  "Like `use-package', but with `elpaca-use-package-by-default' disabled.
 `NAME' and `ARGS' are as with `use-package'"
   (declare (indent defun))
   `(use-package ,name
-     :straight nil
+     :elpaca nil
      ,@args))
-(use-feature straight-x
-  :commands (straight-x-fetch-all))
 
 ;; useful for corfu and vertico extensions
 (defmacro use-extension (pkg name &rest args)
@@ -40,33 +68,11 @@
 `PKG' is the name of the package, `NAME' and `ARGS' are as with `use-package'"
   (declare (indent defun))
   `(use-package ,name
-     :straight nil
+     :elpaca nil
      :after ,pkg
      :demand t
      ,@args))
 
-(use-package diminish)
-
-;; emacs --batch -l "~/.emacs.d/init.el" -f "my/upgrade-packages"
-(defun my/upgrade-packages ()
-  "Upgrade all packages installed with straight."
-  (interactive)
-  (setq-local force-reload t)
-  (straight-pull-recipe-repositories)
-  (straight-x-fetch-all)
-  (while straight-x-running
-    (sleep-for 1))
-  (straight-merge-all)
-  (straight-check-all)
-  (straight-freeze-versions))
-
-;; emacs --batch -l "~/.emacs.d/init.el" -f "my/thaw-packages"
-(defun my/thaw-packages ()
-  "Restore all packages to the versions in the straight lockfile."
-  (interactive)
-  (setq-local force-reload t)
-  (straight-thaw-versions))
-
 (defun add-to-list* (list-var &rest elts)
   "Add `ELTS' to `LIST-VAR'."
   (dolist (elt elts)
diff --git a/.emacs.d/lisp/init-project.el b/.emacs.d/lisp/init-project.el
index 62f2630..2229eeb 100644
--- a/.emacs.d/lisp/init-project.el
+++ b/.emacs.d/lisp/init-project.el
@@ -136,7 +136,7 @@ mode as the current buffer (or do nothing)."
   ("C-x C-S-b" . persp-switch-buffer-same-mode)
   ("C-c x x" . persp-switch-last)
   ("C-c x ." . persp-switch-quick)
-  :hook (after-init . persp-mode))
+  :hook (elpaca-after-init . persp-mode))
 
 (provide 'init-project)
 ;;; init-project.el ends here
diff --git a/.emacs.d/lisp/init-smartparens.el b/.emacs.d/lisp/init-smartparens.el
index 0f96b64..2f2874d 100644
--- a/.emacs.d/lisp/init-smartparens.el
+++ b/.emacs.d/lisp/init-smartparens.el
@@ -16,12 +16,12 @@
   (sp-autoskip-closing-pair 'always)
   (sp-hybrid-kill-entire-symbol t)
   (sp-hybrid-kill-excessive-whitespace nil)
-  :hook (after-init . (lambda ()
-                        (smartparens-global-strict-mode)
-                        (show-smartparens-global-mode)
-                        (setq sp-paredit-bindings (delete '("M-?" . sp-convolute-sexp) sp-paredit-bindings))
-                        (require 'smartparens-config)
-                        (sp-use-paredit-bindings)))
+  :hook (elpaca-after-init . (lambda ()
+                               (smartparens-global-strict-mode)
+                               (show-smartparens-global-mode)
+                               (setq sp-paredit-bindings (delete '("M-?" . sp-convolute-sexp) sp-paredit-bindings))
+                               (require 'smartparens-config)
+                               (sp-use-paredit-bindings)))
   :config
   (sp-pair "\"" "\"" :wrap "M-\"")
   ;; From https://github.com/bodil/emacs.d/blob/master/bodil/bodil-paredit.el
diff --git a/.emacs.d/lisp/init-ui.el b/.emacs.d/lisp/init-ui.el
index 89bd8d8..b4d6888 100644
--- a/.emacs.d/lisp/init-ui.el
+++ b/.emacs.d/lisp/init-ui.el
@@ -4,23 +4,22 @@
 ;; Frame customisations, and disabling of {menu,tool,scoll}-bar-mode done in early-init.el, rather than here
 ;;; Code:
 
-(use-package emacs
+(use-feature emacs
   :hook
-  (emacs-startup . (lambda ()
-                     (cond
-                      ((find-font (font-spec :name "iosevka comfy"))
-                       (set-face-attribute 'default nil :font "iosevka comfy"))
-                      ((find-font (font-spec :name "iosevka"))
-                       (set-face-attribute 'default nil :font "iosevka")))
+  (elpaca-after-init . (lambda ()
+                         (cond
+                          ((find-font (font-spec :name "iosevka comfy"))
+                           (set-face-attribute 'default nil :font "iosevka comfy"))
+                          ((find-font (font-spec :name "iosevka"))
+                           (set-face-attribute 'default nil :font "iosevka")))
 
-                     (global-display-line-numbers-mode)
-                     (global-hl-line-mode +1)
+                         (global-display-line-numbers-mode)
+                         (global-hl-line-mode +1)
 
-                     (global-set-key (kbd "C-x C-S-k") 'kill-this-buffer)))
-  (after-init . (lambda ()
-                  (add-to-list 'custom-theme-load-path "~/.emacs.d/themes")
-                  (load-theme 'non-modo t)))
+                         (global-set-key (kbd "C-x C-S-k") 'kill-this-buffer)
 
+                         (add-to-list 'custom-theme-load-path "~/.emacs.d/themes")
+                         (load-theme 'non-modo t)))
   :config
   ;; https://github.com/rougier/elegant-emacs/blob/master/sanity.el
   (setq inhibit-startup-screen t
@@ -72,9 +71,9 @@
      ("FAIL"   . "red3")
      ("NOTE"   . "DarkOrange2")
      ("DEPRECATED" . "yellow")))
-  :hook (emacs-startup . global-hl-todo-mode))
+  :hook (elpaca-after-init . global-hl-todo-mode))
 
-(use-package whitespace
+(use-feature whitespace
   :diminish
   :custom
   (whitespace-line-column 120)
@@ -101,7 +100,7 @@
 (use-package idle-highlight-mode
   :hook (prog-mode . idle-highlight-mode))
 
-(use-package paren
+(use-feature paren
   :config
   (show-paren-mode +1))
 
@@ -113,12 +112,16 @@
 (use-package rainbow-delimiters
   :hook
   (text-mode . (lambda () (rainbow-delimiters-mode +1)))
-  (prog-mode . (lambda () (rainbow-delimiters-mode +1))))
+  (prog-mode . (lambda () (rainbow-delimiters-mode +1)))
+  (ielm-mode . (lambda () (rainbow-delimiters-mode +1))))
 
 (use-package rainbow-mode
-  :diminish)
+  :diminish
+  :hook
+  (emacs-lisp-mode . rainbow-mode)
+  (css-mode . rainbow-mode))
 
-(use-package repeat
+(use-feature repeat
   :defer 5
   :config
   (let ((inhibit-message t))
@@ -163,8 +166,9 @@
     (smartparens-strict-mode)))
 
 (use-package highlight-sexp
+  :elpaca (highlight-sexp :host github :repo "daimrod/highlight-sexp")
   :diminish
-  :custom (hl-sexp-background-color "grey10") ;; grey25 grey30 DarkBlue navy MidnightBlue DarkSlateBlue
+  :custom (hl-sexp-background-color "grey10")
   :hook
   (emacs-lisp-mode . highlight-sexp-mode)
   (clojure-mode . highlight-sexp-mode))
diff --git a/.emacs.d/lisp/init-web.el b/.emacs.d/lisp/init-web.el
index c89f45d..d82b9cb 100644
--- a/.emacs.d/lisp/init-web.el
+++ b/.emacs.d/lisp/init-web.el
@@ -21,11 +21,9 @@
   (add-to-list 'auto-mode-alist '("\\.jsp\\'" . web-mode))
   (add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode)))
 
-(use-package css-mode
+(use-feature css-mode
   :custom
-  (css-indent-offset 2)
-  :config
-  (rainbow-mode +1))
+  (css-indent-offset 2))
 
 (use-package scss-mode
   :config
diff --git a/.emacs.d/lisp/init-windows.el b/.emacs.d/lisp/init-windows.el
index 4cc7de4..95108b5 100644
--- a/.emacs.d/lisp/init-windows.el
+++ b/.emacs.d/lisp/init-windows.el
@@ -2,7 +2,7 @@
 ;;; Commentary:
 ;;; Code:
 
-(use-package emacs
+(use-feature emacs
   :custom
   (switch-to-buffer-obey-display-actions t)
   :bind
@@ -35,7 +35,7 @@
             (if this-win-2nd (other-window 1))))))
   (define-key ctl-x-4-map "t" 'toggle-window-split))
 
-(use-package winner
+(use-feature winner
   :defer 5
   :config
   (winner-mode +1)
@@ -47,7 +47,7 @@
   (dolist (cmd '(winner-undo winner-redo))
     (put cmd 'repeat-map 'winner-repeat-map)))
 
-(use-package windmove
+(use-feature windmove
   :defer 5
   :config (windmove-default-keybindings))
 
@@ -98,9 +98,9 @@
      help-mode
      helpful-mode
      compilation-mode))
-  :hook (emacs-startup . (lambda ()
-                           (popper-mode +1)
-                           (popper-echo-mode +1))))
+  :hook (elpaca-after-init . (lambda ()
+                               (popper-mode +1)
+                               (popper-echo-mode +1))))
 
 (use-package frog-jump-buffer
   :config
@@ -163,7 +163,7 @@
     (let ((inhibit-message t))
       (buffer-ring-add (persp-current-name))))
   :hook
-  (emacs-startup . buffer-ring-mode)
+  (elpaca-after-init . buffer-ring-mode)
   (persp-created . persp-buffer-ring-create-and-switch)
   (persp-switch . persp-buffer-ring-switch)
   :bind