idk
This commit is contained in:
parent
cd47010729
commit
a96118c33a
|
@ -3810,6 +3810,8 @@ I'd like to start learning and using rust if I can.
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(use-package ron-mode
|
(use-package ron-mode
|
||||||
:mode "\\.ron\\'")
|
:mode "\\.ron\\'")
|
||||||
|
|
||||||
|
(load-file "./wgsl-ts-mode.el")
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
*** Web
|
*** Web
|
||||||
|
|
2
init.el
2
init.el
|
@ -2820,6 +2820,8 @@ targets."
|
||||||
(use-package ron-mode
|
(use-package ron-mode
|
||||||
:mode "\\.ron\\'")
|
:mode "\\.ron\\'")
|
||||||
|
|
||||||
|
(load-file "./wgsl-ts-mode.el")
|
||||||
|
|
||||||
(defun chris/web-mode-setup ()
|
(defun chris/web-mode-setup ()
|
||||||
"some setup for web development"
|
"some setup for web development"
|
||||||
(setq-local completion-at-point-functions
|
(setq-local completion-at-point-functions
|
||||||
|
|
340
wgsl-ts-mode.el
Normal file
340
wgsl-ts-mode.el
Normal file
|
@ -0,0 +1,340 @@
|
||||||
|
;;; wgsl-ts-mode.el --- Tree-sitter support for the WebGPU Shading Language -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2023 Anthony Cowley
|
||||||
|
;; Author: Anthony Cowley
|
||||||
|
;; URL: https://github.com/acowley/wgsl-ts-mode
|
||||||
|
;; Package-Requires: ((emacs "29.1"))
|
||||||
|
;; Keywords: wgsl tree-sitter
|
||||||
|
;; Version: 1.0
|
||||||
|
|
||||||
|
;; 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 of the License, 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; Syntax highlighting for the WebGPU Shading Language (WGSL) based on a tree-sitter grammar.
|
||||||
|
;;
|
||||||
|
;; The approach taken here is based on `rust-ts-mode' by Randy Taylor.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'prog-mode)
|
||||||
|
(require 'treesit)
|
||||||
|
(require 'c-ts-common)
|
||||||
|
|
||||||
|
(defvar wgsl-ts-mode--operators
|
||||||
|
'("!" "!=" "%" "%=" "&" "&=" "&&" "*" "*=" "+" "+=" "," "-" "-="
|
||||||
|
"->" "." "/" "/=" ":" ";" "<<" "<" "<="
|
||||||
|
"=" "==" ">" ">=" ">>" "@" "^" "^=" "|" "|=" "||")
|
||||||
|
"WGSL operators for tree-sitter font-locking.")
|
||||||
|
|
||||||
|
(defvar wgsl-ts-mode--keywords
|
||||||
|
'("if" "else" "fn" "switch" "case" "break" "default" "loop"
|
||||||
|
"continue" "continuing" "for" "let" "var" "return" "struct"
|
||||||
|
"type" "while")
|
||||||
|
"WGSL keywords for tree-sitter font-locking.")
|
||||||
|
|
||||||
|
(defvar wgsl-ts-mode--builtins
|
||||||
|
'(;; Constructor built-in functions
|
||||||
|
;"array" "bool" "f16" "f32" "i32" "mat2x2" "mat2x3" "mat2x4" "mat3x3"
|
||||||
|
;"mat3x3" "mat3x4" "mat4x2" "mat4x3" "mat4x4" "u32" "vec2" "vec3" "vec4"
|
||||||
|
;; Bit reinterpretation built-in functions
|
||||||
|
"bitcast"
|
||||||
|
;; Logical built-in functions
|
||||||
|
"all" "any" "select"
|
||||||
|
;; Array built-in functions
|
||||||
|
"arrayLength"
|
||||||
|
;; Numeric built-in functions
|
||||||
|
"abs" "acos" "acosh" "asin" "asinh" "atan" "atanh" "atan2" "ceil" "clamp"
|
||||||
|
"cos" "cosh" "countLeadingZeros" "countOneBits" "countTrailingZeros"
|
||||||
|
"cross" "degrees" "determinant" "distance" "dot" "exp" "exp2"
|
||||||
|
"extractBits" "faceForward" "firstLeadingBit" "firstTrailingBit"
|
||||||
|
"floor" "fma" "fract" "frexp" "insertBits" "inverseSqrt" "ldexp"
|
||||||
|
"length" "log" "log2" "max" "min" "mix" "modf" "normalize" "pow"
|
||||||
|
"quantizeToF16" "radians" "reflect" "refract" "reverseBits" "round"
|
||||||
|
"saturate" "sign" "sin" "sinh" "smoothstep" "sqrt" "step" "tan" "tanh"
|
||||||
|
"transpose" "trunc"
|
||||||
|
;; Derivative built-in functions
|
||||||
|
"dpdx" "dpdxCoarse" "dpdxFine" "dpdy" "dpdyCoarse" "dpdyFine" "fwidth"
|
||||||
|
"fwidthCoarse" "fwidthFine"
|
||||||
|
;; Texture built-in functions
|
||||||
|
"textureDimensions" "textureGather" "textureGatherCompare" "textureLoad"
|
||||||
|
"textureNumLayers" "textureNumLevels" "textureNumSamples" "textureSample"
|
||||||
|
"textureSampleBias" "textureSampleCompare" "textureSampleCompareLevel"
|
||||||
|
"textureSampleGrad" "textureSampleLevel" "textureSampleBaseClampToEdge"
|
||||||
|
"textureStore"
|
||||||
|
;; Data packing built-in functions
|
||||||
|
"pack4x8snorm" "pack4x8unorm" "pack2x16snorm" "pack2x16unorm"
|
||||||
|
"pack2x16float"
|
||||||
|
;; Data unpacking built-in functions
|
||||||
|
"unpack4x8snorm" "unpack4x8unorm" "unpack2x16snorm" "unpack2x16unorm"
|
||||||
|
"unpack2x16float"
|
||||||
|
;; Synchronization built-in functions
|
||||||
|
"storageBarrier" "textureBarrier" "workgroupBarrier" "workgroupUniformLoad"
|
||||||
|
;; Built-in inputs and outputs
|
||||||
|
"frag_depth" "front_facing" "global_invocation_id" "instance_index"
|
||||||
|
"local_invocation_id" "local_invocation_index" "num_workgroups"
|
||||||
|
"position" "sample_index" "sample_mask" "vertex_index" "workgroup_id"
|
||||||
|
)
|
||||||
|
"WGSL built-in functions from https://www.w3.org/TR/WGSL/")
|
||||||
|
|
||||||
|
;; Note: The built-in inputs and outputs should perhaps not be lumped
|
||||||
|
;; in with the other built-in keywords. They are used in attributes,
|
||||||
|
;; but classifying them as general built-ins means that any use of
|
||||||
|
;; these identifiers receives the syntax highlighting of a built-in
|
||||||
|
;; value rather than a regular identifier.
|
||||||
|
|
||||||
|
(setq wgsl-ts-mode--builtins-hash-table
|
||||||
|
(let ((tbl (make-hash-table :test 'equal)))
|
||||||
|
(mapc (lambda (x) (puthash x t tbl)) wgsl-ts-mode--builtins)
|
||||||
|
tbl))
|
||||||
|
|
||||||
|
(defun wgsl-ts-mode--is-builtin? (x)
|
||||||
|
(gethash (treesit-node-text x) wgsl-ts-mode--builtins-hash-table))
|
||||||
|
|
||||||
|
(defvar wgsl-ts-mode--font-lock-rules
|
||||||
|
`(:language wgsl
|
||||||
|
:override t
|
||||||
|
:feature comment
|
||||||
|
(([(line_comment) (block_comment)]) @font-lock-comment-face)
|
||||||
|
|
||||||
|
:language wgsl
|
||||||
|
:override t
|
||||||
|
:feature bitcast
|
||||||
|
((bitcast_expression) @font-lock-builtin-face)
|
||||||
|
|
||||||
|
:language wgsl
|
||||||
|
:override t
|
||||||
|
:feature operator
|
||||||
|
(([,@wgsl-ts-mode--operators]) @font-lock-operator-face)
|
||||||
|
|
||||||
|
:language wgsl
|
||||||
|
:override t
|
||||||
|
:feature constant
|
||||||
|
((identifier) @font-lock-constant-face)
|
||||||
|
|
||||||
|
:language wgsl
|
||||||
|
:override t
|
||||||
|
:feature attribute
|
||||||
|
((attribute) @font-lock-preprocessor-face)
|
||||||
|
|
||||||
|
:language wgsl
|
||||||
|
:override t
|
||||||
|
:feature type
|
||||||
|
((type_declaration) @font-lock-type-face)
|
||||||
|
|
||||||
|
:language wgsl
|
||||||
|
:override t
|
||||||
|
:feature funcall
|
||||||
|
((type_constructor_or_function_call_expression) @font-lock-function-call-face)
|
||||||
|
|
||||||
|
:language wgsl
|
||||||
|
:override t
|
||||||
|
:feature definition
|
||||||
|
((function_declaration name: (identifier) @font-lock-function-name-face)
|
||||||
|
(variable_identifier_declaration name: (identifier) @font-lock-property-name-face))
|
||||||
|
|
||||||
|
:language wgsl
|
||||||
|
:override t
|
||||||
|
:feature bracket
|
||||||
|
((["(" ")" "[" "]" "{" "}"]) @font-lock-bracket-face)
|
||||||
|
|
||||||
|
:language wgsl
|
||||||
|
:override t
|
||||||
|
:feature texel_format
|
||||||
|
((texel_format) @font-lock-builtin-face)
|
||||||
|
|
||||||
|
:language wgsl
|
||||||
|
:override t
|
||||||
|
:feature builtin
|
||||||
|
;; (([,@wgsl-ts-mode--builtins]) @font-lock-builtin-face)
|
||||||
|
(((identifier) @font-lock-builtin-face
|
||||||
|
(:pred wgsl-ts-mode--is-builtin? @font-lock-builtin-face)))
|
||||||
|
|
||||||
|
:language wgsl
|
||||||
|
:override t
|
||||||
|
:feature declaration
|
||||||
|
((struct_declaration) @font-lock-keyword-face)
|
||||||
|
|
||||||
|
:language wgsl
|
||||||
|
:override t
|
||||||
|
:feature keyword
|
||||||
|
(([,@wgsl-ts-mode--keywords]) @font-lock-keyword-face)
|
||||||
|
|
||||||
|
:language wgsl
|
||||||
|
:override t
|
||||||
|
:feature address_space
|
||||||
|
(([(address_space) (access_mode)]) @font-lock-builtin-face)
|
||||||
|
|
||||||
|
:language wgsl
|
||||||
|
:override t
|
||||||
|
:feature number
|
||||||
|
(([(float_literal) (int_literal)]) @font-lock-number-face)
|
||||||
|
|
||||||
|
:language wgsl
|
||||||
|
:override t
|
||||||
|
:feature constant
|
||||||
|
((bool_literal) @font-lock-constant-face)
|
||||||
|
|
||||||
|
:language wgsl
|
||||||
|
:override t
|
||||||
|
:feature delimiter
|
||||||
|
((["," "." ";" ":"]) @font-lock-delimiter-face)
|
||||||
|
))
|
||||||
|
|
||||||
|
(defcustom wgsl-ts-mode-indent-offset 2
|
||||||
|
"Number of spaces for each indentation step in `wgsl-ts-mode'."
|
||||||
|
:version "29.1"
|
||||||
|
:type 'integer
|
||||||
|
:safe 'integerp
|
||||||
|
:group 'wgsl)
|
||||||
|
|
||||||
|
(defvar wgsl-ts-mode--indent-rules
|
||||||
|
`((wgsl
|
||||||
|
((parent-is "source_file") column-0 0)
|
||||||
|
((node-is ")") parent-bol 0)
|
||||||
|
((node-is "]") parent-bol 0)
|
||||||
|
((node-is "}") (and parent parent-bol) 0)
|
||||||
|
((and (parent-is "comment") c-ts-common-looking-at-star)
|
||||||
|
c-ts-common-comment-start-after-first-star -1)
|
||||||
|
((parent-is "comment") prev-adaptive-prefix 0)
|
||||||
|
((parent-is "arguments") parent-bol wgsl-ts-mode-indent-offset)
|
||||||
|
((parent-is "assignment_statement") parent-bol wgsl-ts-mode-indent-offset)
|
||||||
|
((parent-is "array_expression") parent-bol wgsl-ts-mode-indent-offset)
|
||||||
|
((parent-is "binary_expression") parent-bol wgsl-ts-mode-indent-offset)
|
||||||
|
((parent-is "compound_statement") parent-bol wgsl-ts-mode-indent-offset)
|
||||||
|
((parent-is "declaration_list") parent-bol wgsl-ts-mode-indent-offset)
|
||||||
|
((parent-is "enum_variant_list") parent-bol wgsl-ts-mode-indent-offset)
|
||||||
|
((parent-is "field_declaration_list") parent-bol wgsl-ts-mode-indent-offset)
|
||||||
|
((parent-is "field_expression") parent-bol wgsl-ts-mode-indent-offset)
|
||||||
|
((parent-is "field_initializer_list") parent-bol wgsl-ts-mode-indent-offset)
|
||||||
|
((parent-is "let_declaration") parent-bol wgsl-ts-mode-indent-offset)
|
||||||
|
((parent-is "var_declaration") parent-bol wgsl-ts-mode-indent-offset)
|
||||||
|
((parent-is "parameters") parent-bol wgsl-ts-mode-indent-offset)
|
||||||
|
((parent-is "struct_pattern") parent-bol wgsl-ts-mode-indent-offset)))
|
||||||
|
"Tree-sitter indent rules for `wgsl-ts-mode'.")
|
||||||
|
|
||||||
|
(defun wgsl-ts-mode--syntax-propertize (beg end)
|
||||||
|
"Apply syntax properties to special characters between BEG and END.
|
||||||
|
|
||||||
|
Apply syntax properties to various special characters with
|
||||||
|
contextual meaning between BEG and END.
|
||||||
|
|
||||||
|
The apostrophe \\=' should be treated as string when used for char literals.
|
||||||
|
|
||||||
|
< and > are usually punctuation, e.g., as greater/less-than. But
|
||||||
|
when used for types, they should be considered pairs.
|
||||||
|
|
||||||
|
This function checks for < and > in the changed RANGES and apply
|
||||||
|
appropriate text property to alter the syntax of template
|
||||||
|
delimiters < and >'s."
|
||||||
|
(goto-char beg)
|
||||||
|
(while (search-forward "'" end t)
|
||||||
|
(when (string-equal "char_literal"
|
||||||
|
(treesit-node-type
|
||||||
|
(treesit-node-at (match-beginning 0))))
|
||||||
|
(put-text-property (match-beginning 0) (match-end 0)
|
||||||
|
'syntax-table (string-to-syntax "\""))))
|
||||||
|
(goto-char beg)
|
||||||
|
(while (re-search-forward (rx (or "<" ">")) end t)
|
||||||
|
(pcase (treesit-node-type
|
||||||
|
(treesit-node-parent
|
||||||
|
(treesit-node-at (match-beginning 0))))
|
||||||
|
(;(or "type_declaration" "type_parameters")
|
||||||
|
"type_declaration"
|
||||||
|
(put-text-property (match-beginning 0)
|
||||||
|
(match-end 0)
|
||||||
|
'syntax-table
|
||||||
|
(pcase (char-before)
|
||||||
|
(?< '(4 . ?>))
|
||||||
|
(?> '(5 . ?<))))))))
|
||||||
|
|
||||||
|
(defun wgsl-ts-mode--defun-name (node)
|
||||||
|
"Return the defun name of NODE.
|
||||||
|
Return nil if there is no name or if NODE is not a defun node."
|
||||||
|
(pcase (treesit-node-type node)
|
||||||
|
("function_declaration"
|
||||||
|
(treesit-node-text
|
||||||
|
(treesit-node-child-by-field-name node "name") t))
|
||||||
|
("struct_declaration"
|
||||||
|
(treesit-node-text
|
||||||
|
(treesit-node-child-by-field-name node "name") t))
|
||||||
|
("type_declaration"
|
||||||
|
(treesit-node-text
|
||||||
|
(treesit-node-child-by-field-name node "name") t))))
|
||||||
|
|
||||||
|
(defvar wgsl-ts-mode--syntax-table
|
||||||
|
(let ((table (make-syntax-table)))
|
||||||
|
(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 ?^ "." table)
|
||||||
|
(modify-syntax-entry ?! "." table)
|
||||||
|
(modify-syntax-entry ?@ "." table)
|
||||||
|
(modify-syntax-entry ?~ "." table)
|
||||||
|
(modify-syntax-entry ?< "." table)
|
||||||
|
(modify-syntax-entry ?> "." 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 `wgsl-ts-mode'.")
|
||||||
|
|
||||||
|
(defun wgsl-ts-setup ()
|
||||||
|
"Setup tree-sitter for wgsl-ts-mode."
|
||||||
|
(setq-local syntax-propertize-function
|
||||||
|
#'wgsl-ts-mode--syntax-propertize)
|
||||||
|
(c-ts-common-comment-setup)
|
||||||
|
|
||||||
|
(setq-local treesit-font-lock-settings
|
||||||
|
(apply #'treesit-font-lock-rules
|
||||||
|
wgsl-ts-mode--font-lock-rules))
|
||||||
|
|
||||||
|
(setq-local treesit-font-lock-feature-list
|
||||||
|
'((comment definition)
|
||||||
|
(keyword string)
|
||||||
|
(assignment attribute builtin constant escape-sequence number
|
||||||
|
type address_space texel_format bitcast funcall)
|
||||||
|
(bracket delimiter error function operator property variable)))
|
||||||
|
|
||||||
|
(setq-local treesit-simple-imenu-settings
|
||||||
|
`(("Struct" "\\`struct_declaration\\'" nil nil)
|
||||||
|
("Fn" "\\`function_declaration\\'" nil nil)))
|
||||||
|
|
||||||
|
(setq-local treesit-font-lock-level 4)
|
||||||
|
(setq-local indent-tabs-mode nil
|
||||||
|
treesit-simple-indent-rules wgsl-ts-mode--indent-rules)
|
||||||
|
(setq-local treesit-defun-type-regexp
|
||||||
|
(regexp-opt '("function_declaration"
|
||||||
|
"struct_declaration")))
|
||||||
|
(setq-local treesit-defun-name-function #'wgsl-ts-mode--defun-name)
|
||||||
|
(treesit-major-mode-setup))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(define-derived-mode wgsl-ts-mode prog-mode "WGSL[ts]"
|
||||||
|
"Major mode for editing WGSL with tree-sitter."
|
||||||
|
:syntax-table wgsl-ts-mode--syntax-table
|
||||||
|
(when (treesit-ready-p 'wgsl)
|
||||||
|
(treesit-parser-create 'wgsl)
|
||||||
|
(wgsl-ts-setup)))
|
||||||
|
|
||||||
|
(if (treesit-ready-p 'wgsl)
|
||||||
|
(add-to-list 'auto-mode-alist '("\\.wgsl\\'" . wgsl-ts-mode)))
|
||||||
|
|
||||||
|
(provide 'wgsl-ts-mode)
|
||||||
|
|
||||||
|
;;; wgsl-ts-mode.el ends here
|
Loading…
Reference in a new issue