From db1b86cbd752cd26ba39874a38fc8bf5e25703ea Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Fri, 12 Jun 2026 22:44:14 -0400 Subject: [PATCH 01/21] evil --- home.org | 138 ++++++------------------------------------------------- 1 file changed, 13 insertions(+), 125 deletions(-) diff --git a/home.org b/home.org index 187485e..46f2a3c 100644 --- a/home.org +++ b/home.org @@ -1006,11 +1006,11 @@ This configuration affects general text editing, across all modes. First, some p enable = true; extraPackages = epkgs: with epkgs; [ avy - devil edit-indirect embark - god-mode - meow + evil + evil-collection + evil-org string-inflection ]; extraConfig = builtins.readFile ./emacs-editing.el; @@ -1029,130 +1029,18 @@ but I'm worried that having too many repeat maps will also be annoying (I'll hav cancel them more frequently). In the end, I opted for Devil mode. It avoids modifier keys, and has its own devil-mode-only repeat maps that don't interfere when using normal modifier key sequences. -#+BEGIN_SRC elisp :tangle nil - (use-package devil - :disable t - :config - (global-devil-mode) - (setq devil-repeatable-keys - '(("%k /") - ("%k d") - ("%k k") - ("%k m ^") - ("%k m b" "%k m f" "%k m a" "% k m e") - ("%k m @" "%k m h") - ("%k m y") - ("%k p" "%k n" "%k b" "%k f" "%k a" "%k e") - ("%k s") - ("%k m d" "%k m ")))) -#+END_SRC - -#+BEGIN_SRC elisp - (defun meow-setup () - (setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty) - (meow-motion-define-key - '("j" . meow-next) - '("k" . meow-prev) - '("" . ignore)) - (meow-leader-define-key - ;; Use SPC (0-9) for digit arguments. - '("1" . meow-digit-argument) - '("2" . meow-digit-argument) - ;; '("3" . meow-digit-argument) - ;; '("4" . meow-digit-argument) - ;; '("5" . meow-digit-argument) - ;; '("6" . meow-digit-argument) - ;; '("7" . meow-digit-argument) - ;; '("8" . meow-digit-argument) - ;; '("9" . meow-digit-argument) - ;; '("0" . meow-digit-argument) - ;; '("/" . meow-keypad-describe-key) - ;; '("?" . meow-cheatsheet)) - ;; (meow-normal-define-key - ;; '("0" . meow-expand-0) - ;; '("9" . meow-expand-9) - ;; '("8" . meow-expand-8) - ;; '("7" . meow-expand-7) - ;; '("6" . meow-expand-6) - ;; '("5" . meow-expand-5) - ;; '("4" . meow-expand-4) - ;; '("3" . meow-expand-3) - ;; '("2" . meow-expand-2) - ;; '("1" . meow-expand-1) - ;; '("-" . negative-argument) - ;; '(";" . meow-reverse) - ;; '("," . meow-inner-of-thing) - ;; '("." . meow-bounds-of-thing) - ;; '("[" . meow-beginning-of-thing) - ;; '("]" . meow-end-of-thing) - ;; '("a" . meow-append) - ;; '("A" . meow-open-below) - ;; '("b" . meow-back-word) - ;; '("B" . meow-back-symbol) - ;; '("c" . meow-change) - ;; '("d" . meow-delete) - ;; '("D" . meow-backward-delete) - ;; '("e" . meow-next-word) - ;; '("E" . meow-next-symbol) - ;; '("f" . meow-find) - ;; '("g" . meow-cancel-selection) - ;; '("G" . meow-grab) - ;; '("h" . meow-left) - ;; '("H" . meow-left-expand) - ;; '("i" . meow-insert) - ;; '("I" . meow-open-above) - ;; '("j" . meow-next) - ;; '("J" . meow-next-expand) - ;; '("k" . meow-prev) - ;; '("K" . meow-prev-expand) - ;; '("l" . meow-right) - ;; '("L" . meow-right-expand) - ;; '("m" . meow-join) - ;; '("n" . meow-search) - ;; '("o" . meow-block) - ;; '("O" . meow-to-block) - ;; '("p" . meow-yank) - ;; '("q" . meow-quit) - ;; '("Q" . meow-goto-line) - ;; '("r" . meow-replace) - ;; '("R" . meow-swap-grab) - ;; '("s" . meow-kill) - ;; '("t" . meow-till) - ;; '("u" . meow-undo) - ;; '("U" . meow-undo-in-selection) - ;; '("v" . meow-visit) - ;; '("w" . meow-mark-word) - ;; '("W" . meow-mark-symbol) - ;; '("x" . meow-line) - ;; '("X" . meow-goto-line) - ;; '("y" . meow-save) - ;; '("Y" . meow-sync-grab) - ;; '("z" . meow-pop-selection) - ;; '("'" . repeat) - ;; '("" . ignore))) - - ;; (require 'meow) - ;; (meow-setup) - ;; (meow-global-mode) -#+END_SRC - #+BEGIN_SRC elisp - (require 'god-mode) - (require 'which-key) + (setopt evil-want-keybinding nil) + (require 'evil) + (evil-mode 1) + (require 'evil-collection) + (evil-collection-init) - (bind-keys :map god-local-mode-map - ("i" . (lambda () (interactive) (god-mode-all -1))) - ("z" . repeat)) - (bind-keys ("" . (lambda () (interactive) (god-mode-all 1)))) - (defun my-god-mode-update-cursor-type () - (setq cursor-type (cond - (org-present-mode nil) - ((or (and (featurep 'god-mode) god-local-mode) buffer-read-only - (and meow-mode (not (eq 'insert meow--current-state)))) 'box) - (t 'bar)))) - - (add-hook 'post-command-hook 'my-god-mode-update-cursor-type) - (which-key-enable-god-mode-support) + (require 'evil-org) + (add-hook 'org-mode-hook 'evil-org-mode) + (evil-org-set-key-theme '(navigation insert textobjects additional calendar)) + (require 'evil-org-agenda) + (evil-org-agenda-set-keys) #+END_SRC Avy allows jumping to any place on the screen with just a few keystrokes. I've stolen most of these From e52adbbc4bd9ed59bedaefa83853688cb4b61a97 Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Wed, 17 Jun 2026 15:42:52 -0400 Subject: [PATCH 02/21] Splitting out shibumi deps --- flake.nix | 10 ++++----- home.org | 64 +++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/flake.nix b/flake.nix index 702f6fe..5d77e93 100644 --- a/flake.nix +++ b/flake.nix @@ -50,13 +50,11 @@ modules = [ nix-index-database.homeModules.default + "${modules}/base.nix" + "${modules}/desktop.nix" + "${modules}/shibumi.nix" + "${modules}/shibumi-desktop.nix" ] ++ - (pkgs.lib.filter - (n: pkgs.lib.strings.hasSuffix ".nix" n) - (pkgs.lib.filesystem.listFilesRecursive "${modules}/base")) ++ - (pkgs.lib.filter - (n: pkgs.lib.strings.hasSuffix ".nix" n) - (pkgs.lib.filesystem.listFilesRecursive "${modules}/desktop")) ++ [{ home.stateVersion = "22.05"; home.username = "jfrikker"; diff --git a/home.org b/home.org index 46f2a3c..bdb04d9 100644 --- a/home.org +++ b/home.org @@ -1,5 +1,38 @@ #+PROPERTY: header-args :mkdirp yes #+PROPERTY: header-args:elisp :lexical t +* Categories + +#+BEGIN_SRC nix :tangle target/base.nix + {lib, ...}: { + imports = lib.filter + (n: lib.strings.hasSuffix ".nix" n) + (lib.filesystem.listFilesRecursive ./base); + } +#+END_SRC + +#+BEGIN_SRC nix :tangle target/desktop.nix + {lib, ...}: { + imports = lib.filter + (n: lib.strings.hasSuffix ".nix" n) + (lib.filesystem.listFilesRecursive ./desktop); + } +#+END_SRC + +#+BEGIN_SRC nix :tangle target/shibumi.nix + {lib, ...}: { + imports = lib.filter + (n: lib.strings.hasSuffix ".nix" n) + (lib.filesystem.listFilesRecursive ./shibumi); + } +#+END_SRC + +#+BEGIN_SRC nix :tangle target/shibumi-desktop.nix + {lib, ...}: { + imports = lib.filter + (n: lib.strings.hasSuffix ".nix" n) + (lib.filesystem.listFilesRecursive ./shibumi-desktop); + } +#+END_SRC * Packages Home-manager "packages" are simply binaries that are placed on the path, without any attached @@ -90,6 +123,7 @@ tools. They boost better speed, or simply more streamlined features. dust fd ripgrep + tokei xh ]; } @@ -133,7 +167,7 @@ between them. Once installed, the actual command is ~wormhole~. These are the other programs I have installed globally. A few (like ~awscli~, ~mysql-client~, etc.) are still Shibumi-specific; ideally I'd find another way to install them. - #+BEGIN_SRC nix :tangle target/base/other-packages.nix + #+BEGIN_SRC nix :tangle target/shibumi/other-packages.nix {pkgs, kube, ...}: { home.packages = with pkgs; [ @@ -142,9 +176,7 @@ are still Shibumi-specific; ideally I'd find another way to install them. kube kubectl mariadb.client - nerd-fonts.jetbrains-mono openssh - tokei ]; fonts.fontconfig.enable = true; @@ -158,17 +190,26 @@ These programs require a full desktop environment: { home.packages = with pkgs; [ google-chrome + nerd-fonts.jetbrains-mono (iosevka-bin.override { variant = "Aile"; }) (iosevka-bin.override { variant = "Etoile"; }) (iosevka-bin.override { variant = "SGr-IosevkaTerm"; }) keymapp proton-pass - slack wireshark ]; } #+END_SRC +#+BEGIN_SRC nix :tangle target/shibumi-desktop/desktop-packages.nix + {pkgs, ...}: + { + home.packages = with pkgs; [ + slack + ]; + } +#+END_SRC + * Program Configurations This section contains applications whose config files will be generated by Home Manager. Home Manager calls these "programs" (as opposed to "packages", which are just binaries to put on the @@ -878,7 +919,8 @@ A basic ace-window setup. Allows switching between windows quickly (although avy #+BEGIN_SRC elisp (bind-keys ("M-o" . ace-window) - ("s-o" . ace-window)) + ("s-o" . ace-window) + ("C-c o" . ace-window)) (setopt aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)) (setopt aw-dispatch-always t) #+END_SRC @@ -1112,7 +1154,13 @@ Just "silently" wrap when searching at the bottom of a document. haskell-ts-mode jenkinsfile-mode jq-mode - lispy + (lispy.overrideAttrs { + packageRequires = [ + ace-window iedit swiper zoutline + ]; + ignoreCompilationError = true; + }) + lispyville lua-mode nix-mode rust-mode @@ -1294,6 +1342,8 @@ for completion. That makes it really annoying to use; don't use yasnippet with e (add-hook 'emacs-lisp-mode-hook (lambda () (lispy-mode 1))) (add-hook 'lisp-mode-hook (lambda () (lispy-mode 1))) (with-eval-after-load 'lispy + (require 'lispyville) + (add-hook 'lispy-mode-hook #'lispyville-mode) (bind-keys :map lispy-mode-map ("i" . (lambda () (interactive) @@ -1808,7 +1858,7 @@ for completion. That makes it really annoying to use; don't use yasnippet with e #+END_SRC #+BEGIN_SRC elisp - (autoload 'claude-code-command-map "claude-code" :type 'keymap) + (require 'claude-code) (keymap-global-set "C-c c" claude-code-command-map) #+END_SRC * Theme From ed88afe698a8ce15ade129e5baeb88d045e6580f Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Fri, 19 Jun 2026 18:33:43 -0400 Subject: [PATCH 03/21] wip --- home.org | 1 + 1 file changed, 1 insertion(+) diff --git a/home.org b/home.org index bdb04d9..4b851a9 100644 --- a/home.org +++ b/home.org @@ -913,6 +913,7 @@ Use variable-width fonts in text buffers. ~mixed-pitch-mode~ keeps most code blo (add-hook 'yaml-ts-mode-hook 'no-mixed-pitch) (add-hook 'mhtml-mode 'no-mixed-pitch) + (add-hook 'nxml-mode 'no-mixed-pitch) #+END_SRC A basic ace-window setup. Allows switching between windows quickly (although avy can do the same...). From b7912eef52f708099594e88eda5413bc30b89bec Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Fri, 19 Jun 2026 18:38:22 -0400 Subject: [PATCH 04/21] Redbook --- home.org | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/home.org b/home.org index 4b851a9..6718d07 100644 --- a/home.org +++ b/home.org @@ -18,19 +18,19 @@ } #+END_SRC -#+BEGIN_SRC nix :tangle target/shibumi.nix +#+BEGIN_SRC nix :tangle target/redbook.nix {lib, ...}: { imports = lib.filter (n: lib.strings.hasSuffix ".nix" n) - (lib.filesystem.listFilesRecursive ./shibumi); + (lib.filesystem.listFilesRecursive ./redbook); } #+END_SRC -#+BEGIN_SRC nix :tangle target/shibumi-desktop.nix +#+BEGIN_SRC nix :tangle target/redbook-desktop.nix {lib, ...}: { imports = lib.filter (n: lib.strings.hasSuffix ".nix" n) - (lib.filesystem.listFilesRecursive ./shibumi-desktop); + (lib.filesystem.listFilesRecursive ./redbook-desktop); } #+END_SRC @@ -165,9 +165,9 @@ between them. Once installed, the actual command is ~wormhole~. #+end_src These are the other programs I have installed globally. A few (like ~awscli~, ~mysql-client~, etc.) -are still Shibumi-specific; ideally I'd find another way to install them. +are still Redbook-specific; ideally I'd find another way to install them. - #+BEGIN_SRC nix :tangle target/shibumi/other-packages.nix + #+BEGIN_SRC nix :tangle target/redbook/other-packages.nix {pkgs, kube, ...}: { home.packages = with pkgs; [ @@ -201,7 +201,7 @@ These programs require a full desktop environment: } #+END_SRC -#+BEGIN_SRC nix :tangle target/shibumi-desktop/desktop-packages.nix +#+BEGIN_SRC nix :tangle target/redbook-desktop/desktop-packages.nix {pkgs, ...}: { home.packages = with pkgs; [ @@ -313,7 +313,7 @@ We all know what ~git~ does. programs.git = { enable = true; settings.user.name = "Joe Frikker"; - settings.user.email = "joe.frikker@shibumi.com"; + settings.user.email = "joe@redbookcattle.com"; }; programs.delta = { From d0d340e04f5bb8e987848189d01d5dce76b5798d Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Fri, 19 Jun 2026 18:39:46 -0400 Subject: [PATCH 05/21] shibumi -> redbook --- flake.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.nix b/flake.nix index 5d77e93..0d616a9 100644 --- a/flake.nix +++ b/flake.nix @@ -41,7 +41,7 @@ ''; }; in { - homeConfigurations.shibumi = + homeConfigurations.redbook = let pkgs = import nixpkgs { system = "aarch64-darwin"; config.allowUnfree = true; }; modules = modules-for-system pkgs; in home-manager.lib.homeManagerConfiguration { @@ -52,8 +52,8 @@ nix-index-database.homeModules.default "${modules}/base.nix" "${modules}/desktop.nix" - "${modules}/shibumi.nix" - "${modules}/shibumi-desktop.nix" + "${modules}/redbook.nix" + "${modules}/redbook-desktop.nix" ] ++ [{ home.stateVersion = "22.05"; From 50d27458af785fc16ff926dada2d00844dd7eb21 Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Tue, 23 Jun 2026 22:54:08 -0400 Subject: [PATCH 06/21] no evil --- home.org | 50 ++++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/home.org b/home.org index 6718d07..832f6c6 100644 --- a/home.org +++ b/home.org @@ -191,6 +191,7 @@ These programs require a full desktop environment: home.packages = with pkgs; [ google-chrome nerd-fonts.jetbrains-mono + nerd-fonts.symbols-only (iosevka-bin.override { variant = "Aile"; }) (iosevka-bin.override { variant = "Etoile"; }) (iosevka-bin.override { variant = "SGr-IosevkaTerm"; }) @@ -314,6 +315,7 @@ We all know what ~git~ does. enable = true; settings.user.name = "Joe Frikker"; settings.user.email = "joe@redbookcattle.com"; + settings.github.user = "joe@redbookcattle.com"; }; programs.delta = { @@ -1051,9 +1053,9 @@ This configuration affects general text editing, across all modes. First, some p avy edit-indirect embark - evil - evil-collection - evil-org + # evil + # evil-collection + # evil-org string-inflection ]; extraConfig = builtins.readFile ./emacs-editing.el; @@ -1073,17 +1075,17 @@ cancel them more frequently). In the end, I opted for Devil mode. It avoids modi its own devil-mode-only repeat maps that don't interfere when using normal modifier key sequences. #+BEGIN_SRC elisp - (setopt evil-want-keybinding nil) - (require 'evil) - (evil-mode 1) - (require 'evil-collection) - (evil-collection-init) + ;; (setopt evil-want-keybinding nil) + ;; (require 'evil) + ;; (evil-mode 1) + ;; (require 'evil-collection) + ;; (evil-collection-init) - (require 'evil-org) - (add-hook 'org-mode-hook 'evil-org-mode) - (evil-org-set-key-theme '(navigation insert textobjects additional calendar)) - (require 'evil-org-agenda) - (evil-org-agenda-set-keys) + ;; (require 'evil-org) + ;; (add-hook 'org-mode-hook 'evil-org-mode) + ;; (evil-org-set-key-theme '(navigation insert textobjects additional calendar)) + ;; (require 'evil-org-agenda) + ;; (evil-org-agenda-set-keys) #+END_SRC Avy allows jumping to any place on the screen with just a few keystrokes. I've stolen most of these @@ -1161,7 +1163,7 @@ Just "silently" wrap when searching at the bottom of a document. ]; ignoreCompilationError = true; }) - lispyville + # lispyville lua-mode nix-mode rust-mode @@ -1339,18 +1341,18 @@ for completion. That makes it really annoying to use; don't use yasnippet with e #+BEGIN_SRC elisp (setopt inferior-lisp-program "sbcl") - (setopt lispy-compat '(god-mode edebug)) + ;; (setopt lispy-compat '(god-mode edebug)) (add-hook 'emacs-lisp-mode-hook (lambda () (lispy-mode 1))) (add-hook 'lisp-mode-hook (lambda () (lispy-mode 1))) - (with-eval-after-load 'lispy - (require 'lispyville) - (add-hook 'lispy-mode-hook #'lispyville-mode) - (bind-keys :map lispy-mode-map - ("i" . (lambda () - (interactive) - (if (and (featurep 'god-mode) god-global-mode) - (god-mode-all -1) - (special-lispy-tab)))))) + ;; (with-eval-after-load 'lispy + ;; (require 'lispyville) + ;; (add-hook 'lispy-mode-hook #'lispyville-mode) + ;; (bind-keys :map lispy-mode-map + ;; ("i" . (lambda () + ;; (interactive) + ;; (if (and (featurep 'god-mode) god-global-mode) + ;; (god-mode-all -1) + ;; (special-lispy-tab)))))) #+END_SRC *** Typescript From af8a00ab5bc9f9c81476aeceea8083d019e5d2b7 Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Sat, 27 Jun 2026 16:16:41 -0400 Subject: [PATCH 07/21] Flake update, and fixing side window sizes --- flake.lock | 18 +++++++++--------- home.org | 45 ++++++++++++++++++++++++++++++++------------- 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/flake.lock b/flake.lock index 665943e..413c16f 100644 --- a/flake.lock +++ b/flake.lock @@ -25,11 +25,11 @@ ] }, "locked": { - "lastModified": 1779969295, - "narHash": "sha256-HwIJ3tOcwSMiV75L7KqJXciXR9UfT+d7rwOZMX7cTnA=", + "lastModified": 1782233665, + "narHash": "sha256-h/xOtrByoA/Ak1lWHn0O1lVZz4qWYbwOSLQ8YSwQO0I=", "owner": "nix-community", "repo": "home-manager", - "rev": "61e2c9659324181e0f0ed911958c536333b1d4f6", + "rev": "062581938b4a378a82dfbb294b494808157153a1", "type": "github" }, "original": { @@ -65,11 +65,11 @@ ] }, "locked": { - "lastModified": 1779604987, - "narHash": "sha256-ZQ5z+fVhxYKtIFwtqGp5O0PD84BM1riASvqDaN5Xs+s=", + "lastModified": 1782030356, + "narHash": "sha256-h4WpMr455AfRub0FXBaon6Vcpe0waUyJ4GivIW6oyd4=", "owner": "nix-community", "repo": "nix-index-database", - "rev": "8fba98c80b48fa013820e0163c5096922fea4ddd", + "rev": "3017088b49efd404f78e3b104f553b97e4af786b", "type": "github" }, "original": { @@ -80,11 +80,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1779560665, - "narHash": "sha256-tpyBcxPpcQb8ukyNF7DoCwfSY3VPsxHoYwj00Cayv5o=", + "lastModified": 1781577229, + "narHash": "sha256-lrp67w8AulE9Ks53n27I45ADSzbOCn4H+CNW1Ck8B+8=", "owner": "nixos", "repo": "nixpkgs", - "rev": "64c08a7ca051951c8eae34e3e3cb1e202fe36786", + "rev": "567a49d1913ce81ac6e9582e3553dd90a955875f", "type": "github" }, "original": { diff --git a/home.org b/home.org index 832f6c6..e266024 100644 --- a/home.org +++ b/home.org @@ -171,11 +171,7 @@ are still Redbook-specific; ideally I'd find another way to install them. {pkgs, kube, ...}: { home.packages = with pkgs; [ - aws-iam-authenticator - awscli2 - kube - kubectl - mariadb.client + postgresql openssh ]; @@ -206,7 +202,9 @@ These programs require a full desktop environment: {pkgs, ...}: { home.packages = with pkgs; [ + linear slack + teams ]; } #+END_SRC @@ -987,6 +985,23 @@ windows. I place windows in the bottom or on the right mostly depending on how w content to be. #+BEGIN_SRC elisp + (defun jf/100-px-window (window) + (let* ((desired (min (/ (frame-width) 2) 101)) + (current (window-width window)) + (delta (- desired current))) + (window-resize window delta :horizontal t))) + + (defun jf/enforce-right-side-heights (win) + (let ((slot-heights '((-1 . 10))) + (parent (window-parent win))) + (when parent + (let ((child (window-child parent))) + (while child + (when-let* (((eq (window-parameter child 'window-side) 'right)) + (height (alist-get (window-parameter child 'window-slot) slot-heights))) + (window-resize child (- height (window-height child)))) + (setq child (window-next-sibling child))))))) + (setq display-buffer-alist '(((or "\\*Flymake diagnostics .*" "\\*Embark Export: .*" @@ -999,7 +1014,8 @@ content to be. "\\*EGLOT connections\\*" "\\*trace-output\\*" "\\*occur\\*" - ".*eshell\\*") + ".*eshell\\*" + "\\*SQL: .*") (display-buffer-in-side-window) (side . bottom) (slot . 0) @@ -1009,25 +1025,28 @@ content to be. ((or "magit: *" "magit-revision: .*" "magit-log*" - "\\*eldoc\\*" "\\*Help\\*" "\\*rustfmt\\*" "\\*slack: .*" "\\*forge: .*" "new-pullreq" "\\*claude:.*" - "\\*Man .*") + "\\*Man .*" + "\\*List .*") (display-buffer-reuse-window display-buffer-in-side-window) (side . right) (slot . 0) - (window-width . 0.5) + (window-width . jf/100-px-window) + (window-height . jf/enforce-right-side-heights) (window-parameters (no-delete-other-windows . t) (no-other-window . t))) - ("\\*Embark Actions\\*" + ((or "\\*Embark Actions\\*" + "\\*eldoc\\*") (display-buffer-in-side-window) (side . right) (slot . -1) - (window-width . 0.5) + (window-width . jf/100-px-window) + (window-height . jf/enforce-right-side-heights) (window-parameters (no-delete-other-windows . t) (no-other-window . t))))) @@ -1159,7 +1178,7 @@ Just "silently" wrap when searching at the bottom of a document. jq-mode (lispy.overrideAttrs { packageRequires = [ - ace-window iedit swiper zoutline + ace-window iedit swiper zoutline hydra ]; ignoreCompilationError = true; }) @@ -1361,7 +1380,7 @@ for completion. That makes it really annoying to use; don't use yasnippet with e (push '(typescript-mode . typescript-ts-mode) major-mode-remap-alist) (push '("\\.tsx\\'" . tsx-mode) auto-mode-alist) (push '(tsx-mode . tsx-ts-mode) major-mode-remap-alist) - (setopt typescript-ts-mode-indent-offset 4) + (setopt typescript-ts-mode-indent-offset 2) (with-eval-after-load 'typescript-ts-mode (defun my-tsx-ts-mode--indent-compatibility-b893426 () "Indent rules helper, to handle different releases of tree-sitter-tsx. From c68e79ca4f8b6c1c8edfe4d9bdb308bb73e40947 Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Tue, 30 Jun 2026 15:42:28 -0400 Subject: [PATCH 08/21] Bufferlo, and re-add God mode --- home.org | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/home.org b/home.org index e266024..06d0767 100644 --- a/home.org +++ b/home.org @@ -1072,6 +1072,7 @@ This configuration affects general text editing, across all modes. First, some p avy edit-indirect embark + god-mode # evil # evil-collection # evil-org @@ -1104,7 +1105,22 @@ its own devil-mode-only repeat maps that don't interfere when using normal modif ;; (add-hook 'org-mode-hook 'evil-org-mode) ;; (evil-org-set-key-theme '(navigation insert textobjects additional calendar)) ;; (require 'evil-org-agenda) - ;; (evil-org-agenda-set-keys) + ;; (evil-org-agenda-set-keys) + (require 'god-mode) + (require 'which-key) + + (bind-keys :map god-local-mode-map + ("i" . (lambda () (interactive) (god-mode-all -1))) + ("z" . repeat)) + (bind-keys ("" . (lambda () (interactive) (god-mode-all 1)))) + (defun my-god-mode-update-cursor-type () + (setq cursor-type (cond + (org-present-mode nil) + ((or (and (featurep 'god-mode) god-local-mode) buffer-read-only) 'box) + (t 'bar)))) + + (add-hook 'post-command-hook 'my-god-mode-update-cursor-type) + (which-key-enable-god-mode-support) #+END_SRC Avy allows jumping to any place on the screen with just a few keystrokes. I've stolen most of these @@ -1162,6 +1178,34 @@ Just "silently" wrap when searching at the bottom of a document. (bind-keys ("C-x 4 n" . edit-indirect-region)) #+END_SRC +** Workflow +:PROPERTIES: +:header-args:elisp: :tangle target/desktop/emacs-workflow.el +:END: + +#+BEGIN_SRC nix :tangle target/desktop/emacs-workflow.nix + { + programs.emacs = { + enable = true; + extraPackages = epkgs: with epkgs; [ + bufferlo + ]; + extraConfig = builtins.readFile ./emacs-workflow.el; + }; + } +#+END_SRC + +#+BEGIN_SRC elisp + (bufferlo-mode) + + (with-eval-after-load 'bufferlo + (setq mode-line-misc-info + (assq-delete-all 'bufferlo-mode mode-line-misc-info))) + + (bind-keys + ("s-b" . bufferlo-switch-to-buffer)) +#+END_SRC + ** Language Support :PROPERTIES: :header-args:elisp: :tangle target/desktop/emacs-languages.el @@ -1360,7 +1404,7 @@ for completion. That makes it really annoying to use; don't use yasnippet with e #+BEGIN_SRC elisp (setopt inferior-lisp-program "sbcl") - ;; (setopt lispy-compat '(god-mode edebug)) + (setopt lispy-compat '(god-mode edebug)) (add-hook 'emacs-lisp-mode-hook (lambda () (lispy-mode 1))) (add-hook 'lisp-mode-hook (lambda () (lispy-mode 1))) ;; (with-eval-after-load 'lispy @@ -1540,7 +1584,6 @@ for completion. That makes it really annoying to use; don't use yasnippet with e ;; ("C-x M-:" . consult-complex-command) ("C-x b" . consult-buffer) - ("s-b" . consult-project-buffer) ("s-B" . consult-buffer) ("C-x 4 b" . consult-buffer-other-window) ("C-x 5 b" . consult-buffer-other-frame) From 6c1b0faea4612b6a73522139dbb64097dfca19ba Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Tue, 30 Jun 2026 16:16:57 -0400 Subject: [PATCH 09/21] format-all --- home.org | 1 + 1 file changed, 1 insertion(+) diff --git a/home.org b/home.org index 06d0767..02fd887 100644 --- a/home.org +++ b/home.org @@ -1072,6 +1072,7 @@ This configuration affects general text editing, across all modes. First, some p avy edit-indirect embark + format-all god-mode # evil # evil-collection From 69f3fa445b1d1fca94f9ce9eb3a6f86908079e9b Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Tue, 30 Jun 2026 16:19:08 -0400 Subject: [PATCH 10/21] Fewer sbcl packages --- home.org | 2 -- 1 file changed, 2 deletions(-) diff --git a/home.org b/home.org index 02fd887..2305d48 100644 --- a/home.org +++ b/home.org @@ -54,10 +54,8 @@ carefully so it doesn't get carried away... alexandria cl-markup cl-mock - cl-rdkafka clack clack-handler-woo - dbd-mysql dbi defstar dexador From 1c379cc4a3273d47acadefe97dad232f801c5cbd Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Thu, 2 Jul 2026 15:19:56 -0400 Subject: [PATCH 11/21] wip --- flake.lock | 110 +++++++++++++++++++++++++++-------------------------- flake.nix | 21 ++++++---- home.org | 65 +++++++++++++++++++++++++++++-- 3 files changed, 131 insertions(+), 65 deletions(-) diff --git a/flake.lock b/flake.lock index 413c16f..a6866e3 100644 --- a/flake.lock +++ b/flake.lock @@ -1,20 +1,41 @@ { "nodes": { - "flake-parts": { + "claude-code": { "inputs": { - "nixpkgs-lib": "nixpkgs-lib" + "flake-utils": "flake-utils", + "nixpkgs": [ + "nixpkgs" + ] }, "locked": { - "lastModified": 1765835352, - "narHash": "sha256-XswHlK/Qtjasvhd1nOa1e8MgZ8GS//jBoTqWtrS1Giw=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "a34fae9c08a15ad73f295041fec82323541400a9", + "lastModified": 1782941856, + "narHash": "sha256-dFuLC6GQSR1g9Uy7lc9Qk/etujkCjrDE85B/np7khvg=", + "owner": "sadjow", + "repo": "claude-code-nix", + "rev": "90a137caf9a6d82389c0b26a719e26c4e6707367", "type": "github" }, "original": { - "owner": "hercules-ci", - "repo": "flake-parts", + "owner": "sadjow", + "repo": "claude-code-nix", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", "type": "github" } }, @@ -25,11 +46,11 @@ ] }, "locked": { - "lastModified": 1782233665, - "narHash": "sha256-h/xOtrByoA/Ak1lWHn0O1lVZz4qWYbwOSLQ8YSwQO0I=", + "lastModified": 1782964450, + "narHash": "sha256-2rwNd77TzZ4sDDvMam0IXFXN5IfC35mifoeKS0uAc/4=", "owner": "nix-community", "repo": "home-manager", - "rev": "062581938b4a378a82dfbb294b494808157153a1", + "rev": "ebc87daabc8d3f595e9a8b67107eaaa8115ad582", "type": "github" }, "original": { @@ -39,25 +60,6 @@ "type": "github" } }, - "kube": { - "inputs": { - "flake-parts": "flake-parts", - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1767247330, - "narHash": "sha256-CxXwzmvAOO07719jzE0Zw14C9r3fQcXfPllLtt5cIzo=", - "rev": "4a4d79a290c92de630e503f395fc8fd709904c1b", - "type": "tarball", - "url": "https://gitea.home-frikker.dedyn.io/api/v1/repos/jfrikker/kube/archive/4a4d79a290c92de630e503f395fc8fd709904c1b.tar.gz" - }, - "original": { - "type": "tarball", - "url": "https://gitea.home-frikker.dedyn.io/jfrikker/kube/archive/1.0.1.tar.gz" - } - }, "nix-index-database": { "inputs": { "nixpkgs": [ @@ -65,11 +67,11 @@ ] }, "locked": { - "lastModified": 1782030356, - "narHash": "sha256-h4WpMr455AfRub0FXBaon6Vcpe0waUyJ4GivIW6oyd4=", + "lastModified": 1782636943, + "narHash": "sha256-ripjZa7BBLwL1uS5VJF3s/VpZpWt5ZIQEvkJ/FJNpQw=", "owner": "nix-community", "repo": "nix-index-database", - "rev": "3017088b49efd404f78e3b104f553b97e4af786b", + "rev": "058b1f9381fa79fcda49982370a750ff92dbba43", "type": "github" }, "original": { @@ -80,42 +82,42 @@ }, "nixpkgs": { "locked": { - "lastModified": 1781577229, - "narHash": "sha256-lrp67w8AulE9Ks53n27I45ADSzbOCn4H+CNW1Ck8B+8=", + "lastModified": 1782847225, + "narHash": "sha256-JC9PjqKYG9ve5U8aDOLQipp3+KLANBHUvGdLZlxzdKI=", "owner": "nixos", "repo": "nixpkgs", - "rev": "567a49d1913ce81ac6e9582e3553dd90a955875f", + "rev": "95ca1e203c0750115fd4a6f17d5a245dfe6b1edd", "type": "github" }, "original": { "owner": "nixos", - "ref": "nixos-unstable", + "ref": "nixos-26.05", "repo": "nixpkgs", "type": "github" } }, - "nixpkgs-lib": { - "locked": { - "lastModified": 1765674936, - "narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=", - "owner": "nix-community", - "repo": "nixpkgs.lib", - "rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nixpkgs.lib", - "type": "github" - } - }, "root": { "inputs": { + "claude-code": "claude-code", "home-manager": "home-manager", - "kube": "kube", "nix-index-database": "nix-index-database", "nixpkgs": "nixpkgs" } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 0d616a9..ab31f89 100644 --- a/flake.nix +++ b/flake.nix @@ -3,15 +3,20 @@ inputs = { # Specify the source of Home Manager and Nixpkgs. - nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + nixpkgs.url = "github:nixos/nixpkgs/nixos-26.05"; + claude-code = { + url = "github:sadjow/claude-code-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + home-manager = { url = "github:nix-community/home-manager/master"; inputs.nixpkgs.follows = "nixpkgs"; }; - kube = { - url = "https://gitea.home-frikker.dedyn.io/jfrikker/kube/archive/1.0.1.tar.gz"; - inputs.nixpkgs.follows = "nixpkgs"; - }; + # kube = { + # url = "https://gitea.home-frikker.dedyn.io/jfrikker/kube/archive/1.0.1.tar.gz"; + # inputs.nixpkgs.follows = "nixpkgs"; + # }; nix-index-database = { url = "github:nix-community/nix-index-database"; @@ -19,7 +24,7 @@ }; }; - outputs = { nixpkgs, home-manager, kube, nix-index-database, ... }: + outputs = { nixpkgs, home-manager, claude-code, nix-index-database, ... }: let modules-for-system = pkgs: pkgs.stdenv.mkDerivation { name = "home-manager-modules"; src = pkgs.lib.fileset.toSource { @@ -62,7 +67,7 @@ home.packages = [ pkgs.pinentry_mac ]; }]; - extraSpecialArgs = { kube = kube.packages.aarch64-darwin.default; }; + extraSpecialArgs = { claude-code = claude-code.packages.aarch64-darwin.default; }; }; homeConfigurations.home = let pkgs = nixpkgs.legacyPackages.x86_64-linux; @@ -82,7 +87,7 @@ home.homeDirectory = "/home/jfrikker"; }]; - extraSpecialArgs = { kube = kube.packages.x86_64-linux.default; }; + extraSpecialArgs = { claude-code = claude-code.packages.x86_64-linux.default; }; }; packages.aarch64-darwin.default = modules-for-system nixpkgs.legacyPackages.aarch64-darwin; }; diff --git a/home.org b/home.org index 2305d48..6be14b5 100644 --- a/home.org +++ b/home.org @@ -166,7 +166,7 @@ These are the other programs I have installed globally. A few (like ~awscli~, ~m are still Redbook-specific; ideally I'd find another way to install them. #+BEGIN_SRC nix :tangle target/redbook/other-packages.nix - {pkgs, kube, ...}: + {pkgs, ...}: { home.packages = with pkgs; [ postgresql @@ -728,9 +728,10 @@ Actually, nix *really* requires ~bash~. This is a plugin that allows using zsh f ** Claude Code #+BEGIN_SRC nix :tangle target/base/claude-code.nix - { + {claude-code, ...}: { programs.claude-code = { enable = true; + package = claude-code; }; } #+END_SRC @@ -1197,12 +1198,21 @@ Just "silently" wrap when searching at the bottom of a document. #+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)) + (bind-keys - ("s-b" . bufferlo-switch-to-buffer)) + ("s-b" . bufferlo-switch-to-buffer) + ("C-x t 0" . bufferlo-tab-close-kill-buffers) + ("C-x k" . my/bury-or-kill-buffer)) #+END_SRC ** Language Support @@ -1216,6 +1226,7 @@ Just "silently" wrap when searching at the bottom of a document. enable = true; extraPackages = epkgs: with epkgs; [ consult-eglot + graphql-ts-mode haskell-ts-mode jenkinsfile-mode jq-mode @@ -1335,6 +1346,10 @@ available? It seems to work for now anyway... (advice-add 'prog-fill-reindent-defun :override #'my-prog-fill-reindent-defun)) #+end_src +#+BEGIN_SRC elisp + (add-hook 'compilation-filter-hook 'ansi-color-compilation-filter) +#+END_SRC + *** Flymake #+begin_src elisp (autoload 'flymake-show-project-diagnostics "flymake") @@ -1406,6 +1421,7 @@ for completion. That makes it really annoying to use; don't use yasnippet with e (setopt lispy-compat '(god-mode edebug)) (add-hook 'emacs-lisp-mode-hook (lambda () (lispy-mode 1))) (add-hook 'lisp-mode-hook (lambda () (lispy-mode 1))) + (add-hook 'lisp-data-mode-hook (lambda () (lispy-mode 1))) ;; (with-eval-after-load 'lispy ;; (require 'lispyville) ;; (add-hook 'lispy-mode-hook #'lispyville-mode) @@ -1437,6 +1453,49 @@ for completion. That makes it really annoying to use; don't use yasnippet with e `(((match "<" "jsx_text") parent 0) ((parent-is "jsx_text") grand-parent typescript-ts-mode-indent-offset))))) (advice-add 'tsx-ts-mode--indent-compatibility-b893426 :override #'my-tsx-ts-mode--indent-compatibility-b893426)) + + (defvar my/edit-indirect-tag-modes + '(("graphql" . graphql-ts-mode) + ("gql" . graphql-ts-mode) + ("sql" . sql-mode) + ("css" . css-mode)) + "Map of tagged-template tag names to major modes.") + + (defun my/edit-indirect--node-bounds (node) + "Return (BEG . END) for NODE's contents, excluding delimiters." + (cons (1+ (treesit-node-start node)) + (1- (treesit-node-end node)))) + + (defun my/edit-indirect-tagged-template-at-point () + (interactive) + (let* ((node (treesit-node-at (point))) + (tmpl-node (treesit-parent-until + node + (lambda (n) (equal (treesit-node-type n) "template_string")))) + (str-node (unless tmpl-node + (treesit-parent-until + node + (lambda (n) (equal (treesit-node-type n) "string"))))) + (target-node (or tmpl-node str-node))) + (unless target-node + (user-error "Point is not inside a string or template literal")) + (let* ((tagged-node (and tmpl-node (treesit-node-parent tmpl-node))) + (tag-node (and tagged-node + (equal (treesit-node-type tagged-node) "call_expression") + (treesit-node-child-by-field-name tagged-node "function"))) + (tag-name (and tag-node (treesit-node-text tag-node t))) + (mode (cond + (tag-name (or (cdr (assoc tag-name my/edit-indirect-tag-modes)) + major-mode)) + (t 'text-mode))) + (bounds (my/edit-indirect--node-bounds target-node)) + (buf (edit-indirect-region (car bounds) (cdr bounds) t))) + (with-current-buffer buf + (funcall mode))))) + + (with-eval-after-load 'typescript-ts-mode + (define-key typescript-ts-mode-map (kbd "C-c '") #'my/edit-indirect-tagged-template-at-point) + (define-key tsx-ts-mode-map (kbd "C-c '") #'my/edit-indirect-tagged-template-at-point)) #+END_SRC *** Java From 8fae2a5338d7f332665d29eb6cf4598867ec564f Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Tue, 7 Jul 2026 15:01:03 -0400 Subject: [PATCH 12/21] wip --- home.org | 58 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/home.org b/home.org index 6be14b5..a5b9815 100644 --- a/home.org +++ b/home.org @@ -656,7 +656,7 @@ Now we'll set up some keybindings: key = "g", mods = "CMD", action = wezterm.action.SpawnCommandInNewTab { - args = { wezterm.home_dir .. "/.nix-profile/bin/zsh", "-l", "-c", "lazygit" } + args = { wezterm.home_dir .. "/.nix-profile/bin/zsh", "-l", "-i", "-c", "lazygit" } } }, { @@ -686,6 +686,17 @@ Now we'll set up some keybindings: end #+END_SRC +** Ghostty + +#+BEGIN_SRC nix :tangle target/desktop/ghostty.nix + {pkgs, ...}: { + programs.ghostty = { + enable = true; + package = pkgs.ghostty-bin; + }; + } +#+END_SRC + ** Zsh This is my default shell for now. Unfortunately, nix requires a posix-compliant shell, so bash or @@ -984,22 +995,25 @@ windows. I place windows in the bottom or on the right mostly depending on how w content to be. #+BEGIN_SRC elisp - (defun jf/100-px-window (window) - (let* ((desired (min (/ (frame-width) 2) 101)) - (current (window-width window)) - (delta (- desired current))) - (window-resize window delta :horizontal t))) + (defun jf/window-children (window) + (let ((result nil) + (child (window-child window))) + (while child + (push child result) + (setq child (window-next-sibling child))) + (reverse result))) (defun jf/enforce-right-side-heights (win) - (let ((slot-heights '((-1 . 10))) + (let ((slot-heights '((-1 . 20))) (parent (window-parent win))) (when parent - (let ((child (window-child parent))) - (while child - (when-let* (((eq (window-parameter child 'window-side) 'right)) - (height (alist-get (window-parameter child 'window-slot) slot-heights))) - (window-resize child (- height (window-height child)))) - (setq child (window-next-sibling child))))))) + (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)))))))) (setq display-buffer-alist '(((or "\\*Flymake diagnostics .*" @@ -1032,22 +1046,24 @@ content to be. "\\*claude:.*" "\\*Man .*" "\\*List .*") - (display-buffer-reuse-window display-buffer-in-side-window) + (display-buffer-in-side-window) (side . right) (slot . 0) - (window-width . jf/100-px-window) + (window-width . 101) (window-height . jf/enforce-right-side-heights) + (preserve-size . (t . nil)) (window-parameters (no-delete-other-windows . t) (no-other-window . t))) ((or "\\*Embark Actions\\*" "\\*eldoc\\*") (display-buffer-in-side-window) - (side . right) - (slot . -1) - (window-width . jf/100-px-window) - (window-height . jf/enforce-right-side-heights) - (window-parameters (no-delete-other-windows . t) - (no-other-window . t))))) + (side . right) + (slot . -1) + (window-width . 101) + (window-height . jf/enforce-right-side-heights) + (preserve-size . (t . t)) + (window-parameters (no-delete-other-windows . t) + (no-other-window . t))))) (setopt window-persistent-parameters (cl-list* '(no-delete-other-windows . writable) From 8effe5f40119e465bab69942a01bddcea35ab9f8 Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Tue, 7 Jul 2026 22:48:21 -0400 Subject: [PATCH 13/21] popper --- flake.lock | 24 +++++------ home.org | 123 ++++++++++++++++++++++++++++++++++------------------- 2 files changed, 91 insertions(+), 56 deletions(-) diff --git a/flake.lock b/flake.lock index a6866e3..4a2a988 100644 --- a/flake.lock +++ b/flake.lock @@ -8,11 +8,11 @@ ] }, "locked": { - "lastModified": 1782941856, - "narHash": "sha256-dFuLC6GQSR1g9Uy7lc9Qk/etujkCjrDE85B/np7khvg=", + "lastModified": 1783380155, + "narHash": "sha256-SwUwKaLrZ+c5y4GoZHKBf1nUsDHVsIUtn2CFloZrV2A=", "owner": "sadjow", "repo": "claude-code-nix", - "rev": "90a137caf9a6d82389c0b26a719e26c4e6707367", + "rev": "25d979d1a39d0acdbcb1b8d0b9d83ffdd10b5f43", "type": "github" }, "original": { @@ -46,11 +46,11 @@ ] }, "locked": { - "lastModified": 1782964450, - "narHash": "sha256-2rwNd77TzZ4sDDvMam0IXFXN5IfC35mifoeKS0uAc/4=", + "lastModified": 1783436070, + "narHash": "sha256-F80z1JoiJgZyTT5D+3siLOVzqmCEphLR7t0Ym/I2CLI=", "owner": "nix-community", "repo": "home-manager", - "rev": "ebc87daabc8d3f595e9a8b67107eaaa8115ad582", + "rev": "f09af49406ffad37acb6538d3207189a1a1e0b7e", "type": "github" }, "original": { @@ -67,11 +67,11 @@ ] }, "locked": { - "lastModified": 1782636943, - "narHash": "sha256-ripjZa7BBLwL1uS5VJF3s/VpZpWt5ZIQEvkJ/FJNpQw=", + "lastModified": 1783414108, + "narHash": "sha256-RY8e+gR2/DhXsYDxGDL6Hhe9+POD9u4+llwxMBqMQDs=", "owner": "nix-community", "repo": "nix-index-database", - "rev": "058b1f9381fa79fcda49982370a750ff92dbba43", + "rev": "96d6de10eb281b98f5cfcd1841394c03da5df77c", "type": "github" }, "original": { @@ -82,11 +82,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1782847225, - "narHash": "sha256-JC9PjqKYG9ve5U8aDOLQipp3+KLANBHUvGdLZlxzdKI=", + "lastModified": 1783148766, + "narHash": "sha256-uslt2pqShTIXDdAHRHv2QkYLsVdY8Oqwz0EA48/RSM8=", "owner": "nixos", "repo": "nixpkgs", - "rev": "95ca1e203c0750115fd4a6f17d5a245dfe6b1edd", + "rev": "a50de1b7d8a586adc18d2395c19de7d6058e6030", "type": "github" }, "original": { diff --git a/home.org b/home.org index a5b9815..d5c0fb0 100644 --- a/home.org +++ b/home.org @@ -794,6 +794,7 @@ These are just some general settings that apply everywhere. First, a few package ligature mixed-pitch ace-window + popper ]; extraConfig = builtins.readFile ./emacs-global.el; }; @@ -1015,6 +1016,40 @@ content to be. when height do (progn (window-resize child (- height (window-height child))) (window-preserve-size child nil t)))))))) + (setopt popper-reference-buffers + '("\\*Flymake diagnostics .*" + "\\*Embark Export: .*" + "\\*Embark Collect .*" + "\\*xref\\*" + ("\\*compilation\\*" . hide) + "\\*sly-mrepl *" + "\\*Messages\\*" + "\\*lispy-message\\*" + "\\*EGLOT connections\\*" + "\\*trace-output\\*" + "\\*occur\\*" + ".*eshell\\*" + "\\*SQL: .*" + "magit: *" + "magit-revision: .*" + "magit-log*" + "\\*Help\\*" + "\\*rustfmt\\*" + "\\*slack: .*" + "\\*forge: .*" + "new-pullreq" + "\\*claude:.*" + "\\*Man .*" + "\\*List .*" + "\\*eldoc\\*")) + (setopt popper-display-control nil) + + (popper-mode) + (popper-echo-mode) + + (bind-keys ("C-z" . popper-toggle) + ("C-;" . popper-cycle)) + (setq display-buffer-alist '(((or "\\*Flymake diagnostics .*" "\\*Embark Export: .*" @@ -1029,41 +1064,41 @@ content to be. "\\*occur\\*" ".*eshell\\*" "\\*SQL: .*") - (display-buffer-in-side-window) - (side . bottom) - (slot . 0) - (window-height . 0.33) - (window-parameters (no-delete-other-windows . t) - (no-other-window . t))) - ((or "magit: *" - "magit-revision: .*" - "magit-log*" - "\\*Help\\*" - "\\*rustfmt\\*" - "\\*slack: .*" - "\\*forge: .*" - "new-pullreq" - "\\*claude:.*" - "\\*Man .*" - "\\*List .*") - (display-buffer-in-side-window) - (side . right) - (slot . 0) - (window-width . 101) - (window-height . jf/enforce-right-side-heights) - (preserve-size . (t . nil)) - (window-parameters (no-delete-other-windows . t) - (no-other-window . t))) - ((or "\\*Embark Actions\\*" - "\\*eldoc\\*") - (display-buffer-in-side-window) - (side . right) - (slot . -1) - (window-width . 101) - (window-height . jf/enforce-right-side-heights) - (preserve-size . (t . t)) - (window-parameters (no-delete-other-windows . t) - (no-other-window . t))))) + (display-buffer-in-side-window) + (side . bottom) + (slot . 0) + (window-height . 0.33) + (window-parameters (no-delete-other-windows . t) + (no-other-window . t))) + ((or "magit: *" + "magit-revision: .*" + "magit-log*" + "\\*Help\\*" + "\\*rustfmt\\*" + "\\*slack: .*" + "\\*forge: .*" + "new-pullreq" + "\\*claude:.*" + "\\*Man .*" + "\\*List .*") + (display-buffer-in-side-window) + (side . right) + (slot . 0) + (window-width . 101) + (window-height . jf/enforce-right-side-heights) + (preserve-size . (t . nil)) + (window-parameters (no-delete-other-windows . t) + (no-other-window . t))) + ((or "\\*Embark Actions\\*" + "\\*eldoc\\*") + (display-buffer-in-side-window) + (side . right) + (slot . -1) + (window-width . 101) + (window-height . jf/enforce-right-side-heights) + (preserve-size . (t . t)) + (window-parameters (no-delete-other-windows . t) + (no-other-window . t))))) (setopt window-persistent-parameters (cl-list* '(no-delete-other-windows . writable) @@ -1438,15 +1473,15 @@ for completion. That makes it really annoying to use; don't use yasnippet with e (add-hook 'emacs-lisp-mode-hook (lambda () (lispy-mode 1))) (add-hook 'lisp-mode-hook (lambda () (lispy-mode 1))) (add-hook 'lisp-data-mode-hook (lambda () (lispy-mode 1))) - ;; (with-eval-after-load 'lispy - ;; (require 'lispyville) - ;; (add-hook 'lispy-mode-hook #'lispyville-mode) - ;; (bind-keys :map lispy-mode-map - ;; ("i" . (lambda () - ;; (interactive) - ;; (if (and (featurep 'god-mode) god-global-mode) - ;; (god-mode-all -1) - ;; (special-lispy-tab)))))) + (with-eval-after-load 'lispy + ;; (require 'lispyville) + ;; (add-hook 'lispy-mode-hook #'lispyville-mode) + (bind-keys :map lispy-mode-map + ("i" . (lambda () + (interactive) + (if (and (featurep 'god-mode) god-global-mode) + (god-mode-all -1) + (special-lispy-tab)))))) #+END_SRC *** Typescript From eb057a2c3a84018c2cdcf51b6e97ac5a3b6718d6 Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Tue, 7 Jul 2026 23:10:02 -0400 Subject: [PATCH 14/21] perspective --- home.org | 53 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/home.org b/home.org index d5c0fb0..e9e9e2b 100644 --- a/home.org +++ b/home.org @@ -795,6 +795,7 @@ These are just some general settings that apply everywhere. First, a few package mixed-pitch ace-window popper + perspective ]; extraConfig = builtins.readFile ./emacs-global.el; }; @@ -941,11 +942,12 @@ Set up a few project- / workspace-related key bindings. #+BEGIN_SRC elisp (bind-keys ("s-f" . project-find-file) - ("s-F" . project-switch-project)) - - (with-eval-after-load 'tab-bar - (bind-keys :map tab-bar-mode-map - ("s-s" . tab-bar-switch-to-tab))) + ("s-F" . project-switch-project) + ("s-s" . persp-switch)) + + ;; (with-eval-after-load 'tab-bar + ;; (bind-keys :map tab-bar-mode-map + ;; ("s-s" . tab-bar-switch-to-tab))) #+END_SRC Don't run a server. I'm not using this, I can always turn it back on if I need to. @@ -1050,6 +1052,11 @@ content to be. (bind-keys ("C-z" . popper-toggle) ("C-;" . popper-cycle)) + (require 'perspective) + (setopt persp-mode-prefix-key (kbd "C-x t")) + (setopt persp-show-modestring nil) + (persp-mode) + (setq display-buffer-alist '(((or "\\*Flymake diagnostics .*" "\\*Embark Export: .*" @@ -1239,7 +1246,7 @@ Just "silently" wrap when searching at the bottom of a document. programs.emacs = { enable = true; extraPackages = epkgs: with epkgs; [ - bufferlo + # bufferlo ]; extraConfig = builtins.readFile ./emacs-workflow.el; }; @@ -1247,23 +1254,24 @@ Just "silently" wrap when searching at the bottom of a document. #+END_SRC #+BEGIN_SRC elisp - (bufferlo-mode) + ;; (bufferlo-mode) - (setopt bufferlo-include-buried-buffers nil) + ;; (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))) + ;; (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)) + ;; (defun my/bury-or-kill-buffer () + ;; (interactive) + ;; (bury-buffer) + ;; (bufferlo-kill-orphan-buffers)) (bind-keys - ("s-b" . bufferlo-switch-to-buffer) - ("C-x t 0" . bufferlo-tab-close-kill-buffers) - ("C-x k" . my/bury-or-kill-buffer)) + ("s-b" . consult-buffer) + ;; ("C-x t 0" . bufferlo-tab-close-kill-buffers) + ;; ("C-x k" . my/bury-or-kill-buffer) + ) #+END_SRC ** Language Support @@ -1696,7 +1704,7 @@ for completion. That makes it really annoying to use; don't use yasnippet with e ("s-B" . consult-buffer) ("C-x 4 b" . consult-buffer-other-window) ("C-x 5 b" . consult-buffer-other-frame) - ("C-x t b" . consult-buffer-other-tab) + ;; ("C-x t b" . consult-buffer-other-tab) ("C-x r b" . consult-bookmark) ("C-x p b" . consult-project-buffer) @@ -1741,9 +1749,12 @@ for completion. That makes it really annoying to use; don't use yasnippet with e 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-project-recent-file + consult-source-recent-file + consult-source-buffer :hidden t :default nil ;; :preview-key "M-." - :preview-key '(:debounce 0.4 any))) + consult-source-project-recent-file + :preview-key '(:debounce 0.4 any)) + (add-to-list 'consult-buffer-sources persp-consult-source)) (setopt consult-narrow-key "<") ;; "C-+" From ba8ef4f585e3474ce77199a0c9f72b8383708161 Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Thu, 9 Jul 2026 23:36:36 -0400 Subject: [PATCH 15/21] wip --- home.org | 84 +++++++++++++++++++++++++++----------------------------- 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/home.org b/home.org index e9e9e2b..93e16fa 100644 --- a/home.org +++ b/home.org @@ -790,12 +790,13 @@ These are just some general settings that apply everywhere. First, a few package programs.emacs = { enable = true; extraPackages = epkgs: with epkgs; [ + ace-window doom-modeline + free-keys ligature mixed-pitch - ace-window - popper perspective + popper ]; extraConfig = builtins.readFile ./emacs-global.el; }; @@ -807,6 +808,7 @@ 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) @@ -818,6 +820,15 @@ Turn off some default settings that I don't find useful. 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 mouse-wheel-tilt-scroll t) + (setq-default truncate-lines t) #+END_SRC Make sure which-key mode is always on. The on-the-fly keymap help it gives is indespensable. @@ -1018,12 +1029,17 @@ content to be. when height do (progn (window-resize child (- height (window-height child))) (window-preserve-size child nil t)))))))) + (require 'perspective) + (setopt persp-mode-prefix-key (kbd "C-x t")) + (setopt persp-show-modestring nil) + (persp-mode) + (setopt popper-reference-buffers '("\\*Flymake diagnostics .*" "\\*Embark Export: .*" "\\*Embark Collect .*" "\\*xref\\*" - ("\\*compilation\\*" . hide) + "\\*compilation\\*" "\\*sly-mrepl *" "\\*Messages\\*" "\\*lispy-message\\*" @@ -1045,18 +1061,14 @@ content to be. "\\*List .*" "\\*eldoc\\*")) (setopt popper-display-control nil) + (setopt popper-group-function 'popper-group-by-perspective) (popper-mode) (popper-echo-mode) - (bind-keys ("C-z" . popper-toggle) + (bind-keys ("C-q" . popper-toggle) ("C-;" . popper-cycle)) - (require 'perspective) - (setopt persp-mode-prefix-key (kbd "C-x t")) - (setopt persp-show-modestring nil) - (persp-mode) - (setq display-buffer-alist '(((or "\\*Flymake diagnostics .*" "\\*Embark Export: .*" @@ -1091,7 +1103,7 @@ content to be. (display-buffer-in-side-window) (side . right) (slot . 0) - (window-width . 101) + (window-width . 93) (window-height . jf/enforce-right-side-heights) (preserve-size . (t . nil)) (window-parameters (no-delete-other-windows . t) @@ -1101,7 +1113,7 @@ content to be. (display-buffer-in-side-window) (side . right) (slot . -1) - (window-width . 101) + (window-width . 93) (window-height . jf/enforce-right-side-heights) (preserve-size . (t . t)) (window-parameters (no-delete-other-windows . t) @@ -1200,10 +1212,13 @@ his article. (avy-goto-char-timer))) (bind-keys - ("M-j" . avy-goto-char-timer) - ("C-c j" . avy-goto-char-timer) - ("M-J" . avy-goto-char-timer-embark) - ("C-." . embark-act)) + ("C-j" . avy-goto-char-timer) + ("M-j" . avy-goto-char-timer-embark) + ("C-." . embark-act) + :map lispy-mode-map + ("C-j" . avy-goto-char-timer) + :map org-mode-map + ("C-j" . avy-goto-char-timer)) #+END_SRC Just "silently" wrap when searching at the bottom of a document. @@ -1298,6 +1313,7 @@ Just "silently" wrap when searching at the bottom of a document. # lispyville lua-mode nix-mode + prisma-ts-mode rust-mode sly sly-macrostep @@ -1328,6 +1344,7 @@ Just "silently" wrap when searching at the bottom of a document. g.tree-sitter-nix g.tree-sitter-org g.tree-sitter-php + g.tree-sitter-prisma g.tree-sitter-python g.tree-sitter-rust g.tree-sitter-rust-format-args @@ -1365,7 +1382,7 @@ Show a vertical bar 100 characters out; ideally I don't want lines longer than t is about the max you can have and still fit two files side-by-side on the screen. #+begin_src elisp - (setq-default fill-column 100) + (setq-default fill-column 120) (defun jf-init-fill-column () (display-fill-column-indicator-mode 1)) @@ -1494,10 +1511,10 @@ for completion. That makes it really annoying to use; don't use yasnippet with e *** Typescript #+BEGIN_SRC elisp - (push '("\\.ts\\'" . typescript-mode) auto-mode-alist) - (push '(typescript-mode . typescript-ts-mode) major-mode-remap-alist) - (push '("\\.tsx\\'" . tsx-mode) auto-mode-alist) - (push '(tsx-mode . tsx-ts-mode) major-mode-remap-alist) + (add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-mode)) + (add-to-list 'major-mode-remap-alist '(typescript-mode . typescript-ts-mode)) + (add-to-list 'auto-mode-alist '("\\.tsx\\'" . tsx-mode)) + (add-to-list 'major-mode-remap-alist '(tsx-mode . tsx-ts-mode)) (setopt typescript-ts-mode-indent-offset 2) (with-eval-after-load 'typescript-ts-mode (defun my-tsx-ts-mode--indent-compatibility-b893426 () @@ -1743,6 +1760,7 @@ 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) @@ -1750,10 +1768,11 @@ for completion. That makes it really annoying to use; don't use yasnippet with e consult-bookmark consult-recent-file consult-xref consult-source-bookmark consult-source-file-register consult-source-recent-file - consult-source-buffer :hidden t :default nil + 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)) (setopt consult-narrow-key "<") ;; "C-+" @@ -1955,29 +1974,6 @@ for completion. That makes it really annoying to use; don't use yasnippet with e (setopt slack-buffer-function #'switch-to-buffer) #+END_SRC -** Kubernetes -:PROPERTIES: -:header-args:elisp: :tangle target/desktop/emacs-kubernetes.el -:END: - -#+BEGIN_SRC nix :tangle target/desktop/emacs-kubernetes.nix - { - programs.emacs = { - enable = true; - extraPackages = epkgs: with epkgs; [ - kubed - ]; - extraConfig = builtins.readFile ./emacs-kubernetes.el; - }; - } -#+END_SRC - -#+BEGIN_SRC elisp - (use-package kubed - :bind-keymap - ("s-k" . kubed-prefix-map)) -#+END_SRC - ** Ledger #+BEGIN_SRC nix :tangle target/desktop/emacs-ledger.nix From a1abf5b4a16898232654c4f1f3fc371301e1fa1d Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Fri, 10 Jul 2026 00:11:54 -0400 Subject: [PATCH 16/21] wip --- home.org | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/home.org b/home.org index 93e16fa..6ab013a 100644 --- a/home.org +++ b/home.org @@ -1214,11 +1214,15 @@ his article. (bind-keys ("C-j" . avy-goto-char-timer) ("M-j" . avy-goto-char-timer-embark) - ("C-." . embark-act) - :map lispy-mode-map - ("C-j" . avy-goto-char-timer) - :map org-mode-map - ("C-j" . avy-goto-char-timer)) + ("C-." . embark-act)) + + (with-eval-after-load 'lispy + (bind-keys :map lispy-mode-map + ("C-j" . avy-goto-char-timer))) + + (with-eval-after-load 'org + (bind-keys :map org-mode-map + ("C-j" . avy-goto-char-timer))) #+END_SRC Just "silently" wrap when searching at the bottom of a document. From 5f96f98158accaa3925c96dff2f3d37f3e45e569 Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Wed, 15 Jul 2026 15:21:15 -0400 Subject: [PATCH 17/21] wip --- home.org | 172 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 105 insertions(+), 67 deletions(-) diff --git a/home.org b/home.org index 6ab013a..2768024 100644 --- a/home.org +++ b/home.org @@ -201,7 +201,13 @@ These programs require a full desktop environment: { home.packages = with pkgs; [ linear - slack + (slack.overrideAttrs { + version = "4.50.143"; + src = pkgs.fetchurl { + url = "https://downloads.slack-edge.com/desktop-releases/mac/arm64/4.50.143/Slack-4.50.143-macOS.dmg"; + hash = "sha256-f5oYi8NPKXWpDcowFYMUjptbQs4V9hK2bm1TuaQeJn0="; + }; + }) teams ]; } @@ -1034,12 +1040,30 @@ content to be. (setopt persp-show-modestring nil) (persp-mode) + (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 .*" "\\*Embark Export: .*" "\\*Embark Collect .*" "\\*xref\\*" - "\\*compilation\\*" + "\\*compilation\\*" + "\\*pnpm:.*" "\\*sly-mrepl *" "\\*Messages\\*" "\\*lispy-message\\*" @@ -1061,7 +1085,7 @@ content to be. "\\*List .*" "\\*eldoc\\*")) (setopt popper-display-control nil) - (setopt popper-group-function 'popper-group-by-perspective) + (setopt popper-group-function 'jf/popper-group-by-owning-perspective) (popper-mode) (popper-echo-mode) @@ -1075,6 +1099,7 @@ content to be. "\\*Embark Collect .*" "\\*xref\\*" "\\*compilation\\*" + "\\*pnpm:.*" "\\*sly-mrepl *" "\\*Messages\\*" "\\*lispy-message\\*" @@ -1185,7 +1210,7 @@ its own devil-mode-only repeat maps that don't interfere when using normal modif (bind-keys ("" . (lambda () (interactive) (god-mode-all 1)))) (defun my-god-mode-update-cursor-type () (setq cursor-type (cond - (org-present-mode nil) + ((and (featurep 'org-present) org-present-mode) nil) ((or (and (featurep 'god-mode) god-local-mode) buffer-read-only) 'box) (t 'bar)))) @@ -1317,6 +1342,7 @@ Just "silently" wrap when searching at the bottom of a document. # lispyville lua-mode nix-mode + pnpm-mode prisma-ts-mode rust-mode sly @@ -1576,6 +1602,9 @@ for completion. That makes it really annoying to use; don't use yasnippet with e (with-eval-after-load 'typescript-ts-mode (define-key typescript-ts-mode-map (kbd "C-c '") #'my/edit-indirect-tagged-template-at-point) (define-key tsx-ts-mode-map (kbd "C-c '") #'my/edit-indirect-tagged-template-at-point)) + + (with-eval-after-load 'eglot + (add-to-list 'eglot-server-programs '((prisma-ts-mode) "prisma-language-server" "--stdio"))) #+END_SRC *** Java @@ -1861,73 +1890,73 @@ for completion. That makes it really annoying to use; don't use yasnippet with e (set-face-attribute 'org-level-7 nil :font "Iosevka Aile") (set-face-attribute 'org-level-8 nil :font "Iosevka Aile") - (require 'org-present) - (require 'face-remap) - (require 'visual-fill-column) - (defvar-local my/org-present-face-remapping-cookies nil) - (defun my/org-present-start () - (setq-local my/org-present-face-remapping-cookies nil) - ;; Tweak font sizes - (dolist (face '((default :height 2.0) - (header-line :height 4.0 :background "#303446") - (org-document-title :height 1.75) - (org-code :height 2.0) - (org-verbatim :height 2.0) - (org-block :height 1.25) - (org-block-begin-line :height 0.7) - (org-level-1 :height 3.0) - (org-level-2 :height 3.0) - (org-level-3 :height 3.0) - (org-level-4 :height 3.0) - (org-level-5 :height 3.0) - (org-level-6 :height 3.0) - (org-level-7 :height 3.0) - (org-level-8 :height 3.0))) - (push (apply #'face-remap-add-relative face) my/org-present-face-remapping-cookies)) + (with-eval-after-load 'org-present + (require 'face-remap) + (require 'visual-fill-column) + + (defun my/org-present-start () + (setq-local my/org-present-face-remapping-cookies nil) + ;; Tweak font sizes + (dolist (face '((default :height 2.0) + (header-line :height 4.0 :background "#303446") + (org-document-title :height 1.75) + (org-code :height 2.0) + (org-verbatim :height 2.0) + (org-block :height 1.25) + (org-block-begin-line :height 0.7) + (org-level-1 :height 3.0) + (org-level-2 :height 3.0) + (org-level-3 :height 3.0) + (org-level-4 :height 3.0) + (org-level-5 :height 3.0) + (org-level-6 :height 3.0) + (org-level-7 :height 3.0) + (org-level-8 :height 3.0))) + (push (apply #'face-remap-add-relative face) my/org-present-face-remapping-cookies)) - ;; Set a blank header line string to create blank space at the top - (setq header-line-format " ") + ;; Set a blank header line string to create blank space at the top + (setq header-line-format " ") - ;; Display inline images automatically - (org-display-inline-images) - (org-present-hide-cursor) + ;; Display inline images automatically + (org-display-inline-images) + (org-present-hide-cursor) - ;; Center the presentation and wrap lines - (visual-fill-column-mode 1) - (setq visual-fill-column-center-text t) - ;; (visual-line-mode 1) - ) + ;; Center the presentation and wrap lines + (visual-fill-column-mode 1) + (setq visual-fill-column-center-text t) + ;; (visual-line-mode 1) + ) - (defun my/org-present-end () - ;; Reset font customizations - (dolist (cookie my/org-present-face-remapping-cookies) - (face-remap-remove-relative cookie)) + (defun my/org-present-end () + ;; Reset font customizations + (dolist (cookie my/org-present-face-remapping-cookies) + (face-remap-remove-relative cookie)) - ;; Clear the header line string so that it isn't displayed - (setq header-line-format nil) + ;; Clear the header line string so that it isn't displayed + (setq header-line-format nil) - ;; Stop displaying inline images - (org-remove-inline-images) - (org-present-show-cursor) + ;; Stop displaying inline images + (org-remove-inline-images) + (org-present-show-cursor) - ;; Stop centering the document - (visual-fill-column-mode 0) - ;; (visual-line-mode 0) - ) + ;; Stop centering the document + (visual-fill-column-mode 0) + ;; (visual-line-mode 0) + ) - (add-hook 'org-present-mode-hook 'my/org-present-start) - (add-hook 'org-present-mode-quit-hook 'my/org-present-end) + (add-hook 'org-present-mode-hook 'my/org-present-start) + (add-hook 'org-present-mode-quit-hook 'my/org-present-end)) - (require 'org-roam) - (bind-keys ("C-c n l" . org-roam-buffer-toggle) - ("C-c n f" . org-roam-node-find) - ("C-c n g" . org-roam-graph) - ("C-c n i" . org-roam-node-insert) - ("C-c n c" . org-roam-capture)) + ;; (require 'org-roam) + ;; (bind-keys ("C-c n l" . org-roam-buffer-toggle) + ;; ("C-c n f" . org-roam-node-find) + ;; ("C-c n g" . org-roam-graph) + ;; ("C-c n i" . org-roam-node-insert) + ;; ("C-c n c" . org-roam-capture)) ;; (setq org-roam-node-display-template (concat "${title:*} " (propertize "${tags:10}" 'face 'org-tag))) - (org-roam-db-autosync-mode) + ;; (org-roam-db-autosync-mode) (add-hook 'org-mode-hook 'org-modern-mode) @@ -1973,9 +2002,16 @@ for completion. That makes it really annoying to use; don't use yasnippet with e #+END_SRC #+BEGIN_SRC elisp - (setopt lui-time-stamp-format "[%Y-%m-%d %H:%M]") - (setopt slack-render-profile-images-p nil) - (setopt slack-buffer-function #'switch-to-buffer) + (use-package lui + :defer t + :custom + (lui-time-stamp-format "[%Y-%m-%d %H:%M]")) + + (use-package slack + :commands slack-start + :custom + (slack-render-profile-images-p nil) + (slack-buffer-function #'switch-to-buffer)) #+END_SRC ** Ledger @@ -2027,12 +2063,13 @@ for completion. That makes it really annoying to use; don't use yasnippet with e enable = true; extraPackages = epkgs: with epkgs; [ (epkgs.trivialBuild { - name = "claude-code"; + pname = "claude-code"; + version = "0.4.5"; src = pkgs.fetchFromGitHub { owner = "stevemolitor"; repo = "claude-code.el"; - rev = "4a9914bd4161eb43f489820f9174c62390e5adc8"; - sha256 = "sha256-ISlD6q1hceckry1Jd19BX1MfobHJxng5ulX2gq9f644="; + rev = "03199df8b3a1e9cd4857f0851f7a912ba524aff3"; + sha256 = "sha256-5QJrWIu4EgnHcOqMwlrs2JBBx7aI9OaSJswesr6Apfk="; }; packageRequires = [ epkgs.inheritenv ]; }) @@ -2043,8 +2080,9 @@ for completion. That makes it really annoying to use; don't use yasnippet with e #+END_SRC #+BEGIN_SRC elisp - (require 'claude-code) - (keymap-global-set "C-c c" claude-code-command-map) + (use-package claude-code + :bind-keymap ("C-c c" . claude-code-command-map) + :custom (claude-code-optimize-window-resize nil)) #+END_SRC * Theme I like Catppuccin Frappe as my theme. Let's use it in as many places as we can. From e6240591c9a8783ec02a575b649667309dbf671e Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Fri, 24 Jul 2026 17:08:51 -0400 Subject: [PATCH 18/21] font etc --- home.org | 119 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 77 insertions(+), 42 deletions(-) diff --git a/home.org b/home.org index 2768024..e8ad7ba 100644 --- a/home.org +++ b/home.org @@ -188,7 +188,7 @@ These programs require a full desktop environment: nerd-fonts.symbols-only (iosevka-bin.override { variant = "Aile"; }) (iosevka-bin.override { variant = "Etoile"; }) - (iosevka-bin.override { variant = "SGr-IosevkaTerm"; }) + (iosevka-bin.override { variant = "SGr-IosevkaTermSS14"; }) keymapp proton-pass wireshark @@ -835,6 +835,9 @@ Turn off some default settings that I don't find useful. (setopt mouse-wheel-tilt-scroll t) (setq-default truncate-lines t) + + (setopt tab-bar-show nil) + (tab-bar-mode) #+END_SRC Make sure which-key mode is always on. The on-the-fly keymap help it gives is indespensable. @@ -960,11 +963,12 @@ Set up a few project- / workspace-related key bindings. #+BEGIN_SRC elisp (bind-keys ("s-f" . project-find-file) ("s-F" . project-switch-project) - ("s-s" . persp-switch)) + ;; ("s-s" . persp-switch) + ) - ;; (with-eval-after-load 'tab-bar - ;; (bind-keys :map tab-bar-mode-map - ;; ("s-s" . tab-bar-switch-to-tab))) + (with-eval-after-load 'tab-bar + (bind-keys :map tab-bar-mode-map + ("s-s" . tab-bar-switch-to-tab))) #+END_SRC Don't run a server. I'm not using this, I can always turn it back on if I need to. @@ -1035,27 +1039,40 @@ content to be. when height do (progn (window-resize child (- height (window-height child))) (window-preserve-size child nil t)))))))) - (require 'perspective) - (setopt persp-mode-prefix-key (kbd "C-x t")) - (setopt persp-show-modestring nil) - (persp-mode) + (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/popper-group-by-owning-perspective () - "Return the name of the perspective that owns the current buffer. + (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)))) - 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)))) + (add-hook 'window-size-change-functions #'jf/enforce-right-side-widths) + + ;; (require 'perspective) + ;; (setopt persp-mode-prefix-key (kbd "C-x t")) + ;; (setopt persp-show-modestring nil) + ;; (persp-mode) + + ;; (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 .*" @@ -1085,7 +1102,7 @@ content to be. "\\*List .*" "\\*eldoc\\*")) (setopt popper-display-control nil) - (setopt popper-group-function 'jf/popper-group-by-owning-perspective) + ;; (setopt popper-group-function 'jf/popper-group-by-owning-perspective) (popper-mode) (popper-echo-mode) @@ -1128,9 +1145,9 @@ content to be. (display-buffer-in-side-window) (side . right) (slot . 0) - (window-width . 93) + (window-width . jf/enforce-right-side-width) (window-height . jf/enforce-right-side-heights) - (preserve-size . (t . nil)) + (preserve-size . (nil . nil)) (window-parameters (no-delete-other-windows . t) (no-other-window . t))) ((or "\\*Embark Actions\\*" @@ -1138,9 +1155,9 @@ content to be. (display-buffer-in-side-window) (side . right) (slot . -1) - (window-width . 93) + (window-width . jf/enforce-right-side-width) (window-height . jf/enforce-right-side-heights) - (preserve-size . (t . t)) + (preserve-size . (nil . t)) (window-parameters (no-delete-other-windows . t) (no-other-window . t))))) @@ -1793,7 +1810,21 @@ for completion. That makes it really annoying to use; don't use yasnippet with e (eval-when-compile (require 'consult)) - (require 'perspective) + ;; (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) @@ -1804,9 +1835,7 @@ for completion. That makes it really annoying to use; don't use yasnippet with e 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)) + :preview-key '(:debounce 0.4 any))) (setopt consult-narrow-key "<") ;; "C-+" @@ -1958,9 +1987,10 @@ for completion. That makes it really annoying to use; don't use yasnippet with e ;; (setq org-roam-node-display-template (concat "${title:*} " (propertize "${tags:10}" 'face 'org-tag))) ;; (org-roam-db-autosync-mode) - (add-hook 'org-mode-hook 'org-modern-mode) + (use-package org-modern + :hook org-mode-hook) - (define-key org-mode-map (kbd "C-c C-r") verb-command-map) + ;; (define-key org-mode-map (kbd "C-c C-r") verb-command-map) #+END_SRC ** Terminal @@ -1981,7 +2011,9 @@ for completion. That makes it really annoying to use; don't use yasnippet with e #+END_SRC #+BEGIN_SRC elisp - (eat-eshell-mode) + (use-package eat + :commands (eat) + :hook (eshell-load-hook . eat-eshell-mode)) #+END_SRC ** Slack @@ -2045,10 +2077,13 @@ for completion. That makes it really annoying to use; don't use yasnippet with e #+END_SRC #+BEGIN_SRC elisp - (setopt age-default-identity "~/source/dotfiles/keys/yubi1age.txt") - (setopt age-default-recipient "~/source/dotfiles/keys/myself.txt") - (setenv "PINENTRY_PROGRAM" "pinentry-mac") - (age-file-enable) + (use-package age + :custom + (setopt age-default-identity "~/source/dotfiles/keys/yubi1age.txt") + (age-default-recipient "~/source/dotfiles/keys/myself.txt") + :config + (setenv "PINENTRY_PROGRAM" "pinentry-mac") + (age-file-enable)) #+END_SRC ** Claude Code @@ -2197,7 +2232,7 @@ I like Catppuccin Frappe as my theme. Let's use it in as many places as we can. ;; (set-face-attribute 'default nil :font "JetBrainsMono Nerd Font" :height 130) ;; (set-face-attribute 'fixed-pitch nil :font "JetBrainsMono Nerd Font" :height 130) - (set-face-attribute 'default nil :font "Iosevka Term" :height 130 :width 'expanded) - (set-face-attribute 'fixed-pitch nil :font "Iosevka Term" :height 130 :width 'expanded) + (set-face-attribute 'default nil :font "Iosevka Term SS14" :height 130 :width 'expanded) + (set-face-attribute 'fixed-pitch nil :font "Iosevka Term SS14" :height 130 :width 'expanded) (set-face-attribute 'variable-pitch nil :font "Iosevka Etoile" :height 130) #+END_SRC From 3159d20e6d04ff791f4684dd32310f9bdacdd0d0 Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Thu, 6 Aug 2026 16:22:57 -0400 Subject: [PATCH 19/21] wip --- home.org | 363 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 225 insertions(+), 138 deletions(-) diff --git a/home.org b/home.org index e8ad7ba..6b45389 100644 --- a/home.org +++ b/home.org @@ -318,6 +318,7 @@ We all know what ~git~ does. settings.user.name = "Joe Frikker"; settings.user.email = "joe@redbookcattle.com"; settings.github.user = "joe@redbookcattle.com"; + settings.merge.conflictstyle = "zdiff3"; }; programs.delta = { @@ -344,7 +345,7 @@ The best text editor ever? Heresy! auto-save.after-delay.timeout = 1000; cursorline = true; idle-timeout = 0; - rulers = [100]; + rulers = [120]; text-width = 100; lsp.goto-reference-include-declaration = false; cursor-shape.insert = "bar"; @@ -505,6 +506,7 @@ Then the real lua config: #+BEGIN_SRC lua local config = {} config.default_prog = { '/Users/jfrikker/.nix-profile/bin/zsh', '-l' } + config.font = wezterm.font 'Iosevka Term SS14' config.font_size = 13.0 -- config.font = wezterm.font("JetBrains Mono") config.inactive_pane_hsb = { @@ -699,6 +701,11 @@ Now we'll set up some keybindings: programs.ghostty = { enable = true; package = pkgs.ghostty-bin; + settings = { + adjust-cell-height = "15%"; + font-family = "Iosevka Term SS14"; + font-size = 13; + }; }; } #+END_SRC @@ -832,6 +839,8 @@ Turn off some default settings that I don't find useful. (column-number-mode t) (setopt auto-save-default nil) (setopt create-lockfiles nil) + (setopt enable-recursive-minibuffers t) + (setopt line-spacing 0.15) (setopt mouse-wheel-tilt-scroll t) (setq-default truncate-lines t) @@ -987,7 +996,7 @@ less so? I'm trying this out. This disables visual selections. It's bold, which is why I like it :) #+BEGIN_SRC elisp - ;; (transient-mark-mode -1) + (transient-mark-mode -1) #+END_SRC I use tabs to manage multiple "workspaces". I don't tie a project to a tab or anything; often fixing @@ -1019,152 +1028,229 @@ windows. I place windows in the bottom or on the right mostly depending on how w content to be. #+BEGIN_SRC elisp - (defun jf/window-children (window) - (let ((result nil) - (child (window-child window))) - (while child - (push child result) - (setq child (window-next-sibling child))) - (reverse result))) + (defun jf/window-children (window) + (let ((result nil) + (child (window-child window))) + (while child + (push child result) + (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/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/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/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/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/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)))) - (add-hook 'window-size-change-functions #'jf/enforce-right-side-widths) + (add-hook 'window-size-change-functions #'jf/enforce-right-side-widths) - ;; (require 'perspective) - ;; (setopt persp-mode-prefix-key (kbd "C-x t")) - ;; (setopt persp-show-modestring nil) - ;; (persp-mode) + ;; (require 'perspective) + ;; (setopt persp-mode-prefix-key (kbd "C-x t")) + ;; (setopt persp-show-modestring nil) + ;; (persp-mode) - ;; (defun jf/popper-group-by-owning-perspective () - ;; "Return the name of the perspective that owns the current buffer. + ;; (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)))) + ;; 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 .*" - "\\*Embark Export: .*" - "\\*Embark Collect .*" - "\\*xref\\*" - "\\*compilation\\*" - "\\*pnpm:.*" - "\\*sly-mrepl *" - "\\*Messages\\*" - "\\*lispy-message\\*" - "\\*EGLOT connections\\*" - "\\*trace-output\\*" - "\\*occur\\*" - ".*eshell\\*" - "\\*SQL: .*" - "magit: *" - "magit-revision: .*" - "magit-log*" - "\\*Help\\*" - "\\*rustfmt\\*" - "\\*slack: .*" - "\\*forge: .*" - "new-pullreq" - "\\*claude:.*" - "\\*Man .*" - "\\*List .*" - "\\*eldoc\\*")) - (setopt popper-display-control nil) - ;; (setopt popper-group-function 'jf/popper-group-by-owning-perspective) + (setopt popper-reference-buffers + '("\\*Flymake diagnostics .*" + "\\*Embark Export: .*" + "\\*Embark Collect .*" + "\\*xref\\*" + "\\*compilation\\*" + "\\*pnpm:.*" + "\\*sly-mrepl *" + "\\*lispy-message\\*" + "\\*occur\\*" + ".*eshell\\*" + "\\*SQL: .*" + "magit-revision: .*" + "\\*Help\\*" + "\\*rustfmt\\*" + "\\*slack: .*" + "\\*forge: .*" + "new-pullreq" + "\\*claude:.*" + "\\*Man .*" + "\\*List .*" + "\\*eldoc\\*")) + (setopt popper-display-control nil) + ;; (setopt popper-group-function 'jf/popper-group-by-owning-perspective) - (popper-mode) - (popper-echo-mode) + (popper-mode) + (popper-echo-mode) - (bind-keys ("C-q" . popper-toggle) - ("C-;" . popper-cycle)) + (bind-keys ("C-q" . popper-toggle) + ("C-;" . popper-cycle)) - (setq display-buffer-alist - '(((or "\\*Flymake diagnostics .*" - "\\*Embark Export: .*" - "\\*Embark Collect .*" - "\\*xref\\*" - "\\*compilation\\*" - "\\*pnpm:.*" - "\\*sly-mrepl *" - "\\*Messages\\*" - "\\*lispy-message\\*" - "\\*EGLOT connections\\*" - "\\*trace-output\\*" - "\\*occur\\*" - ".*eshell\\*" - "\\*SQL: .*") - (display-buffer-in-side-window) - (side . bottom) - (slot . 0) - (window-height . 0.33) - (window-parameters (no-delete-other-windows . t) - (no-other-window . t))) - ((or "magit: *" - "magit-revision: .*" - "magit-log*" - "\\*Help\\*" - "\\*rustfmt\\*" - "\\*slack: .*" - "\\*forge: .*" - "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\\*" - "\\*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))))) + (defvar jf/fullscreen-popup--param 'jf/fullscreen-saved-configuration + "Key used to stash the window configuration a fullscreen popup replaced. +Stored per-tab when `tab-bar-mode' is active, otherwise as a plain frame +parameter; see `jf/tab-or-frame-parameter'.") - (setopt window-persistent-parameters - (cl-list* '(no-delete-other-windows . writable) - '(no-other-window . writable) - window-persistent-parameters)) + (defvar-local jf/fullscreen-popup-p nil + "Non-nil in a buffer currently being displayed as a fullscreen popup.") + + (defun jf/current-tab-cell (&optional frame) + "Return FRAME's current tab's raw data cell, or nil without `tab-bar-mode'." + (and (bound-and-true-p tab-bar-mode) + (assq 'current-tab (tab-bar-tabs frame)))) + + (defun jf/tab-or-frame-parameter (parameter &optional frame) + "Like `frame-parameter', but scoped to FRAME's selected tab when tabs are in use. + +A plain frame parameter is shared by every tab on that frame, which is wrong +for state like `jf/fullscreen-popup--param': switching tabs swaps in an +entirely different window layout, so \"the layout to restore\" has to travel +with the tab, not the frame." + (if-let ((tab (jf/current-tab-cell frame))) + (alist-get parameter tab) + (frame-parameter frame parameter))) + + (defun jf/set-tab-or-frame-parameter (parameter value &optional frame) + "Set PARAMETER to VALUE, scoped like `jf/tab-or-frame-parameter'." + (if-let ((tab (jf/current-tab-cell frame))) + (let ((cell (assq parameter tab))) + (if cell + (setcdr cell value) + (setcdr tab (cons (cons parameter value) (cdr tab))))) + (set-frame-parameter frame parameter value))) + + (defun jf/display-buffer-fullscreen (buffer alist) + "Display BUFFER, deleting other windows, saving the prior layout. + +Intended for use in `display-buffer-alist' for popups (e.g. Magit +status/log) that should take over the frame while displayed, but +restore the previous window configuration once closed via either +`q' or `popper-toggle' -- both end up calling `quit-window', which +is where the restore actually happens; see +`jf/quit-window-restore-fullscreen'." + (unless (jf/tab-or-frame-parameter jf/fullscreen-popup--param) + (jf/set-tab-or-frame-parameter jf/fullscreen-popup--param + (current-window-configuration))) + (when-let ((window (or (display-buffer-reuse-window buffer alist) + (display-buffer-same-window buffer alist) + (display-buffer-pop-up-window buffer alist) + (display-buffer-use-some-window buffer alist)))) + (let ((ignore-window-parameters t)) + (delete-other-windows window)) + (with-current-buffer buffer + (setq jf/fullscreen-popup-p t)) + window)) + + (defun jf/quit-window-restore-fullscreen (orig-fn &optional kill window) + "Restore the saved window configuration after quitting a fullscreen popup. + +Advice around `quit-window' so both `q' (which Magit and other +special-mode buffers bind to buffer-quitting commands that call +`quit-window') and Popper's close/toggle commands (which also call +`quit-window' directly) trigger the restore. Only restores once the +last fullscreen popup on the tab (or frame, without `tab-bar-mode') +has closed, so opening one fullscreen popup from within another +falls back to the outer one first." + (let* ((window (or window (selected-window))) + (was-fullscreen (buffer-local-value 'jf/fullscreen-popup-p + (window-buffer window))) + (frame (window-frame window))) + (funcall orig-fn kill window) + (when (and was-fullscreen + (not (and (window-live-p window) + (buffer-local-value 'jf/fullscreen-popup-p + (window-buffer window)))) + (jf/tab-or-frame-parameter jf/fullscreen-popup--param frame)) + (let ((conf (jf/tab-or-frame-parameter jf/fullscreen-popup--param frame))) + (jf/set-tab-or-frame-parameter jf/fullscreen-popup--param nil frame) + (set-window-configuration conf))))) + + (advice-add 'quit-window :around #'jf/quit-window-restore-fullscreen) + + (setq display-buffer-alist + '(((or "magit: *" + "magit-log*" + "\\*Messages\\*" + "\\*trace-output\\*" + "\\*EGLOT connections\\*") + (jf/display-buffer-fullscreen)) + ((or "\\*Flymake diagnostics .*" + "\\*Embark Export: .*" + "\\*Embark Collect .*" + "\\*xref\\*" + "\\*compilation\\*" + "\\*pnpm:.*" + "\\*sly-mrepl *" + "\\*lispy-message\\*" + "\\*occur\\*" + ".*eshell\\*" + "\\*SQL: .*") + (display-buffer-in-side-window) + (side . bottom) + (slot . 0) + (window-height . 0.33) + (window-parameters (no-delete-other-windows . t) + (no-other-window . t))) + ((or "magit-revision: .*" + "\\*Help\\*" + "\\*rustfmt\\*" + "\\*slack: .*" + "\\*forge: .*" + "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\\*" + "\\*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))))) + + (setopt window-persistent-parameters + (cl-list* '(no-delete-other-windows . writable) + '(no-other-window . writable) + window-persistent-parameters)) #+END_SRC @@ -1497,6 +1583,7 @@ I don't like UI elements that insert fake text into the file. They mess up the s (setopt eglot-ignored-server-capabilities '(:inlayHintProvider :semanticTokensProvider)) (add-hook 'eglot-managed-mode-hook (lambda () (eglot-inlay-hints-mode -1)) nil t) (setopt eglot-code-action-indications nil) + (setopt eglot-events-buffer-config '(:size 300000 :format full)) #+END_SRC Set up a few useful eglot keys. @@ -2232,7 +2319,7 @@ I like Catppuccin Frappe as my theme. Let's use it in as many places as we can. ;; (set-face-attribute 'default nil :font "JetBrainsMono Nerd Font" :height 130) ;; (set-face-attribute 'fixed-pitch nil :font "JetBrainsMono Nerd Font" :height 130) - (set-face-attribute 'default nil :font "Iosevka Term SS14" :height 130 :width 'expanded) - (set-face-attribute 'fixed-pitch nil :font "Iosevka Term SS14" :height 130 :width 'expanded) + (set-face-attribute 'default nil :font "Iosevka Term SS14" :height 130) + (set-face-attribute 'fixed-pitch nil :font "Iosevka Term SS14" :height 130) (set-face-attribute 'variable-pitch nil :font "Iosevka Etoile" :height 130) #+END_SRC From 5f639e747da957cad7a890d6c85886bf07e70e38 Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Wed, 19 Aug 2026 17:39:50 -0400 Subject: [PATCH 20/21] kitty? --- home.org | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/home.org b/home.org index 6b45389..9fbb94c 100644 --- a/home.org +++ b/home.org @@ -694,6 +694,32 @@ Now we'll set up some keybindings: end #+END_SRC +** Kitty +#+BEGIN_SRC nix :tangle target/desktop/kitty.nix + {pkgs, ...}: { + programs.kitty = { + enable = true; + font = { + name = "Iosevka Term SS14"; + package = pkgs.iosevka-bin.override { variant = "SGr-IosevkaTermSS14"; }; + size = 13; + }; + themeFile = "Catppuccin-Frappe"; + keybindings = { + "ctrl+1" = "goto_tab 1"; + "ctrl+2" = "goto_tab 2"; + "ctrl+3" = "goto_tab 3"; + "ctrl+4" = "goto_tab 4"; + "ctrl+5" = "goto_tab 5"; + "ctrl+6" = "goto_tab 6"; + "ctrl+7" = "goto_tab 7"; + "ctrl+8" = "goto_tab 8"; + "ctrl+9" = "goto_tab 9"; + }; + }; + } +#+END_SRC + ** Ghostty #+BEGIN_SRC nix :tangle target/desktop/ghostty.nix @@ -1972,6 +1998,8 @@ for completion. That makes it really annoying to use; don't use yasnippet with e ("C-c C" . org-capture) ("C-c l" . org-id-store-link)) + (setopt org-babel-load-languages '((emacs-lisp . t) (sql . t))) + (setopt org-confirm-babel-evaluate nil) (add-hook 'org-mode-hook 'visual-line-mode) (setopt org-link-keep-stored-after-insertion t org-capture-templates @@ -2295,6 +2323,13 @@ I like Catppuccin Frappe as my theme. Let's use it in as many places as we can. return config #+END_SRC +** Ghostty +#+BEGIN_SRC nix :tangle target/desktop/ghostty-theme.nix + { + programs.ghostty.settings.theme = "Catppuccin Frappe"; + } +#+END_SRC + ** Emacs :PROPERTIES: :header-args:elisp: :tangle target/desktop/emacs-theme.el From 3682c1ad10be7620dab27ff2944986d16a7fbf4c Mon Sep 17 00:00:00 2001 From: Joe Frikker Date: Wed, 19 Aug 2026 21:32:09 -0400 Subject: [PATCH 21/21] flake update --- flake.lock | 52 +++++++++++++++++----------------------------------- 1 file changed, 17 insertions(+), 35 deletions(-) diff --git a/flake.lock b/flake.lock index 4a2a988..ec8a989 100644 --- a/flake.lock +++ b/flake.lock @@ -2,40 +2,22 @@ "nodes": { "claude-code": { "inputs": { - "flake-utils": "flake-utils", "nixpkgs": [ "nixpkgs" - ] - }, - "locked": { - "lastModified": 1783380155, - "narHash": "sha256-SwUwKaLrZ+c5y4GoZHKBf1nUsDHVsIUtn2CFloZrV2A=", - "owner": "sadjow", - "repo": "claude-code-nix", - "rev": "25d979d1a39d0acdbcb1b8d0b9d83ffdd10b5f43", - "type": "github" - }, - "original": { - "owner": "sadjow", - "repo": "claude-code-nix", - "type": "github" - } - }, - "flake-utils": { - "inputs": { + ], "systems": "systems" }, "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "lastModified": 1787169825, + "narHash": "sha256-3MmWHAzeoFHfwjUCQC01olBN+MC4xoSuR7D0bpPr+EE=", + "owner": "sadjow", + "repo": "claude-code-nix", + "rev": "f575914388682670df73e80c9caf82063b659699", "type": "github" }, "original": { - "owner": "numtide", - "repo": "flake-utils", + "owner": "sadjow", + "repo": "claude-code-nix", "type": "github" } }, @@ -46,11 +28,11 @@ ] }, "locked": { - "lastModified": 1783436070, - "narHash": "sha256-F80z1JoiJgZyTT5D+3siLOVzqmCEphLR7t0Ym/I2CLI=", + "lastModified": 1787176219, + "narHash": "sha256-djoRr6jBpe35q/0JwAvXpFXg1Ktf+X54NU2RLR7wnHw=", "owner": "nix-community", "repo": "home-manager", - "rev": "f09af49406ffad37acb6538d3207189a1a1e0b7e", + "rev": "c53d643b3737e2fcd04e6cb3b3580ef50b2087a0", "type": "github" }, "original": { @@ -67,11 +49,11 @@ ] }, "locked": { - "lastModified": 1783414108, - "narHash": "sha256-RY8e+gR2/DhXsYDxGDL6Hhe9+POD9u4+llwxMBqMQDs=", + "lastModified": 1786852476, + "narHash": "sha256-IM5CYtf86W4w8eUPpKcY/LpdHElmVBtJhaKnoTKxZEA=", "owner": "nix-community", "repo": "nix-index-database", - "rev": "96d6de10eb281b98f5cfcd1841394c03da5df77c", + "rev": "c7962dc97b45129df8d751bedaf37beb5a17706e", "type": "github" }, "original": { @@ -82,11 +64,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1783148766, - "narHash": "sha256-uslt2pqShTIXDdAHRHv2QkYLsVdY8Oqwz0EA48/RSM8=", + "lastModified": 1787101114, + "narHash": "sha256-gwrPcFf/rDjHPaVflbDZ040ZDmBTRj/7+s8ZmE2SaIM=", "owner": "nixos", "repo": "nixpkgs", - "rev": "a50de1b7d8a586adc18d2395c19de7d6058e6030", + "rev": "b18a4b905f8d028dc4476412e6d6891728695379", "type": "github" }, "original": {