1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-19 12:20:17 -08:00

Merge from origin/emacs-29

db96b1282f * lisp/help.el: Use 'C-h C-q' to toggle 'help-quick' wind...
489865c21e ; Improve markup of long key sequences
d42c2668cf ; * etc/NEWS: Fix wording of a recently edited entry.
7a0eaee198 * lisp/isearch.el: Small fixes.
b69bffeec0 * lisp/vc/diff-mode.el (diff-minor-mode-prefix): Replace ...
9263847ab7 ; * etc/NEWS: Move the paragraph with 'C-u RET' closer to...
62fb2dc37d * doc/emacs/display.texi (Text Scale): Improve section ab...
70480d3b6b * lisp/repeat.el (repeat-echo-function): Suggest 'add-fun...
fd48201ffe * lisp/tab-line.el (tab-line-cache-key-default): More cac...
b164660260 * etc/package-keyring.gpg: Update with new key
c0be51389e ; Yet another declare-function to avoid treesit-related w...
8676bec51d ; * lisp/treesit.el (treesit--simple-imenu-1): Doc fix; w...
2ddc480f44 Warn of absent networks module in ERC
19d00fab9a Avoid "already compiled" warning in erc-compat
2d8f7b66bc ; Fix one more treesit byte-compilation warning.
2d0a921486 ; Avoid treesit-related byte-compiler warnings
8503b370be (python--treesit-settings): Remove duplicate matcher
b464e6c490 Make last change of w32 GUI dialogs conditional and rever...
eedc9d79ae Fix tree-sitter typos
248c13dcfe Update tree-sitter major modes to use the new Imenu facility
b39dc7ab27 Add tree-sitter helper functions for Imenu
ba1ddea9da Fix treesit--things-around (bug#60355)
7512b9025a ; * lisp/treesit.el (treesit-traverse-parent): Remove alias.
5326b04198 Improve treesit-node-top-level and treesit-parent-until
637f5b164f ; Add "src" to the heuristic sub-directory heuristic
8ab6df0c9f ; * lisp/epa-ks.el (epa-ks-do-key-to-fetch): Fix 'when' u...
2b55a48d3e * src/w32menu.c (simple_dialog_show): Use MB_YESNOCANCEL ...
8b8b791567 ; Improve documentation of TAB/SPC indentation
624e382211 ; Improve doc strings of some new faces
41f12e1019 ; * lisp/elide-head.el (elide-head): Doc fix to silence c...
e3b4cd0ac1 ; * lisp/htmlfontify.el (hfy-text-p): Fix whitespace.
1b4dc4691c Fix htmlfontify.el command injection vulnerability.
1fe4b98b4d Improve support for Scheme R6RS and R7RS libraries (bug#5...
2347f37f67 ; * test/src/treesit-tests.el: remove dead store (bytecom...
a6d961ae2f Add a new tree-sitter query predicate 'pred'
835a80dcc4 ; Fix tree-sitter defun tests
a14821d615 Improve gnutls-min-prime-bits docstring
b14bbd108e Improve handling of tab-bar height.
669160d47b ; * nt/INSTALL.W64: More fixes and updates.
26b2ec7cb8 Simplify last change (bug#60311)
082fc6e308 Fix 'json-available-p' on MS-Windows
6c86faec29 loaddefs-gen: Group results by absolute file name
d90d7d15f2 ; Fix vindexes in parsing.texi
eb26872837 Fix imenu for c-ts-mode (bug#60296)
8f68b6497e Clean up python-ts-mode font-lock features
28f26b11a1 Add comment indent and filling to other tree-sitter major...
c6b0282645 ; Remove unused function in c-ts-mode
6e52a9fcad ; * doc/lispref/modes.texi (Parser-based Font Lock): Mino...
2bcd1e9a99 ; * doc/lispref/parsing.texi (Retrieving Nodes): Add notice.
7c7950fe00 Add maintainer stub for tree-sitter files
cf32776622 ; * doc/lispref/parsing.texi (Using Parser): Remove delet...

# Conflicts:
#	etc/NEWS
#	lisp/progmodes/c-ts-mode.el
#	lisp/progmodes/typescript-ts-mode.el
#	lisp/treesit.el
This commit is contained in:
Stefan Kangas 2022-12-28 21:40:59 +01:00
commit dce6791e99
50 changed files with 945 additions and 813 deletions

View file

@ -487,92 +487,44 @@ For NODE, OVERRIDE, START, and END, see
(defun c-ts-mode--defun-name (node)
"Return the name of the defun NODE.
Return nil if NODE is not a defun node, return an empty string if
NODE doesn't have a name."
Return nil if NODE is not a defun node or doesn't have a name."
(treesit-node-text
(pcase (treesit-node-type node)
((or "function_definition" "declaration")
(c-ts-mode--declarator-identifier
(treesit-node-child-by-field-name node "declarator")))
("struct_specifier"
((or "struct_specifier" "enum_specifier"
"union_specifier" "class_specifier")
(treesit-node-child-by-field-name node "name")))
t))
(defun c-ts-mode--imenu-1 (node)
"Helper for `c-ts-mode--imenu'.
Find string representation for NODE and set marker, then recurse
the subtrees."
(let* ((ts-node (car node))
(subtrees (mapcan #'c-ts-mode--imenu-1 (cdr node)))
(name (when ts-node
(treesit-defun-name ts-node)))
(marker (when ts-node
(set-marker (make-marker)
(treesit-node-start ts-node)))))
(cond
;; A struct_specifier could be inside a parameter list, another
;; struct definition, a variable declaration, a function
;; declaration. In those cases we don't include it.
((string-match-p
(rx (or "parameter_declaration" "field_declaration"
"declaration" "function_definition"))
(or (treesit-node-type (treesit-node-parent ts-node))
""))
nil)
;; Ignore function local variable declarations.
((and (equal (treesit-node-type ts-node) "declaration")
(not (equal (treesit-node-type (treesit-node-parent ts-node))
"translation_unit")))
nil)
((or (null ts-node) (null name)) subtrees)
(subtrees
`((,name ,(cons name marker) ,@subtrees)))
(t
`((,name . ,marker))))))
(defun c-ts-mode--imenu ()
"Return Imenu alist for the current buffer."
(let* ((node (treesit-buffer-root-node))
(func-tree (treesit-induce-sparse-tree
node "^function_definition$" nil 1000))
(var-tree (treesit-induce-sparse-tree
node "^declaration$" nil 1000))
(struct-tree (treesit-induce-sparse-tree
node "^struct_specifier$" nil 1000))
(func-index (c-ts-mode--imenu-1 func-tree))
(var-index (c-ts-mode--imenu-1 var-tree))
(struct-index (c-ts-mode--imenu-1 struct-tree)))
(append
(when struct-index `(("Struct" . ,struct-index)))
(when var-index `(("Variable" . ,var-index)))
(when func-index `(("Function" . ,func-index))))))
;;; Defun navigation
(defun c-ts-mode--end-of-defun ()
"`end-of-defun-function' of `c-ts-mode'."
;; A struct/enum/union_specifier node doesn't include the ; at the
;; end, so we manually skip it.
(treesit-end-of-defun)
(when (looking-at (rx (* " ") ";"))
(goto-char (match-end 0))
;; This part is copied from `end-of-defun'.
(unless (bolp)
(skip-chars-forward " \t")
(if (looking-at "\\s<\\|\n")
(forward-line 1)))))
(defun c-ts-mode--defun-valid-p (node)
(if (string-match-p
(rx (or "struct_specifier"
"enum_specifier"
"union_specifier"))
(treesit-node-type node))
(null
(treesit-node-top-level
node (rx (or "function_definition"
"type_definition"))))
t))
"Return non-nil if NODE is a valid defun node.
Ie, NODE is not nested."
(not (or (and (member (treesit-node-type node)
'("struct_specifier"
"enum_specifier"
"union_specifier"
"declaration"))
;; If NODE's type is one of the above, make sure it is
;; top-level.
(treesit-node-top-level
node (rx (or "function_definition"
"type_definition"
"struct_specifier"
"enum_specifier"
"union_specifier"
"declaration"))))
(and (equal (treesit-node-type node) "declaration")
;; If NODE is a declaration, make sure it is not a
;; function declaration.
(equal (treesit-node-type
(treesit-node-child-by-field-name
node "declarator"))
"function_declarator")))))
(defun c-ts-mode--defun-skipper ()
"Custom defun skipper for `c-ts-mode' and friends.
@ -660,6 +612,59 @@ ARG is passed to `fill-paragraph'."
;; itself.
t)))
(defun c-ts-mode-comment-setup ()
"Set up local variables for C-like comment.
Set up:
- `comment-start'
- `comment-end'
- `comment-start-skip'
- `comment-end-skip'
- `adaptive-fill-mode'
- `adaptive-fill-first-line-regexp'
- `paragraph-start'
- `paragraph-separate'
- `fill-paragraph-function'"
(setq-local comment-start "// ")
(setq-local comment-end "")
(setq-local comment-start-skip (rx (or (seq "/" (+ "/"))
(seq "/" (+ "*")))
(* (syntax whitespace))))
(setq-local comment-end-skip
(rx (* (syntax whitespace))
(group (or (syntax comment-end)
(seq (+ "*") "/")))))
(setq-local adaptive-fill-mode t)
;; This matches (1) empty spaces (the default), (2) "//", (3) "*",
;; but do not match "/*", because we don't want to use "/*" as
;; prefix when filling. (Actually, it doesn't matter, because
;; `comment-start-skip' matches "/*" which will cause
;; `fill-context-prefix' to use "/*" as a prefix for filling, that's
;; why we mask the "/*" in `c-ts-mode--fill-paragraph'.)
(setq-local adaptive-fill-regexp
(concat (rx (* (syntax whitespace))
(group (or (seq "/" (+ "/")) (* "*"))))
adaptive-fill-regexp))
;; Same as `adaptive-fill-regexp'.
(setq-local adaptive-fill-first-line-regexp
(rx bos
(seq (* (syntax whitespace))
(group (or (seq "/" (+ "/")) (* "*")))
(* (syntax whitespace)))
eos))
;; Same as `adaptive-fill-regexp'.
(setq-local paragraph-start
(rx (or (seq (* (syntax whitespace))
(group (or (seq "/" (+ "/")) (* "*")))
(* (syntax whitespace))
;; Add this eol so that in
;; `fill-context-prefix', `paragraph-start'
;; doesn't match the prefix.
eol)
"\f")))
(setq-local paragraph-separate paragraph-start)
(setq-local fill-paragraph-function #'c-ts-mode--fill-paragraph))
;;; Modes
(defvar-keymap c-ts-mode-map
@ -694,44 +699,25 @@ ARG is passed to `fill-paragraph'."
(when (eq c-ts-mode-indent-style 'linux)
(setq-local indent-tabs-mode t))
(setq-local adaptive-fill-mode t)
;; This matches (1) empty spaces (the default), (2) "//", (3) "*",
;; but do not match "/*", because we don't want to use "/*" as
;; prefix when filling. (Actually, it doesn't matter, because
;; `comment-start-skip' matches "/*" which will cause
;; `fill-context-prefix' to use "/*" as a prefix for filling, that's
;; why we mask the "/*" in `c-ts-mode--fill-paragraph'.)
(setq-local adaptive-fill-regexp
(concat (rx (* (syntax whitespace))
(group (or (seq "/" (+ "/")) (* "*"))))
adaptive-fill-regexp))
;; Same as `adaptive-fill-regexp'.
(setq-local adaptive-fill-first-line-regexp
(rx bos
(seq (* (syntax whitespace))
(group (or (seq "/" (+ "/")) (* "*")))
(* (syntax whitespace)))
eos))
;; Same as `adaptive-fill-regexp'.
(setq-local paragraph-start
(rx (or (seq (* (syntax whitespace))
(group (or (seq "/" (+ "/")) (* "*")))
(* (syntax whitespace))
;; Add this eol so that in
;; `fill-context-prefix', `paragraph-start'
;; doesn't match the prefix.
eol)
"\f")))
(setq-local paragraph-separate paragraph-start)
(setq-local fill-paragraph-function #'c-ts-mode--fill-paragraph)
;; Comment
(c-ts-mode-comment-setup)
;; Electric
(setq-local electric-indent-chars
(append "{}():;," electric-indent-chars))
;; Imenu.
(setq-local imenu-create-index-function #'c-ts-mode--imenu)
(setq-local which-func-functions nil)
(setq-local treesit-simple-imenu-settings
(let ((pred #'c-ts-mode--defun-valid-p))
`(("Struct" ,(rx bos (or "struct" "enum" "union")
"_specifier" eos)
,pred nil)
("Variable" ,(rx bos "declaration" eos) ,pred nil)
("Function" "\\`function_definition\\'" ,pred nil)
("Class" ,(rx bos (or "class_specifier"
"function_definition")
eos)
,pred nil))))
(setq-local treesit-font-lock-feature-list
'(( comment definition)
@ -752,13 +738,6 @@ ARG is passed to `fill-paragraph'."
;; Comments.
(setq-local comment-start "/* ")
(setq-local comment-end " */")
(setq-local comment-start-skip (rx (or (seq "/" (+ "/"))
(seq "/" (+ "*")))
(* (syntax whitespace))))
(setq-local comment-end-skip
(rx (* (syntax whitespace))
(group (or (syntax comment-end)
(seq (+ "*") "/")))))
(setq-local treesit-simple-indent-rules
(c-ts-mode--set-indent-style 'c))
@ -766,11 +745,7 @@ ARG is passed to `fill-paragraph'."
;; Font-lock.
(setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'c))
(treesit-major-mode-setup)
;; Override default value of end-of-defun-function set by
;; `treesit-major-mode-setup'.
(setq-local end-of-defun-function #'c-ts-mode--end-of-defun))
(treesit-major-mode-setup))
;;;###autoload
(define-derived-mode c++-ts-mode c-ts-base-mode "C++"
@ -781,17 +756,6 @@ ARG is passed to `fill-paragraph'."
(unless (treesit-ready-p 'cpp)
(error "Tree-sitter for C++ isn't available"))
;; Comments.
(setq-local comment-start "// ")
(setq-local comment-end "")
(setq-local comment-start-skip (rx (or (seq "/" (+ "/"))
(seq "/" (+ "*")))
(* (syntax whitespace))))
(setq-local comment-end-skip
(rx (* (syntax whitespace))
(group (or (syntax comment-end)
(seq (+ "*") "/")))))
(setq-local treesit-text-type-regexp
(regexp-opt '("comment"
"raw_string_literal")))
@ -804,11 +768,7 @@ ARG is passed to `fill-paragraph'."
;; Font-lock.
(setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'cpp))
(treesit-major-mode-setup)
;; Override default value of end-of-defun-function set by
;; `treesit-major-mode-setup'.
(setq-local end-of-defun-function #'c-ts-mode--end-of-defun))
(treesit-major-mode-setup))
(provide 'c-ts-mode)