diff options
| author | Jim Porter | 2022-03-27 12:09:58 -0700 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2022-04-03 14:16:44 +0200 |
| commit | c12a48c3350bb5aa2cbefda10c5364c778463366 (patch) | |
| tree | 23f553a42ecb9c2efb840235bbb9cd998c109cd1 /lisp | |
| parent | 9f521db6fec6c6dbdfeb1145f4dbb603c0240299 (diff) | |
| download | emacs-c12a48c3350bb5aa2cbefda10c5364c778463366.tar.gz emacs-c12a48c3350bb5aa2cbefda10c5364c778463366.zip | |
Fix handling of '\\' inside double-quotes in Eshell
Previously, Eshell would get confused and think the following command
was unterminated due to the second double-quote looking like it was
escaped:
echo "\\"
* lisp/eshell/esh-util.el (eshell-find-delimiter): Correct docstring
and treat '\' as an escapeable character when using backslash escapes.
* test/lisp/eshell/eshell-tests.el
(eshell-test/escape-special-quoted): Adapt test.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/eshell/esh-util.el | 51 |
1 files changed, 27 insertions, 24 deletions
diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el index 788404fc43a..8089d4d74b6 100644 --- a/lisp/eshell/esh-util.el +++ b/lisp/eshell/esh-util.el | |||
| @@ -151,49 +151,52 @@ Otherwise, evaluates FORM with no error handling." | |||
| 151 | (defun eshell-find-delimiter | 151 | (defun eshell-find-delimiter |
| 152 | (open close &optional bound reverse-p backslash-p) | 152 | (open close &optional bound reverse-p backslash-p) |
| 153 | "From point, find the CLOSE delimiter corresponding to OPEN. | 153 | "From point, find the CLOSE delimiter corresponding to OPEN. |
| 154 | The matching is bounded by BOUND. | 154 | The matching is bounded by BOUND. If REVERSE-P is non-nil, |
| 155 | If REVERSE-P is non-nil, process the region backwards. | 155 | process the region backwards. |
| 156 | If BACKSLASH-P is non-nil, and OPEN and CLOSE are the same character, | 156 | |
| 157 | then quoting is done by a backslash, rather than a doubled delimiter." | 157 | If BACKSLASH-P is non-nil, or OPEN and CLOSE are different |
| 158 | characters, then a backslash can be used to escape a delimiter | ||
| 159 | (or another backslash). Otherwise, the delimiter is escaped by | ||
| 160 | doubling it up." | ||
| 158 | (save-excursion | 161 | (save-excursion |
| 159 | (let ((depth 1) | 162 | (let ((depth 1) |
| 160 | (bound (or bound (point-max)))) | 163 | (bound (or bound (point-max)))) |
| 161 | (if (if reverse-p | 164 | (when (if reverse-p |
| 162 | (eq (char-before) close) | 165 | (eq (char-before) close) |
| 163 | (eq (char-after) open)) | 166 | (eq (char-after) open)) |
| 164 | (forward-char (if reverse-p -1 1))) | 167 | (forward-char (if reverse-p -1 1))) |
| 165 | (while (and (> depth 0) | 168 | (while (and (> depth 0) |
| 166 | (funcall (if reverse-p '> '<) (point) bound)) | 169 | (funcall (if reverse-p #'> #'<) (point) bound)) |
| 167 | (let ((c (if reverse-p (char-before) (char-after))) nc) | 170 | (let ((c (if reverse-p (char-before) (char-after)))) |
| 168 | (cond ((and (not reverse-p) | 171 | (cond ((and (not reverse-p) |
| 169 | (or (not (eq open close)) | 172 | (or (not (eq open close)) |
| 170 | backslash-p) | 173 | backslash-p) |
| 171 | (eq c ?\\) | 174 | (eq c ?\\) |
| 172 | (setq nc (char-after (1+ (point)))) | 175 | (memq (char-after (1+ (point))) |
| 173 | (or (eq nc open) (eq nc close))) | 176 | (list open close ?\\))) |
| 174 | (forward-char 1)) | 177 | (forward-char 1)) |
| 175 | ((and reverse-p | 178 | ((and reverse-p |
| 176 | (or (not (eq open close)) | 179 | (or (not (eq open close)) |
| 177 | backslash-p) | 180 | backslash-p) |
| 178 | (or (eq c open) (eq c close)) | 181 | (eq (char-before (1- (point))) ?\\) |
| 179 | (eq (char-before (1- (point))) | 182 | (memq c (list open close ?\\))) |
| 180 | ?\\)) | ||
| 181 | (forward-char -1)) | 183 | (forward-char -1)) |
| 182 | ((eq open close) | 184 | ((eq open close) |
| 183 | (if (eq c open) | 185 | (when (eq c open) |
| 184 | (if (and (not backslash-p) | 186 | (if (and (not backslash-p) |
| 185 | (eq (if reverse-p | 187 | (eq (if reverse-p |
| 186 | (char-before (1- (point))) | 188 | (char-before (1- (point))) |
| 187 | (char-after (1+ (point)))) open)) | 189 | (char-after (1+ (point)))) |
| 188 | (forward-char (if reverse-p -1 1)) | 190 | open)) |
| 189 | (setq depth (1- depth))))) | 191 | (forward-char (if reverse-p -1 1)) |
| 192 | (setq depth (1- depth))))) | ||
| 190 | ((= c open) | 193 | ((= c open) |
| 191 | (setq depth (+ depth (if reverse-p -1 1)))) | 194 | (setq depth (+ depth (if reverse-p -1 1)))) |
| 192 | ((= c close) | 195 | ((= c close) |
| 193 | (setq depth (+ depth (if reverse-p 1 -1)))))) | 196 | (setq depth (+ depth (if reverse-p 1 -1)))))) |
| 194 | (forward-char (if reverse-p -1 1))) | 197 | (forward-char (if reverse-p -1 1))) |
| 195 | (if (= depth 0) | 198 | (when (= depth 0) |
| 196 | (if reverse-p (point) (1- (point))))))) | 199 | (if reverse-p (point) (1- (point))))))) |
| 197 | 200 | ||
| 198 | (defun eshell-convert (string) | 201 | (defun eshell-convert (string) |
| 199 | "Convert STRING into a more native looking Lisp object." | 202 | "Convert STRING into a more native looking Lisp object." |