Open anderspapitto opened 1 year ago
This is really out of scope for envrc
to handle directly, but it's probably possible to hack something together.
something similar to how envrc handles buffers like Help, i.e. I would like envrc to hook into jump-to-definition
envrc
doesn't "handle" this, exactly. Those buffers simply inherit default-directory
from the calling buffer. If you wrap the jump function with an around
advice, you can note the pre-jump default-directory
, restore it in the post-jump buffer, and then trigger envrc
and LSP as desired.
I wrote some not-so-elegant hacks to deal with this problem. It seems to work well so far.
(defun akira/xref-inherit-envrc (func &rest args)
(if envrc-mode
(cl-letf*
(((default-value 'process-environment) process-environment)
((default-value 'exec-path) exec-path))
(let* ((marker (apply func args))
(new-buf (marker-buffer marker)))
(with-current-buffer new-buf
(setq-local process-environment (default-value 'process-environment))
(setq-local exec-path (default-value 'exec-path))
marker)))
(apply func args)))
;; for `evil-ret', for example, with `evil-mode', when your cursor is above <vector> in #include <vector>,
;; you can press enter to direct access the file
(defun akira/lsp-document-link-inherit-envrc (func &rest args)
(if (and envrc-mode
(equal "file"
(url-type (url-generic-parse-url (url-unhex-string (car args))))))
(cl-letf*
(((default-value 'process-environment) process-environment)
((default-value 'exec-path) exec-path)
(result (apply func args)))
(setq-local process-environment (default-value 'process-environment))
(setq-local exec-path (default-value 'exec-path))
result)
(apply func args)))
;; for the builtin gdb debugger of emacs
(defun akira/gud-display-line-inherit-envrc (func &rest args)
;; the caller calls `gud-display-line' in a buffer with `default-directory' set correctly, but doesn't
;; have `envrc-mode' enabled, thus we enable it before calling `gud-display-line'
(unless envrc-mode
(envrc-mode))
(cl-letf*
(((default-value 'process-environment) process-environment)
((default-value 'exec-path) exec-path)
;; the first parameter is the file-name
(f-name (car args))
(result (apply func args)))
;; `gud-display-line' create a buffer for the file, but doesn't seem to return the buffer instance
;; Also when the function finishes, the `(current-buffer)' is not the buffer newly created.
;; Thus I choose to use `get-file-buffer' to get access to the buffer.
(with-current-buffer (get-file-buffer f-name)
(setq-local process-environment (default-value 'process-environment))
(setq-local exec-path (default-value 'exec-path)))
result))
(advice-add #'xref-location-marker :around #'akira/xref-inherit-envrc)
(advice-add #'lsp--document-link-handle-target :around #'akira/lsp-document-link-inherit-envrc)
(advice-add #'gud-display-line :around #'akira/gud-display-line-inherit-envrc)
I'm using Emacs 29.
I have the following situation
I would like the behavior to be something similar to how envrc handles buffers like
*Help*
, i.e. I would like envrc to hook into jump-to-definition with something that says "if the place I jump to has no .envrc file, keep using the one that I was just in"