purcell / envrc

Emacs support for direnv which operates buffer-locally
378 stars 35 forks source link

Question about disabling .envrc loading on consult previews #83

Closed Rutherther closed 3 months ago

Rutherther commented 5 months ago

I am using consult for preview when switching files in the minibuffer. The issue is that when I hit a file that is from not loaded .envrc environment, the environment gets loaded. This produces a delay in browsing the entries. I would like to somehow disable envrc when using this preview.

I am not sure if there is any support needed on either envrc or consult side, or not. I am using envrc-global-mode. I was thinking that easiest solution for me could be to just disable envrc-global-mode when using minibuffer, and reenable it afterwards. However, I was wondering if there could be a better solution than this one, provided by envrc logic in envrc-global-mode?

I noticed the current code of envrc checks for being in minibuffer, however, since the preview itself is not in the minibuffer, it's not hit.

Rutherther commented 5 months ago

Upon further inspection it looks to me like one way to resolve this would be to expose a way to disable envrc in buffers based on their name, for example with regex matching. The preview buffer will always have "Preview:" prefix when the file is not already opened. For already opened files, the envrc should not be ran anyway.

purcell commented 5 months ago

I don't know in which buffer consult executes commands like grep for previews, but if it's the preview buffer itself then it might be annoying to disable envrc-mode in all such buffers, because the command might not work correctly without the current environment being activated.

I get the concern, though. Presumably it's slow to load the env because it's Nix and is not cached locally, or something like that?

Rutherther commented 5 months ago

Based on my understanding of consult, it will first do the grep, and then from the found results craft the previews when one goes over them. The preview is an optional feature that can be disabled without losing anything else than the preview.

I of course understand concerns of disabling envrc. Sometimes without the environment, even the preview could not work properly. That's why I wouldn't propose a solution that would disable it for everyone using consult preview, but make it somehow more general. Personally it looks to me that disabling by buffer name could be a possibility.

Yes, the env is Nix, but it's too slow for me even if cached. It doesn't take very long cached, but it's noticeable for me. For example when I open recent files and the first one happens to be from not loaded environment. The time it takes (measured from putting start_time, end_time in .envrc at beginning and end, maybe there is also some other overhead) is something like 300 - 400 ms. This can look fine, but from the otherwise visibly instant command it is very inconvenient for me. Also I have a envrc that does a shell hook where the command it does takes another 500 ms. Maybe it could be argued the envrc is poorly designed in this case. (and I will surely remake it in the future)

purcell commented 5 months ago

Might something like the following work, perhaps?

(advice-add #'consult--find-file-temporarily
  :around (lambda (orig name)
            (let ((envrc-global-mode nil))
               (funcall orig name))))
Rutherther commented 5 months ago

Thanks for this suggestion. Unfortunately it does not work. I made some logging to get more information

  (defun consult-find-temporarily-wrapper (orig name)
    (message "consult--find-file-temporarily %s called" name)
    (unwind-protect
      (funcall orig name)
      (message "consult--find-file-temporarily ran")
        )
    )

  (advice-add #'consult--find-file-temporarily
              :around #'consult-find-temporarily-wrapper)

  (define-globalized-minor-mode envrc-global-mode envrc-mode
    (lambda () (when (and (not (minibufferp))
                          (not (file-remote-p default-directory))
                          (executable-find envrc-direnv-executable))
                (message "envrc-global-mode %s" (buffer-name))
                                        ;(envrc-mode 1)
                )))

and I get (I changed the file name)

consult--find-file-temporarily /my-file called
consult--find-file-temporarily ran
envrc-global-mode  Preview:/my-file

So it seems consult--find-file-temporarily is executed prior to envrc-global-mode execution