tools/direnv: replace direnv package with envrc

wbolster/emacs-direnv uses an approach that mutates global state,
allowing a direnv to bleed into unrelated buffers and contexts. For this
to work it must rereads the direnv every time you switch buffers, which
can be very slow.

purcell/envrc, on the other hand, makes env state buffer-local, so the
direnv only needs to be read once, when a is first initialized. This is
faster and less error prone. However, it's necessary to manually reload
the direnv if you've changed your .envrc outside of Emacs (with `M-x
envrc-reload` or `M-x envrc-reload-all`).
This commit is contained in:
Henrik Lissner 2020-08-21 02:34:07 -04:00
parent e54bb170c3
commit 06c404ecb1
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
3 changed files with 24 additions and 15 deletions

View file

@ -34,7 +34,7 @@ direnv and then made available to the current shell.
This module provides no flags. This module provides no flags.
** Plugins ** Plugins
+ [[https://github.com/wbolster/emacs-direnv][direnv]] + [[https://github.com/purcell/envrc][envrc]]
** Hacks ** Hacks
+ Normally, the direnv environment is updated on ~post-command-hook~. We've + Normally, the direnv environment is updated on ~post-command-hook~. We've

View file

@ -5,30 +5,39 @@
"join_args" "expand_path" "dotenv" "user_rel_path" "find_up" "source_env" "join_args" "expand_path" "dotenv" "user_rel_path" "find_up" "source_env"
"watch_file" "source_up" "direnv_load" "MANPATH_add" "load_prefix" "layout" "watch_file" "source_up" "direnv_load" "MANPATH_add" "load_prefix" "layout"
"use" "rvm" "use_nix" "use_guix") "use" "rvm" "use_nix" "use_guix")
"TODO") "A list of direnv keywords, which are fontified when in `+direnv-rc-mode'.")
;; ;;
;;; Packages ;;; Packages
(use-package! direnv (use-package! envrc
:hook (before-hack-local-variables . direnv--maybe-update-environment) :when (executable-find "direnv")
:hook (flycheck-before-syntax-check . direnv--maybe-update-environment) :after-call doom-first-file
:hook (direnv-envrc-mode . +direnv-envrc-fontify-keywords-h) :mode ("\\.envrc\\'" . +direnv-rc-mode)
:config :config
(add-to-list 'direnv-non-file-modes 'vterm-mode) (add-to-list 'doom-debug-variables 'envrc-debug)
(defun +direnv-envrc-fontify-keywords-h () ;; I'm avoiding `global-envrc-mode' intentionally, because it has the
"Fontify special .envrc keywords; it's a good indication of whether or not ;; potential to run too late in the mode startup process (and after, say,
we've typed them correctly." ;; server hooks that may rely on that local direnv environment).
(add-hook! 'change-major-mode-after-body-hook
(defun +direnv-init-h ()
(unless (or envrc-mode
(minibufferp)
(file-remote-p default-directory))
(envrc-mode 1))))
(define-derived-mode +direnv-rc-mode sh-mode "envrc"
"Major mode for .envrc files."
;; Fontify .envrc keywords; it's a good indication of whether or not we've
;; typed them correctly, and that we're in the correct major mode.
(font-lock-add-keywords (font-lock-add-keywords
nil `((,(regexp-opt +direnv-keywords 'symbols) nil `((,(regexp-opt +direnv-keywords 'symbols)
(0 font-lock-keyword-face))))) (0 font-lock-keyword-face)))))
(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 #'direnv-update-directory-environment :before-while #'envrc-mode
(or (executable-find "direnv") (or (executable-find "direnv")
(ignore (doom-log "Couldn't find direnv executable")))) (ignore (doom-log "Couldn't find direnv executable")))))
(direnv-mode +1))

View file

@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*- ;; -*- no-byte-compile: t; -*-
;;; tools/direnv/packages.el ;;; tools/direnv/packages.el
(package! direnv :pin "f5484b0fc33d4e5116612626294efb362ff9ecd4") (package! envrc :pin "1dc5aad14d2c27211c7c288d2d9dffeb2e27cb2d")