fix(direnv): envrc triggering in its own internal buffers

This would produce extra (and confusing) noise in envrc's error popup,
and also means multiple (potentially expensive) calls to direnv in
failure cases.
This commit is contained in:
Henrik Lissner 2023-03-11 19:50:28 -05:00
parent f1f010ff99
commit 52129f04bb
No known key found for this signature in database
GPG key ID: B60957CA074D39A3

View file

@ -7,13 +7,12 @@
(set-popup-rule! "^\\*envrc\\*" :quit t :ttl 0) (set-popup-rule! "^\\*envrc\\*" :quit t :ttl 0)
;; A globalized minor mode triggers on `after-change-major-mode-hook' ;; HACK: Normally, envrc updates on `after-change-major-mode-hook' (runs after
;; normally, which runs after a major mode's body and hooks. If those hooks do ;; a major mode's body and hooks). IMHO, this is too late; a mode's hooks
;; any initialization work that's sensitive to environmental state set up by ;; might depend on environmental state that direnv sets up (e.g. starting an
;; direnv, then you're gonna have a bad time, so I move the trigger to ;; LSP server that expects project-specific envvars), so I move it to
;; `change-major-mode-after-body-hook' instead. This runs before said hooks ;; `change-major-mode-after-body-hook' instead, which runs before said
;; (but not the body; fingers crossed that no major mode does important env ;; hooks, but not the body.
;; initialization there).
(add-hook! 'envrc-global-mode-hook (add-hook! 'envrc-global-mode-hook
(defun +direnv-init-global-mode-earlier-h () (defun +direnv-init-global-mode-earlier-h ()
(let ((fn #'envrc-global-mode-enable-in-buffers)) (let ((fn #'envrc-global-mode-enable-in-buffers))
@ -22,6 +21,13 @@
(remove-hook 'after-change-major-mode-hook fn) (remove-hook 'after-change-major-mode-hook fn)
(add-hook 'change-major-mode-after-body-hook fn 100))))) (add-hook 'change-major-mode-after-body-hook fn 100)))))
;; ...However, the above hack causes envrc to trigger in its own, internal
;; buffers, causing extra direnv errors.
(defadvice! +direnv--debounce-update-a (&rest _)
"Prevent direnv from running multiple times, consecutively in a buffer."
:before-while #'envrc--update
(not (string-prefix-p "*envrc" (buffer-name))))
(defadvice! +direnv--fail-gracefully-a (&rest _) (defadvice! +direnv--fail-gracefully-a (&rest _)
"Don't try to use direnv if the executable isn't present." "Don't try to use direnv if the executable isn't present."
:before-while #'envrc-global-mode :before-while #'envrc-global-mode