From 52129f04bbe65d8fdafdec6691abc5d9a0882dfa Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 11 Mar 2023 19:50:28 -0500 Subject: [PATCH] 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. --- modules/tools/direnv/config.el | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/modules/tools/direnv/config.el b/modules/tools/direnv/config.el index 870041a84..a2982c2a3 100644 --- a/modules/tools/direnv/config.el +++ b/modules/tools/direnv/config.el @@ -7,13 +7,12 @@ (set-popup-rule! "^\\*envrc\\*" :quit t :ttl 0) - ;; A globalized minor mode triggers on `after-change-major-mode-hook' - ;; normally, which runs after a major mode's body and hooks. If those hooks do - ;; any initialization work that's sensitive to environmental state set up by - ;; direnv, then you're gonna have a bad time, so I move the trigger to - ;; `change-major-mode-after-body-hook' instead. This runs before said hooks - ;; (but not the body; fingers crossed that no major mode does important env - ;; initialization there). + ;; HACK: Normally, envrc updates on `after-change-major-mode-hook' (runs after + ;; a major mode's body and hooks). IMHO, this is too late; a mode's hooks + ;; might depend on environmental state that direnv sets up (e.g. starting an + ;; LSP server that expects project-specific envvars), so I move it to + ;; `change-major-mode-after-body-hook' instead, which runs before said + ;; hooks, but not the body. (add-hook! 'envrc-global-mode-hook (defun +direnv-init-global-mode-earlier-h () (let ((fn #'envrc-global-mode-enable-in-buffers)) @@ -22,6 +21,13 @@ (remove-hook 'after-change-major-mode-hook fn) (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 _) "Don't try to use direnv if the executable isn't present." :before-while #'envrc-global-mode