This tree-sitter powered Emacs 29+ major mode provides syntax highlighting, indentation, imenu and which-function support for C3. It's built against the tree-sitter grammar located at https://github.com/c3lang/tree-sitter-c3.
Warning
If you're updating, please do M-x treesit-install-language-grammar RET c3 RET
to update the tree-sitter grammar too.
This mode requires Emacs 29 or greater for the built-in tree-sitter support.
Add the source url to your treesit-language-source-alist
.
(setq treesit-language-source-alist
'((c3 "https://github.com/c3lang/tree-sitter-c3")))
If you already have a treesit-language-source-alist
, you can also append to it using:
(add-to-list 'treesit-language-source-alist
'(c3 "https://github.com/c3lang/tree-sitter-c3"))
Next, run M-x treesit-install-language-grammar RET c3 RET
. (This requires cc
to be available on your system.)
A libtree-sitter-c3.so
should now be built and installed in your emacs directory.
Clone this repository and add:
(add-to-list 'load-path "path/to/c3-ts-mode")
(require 'c3-ts-mode)
Set the indent offset using the c3-ts-mode-indent-offset
variable:
(setq c3-ts-mode-indent-offset 2)
To enable all highlighting features, you might want to set treesit-font-lock-level
to 4 (the default is 3):
(setq treesit-font-lock-level 4)
The default face for module paths is font-lock-constant-face
. Override it by setting c3-ts-mode-module-path-face
. The face name must be prefixed with @
:
(setq c3-ts-mode-module-path-face '@font-lock-some-face-here)
The default face for assignments (see Notes) is font-lock-variable-name-face
. Override it by setting c3-ts-mode-assignment-face
. The face name must be prefixed with @
:
(setq c3-ts-mode-assignment-face '@font-lock-some-face-here)
Further options:
;; Disable highlighting of variables
(setq c3-ts-mode-highlight-variable nil)
;; Disable highlighting of members
(setq c3-ts-mode-highlight-property nil)
;; Disable highlighting of punctuation
(setq c3-ts-mode-highlight-punctuation nil)
;; Disable highlighting of assignments
(setq c3-ts-mode-highlight-assignment nil)
Here is an example how to override highlighting of the "assert" keyword and argument names:
(defun add-custom-c3-ts-rules ()
(add-to-list 'treesit-font-lock-settings
(car (treesit-font-lock-rules
:language 'c3
;; Choose a feature name here (see docs for 'treesit-font-lock-rules')
:feature 'custom
;; Use 't' to override the face, 'append'/'prepend' to append/prepend to existing ones
:override t
;; This will highlight the "assert" keyword and argument names with custom faces
;; See "37.5 Pattern Matching Tree-sitter Nodes" in the Emacs manual
'((assert_stmt "assert" @assert-face)
(call_invocation (call_arg name: (_) @named-arg-face)))
)) t)
;; Add feature 'custom' to feature level 4
(push 'custom (nth 3 treesit-font-lock-feature-list)))
(add-hook 'c3-ts-mode-hook #'add-custom-c3-ts-rules)
- A special feature is that assignments (and updates via
++
/--
) are highlighted accurately.- If a variable or field is assigned, the variable name is highlighted.
- If a pointer dereference is assigned, the asterisk is highlighted.
- If an array element is assigned, the subscript brackets are highlighted.
- You can configure this feature using
c3-ts-mode-highlight-assignment
andc3-ts-mode-assignment-face
.
- If punctuation is enabled (
treesit-font-lock-level
is4
andc3-ts-mode-highlight-punctuation
is't
), make sure bothfont-lock-punctuation-face
andfont-lock-brackets-face
is defined in your theme. - Indentation is tricky and has a bunch of edge cases - please submit an issue if you find a case where it doesn't work as expected.