about summary refs log tree commit diff stats
path: root/.emacs.d
diff options
context:
space:
mode:
Diffstat (limited to '.emacs.d')
-rw-r--r--.emacs.d/.gitignore2
-rw-r--r--.emacs.d/early-init.el7
-rw-r--r--.emacs.d/lisp/init-clojure.el16
-rw-r--r--.emacs.d/lisp/init-completion.el33
-rw-r--r--.emacs.d/lisp/init-crux.el1
-rw-r--r--.emacs.d/lisp/init-editor.el19
-rw-r--r--.emacs.d/lisp/init-git.el5
-rw-r--r--.emacs.d/lisp/init-lsp.el33
-rw-r--r--.emacs.d/lisp/init-minibuffer.el25
-rw-r--r--.emacs.d/lisp/init-navigation.el9
-rw-r--r--.emacs.d/lisp/init-packages.el16
-rw-r--r--.emacs.d/lisp/init-project.el1
-rw-r--r--.emacs.d/lisp/init-shell.el36
-rw-r--r--.emacs.d/lisp/init-sql.el1
-rw-r--r--.emacs.d/lisp/init-ui.el2
-rw-r--r--.emacs.d/themes/non-modo-theme.el2
16 files changed, 136 insertions, 72 deletions
diff --git a/.emacs.d/.gitignore b/.emacs.d/.gitignore
index 11659a7..2ce66c1 100644
--- a/.emacs.d/.gitignore
+++ b/.emacs.d/.gitignore
@@ -36,7 +36,7 @@ site-lisp
 straight
 !straight/versions
 elpaca
-elpa
+elpaca.lock
 eln-cache
 forge-database.sqlite
 sql
diff --git a/.emacs.d/early-init.el b/.emacs.d/early-init.el
index 1dd7a01..e55becc 100644
--- a/.emacs.d/early-init.el
+++ b/.emacs.d/early-init.el
@@ -2,6 +2,10 @@
 ;;; Commentary:
 ;;; Code:
 
