[emacs] Fixing magit key loading

This commit is contained in:
2026-03-03 23:18:10 -05:00
parent 2862708767
commit fc95f7e6d7

View File

@ -8,6 +8,12 @@
(after! envrc
(envrc-global-mode))
;; Force systemd user ssh-agent socket for all Emacs subprocesses.
(let* ((xdg (format "/run/user/%d" (user-uid)))
(sock (expand-file-name "ssh-agent.socket" xdg)))
(setenv "XDG_RUNTIME_DIR" xdg)
(setenv "SSH_AUTH_SOCK" sock))
;; load pinentry
(when (require 'pinentry nil t)
(pinentry-start))
@ -444,35 +450,55 @@ Always open the result in `eww`."
(global-set-key (kbd "C-c l") #'life-scrobble-url)
(after! magit
(defvar my/ssh-key-injector-script
(expand-file-name "~/.local/bin/load_keys"))
(defvar my/ssh-key-injector-script (expand-file-name "~/.local/bin/load_keys"))
(defun my/ssh-agent-has-keys-p (&rest _ignore)
"Non-nil if ssh-agent currently has at least one identity loaded."
(eq 0 (call-process "ssh-add" nil nil nil "-l")))
(defun my/systemd-ssh-auth-sock ()
(format "/run/user/%d/ssh-agent.socket" (user-uid)))
(defun my/ssh-add-status ()
"ssh-add -l exit code: 0=has keys, 1=no keys, 2=no agent."
(call-process "ssh-add" nil nil nil "-l"))
(defun my/run-ssh-key-injector ()
(let* ((buf (get-buffer-create "*ssh-key-injector*"))
(sock (my/systemd-ssh-auth-sock))
(process-connection-type t) ;; PTY for pinentry-curses
(process-environment (copy-sequence process-environment)))
(setenv "SSH_AUTH_SOCK" sock)
(setenv "XDG_RUNTIME_DIR" (format "/run/user/%d" (user-uid)))
(defun my/ensure-ssh-keys-loaded (&rest _ignore)
"Ensure ssh-agent has keys loaded; if not, run injector script."
(unless (file-executable-p my/ssh-key-injector-script)
(user-error "SSH injector script not executable: %s" my/ssh-key-injector-script))
(let ((buf (get-buffer-create "*ssh-key-injector*")))
(with-current-buffer buf (erase-buffer))
(let ((exit (call-process-shell-command my/ssh-key-injector-script nil buf t)))
(with-current-buffer buf
(erase-buffer)
(insert (format "Emacs SSH_AUTH_SOCK=%s\n" (getenv "SSH_AUTH_SOCK")))
(insert (format "Emacs XDG_RUNTIME_DIR=%s\n\n" (getenv "XDG_RUNTIME_DIR"))))
(let ((proc (make-process
:name "ssh-key-injector"
:buffer buf
:stderr buf
:command (list my/ssh-key-injector-script)
:noquery t)))
(while (process-live-p proc)
(accept-process-output proc 0.05))
(let ((exit (process-exit-status proc)))
(unless (eq exit 0)
(display-buffer buf)
(user-error "SSH key injection failed (see *ssh-key-injector*)")))))
(user-error "SSH key injection failed (exit %d). See *ssh-key-injector*." exit))))))
;; IMPORTANT: remove then re-add, so we don't keep an old advised function object around
(advice-remove 'magit-status #'my/ensure-ssh-keys-loaded)
(advice-add 'magit-status :before #'my/ensure-ssh-keys-loaded)
(defun my/ensure-ssh-keys-loaded (&rest _ignore)
(pcase (my/ssh-add-status)
(0 nil) ;; already has identities
(1 (my/run-ssh-key-injector)) ;; agent reachable but empty
(2 (user-error "No reachable ssh-agent. SSH_AUTH_SOCK=%s"
(or (getenv "SSH_AUTH_SOCK") "<unset>")))
(_ (my/run-ssh-key-injector))))
;; optional:
(advice-remove 'magit-fetch #'my/ensure-ssh-keys-loaded)
(advice-add 'magit-fetch :before #'my/ensure-ssh-keys-loaded)
(advice-remove 'magit-push #'my/ensure-ssh-keys-loaded)
(advice-add 'magit-push :before #'my/ensure-ssh-keys-loaded)
(advice-remove 'magit-pull #'my/ensure-ssh-keys-loaded)
(advice-add 'magit-pull :before #'my/ensure-ssh-keys-loaded))
(dolist (fn '(magit-status magit-fetch magit-push magit-pull))
(advice-remove fn #'my/ensure-ssh-keys-loaded)
(advice-add fn :before #'my/ensure-ssh-keys-loaded)))
(defun my/disable-apheleia-in-certain-projects ()
(when-let ((root (and (fboundp 'project-root)