emacs-elpa-diffs
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]