diff options
| author | Yuan Fu | 2025-01-12 00:35:20 -0800 |
|---|---|---|
| committer | Yuan Fu | 2025-01-12 21:27:41 -0800 |
| commit | 7d3bc1ff2f44215ad24fdd8b243e7cee8ff66fa0 (patch) | |
| tree | ac231ad06d342f013cb4e15169b0219dc25d090c | |
| parent | e6591b549f35af1be31f5bf3547e1170b7604a99 (diff) | |
| download | emacs-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.el | 77 |
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. | ||
| 627 | MODE 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. |
| 598 | MODE is either `c' or `cpp'." | 643 | MODE 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 |