From b70896f78f88e1a482ea394c9a4163394d2e5f0b Mon Sep 17 00:00:00 2001 From: Jim Porter Date: Sun, 28 Jan 2024 15:49:03 -0800 Subject: [PATCH] In Eshell, allow an escaped newline at the end of a command Normally, "echo" runs the command "echo". Likewise, "echo\" should too: we escape the first newline, and then the second one is unescaped and should send the command input to Eshell. Previously, you had to press RET a third time, but now it works as expected. * lisp/eshell/esh-arg.el (eshell-looking-at-backslash-return): Make obsolete. (eshell-parse-backslash): A backslash sequence is only incomplete if there's nothing at all after it. * test/lisp/eshell/esh-arg-tests.el (esh-arg-test/escape/newline) (esh-arg-test/escape-quoted/newline): Remove inaccurate comment; escaped newlines are always special. (esh-arg-test/escape/trailing-newline): New test. (cherry picked from commit 1f5a13d5843306af2e6a74fbdfd6d00af8804a23) --- lisp/eshell/esh-arg.el | 5 +++-- test/lisp/eshell/esh-arg-tests.el | 14 ++++++++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/lisp/eshell/esh-arg.el b/lisp/eshell/esh-arg.el index 1880cc03885..97ddac58629 100644 --- a/lisp/eshell/esh-arg.el +++ b/lisp/eshell/esh-arg.el @@ -440,6 +440,7 @@ Point is left at the end of the arguments." (defsubst eshell-looking-at-backslash-return (pos) "Test whether a backslash-return sequence occurs at POS." + (declare (obsolete nil "30.1")) (and (eq (char-after pos) ?\\) (or (= (1+ pos) (point-max)) (and (eq (char-after (1+ pos)) ?\n) @@ -464,8 +465,8 @@ backslash is ignored and the character after is returned. If the backslash is in a quoted string, the backslash and the character after are both returned." (when (eq (char-after) ?\\) - (when (eshell-looking-at-backslash-return (point)) - (throw 'eshell-incomplete "\\")) + (when (= (1+ (point)) (point-max)) + (throw 'eshell-incomplete "\\")) (forward-char 2) ; Move one char past the backslash. (let ((special-chars (if eshell-current-quoted eshell-special-chars-inside-quoting diff --git a/test/lisp/eshell/esh-arg-tests.el b/test/lisp/eshell/esh-arg-tests.el index b626cf10bf1..b748c5ab4c0 100644 --- a/test/lisp/eshell/esh-arg-tests.el +++ b/test/lisp/eshell/esh-arg-tests.el @@ -60,13 +60,17 @@ chars." "he\\\\llo\n"))) (ert-deftest esh-arg-test/escape/newline () - "Test that an escaped newline is equivalent to the empty string. -When newlines are *nonspecial*, an escaped newline should be -treated as just a newline." + "Test that an escaped newline is equivalent to the empty string." (with-temp-eshell (eshell-match-command-output "echo hi\\\nthere" "hithere\n"))) +(ert-deftest esh-arg-test/escape/trailing-newline () + "Test that an escaped newline is equivalent to the empty string." + (with-temp-eshell + (eshell-match-command-output "echo hi\\\n" + "hi\n"))) + (ert-deftest esh-arg-test/escape/newline-conditional () "Test invocation of an if/else statement using line continuations." (let ((eshell-test-value t)) @@ -95,9 +99,7 @@ chars." "\\\"hi\\\\\n"))) (ert-deftest esh-arg-test/escape-quoted/newline () - "Test that an escaped newline is equivalent to the empty string. -When newlines are *nonspecial*, an escaped newline should be -treated literally, as a backslash and a newline." + "Test that an escaped newline is equivalent to the empty string." (with-temp-eshell (eshell-match-command-output "echo \"hi\\\nthere\"" "hithere\n"))) -- 2.39.5