+
+(when (eq system-type 'darwin)
+  (setq frame-resize-pixelwise t))
+
 (setq gc-cons-threshold most-positive-fixnum
       gc-cons-percentage 0.6)
 
@@ -21,7 +25,8 @@
 
 (setq frame-inhibit-implied-resize t)
 
-(unless (eq system-type 'darwin)
+(if (eq system-type 'darwin)
+    (add-to-list 'default-frame-alist '(undecorated-round . t))
   (toggle-frame-maximized)
   (add-to-list 'default-frame-alist '(fullscreen . maximized)))
 
diff --git a/.emacs.d/lisp/init-clojure.el b/.emacs.d/lisp/init-clojure.el
index c479836..7673565 100644
--- a/.emacs.d/lisp/init-clojure.el
+++ b/.emacs.d/lisp/init-clojure.el
@@ -102,12 +102,12 @@
   :init
   ;; Always show more of the path in clj buffer names.
   ;; Using setq-local in clojure-mode-hook is not enough, as it runs too late
-  (defun clj-uniquify-get-proposed-name (orig base dirname &optional depth original-dirname)
+  (defun clj-uniquify-get-proposed-name (orig base dirname &optional depth)
     (when (and (> (length base) 4)
                (string= ".clj" (substring base -4))
                (not (string= "project.clj" base)))
       (setq-local uniquify-min-dir-content 3))
-    (funcall orig base dirname depth original-dirname))
+    (funcall orig base dirname depth))
   (advice-add 'uniquify-get-proposed-name :around 'clj-uniquify-get-proposed-name)
   :hook
   (clojure-mode . clojure-mode-hook-fn))
@@ -152,10 +152,10 @@
     (cider-jack-in params))
   (defun load-debug-namespaces ()
     (interactive)
-    (cider-interactive-eval "(require 'snitch.core)" nil nil (cider--nrepl-pr-request-map))
-    (cider-interactive-eval "(require 'miracle.save)" nil nil (cider--nrepl-pr-request-map))
-    (cider-interactive-eval "(require 'sc.api)" nil nil (cider--nrepl-pr-request-map))
-    (cider-interactive-eval "(require '[debux.cs.core :refer [dbg dbgn dbgt]])" nil nil (cider--nrepl-pr-request-map)))
+    (cider-interactive-eval "(require 'snitch.core)" nil nil (cider--nrepl-pr-request-plist))
+    (cider-interactive-eval "(require 'miracle.save)" nil nil (cider--nrepl-pr-request-plist))
+    (cider-interactive-eval "(require 'sc.api)" nil nil (cider--nrepl-pr-request-plist))
+    (cider-interactive-eval "(require '[debux.cs.core :refer [dbg dbgn dbgt]])" nil nil (cider--nrepl-pr-request-plist)))
   (defun cider-toggle-boolean ()
     (interactive)
     (let ((opposite (pcase (cider-symbol-at-point)
@@ -196,12 +196,14 @@
         cider-connection-message-fn nil
         cider-show-error-buffer 'except-in-repl
         cider-test-fail-fast nil
+        cider-download-java-sources t
         clojure-toplevel-inside-comment-form t)
   (setq cider-clojure-compilation-error-phases nil)
   (setq-default cider-use-overlays t)
   (unbind-key "C-c C-l" cider-mode-map)
   (unbind-key "C-c C-b" cider-mode-map)
   (unbind-key "C-c C-b" cider-repl-mode-map)
+  (unbind-key "M-." cider-repl-mode-map)
 
   (defun fix-duplicate-windows ()
     "When all windows are the same, delete all of them except the current one."
@@ -213,6 +215,8 @@
   (:map cider-mode-map
         ("C-c M-l" . cider-load-file)
         ("C-c M-b" . cider-interrupt)
+        ("C-c C-j C-;" . cider-pprint-eval-last-sexp-to-comment)
+        ("C-c C-M-p" . cider-pprint-eval-last-sexp-to-repl)
         ("C-x M-i e" . cider-inspect-last-sexp)
         ("C-x M-i f" . cider-inspect-defun-at-point)
         ("C-x M-i l" . cider-inspect-last-result)
diff --git a/.emacs.d/lisp/init-completion.el b/.emacs.d/lisp/init-completion.el
index f7e07de..16eca6b 100644
--- a/.emacs.d/lisp/init-completion.el
+++ b/.emacs.d/lisp/init-completion.el
@@ -14,17 +14,10 @@
           (list '+elpaca-unload-dabbrev 'elpaca--activate-package)))
 
 (use-feature dabbrev
-  ;; Load newer version until 30.1 is released
-  ;; https://mail.gnu.org/archive/html/bug-gnu-emacs/2024-05/msg00422.html
-  ;; Relies on the fact that the emacs repo is checked out to elpaca/repos/project
-  :ensure `(dabbrev :build ,(+elpaca-dabbrev-build-steps) :repo "~/.emacs.d/elpaca/repos/project/" :files ("lisp/dabbrev.el"))
   :custom
   (dabbrev-case-distinction nil)
   (dabbrev-case-fold-search t)
-  (dabbrev-case-replace nil)
-  ;; TODO remove this after 30.1
-  :bind
-  ("C-M-/" . hippie-expand))
+  (dabbrev-case-replace nil))
 
 (use-package mono-complete
   :config
@@ -56,12 +49,12 @@
                                       try-expand-line
                                       try-complete-lisp-symbol-partially
                                       try-complete-lisp-symbol))
-  :config
-  ;; Modified from https://www.emacswiki.org/emacs/HippieExpand#h5o-9
-  (define-advice he-substitute-string (:after (str &optional trans-case) he-paredit-fix)
-    "Remove extra bracket when expanding line in paredit/smartparents mode."
-    (if (and (or smartparens-mode paredit-mode) (string-match "[]})]$" str))
-        (progn (backward-delete-char 1) (forward-char))))
+  :hook (elpaca-after-init . (lambda ()
+                               ;; Modified from https://www.emacswiki.org/emacs/HippieExpand#h5o-9
+                               (define-advice he-substitute-string (:after (str &optional trans-case) he-paredit-fix)
+                                 "Remove extra bracket when expanding line in paredit/smartparents mode."
+                                 (if (and (or smartparens-mode paredit-mode) (string-match "[]})]$" str))
+                                     (progn (backward-delete-char 1) (forward-char))))))
   :bind
   ("C-M-/" . hippie-expand))
 
@@ -83,10 +76,6 @@
   (orderless-component-separator 'orderless-escapable-split-on-space)
   (completion-styles '(orderless partial-completion basic))
   (completion-category-defaults nil)
-  (completion-category-overrides '((file (styles partial-completion orderless))
-                                   (command (styles +orderless-with-strict-leading-initialism))
-                                   (variable (styles +orderless-with-strict-leading-initialism))
-                                   (symbol (styles +orderless-with-strict-leading-initialism))))
   (orderless-matching-styles '(orderless-literal orderless-regexp orderless-strict-initialism))
   (orderless-style-dispatchers (list #'+orderless-consult-dispatch
                                      #'orderless-affix-dispatch))
@@ -127,6 +116,7 @@ candidate, in that order, at the beginning of words, with
 no words in between, beginning with the first word."
     (orderless-strict-initialism component t))
 
+  ;; Replace initialism (,) with strict-leading-initialism, and also add strict initialism
   (setf (alist-get ?, orderless-affix-dispatch-alist) #'orderless-strict-leading-initialism)
   (add-to-list 'orderless-affix-dispatch-alist '(?` . orderless-strict-initialism) t)
 
@@ -156,7 +146,12 @@ no words in between, beginning with the first word."
 
   ;; Based on https://github.com/minad/consult/wiki#minads-orderless-configuration
   (orderless-define-completion-style +orderless-with-strict-leading-initialism
-    (orderless-matching-styles '(orderless-literal orderless-regexp orderless-strict-leading-initialism))))
+    (orderless-matching-styles '(orderless-literal orderless-regexp orderless-strict-leading-initialism)))
+
+  (setopt completion-category-overrides '((file (styles partial-completion orderless))
+                                          (command (styles +orderless-with-strict-leading-initialism))
+                                          (variable (styles +orderless-with-strict-leading-initialism))
+                                          (symbol (styles +orderless-with-strict-leading-initialism)))))
 
 ;; code completion - corfu
 (use-package corfu
diff --git a/.emacs.d/lisp/init-crux.el b/.emacs.d/lisp/init-crux.el
index 9d00417..5f7b836 100644
--- a/.emacs.d/lisp/init-crux.el
+++ b/.emacs.d/lisp/init-crux.el
@@ -15,6 +15,7 @@
   ("C-^" . crux-top-join-line)
   ("C-<backspace>" . crux-kill-line-backwards)
   ([remap kill-whole-line] . crux-kill-whole-line)
+  ([remap keyboard-quit] . crux-keyboard-quit-dwim)
   ;; TODO don't need all of these
   ("C-<return>" . crux-smart-open-line)
   ("S-<return>" . crux-smart-open-line)
diff --git a/.emacs.d/lisp/init-editor.el b/.emacs.d/lisp/init-editor.el
index 1143b59..fc575c4 100644
--- a/.emacs.d/lisp/init-editor.el
+++ b/.emacs.d/lisp/init-editor.el
@@ -116,6 +116,13 @@
   :config
   (when (string-suffix-p "aspell" ispell-program-name)
     (setq ispell-extra-args '("--sug-mode=ultra")))
+  (unbind-key "C-," flyspell-mode-map)
+  (unbind-key "C-." flyspell-mode-map)
+  ;;(unbind-key "C-;" flyspell-mode-map)
+  :custom (flyspell-auto-correct-binding (kbd "C-x C-M-;"))
+  :bind (:map flyspell-mode-map
+              ("C-x C-," . flyspell-goto-next-error)
+              ("C-x C-." . flyspell-correct-word))
   :hook
   (text-mode . flyspell-mode)
   (prog-mode . flyspell-prog-mode))
@@ -162,8 +169,6 @@
 
 (defun +elpaca-unload-xref (e)
   (and (featurep 'xref) (unload-feature 'xref t))
-  ;; Make sure xref-find-definitions doesn't override this embark binding (unless https://github.com/oantolin/embark/issues/732 can be fixed)
-  (bind-key "M-." 'embark-dwim)
   ;; Make sure these aren't overwritten
   (setq xref-search-program 'ripgrep
         xref-show-xrefs-function #'consult-xref
@@ -176,7 +181,7 @@
           (list '+elpaca-unload-xref 'elpaca--activate-package)))
 
 (use-package xref
-  :ensure `(xref :build ,(+elpaca-xref-build-steps))
+  :ensure `(xref :build ,(+elpaca-xref-build-steps) :ref "87db670d045bea2d90139b1f741eea8db7c193ea" :pin t)
   :custom
   (xref-search-program 'ripgrep)
   (xref-show-xrefs-function #'consult-xref)
@@ -214,9 +219,7 @@ With a prefix argument, moves up `current-prefix-arg' sexps first."
   (add-to-list 'xref-prompt-for-identifier 'xref-find-references-other-frame t)
   :bind
   ("C-c q" . xref-find-references-current-defun)
-  ("C-c C-M-." . xref-find-definitions-current-list-function)
-  ;; Make sure xref-find-definitions doesn't override this embark binding (unless https://github.com/oantolin/embark/issues/732 can be fixed)
-  ("M-." . embark-dwim))
+  ("C-c C-M-." . xref-find-definitions-current-list-function))
 
 (use-package ws-butler
   :diminish
@@ -306,5 +309,9 @@ With a prefix argument, moves up `current-prefix-arg' sexps first."
               ("x" . cider-eval-region)
               ("r" . cider-insert-region-in-repl)))
 
+(use-package repeat-fu
+  :bind ("M-+" . repeat-fu-execute)
+  :hook ((prog-mode text-mode) . repeat-fu-mode))
+
 (provide 'init-editor)
 ;;; init-editor.el ends here
diff --git a/.emacs.d/lisp/init-git.el b/.emacs.d/lisp/init-git.el
index 759c36c..10c9c78 100644
--- a/.emacs.d/lisp/init-git.el
+++ b/.emacs.d/lisp/init-git.el
@@ -77,6 +77,8 @@
   ("C-c g r" . my/magit-refresh-state)
   ("C-c g m" . my/magit-update-master)
   ("C-c g C-c" . my/magit-stage-and-commit-file)
+  ;; Used by eshell-prompt-function (see init-shell.el)
+  :commands (magit-get-shortname magit-file-status)
   :config
   ;; Requires the following gitconfig:
   ;; [alias]
@@ -338,6 +340,9 @@ 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-feature git-link-transient
+  :bind ("C-c g d" . git-link-dispatch))
+
 (use-feature git-related
   :bind
   ("C-c g #" . git-related-find-file)
diff --git a/.emacs.d/lisp/init-lsp.el b/.emacs.d/lisp/init-lsp.el
index 49ff138..9a0b4d5 100644
--- a/.emacs.d/lisp/init-lsp.el
+++ b/.emacs.d/lisp/init-lsp.el
@@ -56,7 +56,38 @@
         lsp-references-exclude-definition t
         ;; user cider for indendation and eldoc
         lsp-enable-indentation nil
-        lsp-eldoc-enable-hover nil))
+        lsp-eldoc-enable-hover nil)
+
+  ;; Copied from https://github.com/blahgeek/emacs-lsp-booster/blob/4200ed6ae0cd83b8e3fd1dbefb09121480951a22/README.md#configure-lsp-mode
+  (defun lsp-booster--advice-json-parse (old-fn &rest args)
+    "Try to parse bytecode instead of json."
+    (or
+     (when (equal (following-char) ?#)
+       (let ((bytecode (read (current-buffer))))
+         (when (byte-code-function-p bytecode)
+           (funcall bytecode))))
+     (apply old-fn args)))
+  (advice-add (if (progn (require 'json)
+                         (fboundp 'json-parse-buffer))
+                  'json-parse-buffer
+                'json-read)
+              :around
+              #'lsp-booster--advice-json-parse)
+  (defun lsp-booster--advice-final-command (old-fn cmd &optional test?)
+    "Prepend emacs-lsp-booster command to lsp CMD."
+    (let ((orig-result (funcall old-fn cmd test?)))
+      (if (and (not test?)                             ;; for check lsp-server-present?
+               (not (file-remote-p default-directory)) ;; see lsp-resolve-final-command, it would add extra shell wrapper
+               lsp-use-plists
+               (not (functionp 'json-rpc-connection))  ;; native json-rpc
+               (executable-find "emacs-lsp-booster"))
+          (progn
+            (when-let ((command-from-exec-path (executable-find (car orig-result))))  ;; resolve command from exec-path (in case not found in $PATH)
+              (setcar orig-result command-from-exec-path))
+            (message "Using emacs-lsp-booster for %s!" orig-result)
+            (cons "emacs-lsp-booster" orig-result))
+        orig-result)))
+  (advice-add 'lsp-resolve-final-command :around #'lsp-booster--advice-final-command))
 
 (provide 'init-lsp)
 ;;; init-lsp.el ends here
diff --git a/.emacs.d/lisp/init-minibuffer.el b/.emacs.d/lisp/init-minibuffer.el
index 93c18dd..118f730 100644
--- a/.emacs.d/lisp/init-minibuffer.el
+++ b/.emacs.d/lisp/init-minibuffer.el
@@ -82,18 +82,11 @@
              (eq 'file (vertico--metadata-get 'category)))
         (add-to-history minibuffer-history-variable (minibuffer-contents))))
 
-  ;; https://github.com/minad/vertico/wiki#customize-sorting-based-on-completion-category
-  (defun sort-directories-first (files)
-    ;; Still sort by history position, length and alphabetically
-    (setq files (vertico-sort-history-length-alpha files))
-    ;; But then move directories first
-    (nconc (seq-filter (lambda (x) (string-suffix-p "/" x)) files)
-           (seq-remove (lambda (x) (string-suffix-p "/" x)) files)))
   (defun toggle-sort-directories-first ()
     (interactive)
-    (if (eq vertico-sort-function 'sort-directories-first)
+    (if (eq vertico-sort-function 'vertico-sort-directories-first)
         (set (make-local-variable 'vertico-sort-function) 'vertico-sort-history-length-alpha)
-      (set (make-local-variable 'vertico-sort-function) 'sort-directories-first))
+      (set (make-local-variable 'vertico-sort-function) 'vertico-sort-directories-first))
     (setq vertico--input t)
     (vertico--update))
 
@@ -143,7 +136,8 @@
         '((execute-extended-command
            (+vertico-transform-functions . +vertico-highlight-enabled-mode))))
   (setq vertico-multiform-categories
-        '((file (+vertico-transform-functions . +vertico-highlight-directory))
+        '((file (+vertico-transform-functions . +vertico-highlight-directory)
+                (:keymap . vertico-directory-map))
           (imenu grid)))
   :bind (:map vertico-multiform-map
               ("M-H" . vertico-multiform-buffer-grid)))
@@ -521,6 +515,9 @@ The symbol at point is added to the future history."
 (use-package consult-ls-git
   :bind ("C-c g f" . consult-ls-git))
 
+(use-package consult-vc-modified-files
+  :bind (:map vc-prefix-map ("f" . consult-vc-modified-files)))
+
 (use-package consult-project-extra)
 
 (use-package marginalia
@@ -532,8 +529,9 @@ The symbol at point is added to the future history."
 (use-package embark
   :bind
   (("C-." . embark-act)
-   ("M-." . embark-dwim)
    ([remap xref-find-definitions-current-list-function] . embark-dwim-beginning-of-list)
+   ([remap xref-find-definitions] . embark-dwim)
+   ([remap xref-find-definitions-other-window] . embark-dwim-other-window)
    ("C-c C-o" . embark-export)
    ("C-h b" . embark-bindings)
    ("C-h B" . describe-bindings)
@@ -548,6 +546,11 @@ The symbol at point is added to the future history."
   :custom
   (prefix-help-command 'embark-prefix-help-command)
   :config
+  (defun embark-dwim-other-window ()
+    "Like `embark-dwim' but switch to the other window."
+    (interactive)
+    (other-window-prefix)
+    (embark-dwim))
   (defun embark-dwim-beginning-of-list ()
     "`embark-dwim' at the beginning of the current list.
 With a prefix argument, moves up `current-prefix-arg' sexps first."
diff --git a/.emacs.d/lisp/init-navigation.el b/.emacs.d/lisp/init-navigation.el
index e178d70..b407e7b 100644
--- a/.emacs.d/lisp/init-navigation.el
+++ b/.emacs.d/lisp/init-navigation.el
@@ -7,6 +7,13 @@
   (avy-all-windows nil)
   (avy-all-windows-alt t)
   (avy-timeout-seconds 0.3)
+  :init
+  ;; Allow C-[ to be bound (instead of being equivalent to ESC), but only in GUI Emacs
+  ;; https://emacs.stackexchange.com/a/52334
+  (let ((frame (framep (selected-frame))))
+    (or (eq  t  frame)
+        (eq 'pc frame)
+        (define-key input-decode-map (kbd "C-[") [control-bracketleft])))
   :config
   ;; https://karthinks.com/software/avy-can-do-anything/#avy-plus-embark-any-action-anywhere
   (defun avy-action-embark (pt)
@@ -38,7 +45,7 @@
   ("C-c C-;" . avy-copy-as-kill-in-line))
 
 (use-package casual-avy
-  :bind ("C-M-;" . casual-avy-tmenu))
+  :bind ([control-bracketleft] . casual-avy-tmenu))
 
 (use-package smartscan
   :custom (smartscan-symbol-selector "symbol")
diff --git a/.emacs.d/lisp/init-packages.el b/.emacs.d/lisp/init-packages.el
index ecc225e..55b3eb5 100644
--- a/.emacs.d/lisp/init-packages.el
+++ b/.emacs.d/lisp/init-packages.el
@@ -3,12 +3,12 @@
 ;;; Code:
 
 ;; Elpaca installer block
-(defvar elpaca-installer-version 0.8)
+(defvar elpaca-installer-version 0.11)
 (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 :depth 1
+                              :ref nil :depth 1 :inherit ignore
                               :files (:defaults "elpaca-test.el" (:exclude "extensions"))
                               :build (:not elpaca--activate-package)))
 (let* ((repo  (expand-file-name "elpaca/" elpaca-repos-directory))
@@ -18,7 +18,7 @@
   (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))
+    (when (<= emacs-major-version 28) (require 'subr-x))
     (condition-case-unless-debug err
         (if-let* ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*"))
                   ((zerop (apply #'call-process `("git" nil ,buffer t "clone"
@@ -38,7 +38,7 @@
   (unless (require 'elpaca-autoloads nil t)
     (require 'elpaca)
     (elpaca-generate-autoloads "elpaca" repo)
-    (load "./elpaca-autoloads")))
+    (let ((load-source-file-function nil)) (load "./elpaca-autoloads"))))
 (add-hook 'after-init-hook #'elpaca-process-queues)
 (elpaca `(,@elpaca-order))
 ;; End of elpaca installer block
@@ -164,14 +164,6 @@ using this command."
       (when package-features
         (message "Reloaded: %s" (mapconcat #'symbol-name package-features " "))))))
 
-(define-advice elpaca-merge (:after (id &optional _fetch _interactive) elpaca-merge-reload)
-  "Automically reload packages after they have been updated."
-  (cl-letf (((symbol-function 'yes-or-no-p) (cl-constantly t)))
-    (when (not (or (memq id elpaca-ignored-dependencies)
-                   ;; TODO why aren't xref and project already in the list?
-                   (memq id '(xref project perspective))))
-      (+elpaca-reload-package id))))
-
 ;; https://github.com/radian-software/radian/blob/e3aad124c8e0cc870ed09da8b3a4905d01e49769/emacs/radian.el#L352
 (defmacro use-feature (name &rest args)
   "Like `use-package', but without elpaca integration.
diff --git a/.emacs.d/lisp/init-project.el b/.emacs.d/lisp/init-project.el
index d2c7ca7..e66a4cd 100644
--- a/.emacs.d/lisp/init-project.el
+++ b/.emacs.d/lisp/init-project.el
@@ -5,6 +5,7 @@
 (require 'subr-x)
 
 (use-package project
+  :ensure (:ref "87db670d045bea2d90139b1f741eea8db7c193ea" :pin t)
   :config
   (defun project--clojure-switch-to-test (filename project-root)
     (let* ((project-src-file (string-remove-prefix project-root filename))
diff --git a/.emacs.d/lisp/init-shell.el b/.emacs.d/lisp/init-shell.el
index 8a64d4b..bf737cb 100644
--- a/.emacs.d/lisp/init-shell.el
+++ b/.emacs.d/lisp/init-shell.el
@@ -9,21 +9,31 @@
   (eshell-mode-hook . (lambda () (setenv "TERM" "xterm-256color")))
   :custom
   (eshell-directory-name (expand-file-name "eshell" save-dir))
+  ;; https://lambdaland.org/posts/2024-08-19_fancy_eshell_prompt/#eshell-prompt
+  (eshell-highlight-prompt nil)
+  (eshell-prompt-regexp "^[^#$\n]* [$#] ")
   (eshell-prompt-function
-   ;; Based on https://www.reddit.com/r/emacs/comments/6f0rkz/my_fancy_eshell_prompt/
    (lambda ()
-     (concat
-      (propertize "┌─[" 'face `(:foreground "green"))
-      (propertize (user-login-name) 'face `(:foreground "red"))
-      (propertize "@" 'face `(:foreground "green"))
-      (propertize (system-name) 'face `(:foreground "LightBlue"))
-      (propertize "]──[" 'face `(:foreground "green"))
-      (propertize (format-time-string "%H:%M" (current-time)) 'face `(:foreground "yellow"))
-      (propertize "]──[" 'face `(:foreground "green"))
-      (propertize (concat (eshell/pwd)) 'face `(:foreground "white"))
-      (propertize "]\n" 'face `(:foreground "green"))
-      (propertize "└─>" 'face `(:foreground "green"))
-      (propertize (if (= (user-uid) 0) " # " " $ ") 'face `(:foreground "green")))))
+     (let* ((cwd (abbreviate-file-name (eshell/pwd)))
+            (ref (magit-get-shortname "HEAD"))
+            (stat (magit-file-status))
+            (x-stat eshell-last-command-status)
+            (git-chunk
+             (if ref
+                 (format "%s%s%s "
+                         (propertize (if stat "[" "(") 'font-lock-face (list :foreground (if stat "red" "green")))
+                         (propertize ref 'font-lock-face '(:foreground "yellow"))
+                         (propertize (if stat "]" ")") 'font-lock-face (list :foreground (if stat "red" "green"))))
+               "")))
+       (propertize
+        (format "%s %s %s$ "
+                (if (< 0 x-stat) (format (propertize "!%s" 'font-lock-face '(:foreground "red")) x-stat)
+                  (propertize "➤" 'font-lock-face (list :foreground (if (< 0 x-stat) "red" "green"))))
+                (propertize cwd 'font-lock-face '(:foreground "#45babf"))
+                git-chunk)
+        'read-only t
+        'front-sticky   '(font-lock-face read-only)
+        'rear-nonsticky '(font-lock-face read-only)))))
   :config
   (setenv "PAGER" "cat"))
 
diff --git a/.emacs.d/lisp/init-sql.el b/.emacs.d/lisp/init-sql.el
index d1a3fe3..cf3a89a 100644
--- a/.emacs.d/lisp/init-sql.el
+++ b/.emacs.d/lisp/init-sql.el
@@ -49,6 +49,7 @@
   :bind ("C-c c C-u" . sqlup-capitalize-keywords-in-region))
 
 (use-package sql-indent
+  :diminish sqlind-minor-mode
   :commands sqlind-minor-mode)
 
 (use-package sqlformat
diff --git a/.emacs.d/lisp/init-ui.el b/.emacs.d/lisp/init-ui.el
index 354f187..50e9cdb 100644
--- a/.emacs.d/lisp/init-ui.el
+++ b/.emacs.d/lisp/init-ui.el
@@ -8,6 +8,8 @@
   :hook
   (elpaca-after-init . (lambda ()
                          (cond
+                          ((find-font (font-spec :name "aporetic serif mono"))
+                           (set-face-attribute 'default nil :font "aporetic serif mono"))
                           ((find-font (font-spec :name "iosevka comfy"))
                            (set-face-attribute 'default nil :font "iosevka comfy"))
                           ((find-font (font-spec :name "iosevka"))
diff --git a/.emacs.d/themes/non-modo-theme.el b/.emacs.d/themes/non-modo-theme.el
index c5f4422..4ef4a54 100644
--- a/.emacs.d/themes/non-modo-theme.el
+++ b/.emacs.d/themes/non-modo-theme.el
@@ -1479,7 +1479,7 @@
    `(shortdoc-section (())) ; remove the default's variable-pitch style
 ;;;;; show-paren-mode
    `(show-paren-match ((,class :inherit bold :background "#7416b5" :foreground "#ffffff" :underline t)))
-   `(show-paren-match-expression ((,class :background "#221044")))
+   `(show-paren-match-expression ((,class :background "grey12")))
    `(show-paren-mismatch ((,class :background "#a4202a" :foreground "#ffffff")))
 ;;;;; shr
    `(shr-abbreviation ((,class :foreground "#9d9def" :underline (:color "#5f6fff" :style wave))))