aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuan Fu2025-01-12 00:35:20 -0800
committerYuan Fu2025-01-12 21:27:41 -0800
commit7d3bc1ff2f44215ad24fdd8b243e7cee8ff66fa0 (patch)
treeac231ad06d342f013cb4e15169b0219dc25d090c
parente6591b549f35af1be31f5bf3547e1170b7604a99 (diff)
downloademacs-7d3bc1ff2f44215ad24fdd8b243e7cee8ff66fa0.tar.gz
emacs-7d3bc1ff2f44215ad24fdd8b243e7cee8ff66fa0.zip
Add newly supported keywords to c-ts-mode (bug#75226)
For the new keywords, test if the grammar supports them before useing it. * lisp/progmodes/c-ts-mode.el: (c-ts-mode--optional-c-keywords): New variable. (c-ts-mode--ms-keywords): New variable. (c-ts-mode--compute-optional-keywords): New function. (c-ts-mode--keywords): Add new optional keywords. (c-ts-mode--c++-operators): New variable. (c-ts-mode--c++-operator-keywords): New variable. (c-ts-mode--font-lock-settings): Use c-ts-mode--c++-operators.
-rw-r--r--lisp/progmodes/c-ts-mode.el77
1 files changed, 67 insertions, 10 deletions
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index dd08731edb4..f4f6bef2775 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -593,30 +593,76 @@ NODE, PARENT, BOL, ARGS are as usual."
593 "#else" "#elif" "#endif" "#include") 593 "#else" "#elif" "#endif" "#include")
594 "C/C++ keywords for tree-sitter font-locking.") 594 "C/C++ keywords for tree-sitter font-locking.")
595 595
596(defvar c-ts-mode--optional-c-keywords
597 ;; v0.20.4 actually contains all the new keywords I can find that
598 ;; aren't in c-ts-mode before. The version doesn't really matter, we
599 ;; just want a rough grouping so that we can enable as much keywords
600 ;; as possible.
601 '(("v0.20.4" . ("_Generic" "_Noreturn" "noreturn"
602 "__attribute__" "__restrict__"
603 "offsetof" "thread_local"))
604 ("v0.20.5" . ("__extension__" "__extension__"
605 "__forceinline" "__inline" "__inline__"
606 "__thread"
607 "__alignof__" "__alignof" "alignof" "_Alignof"))
608 ("v0.20.7" . ("__try" "__except" "__finally" "__leave"))
609 ;; GitHub release jumped from v0.20.7 to v0.23.1. There are
610 ;; intermediate git tags, but there aren't many keywords here, so I
611 ;; skipped intermediate versions too.
612 ("v0.23.1" ("_Nonnull" "__attribute"
613 "alignas" "_Alignas" "__asm" "__volatile__"))
614 ;; No changes to keywords in v0.23.2, v0.23.3, v0.23.4.
615 )
616 "Keywords added in each tree-sitter-c version.")
617
618(defvar c-ts-mode--ms-keywords
619 ;; For some reason, "__restrict" "__uptr" and "__sptr" are not
620 ;; recognized by the grammar, although being in grammar.js.
621 '("__declspec" "__based" "__cdecl" "__clrcall" "__stdcall"
622 "__fastcall" "__thiscall" "__vectorcall" "_unaligned" "__unaligned")
623 "MSVC keywords.")
624
625(defun c-ts-mode--compute-optional-keywords (mode)
626 "Return a list of keywords that are supported by the grammar.
627MODE should be either `c' or `cpp'."
628 (if (eq mode 'c)
629 (mapcan
630 (lambda (entry)
631 (let ((keywords (cdr entry)))
632 (if (ignore-errors
633 (treesit-query-compile 'c `([,@keywords] @cap) t)
634 t)
635 (copy-sequence keywords)
636 nil)))
637 c-ts-mode--optional-c-keywords)
638 ;; As for now, there aren't additional optional keywords for C++.
639 ()))
640
596(defun c-ts-mode--keywords (mode) 641(defun c-ts-mode--keywords (mode)
597 "C/C++ keywords for tree-sitter font-locking. 642 "C/C++ keywords for tree-sitter font-locking.
598MODE is either `c' or `cpp'." 643MODE is either `c' or `cpp'."
599 (let ((c-keywords 644 (let ((c-keywords
600 '("_Atomic" "break" "case" "const" "continue" 645 `("_Atomic" "break" "case" "const" "continue"
601 "default" "do" "else" "enum" 646 "default" "do" "else" "enum"
602 "extern" "for" "goto" "if" "inline" 647 "extern" "for" "goto" "if" "inline"
603 "register" "restrict" "return" 648 "register" "restrict" "return"
604 "sizeof" "static" "struct" 649 "sizeof" "static" "struct"
605 "switch" "typedef" "union" 650 "switch" "typedef" "union"
606 "volatile" "while"))) 651 "volatile" "while"
652 ,@c-ts-mode--ms-keywords
653 ,@(c-ts-mode--compute-optional-keywords mode))))
607 (if (eq mode 'cpp) 654 (if (eq mode 'cpp)
608 (append c-keywords 655 (append c-keywords
609 '("and" "and_eq" "bitand" "bitor" 656 c-ts-mode--c++-operator-keywords
610 "catch" "class" "co_await" "co_return" 657 '("catch" "class" "co_await" "co_return"
611 "co_yield" "compl" "concept" "consteval" 658 "co_yield" "concept" "consteval"
612 "constexpr" "constinit" "decltype" "delete" 659 "constexpr" "constinit" "decltype" "delete"
613 "explicit" "final" "friend" 660 "explicit" "final" "friend"
614 "mutable" "namespace" "new" "noexcept" 661 "mutable" "namespace" "new" "noexcept"
615 "not" "not_eq" "operator" "or" 662 "operator" "override" "private" "protected"
616 "or_eq" "override" "private" "protected" 663 "public" "requires" "static_assert" "template" "throw"
617 "public" "requires" "template" "throw"
618 "try" "typename" "using" 664 "try" "typename" "using"
619 "xor" "xor_eq" "thread_local")) 665 "thread_local"))
620 (append '("auto") c-keywords)))) 666 (append '("auto") c-keywords))))
621 667
622(defvar c-ts-mode--type-keywords 668(defvar c-ts-mode--type-keywords
@@ -629,6 +675,15 @@ MODE is either `c' or `cpp'."
629 "+=" "*=" "/=" "%=" "|=" "&=" "^=" ">>=" "<<=" "--" "++") 675 "+=" "*=" "/=" "%=" "|=" "&=" "^=" ">>=" "<<=" "--" "++")
630 "C/C++ operators for tree-sitter font-locking.") 676 "C/C++ operators for tree-sitter font-locking.")
631 677
678(defvar c-ts-mode--c++-operators
679 '(".*" "->*" "<=>")
680 "C++ operators that aren't supported by C.")
681
682(defvar c-ts-mode--c++-operator-keywords
683 '("and" "and_eq" "bitand" "bitor" "compl" "not" "not_eq" "or" "or_eq"
684 "xor" "xor_eq")
685 "C++ operators that we fontify as keywords.")
686
632(defvar c-ts-mode--for-each-tail-regexp 687(defvar c-ts-mode--for-each-tail-regexp
633 (rx "FOR_EACH_" (or "TAIL" "TAIL_SAFE" "ALIST_VALUE" 688 (rx "FOR_EACH_" (or "TAIL" "TAIL_SAFE" "ALIST_VALUE"
634 "LIVE_BUFFER" "FRAME")) 689 "LIVE_BUFFER" "FRAME"))
@@ -697,7 +752,9 @@ MODE is either `c' or `cpp'."
697 752
698 :language mode 753 :language mode
699 :feature 'operator 754 :feature 'operator
700 `([,@c-ts-mode--operators] @font-lock-operator-face 755 `([,@c-ts-mode--operators
756 ,@(when (eq mode 'cpp) c-ts-mode--c++-operators)]
757 @font-lock-operator-face
701 "!" @font-lock-negation-char-face) 758 "!" @font-lock-negation-char-face)
702 759
703 :language mode 760 :language mode