summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
authorJim Porter <jporterbugs@gmail.com>2022-07-09 10:34:31 -0700
committerJim Porter <jporterbugs@gmail.com>2022-09-04 15:15:01 -0700
commit1be925faa1065af5754fc11914b56ae98dfb2a83 (patch)
tree6003dde699588471a1a801705c3ea28bf272ac9f /lisp
parent5af5ed6c6271a452bf37afa0e7349838960d446a (diff)
downloademacs-1be925faa1065af5754fc11914b56ae98dfb2a83.tar.gz
Simplify Eshell handle functions and add tests/documentation
* lisp/eshell/esh-arg.el (eshell-parse-argument-hook): Explain how to use 'eshell-finish-arg'. * lisp/eshell/esh-io.el (eshell-create-handles): Only call 'eshell-get-target' for stderr if necessary. (eshell-protect-handles): Use 'dotimes'. (eshell-set-output-handle): Pass HANDLES and fix an edge case with setting a duplicate TARGET. * test/lisp/eshell/eshell-tests-helpers.el (eshell-with-temp-buffer): New macro. * test/lisp/eshell/esh-cmd-tests.el (esh-cmd-test/quoted-lisp-form) (esh-cmd-test/backquoted-lisp-form) (esh-cmd-test/backquoted-lisp-form/splice): New tests. * test/lisp/eshell/eshell-tests.el (eshell-test/redirect-buffer) (eshell-test/redirect-buffer-escaped): Move to... * test/lisp/eshell/esh-io-tests.el: ... here, and add other I/O tests. * doc/misc/eshell.texi (Arguments): Add documentation for special argument types. (Input/Output): Expand documentation for redirection and pipelines.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/eshell/esh-arg.el4
-rw-r--r--lisp/eshell/esh-io.el55
2 files changed, 32 insertions, 27 deletions
diff --git a/lisp/eshell/esh-arg.el b/lisp/eshell/esh-arg.el
index 8e44a88459f..50fb7f5fdc6 100644
--- a/lisp/eshell/esh-arg.el
+++ b/lisp/eshell/esh-arg.el
@@ -147,6 +147,10 @@ return the result of the parse as a sexp. It is also responsible for
moving the point forward to reflect the amount of input text that was
parsed.
+If the hook determines that it has reached the end of an argument, it
+should call `eshell-finish-arg' to complete processing of the current
+argument and proceed to the next.
+
If no function handles the current character at point, it will be
treated as a literal character."
:type 'hook
diff --git a/lisp/eshell/esh-io.el b/lisp/eshell/esh-io.el
index d54be55c130..f5dac2c81cd 100644
--- a/lisp/eshell/esh-io.el
+++ b/lisp/eshell/esh-io.el
@@ -236,22 +236,21 @@ The default location for standard output and standard error will go to
STDOUT and STDERR, respectively.
OUTPUT-MODE and ERROR-MODE are either `overwrite', `append' or `insert';
a nil value of mode defaults to `insert'."
- (let ((handles (make-vector eshell-number-of-handles nil))
- (output-target (eshell-get-target stdout output-mode))
- (error-target (eshell-get-target stderr error-mode)))
+ (let* ((handles (make-vector eshell-number-of-handles nil))
+ (output-target (eshell-get-target stdout output-mode))
+ (error-target (if stderr
+ (eshell-get-target stderr error-mode)
+ output-target)))
(aset handles eshell-output-handle (cons output-target 1))
- (aset handles eshell-error-handle
- (cons (if stderr error-target output-target) 1))
+ (aset handles eshell-error-handle (cons error-target 1))
handles))
(defun eshell-protect-handles (handles)
"Protect the handles in HANDLES from a being closed."
- (let ((idx 0))
- (while (< idx eshell-number-of-handles)
- (if (aref handles idx)
- (setcdr (aref handles idx)
- (1+ (cdr (aref handles idx)))))
- (setq idx (1+ idx))))
+ (dotimes (idx eshell-number-of-handles)
+ (when (aref handles idx)
+ (setcdr (aref handles idx)
+ (1+ (cdr (aref handles idx))))))
handles)
(defun eshell-close-handles (&optional exit-code result handles)
@@ -278,6 +277,24 @@ the value already set in `eshell-last-command-result'."
(eshell-close-target target (= eshell-last-command-status 0)))
(setcar handle nil))))))
+(defun eshell-set-output-handle (index mode &optional target handles)
+ "Set handle INDEX for the current HANDLES to point to TARGET using MODE.
+If HANDLES is nil, use `eshell-current-handles'."
+ (when target
+ (let ((handles (or handles eshell-current-handles)))
+ (if (and (stringp target)
+ (string= target (null-device)))
+ (aset handles index nil)
+ (let ((where (eshell-get-target target mode))
+ (current (car (aref handles index))))
+ (if (listp current)
+ (unless (member where current)
+ (setq current (append current (list where))))
+ (setq current (list where)))
+ (if (not (aref handles index))
+ (aset handles index (cons nil 1)))
+ (setcar (aref handles index) current))))))
+
(defun eshell-close-target (target status)
"Close an output TARGET, passing STATUS as the result.
STATUS should be non-nil on successful termination of the output."
@@ -390,22 +407,6 @@ it defaults to `insert'."
(error "Invalid redirection target: %s"
(eshell-stringify target)))))
-(defun eshell-set-output-handle (index mode &optional target)
- "Set handle INDEX, using MODE, to point to TARGET."
- (when target
- (if (and (stringp target)
- (string= target (null-device)))
- (aset eshell-current-handles index nil)
- (let ((where (eshell-get-target target mode))
- (current (car (aref eshell-current-handles index))))
- (if (and (listp current)
- (not (member where current)))
- (setq current (append current (list where)))
- (setq current (list where)))
- (if (not (aref eshell-current-handles index))
- (aset eshell-current-handles index (cons nil 1)))
- (setcar (aref eshell-current-handles index) current)))))
-
(defun eshell-interactive-output-p ()
"Return non-nil if current handles are bound for interactive display."
(and (eq (car (aref eshell-current-handles