Compare commits
2
Commits
e632e7326b
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf22faa2f1 | ||
|
|
824b892c76 |
@@ -18,3 +18,4 @@
|
|||||||
/history
|
/history
|
||||||
/ido.last
|
/ido.last
|
||||||
/places
|
/places
|
||||||
|
/places.eld
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
(custom-set-variables
|
|
||||||
;; custom-set-variables was added by Custom.
|
|
||||||
;; If you edit it by hand, you could mess it up, so be careful.
|
|
||||||
;; Your init file should contain only one such instance.
|
|
||||||
;; If there is more than one, they won't work right.
|
|
||||||
'(custom-safe-themes
|
|
||||||
'("e13beeb34b932f309fb2c360a04a460821ca99fe58f69e65557d6c1b10ba18c7"
|
|
||||||
default))
|
|
||||||
'(inhibit-startup-screen t)
|
|
||||||
'(package-selected-packages
|
|
||||||
'(ace-window cargo cargo-mode crystal-mode dimmer dune dune-format
|
|
||||||
elixir-mode flycheck-rust gleam-ts-mode go-mode
|
|
||||||
gruber-darker-theme neocaml neotree ocamlformat
|
|
||||||
projectile rust-mode treemacs use-package-treesit
|
|
||||||
yaml-mode)))
|
|
||||||
|
|
||||||
(custom-set-faces
|
|
||||||
;; custom-set-faces was added by Custom.
|
|
||||||
;; If you edit it by hand, you could mess it up, so be careful.
|
|
||||||
;; Your init file should contain only one such instance.
|
|
||||||
;; If there is more than one, they won't work right.
|
|
||||||
)
|
|
||||||
Vendored
-683
@@ -1,683 +0,0 @@
|
|||||||
;;; c3-ts-mode.el --- Major mode for C3 using tree-sitter -*- lexical-binding: t -*-
|
|
||||||
|
|
||||||
;; Author: Christian Buttner <https://github.com/cbuttner>
|
|
||||||
;; URL: https://github.com/c3lang/c3-ts-mode
|
|
||||||
;; Keywords: c3 languages tree-sitter
|
|
||||||
;; Version: 0.9.0
|
|
||||||
;; Package-Requires : ((emacs "29.1"))
|
|
||||||
|
|
||||||
;;; License:
|
|
||||||
|
|
||||||
;; This program is free software; you can redistribute it and/or
|
|
||||||
;; modify it under the terms of the GNU General Public License as
|
|
||||||
;; published by the Free Software Foundation; either version 3, or
|
|
||||||
;; (at your option) any later version.
|
|
||||||
;;
|
|
||||||
;; This program is distributed in the hope that it will be useful,
|
|
||||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
;; General Public License for more details.
|
|
||||||
;;
|
|
||||||
;; You should have received a copy of the GNU General Public License
|
|
||||||
;; along with this program; if not, see <https://www.gnu.org/licenses>.
|
|
||||||
|
|
||||||
;;; Commentary:
|
|
||||||
|
|
||||||
;; 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>.
|
|
||||||
|
|
||||||
;;; Code:
|
|
||||||
|
|
||||||
(require 'treesit)
|
|
||||||
(require 'c-ts-common)
|
|
||||||
(require 'compile)
|
|
||||||
|
|
||||||
(eval-when-compile (require 'rx))
|
|
||||||
|
|
||||||
(declare-function treesit-node-child-by-field-name "treesit.c")
|
|
||||||
(declare-function treesit-node-type "treesit.c")
|
|
||||||
(declare-function treesit-node-text "treesit.c")
|
|
||||||
(declare-function treesit-parser-create "treesit.c")
|
|
||||||
|
|
||||||
(defgroup c3-ts nil
|
|
||||||
"Major mode for editing C3 files."
|
|
||||||
:prefix "c3-ts-"
|
|
||||||
:group 'languages)
|
|
||||||
|
|
||||||
(defcustom c3-ts-mode-indent-offset 2
|
|
||||||
"Number of spaces for each indentation step in `c3-ts-mode'."
|
|
||||||
:version "29.1"
|
|
||||||
:type 'integer
|
|
||||||
:safe 'integerp
|
|
||||||
:group 'c3-ts)
|
|
||||||
|
|
||||||
(defcustom c3-ts-mode-highlight-variable 't
|
|
||||||
"Enable highlighting of variables in `c3-ts-mode'."
|
|
||||||
:version "29.1"
|
|
||||||
:type 'boolean
|
|
||||||
:safe 'booleanp
|
|
||||||
:group 'c3-ts)
|
|
||||||
|
|
||||||
(defcustom c3-ts-mode-highlight-property 't
|
|
||||||
"Enable highlighting of members in `c3-ts-mode'."
|
|
||||||
:version "29.1"
|
|
||||||
:type 'boolean
|
|
||||||
:safe 'booleanp
|
|
||||||
:group 'c3-ts)
|
|
||||||
|
|
||||||
(defcustom c3-ts-mode-highlight-assignment 't
|
|
||||||
"Enable highlighting of assignments in `c3-ts-mode'."
|
|
||||||
:version "29.1"
|
|
||||||
:type 'boolean
|
|
||||||
:safe 'booleanp
|
|
||||||
:group 'c3-ts)
|
|
||||||
|
|
||||||
(defcustom c3-ts-mode-highlight-punctuation 't
|
|
||||||
"Enable highlighting of punctuation in `c3-ts-mode'."
|
|
||||||
:version "29.1"
|
|
||||||
:type 'boolean
|
|
||||||
:safe 'booleanp
|
|
||||||
:group 'c3-ts)
|
|
||||||
|
|
||||||
(defcustom c3-ts-mode-module-path-face '@font-lock-constant-face
|
|
||||||
"The face to use for highlighting module paths in `c3-ts-mode'."
|
|
||||||
:version "29.1"
|
|
||||||
:type 'symbol
|
|
||||||
:group 'c3-ts)
|
|
||||||
|
|
||||||
(defcustom c3-ts-mode-assignment-face '@font-lock-variable-name-face
|
|
||||||
"The face to use for highlighting assignments in `c3-ts-mode'."
|
|
||||||
:version "29.1"
|
|
||||||
:type 'symbol
|
|
||||||
:group 'c3-ts)
|
|
||||||
|
|
||||||
(defcustom c3-ts-mode-hook nil
|
|
||||||
"Hook run after entering `c3-ts-mode'."
|
|
||||||
:version "29.1"
|
|
||||||
:type 'hook
|
|
||||||
:group 'c3-ts)
|
|
||||||
|
|
||||||
(defvar c3-ts-mode--syntax-table
|
|
||||||
(let ((table (make-syntax-table)))
|
|
||||||
;; Adapted from c-ts-mode.el
|
|
||||||
(modify-syntax-entry ?_ "_" table)
|
|
||||||
(modify-syntax-entry ?\\ "\\" table)
|
|
||||||
(modify-syntax-entry ?+ "." table)
|
|
||||||
(modify-syntax-entry ?- "." table)
|
|
||||||
(modify-syntax-entry ?= "." table)
|
|
||||||
(modify-syntax-entry ?% "." table)
|
|
||||||
(modify-syntax-entry ?< ". 1" table) ; C3: the first character of a comment-start sequence
|
|
||||||
(modify-syntax-entry ?> ". 4" table) ; C3: the second character of a comment-end sequence
|
|
||||||
(modify-syntax-entry ?@ "w" table) ; C3: identifiers starting with @
|
|
||||||
(modify-syntax-entry ?& "." table)
|
|
||||||
(modify-syntax-entry ?| "." table)
|
|
||||||
(modify-syntax-entry ?\' "\"" table)
|
|
||||||
(modify-syntax-entry ?` "\"" table)
|
|
||||||
(modify-syntax-entry ?\240 "." table)
|
|
||||||
(modify-syntax-entry ?/ ". 124b" table)
|
|
||||||
(modify-syntax-entry ?* ". 23" table)
|
|
||||||
(modify-syntax-entry ?\n "> b" table)
|
|
||||||
(modify-syntax-entry ?\^m "> b" table)
|
|
||||||
table)
|
|
||||||
"Syntax table for `c3-ts-mode'.")
|
|
||||||
|
|
||||||
(defvar c3-ts-mode--keywords
|
|
||||||
;; From "c3c --list-keywords", without base types
|
|
||||||
'("alias"
|
|
||||||
"assert"
|
|
||||||
"asm"
|
|
||||||
"attrdef"
|
|
||||||
"bitstruct"
|
|
||||||
"break"
|
|
||||||
"case"
|
|
||||||
"catch"
|
|
||||||
"const"
|
|
||||||
"continue"
|
|
||||||
"default"
|
|
||||||
"defer"
|
|
||||||
"do"
|
|
||||||
"else"
|
|
||||||
"enum"
|
|
||||||
"extern"
|
|
||||||
;; "false" ;; NOTE Treated as constant
|
|
||||||
"faultdef"
|
|
||||||
"for"
|
|
||||||
"foreach"
|
|
||||||
"foreach_r"
|
|
||||||
"fn"
|
|
||||||
"tlocal"
|
|
||||||
"if"
|
|
||||||
"inline"
|
|
||||||
"import"
|
|
||||||
"macro"
|
|
||||||
"module"
|
|
||||||
"nextcase"
|
|
||||||
;; "null" ;; NOTE Treated as constant
|
|
||||||
"interface"
|
|
||||||
"return"
|
|
||||||
"static"
|
|
||||||
"struct"
|
|
||||||
"switch"
|
|
||||||
;; "true" ;; NOTE Treated as constant
|
|
||||||
"try"
|
|
||||||
"typedef"
|
|
||||||
"union"
|
|
||||||
"var"
|
|
||||||
"while"
|
|
||||||
|
|
||||||
"$alignof"
|
|
||||||
"$assert"
|
|
||||||
"$assignable"
|
|
||||||
"$case"
|
|
||||||
"$default"
|
|
||||||
"$defined"
|
|
||||||
"$echo"
|
|
||||||
"$else"
|
|
||||||
"$embed"
|
|
||||||
"$endfor"
|
|
||||||
"$endforeach"
|
|
||||||
"$endif"
|
|
||||||
"$endswitch"
|
|
||||||
"$eval"
|
|
||||||
"$evaltype"
|
|
||||||
"$error"
|
|
||||||
"$exec"
|
|
||||||
"$extnameof"
|
|
||||||
"$feature"
|
|
||||||
"$for"
|
|
||||||
"$foreach"
|
|
||||||
"$if"
|
|
||||||
"$include"
|
|
||||||
"$is_const"
|
|
||||||
"$kindof"
|
|
||||||
"$nameof"
|
|
||||||
"$offsetof"
|
|
||||||
"$qnameof"
|
|
||||||
"$sizeof"
|
|
||||||
"$stringify"
|
|
||||||
"$switch"
|
|
||||||
"$typefrom"
|
|
||||||
"$typeof"
|
|
||||||
"$vacount"
|
|
||||||
"$vatype"
|
|
||||||
"$vaconst"
|
|
||||||
"$vaarg"
|
|
||||||
"$vaexpr"
|
|
||||||
"$vasplat"))
|
|
||||||
|
|
||||||
(defvar c3-ts-mode--type-properties
|
|
||||||
;; From "c3c --list-type-properties"
|
|
||||||
'("alignof"
|
|
||||||
"associated"
|
|
||||||
"elements"
|
|
||||||
"extnameof"
|
|
||||||
"from_ordinal"
|
|
||||||
"get"
|
|
||||||
"inf"
|
|
||||||
"is_eq"
|
|
||||||
"is_ordered"
|
|
||||||
"is_substruct"
|
|
||||||
"len"
|
|
||||||
"lookup"
|
|
||||||
"lookup_field"
|
|
||||||
"max"
|
|
||||||
"membersof"
|
|
||||||
"methodsof"
|
|
||||||
"min"
|
|
||||||
"nan"
|
|
||||||
"inner"
|
|
||||||
"kindof"
|
|
||||||
"names"
|
|
||||||
"nameof"
|
|
||||||
"params"
|
|
||||||
"paramsof"
|
|
||||||
"parentof"
|
|
||||||
"qnameof"
|
|
||||||
"returns"
|
|
||||||
"sizeof"
|
|
||||||
"set"
|
|
||||||
"tagof"
|
|
||||||
"has_tagof"
|
|
||||||
"values"
|
|
||||||
;; Separate token in c3c
|
|
||||||
"typeid"))
|
|
||||||
|
|
||||||
|
|
||||||
(defvar c3-ts-mode--operators
|
|
||||||
;; From "c3c --list-operators"
|
|
||||||
'("&"
|
|
||||||
"!"
|
|
||||||
"~"
|
|
||||||
"|"
|
|
||||||
"^"
|
|
||||||
":"
|
|
||||||
;; ","
|
|
||||||
;; ";"
|
|
||||||
"="
|
|
||||||
">"
|
|
||||||
"/"
|
|
||||||
"."
|
|
||||||
;; "#"
|
|
||||||
"<"
|
|
||||||
;; "{"
|
|
||||||
;; "["
|
|
||||||
;; "("
|
|
||||||
"-"
|
|
||||||
"%"
|
|
||||||
"+"
|
|
||||||
"?"
|
|
||||||
;; "}"
|
|
||||||
;; "]"
|
|
||||||
;; ")"
|
|
||||||
"*"
|
|
||||||
;; "_"
|
|
||||||
"&&"
|
|
||||||
;; "->"
|
|
||||||
"!!"
|
|
||||||
"&="
|
|
||||||
"|="
|
|
||||||
"^="
|
|
||||||
"/="
|
|
||||||
".."
|
|
||||||
"?:"
|
|
||||||
"=="
|
|
||||||
">="
|
|
||||||
"=>"
|
|
||||||
"<="
|
|
||||||
;; "[<"
|
|
||||||
"-="
|
|
||||||
"--"
|
|
||||||
"%="
|
|
||||||
"*="
|
|
||||||
"!="
|
|
||||||
"||"
|
|
||||||
"+="
|
|
||||||
"++"
|
|
||||||
;; ">]"
|
|
||||||
"??"
|
|
||||||
;; "::"
|
|
||||||
"<<"
|
|
||||||
">>"
|
|
||||||
"..."
|
|
||||||
"<<="
|
|
||||||
">>="
|
|
||||||
"&&&"
|
|
||||||
"+++"
|
|
||||||
"|||"
|
|
||||||
"???"
|
|
||||||
"+++="))
|
|
||||||
|
|
||||||
(defvar c3-ts-mode--feature-list
|
|
||||||
`((comment definition)
|
|
||||||
(keyword string type)
|
|
||||||
;; TODO Not clear if assignment should go in level 4 or not (3 is the default level).
|
|
||||||
,(append
|
|
||||||
'(builtin attribute escape-sequence literal constant assembly module function doc-comment)
|
|
||||||
(when c3-ts-mode-highlight-assignment '(assignment)))
|
|
||||||
,(append
|
|
||||||
'(type-property operator bracket)
|
|
||||||
(when c3-ts-mode-highlight-punctuation '(punctuation))
|
|
||||||
(when c3-ts-mode-highlight-variable '(variable))
|
|
||||||
(when c3-ts-mode-highlight-property '(property)))
|
|
||||||
;; (error) ;; Disabled by default
|
|
||||||
)
|
|
||||||
"`treesit-font-lock-feature-list' for `c3-ts-mode'.")
|
|
||||||
|
|
||||||
(defvar c3-ts-mode--font-lock-settings
|
|
||||||
;; NOTE Earlier rules have precedence over later rules
|
|
||||||
(treesit-font-lock-rules
|
|
||||||
:language 'c3
|
|
||||||
:feature 'doc-comment
|
|
||||||
'((doc_comment_contract name: (at_ident) @font-lock-builtin-face)
|
|
||||||
(doc_comment_contract mutability_contract: (_) @font-lock-constant-face)
|
|
||||||
(doc_comment ["<*" "*>"] @font-lock-doc-face)
|
|
||||||
(doc_comment_text) @font-lock-doc-face
|
|
||||||
;; (doc_comment_contract parameter: ([(ident) (ct_ident) (hash_ident)]) @font-lock-variable-name-face)
|
|
||||||
(doc_comment_contract [":" "?"] @font-lock-doc-face)
|
|
||||||
(doc_comment_contract description: (_) @font-lock-doc-face)
|
|
||||||
)
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'comment
|
|
||||||
'((line_comment) @font-lock-comment-face
|
|
||||||
(block_comment) @font-lock-comment-face
|
|
||||||
(doc_comment) @font-lock-doc-face)
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'literal
|
|
||||||
'((integer_literal) @font-lock-number-face
|
|
||||||
(real_literal) @font-lock-number-face
|
|
||||||
(char_literal) @font-lock-constant-face
|
|
||||||
(bytes_literal) @font-lock-constant-face)
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'string
|
|
||||||
'((string_literal) @font-lock-string-face
|
|
||||||
(raw_string_literal) @font-lock-string-face)
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'escape-sequence
|
|
||||||
:override t
|
|
||||||
'((escape_sequence) @font-lock-escape-face)
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'keyword
|
|
||||||
`([,@c3-ts-mode--keywords] @font-lock-keyword-face)
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'builtin
|
|
||||||
'([(builtin) (builtin_const)] @font-lock-builtin-face)
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'type-property
|
|
||||||
`((type_access_expr (access_ident (ident) @font-lock-constant-face (:match ,(rx-to-string `(: bos (or ,@c3-ts-mode--type-properties) eos)) @font-lock-constant-face))))
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'constant
|
|
||||||
'((const_ident) @font-lock-constant-face
|
|
||||||
["true" "false" "null"] @font-lock-constant-face)
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'assembly
|
|
||||||
'((asm_instr [(ident) "int"] @font-lock-function-call-face)
|
|
||||||
(asm_expr [(ct_ident) (ct_const_ident)] @font-lock-variable-use-face))
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'module
|
|
||||||
`((module_resolution (ident) ,c3-ts-mode-module-path-face)
|
|
||||||
(module_declaration (path_ident (ident) ,c3-ts-mode-module-path-face))
|
|
||||||
(import_path (path_ident (ident) ,c3-ts-mode-module-path-face)))
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'attribute
|
|
||||||
'((attribute name: (at_ident) @font-lock-builtin-face)
|
|
||||||
(at_type_ident) @font-lock-builtin-face
|
|
||||||
(call_inline_attributes (at_ident) @font-lock-builtin-face)
|
|
||||||
(type_suffix (at_ident) @font-lock-builtin-face))
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'type
|
|
||||||
'((type_ident) @font-lock-type-face
|
|
||||||
(ct_type_ident) @font-lock-type-face
|
|
||||||
(base_type_name) @font-lock-type-face
|
|
||||||
|
|
||||||
;; TODO Probably don't want these
|
|
||||||
;; (type_suffix ["[" "[<" ">]" "]"] @font-lock-type-face)
|
|
||||||
;; (type "!" @font-lock-type-face :anchor)
|
|
||||||
)
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'definition
|
|
||||||
'((func_header name: (_) @font-lock-function-name-face)
|
|
||||||
(macro_header name: (_) @font-lock-function-name-face))
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'function
|
|
||||||
'((call_expr function: (ident_expr [(ident) (at_ident)] @font-lock-function-call-face))
|
|
||||||
(call_expr function: (trailing_generic_expr argument: (ident_expr [(ident) (at_ident)] @font-lock-function-call-face)))
|
|
||||||
;; Method call
|
|
||||||
(call_expr function: (field_expr field: (access_ident [(ident) (at_ident)] @font-lock-function-call-face))) ; NOTE Ambiguous, could be calling a method or function pointer
|
|
||||||
;; Method on type
|
|
||||||
(call_expr function: (type_access_expr field: (access_ident [(ident) (at_ident)] @font-lock-function-call-face))))
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'assignment
|
|
||||||
`((assignment_expr left: (ident_expr (ident) ,c3-ts-mode-assignment-face))
|
|
||||||
(assignment_expr left: (field_expr field: (_) ,c3-ts-mode-assignment-face))
|
|
||||||
(assignment_expr left: (unary_expr operator: "*" ,c3-ts-mode-assignment-face))
|
|
||||||
(assignment_expr left: (subscript_expr ["[" "]"] ,c3-ts-mode-assignment-face))
|
|
||||||
(assignment_expr left: (maybe_deref_expr ["[" "]"] ,c3-ts-mode-assignment-face))
|
|
||||||
|
|
||||||
(update_expr argument: (ident_expr (ident) ,c3-ts-mode-assignment-face))
|
|
||||||
(update_expr argument: (field_expr field: (_) ,c3-ts-mode-assignment-face))
|
|
||||||
(update_expr argument: (unary_expr operator: "*" ,c3-ts-mode-assignment-face))
|
|
||||||
(update_expr argument: (subscript_expr ["[" "]"] ,c3-ts-mode-assignment-face))
|
|
||||||
|
|
||||||
(unary_expr operator: ["--" "++"] argument: (ident_expr (ident) ,c3-ts-mode-assignment-face))
|
|
||||||
(unary_expr operator: ["--" "++"] argument: (field_expr field: (access_ident (ident)) ,c3-ts-mode-assignment-face))
|
|
||||||
(unary_expr operator: ["--" "++"] argument: (subscript_expr ["[" "]"] ,c3-ts-mode-assignment-face)))
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'operator
|
|
||||||
`(([,@c3-ts-mode--operators]) @font-lock-operator-face)
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'property
|
|
||||||
'(;; Member
|
|
||||||
(field_expr field: (access_ident (ident) @font-lock-property-use-face))
|
|
||||||
(struct_member_declaration (ident) @font-lock-property-name-face)
|
|
||||||
(struct_member_declaration (identifier_list (ident) @font-lock-property-name-face))
|
|
||||||
(bitstruct_member_declaration (ident) @font-lock-property-name-face)
|
|
||||||
(initializer_list (initializer_element (param_path (param_path_element (access_ident (ident) @font-lock-property-name-face))))))
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'variable
|
|
||||||
'([(ident) (ct_ident)] @font-lock-variable-use-face
|
|
||||||
;; Parameter
|
|
||||||
(param name: (_) @font-lock-variable-name-face)
|
|
||||||
(trailing_block_param (at_ident) @font-lock-variable-name-face)
|
|
||||||
(call_arg_list (call_arg name: (_) @font-lock-variable-name-face))
|
|
||||||
(enum_param (ident) @font-lock-variable-name-face)
|
|
||||||
;; Declaration
|
|
||||||
(declaration (identifier_list [(ident) (ct_ident)] @font-lock-variable-name-face))
|
|
||||||
(declaration name: [(ident) (ct_ident)] @font-lock-variable-name-face)
|
|
||||||
(var_declaration name: [(ident) (ct_ident)] @font-lock-variable-name-face)
|
|
||||||
(try_unwrap (ident) @font-lock-variable-name-face)
|
|
||||||
(catch_unwrap (ident) @font-lock-variable-name-face))
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'bracket
|
|
||||||
'((["(" ")" "[" "]" "{" "}" "[<" ">]"]) @font-lock-bracket-face)
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'punctuation
|
|
||||||
'(([";" "," "::"]) @font-lock-punctuation-face)
|
|
||||||
|
|
||||||
:language 'c3
|
|
||||||
:feature 'error
|
|
||||||
:override t
|
|
||||||
'((ERROR) @font-lock-warning-face))
|
|
||||||
"Tree-sitter font-lock settings for `c3-ts-mode'.")
|
|
||||||
|
|
||||||
(defvar c3-ts-mode--simple-indent-rules
|
|
||||||
`((c3
|
|
||||||
((parent-is "source_file") column-0 0)
|
|
||||||
|
|
||||||
((node-is "else") parent-bol 0) ;; Also matches $else
|
|
||||||
((node-is "^\\(case\\|ct_case\\|default\\|ct_default\\)_stmt$") parent-bol c3-ts-mode-indent-offset)
|
|
||||||
((node-is "ct_stmt_body") parent-bol c3-ts-mode-indent-offset)
|
|
||||||
((parent-is "ct_stmt_body") standalone-parent 0)
|
|
||||||
((node-is "$endif") parent-bol 0)
|
|
||||||
((node-is "$endfor") parent-bol 0)
|
|
||||||
((node-is "$endswitch") parent-bol 0)
|
|
||||||
|
|
||||||
((and (parent-is "block_comment_text") c-ts-common-looking-at-star)
|
|
||||||
c-ts-common-comment-start-after-first-star -1)
|
|
||||||
|
|
||||||
;; NOTE This only indents the first line of a doc comment text. This way we preserve identation on subsequent lines, such as list item indentation. TODO Indent to a minimum of 1? Can still ruin formatting
|
|
||||||
((node-is "doc_comment_text") parent-bol 1)
|
|
||||||
((node-is "doc_comment_contract") parent-bol 1)
|
|
||||||
((node-is "*>") parent-bol 0)
|
|
||||||
|
|
||||||
((node-is "}") standalone-parent 0)
|
|
||||||
((node-is ")") standalone-parent 0)
|
|
||||||
|
|
||||||
((match "while" "do_stmt" nil nil nil) standalone-parent 0)
|
|
||||||
((match "compound_stmt" "else_part" nil nil nil) standalone-parent 0)
|
|
||||||
|
|
||||||
;; Attributes
|
|
||||||
((node-is "attributes") standalone-parent c3-ts-mode-indent-offset)
|
|
||||||
((parent-is "attributes") parent 0) ;; Align attributes on same column
|
|
||||||
|
|
||||||
;; Body/block children
|
|
||||||
((parent-is "enum_body") standalone-parent c3-ts-mode-indent-offset)
|
|
||||||
((parent-is "struct_body") standalone-parent c3-ts-mode-indent-offset)
|
|
||||||
((parent-is "bitstruct_body") standalone-parent c3-ts-mode-indent-offset)
|
|
||||||
((parent-is "interface_body") standalone-parent c3-ts-mode-indent-offset)
|
|
||||||
((parent-is "macro_func_body") standalone-parent c3-ts-mode-indent-offset)
|
|
||||||
((parent-is "implies_body") standalone-parent c3-ts-mode-indent-offset)
|
|
||||||
|
|
||||||
((parent-is "compound_stmt") standalone-parent c3-ts-mode-indent-offset)
|
|
||||||
((parent-is "initializer_list") standalone-parent c3-ts-mode-indent-offset)
|
|
||||||
((parent-is "case_stmt") standalone-parent c3-ts-mode-indent-offset)
|
|
||||||
((parent-is "default_stmt") standalone-parent c3-ts-mode-indent-offset)
|
|
||||||
|
|
||||||
;; if/switch/for/while/defer with block
|
|
||||||
((match "compound_stmt" "\\(if\\|switch\\|for\\|foreach\\|while\\|do\\|defer\\)_stmt" nil nil nil) standalone-parent 0)
|
|
||||||
|
|
||||||
;; for/while/defer without block
|
|
||||||
((parent-is "\\(for\\|foreach\\|while\\|defer\\)_stmt") standalone-parent c3-ts-mode-indent-offset)
|
|
||||||
|
|
||||||
;; Body not handled so far
|
|
||||||
((field-is "body") standalone-parent 0)
|
|
||||||
((field-is "lambda_body") standalone-parent 0)
|
|
||||||
|
|
||||||
;; Trailing macro block
|
|
||||||
((match "compound_stmt" nil "trailing" nil nil) parent 0)
|
|
||||||
|
|
||||||
((match nil "field_expr" "field" nil nil) parent-bol c3-ts-mode-indent-offset)
|
|
||||||
((n-p-gp "." "field_expr" nil) parent-bol c3-ts-mode-indent-offset) ;; Field access beginning with "."
|
|
||||||
((match nil "type_access_expr" "field" nil nil) parent-bol c3-ts-mode-indent-offset)
|
|
||||||
((match nil "assignment_expr" "right" nil nil) parent-bol c3-ts-mode-indent-offset)
|
|
||||||
((match nil "const_declaration" "right" nil nil) parent-bol c3-ts-mode-indent-offset)
|
|
||||||
((match nil "declaration" "right" nil nil) parent-bol c3-ts-mode-indent-offset)
|
|
||||||
|
|
||||||
;; Multi line declarations
|
|
||||||
((parent-is "identifier_list") parent 0)
|
|
||||||
((parent-is "^for_cond") parent 1)
|
|
||||||
((parent-is "^foreach_cond") parent 1)
|
|
||||||
((parent-is "ct_for_cond") parent 0)
|
|
||||||
((parent-is "ct_foreach_cond") parent 0)
|
|
||||||
((parent-is "paren_cond") parent 1)
|
|
||||||
((parent-is "catch_unwrap_list") parent 0)
|
|
||||||
((parent-is "comma_decl_or_expr") parent 0)
|
|
||||||
|
|
||||||
;; First parameter/argument
|
|
||||||
((match "^\\(call_\\|attribute_\\)?arg\\|param\\|enum_param_declaration\\|trailing_block_param$" nil nil 1 1) parent-bol c3-ts-mode-indent-offset)
|
|
||||||
;; Subsequent params/arguments
|
|
||||||
((match "^\\(call_\\|attribute_\\)?arg\\|param\\|enum_param_declaration\\|trailing_block_param$" nil nil 2 nil) (nth-sibling 1) 0)
|
|
||||||
|
|
||||||
;; String/bytes literals
|
|
||||||
((node-is "raw_string_literal") no-indent)
|
|
||||||
((match "string_literal" "string_expr" nil 0 0) parent 0)
|
|
||||||
((match "string_literal" "string_expr" nil 1 nil) (nth-sibling 0) 0)
|
|
||||||
((match "bytes_literal" "bytes_expr" nil 0 0) parent 0)
|
|
||||||
((match "bytes_literal" "bytes_expr" nil 1 nil) (nth-sibling 0) 0)
|
|
||||||
|
|
||||||
((parent-is "paren") parent 1)
|
|
||||||
((parent-is "binary") parent 0)
|
|
||||||
((parent-is "range") parent 0)
|
|
||||||
((parent-is "elvis_orelse") parent 0)
|
|
||||||
((parent-is "ternary") parent c3-ts-mode-indent-offset)
|
|
||||||
((parent-is "subscript") parent c3-ts-mode-indent-offset)
|
|
||||||
((parent-is "update") parent c3-ts-mode-indent-offset)
|
|
||||||
((parent-is "call") parent c3-ts-mode-indent-offset)
|
|
||||||
((parent-is "cast") parent c3-ts-mode-indent-offset)
|
|
||||||
|
|
||||||
((parent-is "func_declaration") standalone-parent 0)
|
|
||||||
((parent-is "func_header") standalone-parent 0)
|
|
||||||
((parent-is "macro_declaration") standalone-parent 0)
|
|
||||||
((parent-is "macro_header") standalone-parent 0)
|
|
||||||
|
|
||||||
((node-is "initializer_list") parent 0)
|
|
||||||
|
|
||||||
;; ((parent-is "ERROR") no-indent 0)
|
|
||||||
)))
|
|
||||||
|
|
||||||
(defun c3-ts-mode--defun-name (node)
|
|
||||||
"Return the name of the defun NODE."
|
|
||||||
(let ()
|
|
||||||
(treesit-node-text
|
|
||||||
(treesit-node-child-by-field-name
|
|
||||||
(pcase (treesit-node-type node)
|
|
||||||
("func_definition"
|
|
||||||
(car
|
|
||||||
(treesit-filter-child node
|
|
||||||
(lambda (ch)
|
|
||||||
(string-equal (treesit-node-type ch) "func_header"))
|
|
||||||
t)))
|
|
||||||
("macro_declaration"
|
|
||||||
(car
|
|
||||||
(treesit-filter-child node
|
|
||||||
(lambda (ch)
|
|
||||||
(string-equal (treesit-node-type ch) "macro_header"))
|
|
||||||
t)))
|
|
||||||
(_ node))
|
|
||||||
"name")
|
|
||||||
t)))
|
|
||||||
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(define-derived-mode c3-ts-mode prog-mode "C3"
|
|
||||||
"Major mode for editing C3 files, powered by tree-sitter."
|
|
||||||
:group 'c3-ts
|
|
||||||
:syntax-table c3-ts-mode--syntax-table
|
|
||||||
|
|
||||||
;; Comment
|
|
||||||
(c-ts-common-comment-setup)
|
|
||||||
|
|
||||||
;; Electric
|
|
||||||
(setq-local electric-indent-chars
|
|
||||||
(append "{}():;," electric-indent-chars))
|
|
||||||
|
|
||||||
(when (treesit-ready-p 'c3)
|
|
||||||
(treesit-parser-create 'c3)
|
|
||||||
|
|
||||||
;; Font-lock
|
|
||||||
(setq-local treesit-font-lock-settings c3-ts-mode--font-lock-settings)
|
|
||||||
(setq-local treesit-font-lock-feature-list c3-ts-mode--feature-list)
|
|
||||||
|
|
||||||
;; Indent
|
|
||||||
(setq-local treesit-simple-indent-rules c3-ts-mode--simple-indent-rules)
|
|
||||||
|
|
||||||
;; Navigation
|
|
||||||
(setq-local treesit-defun-name-function #'c3-ts-mode--defun-name)
|
|
||||||
(setq-local treesit-defun-type-regexp
|
|
||||||
(rx bos
|
|
||||||
(or "struct_declaration"
|
|
||||||
"bitstruct_declaration"
|
|
||||||
"enum_declaration"
|
|
||||||
"interface_declaration"
|
|
||||||
"func_definition"
|
|
||||||
"macro_declaration"
|
|
||||||
"const_declaration"
|
|
||||||
"alias_declaration"
|
|
||||||
"typedef_declaration"
|
|
||||||
"faultdef_declaration"
|
|
||||||
"attrdef_declaration")
|
|
||||||
eos))
|
|
||||||
|
|
||||||
;; Imenu
|
|
||||||
(setq-local treesit-simple-imenu-settings
|
|
||||||
`(("Struct" "\\`struct_declaration\\'" nil nil)
|
|
||||||
("Bitstruct" "\\`bitstruct_declaration\\'" nil nil)
|
|
||||||
("Enum" "\\`enum_declaration\\'" nil nil)
|
|
||||||
("Interface" "\\`interface_declaration\\'" nil nil)
|
|
||||||
("Function" "\\`func_definition\\'" nil nil)
|
|
||||||
("Macro" "\\`macro_declaration\\'" nil nil)
|
|
||||||
("Const" "\\`const_declaration\\'" nil nil)
|
|
||||||
("Alias" "\\`alias_declaration\\'" nil nil)
|
|
||||||
("Type" "\\`typedef_declaration\\'" nil nil)
|
|
||||||
("Fault" "\\`faultdef_declaration\\'" nil nil)
|
|
||||||
("Attribute" "\\`attrdef_declaration\\'" nil nil)))
|
|
||||||
|
|
||||||
;; Which-function
|
|
||||||
(setq-local which-func-functions (treesit-defun-at-point))
|
|
||||||
|
|
||||||
(treesit-major-mode-setup)))
|
|
||||||
|
|
||||||
(when (treesit-ready-p 'c3)
|
|
||||||
(add-to-list 'auto-mode-alist '("\\.c3[it]?\\'" . c3-ts-mode)))
|
|
||||||
|
|
||||||
(eval-after-load 'compile
|
|
||||||
(lambda()
|
|
||||||
(add-to-list 'compilation-error-regexp-alist-alist
|
|
||||||
'(c3
|
|
||||||
"^(\\([^:]*\\):\\([0-9]+\\):\\([0-9]+\\)) \\(Warning\\)?.*$"
|
|
||||||
1 2 3 (4)))
|
|
||||||
(add-to-list 'compilation-error-regexp-alist 'c3)))
|
|
||||||
|
|
||||||
(provide 'c3-ts-mode)
|
|
||||||
|
|
||||||
|
|
||||||
;;; c3-ts-mode.el ends here
|
|
||||||
Reference in New Issue
Block a user