Function: python--treesit-fontify-string
python--treesit-fontify-string is a byte-compiled function defined in
python.el.gz.
Signature
(python--treesit-fontify-string NODE OVERRIDE START END &rest _)
Documentation
Fontify string.
NODE is the string node. Do not fontify the initial f for
f-strings. OVERRIDE is the override flag described in
treesit-font-lock-rules. START and END mark the region to be
fontified.
Source Code
;; Defined in /usr/src/emacs/lisp/progmodes/python.el.gz
(defun python--treesit-fontify-string (node override start end &rest _)
"Fontify string.
NODE is the string node. Do not fontify the initial f for
f-strings. OVERRIDE is the override flag described in
`treesit-font-lock-rules'. START and END mark the region to be
fontified."
;; Criteria for docstring: go up the parse tree until top-level or a
;; node under function/class, at each level, the node is the first
;; child (excluding comments). This condition also rules out negative
;; cases like
;;
;; def function():
;; return "some string"
;;
;; And it recognizes for BOF docstrings, and allows comments before
;; the docstring.
;;
;; Older grammar has function_definition -> block -> expression_statement -> string
;; Newer grammar has function_definition -> block -> string
;; This algorithm works for both.
(let* ((cursor node)
(face (catch 'break
(while t
(let ((parent (treesit-node-parent cursor))
(cursor-idx (treesit-node-index cursor)))
(when (null parent)
(throw 'break 'font-lock-doc-face))
(when (and (member (treesit-node-type parent)
'("function_definition"
"class_definition"))
(equal (treesit-node-field-name-for-child
parent cursor-idx)
"body"))
(throw 'break 'font-lock-doc-face))
;; If there's any non-comment sibling before
;; cursor, the string isn't a docstring.
(dotimes (idx cursor-idx)
(unless (equal (treesit-node-type
(treesit-node-child parent idx))
"comment")
(throw 'break 'font-lock-string-face)))
(setq cursor parent)))))
(ignore-interpolation
(not (seq-some
(lambda (feats) (memq 'string-interpolation feats))
(seq-take treesit-font-lock-feature-list
(if (fboundp 'treesit--compute-font-lock-level)
(treesit--compute-font-lock-level
treesit-font-lock-level)
treesit-font-lock-level)))))
;; If interpolation is enabled, highlight only
;; string_start/string_content/string_end children. Do not
;; touch interpolation node that can occur inside of the
;; string.
(string-nodes (if ignore-interpolation
(list node)
(treesit-filter-child
node
(lambda (ch) (member (treesit-node-type ch)
'("string_start"
"string_content"
"string_end")))
t))))
(dolist (string-node string-nodes)
(let ((string-beg (treesit-node-start string-node))
(string-end (treesit-node-end string-node)))
(when (or ignore-interpolation
(equal (treesit-node-type string-node) "string_start"))
;; Don't highlight string prefixes like f/r/b.
(save-excursion
(goto-char string-beg)
(when (re-search-forward "[\"']" string-end t)
(setq string-beg (match-beginning 0)))))
(treesit-fontify-with-override
string-beg string-end face override start end)))))