[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/exec-path-from-shell b2e99326bf 2/4: Support nushell (fixe
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/exec-path-from-shell b2e99326bf 2/4: Support nushell (fixes #109) |
Date: |
Thu, 11 Apr 2024 06:59:35 -0400 (EDT) |
branch: elpa/exec-path-from-shell
commit b2e99326bf4cb3575cf282a1930b15156ad9c113
Author: Steve Purcell <steve@sanityinc.com>
Commit: Steve Purcell <steve@sanityinc.com>
Support nushell (fixes #109)
---
.github/workflows/test.yml | 4 +--
README.md | 23 +++++++-------
exec-path-from-shell.el | 79 ++++++++++++++++++++++++++++++++++++----------
3 files changed, 76 insertions(+), 30 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index dd3b91635f..ecaf3c66be 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -11,7 +11,7 @@ jobs:
steps:
- uses: purcell/setup-emacs@master
with:
- version: 29.1
+ version: 29.3
- uses: actions/checkout@v2
- name: Run tests
run: make package-lint
@@ -21,7 +21,7 @@ jobs:
strategy:
matrix:
emacs_version:
- - 24.1
+ - 24.4
- 24.5
- 25.1
- 25.3
diff --git a/README.md b/README.md
index 26adcaf673..7eaab5e6ac 100644
--- a/README.md
+++ b/README.md
@@ -25,21 +25,22 @@ variables of interest, then copying them into the Emacs
environment.
## Compatibility
-If the path printed by evaluating `(getenv "SHELL")` in Emacs points at `bash`
-or `zsh`, this should work fine.
+Supported shells:
-At a minimum, this package assumes that your shell is at least UNIX-y: if
-`(getenv "SHELL")` evaluates to something like `".../cmdproxy.exe"`, this
-package probably isn't for you.
-
-Further, if you use a non-POSIX-standard shell such as `tcsh` or `fish`, your
-shell will be asked to execute `sh` as a subshell in order to print
-out the variables in a format which can be reliably parsed. `sh` must
-be a POSIX-compliant shell in this case.
+* `zsh`
+* `bash`
+* `tcsh`
+* `fish`
+* `nu`
Note that shell variables which have not been exported as environment
variables (e.g. using the "export" keyword) may not be visible to
-`exec-path-from-shell'.
+`exec-path-from-shell`.
+
+If you experience issues, enable the variable
+`exec-path-from-shell-debug` before runnin functions from the package:
+this will produce detailed logging in `*Messages*` about the shell
+command line and output.
## Installation
diff --git a/exec-path-from-shell.el b/exec-path-from-shell.el
index 32488d9eb9..c231bfa374 100644
--- a/exec-path-from-shell.el
+++ b/exec-path-from-shell.el
@@ -6,7 +6,7 @@
;; Keywords: unix, environment
;; URL: https://github.com/purcell/exec-path-from-shell
;; Package-Version: 2.1
-;; Package-Requires: ((emacs "24.1") (cl-lib "0.6"))
+;; Package-Requires: ((emacs "24.4"))
;; This file is not part of GNU Emacs.
@@ -76,6 +76,7 @@
;; Satisfy the byte compiler
(eval-when-compile (require 'eshell))
(require 'cl-lib)
+(require 'json)
(defgroup exec-path-from-shell nil
"Make Emacs use shell-defined values for $PATH etc."
@@ -135,6 +136,10 @@ The default value denotes an interactive login shell."
(when exec-path-from-shell-debug
(apply 'message msg args)))
+(defun exec-path-from-shell--nushell-p (shell)
+ "Return non-nil if SHELL is nu."
+ (string-match-p "nu$" shell))
+
(defun exec-path-from-shell--standard-shell-p (shell)
"Return non-nil iff SHELL supports the standard ${VAR-default} syntax."
(not (string-match-p "\\(fish\\|nu\\|t?csh\\)$" shell)))
@@ -188,6 +193,44 @@ shell-escaped, so they may contain $ etc."
(match-string 1)
(error "Expected printf output from shell, but got: %S"
(buffer-string))))))
+(defun exec-path-from-shell-getenvs--nushell (names)
+ "Use nushell to get the value of env vars with the given NAMES.
+
+Execute the shell according to `exec-path-from-shell-arguments'.
+The result is a list of (NAME . VALUE) pairs."
+ (let* ((shell (exec-path-from-shell--shell))
+ (expr (format "[ %s ] | to json"
+ (string-join
+ (mapcar (lambda (name)
+ (format "$env.%s?"
(exec-path-from-shell--double-quote name)))
+ names)
+ ", ")))
+ (shell-args (append exec-path-from-shell-arguments (list "-c" expr))))
+ (with-temp-buffer
+ (exec-path-from-shell--debug "Invoking shell %s with args %S" shell
shell-args)
+ (let ((exit-code (exec-path-from-shell--warn-duration
+ (apply #'call-process shell nil t nil shell-args))))
+ (exec-path-from-shell--debug "Shell printed: %S" (buffer-string))
+ (unless (zerop exit-code)
+ (error "Non-zero exit code from shell %s invoked with args %S.
Output was:\n%S"
+ shell shell-args (buffer-string))))
+ (goto-char (point-min))
+ (let ((json-array-type 'list)
+ (json-null :null))
+ (let ((values (json-read-array))
+ result)
+ (while values
+ (let ((value (car values)))
+ (push (cons (car names)
+ (unless (eq :null value)
+ (if (listp value)
+ (string-join value path-separator)
+ value)))
+ result))
+ (setq values (cdr values)
+ names (cdr names)))
+ result)))))
+
(defun exec-path-from-shell-getenvs (names)
"Get the environment variables with NAMES from the user's shell.
@@ -195,22 +238,24 @@ Execute the shell according to
`exec-path-from-shell-arguments'.
The result is a list of (NAME . VALUE) pairs."
(when (file-remote-p default-directory)
(error "You cannot run exec-path-from-shell from a remote buffer (Tramp,
etc.)"))
- (let* ((random-default (md5 (format "%s%s%s" (emacs-pid) (random)
(current-time))))
- (dollar-names (mapcar (lambda (n) (format "${%s-%s}" n
random-default)) names))
- (values (split-string (exec-path-from-shell-printf
- (mapconcat #'identity (make-list (length
names) "%s") "\\000")
- dollar-names) "\0")))
- (let (result)
- (while names
- (prog1
- (let ((value (car values)))
- (push (cons (car names)
- (unless (string-equal random-default value)
- value))
- result))
- (setq values (cdr values)
- names (cdr names))))
- result)))
+ (if (exec-path-from-shell--nushell-p (exec-path-from-shell--shell))
+ (exec-path-from-shell-getenvs--nushell names)
+ (let* ((random-default (md5 (format "%s%s%s" (emacs-pid) (random)
(current-time))))
+ (dollar-names (mapcar (lambda (n) (format "${%s-%s}" n
random-default)) names))
+ (values (split-string (exec-path-from-shell-printf
+ (mapconcat #'identity (make-list (length
names) "%s") "\\000")
+ dollar-names) "\0")))
+ (let (result)
+ (while names
+ (prog1
+ (let ((value (car values)))
+ (push (cons (car names)
+ (unless (string-equal random-default value)
+ value))
+ result))
+ (setq values (cdr values)
+ names (cdr names))))
+ result))))
(defun exec-path-from-shell-getenv (name)
"Get the environment variable NAME from the user's shell.