Compare commits

...

10 commits

Author SHA1 Message Date
Chris Cochrun
3032aefc86 working aider 2025-06-19 06:23:37 -05:00
Chris Cochrun
9d611fb93f adding gdb stuff 2025-06-04 11:02:50 -05:00
Chris Cochrun
e401a1c326 adding audio dir to empv 2025-05-23 10:20:49 -05:00
Chris Cochrun
4cbda36866 rustic tweaks 2025-05-20 06:36:53 -05:00
Chris Cochrun
acda63857e comment out wgsl mode 2025-05-05 10:38:15 -05:00
Chris Cochrun
a96118c33a idk 2025-05-01 09:29:03 -05:00
Chris Cochrun
cd47010729 fixing empv-yt-dlp 2025-04-29 14:58:00 -05:00
Chris Cochrun
2a45a5decf making emacs undecorated 2025-04-29 10:10:57 -05:00
Chris Cochrun
f0eed6f298 fixing visual lines 2025-04-22 09:47:48 -05:00
Chris Cochrun
967709f37f switching clojure to clojure-ts-mode 2025-04-09 23:29:28 -05:00
4 changed files with 427 additions and 25 deletions

1
.gitignore vendored
View file

@ -12,3 +12,4 @@ bookmarks
elpa elpa
recentf recentf
.aider*

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 #+begin_src emacs-lisp
(setq inhibit-startup-message t) (setq inhibit-startup-message t)
(scroll-bar-mode -1) (setq default-frame-alist '((undecorated . t)))
(tool-bar-mode -1) (tool-bar-mode -1)
(tooltip-mode -1) (tooltip-mode -1)
(set-fringe-mode +1) (set-fringe-mode +1)
(scroll-bar-mode -1)
(menu-bar-mode -1) (menu-bar-mode -1)
(blink-cursor-mode -1) (blink-cursor-mode -1)
(column-number-mode +1) (column-number-mode +1)
@ -782,6 +782,9 @@ This evil-collection package includes a lot of other evil based things.
"e" '(sly-eval-defun :which-key "evaluate top level")) "e" '(sly-eval-defun :which-key "evaluate top level"))
(general-def 'minibuffer-local-map (general-def 'minibuffer-local-map
"C-v" 'evil-paste-after) "C-v" 'evil-paste-after)
(general-def 'visual
"<down>" 'evil-next-visual-line
"<up>" 'evil-previous-visual-line)
(general-def 'normal (general-def 'normal
"gcc" 'comment-line "gcc" 'comment-line
"K" 'helpful-at-point "K" 'helpful-at-point
@ -2285,7 +2288,7 @@ GPTEL is a package that uses chatGPT to get some text generation in org-mode
#+begin_src emacs-lisp #+begin_src emacs-lisp
(use-package gptel (use-package gptel
:init :init
(setq gptel-model "llama3.2:3b-instruct-fp16" (setq gptel-model "gemma3:4b-it-q8_0"
gptel-backend (gptel-make-ollama "ollama" gptel-backend (gptel-make-ollama "ollama"
:host "ai.tfcconnection.org" :host "ai.tfcconnection.org"
:protocol "https" :protocol "https"
@ -2372,6 +2375,15 @@ Idk, let's try this i guess
"lew" 'ellama-improve-wording "lew" 'ellama-improve-wording
"ls" 'ellama-provider-select)) "ls" 'ellama-provider-select))
#+end_src #+end_src
*** aider
#+begin_src emacs-lisp
(use-package aidermacs
:config
(setenv "OLLAMA_API_BASE" "https://ai.tfcconnection.org")
(setq aidermacs-default-model "ollama_chat/llama3.2:latest"
aidermacs-backend 'comint
aidermacs-watch-files t))
#+end_src
** Jinx ** 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. 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.
@ -3512,6 +3524,12 @@ Let's also set =hl-line-mode= to be on for comint and prog modes
(add-hook 'prog-mode-hook 'hs-minor-mode) (add-hook 'prog-mode-hook 'hs-minor-mode)
#+END_SRC #+END_SRC
And here is some setup for GDB when I need to use it.
#+begin_src emacs-lisp
(setq gdb-many-windows t
gdb-show-main t)
#+end_src
*** Lisp *** Lisp
:PROPERTIES: :PROPERTIES:
:ID: 20250107T125200.695450 :ID: 20250107T125200.695450
@ -3754,6 +3772,8 @@ I'd like to start learning and using rust if I can.
rustic-clippy-arguments "-- -W clippy::pedantic -W clippy::perf -W clippy::nursery -W clippy::unwrap_used" rustic-clippy-arguments "-- -W clippy::pedantic -W clippy::perf -W clippy::nursery -W clippy::unwrap_used"
rustic-rustfmt-args "--edition 2021" rustic-rustfmt-args "--edition 2021"
rust-format-on-save t rust-format-on-save t
rustic-cargo-clippy-trigger-fix t
rustic-cargo-clippy-fix-args "--allow-dirty"
rustic-test-arguments "--benches --tests --all-features -- --nocapture") rustic-test-arguments "--benches --tests --all-features -- --nocapture")
(advice-add 'eglot-completion-at-point :around #'cape-wrap-buster) (advice-add 'eglot-completion-at-point :around #'cape-wrap-buster)
(add-to-list 'compilation-error-regexp-alist rustic-compilation-error) (add-to-list 'compilation-error-regexp-alist rustic-compilation-error)
@ -3796,6 +3816,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
@ -3962,13 +3984,13 @@ I'm gonnna dabble in using clojure for the website
:ensure t) :ensure t)
;; then install the checker as soon as `clojure-mode' is loaded ;; then install the checker as soon as `clojure-mode' is loaded
(use-package clojure-mode (use-package clojure-ts-mode
:ensure t :ensure t
:config :config
(require 'flycheck-clj-kondo)) (require 'flycheck-clj-kondo))
(use-package cider (use-package cider
:after clojure-mode) :after clojure-ts-mode)
#+end_src #+end_src
*** Yaml *** Yaml
@ -4044,6 +4066,8 @@ It's probably smart to have markdown.
("\\.rmd\\'". markdown-mode)) ("\\.rmd\\'". markdown-mode))
:config :config
(setq markdown-regex-yaml-metadata-border "\\(-\\{3\\}\\|+\\{3\\}\\)$")
(dolist (face (dolist (face
'((markdown-header-face-1 1.4 ultra-bold) '((markdown-header-face-1 1.4 ultra-bold)
(markdown-header-face-2 1.2 extra-bold) (markdown-header-face-2 1.2 extra-bold)
@ -5048,6 +5072,7 @@ With empv we can perhaps control mpv much more fine grainly and even search yout
(setq empv-invidious-instance "https://inv.cochrun.xyz/api/v1" (setq empv-invidious-instance "https://inv.cochrun.xyz/api/v1"
empv-video-file-extensions '("mkv" "mp4" "avi" "mov" "webm") empv-video-file-extensions '("mkv" "mp4" "avi" "mov" "webm")
empv-mpv-args '("--no-terminal" "--idle" "--input-ipc-server=/tmp/empv-socket") empv-mpv-args '("--no-terminal" "--idle" "--input-ipc-server=/tmp/empv-socket")
empv-audio-dir "~/music"
empv-video-dir "~/vids") empv-video-dir "~/vids")
(empv-embark-initialize-extra-actions) (empv-embark-initialize-extra-actions)
(general-auto-unbind-keys) (general-auto-unbind-keys)
@ -5066,14 +5091,17 @@ With empv we can perhaps control mpv much more fine grainly and even search yout
(let* ((item (when (not file) (empv-youtube-results--current-item))) (let* ((item (when (not file) (empv-youtube-results--current-item)))
(video-id (when (not file) (alist-get 'videoId item))) (video-id (when (not file) (alist-get 'videoId item)))
(playlist-id (when (not file) (alist-get 'playlistId item))) (playlist-id (when (not file) (alist-get 'playlistId item)))
(title (if file (shell-command-to-string (url (if file
(format "yt-dlp --no-warnings --quiet --get-title %s" file)) (progn
(alist-get 'title item))) (message file)
(url (if file file (string-replace "inv.cochrun.xyz" "youtube.com" file))
(format (format
"https://youtube.com/%s=%s" "https://youtube.com/%s=%s"
(if video-id "watch?v" "playlist?list") (if video-id "watch?v" "playlist?list")
(or video-id playlist-id)))) (or video-id playlist-id))))
(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*")) (output-buffer (generate-new-buffer "*yt-dlp*"))
(process (progn (process (progn
(message "Starting to download %s at %s" title url) (message "Starting to download %s at %s" title url)
@ -5082,20 +5110,25 @@ With empv we can perhaps control mpv much more fine grainly and even search yout
:buffer output-buffer :buffer output-buffer
:command `("yt-dlp" "-o" :command `("yt-dlp" "-o"
"~/vids/%(title)s.%(ext)s" "~/vids/%(title)s.%(ext)s"
;; "-f best[ext=mp4]" "-f best[ext=mp4]"
,(cl-coerce url 'string) ,(cl-coerce url 'string)
"--embed-thumbnail" "--embed-thumbnail"
"--sponsorblock-remove=sponsor,intro,outro")) "--sponsorblock-remove=sponsor,intro,outro"))
(get-buffer-process output-buffer))) (get-buffer-process output-buffer)))
(enqueue `(lambda (process event) (enqueue `(lambda (process event)
(message "running %s because %s" process event) (when (eq (process-status process) 'exit)
(empv-enqueue (concat "/home/chris/vids/" (string-trim ,title) ".mp4"))))) (progn (message "running %s because %s" process event)
(empv-enqueue (concat "/home/chris/vids/" (string-trim ,title) ".mp4"))
;; (kill-buffer ,output-buffer)
)))))
(message url) (message url)
(if (process-live-p process) (if (process-live-p process)
(set-process-sentinel (set-process-sentinel
process enqueue) process enqueue)
(message "No process running")))) (message "No process running"))))
;; (chris/empv-yt-dlp "https://inv.cochrun.xyz/watch?v=mNYcUMZfSP0")
(defun chris/empv-yt-dlp-jellyfin () (defun chris/empv-yt-dlp-jellyfin ()
"Grabs the current video at point and downloads it to my jellyfin server" "Grabs the current video at point and downloads it to my jellyfin server"
(interactive) (interactive)

52
init.el
View file

@ -9,11 +9,11 @@
(setq inhibit-startup-message t) (setq inhibit-startup-message t)
(scroll-bar-mode -1) (setq default-frame-alist '((undecorated . t)))
(tool-bar-mode -1) (tool-bar-mode -1)
(tooltip-mode -1) (tooltip-mode -1)
(set-fringe-mode +1) (set-fringe-mode +1)
(scroll-bar-mode -1)
(menu-bar-mode -1) (menu-bar-mode -1)
(blink-cursor-mode -1) (blink-cursor-mode -1)
(column-number-mode +1) (column-number-mode +1)
@ -507,6 +507,9 @@
"e" '(sly-eval-defun :which-key "evaluate top level")) "e" '(sly-eval-defun :which-key "evaluate top level"))
(general-def 'minibuffer-local-map (general-def 'minibuffer-local-map
"C-v" 'evil-paste-after) "C-v" 'evil-paste-after)
(general-def 'visual
"<down>" 'evil-next-visual-line
"<up>" 'evil-previous-visual-line)
(general-def 'normal (general-def 'normal
"gcc" 'comment-line "gcc" 'comment-line
"K" 'helpful-at-point "K" 'helpful-at-point
@ -1757,7 +1760,7 @@ Also see `chris/window-delete-popup-frame'." command)
(use-package gptel (use-package gptel
:init :init
(setq gptel-model "llama3.2:3b-instruct-fp16" (setq gptel-model "gemma3:4b-it-q8_0"
gptel-backend (gptel-make-ollama "ollama" gptel-backend (gptel-make-ollama "ollama"
:host "ai.tfcconnection.org" :host "ai.tfcconnection.org"
:protocol "https" :protocol "https"
@ -1782,6 +1785,13 @@ Describe everything that follows in the present tense, in response to what I typ
"la" 'gptel-send "la" 'gptel-send
"lm" 'gptel-menu)) "lm" 'gptel-menu))
(use-package aidermacs
:config
(setenv "OLLAMA_API_BASE" "https://ai.tfcconnection.org")
(setq aidermacs-default-model "ollama_chat/llama3.2:latest"
aidermacs-backend 'comint
aidermacs-watch-files t))
(use-package jinx (use-package jinx
;; :hook (emacs-startup . global-jinx-mode) ;; :hook (emacs-startup . global-jinx-mode)
:init (flyspell-mode -1) :init (flyspell-mode -1)
@ -2576,6 +2586,9 @@ targets."
(add-hook 'prog-mode-hook 'hl-line-mode) (add-hook 'prog-mode-hook 'hl-line-mode)
(add-hook 'prog-mode-hook 'hs-minor-mode) (add-hook 'prog-mode-hook 'hs-minor-mode)
(setq gdb-many-windows t
gdb-show-main t)
(use-package smartparens (use-package smartparens
:config :config
(smartparens-global-mode +1) (smartparens-global-mode +1)
@ -2769,6 +2782,8 @@ targets."
rustic-clippy-arguments "-- -W clippy::pedantic -W clippy::perf -W clippy::nursery -W clippy::unwrap_used" rustic-clippy-arguments "-- -W clippy::pedantic -W clippy::perf -W clippy::nursery -W clippy::unwrap_used"
rustic-rustfmt-args "--edition 2021" rustic-rustfmt-args "--edition 2021"
rust-format-on-save t rust-format-on-save t
rustic-cargo-clippy-trigger-fix t
rustic-cargo-clippy-fix-args "--allow-dirty"
rustic-test-arguments "--benches --tests --all-features -- --nocapture") rustic-test-arguments "--benches --tests --all-features -- --nocapture")
(advice-add 'eglot-completion-at-point :around #'cape-wrap-buster) (advice-add 'eglot-completion-at-point :around #'cape-wrap-buster)
(add-to-list 'compilation-error-regexp-alist rustic-compilation-error) (add-to-list 'compilation-error-regexp-alist rustic-compilation-error)
@ -2808,6 +2823,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
@ -2889,13 +2906,13 @@ targets."
:ensure t) :ensure t)
;; then install the checker as soon as `clojure-mode' is loaded ;; then install the checker as soon as `clojure-mode' is loaded
(use-package clojure-mode (use-package clojure-ts-mode
:ensure t :ensure t
:config :config
(require 'flycheck-clj-kondo)) (require 'flycheck-clj-kondo))
(use-package cider (use-package cider
:after clojure-mode) :after clojure-ts-mode)
(use-package yaml-mode (use-package yaml-mode
:mode ("\\.yml\\'" . yaml-mode)) :mode ("\\.yml\\'" . yaml-mode))
@ -2942,6 +2959,8 @@ targets."
("\\.rmd\\'". markdown-mode)) ("\\.rmd\\'". markdown-mode))
:config :config
(setq markdown-regex-yaml-metadata-border "\\(-\\{3\\}\\|+\\{3\\}\\)$")
(dolist (face (dolist (face
'((markdown-header-face-1 1.4 ultra-bold) '((markdown-header-face-1 1.4 ultra-bold)
(markdown-header-face-2 1.2 extra-bold) (markdown-header-face-2 1.2 extra-bold)
@ -3694,6 +3713,7 @@ targets."
(setq empv-invidious-instance "https://inv.cochrun.xyz/api/v1" (setq empv-invidious-instance "https://inv.cochrun.xyz/api/v1"
empv-video-file-extensions '("mkv" "mp4" "avi" "mov" "webm") empv-video-file-extensions '("mkv" "mp4" "avi" "mov" "webm")
empv-mpv-args '("--no-terminal" "--idle" "--input-ipc-server=/tmp/empv-socket") empv-mpv-args '("--no-terminal" "--idle" "--input-ipc-server=/tmp/empv-socket")
empv-audio-dir "~/music"
empv-video-dir "~/vids") empv-video-dir "~/vids")
(empv-embark-initialize-extra-actions) (empv-embark-initialize-extra-actions)
(general-auto-unbind-keys) (general-auto-unbind-keys)
@ -3712,14 +3732,17 @@ targets."
(let* ((item (when (not file) (empv-youtube-results--current-item))) (let* ((item (when (not file) (empv-youtube-results--current-item)))
(video-id (when (not file) (alist-get 'videoId item))) (video-id (when (not file) (alist-get 'videoId item)))
(playlist-id (when (not file) (alist-get 'playlistId item))) (playlist-id (when (not file) (alist-get 'playlistId item)))
(title (if file (shell-command-to-string (url (if file
(format "yt-dlp --no-warnings --quiet --get-title %s" file)) (progn
(alist-get 'title item))) (message file)
(url (if file file (string-replace "inv.cochrun.xyz" "youtube.com" file))
(format (format
"https://youtube.com/%s=%s" "https://youtube.com/%s=%s"
(if video-id "watch?v" "playlist?list") (if video-id "watch?v" "playlist?list")
(or video-id playlist-id)))) (or video-id playlist-id))))
(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*")) (output-buffer (generate-new-buffer "*yt-dlp*"))
(process (progn (process (progn
(message "Starting to download %s at %s" title url) (message "Starting to download %s at %s" title url)
@ -3728,20 +3751,25 @@ targets."
:buffer output-buffer :buffer output-buffer
:command `("yt-dlp" "-o" :command `("yt-dlp" "-o"
"~/vids/%(title)s.%(ext)s" "~/vids/%(title)s.%(ext)s"
;; "-f best[ext=mp4]" "-f best[ext=mp4]"
,(cl-coerce url 'string) ,(cl-coerce url 'string)
"--embed-thumbnail" "--embed-thumbnail"
"--sponsorblock-remove=sponsor,intro,outro")) "--sponsorblock-remove=sponsor,intro,outro"))
(get-buffer-process output-buffer))) (get-buffer-process output-buffer)))
(enqueue `(lambda (process event) (enqueue `(lambda (process event)
(message "running %s because %s" process event) (when (eq (process-status process) 'exit)
(empv-enqueue (concat "/home/chris/vids/" (string-trim ,title) ".mp4"))))) (progn (message "running %s because %s" process event)
(empv-enqueue (concat "/home/chris/vids/" (string-trim ,title) ".mp4"))
;; (kill-buffer ,output-buffer)
)))))
(message url) (message url)
(if (process-live-p process) (if (process-live-p process)
(set-process-sentinel (set-process-sentinel
process enqueue) process enqueue)
(message "No process running")))) (message "No process running"))))
;; (chris/empv-yt-dlp "https://inv.cochrun.xyz/watch?v=mNYcUMZfSP0")
(defun chris/empv-yt-dlp-jellyfin () (defun chris/empv-yt-dlp-jellyfin ()
"Grabs the current video at point and downloads it to my jellyfin server" "Grabs the current video at point and downloads it to my jellyfin server"
(interactive) (interactive)

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