aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes
diff options
context:
space:
mode:
authorPo Lu2023-01-11 16:07:32 +0800
committerPo Lu2023-01-11 16:07:32 +0800
commit2fa5583d96fe78ff66d6fd41f18e54e4e20ea7d6 (patch)
treed3cf4a755e2da9b11c284763ed20041033b5dc3b /lisp/progmodes
parent494bedde3235f9034746c977260bbbc2c1e51d8c (diff)
parent033f2cc6140d03e78403f37689b9f54b64bded01 (diff)
downloademacs-2fa5583d96fe78ff66d6fd41f18e54e4e20ea7d6.tar.gz
emacs-2fa5583d96fe78ff66d6fd41f18e54e4e20ea7d6.zip
Merge remote-tracking branch 'origin/master' into feature/android
Diffstat (limited to 'lisp/progmodes')
-rw-r--r--lisp/progmodes/c-ts-mode.el174
-rw-r--r--lisp/progmodes/cc-fonts.el4
-rw-r--r--lisp/progmodes/go-ts-mode.el107
-rw-r--r--lisp/progmodes/gud.el5
-rw-r--r--lisp/progmodes/js.el5
-rw-r--r--lisp/progmodes/project.el2
-rw-r--r--lisp/progmodes/python.el36
-rw-r--r--lisp/progmodes/ruby-ts-mode.el17
-rw-r--r--lisp/progmodes/typescript-ts-mode.el22
-rw-r--r--lisp/progmodes/xref.el2
10 files changed, 257 insertions, 117 deletions
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index e76966e7660..e929fe1dd81 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -122,9 +122,13 @@ MODE is either `c' or `cpp'."
122 ((node-is "else") parent-bol 0) 122 ((node-is "else") parent-bol 0)
123 ((node-is "case") parent-bol 0) 123 ((node-is "case") parent-bol 0)
124 ((node-is "preproc_arg") no-indent) 124 ((node-is "preproc_arg") no-indent)
125 (c-ts-mode--comment-2nd-line-matcher
126 c-ts-mode--comment-2nd-line-anchor
127 1)
125 ((and (parent-is "comment") c-ts-mode--looking-at-star) 128 ((and (parent-is "comment") c-ts-mode--looking-at-star)
126 c-ts-mode--comment-start-after-first-star -1) 129 c-ts-mode--comment-start-after-first-star -1)
127 ((parent-is "comment") prev-adaptive-prefix 0) 130 ((parent-is "comment") prev-adaptive-prefix 0)
131 (c-ts-mode--top-level-label-matcher point-min 1)
128 ((node-is "labeled_statement") parent-bol 0) 132 ((node-is "labeled_statement") parent-bol 0)
129 ((parent-is "labeled_statement") parent-bol c-ts-mode-indent-offset) 133 ((parent-is "labeled_statement") parent-bol c-ts-mode-indent-offset)
130 ((match "preproc_ifdef" "compound_statement") point-min 0) 134 ((match "preproc_ifdef" "compound_statement") point-min 0)
@@ -138,6 +142,7 @@ MODE is either `c' or `cpp'."
138 ((parent-is "function_definition") parent-bol 0) 142 ((parent-is "function_definition") parent-bol 0)
139 ((parent-is "conditional_expression") first-sibling 0) 143 ((parent-is "conditional_expression") first-sibling 0)
140 ((parent-is "assignment_expression") parent-bol c-ts-mode-indent-offset) 144 ((parent-is "assignment_expression") parent-bol c-ts-mode-indent-offset)
145 ((parent-is "concatenated_string") parent-bol c-ts-mode-indent-offset)
141 ((parent-is "comma_expression") first-sibling 0) 146 ((parent-is "comma_expression") first-sibling 0)
142 ((parent-is "init_declarator") parent-bol c-ts-mode-indent-offset) 147 ((parent-is "init_declarator") parent-bol c-ts-mode-indent-offset)
143 ((parent-is "parenthesized_expression") first-sibling 1) 148 ((parent-is "parenthesized_expression") first-sibling 1)
@@ -151,7 +156,9 @@ MODE is either `c' or `cpp'."
151 ((parent-is "call_expression") parent 0) 156 ((parent-is "call_expression") parent 0)
152 ((parent-is "enumerator_list") parent-bol c-ts-mode-indent-offset) 157 ((parent-is "enumerator_list") parent-bol c-ts-mode-indent-offset)
153 ,@(when (eq mode 'cpp) 158 ,@(when (eq mode 'cpp)
154 '(((node-is "access_specifier") parent-bol 0))) 159 '(((node-is "access_specifier") parent-bol 0)
160 ;; Indent the body of namespace definitions.
161 ((parent-is "declaration_list") parent-bol c-ts-mode-indent-offset)))
155 ((parent-is "field_declaration_list") parent-bol c-ts-mode-indent-offset) 162 ((parent-is "field_declaration_list") parent-bol c-ts-mode-indent-offset)
156 ((parent-is "initializer_list") parent-bol c-ts-mode-indent-offset) 163 ((parent-is "initializer_list") parent-bol c-ts-mode-indent-offset)
157 ((parent-is "if_statement") parent-bol c-ts-mode-indent-offset) 164 ((parent-is "if_statement") parent-bol c-ts-mode-indent-offset)
@@ -167,7 +174,12 @@ MODE is either `c' or `cpp'."
167 ((match "while" "do_statement") parent 0) 174 ((match "while" "do_statement") parent 0)
168 ,@common) 175 ,@common)
169 (k&r ,@common) 176 (k&r ,@common)
170 (linux ,@common) 177 (linux
178 ;; Reference:
179 ;; https://www.kernel.org/doc/html/latest/process/coding-style.html,
180 ;; and script/Lindent in Linux kernel repository.
181 ((node-is "labeled_statement") point-min 0)
182 ,@common)
171 (bsd 183 (bsd
172 ((parent-is "if_statement") parent-bol 0) 184 ((parent-is "if_statement") parent-bol 0)
173 ((parent-is "for_statement") parent-bol 0) 185 ((parent-is "for_statement") parent-bol 0)
@@ -190,6 +202,17 @@ MODE is either `c' or `cpp'."
190 ('linux (alist-get 'linux (c-ts-mode--indent-styles mode))))))) 202 ('linux (alist-get 'linux (c-ts-mode--indent-styles mode)))))))
191 `((,mode ,@style)))) 203 `((,mode ,@style))))
192 204
205(defun c-ts-mode--top-level-label-matcher (node &rest _)
206 "A matcher that matches a top-level label.
207NODE should be a labeled_statement."
208 (let ((func (treesit-parent-until
209 node (lambda (n)
210 (equal (treesit-node-type n)
211 "function_definition")))))
212 (and (equal (treesit-node-type node)
213 "labeled_statement")
214 (not (treesit-node-top-level func "function_definition")))))
215
193(defun c-ts-mode--bracket-children-anchor (_n parent &rest _) 216(defun c-ts-mode--bracket-children-anchor (_n parent &rest _)
194 "This anchor is used for children of a compound_statement. 217 "This anchor is used for children of a compound_statement.
195So anything inside a {} block. PARENT should be the 218So anything inside a {} block. PARENT should be the
@@ -205,11 +228,10 @@ beginning of grandparent."
205 (treesit-node-parent parent) 228 (treesit-node-parent parent)
206 parent))))) 229 parent)))))
207 230
208(defun c-ts-mode--looking-at-star (&rest _) 231(defun c-ts-mode--looking-at-star (_n _p bol &rest _)
209 "A tree-sitter simple indent matcher. 232 "A tree-sitter simple indent matcher.
210Matches if there is a \"*\" after point (ignoring whitespace in 233Matches if there is a \"*\" after BOL."
211between)." 234 (eq (char-after bol) ?*))
212 (looking-at (rx (* (syntax whitespace)) "*")))
213 235
214(defun c-ts-mode--comment-start-after-first-star (_n parent &rest _) 236(defun c-ts-mode--comment-start-after-first-star (_n parent &rest _)
215 "A tree-sitter simple indent anchor. 237 "A tree-sitter simple indent anchor.
@@ -221,6 +243,35 @@ Assumes PARENT is a comment node."
221 (match-end 0) 243 (match-end 0)
222 (point)))) 244 (point))))
223 245
246(defun c-ts-mode--comment-2nd-line-matcher (_n parent &rest _)
247 "Matches if point is at the second line of a block comment.
248PARENT should be a comment node."
249 (and (equal (treesit-node-type parent) "comment")
250 (save-excursion
251 (forward-line -1)
252 (back-to-indentation)
253 (eq (point) (treesit-node-start parent)))))
254
255(defun c-ts-mode--comment-2nd-line-anchor (&rest _)
256 "Return appropriate anchor for the second line of a comment.
257
258If the first line is /* alone, return the position right after
259the star; if the first line is /* followed by some text, return
260the position right before the text minus 1.
261
262Use an offset of 1 with this anchor."
263 (save-excursion
264 (forward-line -1)
265 (back-to-indentation)
266 (when (looking-at comment-start-skip)
267 (goto-char (match-end 0))
268 (if (looking-at (rx (* (or " " "\t")) eol))
269 ;; Only /* at the first line.
270 (progn (skip-chars-backward " \t")
271 (point))
272 ;; There is something after /* at the first line.
273 (1- (point))))))
274
224;;; Font-lock 275;;; Font-lock
225 276
226(defvar c-ts-mode--preproc-keywords 277(defvar c-ts-mode--preproc-keywords
@@ -419,20 +470,29 @@ MODE is either `c' or `cpp'."
419 470
420;;; Font-lock helpers 471;;; Font-lock helpers
421 472
422(defun c-ts-mode--declarator-identifier (node) 473(defun c-ts-mode--declarator-identifier (node &optional qualified)
423 "Return the identifier of the declarator node NODE." 474 "Return the identifier of the declarator node NODE.
475
476If QUALIFIED is non-nil, include the names space part of the
477identifier and return a qualified_identifier."
424 (pcase (treesit-node-type node) 478 (pcase (treesit-node-type node)
425 ;; Recurse. 479 ;; Recurse.
426 ((or "attributed_declarator" "parenthesized_declarator") 480 ((or "attributed_declarator" "parenthesized_declarator")
427 (c-ts-mode--declarator-identifier (treesit-node-child node 0 t))) 481 (c-ts-mode--declarator-identifier (treesit-node-child node 0 t)
482 qualified))
428 ((or "pointer_declarator" "reference_declarator") 483 ((or "pointer_declarator" "reference_declarator")
429 (c-ts-mode--declarator-identifier (treesit-node-child node -1))) 484 (c-ts-mode--declarator-identifier (treesit-node-child node -1)
485 qualified))
430 ((or "function_declarator" "array_declarator" "init_declarator") 486 ((or "function_declarator" "array_declarator" "init_declarator")
431 (c-ts-mode--declarator-identifier 487 (c-ts-mode--declarator-identifier
432 (treesit-node-child-by-field-name node "declarator"))) 488 (treesit-node-child-by-field-name node "declarator")
489 qualified))
433 ("qualified_identifier" 490 ("qualified_identifier"
434 (c-ts-mode--declarator-identifier 491 (if qualified
435 (treesit-node-child-by-field-name node "name"))) 492 node
493 (c-ts-mode--declarator-identifier
494 (treesit-node-child-by-field-name node "name")
495 qualified)))
436 ;; Terminal case. 496 ;; Terminal case.
437 ((or "identifier" "field_identifier") 497 ((or "identifier" "field_identifier")
438 node))) 498 node)))
@@ -534,9 +594,11 @@ Return nil if NODE is not a defun node or doesn't have a name."
534 (pcase (treesit-node-type node) 594 (pcase (treesit-node-type node)
535 ((or "function_definition" "declaration") 595 ((or "function_definition" "declaration")
536 (c-ts-mode--declarator-identifier 596 (c-ts-mode--declarator-identifier
537 (treesit-node-child-by-field-name node "declarator"))) 597 (treesit-node-child-by-field-name node "declarator")
598 t))
538 ((or "struct_specifier" "enum_specifier" 599 ((or "struct_specifier" "enum_specifier"
539 "union_specifier" "class_specifier") 600 "union_specifier" "class_specifier"
601 "namespace_definition")
540 (treesit-node-child-by-field-name node "name"))) 602 (treesit-node-child-by-field-name node "name")))
541 t)) 603 t))
542 604
@@ -568,6 +630,23 @@ Ie, NODE is not nested."
568 node "declarator")) 630 node "declarator"))
569 "function_declarator"))))) 631 "function_declarator")))))
570 632
633(defun c-ts-mode--defun-for-class-in-imenu-p (node)
634 "Check if NODE is a valid entry for the Class subindex.
635
636Basically, if NODE is a class, return non-nil; if NODE is a
637function but is under a class, return non-nil; if NODE is a
638top-level function, return nil.
639
640This is for the Class subindex in
641`treesit-simple-imenu-settings'."
642 (pcase (treesit-node-type node)
643 ;; The Class subindex only has class_specifier and
644 ;; function_definition.
645 ("class_specifier" t)
646 ("function_definition"
647 ;; Return t if this function is nested in a class.
648 (treesit-node-top-level node "class_specifier"))))
649
571(defun c-ts-mode--defun-skipper () 650(defun c-ts-mode--defun-skipper ()
572 "Custom defun skipper for `c-ts-mode' and friends. 651 "Custom defun skipper for `c-ts-mode' and friends.
573Structs in C ends with a semicolon, but the semicolon is not 652Structs in C ends with a semicolon, but the semicolon is not
@@ -741,7 +820,8 @@ Set up:
741 "struct_specifier" 820 "struct_specifier"
742 "enum_specifier" 821 "enum_specifier"
743 "union_specifier" 822 "union_specifier"
744 "class_specifier")) 823 "class_specifier"
824 "namespace_definition"))
745 #'c-ts-mode--defun-valid-p)) 825 #'c-ts-mode--defun-valid-p))
746 (setq-local treesit-defun-skipper #'c-ts-mode--defun-skipper) 826 (setq-local treesit-defun-skipper #'c-ts-mode--defun-skipper)
747 (setq-local treesit-defun-name-function #'c-ts-mode--defun-name) 827 (setq-local treesit-defun-name-function #'c-ts-mode--defun-name)
@@ -772,7 +852,7 @@ Set up:
772 ("Class" ,(rx bos (or "class_specifier" 852 ("Class" ,(rx bos (or "class_specifier"
773 "function_definition") 853 "function_definition")
774 eos) 854 eos)
775 ,pred nil)))) 855 c-ts-mode--defun-for-class-in-imenu-p nil))))
776 856
777 (setq-local treesit-font-lock-feature-list 857 (setq-local treesit-font-lock-feature-list
778 '(( comment definition) 858 '(( comment definition)
@@ -782,49 +862,49 @@ Set up:
782 862
783;;;###autoload 863;;;###autoload
784(define-derived-mode c-ts-mode c-ts-base-mode "C" 864(define-derived-mode c-ts-mode c-ts-base-mode "C"
785 "Major mode for editing C, powered by tree-sitter." 865 "Major mode for editing C, powered by tree-sitter.
786 :group 'c
787
788 (unless (treesit-ready-p 'c)
789 (error "Tree-sitter for C isn't available"))
790
791 (treesit-parser-create 'c)
792
793 ;; Comments.
794 (setq-local comment-start "/* ")
795 (setq-local comment-end " */")
796
797 (setq-local treesit-simple-indent-rules
798 (c-ts-mode--set-indent-style 'c))
799 866
800 ;; Font-lock. 867This mode is independent from the classic cc-mode.el based
801 (setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'c)) 868`c-mode', so configuration variables of that mode, like
869`c-basic-offset', don't affect this mode."
870 :group 'c
802 871
803 (treesit-major-mode-setup)) 872 (when (treesit-ready-p 'c)
873 (treesit-parser-create 'c)
874 ;; Comments.
875 (setq-local comment-start "/* ")
876 (setq-local comment-end " */")
877 ;; Indent.
878 (setq-local treesit-simple-indent-rules
879 (c-ts-mode--set-indent-style 'c))
880 ;; Font-lock.
881 (setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'c))
882 (treesit-major-mode-setup)))
804 883
805;;;###autoload 884;;;###autoload
806(define-derived-mode c++-ts-mode c-ts-base-mode "C++" 885(define-derived-mode c++-ts-mode c-ts-base-mode "C++"
807 "Major mode for editing C++, powered by tree-sitter." 886 "Major mode for editing C++, powered by tree-sitter."
808 :group 'c++ 887 :group 'c++
809 888
810 (unless (treesit-ready-p 'cpp) 889 (when (treesit-ready-p 'cpp)
811 (error "Tree-sitter for C++ isn't available")) 890 (setq-local treesit-text-type-regexp
891 (regexp-opt '("comment"
892 "raw_string_literal")))
812 893
813 (setq-local treesit-text-type-regexp 894 (treesit-parser-create 'cpp)
814 (regexp-opt '("comment"
815 "raw_string_literal")))
816 895
817 (treesit-parser-create 'cpp) 896 ;; Syntax.
818 (setq-local syntax-propertize-function 897 (setq-local syntax-propertize-function
819 #'c-ts-mode--syntax-propertize) 898 #'c-ts-mode--syntax-propertize)
820 899
821 (setq-local treesit-simple-indent-rules 900 ;; Indent.
822 (c-ts-mode--set-indent-style 'cpp)) 901 (setq-local treesit-simple-indent-rules
902 (c-ts-mode--set-indent-style 'cpp))
823 903
824 ;; Font-lock. 904 ;; Font-lock.
825 (setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'cpp)) 905 (setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'cpp))
826 906
827 (treesit-major-mode-setup)) 907 (treesit-major-mode-setup)))
828 908
829(provide 'c-ts-mode) 909(provide 'c-ts-mode)
830 910
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index d84c4f8ad8a..4dcc3e0ade9 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -2530,8 +2530,8 @@ higher."
2530 (get-text-property (match-beginning 0) 'fontified) 2530 (get-text-property (match-beginning 0) 'fontified)
2531 (not (memq (c-get-char-property (match-beginning 0) 'face) 2531 (not (memq (c-get-char-property (match-beginning 0) 'face)
2532 c-literal-faces))) 2532 c-literal-faces)))
2533 (c-put-font-lock-face (match-beginning 0) (match-end 0) 2533 (put-text-property (match-beginning 0) (match-end 0)
2534 font-lock-type-face)) 2534 'fontified nil))
2535 (dolist (win-boundary window-boundaries) 2535 (dolist (win-boundary window-boundaries)
2536 (when (and (< (match-beginning 0) (cdr win-boundary)) 2536 (when (and (< (match-beginning 0) (cdr win-boundary))
2537 (> (match-end 0) (car win-boundary)) 2537 (> (match-end 0) (car win-boundary))
diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el
index 1d6a8a30db5..64e761d2f72 100644
--- a/lisp/progmodes/go-ts-mode.el
+++ b/lisp/progmodes/go-ts-mode.el
@@ -36,6 +36,7 @@
36(declare-function treesit-node-child-by-field-name "treesit.c") 36(declare-function treesit-node-child-by-field-name "treesit.c")
37(declare-function treesit-node-start "treesit.c") 37(declare-function treesit-node-start "treesit.c")
38(declare-function treesit-node-type "treesit.c") 38(declare-function treesit-node-type "treesit.c")
39(declare-function treesit-search-subtree "treesit.c")
39 40
40(defcustom go-ts-mode-indent-offset 4 41(defcustom go-ts-mode-indent-offset 4
41 "Number of spaces for each indentation step in `go-ts-mode'." 42 "Number of spaces for each indentation step in `go-ts-mode'."
@@ -173,44 +174,6 @@
173 '((ERROR) @font-lock-warning-face)) 174 '((ERROR) @font-lock-warning-face))
174 "Tree-sitter font-lock settings for `go-ts-mode'.") 175 "Tree-sitter font-lock settings for `go-ts-mode'.")
175 176
176(defun go-ts-mode--imenu ()
177 "Return Imenu alist for the current buffer."
178 (let* ((node (treesit-buffer-root-node))
179 (func-tree (treesit-induce-sparse-tree
180 node "function_declaration" nil 1000))
181 (type-tree (treesit-induce-sparse-tree
182 node "type_spec" nil 1000))
183 (func-index (go-ts-mode--imenu-1 func-tree))
184 (type-index (go-ts-mode--imenu-1 type-tree)))
185 (append
186 (when func-index `(("Function" . ,func-index)))
187 (when type-index `(("Type" . ,type-index))))))
188
189(defun go-ts-mode--imenu-1 (node)
190 "Helper for `go-ts-mode--imenu'.
191Find string representation for NODE and set marker, then recurse
192the subtrees."
193 (let* ((ts-node (car node))
194 (children (cdr node))
195 (subtrees (mapcan #'go-ts-mode--imenu-1
196 children))
197 (name (when ts-node
198 (treesit-node-text
199 (pcase (treesit-node-type ts-node)
200 ("function_declaration"
201 (treesit-node-child-by-field-name ts-node "name"))
202 ("type_spec"
203 (treesit-node-child-by-field-name ts-node "name"))))))
204 (marker (when ts-node
205 (set-marker (make-marker)
206 (treesit-node-start ts-node)))))
207 (cond
208 ((or (null ts-node) (null name)) subtrees)
209 (subtrees
210 `((,name ,(cons name marker) ,@subtrees)))
211 (t
212 `((,name . ,marker))))))
213
214;;;###autoload 177;;;###autoload
215(add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode)) 178(add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode))
216 179
@@ -228,14 +191,30 @@ the subtrees."
228 (setq-local comment-end "") 191 (setq-local comment-end "")
229 (setq-local comment-start-skip (rx "//" (* (syntax whitespace)))) 192 (setq-local comment-start-skip (rx "//" (* (syntax whitespace))))
230 193
194 ;; Navigation.
195 (setq-local treesit-defun-type-regexp
196 (regexp-opt '("method_declaration"
197 "function_declaration"
198 "type_declaration")))
199 (setq-local treesit-defun-name-function #'go-ts-mode--defun-name)
200
231 ;; Imenu. 201 ;; Imenu.
232 (setq-local imenu-create-index-function #'go-ts-mode--imenu) 202 (setq-local treesit-simple-imenu-settings
233 (setq-local which-func-functions nil) 203 `(("Function" "\\`function_declaration\\'" nil nil)
204 ("Method" "\\`method_declaration\\'" nil nil)
205 ("Struct" "\\`type_declaration\\'" go-ts-mode--struct-node-p nil)
206 ("Interface" "\\`type_declaration\\'" go-ts-mode--interface-node-p nil)
207 ("Type" "\\`type_declaration\\'" go-ts-mode--other-type-node-p nil)
208 ("Alias" "\\`type_declaration\\'" go-ts-mode--alias-node-p nil)))
234 209
235 ;; Indent. 210 ;; Indent.
236 (setq-local indent-tabs-mode t 211 (setq-local indent-tabs-mode t
237 treesit-simple-indent-rules go-ts-mode--indent-rules) 212 treesit-simple-indent-rules go-ts-mode--indent-rules)
238 213
214 ;; Electric
215 (setq-local electric-indent-chars
216 (append "{}()" electric-indent-chars))
217
239 ;; Font-lock. 218 ;; Font-lock.
240 (setq-local treesit-font-lock-settings go-ts-mode--font-lock-settings) 219 (setq-local treesit-font-lock-settings go-ts-mode--font-lock-settings)
241 (setq-local treesit-font-lock-feature-list 220 (setq-local treesit-font-lock-feature-list
@@ -247,6 +226,54 @@ the subtrees."
247 226
248 (treesit-major-mode-setup))) 227 (treesit-major-mode-setup)))
249 228
229(defun go-ts-mode--defun-name (node)
230 "Return the defun name of NODE.
231Return nil if there is no name or if NODE is not a defun node."
232 (pcase (treesit-node-type node)
233 ("function_declaration"
234 (treesit-node-text
235 (treesit-node-child-by-field-name
236 node "name")
237 t))
238 ("method_declaration"
239 (let* ((receiver-node (treesit-node-child-by-field-name node "receiver"))
240 (type-node (treesit-search-subtree receiver-node "type_identifier"))
241 (name-node (treesit-node-child-by-field-name node "name")))
242 (concat
243 "(" (treesit-node-text type-node) ")."
244 (treesit-node-text name-node))))
245 ("type_declaration"
246 (treesit-node-text
247 (treesit-node-child-by-field-name
248 (treesit-node-child node 0 t) "name")
249 t))))
250
251(defun go-ts-mode--interface-node-p (node)
252 "Return t if NODE is an interface."
253 (and
254 (string-equal "type_declaration" (treesit-node-type node))
255 (treesit-search-subtree node "interface_type" nil nil 2)))
256
257(defun go-ts-mode--struct-node-p (node)
258 "Return t if NODE is a struct."
259 (and
260 (string-equal "type_declaration" (treesit-node-type node))
261 (treesit-search-subtree node "struct_type" nil nil 2)))
262
263(defun go-ts-mode--alias-node-p (node)
264 "Return t if NODE is a type alias."
265 (and
266 (string-equal "type_declaration" (treesit-node-type node))
267 (treesit-search-subtree node "type_alias" nil nil 1)))
268
269(defun go-ts-mode--other-type-node-p (node)
270 "Return t if NODE is a type, other than interface, struct or alias."
271 (and
272 (string-equal "type_declaration" (treesit-node-type node))
273 (not (go-ts-mode--interface-node-p node))
274 (not (go-ts-mode--struct-node-p node))
275 (not (go-ts-mode--alias-node-p node))))
276
250;; go.mod support. 277;; go.mod support.
251 278
252(defvar go-mod-ts-mode--syntax-table 279(defvar go-mod-ts-mode--syntax-table
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el
index 20692d6c8df..92e018aaec1 100644
--- a/lisp/progmodes/gud.el
+++ b/lisp/progmodes/gud.el
@@ -3561,8 +3561,9 @@ Treats actions as defuns."
3561 (kill-local-variable 'gdb-define-alist) 3561 (kill-local-variable 'gdb-define-alist)
3562 (remove-hook 'after-save-hook #'gdb-create-define-alist t)))) 3562 (remove-hook 'after-save-hook #'gdb-create-define-alist t))))
3563 3563
3564(defcustom gud-tooltip-modes '(gud-mode c-mode c++-mode fortran-mode 3564(defcustom gud-tooltip-modes '( gud-mode c-mode c++-mode fortran-mode
3565 python-mode) 3565 python-mode c-ts-mode c++-ts-mode
3566 python-ts-mode)
3566 "List of modes for which to enable GUD tooltips." 3567 "List of modes for which to enable GUD tooltips."
3567 :type '(repeat (symbol :tag "Major mode")) 3568 :type '(repeat (symbol :tag "Major mode"))
3568 :group 'tooltip) 3569 :group 'tooltip)
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index 881f4a83b17..902d4fa7ab3 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -3542,7 +3542,10 @@ This function is intended for use in `after-change-functions'."
3542 (identifier) 3542 (identifier)
3543 (identifier) 3543 (identifier)
3544 @font-lock-function-name-face) 3544 @font-lock-function-name-face)
3545 value: (array (number) (function)))) 3545 value: (array (number) (function)))
3546 (import_clause (identifier) @font-lock-variable-name-face)
3547 (import_clause (named_imports (import_specifier (identifier))
3548 @font-lock-variable-name-face)))
3546 3549
3547 :language 'javascript 3550 :language 'javascript
3548 :feature 'property 3551 :feature 'property
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index 730998727ce..dc87cb8e15d 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -1,7 +1,7 @@
1;;; project.el --- Operations on the current project -*- lexical-binding: t; -*- 1;;; project.el --- Operations on the current project -*- lexical-binding: t; -*-
2 2
3;; Copyright (C) 2015-2023 Free Software Foundation, Inc. 3;; Copyright (C) 2015-2023 Free Software Foundation, Inc.
4;; Version: 0.9.3 4;; Version: 0.9.4
5;; Package-Requires: ((emacs "26.1") (xref "1.4.0")) 5;; Package-Requires: ((emacs "26.1") (xref "1.4.0"))
6 6
7;; This is a GNU ELPA :core package. Avoid using functionality that 7;; This is a GNU ELPA :core package. Avoid using functionality that
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 59164d7d50c..21d16db287c 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -1067,11 +1067,28 @@ fontified."
1067 "expression_statement")) 1067 "expression_statement"))
1068 'font-lock-doc-face 1068 'font-lock-doc-face
1069 'font-lock-string-face))) 1069 'font-lock-string-face)))
1070 (when (eq (char-after string-beg) ?f) 1070 ;; Don't highlight string prefixes like f/r/b.
1071 (cl-incf string-beg)) 1071 (save-excursion
1072 (goto-char string-beg)
1073 (when (search-forward "\"" string-end t)
1074 (setq string-beg (match-beginning 0))))
1072 (treesit-fontify-with-override 1075 (treesit-fontify-with-override
1073 string-beg string-end face override start end))) 1076 string-beg string-end face override start end)))
1074 1077
1078(defun python--treesit-fontify-string-interpolation
1079 (node _ start end &rest _)
1080 "Fontify string interpolation.
1081NODE is the string node. Do not fontify the initial f for
1082f-strings. START and END mark the region to be
1083fontified."
1084 ;; This is kind of a hack, it basically removes the face applied by
1085 ;; the string feature, so that following features can apply their
1086 ;; face.
1087 (let ((n-start (treesit-node-start node))
1088 (n-end (treesit-node-end node)))
1089 (remove-text-properties
1090 (max start n-start) (min end n-end) '(face))))
1091
1075(defvar python--treesit-settings 1092(defvar python--treesit-settings
1076 (treesit-font-lock-rules 1093 (treesit-font-lock-rules
1077 :feature 'comment 1094 :feature 'comment
@@ -1082,10 +1099,12 @@ fontified."
1082 :language 'python 1099 :language 'python
1083 '((string) @python--treesit-fontify-string) 1100 '((string) @python--treesit-fontify-string)
1084 1101
1102 ;; HACK: This feature must come after the string feature and before
1103 ;; other features. Maybe we should make string-interpolation an
1104 ;; option rather than a feature.
1085 :feature 'string-interpolation 1105 :feature 'string-interpolation
1086 :language 'python 1106 :language 'python
1087 :override t 1107 '((interpolation) @python--treesit-fontify-string-interpolation)
1088 '((interpolation (identifier) @font-lock-variable-name-face))
1089 1108
1090 :feature 'definition 1109 :feature 'definition
1091 :language 'python 1110 :language 'python
@@ -3766,15 +3785,16 @@ the python shell:
3766 (line-beginning-position) 3785 (line-beginning-position)
3767 start)))) 3786 start))))
3768 (substring (buffer-substring-no-properties start end)) 3787 (substring (buffer-substring-no-properties start end))
3769 (starts-at-point-min-p (save-restriction 3788 (starts-at-first-line-p (save-restriction
3770 (widen) 3789 (widen)
3771 (= (point-min) start))) 3790 (goto-char start)
3791 (= (line-number-at-pos) 1)))
3772 (encoding (python-info-encoding)) 3792 (encoding (python-info-encoding))
3773 (toplevel-p (zerop (save-excursion 3793 (toplevel-p (zerop (save-excursion
3774 (goto-char start) 3794 (goto-char start)
3775 (python-util-forward-comment 1) 3795 (python-util-forward-comment 1)
3776 (current-indentation)))) 3796 (current-indentation))))
3777 (fillstr (cond (starts-at-point-min-p 3797 (fillstr (cond (starts-at-first-line-p
3778 nil) 3798 nil)
3779 ((not no-cookie) 3799 ((not no-cookie)
3780 (concat 3800 (concat
diff --git a/lisp/progmodes/ruby-ts-mode.el b/lisp/progmodes/ruby-ts-mode.el
index 5f5de500435..d68b57966ba 100644
--- a/lisp/progmodes/ruby-ts-mode.el
+++ b/lisp/progmodes/ruby-ts-mode.el
@@ -82,6 +82,16 @@
82(require 'ruby-mode) 82(require 'ruby-mode)
83 83
84(declare-function treesit-parser-create "treesit.c") 84(declare-function treesit-parser-create "treesit.c")
85(declare-function treesit-induce-sparse-tree "treesit.c")
86(declare-function treesit-node-child-by-field-name "treesit.c")
87(declare-function treesit-search-subtree "treesit.c")
88(declare-function treesit-node-parent "treesit.c")
89(declare-function treesit-node-next-sibling "treesit.c")
90(declare-function treesit-node-type "treesit.c")
91(declare-function treesit-node-child "treesit.c")
92(declare-function treesit-node-end "treesit.c")
93(declare-function treesit-node-start "treesit.c")
94(declare-function treesit-node-string "treesit.c")
85 95
86(defgroup ruby-ts nil 96(defgroup ruby-ts nil
87 "Major mode for editing Ruby code." 97 "Major mode for editing Ruby code."
@@ -304,7 +314,12 @@ values of OVERRIDE"
304 (array_pattern 314 (array_pattern
305 (identifier) @font-lock-variable-name-face) 315 (identifier) @font-lock-variable-name-face)
306 (keyword_pattern 316 (keyword_pattern
307 key: (hash_key_symbol) @font-lock-variable-name-face) 317 value: (identifier) @font-lock-variable-name-face)
318 (keyword_pattern
319 key: (hash_key_symbol) @font-lock-variable-name-face
320 !value)
321 (as_pattern
322 name: (identifier) @font-lock-variable-name-face)
308 (in_clause 323 (in_clause
309 pattern: (identifier) @font-lock-variable-name-face)) 324 pattern: (identifier) @font-lock-variable-name-face))
310 325
diff --git a/lisp/progmodes/typescript-ts-mode.el b/lisp/progmodes/typescript-ts-mode.el
index 0a79ae01248..0786150d906 100644
--- a/lisp/progmodes/typescript-ts-mode.el
+++ b/lisp/progmodes/typescript-ts-mode.el
@@ -194,7 +194,13 @@ Argument LANGUAGE is either `typescript' or `tsx'."
194 name: (array_pattern 194 name: (array_pattern
195 (identifier) 195 (identifier)
196 (identifier) @font-lock-function-name-face) 196 (identifier) @font-lock-function-name-face)
197 value: (array (number) (function)))) 197 value: (array (number) (function)))
198
199 (catch_clause
200 parameter: (identifier) @font-lock-variable-name-face)
201
202 (import_clause (identifier) @font-lock-variable-name-face)
203 (import_clause (named_imports (import_specifier (identifier)) @font-lock-variable-name-face)))
198 204
199 :language language 205 :language language
200 :override t 206 :override t
@@ -223,17 +229,7 @@ Argument LANGUAGE is either `typescript' or `tsx'."
223 parameters: 229 parameters:
224 [(_ (identifier) @font-lock-variable-name-face) 230 [(_ (identifier) @font-lock-variable-name-face)
225 (_ (_ (identifier) @font-lock-variable-name-face)) 231 (_ (_ (identifier) @font-lock-variable-name-face))
226 (_ (_ (_ (identifier) @font-lock-variable-name-face)))]) 232 (_ (_ (_ (identifier) @font-lock-variable-name-face)))]))
227
228 (return_statement (identifier) @font-lock-variable-name-face)
229
230 (binary_expression left: (identifier) @font-lock-variable-name-face)
231 (binary_expression right: (identifier) @font-lock-variable-name-face)
232
233 (arguments (identifier) @font-lock-variable-name-face)
234
235 (parenthesized_expression (identifier) @font-lock-variable-name-face)
236 (parenthesized_expression (_ (identifier) @font-lock-variable-name-face)))
237 233
238 :language language 234 :language language
239 :override t 235 :override t
@@ -245,8 +241,6 @@ Argument LANGUAGE is either `typescript' or `tsx'."
245 241
246 (pair key: (property_identifier) @font-lock-variable-name-face) 242 (pair key: (property_identifier) @font-lock-variable-name-face)
247 243
248 (pair value: (identifier) @font-lock-variable-name-face)
249
250 ((shorthand_property_identifier) @font-lock-property-face) 244 ((shorthand_property_identifier) @font-lock-property-face)
251 245
252 ((shorthand_property_identifier_pattern) 246 ((shorthand_property_identifier_pattern)
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index d5cee9fa84f..916d83d407b 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -1,7 +1,7 @@
1;;; xref.el --- Cross-referencing commands -*-lexical-binding:t-*- 1;;; xref.el --- Cross-referencing commands -*-lexical-binding:t-*-
2 2
3;; Copyright (C) 2014-2023 Free Software Foundation, Inc. 3;; Copyright (C) 2014-2023 Free Software Foundation, Inc.
4;; Version: 1.6.0 4;; Version: 1.6.1
5;; Package-Requires: ((emacs "26.1")) 5;; Package-Requires: ((emacs "26.1"))
6 6
7;; This is a GNU ELPA :core package. Avoid functionality that is not 7;; This is a GNU ELPA :core package. Avoid functionality that is not