mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-25 07:28:20 +00:00
* lisp/eshell: Make backslash a no-op in front of normal chars
Fixes: debbugs:8531 * lisp/eshell/esh-arg.el (eshell-parse-argument-hook): Update comment. (eshell-parse-backslash): Return escaped character after backslash if it is special. Otherwise, if the backslash is not in a quoted string, ignore the backslash and return the character after; if the backslash is in a quoted string, return the backslash and the character after. * test/automated/eshell.el (eshell-test/escape-nonspecial) (eshell-test/escape-nonspecial-unicode) (eshell-test/escape-nonspecial-quoted) (eshell-test/escape-special-quoted): Add tests for new `eshell-parse-backslash' behavior.
This commit is contained in:
parent
3d78c5578c
commit
c44f5b046b
@ -89,7 +89,7 @@ yield the values intended."
|
||||
(goto-char (match-end 0))
|
||||
(eshell-finish-arg)))))
|
||||
|
||||
;; backslash before a special character means escape it
|
||||
;; parse backslash and the character after
|
||||
'eshell-parse-backslash
|
||||
|
||||
;; text beginning with ' is a literally quoted
|
||||
@ -305,34 +305,27 @@ If the character is itself a backslash, it needs no escaping."
|
||||
(string ?\\ char)))))
|
||||
|
||||
(defun eshell-parse-backslash ()
|
||||
"Parse a single backslash (\) character, which might mean escape.
|
||||
It only means escape if the character immediately following is a
|
||||
special character that is not itself a backslash."
|
||||
"Parse a single backslash (\\) character and the character after.
|
||||
If the character after the backslash is special, always ignore
|
||||
the backslash and return the escaped character.
|
||||
|
||||
Otherwise, if the backslash is not in quoted string, the
|
||||
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) ?\\)
|
||||
(if (eshell-looking-at-backslash-return (point))
|
||||
(throw 'eshell-incomplete ?\\)
|
||||
(if (and (not (eq (char-after (1+ (point))) ?\\))
|
||||
(if eshell-current-quoted
|
||||
(memq (char-after (1+ (point)))
|
||||
eshell-special-chars-inside-quoting)
|
||||
(memq (char-after (1+ (point)))
|
||||
eshell-special-chars-outside-quoting)))
|
||||
(progn
|
||||
(forward-char 2)
|
||||
(list 'eshell-escape-arg
|
||||
(char-to-string (char-before))))
|
||||
;; allow \\<RET> to mean a literal "\" character followed by a
|
||||
;; normal return, rather than a backslash followed by a line
|
||||
;; continuation (i.e., "\\ + \n" rather than "\ + \\n"). This
|
||||
;; is necessary because backslashes in Eshell are not special
|
||||
;; unless they either precede something special, or precede a
|
||||
;; backslash that precedes something special. (Mainly this is
|
||||
;; done to make using backslash on Windows systems more
|
||||
;; natural-feeling).
|
||||
(if (eshell-looking-at-backslash-return (1+ (point)))
|
||||
(forward-char))
|
||||
(forward-char)
|
||||
"\\"))))
|
||||
(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)
|
||||
(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))))))
|
||||
|
||||
(defun eshell-parse-literal-quote ()
|
||||
"Parse a literally quoted string. Nothing has special meaning!"
|
||||
|
@ -166,6 +166,37 @@ e.g. \"{(+ 1 2)} 3\" => 3"
|
||||
(eshell-command-result-p "+ 1 2; + $_ 4"
|
||||
"3\n6\n")))
|
||||
|
||||
(ert-deftest eshell-test/escape-nonspecial ()
|
||||
"Test that \"\\c\" and \"c\" are equivalent when \"c\" is not a
|
||||
special character."
|
||||
(with-temp-eshell
|
||||
(eshell-command-result-p "echo he\\llo"
|
||||
"hello\n")))
|
||||
|
||||
(ert-deftest eshell-test/escape-nonspecial-unicode ()
|
||||
"Test that \"\\c\" and \"c\" are equivalent when \"c\" is a
|
||||
unicode character (unicode characters are nonspecial by
|
||||
definition)."
|
||||
(with-temp-eshell
|
||||
(eshell-command-result-p "echo Vid\\éos"
|
||||
"Vidéos\n")))
|
||||
|
||||
(ert-deftest eshell-test/escape-nonspecial-quoted ()
|
||||
"Test that the backslash is preserved for escaped nonspecial
|
||||
chars"
|
||||
(with-temp-eshell
|
||||
(eshell-command-result-p "echo \"h\\i\""
|
||||
;; Backslashes are doubled for regexp.
|
||||
"h\\\\i\n")))
|
||||
|
||||
(ert-deftest eshell-test/escape-special-quoted ()
|
||||
"Test that the backslash is not preserved for escaped special
|
||||
chars"
|
||||
(with-temp-eshell
|
||||
(eshell-command-result-p "echo \"h\\\\i\""
|
||||
;; Backslashes are doubled for regexp.
|
||||
"h\\\\i\n")))
|
||||
|
||||
(ert-deftest eshell-test/command-running-p ()
|
||||
"Modeline should show no command running"
|
||||
(with-temp-eshell
|
||||
|
Loading…
Reference in New Issue
Block a user