Merge remote-tracking branch 'origin/redbook'

This commit is contained in:
Joe Frikker
2026-09-06 22:50:16 +00:00
+110 -122
View File
@@ -840,7 +840,6 @@ These are just some general settings that apply everywhere. First, a few package
free-keys
ligature
mixed-pitch
perspective
popper
];
extraConfig = builtins.readFile ./emacs-global.el;
@@ -851,26 +850,9 @@ These are just some general settings that apply everywhere. First, a few package
Turn off some default settings that I don't find useful.
#+BEGIN_SRC elisp
(setopt inhibit-startup-screen t)
(setopt initial-scratch-message nil)
(setopt sentence-end-double-space nil)
(menu-bar-mode -1)
(scroll-bar-mode -1)
(tool-bar-mode -1)
(setopt make-backup-files nil)
(setopt split-width-threshold 200)
(setopt split-height-threshold nil)
(setopt display-buffer-base-action
'((display-buffer-reuse-window display-buffer-same-window
display-buffer-in-previous-window
display-buffer-use-some-window)))
(setopt view-read-only t)
(setopt save-interprogram-paste-before-kill t)
(setopt kill-whole-line t)
(delete-selection-mode t)
(column-number-mode t)
(setopt auto-save-default nil)
(setopt create-lockfiles nil)
(setopt enable-recursive-minibuffers t)
(setopt line-spacing 0.15)
@@ -881,6 +863,50 @@ Turn off some default settings that I don't find useful.
(tab-bar-mode)
#+END_SRC
Don't show the welcome screen, and keep the scratch buffer empty by default. These are not useful
after you've started emacs more than a few times.
#+begin_src elisp
(setopt inhibit-startup-screen t)
(setopt initial-scratch-message nil)
#+end_src
Turn off all the ugly graphical crap.
#+begin_src elisp
(menu-bar-mode -1)
(scroll-bar-mode -1)
(tool-bar-mode -1)
#+end_src
I don't find emacs's backup files useful, and they seem to litter my directories. I could maybe see
a use if I wasn't using git. But, git is so easy to use, that I pretty much use it everywhere. I
don't need a poor man's local history.
Also, why do I have to set so many variables just to get emacs to stop putting extra files
everywhere?
#+begin_src elisp
(setopt make-backup-files nil)
(setopt create-lockfiles nil)
(setopt auto-save-default nil)
#+end_src
Turn on ~view-mode~ automatically when the buffer is read-only. This just helps out with navigation
a bit. I almost want to open files read-only by default, just so I can use ~view-mode~ (maybe with
some other keybindings) all the time. But, I think one more invisible flag to manage is a bit much.
#+begin_src elisp
(setopt view-read-only t)
#+end_src
I don't really do anything with sentences. But, I also never put two spaces after a period. So, at
least this setting is correct.
#+begin_src elisp
(setopt sentence-end-double-space nil)
#+end_src
Make sure which-key mode is always on. The on-the-fly keymap help it gives is indespensable.
#+BEGIN_SRC elisp
@@ -909,23 +935,13 @@ already indented, then try to complete the thing at point." Recommended by [[htt
#+END_SRC
Set the cursor to be a bar. I'm not sure what the benefit would be of a block cursor, since the
current character isn't really "selected" like it would be in Helix. When I had God mode set up, I
switched to a block cursor during normal mode, just because I was so used to it from Helix and
Vim. Now, I don't think there's really a need to ever switch.
current character isn't really "selected" like it would be in Helix. I switch this to a box when in
god mode / read-only buffers, like vim would.
#+BEGIN_SRC elisp
(setq-default cursor-type 'bar)
#+END_SRC
Emacs is supposed to be all about automation (maybe?). There's basically never a case where I don't
want changes I've made to be immediately saved to disk. So let's have Emacs do that. There's still a
fairly long (~5 sec) delay before changes are saved, which is kind of annoying. Maybe I'll look into
that at some point?
#+BEGIN_SRC elisp
; (auto-save-visited-mode)
#+END_SRC
Repeat-mode takes care of eliminating some annoying duplicate keypresses. I mostly use repeat-mode
for two-character commands that need to be repeated; ~devil~ also has some single-key-with-modifier
repeats set up that only apply in that mode.
@@ -1012,6 +1028,9 @@ Set up a few project- / workspace-related key bindings.
("s-s" . tab-bar-switch-to-tab)))
#+END_SRC
#+RESULTS:
: tab-bar-switch-to-tab
Don't run a server. I'm not using this, I can always turn it back on if I need to.
#+BEGIN_SRC elisp
@@ -1068,52 +1087,59 @@ content to be.
(setq child (window-next-sibling child)))
(reverse result)))
(defun jf/enforce-right-side-heights (win)
(let ((slot-heights '((-1 . 20)))
(parent (window-parent win)))
(when parent
(let ((children (jf/window-children parent)))
(when (> (length children) 1)
(cl-loop for child in children
for slot = (window-parameter child 'window-slot)
for height = (alist-get slot slot-heights)
when height do (progn (window-resize child (- height (window-height child)))
(window-preserve-size child nil t))))))))
(defun jf/window-main-root (&optional frame)
"Return FRAME's main (non-side) window or window subtree."
(let* ((root (frame-root-window (or frame (selected-frame))))
(children (jf/window-children root)))
(if (seq-some (lambda (w) (window-parameter w 'window-side)) children)
(seq-find (lambda (w) (not (window-parameter w 'window-side))) children)
root)))
(defun jf/enforce-right-side-width (win)
"Resize side window WIN so its frame keeps 120 columns for the rest of the frame."
(let ((width (max 1 (- (frame-width (window-frame win)) 120))))
(window-resize win (- width (window-width win)) t)))
(defun jf/window-leaves (window)
"Return the live leaf windows in WINDOW's subtree."
(if (window-live-p window)
(list window)
(mapcan #'jf/window-leaves (jf/window-children window))))
(defun jf/enforce-right-side-widths (frame)
"Re-apply `jf/enforce-right-side-width' to all of FRAME's right-side windows."
(dolist (win (window-list frame 'nomini))
(when (eq (window-parameter win 'window-side) 'right)
(jf/enforce-right-side-width win))))
(defun jf/topright-window (windows)
"Return whichever of WINDOWS sits furthest up, then furthest right."
(car (sort (copy-sequence windows)
(lambda (a b)
(let ((top-a (nth 1 (window-edges a)))
(top-b (nth 1 (window-edges b))))
(if (= top-a top-b)
(> (nth 0 (window-edges a)) (nth 0 (window-edges b)))
(< top-a top-b)))))))
(add-hook 'window-size-change-functions #'jf/enforce-right-side-widths)
(defun jf/display-buffer-right (buffer alist)
"Display BUFFER on the right of the main editing area.
;; (require 'perspective)
;; (setopt persp-mode-prefix-key (kbd "C-x t"))
;; (setopt persp-show-modestring nil)
;; (persp-mode)
Applies three rules, based on the shape of the frame's non-side windows:
1. One window -> split it and show BUFFER in the new right window.
2. Two windows side-by-side -> show BUFFER in the right one. If the
right window is selected, swap the two windows first (keeping
focus on the buffer that was active) so BUFFER doesn't evict it.
3. Any other layout -> show BUFFER in the upper-rightmost window."
(let ((main (jf/window-main-root)))
(cond
((window-live-p main)
(let* ((new (split-window main nil 'right))
(width (max 1 (- (frame-width) 120)))
(delta (window-resizable new (- width (window-width new)) t)))
(window-resize new delta t)
(window--display-buffer buffer new 'window alist)))
((and (window-left-child main)
(= (length (jf/window-children main)) 2)
(seq-every-p #'window-live-p (jf/window-children main)))
(let* ((left (window-left-child main))
(right (window-next-sibling left)))
(when (eq (selected-window) right)
(window-swap-states left right)
(select-window left))
(window--display-buffer buffer right 'reuse alist)))
(t
(window--display-buffer buffer (jf/topright-window (jf/window-leaves main)) 'reuse alist)))))
;; (defun jf/popper-group-by-owning-perspective ()
;; "Return the name of the perspective that owns the current buffer.
;; Unlike `popper-group-by-perspective', which just returns whichever
;; perspective happens to be active on the frame right now, this looks
;; up which perspective's buffer list the popup buffer actually belongs
;; to. This matters because popper re-groups popups on
;; `window-configuration-change-hook', which perspective.el triggers
;; *after* switching the frame's active perspective -- so
;; `popper-group-by-perspective' ends up filing a popup under the
;; perspective you just switched *to* rather than the one it came from."
;; (let ((buf (current-buffer)))
;; (or (cl-loop for persp being the hash-values of (perspectives-hash (selected-frame))
;; if (memq buf (persp-buffers persp))
;; return (persp-name persp))
;; (persp-current-name))))
(setopt popper-reference-buffers
'("\\*Flymake diagnostics .*"
@@ -1138,7 +1164,6 @@ content to be.
"\\*List .*"
"\\*eldoc\\*"))
(setopt popper-display-control nil)
;; (setopt popper-group-function 'jf/popper-group-by-owning-perspective)
(popper-mode)
(popper-echo-mode)
@@ -1227,6 +1252,13 @@ falls back to the outer one first."
(advice-add 'quit-window :around #'jf/quit-window-restore-fullscreen)
(setopt split-width-threshold 200)
(setopt split-height-threshold nil)
(setopt display-buffer-base-action
'((display-buffer-reuse-window display-buffer-same-window
display-buffer-in-previous-window
display-buffer-use-some-window)))
(setq display-buffer-alist
'(((or "magit: *"
"magit-log*"
@@ -1259,25 +1291,10 @@ falls back to the outer one first."
"new-pullreq"
"\\*claude:.*"
"\\*Man .*"
"\\*List .*")
(display-buffer-in-side-window)
(side . right)
(slot . 0)
(window-width . jf/enforce-right-side-width)
(window-height . jf/enforce-right-side-heights)
(preserve-size . (nil . nil))
(window-parameters (no-delete-other-windows . t)
(no-other-window . t)))
((or "\\*Embark Actions\\*"
"\\*List .*"
"\\*Embark Actions\\*"
"\\*eldoc\\*")
(display-buffer-in-side-window)
(side . right)
(slot . -1)
(window-width . jf/enforce-right-side-width)
(window-height . jf/enforce-right-side-heights)
(preserve-size . (nil . t))
(window-parameters (no-delete-other-windows . t)
(no-other-window . t)))))
(jf/display-buffer-right))))
(setopt window-persistent-parameters
(cl-list* '(no-delete-other-windows . writable)
@@ -1425,7 +1442,7 @@ Just "silently" wrap when searching at the bottom of a document.
programs.emacs = {
enable = true;
extraPackages = epkgs: with epkgs; [
# bufferlo
buffer-terminator
];
extraConfig = builtins.readFile ./emacs-workflow.el;
};
@@ -1433,24 +1450,10 @@ Just "silently" wrap when searching at the bottom of a document.
#+END_SRC
#+BEGIN_SRC elisp
;; (bufferlo-mode)
;; (setopt bufferlo-include-buried-buffers nil)
;; (with-eval-after-load 'bufferlo
;; (setq mode-line-misc-info
;; (assq-delete-all 'bufferlo-mode mode-line-misc-info)))
;; (defun my/bury-or-kill-buffer ()
;; (interactive)
;; (bury-buffer)
;; (bufferlo-kill-orphan-buffers))
(buffer-terminator-mode 1)
(bind-keys
("s-b" . consult-buffer)
;; ("C-x t 0" . bufferlo-tab-close-kill-buffers)
;; ("C-x k" . my/bury-or-kill-buffer)
)
("s-b" . consult-project-buffer))
#+END_SRC
** Language Support
@@ -1929,21 +1932,6 @@ for completion. That makes it really annoying to use; don't use yasnippet with e
(eval-when-compile
(require 'consult))
;; (require 'perspective)
;; (with-eval-after-load 'consult
;; (consult-customize
;; consult-theme :preview-key '(:debounce 0.2 any)
;; consult-ripgrep consult-git-grep consult-grep consult-man
;; consult-bookmark consult-recent-file consult-xref
;; consult-source-bookmark consult-source-file-register
;; consult-source-recent-file
;; consult-source-buffer
;; ;; :preview-key "M-."
;; consult-source-project-recent-file
;; :preview-key '(:debounce 0.4 any))
;; (consult-customize consult-source-buffer :hidden t :default nil)
;; (add-to-list 'consult-buffer-sources persp-consult-source))
(with-eval-after-load 'consult
(consult-customize
consult-theme :preview-key '(:debounce 0.2 any)