Compare commits

...

10 commits

3 changed files with 517 additions and 44 deletions

View file

@ -97,11 +97,11 @@ Let's start by making some basic ui changes like turning off the scrollbar, tool
#+begin_src emacs-lisp
(setq inhibit-startup-message t)
(scroll-bar-mode -1)
(setq default-frame-alist '((undecorated . t)))
(tool-bar-mode -1)
(tooltip-mode -1)
(set-fringe-mode +1)
(scroll-bar-mode -1)
(menu-bar-mode -1)
(blink-cursor-mode -1)
(column-number-mode +1)
@ -425,6 +425,7 @@ Let's make xref use ripgrep instead of grep for speed.
I am currently using NixOS. In order for emacs to have access to certain programs, we need to set some environment variables
#+begin_src emacs-lisp
(add-to-list 'exec-path "/usr/bin")
(add-to-list 'exec-path "~/.cargo/bin")
(setenv "NIX_CONF_DIR" "/etc/nix")
(setenv "NIX_REMOTE" "daemon")
(setenv "XCURSOR_THEME" "phinger-cursors-light")
@ -581,6 +582,9 @@ Here let's try to add ligatures to our font system since the VictorMono Nerd Fon
There are two major packages we need to get the functionality I desire. Evil and general.
*** Evil
:PROPERTIES:
:ID: 20250304T164537.064599
:END:
#+begin_src emacs-lisp
(use-package evil
@ -614,6 +618,12 @@ This evil-collection package includes a lot of other evil based things.
:after evil
:init (evil-escape-mode +1)
:config
(defun chris/toggle-evil-escape-sequence ()
(interactive)
(if (string= evil-escape-key-sequence "ae")
(setq evil-escape-key-sequence "fd")
(setq evil-escape-key-sequence "ae")))
(setq evil-escape-key-sequence (kbd "ae")
evil-escape-delay 0.3))
#+end_src
@ -772,6 +782,9 @@ This evil-collection package includes a lot of other evil based things.
"e" '(sly-eval-defun :which-key "evaluate top level"))
(general-def 'minibuffer-local-map
"C-v" 'evil-paste-after)
(general-def 'visual
"<down>" 'evil-next-visual-line
"<up>" 'evil-previous-visual-line)
(general-def 'normal
"gcc" 'comment-line
"K" 'helpful-at-point
@ -2362,6 +2375,17 @@ Idk, let's try this i guess
"lew" 'ellama-improve-wording
"ls" 'ellama-provider-select))
#+end_src
*** aider
#+begin_src emacs-lisp
(use-package aidermacs
:config
(setq aidermacs-default-model "ollama_chat/llama3.2:latest"
aidermacs-backend 'comint
aidermacs-watch-files t)
(add-hook 'aidermacs-before-run-backend-hook
((lambda ()
(setenv "OLLAMA_API_BASE" "https://ai.tfcconnection.org")))))
#+end_src
** Jinx
Jinx is an enchanted spell checker for emacs. I think I'll just turn it on globally for a while and see how I feel.
@ -3248,7 +3272,14 @@ In order to view created websites, I'll use =simple-httpd= to get a web server r
Avy provides a lot of functions to search through the current buffer. Most of the time I use evil or consult functions to find what I'm looking for, but avy provides a lot of small movements that are more useful for visible movements.
#+begin_src emacs-lisp
(use-package avy
:after evil)
:after evil
:config
(setq avy-keys '(99 105 101 97 104 116 115 110))
:general
(general-define-key
:states 'normal
:keymaps '(override rustic-mode)
"gh" 'avy-goto-word-0))
#+end_src
These are some evil bindings to avy.
@ -3779,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
@ -3945,13 +3978,13 @@ I'm gonnna dabble in using clojure for the website
:ensure t)
;; then install the checker as soon as `clojure-mode' is loaded
(use-package clojure-mode
(use-package clojure-ts-mode
:ensure t
:config
(require 'flycheck-clj-kondo))
(use-package cider
:after clojure-mode)
:after clojure-ts-mode)
#+end_src
*** Yaml
@ -4027,6 +4060,8 @@ It's probably smart to have markdown.
("\\.rmd\\'". markdown-mode))
:config
(setq markdown-regex-yaml-metadata-border "\\(-\\{3\\}\\|+\\{3\\}\\)$")
(dolist (face
'((markdown-header-face-1 1.4 ultra-bold)
(markdown-header-face-2 1.2 extra-bold)
@ -4171,6 +4206,13 @@ I'm making a small function in here to open files in the appropriate program usi
dired-kill-when-opening-new-dired-buffer t)
(add-hook 'dired-mode-hook 'chris/setup-dired)
(defun chris/convert-doc-to-org ()
"Convert a word doc to an org file"
(interactive)
(let* ((file (dired-get-filename))
(out (string-replace "docx" "org" file)))
(async-shell-command (format "pandoc --wrap=preserve -o '%s' '%s'" out file))))
(custom-set-faces '(dired-directory ((t :foreground "#57c7ff" :inherit dired-header))))
:general
@ -4814,7 +4856,7 @@ Let's add our own eshell prompt. and set the password cache to a significantly h
(setq eshell-banner-message "")
(setq eshell-path-env "/usr/local/bin:/usr/bin:/opt/android-sdk/cmdline-tools/latest/bin:/home/chris/.cargo/bin")
(add-to-list 'eshell-path-env-list "/home/chris/.cargo/bin")
;; this makes it so flutter works properly
(setenv "ANDROID_SDK_ROOT" "/opt/android-sdk")
@ -5035,23 +5077,50 @@ With empv we can perhaps control mpv much more fine grainly and even search yout
(message args)
(empv-play-or-enqueue video))
(defun chris/empv-yt-dlp ()
(defun chris/empv-yt-dlp (&optional file)
"Download the current video and and play it"
(interactive)
(let* ((item (empv-youtube-results--current-item))
(video-id (alist-get 'videoId item))
(playlist-id (alist-get 'playlistId item))
(title (alist-get 'title item))
(url (format
(setq lexical-binding t)
(let* ((item (when (not file) (empv-youtube-results--current-item)))
(video-id (when (not file) (alist-get 'videoId item)))
(playlist-id (when (not file) (alist-get 'playlistId item)))
(url (if file
(progn
(message file)
(string-replace "inv.cochrun.xyz" "youtube.com" file))
(format
"https://youtube.com/%s=%s"
(if video-id "watch?v" "playlist?list")
(or video-id playlist-id))))
(async-shell-command (concat
"yt-dlp" " -o '/home/chris/vids/%(title)s.%(ext)s'"
" \"" url "\""))
(let ((file (format "/home/chris/vids/%s.%s" title "webm")))
(empv-play file))
(message url)))
(title (if file (shell-command-to-string
(format "yt-dlp --no-warnings --quiet --get-title %s" url))
(alist-get 'title item)))
(output-buffer (generate-new-buffer "*yt-dlp*"))
(process (progn
(message "Starting to download %s at %s" title url)
(make-process
:name "yt-dlp"
:buffer output-buffer
:command `("yt-dlp" "-o"
"~/vids/%(title)s.%(ext)s"
"-f best[ext=mp4]"
,(cl-coerce url 'string)
"--embed-thumbnail"
"--sponsorblock-remove=sponsor,intro,outro"))
(get-buffer-process output-buffer)))
(enqueue `(lambda (process event)
(when (eq (process-status process) 'exit)
(progn (message "running %s because %s" process event)
(empv-enqueue (concat "/home/chris/vids/" (string-trim ,title) ".mp4"))
;; (kill-buffer ,output-buffer)
)))))
(message url)
(if (process-live-p process)
(set-process-sentinel
process enqueue)
(message "No process running"))))
;; (chris/empv-yt-dlp "https://inv.cochrun.xyz/watch?v=mNYcUMZfSP0")
(defun chris/empv-yt-dlp-jellyfin ()
"Grabs the current video at point and downloads it to my jellyfin server"
@ -5258,7 +5327,7 @@ q quit-window
(elfeed-search-untag-all-unread)
(if (process-live-p proc)
(set-process-sentinel
proc `(empv-play-or-enqueue
proc `(empv-enqueue
,(concat "/home/chris/vids/" title ".webm")))
(message "No process running"))))

102
init.el
View file

@ -9,11 +9,11 @@
(setq inhibit-startup-message t)
(scroll-bar-mode -1)
(setq default-frame-alist '((undecorated . t)))
(tool-bar-mode -1)
(tooltip-mode -1)
(set-fringe-mode +1)
(scroll-bar-mode -1)
(menu-bar-mode -1)
(blink-cursor-mode -1)
(column-number-mode +1)
@ -207,6 +207,7 @@
(setq xref-search-program 'ripgrep)
(add-to-list 'exec-path "/usr/bin")
(add-to-list 'exec-path "~/.cargo/bin")
(setenv "NIX_CONF_DIR" "/etc/nix")
(setenv "NIX_REMOTE" "daemon")
(setenv "XCURSOR_THEME" "phinger-cursors-light")
@ -350,6 +351,12 @@
:after evil
:init (evil-escape-mode +1)
:config
(defun chris/toggle-evil-escape-sequence ()
(interactive)
(if (string= evil-escape-key-sequence "ae")
(setq evil-escape-key-sequence "fd")
(setq evil-escape-key-sequence "ae")))
(setq evil-escape-key-sequence (kbd "ae")
evil-escape-delay 0.3))
@ -500,6 +507,9 @@
"e" '(sly-eval-defun :which-key "evaluate top level"))
(general-def 'minibuffer-local-map
"C-v" 'evil-paste-after)
(general-def 'visual
"<down>" 'evil-next-visual-line
"<up>" 'evil-previous-visual-line)
(general-def 'normal
"gcc" 'comment-line
"K" 'helpful-at-point
@ -1775,6 +1785,15 @@ Describe everything that follows in the present tense, in response to what I typ
"la" 'gptel-send
"lm" 'gptel-menu))
(use-package aidermacs
:config
(setq aidermacs-default-model "ollama_chat/llama3.2:latest"
aidermacs-backend 'comint
aidermacs-watch-files t)
(add-hook 'aidermacs-before-run-backend-hook
((lambda ()
(setenv "OLLAMA_API_BASE" "https://ai.tfcconnection.org")))))
(use-package jinx
;; :hook (emacs-startup . global-jinx-mode)
:init (flyspell-mode -1)
@ -2346,7 +2365,14 @@ targets."
:ensure t)
(use-package avy
:after evil)
:after evil
:config
(setq avy-keys '(99 105 101 97 104 116 115 110))
:general
(general-define-key
:states 'normal
:keymaps '(override rustic-mode)
"gh" 'avy-goto-word-0))
(use-package evil-avy
:after avy
@ -2794,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
@ -2875,13 +2903,13 @@ targets."
:ensure t)
;; then install the checker as soon as `clojure-mode' is loaded
(use-package clojure-mode
(use-package clojure-ts-mode
:ensure t
:config
(require 'flycheck-clj-kondo))
(use-package cider
:after clojure-mode)
:after clojure-ts-mode)
(use-package yaml-mode
:mode ("\\.yml\\'" . yaml-mode))
@ -2928,6 +2956,8 @@ targets."
("\\.rmd\\'". markdown-mode))
:config
(setq markdown-regex-yaml-metadata-border "\\(-\\{3\\}\\|+\\{3\\}\\)$")
(dolist (face
'((markdown-header-face-1 1.4 ultra-bold)
(markdown-header-face-2 1.2 extra-bold)
@ -3042,6 +3072,13 @@ targets."
dired-kill-when-opening-new-dired-buffer t)
(add-hook 'dired-mode-hook 'chris/setup-dired)
(defun chris/convert-doc-to-org ()
"Convert a word doc to an org file"
(interactive)
(let* ((file (dired-get-filename))
(out (string-replace "docx" "org" file)))
(async-shell-command (format "pandoc --wrap=preserve -o '%s' '%s'" out file))))
(custom-set-faces '(dired-directory ((t :foreground "#57c7ff" :inherit dired-header))))
:general
@ -3500,7 +3537,7 @@ targets."
(setq eshell-banner-message "")
(setq eshell-path-env "/usr/local/bin:/usr/bin:/opt/android-sdk/cmdline-tools/latest/bin:/home/chris/.cargo/bin")
(add-to-list 'eshell-path-env-list "/home/chris/.cargo/bin")
;; this makes it so flutter works properly
(setenv "ANDROID_SDK_ROOT" "/opt/android-sdk")
@ -3684,23 +3721,50 @@ targets."
(message args)
(empv-play-or-enqueue video))
(defun chris/empv-yt-dlp ()
(defun chris/empv-yt-dlp (&optional file)
"Download the current video and and play it"
(interactive)
(let* ((item (empv-youtube-results--current-item))
(video-id (alist-get 'videoId item))
(playlist-id (alist-get 'playlistId item))
(title (alist-get 'title item))
(url (format
(setq lexical-binding t)
(let* ((item (when (not file) (empv-youtube-results--current-item)))
(video-id (when (not file) (alist-get 'videoId item)))
(playlist-id (when (not file) (alist-get 'playlistId item)))
(url (if file
(progn
(message file)
(string-replace "inv.cochrun.xyz" "youtube.com" file))
(format
"https://youtube.com/%s=%s"
(if video-id "watch?v" "playlist?list")
(or video-id playlist-id))))
(async-shell-command (concat
"yt-dlp" " -o '/home/chris/vids/%(title)s.%(ext)s'"
" \"" url "\""))
(let ((file (format "/home/chris/vids/%s.%s" title "webm")))
(empv-play file))
(message url)))
(title (if file (shell-command-to-string
(format "yt-dlp --no-warnings --quiet --get-title %s" url))
(alist-get 'title item)))
(output-buffer (generate-new-buffer "*yt-dlp*"))
(process (progn
(message "Starting to download %s at %s" title url)
(make-process
:name "yt-dlp"
:buffer output-buffer
:command `("yt-dlp" "-o"
"~/vids/%(title)s.%(ext)s"
"-f best[ext=mp4]"
,(cl-coerce url 'string)
"--embed-thumbnail"
"--sponsorblock-remove=sponsor,intro,outro"))
(get-buffer-process output-buffer)))
(enqueue `(lambda (process event)
(when (eq (process-status process) 'exit)
(progn (message "running %s because %s" process event)
(empv-enqueue (concat "/home/chris/vids/" (string-trim ,title) ".mp4"))
;; (kill-buffer ,output-buffer)
)))))
(message url)
(if (process-live-p process)
(set-process-sentinel
process enqueue)
(message "No process running"))))
;; (chris/empv-yt-dlp "https://inv.cochrun.xyz/watch?v=mNYcUMZfSP0")
(defun chris/empv-yt-dlp-jellyfin ()
"Grabs the current video at point and downloads it to my jellyfin server"
@ -3825,7 +3889,7 @@ targets."
(elfeed-search-untag-all-unread)
(if (process-live-p proc)
(set-process-sentinel
proc `(empv-play-or-enqueue
proc `(empv-enqueue
,(concat "/home/chris/vids/" title ".webm")))
(message "No process running"))))

340
wgsl-ts-mode.el Normal file
View 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