|
6 | 6 | ;; Keywords: unix, environment
|
7 | 7 | ;; URL: https://github.com/purcell/exec-path-from-shell
|
8 | 8 | ;; Package-Version: 2.1
|
9 |
| -;; Package-Requires: ((emacs "24.1") (cl-lib "0.6")) |
| 9 | +;; Package-Requires: ((emacs "24.4")) |
10 | 10 |
|
11 | 11 | ;; This file is not part of GNU Emacs.
|
12 | 12 |
|
|
76 | 76 | ;; Satisfy the byte compiler
|
77 | 77 | (eval-when-compile (require 'eshell))
|
78 | 78 | (require 'cl-lib)
|
| 79 | +(require 'json) |
79 | 80 |
|
80 | 81 | (defgroup exec-path-from-shell nil
|
81 | 82 | "Make Emacs use shell-defined values for $PATH etc."
|
@@ -135,6 +136,10 @@ The default value denotes an interactive login shell."
|
135 | 136 | (when exec-path-from-shell-debug
|
136 | 137 | (apply 'message msg args)))
|
137 | 138 |
|
| 139 | +(defun exec-path-from-shell--nushell-p (shell) |
| 140 | + "Return non-nil if SHELL is nu." |
| 141 | + (string-match-p "nu$" shell)) |
| 142 | + |
138 | 143 | (defun exec-path-from-shell--standard-shell-p (shell)
|
139 | 144 | "Return non-nil iff SHELL supports the standard ${VAR-default} syntax."
|
140 | 145 | (not (string-match-p "\\(fish\\|nu\\|t?csh\\)$" shell)))
|
@@ -188,29 +193,69 @@ shell-escaped, so they may contain $ etc."
|
188 | 193 | (match-string 1)
|
189 | 194 | (error "Expected printf output from shell, but got: %S" (buffer-string))))))
|
190 | 195 |
|
| 196 | +(defun exec-path-from-shell-getenvs--nushell (names) |
| 197 | + "Use nushell to get the value of env vars with the given NAMES. |
| 198 | +
|
| 199 | +Execute the shell according to `exec-path-from-shell-arguments'. |
| 200 | +The result is a list of (NAME . VALUE) pairs." |
| 201 | + (let* ((shell (exec-path-from-shell--shell)) |
| 202 | + (expr (format "[ %s ] | to json" |
| 203 | + (string-join |
| 204 | + (mapcar (lambda (name) |
| 205 | + (format "$env.%s?" (exec-path-from-shell--double-quote name))) |
| 206 | + names) |
| 207 | + ", "))) |
| 208 | + (shell-args (append exec-path-from-shell-arguments (list "-c" expr)))) |
| 209 | + (with-temp-buffer |
| 210 | + (exec-path-from-shell--debug "Invoking shell %s with args %S" shell shell-args) |
| 211 | + (let ((exit-code (exec-path-from-shell--warn-duration |
| 212 | + (apply #'call-process shell nil t nil shell-args)))) |
| 213 | + (exec-path-from-shell--debug "Shell printed: %S" (buffer-string)) |
| 214 | + (unless (zerop exit-code) |
| 215 | + (error "Non-zero exit code from shell %s invoked with args %S. Output was:\n%S" |
| 216 | + shell shell-args (buffer-string)))) |
| 217 | + (goto-char (point-min)) |
| 218 | + (let ((json-array-type 'list) |
| 219 | + (json-null :null)) |
| 220 | + (let ((values (json-read-array)) |
| 221 | + result) |
| 222 | + (while values |
| 223 | + (let ((value (car values))) |
| 224 | + (push (cons (car names) |
| 225 | + (unless (eq :null value) |
| 226 | + (if (listp value) |
| 227 | + (string-join value path-separator) |
| 228 | + value))) |
| 229 | + result)) |
| 230 | + (setq values (cdr values) |
| 231 | + names (cdr names))) |
| 232 | + result))))) |
| 233 | + |
191 | 234 | (defun exec-path-from-shell-getenvs (names)
|
192 | 235 | "Get the environment variables with NAMES from the user's shell.
|
193 | 236 |
|
194 | 237 | Execute the shell according to `exec-path-from-shell-arguments'.
|
195 | 238 | The result is a list of (NAME . VALUE) pairs."
|
196 | 239 | (when (file-remote-p default-directory)
|
197 | 240 | (error "You cannot run exec-path-from-shell from a remote buffer (Tramp, etc.)"))
|
198 |
| - (let* ((random-default (md5 (format "%s%s%s" (emacs-pid) (random) (current-time)))) |
199 |
| - (dollar-names (mapcar (lambda (n) (format "${%s-%s}" n random-default)) names)) |
200 |
| - (values (split-string (exec-path-from-shell-printf |
201 |
| - (mapconcat #'identity (make-list (length names) "%s") "\\000") |
202 |
| - dollar-names) "\0"))) |
203 |
| - (let (result) |
204 |
| - (while names |
205 |
| - (prog1 |
206 |
| - (let ((value (car values))) |
207 |
| - (push (cons (car names) |
208 |
| - (unless (string-equal random-default value) |
209 |
| - value)) |
210 |
| - result)) |
211 |
| - (setq values (cdr values) |
212 |
| - names (cdr names)))) |
213 |
| - result))) |
| 241 | + (if (exec-path-from-shell--nushell-p) |
| 242 | + (exec-path-from-shell-getenvs--nushell names) |
| 243 | + (let* ((random-default (md5 (format "%s%s%s" (emacs-pid) (random) (current-time)))) |
| 244 | + (dollar-names (mapcar (lambda (n) (format "${%s-%s}" n random-default)) names)) |
| 245 | + (values (split-string (exec-path-from-shell-printf |
| 246 | + (mapconcat #'identity (make-list (length names) "%s") "\\000") |
| 247 | + dollar-names) "\0"))) |
| 248 | + (let (result) |
| 249 | + (while names |
| 250 | + (prog1 |
| 251 | + (let ((value (car values))) |
| 252 | + (push (cons (car names) |
| 253 | + (unless (string-equal random-default value) |
| 254 | + value)) |
| 255 | + result)) |
| 256 | + (setq values (cdr values) |
| 257 | + names (cdr names)))) |
| 258 | + result)))) |
214 | 259 |
|
215 | 260 | (defun exec-path-from-shell-getenv (name)
|
216 | 261 | "Get the environment variable NAME from the user's shell.
|
|
0 commit comments