Fix Eshell dollar interpolation inside of double-quotes
For example,
echo "${echo hi}"
previously tried to run the program named 'echo hi', instead of 'echo'
with the argument 'hi'.
* lisp/eshell/esh-arg.el (eshell-parse-inner-double-quote):
New function.
* lisp/eshell/esh-var.el (eshell-parse-variable-ref): Support parsing
when wrapped in double-quiotes.
* test/lisp/eshell/esh-var-tests.el (esh-var-test/interp-var)
(esh-var-test/interp-quoted-var)
(esh-var-test/interp-quoted-var-concat)
(esh-var-test/quoted-interp-var)
(esh-var-test/quoted-interp-quoted-var)
(esh-var-test/quoted-interp-lisp, esh-var-test/quoted-interp-cmd)
(esh-var-test/quoted-interp-temp-cmd): New tests.
This commit is contained in:
parent
ae1acb6017
commit
cccee7e840
3 changed files with 91 additions and 9 deletions
|
|
@ -354,6 +354,30 @@ after are both returned."
|
|||
(list 'eshell-escape-arg arg))))
|
||||
(goto-char (1+ end)))))))
|
||||
|
||||
(defun eshell-parse-inner-double-quote (bound)
|
||||
"Parse the inner part of a double quoted string.
|
||||
The string to parse starts at point and ends at BOUND.
|
||||
|
||||
If Eshell is currently parsing a quoted string and there are any
|
||||
backslash-escaped characters, this will return the unescaped
|
||||
string, updating point to BOUND. Otherwise, this returns nil and
|
||||
leaves point where it was."
|
||||
(when eshell-current-quoted
|
||||
(let (strings
|
||||
(start (point))
|
||||
(special-char
|
||||
(rx-to-string
|
||||
`(seq "\\" (group (any ,@eshell-special-chars-inside-quoting))))))
|
||||
(while (re-search-forward special-char bound t)
|
||||
(push (concat (buffer-substring start (match-beginning 0))
|
||||
(match-string 1))
|
||||
strings)
|
||||
(setq start (match-end 0)))
|
||||
(when strings
|
||||
(push (buffer-substring start bound) strings)
|
||||
(goto-char bound)
|
||||
(apply #'concat (nreverse strings))))))
|
||||
|
||||
(defun eshell-parse-special-reference ()
|
||||
"Parse a special syntax reference, of the form `#<args>'.
|
||||
|
||||
|
|
|
|||
|
|
@ -440,18 +440,16 @@ Possible options are:
|
|||
(let ((end (eshell-find-delimiter ?\{ ?\})))
|
||||
(if (not end)
|
||||
(throw 'eshell-incomplete ?\{)
|
||||
(forward-char)
|
||||
(prog1
|
||||
`(eshell-convert
|
||||
(eshell-command-to-value
|
||||
(eshell-as-subcommand
|
||||
,(eshell-parse-command (cons (1+ (point)) end)))))
|
||||
,(let ((subcmd (or (eshell-parse-inner-double-quote end)
|
||||
(cons (point) end)))
|
||||
(eshell-current-quoted nil))
|
||||
(eshell-parse-command subcmd)))))
|
||||
(goto-char (1+ end))))))
|
||||
((memq (char-after) '(?\' ?\"))
|
||||
(let ((name (if (eq (char-after) ?\')
|
||||
(eshell-parse-literal-quote)
|
||||
(eshell-parse-double-quote))))
|
||||
(if name
|
||||
`(eshell-get-variable ,(eval name) indices))))
|
||||
((eq (char-after) ?\<)
|
||||
(let ((end (eshell-find-delimiter ?\< ?\>)))
|
||||
(if (not end)
|
||||
|
|
@ -463,7 +461,9 @@ Possible options are:
|
|||
`(let ((eshell-current-handles
|
||||
(eshell-create-handles ,temp 'overwrite)))
|
||||
(progn
|
||||
(eshell-as-subcommand ,(eshell-parse-command cmd))
|
||||
(eshell-as-subcommand
|
||||
,(let ((eshell-current-quoted nil))
|
||||
(eshell-parse-command cmd)))
|
||||
(ignore
|
||||
(nconc eshell-this-command-hook
|
||||
;; Quote this lambda; it will be evaluated
|
||||
|
|
@ -478,9 +478,18 @@ Possible options are:
|
|||
(condition-case nil
|
||||
`(eshell-command-to-value
|
||||
(eshell-lisp-command
|
||||
',(read (current-buffer))))
|
||||
',(read (or (eshell-parse-inner-double-quote (point-max))
|
||||
(current-buffer)))))
|
||||
(end-of-file
|
||||
(throw 'eshell-incomplete ?\())))
|
||||
((looking-at (rx (or "'" "\"" "\\\"")))
|
||||
(eshell-with-temp-command (or (eshell-parse-inner-double-quote (point-max))
|
||||
(cons (point) (point-max)))
|
||||
(let ((name (if (eq (char-after) ?\')
|
||||
(eshell-parse-literal-quote)
|
||||
(eshell-parse-double-quote))))
|
||||
(when name
|
||||
`(eshell-get-variable ,(eval name) indices)))))
|
||||
((assoc (char-to-string (char-after))
|
||||
eshell-variable-aliases-list)
|
||||
(forward-char)
|
||||
|
|
|
|||
|
|
@ -37,6 +37,25 @@
|
|||
|
||||
;; Variable interpolation
|
||||
|
||||
(ert-deftest esh-var-test/interp-var ()
|
||||
"Interpolate variable"
|
||||
(should (equal (eshell-test-command-result "echo $user-login-name")
|
||||
user-login-name)))
|
||||
|
||||
(ert-deftest esh-var-test/interp-quoted-var ()
|
||||
"Interpolate quoted variable"
|
||||
(should (equal (eshell-test-command-result "echo $'user-login-name'")
|
||||
user-login-name))
|
||||
(should (equal (eshell-test-command-result "echo $\"user-login-name\"")
|
||||
user-login-name)))
|
||||
|
||||
(ert-deftest esh-var-test/interp-quoted-var-concat ()
|
||||
"Interpolate and concat quoted variable"
|
||||
(should (equal (eshell-test-command-result "echo $'user-login-name'-foo")
|
||||
(concat user-login-name "-foo")))
|
||||
(should (equal (eshell-test-command-result "echo $\"user-login-name\"-foo")
|
||||
(concat user-login-name "-foo"))))
|
||||
|
||||
(ert-deftest esh-var-test/interp-lisp ()
|
||||
"Interpolate Lisp form evaluation"
|
||||
(should (equal (eshell-test-command-result "+ $(+ 1 2) 3") 6)))
|
||||
|
|
@ -79,6 +98,36 @@
|
|||
(eshell-command-result-p "echo ${echo hi}-${*echo there}"
|
||||
"hi-there\n")))
|
||||
|
||||
(ert-deftest esh-var-test/quoted-interp-var ()
|
||||
"Interpolate variable inside double-quotes"
|
||||
(should (equal (eshell-test-command-result "echo \"$user-login-name\"")
|
||||
user-login-name)))
|
||||
|
||||
(ert-deftest esh-var-test/quoted-interp-quoted-var ()
|
||||
"Interpolate quoted variable inside double-quotes"
|
||||
(should (equal (eshell-test-command-result
|
||||
"echo \"hi, $'user-login-name'\"")
|
||||
(concat "hi, " user-login-name)))
|
||||
(should (equal (eshell-test-command-result
|
||||
"echo \"hi, $\\\"user-login-name\\\"\"")
|
||||
(concat "hi, " user-login-name))))
|
||||
|
||||
(ert-deftest esh-var-test/quoted-interp-lisp ()
|
||||
"Interpolate Lisp form evaluation inside double-quotes"
|
||||
(should (equal (eshell-test-command-result
|
||||
"echo \"hi $(concat \\\"the\\\" \\\"re\\\")\"")
|
||||
"hi there")))
|
||||
|
||||
(ert-deftest esh-var-test/quoted-interp-cmd ()
|
||||
"Interpolate command result inside double-quotes"
|
||||
(should (equal (eshell-test-command-result
|
||||
"echo \"hi ${echo \\\"there\\\"}\"")
|
||||
"hi there")))
|
||||
|
||||
(ert-deftest esh-var-test/quoted-interp-temp-cmd ()
|
||||
"Interpolate command result redirected to temp file inside double-quotes"
|
||||
(should (equal (eshell-test-command-result "cat \"$<echo hi>\"") "hi")))
|
||||
|
||||
|
||||
;; Built-in variables
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue