Function: eshell-parse-variable-ref

eshell-parse-variable-ref is a byte-compiled function defined in esh-var.el.gz.

Signature

(eshell-parse-variable-ref &optional MODIFIER-P)

Documentation

Eval a variable reference.

Returns a Lisp form which, if evaluated, will return the value of the variable.

If MODIFIER-P is non-nil, the value of the variable will be modified by some function. If MODIFIER-P is nil, the value will be used as-is; this allows optimization of some kinds of variable references.

Possible variable references are:

  NAME an environment or Lisp variable value
  "LONG-NAME" disambiguates the length of the name
  'LONG-NAME' as above
  {COMMAND} result of command is variable's value
  (LISP-FORM) result of Lisp form is variable's value
  <COMMAND> write the output of command to a temporary file;
                result is the file name

Source Code

;; Defined in /usr/src/emacs/lisp/eshell/esh-var.el.gz
(defun eshell-parse-variable-ref (&optional modifier-p)
  "Eval a variable reference.
Returns a Lisp form which, if evaluated, will return the value of the
variable.

If MODIFIER-P is non-nil, the value of the variable will be
modified by some function.  If MODIFIER-P is nil, the value will be
used as-is; this allows optimization of some kinds of variable
references.

Possible variable references are:

  NAME          an environment or Lisp variable value
  \"LONG-NAME\"   disambiguates the length of the name
  \\='LONG-NAME\\='   as above
  {COMMAND}     result of command is variable's value
  (LISP-FORM)   result of Lisp form is variable's value
  <COMMAND>     write the output of command to a temporary file;
                result is the file name"
  (cond
   ((eq (char-after) ?{)
    (let ((end (eshell-find-delimiter ?\{ ?\})))
      (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 ?\< ?\>)))
      (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
            `(eshell-with-handles (,temp 'overwrite)
               (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
          (eshell-command-to-value
           (eshell-lisp-command
            ',(read (or (eshell-unescape-inner-double-quote (point-max))
                        (current-buffer)))))
          indices ,eshell-current-quoted)
      (end-of-file
       (throw 'eshell-incomplete "$("))))
   ((looking-at (rx-to-string
                 `(or "'" ,(if eshell-current-quoted "\\\"" "\""))))
    (eshell-with-temp-command
        (or (eshell-unescape-inner-double-quote (point-max))
            (cons (point) (point-max)))
      (let (name)
        (when-let* ((delim
                     (catch 'eshell-incomplete
                       (ignore (setq name (if (eq (char-after) ?\')
                                              (eshell-parse-literal-quote)
                                            (eshell-parse-double-quote)))))))
          (throw 'eshell-incomplete (concat "$" delim)))
        (when name
          `(eshell-get-variable ,(eval name) indices ,eshell-current-quoted)))))
   ((assoc (char-to-string (char-after))
           eshell-variable-aliases-list)
    (forward-char)
    `(eshell-get-variable ,(char-to-string (char-before)) indices
                          ,eshell-current-quoted))
   ((looking-at eshell-variable-name-regexp)
    (prog1
        `(eshell-get-variable ,(match-string 0) indices ,eshell-current-quoted)
      (goto-char (match-end 0))))
   (t
    (error "Invalid variable reference"))))