mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-17 10:27:41 +00:00
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.
This commit is contained in:
parent
e6591b549f
commit
7d3bc1ff2f
1 changed files with 67 additions and 10 deletions
|
|
@ -593,30 +593,76 @@ NODE, PARENT, BOL, ARGS are as usual."
|
|||
"#else" "#elif" "#endif" "#include")
|
||||
"C/C++ keywords for tree-sitter font-locking.")
|
||||
|
||||
(defvar c-ts-mode--optional-c-keywords
|
||||
;; v0.20.4 actually contains all the new keywords I can find that
|
||||
;; aren't in c-ts-mode before. The version doesn't really matter, we
|
||||
;; just want a rough grouping so that we can enable as much keywords
|
||||
;; as possible.
|
||||
'(("v0.20.4" . ("_Generic" "_Noreturn" "noreturn"
|
||||
"__attribute__" "__restrict__"
|
||||
"offsetof" "thread_local"))
|
||||
("v0.20.5" . ("__extension__" "__extension__"
|
||||
"__forceinline" "__inline" "__inline__"
|
||||
"__thread"
|
||||
"__alignof__" "__alignof" "alignof" "_Alignof"))
|
||||
("v0.20.7" . ("__try" "__except" "__finally" "__leave"))
|
||||
;; GitHub release jumped from v0.20.7 to v0.23.1. There are
|
||||
;; intermediate git tags, but there aren't many keywords here, so I
|
||||
;; skipped intermediate versions too.
|
||||
("v0.23.1" ("_Nonnull" "__attribute"
|
||||
"alignas" "_Alignas" "__asm" "__volatile__"))
|
||||
;; No changes to keywords in v0.23.2, v0.23.3, v0.23.4.
|
||||
)
|
||||
"Keywords added in each tree-sitter-c version.")
|
||||
|
||||
(defvar c-ts-mode--ms-keywords
|
||||
;; For some reason, "__restrict" "__uptr" and "__sptr" are not
|
||||
;; recognized by the grammar, although being in grammar.js.
|
||||
'("__declspec" "__based" "__cdecl" "__clrcall" "__stdcall"
|
||||
"__fastcall" "__thiscall" "__vectorcall" "_unaligned" "__unaligned")
|
||||
"MSVC keywords.")
|
||||
|
||||
(defun c-ts-mode--compute-optional-keywords (mode)
|
||||
"Return a list of keywords that are supported by the grammar.
|
||||
MODE should be either `c' or `cpp'."
|
||||
(if (eq mode 'c)
|
||||
(mapcan
|
||||
(lambda (entry)
|
||||
(let ((keywords (cdr entry)))
|
||||
(if (ignore-errors
|
||||
(treesit-query-compile 'c `([,@keywords] @cap) t)
|
||||
t)
|
||||
(copy-sequence keywords)
|
||||
nil)))
|
||||
c-ts-mode--optional-c-keywords)
|
||||
;; As for now, there aren't additional optional keywords for C++.
|
||||
()))
|
||||
|
||||
(defun c-ts-mode--keywords (mode)
|
||||
"C/C++ keywords for tree-sitter font-locking.
|
||||
MODE is either `c' or `cpp'."
|
||||
(let ((c-keywords
|
||||
'("_Atomic" "break" "case" "const" "continue"
|
||||
`("_Atomic" "break" "case" "const" "continue"
|
||||
"default" "do" "else" "enum"
|
||||
"extern" "for" "goto" "if" "inline"
|
||||
"register" "restrict" "return"
|
||||
"sizeof" "static" "struct"
|
||||
"switch" "typedef" "union"
|
||||
"volatile" "while")))
|
||||
"volatile" "while"
|
||||
,@c-ts-mode--ms-keywords
|
||||
,@(c-ts-mode--compute-optional-keywords mode))))
|
||||
(if (eq mode 'cpp)
|
||||
(append c-keywords
|
||||
'("and" "and_eq" "bitand" "bitor"
|
||||
"catch" "class" "co_await" "co_return"
|
||||
"co_yield" "compl" "concept" "consteval"
|
||||
c-ts-mode--c++-operator-keywords
|
||||
'("catch" "class" "co_await" "co_return"
|
||||
"co_yield" "concept" "consteval"
|
||||
"constexpr" "constinit" "decltype" "delete"
|
||||
"explicit" "final" "friend"
|
||||
"mutable" "namespace" "new" "noexcept"
|
||||
"not" "not_eq" "operator" "or"
|
||||
"or_eq" "override" "private" "protected"
|
||||
"public" "requires" "template" "throw"
|
||||
"operator" "override" "private" "protected"
|
||||
"public" "requires" "static_assert" "template" "throw"
|
||||
"try" "typename" "using"
|
||||
"xor" "xor_eq" "thread_local"))
|
||||
"thread_local"))
|
||||
(append '("auto") c-keywords))))
|
||||
|
||||
(defvar c-ts-mode--type-keywords
|
||||
|
|
@ -629,6 +675,15 @@ MODE is either `c' or `cpp'."
|
|||
"+=" "*=" "/=" "%=" "|=" "&=" "^=" ">>=" "<<=" "--" "++")
|
||||
"C/C++ operators for tree-sitter font-locking.")
|
||||
|
||||
(defvar c-ts-mode--c++-operators
|
||||
'(".*" "->*" "<=>")
|
||||
"C++ operators that aren't supported by C.")
|
||||
|
||||
(defvar c-ts-mode--c++-operator-keywords
|
||||
'("and" "and_eq" "bitand" "bitor" "compl" "not" "not_eq" "or" "or_eq"
|
||||
"xor" "xor_eq")
|
||||
"C++ operators that we fontify as keywords.")
|
||||
|
||||
(defvar c-ts-mode--for-each-tail-regexp
|
||||
(rx "FOR_EACH_" (or "TAIL" "TAIL_SAFE" "ALIST_VALUE"
|
||||
"LIVE_BUFFER" "FRAME"))
|
||||
|
|
@ -697,7 +752,9 @@ MODE is either `c' or `cpp'."
|
|||
|
||||
:language mode
|
||||
:feature 'operator
|
||||
`([,@c-ts-mode--operators] @font-lock-operator-face
|
||||
`([,@c-ts-mode--operators
|
||||
,@(when (eq mode 'cpp) c-ts-mode--c++-operators)]
|
||||
@font-lock-operator-face
|
||||
"!" @font-lock-negation-char-face)
|
||||
|
||||
:language mode
|
||||
|
|
|
|||
Loading…
Reference in a new issue