From be067246af0d5a7541219e438dcf477b1af79f6c Mon Sep 17 00:00:00 2001 From: Jim Porter Date: Mon, 26 May 2025 20:07:36 -0700 Subject: [PATCH] Add some initial generic functions to support Eshell tasks * lisp/eshell/esh-util.el (eshell-task-p, eshell-task-status) (eshell-task-active-p): New generic functions. (eshell-process-list-p): Obsolete in favor of... (eshell-task-list-p): ... this. Update callers. (eshell-make-process-list): Obsolete in favor of... (eshell-make-task-list): ... this. Update callers. * lisp/eshell/esh-proc.el (eshell-task-p, eshell-task-status) (eshell-task-active-p): New functions. --- lisp/eshell/esh-cmd.el | 6 +++--- lisp/eshell/esh-mode.el | 2 +- lisp/eshell/esh-proc.el | 19 ++++++++++++------- lisp/eshell/esh-util.el | 29 ++++++++++++++++++++++++----- 4 files changed, 40 insertions(+), 16 deletions(-) diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el index f4f593fde90..0282c00ae63 100644 --- a/lisp/eshell/esh-cmd.el +++ b/lisp/eshell/esh-cmd.el @@ -1083,7 +1083,7 @@ STATUS is its status." ;; element is a list of the form (BACKGROUND FORM PROCESSES) (see ;; `eshell-add-command'). (dolist (command (eshell-commands-for-process proc)) - (unless (seq-some #'eshell-process-active-p (nth 2 command)) + (unless (seq-some #'eshell-task-active-p (nth 2 command)) (setf (nth 2 command) nil) ; Clear processes from command. (if (and ;; Check STATUS to determine whether we want to resume or ;; abort the command. @@ -1365,13 +1365,13 @@ have been replaced by constants." (setcdr form (cdr new-form))) (eshell-do-eval form synchronous-p)) (if-let* (((memq (car form) eshell-deferrable-commands)) - (procs (eshell-make-process-list result))) + (procs (eshell-make-task-list result))) (if synchronous-p (funcall #'eshell-wait-for-processes procs) (eshell-manipulate form "inserting ignore form" (setcar form 'ignore) (setcdr form nil)) - (when (seq-some #'eshell-process-active-p procs) + (when (seq-some #'eshell-task-active-p procs) (throw 'eshell-defer procs))) (list 'quote result)))))))))))) diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el index c1d29e948f4..3a6c9a2a7f4 100644 --- a/lisp/eshell/esh-mode.el +++ b/lisp/eshell/esh-mode.el @@ -618,7 +618,7 @@ newline." (let* ((proc-running-p (eshell-head-process)) (send-to-process-p (and proc-running-p (not queue-p)))) (unless (and send-to-process-p - (not (eq (process-status + (not (eq (eshell-task-status (eshell-head-process)) 'run))) (if (or send-to-process-p diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el index 02408cfc234..06dbb07952b 100644 --- a/lisp/eshell/esh-proc.el +++ b/lisp/eshell/esh-proc.el @@ -176,15 +176,20 @@ PROC and STATUS to functions on the latter." (define-obsolete-function-alias 'eshell-reset-after-proc 'eshell--reset-after-signal "30.1") -(defun eshell-process-active-p (process) - "Return non-nil if PROCESS is active. +(cl-defmethod eshell-task-p ((_proc process)) t) +(cl-defmethod eshell-task-status ((proc process)) + "Return the status of PROC, as with `process-status'." + (process-status proc)) + +(cl-defmethod eshell-task-active-p ((proc process)) + "Return non-nil if PROC is active. This is like `process-live-p', but additionally checks whether `eshell-sentinel' has finished all of its work yet." - (or (process-live-p process) + (or (process-live-p proc) ;; If we have handles, this is an Eshell-managed ;; process. Wait until we're 100% done and have ;; cleared out the handles (see `eshell-sentinel'). - (process-get process :eshell-handles))) + (process-get proc :eshell-handles))) (defun eshell-wait-for-processes (&optional procs timeout) "Wait until PROCS have completed execution. @@ -193,8 +198,8 @@ if all the processes finished executing before the timeout expired." (let ((expiration (when timeout (time-add (current-time) timeout)))) (catch 'timeout (dolist (proc procs) - (while (if (processp proc) - (eshell-process-active-p proc) + (while (if (eshell-task-p proc) + (eshell-task-active-p proc) (process-attributes proc)) (when (input-pending-p) (discard-input)) @@ -222,7 +227,7 @@ Wait until PROCESS(es) have completed execution.") (when (stringp timeout) (setq timeout (string-to-number timeout))) (dolist (arg args) - (unless (or (processp arg) (natnump arg)) + (unless (or (eshell-task-p arg) (natnump arg)) (error "wait: invalid argument type: %s" (type-of arg)))) (unless (eshell-wait-for-processes args timeout) (error "wait: timed out after %s seconds" timeout)))) diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el index 7fca9635c78..e8ddfcbec3f 100644 --- a/lisp/eshell/esh-util.el +++ b/lisp/eshell/esh-util.el @@ -869,18 +869,37 @@ gid format. Valid values are `string' and `integer', defaulting to "If the `processp' function does not exist, PROC is not a process." (and (fboundp 'processp) (processp proc))) -(defun eshell-process-list-p (procs) +(cl-defgeneric eshell-task-p (_object) + "Return non-nil if OBJECT is a task. +A \"task\" is a process or process-like object." + nil) + +(cl-defgeneric eshell-task-status (task) + "Return the status for TASK, similar to `process-status' (which see).") + +(cl-defgeneric eshell-task-active-p (task) + "Return non-nil if TASK is still active in Eshell. +An active task is any task that still has work left to do before being +cleaned up.") + +(defun eshell-task-list-p (procs) "Return non-nil if PROCS is a list of process objects." (and (listp procs) - (seq-every-p #'eshell-processp procs))) + (seq-every-p #'eshell-task-p procs))) -(defun eshell-make-process-list (procs) +(define-obsolete-function-alias 'eshell-process-list-p + 'eshell-task-list-p "31.1") + +(defun eshell-make-task-list (procs) "Make a list of process objects from PROCS if possible. PROCS can be a single process or a list thereof. If PROCS is anything else, return nil instead." (pcase procs - ((pred eshell-processp) (list procs)) - ((pred eshell-process-list-p) procs))) + ((pred eshell-task-p) (list procs)) + ((pred eshell-task-list-p) procs))) + +(define-obsolete-function-alias 'eshell-make-process-list + 'eshell-make-task-list "31.1") ;; (defun eshell-copy-file ;; (file newname &optional ok-if-already-exists keep-date)