branch: externals/buffer-env commit cd91b62838ab7d5ab73b32eea4ec8471c535f152 Author: Augusto Stoffel <arstof...@gmail.com> Commit: Augusto Stoffel <arstof...@gmail.com>
Obsolete buffer-env-commands in favor of buffer-env-command-alist --- README.org | 18 +++++---------- buffer-env.el | 70 +++++++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 57 insertions(+), 31 deletions(-) diff --git a/README.org b/README.org index 53827cea78..dca6b9e236 100644 --- a/README.org +++ b/README.org @@ -12,7 +12,6 @@ parallel with no undue interference and switch seamlessly between them. ** Basic setup - *** On the project side Your project settings should go into a shell script named =.envrc= which exports a suitable =PATH=, as well as any other desired @@ -25,8 +24,8 @@ direnv so it is not possible to use direnv-specific features in the =.envrc= scripts --- at least not directly. Alternatively, it is possible to configure buffer-env to directly -support other environment setup methods, such as Python virtualenvs or -=.env= files. See below for details. +support other environment setup methods, such as Python virtualenvs, +=.env= files or certain build tools. See below for details. *** On the Emacs side The usual way to activate this package in Emacs is by including the @@ -69,14 +68,14 @@ certain script names are treated specially. These are: dependencies, otherwise you may block Emacs for a long time. - =flake.nix= and =shell.nix=: These files are used by the Nix package manager and are handled similarly to Guix. +- =*.ps1=: Similar to a regular shell script, but interpreted by + PowerShell. For instructions on how to extend this list, see the documentation of -the variable =buffer-env-commands=. +the variable =buffer-env-command-alist=. ** Integration with other environment management mechanisms - *** pyproject.toml - If you are using a fully featured Python project manager such as [[https://python-poetry.org/][Poetry]], [[https://hatch.pypa.io/][Hatch]] or [[https://pdm.fming.dev][PDM]], buffer-env can be configured to infer the project environment directly from the =pyproject.toml= file. See [[https://github.com/astoff/buffer-env/issues/13][this @@ -121,7 +120,7 @@ following configuration: #+begin_src emacs-lisp (with-eval-after-load 'buffer-env - (add-to-list 'buffer-env-commands '(".envrc" . "direnv exec . env -0"))) + (add-to-list 'buffer-env-command-alist '("/\\.envrc\\'" . "direnv exec . env -0"))) #+end_src If you need tighter integration with direnv, you may want to check out @@ -156,11 +155,6 @@ lean, you can just copy the function below and apply it as an (apply fn args))) #+end_src -*** Non-Unix-like systems -Currently, this package assumes your system shell is POSIX. For other -types of operating system, I would need to know what the appropriate -value of =buffer-env-commands= is. Drop me a line if you can help. - ** Related packages This package is essentially a knockoff of the [[https://github.com/purcell/envrc][envrc]] package by Steve Purcell. The main difference is that envrc depends on and tightly diff --git a/buffer-env.el b/buffer-env.el index b3ab2d6d46..7ca1301129 100644 --- a/buffer-env.el +++ b/buffer-env.el @@ -52,25 +52,48 @@ (require 'compat) (require 'seq) -(eval-when-compile (require 'subr-x)) +(eval-when-compile + (require 'rx) + (require 'subr-x)) (defgroup buffer-env nil "Buffer-local process environments." :group 'processes) (defcustom buffer-env-script-name ".envrc" - "File name of the scripts to produce environment variables, or a list of such." + "File name of the script producing environment variables, or a list of such." :type '(choice (repeat string) string)) -(defcustom buffer-env-commands - '((".env" . "set -a && >&2 . \"$0\" && env -0") - ("manifest.scm" . "guix shell -m \"$0\" -- env -0") - ("guix.scm" . "guix shell -D -f \"$0\" -- env -0") - ("flake.nix" . "nix develop -c env -0") - ("shell.nix" . "nix-shell \"$0\" --run \"env -0\"") - ("*.ps1" . "powershell -c '& { param($script) . $script > $null; Get-ChildItem env: |\ - % {\"$($_.Name)=$($_.Value)`0\"} | Write-Host -NoNewLine } '") - ("*" . ">&2 . \"$0\" && env -0")) +(defcustom buffer-env-command-alist + `((,(rx "/.env" eos) + . "set -a && >&2 . \"$0\" && env -0") + (,(rx "/manifest.scm" eos) + . "guix shell -m \"$0\" -- env -0") + (,(rx "/guix.scm" eos) + . "guix shell -D -f \"$0\" -- env -0") + (,(rx "/flake.nix" eos) + . "nix develop -c env -0") + (,(rx "/shell.nix" eos) + . "nix-shell \"$0\" --run \"env -0\"") + (,(rx ".ps1" eos) + . "powershell -c '& { param($script) . $script > $null; Get-ChildItem env: |\ + % {\"$($_.Name)=$($_.Value)`0\"} | Write-Host -NoNewLine } '") + (,(rx any) + . ">&2 . \"$0\" && env -0")) + "Alist of commands used to produce environment variables. +For each entry, the car is a regular expression and the cdr is a +shell command. The command specifies how to execute a script and +collect the environment variables it defines. + +More specifically, the command corresponding to the script file +name is executed in a shell, in the directory of the script, with +its absolute file name as argument. The command should print a +null-separated list of environment variables, and nothing else, +to standard output." + :type '(alist :key-type (regexp :tag "File name pattern") + :value-type (string :tag "Shell command"))) + +(defcustom buffer-env-commands nil "Alist of commands used to produce environment variables. For each entry, the car is a glob pattern and the cdr is a shell command. The command specifies how to execute a script and @@ -83,6 +106,7 @@ null-separated list of environment variables, and nothing else, to standard output." :type '(alist :key-type (string :tag "Glob pattern") :value-type (string :tag "Shell command"))) +(make-obsolete-variable 'buffer-env-commands 'buffer-env-command-alist "0.5") (defcustom buffer-env-safe-files nil "List of scripts marked as safe to execute. @@ -176,12 +200,20 @@ for more details.")) (defun buffer-env--get-command (file) "Return the appropriate shell command to interpret script FILE." - (or (seq-some (pcase-lambda (`(,patt . ,command)) - (when (string-match-p (wildcard-to-regexp patt) - (file-name-nondirectory file)) + (or (when-let + ((c (seq-some (pcase-lambda (`(,patt . ,command)) + (when (string-match-p (wildcard-to-regexp patt) + (file-name-nondirectory file)) + command)) + buffer-env-commands))) + (prog1 c + (lwarn 'buffer-env :warning "\ +`buffer-env-commands' is obsolete, use 'buffer-env-command-alist' instead."))) + (seq-some (pcase-lambda (`(,patt . ,command)) + (when (string-match-p patt file) command)) - buffer-env-commands) - (user-error "[buffer-env] No entry of `buffer-env-commands' matches %s" + buffer-env-command-alist) + (user-error "[buffer-env] No entry of `buffer-env-command-alist' matches %s" file))) (defun buffer-env--filter-vars (vars) @@ -195,9 +227,9 @@ for more details.")) ;;;###autoload (defun buffer-env-update (&optional file) "Update the process environment buffer locally. -FILE is executed in the way prescribed by `buffer-env-commands' -and the buffer-local values of `process-environment' and -`exec-path' are set accordingly. +FILE is executed in the way prescribed by +`buffer-env-command-alist' and the buffer-local values of +`process-environment' and `exec-path' are set accordingly. If FILE omitted, a file with base name `buffer-env-script-name' is looked up in the current directory and its parents; nothing