diff options
| author | Yuan Fu | 2025-09-20 23:36:23 -0700 |
|---|---|---|
| committer | Yuan Fu | 2025-09-22 16:41:06 -0700 |
| commit | 7b8c17d52704548ff2d2ea706247b1cf52de7d36 (patch) | |
| tree | 87aaf440eb76dec53091d6550fee603de7d70fd7 /lisp/progmodes/python.el | |
| parent | 192a0e177305e896d9e0ebc098be1e4cbb63eece (diff) | |
| download | emacs-7b8c17d52704548ff2d2ea706247b1cf52de7d36.tar.gz emacs-7b8c17d52704548ff2d2ea706247b1cf52de7d36.zip | |
Fix python-ts-mode font-lock breakage by grammar change (bug#79457)
* lisp/progmodes/python.el (python--treesit-fontify-string): Use
new algorithm.
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 67 |
1 files changed, 37 insertions, 30 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index e5cc3b0078b..22a4e2c2e5d 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -1092,36 +1092,43 @@ NODE is the string node. Do not fontify the initial f for | |||
| 1092 | f-strings. OVERRIDE is the override flag described in | 1092 | f-strings. OVERRIDE is the override flag described in |
| 1093 | `treesit-font-lock-rules'. START and END mark the region to be | 1093 | `treesit-font-lock-rules'. START and END mark the region to be |
| 1094 | fontified." | 1094 | fontified." |
| 1095 | (let* ((maybe-expression (treesit-node-parent node)) | 1095 | ;; Criteria for docstring: go up the parse tree until top-level or a |
| 1096 | (grandparent (treesit-node-parent | 1096 | ;; node under function/class, at each level, the node is the first |
| 1097 | (treesit-node-parent | 1097 | ;; child (excluding comments). This condition also rules out negative |
| 1098 | maybe-expression))) | 1098 | ;; cases like |
| 1099 | (maybe-defun grandparent) | 1099 | ;; |
| 1100 | (face (if (and (or (member (treesit-node-type maybe-defun) | 1100 | ;; def function(): |
| 1101 | '("function_definition" | 1101 | ;; return "some string" |
| 1102 | "class_definition")) | 1102 | ;; |
| 1103 | ;; If the grandparent is null, meaning the | 1103 | ;; And it recognizes for BOF docstrings, and allows comments before |
| 1104 | ;; string is top-level, and the string has | 1104 | ;; the docstring. |
| 1105 | ;; no node or only comment preceding it, | 1105 | ;; |
| 1106 | ;; it's a BOF docstring. | 1106 | ;; Older grammar has function_definition -> block -> expression_statement -> string |
| 1107 | (and (null grandparent) | 1107 | ;; Newer grammar has function_definition -> block -> string |
| 1108 | (cl-loop | 1108 | ;; This algorithm works for both. |
| 1109 | for prev = (treesit-node-prev-sibling | 1109 | (let* ((cursor node) |
| 1110 | maybe-expression) | 1110 | (face (catch 'break |
| 1111 | then (treesit-node-prev-sibling prev) | 1111 | (while t |
| 1112 | while prev | 1112 | (let ((parent (treesit-node-parent cursor)) |
| 1113 | if (not (equal (treesit-node-type prev) | 1113 | (cursor-idx (treesit-node-index cursor))) |
| 1114 | "comment")) | 1114 | (when (null parent) |
| 1115 | return nil | 1115 | (throw 'break 'font-lock-doc-face)) |
| 1116 | finally return t))) | 1116 | |
| 1117 | ;; This check filters out this case: | 1117 | (when (and (member (treesit-node-type parent) |
| 1118 | ;; def function(): | 1118 | '("function_definition" |
| 1119 | ;; return "some string" | 1119 | "class_definition")) |
| 1120 | (equal (treesit-node-type maybe-expression) | 1120 | (equal (treesit-node-field-name-for-child |
| 1121 | "expression_statement")) | 1121 | parent cursor-idx) |
| 1122 | 'font-lock-doc-face | 1122 | "body")) |
| 1123 | 'font-lock-string-face)) | 1123 | (throw 'break 'font-lock-doc-face)) |
| 1124 | 1124 | ||
| 1125 | (let ((idx 0)) | ||
| 1126 | (while (< idx cursor-idx) | ||
| 1127 | (unless (equal (treesit-node-type | ||
| 1128 | (treesit-node-child parent idx)) | ||
| 1129 | "comment") | ||
| 1130 | (throw 'break 'font-lock-string-face)))) | ||
| 1131 | (setq cursor parent))))) | ||
| 1125 | (ignore-interpolation | 1132 | (ignore-interpolation |
| 1126 | (not (seq-some | 1133 | (not (seq-some |
| 1127 | (lambda (feats) (memq 'string-interpolation feats)) | 1134 | (lambda (feats) (memq 'string-interpolation feats)) |