Function: sh-font-lock-quoted-subshell
sh-font-lock-quoted-subshell is a byte-compiled function defined in
sh-script.el.gz.
Signature
(sh-font-lock-quoted-subshell LIMIT)
Documentation
Search for a subshell embedded in a string.
Find all the unescaped " characters within said subshell, remembering that subshells can nest.
Source Code
;; Defined in /usr/src/emacs/lisp/progmodes/sh-script.el.gz
(defun sh-font-lock-quoted-subshell (limit)
"Search for a subshell embedded in a string.
Find all the unescaped \" characters within said subshell, remembering that
subshells can nest."
(when (eq ?\" (nth 3 (syntax-ppss))) ; Check we matched an opening quote.
;; bingo we have a $( or a ` inside a ""
(let (;; `state' can be: double-quote, backquote, code.
(state (if (eq (char-before) ?`) 'backquote 'code))
(startpos (point))
;; Stacked states in the context.
(states '(double-quote)))
(while (and state (progn (skip-chars-forward "^'\\\\\"`$()" limit)
(< (point) limit)))
;; unescape " inside a $( ... ) construct.
(pcase (char-after)
(?\' (pcase state
('double-quote nil)
(_ (forward-char 1)
;; FIXME: mark skipped double quotes as punctuation syntax.
(let ((spos (point)))
(skip-chars-forward "^'" limit)
(save-excursion
(let ((epos (point)))
(goto-char spos)
(while (search-forward "\"" epos t)
(put-text-property (point) (1- (point))
'syntax-table '(1)))))))))
(?\\ (forward-char 1))
(?\" (pcase state
('double-quote (setq state (pop states)))
(_ (push state states) (setq state 'double-quote)))
(if state (put-text-property (point) (1+ (point))
'syntax-table '(1))))
(?\` (pcase state
('backquote (setq state (pop states)))
(_ (push state states) (setq state 'backquote))))
(?\$ (if (not (eq (char-after (1+ (point))) ?\())
nil
(forward-char 1)
(pcase state
(_ (push state states) (setq state 'code)))))
(?\( (pcase state
('double-quote nil)
(_ (push state states) (setq state 'code))))
(?\) (pcase state
('double-quote nil)
(_ (setq state (pop states)))))
(_ (error "Internal error in sh-font-lock-quoted-subshell")))
(forward-char 1))
(when (< startpos (line-beginning-position))
(put-text-property startpos (point) 'syntax-multiline t)
(add-hook 'syntax-propertize-extend-region-functions
#'syntax-propertize-multiline nil t))
)))