summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Porter <jporterbugs@gmail.com>2022-02-26 20:55:22 -0800
committerLars Ingebrigtsen <larsi@gnus.org>2022-03-03 14:59:33 +0100
commitae1acb601764009fc2551819f9193aa6e9441be4 (patch)
tree568f5226afb3d3d42822c0996b8b196be2f04fd4
parent7c7a4c26cbabe2d84d008e193b7db8ae106e9e47 (diff)
downloademacs-ae1acb601764009fc2551819f9193aa6e9441be4.tar.gz
emacs-ae1acb601764009fc2551819f9193aa6e9441be4.tar.bz2
emacs-ae1acb601764009fc2551819f9193aa6e9441be4.zip
Add a new macro to simplify parsing temporary Eshell command strings
This abstracts out the somewhat-unusual "insert&delete" logic in 'eshell-parse-command' so that it can be used elsewhere, and also ensures that the deletion occurs even if an an error occurs. * lisp/eshell/esh-cmd.el (eshell-with-temp-command): New macro. (eshell-parse-command): Use it.
-rw-r--r--lisp/eshell/esh-cmd.el42
1 files changed, 33 insertions, 9 deletions
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el
index dceb061c8f4..04b54d9d791 100644
--- a/lisp/eshell/esh-cmd.el
+++ b/lisp/eshell/esh-cmd.el
@@ -350,6 +350,36 @@ This only returns external (non-Lisp) processes."
(defvar eshell--sep-terms)
+(defmacro eshell-with-temp-command (command &rest body)
+ "Narrow the buffer to COMMAND and execute the forms in BODY.
+COMMAND can either be a string, or a cons cell demarcating a
+buffer region. If COMMAND is a string, temporarily insert it
+into the buffer before narrowing. Point will be set to the
+beginning of the narrowed region.
+
+The value returned is the last form in BODY."
+ (declare (indent 1))
+ `(let ((cmd ,command))
+ (if (stringp cmd)
+ ;; Since parsing relies partly on buffer-local state
+ ;; (e.g. that of `eshell-parse-argument-hook'), we need to
+ ;; perform the parsing in the Eshell buffer.
+ (let ((begin (point)) end
+ (inhibit-point-motion-hooks t))
+ (with-silent-modifications
+ (insert cmd)
+ (setq end (point))
+ (unwind-protect
+ (save-restriction
+ (narrow-to-region begin end)
+ (goto-char begin)
+ ,@body)
+ (delete-region begin end))))
+ (save-restriction
+ (narrow-to-region (car cmd) (cdr cmd))
+ (goto-char (car cmd))
+ ,@body))))
+
(defun eshell-parse-command (command &optional args toplevel)
"Parse the COMMAND, adding ARGS if given.
COMMAND can either be a string, or a cons cell demarcating a buffer
@@ -361,15 +391,9 @@ hooks should be run before and after the command."
(append
(if (consp command)
(eshell-parse-arguments (car command) (cdr command))
- (let ((here (point))
- (inhibit-point-motion-hooks t))
- (with-silent-modifications
- ;; FIXME: Why not use a temporary buffer and avoid this
- ;; "insert&delete" business? --Stef
- (insert command)
- (prog1
- (eshell-parse-arguments here (point))
- (delete-region here (point))))))
+ (eshell-with-temp-command command
+ (goto-char (point-max))
+ (eshell-parse-arguments (point-min) (point-max))))
args))
(commands
(mapcar