astoff / buffer-env Goto Github PK
View Code? Open in Web Editor NEWBuffer-local process environments for Emacs
Buffer-local process environments for Emacs
You can also call buffer-env-activate interactively and select the activate script directly.
Hi,
buffer-env-update
fails to set up .venv/vin/activate
at all.
I am using the version of buffer-env currently in elpa.
What should I try to debug this further?
GNU Emacs 28.2 (build 1, x86_64-redhat-linux-gnu, GTK+ Version 3.24.38, cairo version 1.17.8) of 2023-06-05
Here is the relevant config for buffer-env in my init.el
:
;;; Handle Python virtualenvs and Guix manifests.
(unless (package-installed-p 'buffer-env)
(package-install 'buffer-env))
I then attempt to run buffer-env-update
on .venv/bin/activate
interactively in my project directory where I created the virtualenv but that fails.
I use virtualenvs successfully on a daily basis with pyvenv but would like to use buffer-env
instead.
Hi,
you use the function format-prompt
, even though "Package-Requires" indicates that Emacs 27.1 is the minimal version. It seems nonsensical to me to raise the version just because of one function (27.1 is probably still the most widely used version). The simplest solution in this case would be to replace it with equivalent, backwards compatible code. An alternative would be to use the compat library, if you intend to make use of other functionality that is defined in Emacs 28.1+ in the future.
Here's my config:
(setup (:pkg buffer-env)
(:option buffer-env-script-name "manifest.scm")
(add-hook 'comint-mode-hook #'hack-dir-local-variables-non-file-buffer)
(add-hook 'hack-local-variables-hook #'buffer-env-update))
However, inside the file I'm editing, hack-local-variables-hook
is set to (outline-apply-default-state t)
.
I'm editing an org-file that tangles the manifest.scm
, but even as I'm editing the babel block that produces the file, it is attempting to run a bad manifest. For now, I'm just going to output to manifest2.scm and delete the manifest.
I've tried the following from within the org bufffer.
(setq hack-locals-old hack-local-variables-hook)
(setq hack-local-variables-hook nil)
Is there any way to temporarily disable this within a buffer/project?
When editing org documents I sometimes run python code in a python interpreter:
C-c '
C-c C-p
C-c C-C
contrary to only running C-c C-c
inside the source block this does not inherit the buffer environment. Is there a way to achieve this (easily)?
Another issue I stumbled onto was running the export command asynchronously
C-c C-e
C-a
l o
this fails due to missing dependencies. Is there a possible workaround using buffer-env?
The recommended configuration says to add buffer-env-update
to hack-local-variables-hook
, but this only works for buffers with an associated file. In all other cases nothing happens, which is confusing and breaks the transparency that I think would be desirable.
This can be remedied by ensuring that hack-dir-local-variables-non-file-buffer
is called, e.g. by adding
(add-hook 'comint-mode-hook #'hack-dir-local-variables-non-file-buffer)
or
(add-hook 'comint-mode-hook #'buffer-env-update)
to the user configuration, e.g. if you want buffer-env to work in a shell or REPL. But this approach requires manually supporting every non-file major-mode.
Assuming I didn't make some mistake here, do you see any good way around this. If not, I think adding a minor mode that initializes buffer-env would be useful?
Hi Augusto,
this is just a minor thing, maybe something you are already aware of, but if I use the snippet in the README to set up the buffer-local process environment, I get a warning. Namely, this:
(defun buffer-env-inherit (fn &rest args)
"Call FN with ARGS using the buffer-local process environment.
Intended as an advice around commands that start a process after
switching buffers."
(cl-letf (((default-value 'process-environment) process-environment)
((default-value 'exec-path) exec-path))
(apply fn args)))
Results in the following message when Flymake is active:
‘((default-value 'process-environment) process-environment)’ is a malformed function
The message disappears if I place this at the beginning of my init.el
:
(eval-when-compile
(require 'cl-lib))
Also, I've started to notice this message recently, but I wasn't able to pin down the exact Emacs master commit that triggers it. As of now, I am using Emacs built on 3425690
commit if it helps.
First, thank you for this package. It's almost exactly what I was need, and I was about to resign myself to writing something crappier by hand. 😄
I would like to suggest an option to override the “search upward for a file with a known name” feature, and to specify a command directly. My use-case is that I use rtx, a clone of asdf, which would have the same concerns. I think it would also apply to direnv users.
rtx already knows how to search for configuration files, and it recognizes a variety of different file names—actually an unbounded list of file names, because plugins can add their own. I'd rather not try to replicate all the different file names possible, and it's not uncommon for multiple config files could occur in the same directory. I would always want to run one command, rtx exec -- env -0
, regardless what directory the buffer is in or what other files exist.
I realize I could create a .envrc
file in my home directory that uses source $(rtx env)
to set the environment, and let buffer-env-update
find it—and I think that will be my work-around for now (Edit: I don't think this would actually work. See the comment below.)—but it seems wasteful to search all the way up to my home directory, just to do it again inside rtx. Also, when editing files outside my home directory, I would still want to use the environment from rtx
. (It has global configuration.) It also feels a little silly to set the environment via bash
when rtx already provides it via rtx exec
—and probably more efficiently, since it's a compiled program.
I don't know what the best interface would be to support this option. I can think of a few alternatives:
Allow buffer-env-script-name
and the file argument to buffer-env-update
to be nil
, and allow nil
as a key in buffer-env-commands
.
nil
indicates. Only allows one command to be defined.Add a buffer-env-treat-as-command
flag, which would cause buffer-env-script-name
and the file argument to buffer-env-update
to be interpreted instead as literal commands.
buffer-env-script-name
might be a script. No way to interactively source files if flag is set.Deprecate buffer-env-script-name
in favor of a new buffer-env-sources
list accepting a mix of strings and type-string pairs, where type is one of file
or command
, and bare strings are treated as files. Commands would be run unconditionally; files would be searched and evaluated as normal. The file argument to buffer-env-update
would accept a string or type-string pair, or else might learn an optional :type
keyword argument, or both.
You can also call buffer-env-activate interactively and select the activate script directly.
I think this might be a typo. I don't see any function called buffer-env-activate
.
Hi,
first of all thanks for this package and for making it available on GNU ELPA. It works as expected with direnv
.
However, why did you choose to go the Customize way with buffer-env-safe-files
? I usually do not use Customize, so I specifically don't put any settings related to it neither in my init.el
nor in a different custom file.
Shouldn't something like this be enough for the purpose buffer-env-safe-files
covers?
(setq-default buffer-env-safe-files '("/path-to/your/.envrc"))
Of course I may be missing something or not getting it entirely. Note that I am also fine with loading a custom.el
file with buffer-env-safe-files
in it, so this is not a bug report. Just plain curiosity.
Hi,
in a little Java project of mine I want to override the value of buffer-env-command
I have globally set to direnv exec . env -0
(the .envrc
files I work with are full of crazy things):
(setq-default buffer-env-command "direnv exec . env -0")
(add-hook 'hack-local-variables-hook #'buffer-env-update)
What I am doing in my Java project is the following in .dir-locals.el
:
((nil . ((buffer-env-command . ">&2 . \"$0\" && env -0")
(buffer-env-script-name . "env/bin/activate")
(python-shell-virtualenv-root . "./env"))))
However, the activate
script is not run. It is run if I do the following, though:
((nil . ((eval (setq buffer-env-command ">&2 . \"$0\" && env -0"))
(buffer-env-script-name . "env/bin/activate")
(python-shell-virtualenv-root . "./env"))))
Which is not what I want because in this way I am losing the global setting for direnv
. What can I do?
For Python projects using a a fully featured project manager like Poetry, Hatch or PDM, it would be nice to extract the project environment directly from the corresponding pyproject.toml
file.
The following code, which can be pasted in the user configuration, seems to work but need more testing. Feedback is welcome!
(setq buffer-env-script-name '(".envrc" "pyproject.toml"))
(with-eval-after-load 'buffer-env
(add-to-list 'buffer-env-commands
'("pyproject.toml" . "\
BACKEND=$(sed -nr 's/^build-backend\s*=\s*\"([a-z]+).*/\\1/p' \"$0\")
case $BACKEND in
poetry|pdm) $BACKEND run env -0;;
hatchling) hatch run env -0;;
*) echo >&2 \"Unsupported build backend '$BACKEND'.\" && exit 1;;
esac")))
Hi,
I edited the .envrc
of one of my projects today and run direnv allow
to make sure the changes are loaded.
However, the first time I act on this project (e.g., C-x p p
-> Select project -> RET
-> v
(for VC-Dir)), I get the following prompt:
Mark current version of ‘/home/manuel/code/eerlijewoz/cockpit/.envrc’ as safe to execute? (y or n)
And when I hit y
I get:
Debugger entered--Lisp error: (wrong-type-argument listp t)
custom-save-variables()
custom-save-all()
customize-save-variable(buffer-env-safe-files (("/home/manuel/code/eerlijewoz/cockpit/.envrc" . "ffe8ad77e9d2affb4445c4a83d830d4606860e1d5ba86aab99...")))
buffer-env--authorize("/home/manuel/code/eerlijewoz/cockpit/.envrc")
buffer-env-update()
hack-local-variables-apply()
hack-dir-local-variables-non-file-buffer()
project--value-in-dir(project-vc-merge-submodules "~/code/eerlijewoz/cockpit/")
project--vc-merge-submodules-p("~/code/eerlijewoz/cockpit/")
project-try-vc("~/code/eerlijewoz/cockpit/")
project--find-in-directory("~/code/eerlijewoz/cockpit/")
project-current(t)
project-find-file(nil)
funcall-interactively(project-find-file nil)
project-switch-project("~/code/eerlijewoz/cockpit/")
funcall-interactively(project-switch-project "~/code/eerlijewoz/cockpit/")
command-execute(project-switch-project)
This is how I set up buffer-env
in my init.el
:
(add-hook 'hack-local-variables-hook #'buffer-env-update)
(with-eval-after-load 'buffer-env
(push '(".envrc" . "direnv exec . env -0") buffer-env-commands))
(defun mu-buffer-env-inherit (fn &rest args)
"Call FN with ARGS using the buffer-local process environment."
(cl-letf (((default-value 'process-environment) process-environment)
((default-value 'exec-path) exec-path))
(apply fn args)))
(advice-add #'mu-buffer-env-inherit :around #'project-shell)
(advice-add #'mu-buffer-env-inherit :around #'shell)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.