Fix python-ts-mode font-lock breakage by grammar change (bug#79457)
* lisp/progmodes/python.el (python--treesit-fontify-string): Use new algorithm.
This commit is contained in:
parent
192a0e1773
commit
7b8c17d527
1 changed files with 36 additions and 29 deletions
|
|
@ -1092,36 +1092,43 @@ NODE is the string node. Do not fontify the initial f for
|
||||||
f-strings. OVERRIDE is the override flag described in
|
f-strings. OVERRIDE is the override flag described in
|
||||||
`treesit-font-lock-rules'. START and END mark the region to be
|
`treesit-font-lock-rules'. START and END mark the region to be
|
||||||
fontified."
|
fontified."
|
||||||
(let* ((maybe-expression (treesit-node-parent node))
|
;; Criteria for docstring: go up the parse tree until top-level or a
|
||||||
(grandparent (treesit-node-parent
|
;; node under function/class, at each level, the node is the first
|
||||||
(treesit-node-parent
|
;; child (excluding comments). This condition also rules out negative
|
||||||
maybe-expression)))
|
;; cases like
|
||||||
(maybe-defun grandparent)
|
;;
|
||||||
(face (if (and (or (member (treesit-node-type maybe-defun)
|
;; def function():
|
||||||
'("function_definition"
|
;; return "some string"
|
||||||
"class_definition"))
|
;;
|
||||||
;; If the grandparent is null, meaning the
|
;; And it recognizes for BOF docstrings, and allows comments before
|
||||||
;; string is top-level, and the string has
|
;; the docstring.
|
||||||
;; no node or only comment preceding it,
|
;;
|
||||||
;; it's a BOF docstring.
|
;; Older grammar has function_definition -> block -> expression_statement -> string
|
||||||
(and (null grandparent)
|
;; Newer grammar has function_definition -> block -> string
|
||||||
(cl-loop
|
;; This algorithm works for both.
|
||||||
for prev = (treesit-node-prev-sibling
|
(let* ((cursor node)
|
||||||
maybe-expression)
|
(face (catch 'break
|
||||||
then (treesit-node-prev-sibling prev)
|
(while t
|
||||||
while prev
|
(let ((parent (treesit-node-parent cursor))
|
||||||
if (not (equal (treesit-node-type prev)
|
(cursor-idx (treesit-node-index cursor)))
|
||||||
"comment"))
|
(when (null parent)
|
||||||
return nil
|
(throw 'break 'font-lock-doc-face))
|
||||||
finally return t)))
|
|
||||||
;; This check filters out this case:
|
|
||||||
;; def function():
|
|
||||||
;; return "some string"
|
|
||||||
(equal (treesit-node-type maybe-expression)
|
|
||||||
"expression_statement"))
|
|
||||||
'font-lock-doc-face
|
|
||||||
'font-lock-string-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))
|
||||||
|
|
||||||
|
(let ((idx 0))
|
||||||
|
(while (< 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
|
(ignore-interpolation
|
||||||
(not (seq-some
|
(not (seq-some
|
||||||
(lambda (feats) (memq 'string-interpolation feats))
|
(lambda (feats) (memq 'string-interpolation feats))
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue