branch: externals/buffer-env
commit 510a38223065ab326518450d2e90822c2e8071bd
Author: Augusto Stoffel <arstof...@gmail.com>
Commit: Augusto Stoffel <arstof...@gmail.com>

    Refactor buffer-env-update, improve error message
---
 buffer-env.el | 129 +++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 73 insertions(+), 56 deletions(-)

diff --git a/buffer-env.el b/buffer-env.el
index dcc0dcd711..56ab23442d 100644
--- a/buffer-env.el
+++ b/buffer-env.el
@@ -161,6 +161,24 @@ Files marked as safe to execute are permanently stored in
          (list buffer-env-script-name)
        buffer-env-script-name))))
 
+(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))
+                    command))
+                buffer-env-commands)
+      (user-error "[buffer-env] No entry of `buffer-env-commands' matches %s"
+                  file)))
+
+(defun buffer-env--filter-vars (vars)
+  "Filter out VARS listed in `buffer-env-ignored-variables'."
+  (seq-filter (lambda (var)
+                (not (seq-contains-p buffer-env-ignored-variables
+                                     var
+                                     'string-prefix-p)))
+              vars))
+
 ;;;###autoload
 (defun buffer-env-update (&optional file)
   "Update the process environment buffer locally.
@@ -184,67 +202,66 @@ When called interactively, ask for a FILE."
                      (buffer-env--locate-script)))
              ((buffer-env--authorize file))
              (modtime (file-attribute-modification-time (file-attributes 
file))))
-    (if-let ((cache (gethash file buffer-env--cache))
-            ((time-equal-p (nth 0 cache) modtime)))
+    (if-let ((cached (gethash file buffer-env--cache))
+            ((time-equal-p (nth 0 cached) modtime)))
         (progn
           (when buffer-env-verbose
             (message "[buffer-env] Environment of `%s' set from `%s' using 
cache"
                      (current-buffer) file))
-          (setq-local process-environment (nth 1 cache)
-                      exec-path (nth 2 cache)
+          (setq-local process-environment (nth 1 cached)
+                      exec-path (nth 2 cached)
                       buffer-env-active file))
-      (when-let ((command (seq-some (pcase-lambda (`(,patt . ,command))
-                                      (when (string-match-p 
(wildcard-to-regexp patt)
-                                                            
(file-name-nondirectory file))
-                                        command))
-                                    buffer-env-commands))
-                 (errbuf (with-current-buffer (get-buffer-create " 
*buffer-env*")
-                           (erase-buffer)
-                           (current-buffer)))
-                 (vars (with-temp-buffer
-                         (let* ((default-directory (file-name-directory file))
-                                (message-log-max nil)
-                                (proc (make-process
-                                       :name "buffer-env"
-                                       :command (list shell-file-name
-                                                      shell-command-switch
-                                                      command file)
-                                       :sentinel #'ignore
-                                       :buffer (current-buffer)
-                                       :stderr errbuf)))
-                           ;; Give subprocess a chance to finish
-                           ;; before setting up a progress reporter
-                           (sit-for 0)
-                           (if (not (process-live-p proc))
-                               (accept-process-output proc)
-                             (let* ((msg (format-message "[buffer-env] Running 
`%s'..." file))
-                                    (reporter (make-progress-reporter msg)))
-                               (while (or (accept-process-output proc 1)
-                                          (process-live-p proc))
-                                 (progress-reporter-update reporter))
-                               (progress-reporter-done reporter)))
-                           (if (= (process-exit-status proc) 0)
-                               (split-string (buffer-substring (point-min) 
(point-max)) "\0" t)
-                             (buffer-env-reset)
-                             (lwarn 'buffer-env :warning "\
-Error running script `%s'.
-Script finished with exit status %s.  See buffer `%s' for details."
-                                    file (process-exit-status proc) errbuf)
-                             nil)))))
-        (setq-local process-environment
-                    (nconc (seq-remove (lambda (var)
-                                         (seq-contains-p 
buffer-env-ignored-variables
-                                                         var 'string-prefix-p))
-                                       vars)
-                           buffer-env-extra-variables))
-        (when-let ((path (getenv "PATH")))
-          (setq-local exec-path (nconc (split-string path path-separator)
-                                       (list exec-directory))))
-        (puthash file (list modtime process-environment exec-path) 
buffer-env--cache)
-        (when buffer-env-verbose
-          (message "[buffer-env] Environment of `%s' set from `%s'"
-                   (current-buffer) file))
-        (setq buffer-env-active file)))))
+      (let* ((command (buffer-env--get-command file))
+             (errbuf (with-current-buffer (get-buffer-create " *buffer-env*")
+                       (erase-buffer)
+                       (current-buffer)))
+             (result (with-temp-buffer
+                       (let* ((default-directory (file-name-directory file))
+                              (message-log-max nil)
+                              (proc (make-process
+                                     :name "buffer-env"
+                                     :command (list shell-file-name
+                                                    shell-command-switch
+                                                    command file)
+                                     :sentinel #'ignore
+                                     :buffer (current-buffer)
+                                     :stderr errbuf)))
+                         ;; Give subprocess a chance to finish
+                         ;; before setting up a progress reporter
+                         (sit-for 0)
+                         (if (not (process-live-p proc))
+                             (accept-process-output proc)
+                           (let* ((msg (format-message "[buffer-env] Running 
`%s'..." file))
+                                  (reporter (make-progress-reporter msg)))
+                             (while (or (accept-process-output proc 1)
+                                        (process-live-p proc))
+                               (progress-reporter-update reporter))
+                             (progress-reporter-done reporter)))
+                         (cons (process-exit-status proc)
+                               (thread-first
+                                 (buffer-substring (point-min) (point-max))
+                                 (split-string "\0" t)
+                                 (buffer-env--filter-vars)
+                                 (nconc buffer-env-extra-variables)))))))
+        (pcase result
+          (`(0 . ,vars)
+           (setq-local process-environment vars)
+           (when-let ((path (getenv "PATH")))
+             (setq-local exec-path (nconc (split-string path path-separator)
+                                          (list exec-directory))))
+           (puthash file (list modtime process-environment exec-path) 
buffer-env--cache)
+           (when buffer-env-verbose
+             (message "[buffer-env] Environment of `%s' set from `%s'"
+                      (current-buffer) file))
+           (setq buffer-env-active file))
+          (`(,status . ,_)
+           (buffer-env-reset)
+           (lwarn 'buffer-env :warning "\
+Error running script %s (exit status %s).
+See script output in %s for more information."
+                  (buttonize file #'find-file file)
+                  status
+                  (buttonize (buffer-name errbuf) #'pop-to-buffer 
errbuf))))))))
 
 ;;;###autoload
 (defun buffer-env-reset ()

Reply via email to