idk
This commit is contained in:
		
							parent
							
								
									cd47010729
								
							
						
					
					
						commit
						a96118c33a
					
				
					 3 changed files with 344 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -3810,6 +3810,8 @@ I'd like to start learning and using rust if I can.
 | 
			
		|||
#+begin_src emacs-lisp
 | 
			
		||||
(use-package ron-mode
 | 
			
		||||
  :mode "\\.ron\\'")
 | 
			
		||||
 | 
			
		||||
(load-file "./wgsl-ts-mode.el")
 | 
			
		||||
#+end_src
 | 
			
		||||
 | 
			
		||||
*** Web
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								init.el
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								init.el
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -2820,6 +2820,8 @@ targets."
 | 
			
		|||
(use-package ron-mode
 | 
			
		||||
  :mode "\\.ron\\'")
 | 
			
		||||
 | 
			
		||||
(load-file "./wgsl-ts-mode.el")
 | 
			
		||||
 | 
			
		||||
(defun chris/web-mode-setup ()
 | 
			
		||||
  "some setup for web development"
 | 
			
		||||
  (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…
	
	Add table
		Add a link
		
	
		Reference in a new issue