]> git.eshelyaron.com Git - emacs.git/commitdiff
Rework how 'eshell-ensure-newline-p' adds newlines
authorJim Porter <jporterbugs@gmail.com>
Thu, 23 May 2024 21:55:59 +0000 (14:55 -0700)
committerEshel Yaron <me@eshelyaron.com>
Thu, 30 May 2024 14:27:12 +0000 (16:27 +0200)
This allows for other output targets (see the following commit) to be
"line-oriented".

* lisp/eshell/esh-io.el (eshell-ensure-newline-p): Move from esh-cmd.el.
(eshell-target-line-oriented-p, eshell--output-maybe-n)
(eshell-print-maybe-n, eshell-error-maybe-n)
(eshell-maybe-output-newline): New functions.

* lisp/eshell/esh-cmd.el (eshell-lisp-command): Don't print a newline
in this function directly; instead, use 'eshell-print-maybe-n' and
'eshell-error-maybe-n'.
(eshell-ensure-newline-p): Move to esh-io.el.

* lisp/eshell/em-unix.el (eshell/cat): Remove now-unnecessary override
of 'eshell-ensure-newline-p'.

(cherry picked from commit eac608cb8041222ba3b2eac48ac6f76ac36bab16)

lisp/eshell/em-unix.el
lisp/eshell/esh-cmd.el
lisp/eshell/esh-io.el

index 7f976d226811e32b59e47e1942ebe1ab147eedad..4137c05fa413b3cd11716c84d8d77a8c47a06e96 100644 (file)
@@ -683,9 +683,7 @@ Concatenate FILE(s), or standard input, to standard output.")
               (with-current-buffer curbuf
                 (eshell-buffered-print str)))
             (forward-line)))))
-     (eshell-flush)
-     ;; if the file does not end in a newline, do not emit one
-     (setq eshell-ensure-newline-p nil))))
+     (eshell-flush))))
 
 (put 'eshell/cat 'eshell-no-numeric-conversions t)
 (put 'eshell/cat 'eshell-filename-arguments t)
index 57aeff592660080d6a313a6a326148fb2f51a39d..1072646ec15fad81b28c940671589f30a0092276 100644 (file)
@@ -254,11 +254,6 @@ the command."
   :type 'sexp
   :risky t)
 
