summaryrefslogtreecommitdiff
path: root/lisp/eshell
diff options
context:
space:
mode:
authorJim Porter <jporterbugs@gmail.com>2022-11-26 11:52:18 -0800
committerJim Porter <jporterbugs@gmail.com>2022-12-07 21:39:07 -0800
commita37df90276a1a8a5c185cf9e523a2cc1176b2fc4 (patch)
tree3d842c00b31559da64f9142f1a78f72f8244e6e3 /lisp/eshell
parentc774e83e36784ab96539c5c083b3bcb6d0158a8c (diff)
downloademacs-a37df90276a1a8a5c185cf9e523a2cc1176b2fc4.tar.gz
Treat escaped newlines in Eshell as the empty string
This fixes a regression introduced during Emacs 29's development. * lisp/eshell/esh-arg.el (eshell-parse-argument): Handle 'eshell-empty-token' as the result of an argument-parsing hook. (eshell-parse-argument-hook): Document 'eshell-empty-token'. (eshell-parse-backslash): Return 'eshell-empty-token' when encountering an escaped newline. * test/lisp/eshell/eshell-tests.el (eshell-test/escape-nonspecial) (eshell-test/escape-nonspecial-unicode) (eshell-test/escape-nonspecial-quoted) (eshell-test/escape-special-quoted): Move from here... * test/lisp/eshell/esh-arg-tests.el (esh-arg-test/escape/nonspecial) (esh-arg-test/escape/nonspecial-unicode) (esh-arg-test/escape-quoted/nonspecial) (esh-arg-test/escape-quoted/special): ... to here. (esh-arg-test/escape/special, esh-arg-test/escape/newline) (esh-arg-test/escape-quoted/newline): New tests. * doc/misc/eshell.texi (Arguments): Explain escaping logic in more detail (bug#59622).
Diffstat (limited to 'lisp/eshell')
-rw-r--r--lisp/eshell/esh-arg.el43
1 files changed, 25 insertions, 18 deletions
diff --git a/lisp/eshell/esh-arg.el b/lisp/eshell/esh-arg.el
index f87cc2f20aa..48ac3e2bd4d 100644
--- a/lisp/eshell/esh-arg.el
+++ b/lisp/eshell/esh-arg.el
@@ -146,9 +146,10 @@ If POS is nil, the location of point is checked."
When each function on this hook is called, point will be at the
current position within the argument list. The function should either
return nil, meaning that it did no argument parsing, or it should
-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.
+return the result of the parse as a sexp. If the function did do
+argument parsing, but the result was nothing at all, it should return
+`eshell-empty-token'. The function 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
@@ -325,13 +326,14 @@ Point is left at the end of the arguments."
(prog1
(char-to-string (char-after))
(forward-char)))))
- (if (not eshell-current-argument)
- (setq eshell-current-argument result)
- (unless eshell-arg-listified
- (setq eshell-current-argument
- (list eshell-current-argument)
- eshell-arg-listified t))
- (nconc eshell-current-argument (list result))))))
+ (unless (eq result 'eshell-empty-token)
+ (if (not eshell-current-argument)
+ (setq eshell-current-argument result)
+ (unless eshell-arg-listified
+ (setq eshell-current-argument
+ (list eshell-current-argument)
+ eshell-arg-listified t))
+ (nconc eshell-current-argument (list result)))))))
(when (and outer eshell-current-argument)
(add-text-properties arg-begin (1+ arg-begin)
'(arg-begin t rear-nonsticky
@@ -375,15 +377,20 @@ after are both returned."
(when (eshell-looking-at-backslash-return (point))
(throw 'eshell-incomplete ?\\))
(forward-char 2) ; Move one char past the backslash.
- ;; If the char is in a quote, backslash only has special meaning
- ;; if it is escaping a special char.
- (if eshell-current-quoted
- (if (memq (char-before) eshell-special-chars-inside-quoting)
+ (if (eq (char-before) ?\n)
+ ;; Escaped newlines are extra-special: they expand to an empty
+ ;; token to allow for continuing Eshell commands across
+ ;; multiple lines.
+ 'eshell-empty-token
+ ;; If the char is in a quote, backslash only has special meaning
+ ;; if it is escaping a special char.
+ (if eshell-current-quoted
+ (if (memq (char-before) eshell-special-chars-inside-quoting)
+ (list 'eshell-escape-arg (char-to-string (char-before)))
+ (concat "\\" (char-to-string (char-before))))
+ (if (memq (char-before) eshell-special-chars-outside-quoting)
(list 'eshell-escape-arg (char-to-string (char-before)))
- (concat "\\" (char-to-string (char-before))))
- (if (memq (char-before) eshell-special-chars-outside-quoting)
- (list 'eshell-escape-arg (char-to-string (char-before)))
- (char-to-string (char-before))))))
+ (char-to-string (char-before)))))))
(defun eshell-parse-literal-quote ()
"Parse a literally quoted string. Nothing has special meaning!"