mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-16 17:24:23 +00:00
Simplify parsing subcommands slightly
This mainly reduces some overly-deep indentation, but also fixes some minor issues with the "$<subcmd>" form: it unnecessarily added " > TEMP" (we already set this later via 'eshell-create-handles'), and it didn't properly unescape inner double quotes. * lisp/eshell/esh-cmd.el (eshell-parse-subcommand-argument): Simplify. * lisp/eshell/esh-var.el (eshell-parse-variable-ref): Simplify and fix edge cases in "$<subcmd>". * test/lisp/eshell/esh-var-tests.el (esh-var-test/quoted-interp-temp-cmd): Adjust test to check behavior of inner double quotes.
This commit is contained in:
parent
5b005f26a8
commit
bb088885df
3 changed files with 56 additions and 55 deletions
|
|
@ -675,13 +675,13 @@ This means an exit code of 0."
|
|||
(or (= (point-max) (1+ (point)))
|
||||
(not (eq (char-after (1+ (point))) ?\}))))
|
||||
(let ((end (eshell-find-delimiter ?\{ ?\})))
|
||||
(if (not end)
|
||||
(throw 'eshell-incomplete "{")
|
||||
(when (eshell-arg-delimiter (1+ end))
|
||||
(prog1
|
||||
`(eshell-as-subcommand
|
||||
,(eshell-parse-command (cons (1+ (point)) end)))
|
||||
(goto-char (1+ end))))))))
|
||||
(unless end
|
||||
(throw 'eshell-incomplete "{"))
|
||||
(when (eshell-arg-delimiter (1+ end))
|
||||
(prog1
|
||||
`(eshell-as-subcommand
|
||||
,(eshell-parse-command (cons (1+ (point)) end)))
|
||||
(goto-char (1+ end)))))))
|
||||
|
||||
(defun eshell-parse-lisp-argument ()
|
||||
"Parse a Lisp expression which is specified as an argument."
|
||||
|
|
|
|||
|
|
@ -507,55 +507,56 @@ Possible variable references are:
|
|||
(cond
|
||||
((eq (char-after) ?{)
|
||||
(let ((end (eshell-find-delimiter ?\{ ?\})))
|
||||
(if (not end)
|
||||
(throw 'eshell-incomplete "${")
|
||||
(forward-char)
|
||||
(prog1
|
||||
`(eshell-apply-indices
|
||||
(eshell-convert
|
||||
(eshell-command-to-value
|
||||
(eshell-as-subcommand
|
||||
,(let ((subcmd (or (eshell-unescape-inner-double-quote end)
|
||||
(cons (point) end)))
|
||||
(eshell-current-quoted nil))
|
||||
(eshell-parse-command subcmd))))
|
||||
;; If this is a simple double-quoted form like
|
||||
;; "${COMMAND}" (i.e. no indices after the subcommand
|
||||
;; and no `#' modifier before), ensure we convert to a
|
||||
;; single string. This avoids unnecessary work
|
||||
;; (e.g. splitting the output by lines) when it would
|
||||
;; just be joined back together afterwards.
|
||||
,(when (and (not modifier-p) eshell-current-quoted)
|
||||
'(not indices)))
|
||||
indices ,eshell-current-quoted)
|
||||
(goto-char (1+ end))))))
|
||||
(unless end
|
||||
(throw 'eshell-incomplete "${"))
|
||||
(forward-char)
|
||||
(prog1
|
||||
`(eshell-apply-indices
|
||||
(eshell-convert
|
||||
(eshell-command-to-value
|
||||
(eshell-as-subcommand
|
||||
,(let ((subcmd (or (eshell-unescape-inner-double-quote end)
|
||||
(cons (point) end)))
|
||||
(eshell-current-quoted nil))
|
||||
(eshell-parse-command subcmd))))
|
||||
;; If this is a simple double-quoted form like
|
||||
;; "${COMMAND}" (i.e. no indices after the subcommand and
|
||||
;; no `#' modifier before), ensure we convert to a single
|
||||
;; string. This avoids unnecessary work (e.g. splitting
|
||||
;; the output by lines) when it would just be joined back
|
||||
;; together afterwards.
|
||||
,(when (and (not modifier-p) eshell-current-quoted)
|
||||
'(not indices)))
|
||||
indices ,eshell-current-quoted)
|
||||
(goto-char (1+ end)))))
|
||||
((eq (char-after) ?\<)
|
||||
(let ((end (eshell-find-delimiter ?\< ?\>)))
|
||||
(if (not end)
|
||||
(throw 'eshell-incomplete "$<")
|
||||
(let* ((temp (make-temp-file temporary-file-directory))
|
||||
(cmd (concat (buffer-substring (1+ (point)) end)
|
||||
" > " temp)))
|
||||
(prog1
|
||||
`(let ((eshell-current-handles
|
||||
(eshell-create-handles ,temp 'overwrite)))
|
||||
(progn
|
||||
(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
|
||||
;; by `eshell-do-eval', which requires very
|
||||
;; particular forms in order to work
|
||||
;; properly. See bug#54190.
|
||||
(list (function
|
||||
(lambda ()
|
||||
(delete-file ,temp)
|
||||
(when-let ((buffer (get-file-buffer ,temp)))
|
||||
(kill-buffer buffer)))))))
|
||||
(eshell-apply-indices ,temp indices ,eshell-current-quoted)))
|
||||
(goto-char (1+ end)))))))
|
||||
(unless end
|
||||
(throw 'eshell-incomplete "$<"))
|
||||
(forward-char)
|
||||
(let* ((temp (make-temp-file temporary-file-directory))
|
||||
(subcmd (or (eshell-unescape-inner-double-quote end)
|
||||
(cons (point) end))))
|
||||
(prog1
|
||||
`(let ((eshell-current-handles
|
||||
(eshell-create-handles ,temp 'overwrite)))
|
||||
(progn
|
||||
(eshell-as-subcommand
|
||||
,(let ((eshell-current-quoted nil))
|
||||
(eshell-parse-command subcmd)))
|
||||
(ignore
|
||||
(nconc eshell-this-command-hook
|
||||
;; Quote this lambda; it will be evaluated by
|
||||
;; `eshell-do-eval', which requires very
|
||||
;; particular forms in order to work
|
||||
;; properly. See bug#54190.
|
||||
(list (function
|
||||
(lambda ()
|
||||
(delete-file ,temp)
|
||||
(when-let ((buffer (get-file-buffer ,temp)))
|
||||
(kill-buffer buffer)))))))
|
||||
(eshell-apply-indices ,temp indices ,eshell-current-quoted)))
|
||||
(goto-char (1+ end))))))
|
||||
((eq (char-after) ?\()
|
||||
(condition-case nil
|
||||
`(eshell-apply-indices
|
||||
|
|
|
|||
|
|
@ -454,7 +454,7 @@ nil, use FUNCTION instead."
|
|||
(let ((temporary-file-directory
|
||||
(file-name-as-directory (make-temp-file "esh-vars-tests" t))))
|
||||
(unwind-protect
|
||||
(eshell-command-result-equal "cat \"$<echo hi>\"" "hi")
|
||||
(eshell-command-result-equal "cat \"$<echo \\\"hi\\\">\"" "hi")
|
||||
(delete-directory temporary-file-directory t))))
|
||||
|
||||
(ert-deftest esh-var-test/quoted-interp-concat-cmd ()
|
||||
|
|
|
|||
Loading…
Reference in a new issue