-(defvar eshell-ensure-newline-p nil
-  "If non-nil, ensure that a newline is emitted after a Lisp form.
-This can be changed by Lisp forms that are evaluated from the Eshell
-command line.")
-
 ;;; Internal Variables:
 
 ;; These variables have been merged into `eshell-foreground-command'.
@@ -1499,7 +1494,7 @@ a string naming a Lisp function."
   (catch 'eshell-external               ; deferred to an external command
     (setq eshell-last-command-status 0
           eshell-last-arguments args)
-    (let* ((eshell-ensure-newline-p (eshell-interactive-output-p))
+    (let* ((eshell-ensure-newline-p t)
            (command-form-p (functionp object))
            (result
             (if command-form-p
@@ -1526,14 +1521,13 @@ a string naming a Lisp function."
                       (setq args (cdr args))))
                   (setq eshell-last-command-name
                         (concat "#<function " (symbol-name object) ">"))
-                  (eshell-apply object eshell-last-arguments))
+                  (eshell-apply* #'eshell-print-maybe-n
+                                 #'eshell-error-maybe-n
+                                 object eshell-last-arguments))
               (setq eshell-last-command-name "#<Lisp object>")
-              (eshell-eval object))))
-      (if (and eshell-ensure-newline-p
-              (save-excursion
-                (goto-char eshell-last-output-end)
-                (not (bolp))))
-         (eshell-print "\n"))
+              (eshell-eval* #'eshell-print-maybe-n
+                            #'eshell-error-maybe-n
+                            object))))
       (eshell-close-handles
        ;; If `eshell-lisp-form-nil-is-failure' is non-nil, Lisp forms
        ;; that succeeded but have a nil result should have an exit
index 9b35125cd28e6e99f139d0a86a401e2af5c5b06b..c7017ee1d7049034b139d7fc42b14a5f615f3736 100644 (file)
@@ -162,6 +162,12 @@ ordinary function or `eshell-generic-target' as desribed above)."
 
 (define-error 'eshell-pipe-broken "Pipe broken")
 
+(defvar eshell-ensure-newline-p nil
+  "If non-nil, ensure that a newline is emitted after a Lisp form.
+This can be changed by Lisp forms that are evaluated from the
+Eshell command line.  This behavior only applies to line-oriented
+output targets (see `eshell-target-line-oriented-p'.")
+
 ;;; Internal Variables:
 
 (defconst eshell-redirection-operators-alist
@@ -493,15 +499,37 @@ after all printing is over with no argument."
   "Output OBJECT to the standard error handle."
   (eshell-output-object object eshell-error-handle))
 
+(defsubst eshell-printn (object)
+  "Output OBJECT followed by a newline to the standard output handle."
+  (eshell-print object)
+  (eshell-print "\n"))
+
 (defsubst eshell-errorn (object)
   "Output OBJECT followed by a newline to the standard error handle."
   (eshell-error object)
   (eshell-error "\n"))
 
-(defsubst eshell-printn (object)
-  "Output OBJECT followed by a newline to the standard output handle."
-  (eshell-print object)
-  (eshell-print "\n"))
+(defun eshell--output-maybe-n (object handle)
+  "Output OBJECT to HANDLE.
+For any line-oriented output targets on HANDLE, ensure the output
+ends in a newline."
+  (eshell-output-object object handle)
+  (when (and eshell-ensure-newline-p
+             (not (and (stringp object)
+                       (string-suffix-p object "\n"))))
+    (eshell-maybe-output-newline handle)))
+
+(defsubst eshell-print-maybe-n (object)
+  "Output OBJECT to the standard output handle.
+For any line-oriented output targets, ensure the output ends in a
+newline."
+  (eshell--output-maybe-n object eshell-output-handle))
+
+(defsubst eshell-error-maybe-n (object)
+  "Output OBJECT to the standard error handle.
+For any line-oriented output targets, ensure the output ends in a
+newline."
+  (eshell--output-maybe-n object eshell-error-handle))
 
 (cl-defstruct (eshell-generic-target (:constructor nil))
   "An Eshell target.
@@ -678,6 +706,16 @@ Returns what was actually sent, or nil if nothing was sent.")
   "Output OBJECT to the Eshell function TARGET."
   (funcall (eshell-function-target-output-function target) object))
 
+(cl-defgeneric eshell-target-line-oriented-p (_target)
+  "Return non-nil if the specified TARGET is line-oriented.
+Line-oriented targets are those that expect a newline after
+command output when `eshell-ensure-newline-p' is non-nil."
+  nil)
+
+(cl-defmethod eshell-target-line-oriented-p ((_target (eql t)))
+  "Return non-nil to indicate that the display is line-oriented."
+  t)
+
 (defun eshell-output-object (object &optional handle-index handles)
   "Insert OBJECT, using HANDLE-INDEX specifically.
 If HANDLE-INDEX is nil, output to `eshell-output-handle'.
@@ -688,5 +726,18 @@ HANDLES is the set of file handles to use; if nil, use
     (dolist (target targets)
       (eshell-output-object-to-target object target))))
 
+(defun eshell-maybe-output-newline (&optional handle-index handles)
+  "Maybe insert a newline, using HANDLE-INDEX specifically.
+This inserts a newline for all line-oriented output targets.
+
+If HANDLE-INDEX is nil, output to `eshell-output-handle'.
+HANDLES is the set of file handles to use; if nil, use
+`eshell-current-handles'."
+  (let ((targets (caar (aref (or handles eshell-current-handles)
+                             (or handle-index eshell-output-handle)))))
+    (dolist (target targets)
+      (when (eshell-target-line-oriented-p target)
+        (eshell-output-object-to-target "\n" target)))))
+
 (provide 'esh-io)
 ;;; esh-io.el ends here