From 71bbf899c3c19bfb165a3da15e1d5d721a1f2cf5 Mon Sep 17 00:00:00 2001 From: Marie Katrine Ekeberg Date: Mon, 16 Oct 2023 16:48:44 +0200 Subject: [PATCH 1/8] Add barebones wgsl-analyzer support --- clients/lsp-wgsl.el | 52 +++++++++++++++++++++++++++++++++++++++++++++ lsp-mode.el | 1 + 2 files changed, 53 insertions(+) create mode 100644 clients/lsp-wgsl.el diff --git a/clients/lsp-wgsl.el b/clients/lsp-wgsl.el new file mode 100644 index 0000000000..ef921f8d41 --- /dev/null +++ b/clients/lsp-wgsl.el @@ -0,0 +1,52 @@ +;;; lsp-wgsl.el --- description -*- lexical-binding: t; -*- + +;; Copyright (C) 2023 emacs-lsp maintainers + +;; Author: emacs-lsp maintainers +;; Keywords: lsp, wgsl, shaders, graphics programming, + +;; 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 . + +;;; Commentary: + +;; LSP Clients for WGSL (WebGPU Shading Language). + +;;; Code: + +(defgroup lsp-wgsl nil + "LSP support for wgsl, using wgsl-analyzer." + :group 'lsp-mode + :link '(url-link "https://github.com/wgsl-analyzer/wgsl-analyzer") + :package-version '(lsp-mode . "8.0.1")) + + +(defcustom lsp-wgsl-server-command "wgsl_analyzer" + "Command to run the wgsl-analyzer executable." + :type 'boolean + :group 'lsp-wgsl + :package-version '(lsp-mode . "8.0.1")) + +(lsp-register-client + (make-lsp-client :new-connection (lsp-stdio-connection + (lambda () + lsp-wgsl-server-command)) + :activation-fn (lsp-activate-on "wgsl") + :priority -1 + :server-id 'wgsl-analyzer)) + + +(lsp-consistency-check lsp-wgsl) + +(provide 'lsp-wgsl) +;;; lsp-wgsl.el ends here diff --git a/lsp-mode.el b/lsp-mode.el index df40db28e6..226bfddee3 100644 --- a/lsp-mode.el +++ b/lsp-mode.el @@ -929,6 +929,7 @@ Changes take effect only when a new session is started." (rst-mode . "restructuredtext") (glsl-mode . "glsl") (shader-mode . "shaderlab") + (wgsl-mode . "wgsl") (jq-mode . "jq") (jq-ts-mode . "jq")) "Language id configuration.") From 52811aaa37b0dfa99baefebcaa7839652751c1e8 Mon Sep 17 00:00:00 2001 From: Marie Katrine Ekeberg Date: Wed, 18 Oct 2023 14:21:52 +0200 Subject: [PATCH 2/8] Add function to execute the lsp extension full source --- clients/lsp-wgsl.el | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/clients/lsp-wgsl.el b/clients/lsp-wgsl.el index ef921f8d41..51d8f28039 100644 --- a/clients/lsp-wgsl.el +++ b/clients/lsp-wgsl.el @@ -37,6 +37,26 @@ :group 'lsp-wgsl :package-version '(lsp-mode . "8.0.1")) + +;; Various interactive functions to use the custom LSP extensions from the server +(defun lsp-wgsl-full-source () + "Gets the full source of the file with all imports and preprocessor definitions resolved." + (interactive) + (lsp-request-async + "wgsl-analyzer/fullSource" + (list :textDocument (list :uri (lsp--buffer-uri))) + (lambda (source) + (let ((buffer (get-buffer-create "*WGSL-full-source*"))) + (with-current-buffer buffer + (setq-local buffer-read-only nil) + (erase-buffer) + (insert source) + (read-only-mode) + ;; activate only syntax highlighting + (font-lock-add-keywords nil wgsl-font-lock-keywords) + (font-lock-mode)) + (switch-to-buffer buffer))))) + (lsp-register-client (make-lsp-client :new-connection (lsp-stdio-connection (lambda () From 70cb86e8b8dee4b1bcd4c14f878956e15d087c61 Mon Sep 17 00:00:00 2001 From: Marie Katrine Ekeberg Date: Fri, 3 Nov 2023 17:46:57 +0100 Subject: [PATCH 3/8] Sending configuration now finally works --- clients/lsp-wgsl.el | 55 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/clients/lsp-wgsl.el b/clients/lsp-wgsl.el index 51d8f28039..c5eaa109fa 100644 --- a/clients/lsp-wgsl.el +++ b/clients/lsp-wgsl.el @@ -37,6 +37,22 @@ :group 'lsp-wgsl :package-version '(lsp-mode . "8.0.1")) +;; Various toggling settings for the lsp server +(defcustom lsp-wgsl-inlayhints-enabled t + "Whether to enable inlay hints or not." + :type 'boolean + :group 'lsp-wgsl + :package-version '(lsp-mode . "8.0.1")) + +;; TODO: maybe type choice instead? +(defcustom lsp-wgsl-inlayhints-type-verbosity "compact" + "The type verbosity to use for inlay hints." + :type '(choice (string "full") + (string "compact") + (string "inner")) + :group 'lsp-wgsl + :package-version '(lsp-mode . "8.0.1")) + ;; Various interactive functions to use the custom LSP extensions from the server (defun lsp-wgsl-full-source () @@ -57,10 +73,49 @@ (font-lock-mode)) (switch-to-buffer buffer))))) + +;; Error("missing field `customImports`" +;; TODO: best way to handle the custom imports logic? +(defcustom lsp-wgsl-custom-imports (lsp-ht) + "" + :type 'list + :group 'lsp-wgsl) + +;; TODO: make it work for empty lists! +(defcustom lsp-wgsl-shaderdefs (list "TEST") + "" + :type 'list + :group 'lsp-wgsl) + + +;; wgsl-analyzer is a bit weird with how it gets config. +;; Currently it relies on a custom extension to query the clients. +;; (could not get standard custom-settings blocks to work) +(defun lsp-wgsl--send-configuration (&rest _) + (list :customImports lsp-wgsl-custom-imports + :diagnostics (list :typeErrors (lsp-json-bool t) + :nagaParsingErrors (lsp-json-bool t) + :nagaValidationErrors (lsp-json-bool nil) + :nagaVersion "main") + :inlayHints (list :enabled (lsp-json-bool lsp-wgsl-inlayhints-enabled) + :typeHints (lsp-json-bool nil) + :parameterHints (lsp-json-bool nil) + :structLayoutHints (lsp-json-bool nil) + :typeVerbosity lsp-wgsl-inlayhints-type-verbosity) + :shaderDefs [] + :trace (list :extension t + :server t))) + (lsp-register-client (make-lsp-client :new-connection (lsp-stdio-connection (lambda () lsp-wgsl-server-command)) + :initialized-fn (lambda (workspace) + (with-lsp-workspace workspace + ;; wgsl-analyzer handles configuration in a VERY non-standard way + ;; https://github.com/wgsl-analyzer/wgsl-analyzer/issues/77 + (lsp--set-configuration '()))) + :request-handlers (lsp-ht ("wgsl-analyzer/requestConfiguration" #'lsp-wgsl--send-configuration)) :activation-fn (lsp-activate-on "wgsl") :priority -1 :server-id 'wgsl-analyzer)) From f9b27f5efff609e04112e091e5de584feb22c9ae Mon Sep 17 00:00:00 2001 From: Marie Katrine Ekeberg Date: Fri, 3 Nov 2023 18:05:31 +0100 Subject: [PATCH 4/8] Added the rest of the configuration properties --- clients/lsp-wgsl.el | 107 +++++++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 32 deletions(-) diff --git a/clients/lsp-wgsl.el b/clients/lsp-wgsl.el index c5eaa109fa..a165b6f92c 100644 --- a/clients/lsp-wgsl.el +++ b/clients/lsp-wgsl.el @@ -38,12 +38,54 @@ :package-version '(lsp-mode . "8.0.1")) ;; Various toggling settings for the lsp server +(defcustom lsp-wgsl-diagnostics-type-errors t + "Whether to show type errors in diagnostics or not." + :type 'boolean + :group 'lsp-wgsl + :package-version '(lsp-mode . "8.0.1")) + +(defcustom lsp-wgsl-diagnostics-naga-parsing-errors t + "Whether to show naga parsing errors in diagnostics or not." + :type 'boolean + :group 'lsp-wgsl + :package-version '(lsp-mode . "8.0.1")) + +(defcustom lsp-wgsl-diagnostics-naga-validation-errors t + "Whether to show naga validation errors in diagnostics or not." + :type 'boolean + :group 'lsp-wgsl + :package-version '(lsp-mode . "8.0.1")) + +(defcustom lsp-wgsl-diagnostics-naga-version "main" + "Naga version to use." + :type 'string + :group 'lsp-wgsl + :package-version '(lsp-mode . "8.0.1")) + (defcustom lsp-wgsl-inlayhints-enabled t "Whether to enable inlay hints or not." :type 'boolean :group 'lsp-wgsl :package-version '(lsp-mode . "8.0.1")) +(defcustom lsp-wgsl-inlayhints-typehints t + "Whether to enable type hints or not when using inlay hints." + :type 'boolean + :group 'lsp-wgsl + :package-version '(lsp-mode . "8.0.1")) + +(defcustom lsp-wgsl-inlayhints-parameterhints t + "Whether to enable parameter hints or not when using inlay hints." + :type 'boolean + :group 'lsp-wgsl + :package-version '(lsp-mode . "8.0.1")) + +(defcustom lsp-wgsl-inlayhints-structlayout t + "Whether to enable struct layout hints or not when using inlay hints." + :type 'boolean + :group 'lsp-wgsl + :package-version '(lsp-mode . "8.0.1")) + ;; TODO: maybe type choice instead? (defcustom lsp-wgsl-inlayhints-type-verbosity "compact" "The type verbosity to use for inlay hints." @@ -53,6 +95,39 @@ :group 'lsp-wgsl :package-version '(lsp-mode . "8.0.1")) +(defcustom lsp-wgsl-custom-imports (lsp-ht) + "List of custom imports in the style of Bevy" + :type 'ht + :group 'lsp-wgsl) + +(defcustom lsp-wgsl-shaderdefs [] + "Defines that should be valid for preprocessor operations like ifdef." + :type 'vector + :group 'lsp-wgsl) + + +;; wgsl-analyzer is a bit weird with how it gets config. +;; Currently it relies on a custom extension to query the clients. +;; (could not get standard custom-settings blocks to work) +(defun lsp-wgsl--send-configuration (&rest _) + (list :customImports lsp-wgsl-custom-imports + :diagnostics (list :typeErrors (lsp-json-bool lsp-wgsl-diagnostics-type-errors) + :nagaParsingErrors (lsp-json-bool lsp-wgsl-diagnostics-naga-parsing-errors) + :nagaValidationErrors (lsp-json-bool lsp-wgsl-diagnostics-naga-validation-errors) + :nagaVersion lsp-wgsl-diagnostics-naga-version) + :inlayHints (list :enabled (lsp-json-bool lsp-wgsl-inlayhints-enabled) + :typeHints (lsp-json-bool lsp-wgsl-inlayhints-typehints) + :parameterHints (lsp-json-bool lsp-wgsl-inlayhints-parameterhints) + :structLayoutHints (lsp-json-bool lsp-wgsl-inlayhints-structlayout) + :typeVerbosity lsp-wgsl-inlayhints-type-verbosity) + ;; using lsp-wgsl-shaderdefs seems to fail even when lsp-wgsl-shaderdefs is [], + ;; which is the reason for this hack. wrong argument consp, nil + :shaderDefs (if (length= lsp-wgsl-shaderdefs 0) [] lsp-wgsl-shaderdefs) + ;; not configurable at the moment, as they don't seem to have much effect. + ;; Fails if not given. + :trace (list :extension t + :server t))) + ;; Various interactive functions to use the custom LSP extensions from the server (defun lsp-wgsl-full-source () @@ -74,38 +149,6 @@ (switch-to-buffer buffer))))) -;; Error("missing field `customImports`" -;; TODO: best way to handle the custom imports logic? -(defcustom lsp-wgsl-custom-imports (lsp-ht) - "" - :type 'list - :group 'lsp-wgsl) - -;; TODO: make it work for empty lists! -(defcustom lsp-wgsl-shaderdefs (list "TEST") - "" - :type 'list - :group 'lsp-wgsl) - - -;; wgsl-analyzer is a bit weird with how it gets config. -;; Currently it relies on a custom extension to query the clients. -;; (could not get standard custom-settings blocks to work) -(defun lsp-wgsl--send-configuration (&rest _) - (list :customImports lsp-wgsl-custom-imports - :diagnostics (list :typeErrors (lsp-json-bool t) - :nagaParsingErrors (lsp-json-bool t) - :nagaValidationErrors (lsp-json-bool nil) - :nagaVersion "main") - :inlayHints (list :enabled (lsp-json-bool lsp-wgsl-inlayhints-enabled) - :typeHints (lsp-json-bool nil) - :parameterHints (lsp-json-bool nil) - :structLayoutHints (lsp-json-bool nil) - :typeVerbosity lsp-wgsl-inlayhints-type-verbosity) - :shaderDefs [] - :trace (list :extension t - :server t))) - (lsp-register-client (make-lsp-client :new-connection (lsp-stdio-connection (lambda () From 7627a27c649cc061bc8ddd972d154a8389d3da96 Mon Sep 17 00:00:00 2001 From: Marie Katrine Ekeberg Date: Fri, 3 Nov 2023 18:44:49 +0100 Subject: [PATCH 5/8] Commented out non-working config paameter --- clients/lsp-wgsl.el | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/clients/lsp-wgsl.el b/clients/lsp-wgsl.el index a165b6f92c..722d09640d 100644 --- a/clients/lsp-wgsl.el +++ b/clients/lsp-wgsl.el @@ -98,18 +98,20 @@ (defcustom lsp-wgsl-custom-imports (lsp-ht) "List of custom imports in the style of Bevy" :type 'ht - :group 'lsp-wgsl) - -(defcustom lsp-wgsl-shaderdefs [] - "Defines that should be valid for preprocessor operations like ifdef." - :type 'vector - :group 'lsp-wgsl) + :group 'lsp-wgsl + :package-version '(lsp-mode . "8.0.1")) +;; (defcustom lsp-wgsl-shaderdefs [] +;; "Defines that should be valid for preprocessor operations like ifdef." +;; :type 'vector +;; :group 'lsp-wgsl +;; :package-version '(lsp-mode . "8.0.1")) ;; wgsl-analyzer is a bit weird with how it gets config. ;; Currently it relies on a custom extension to query the clients. ;; (could not get standard custom-settings blocks to work) (defun lsp-wgsl--send-configuration (&rest _) + ;; TODO: why doesnt this behave like the normal lists?!?!? I cant just send a list?!?!?! why the fuck?!?! (list :customImports lsp-wgsl-custom-imports :diagnostics (list :typeErrors (lsp-json-bool lsp-wgsl-diagnostics-type-errors) :nagaParsingErrors (lsp-json-bool lsp-wgsl-diagnostics-naga-parsing-errors) @@ -120,9 +122,7 @@ :parameterHints (lsp-json-bool lsp-wgsl-inlayhints-parameterhints) :structLayoutHints (lsp-json-bool lsp-wgsl-inlayhints-structlayout) :typeVerbosity lsp-wgsl-inlayhints-type-verbosity) - ;; using lsp-wgsl-shaderdefs seems to fail even when lsp-wgsl-shaderdefs is [], - ;; which is the reason for this hack. wrong argument consp, nil - :shaderDefs (if (length= lsp-wgsl-shaderdefs 0) [] lsp-wgsl-shaderdefs) + :shaderDefs [] ;; not configurable at the moment, as they don't seem to have much effect. ;; Fails if not given. :trace (list :extension t From 8a0b65d45a07c8f70ec91a3acedfd1c2bb90b6a2 Mon Sep 17 00:00:00 2001 From: Marie Katrine Ekeberg Date: Fri, 3 Nov 2023 18:46:22 +0100 Subject: [PATCH 6/8] Add changelog entry for wgsl-analyzer --- CHANGELOG.org | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.org b/CHANGELOG.org index eef1415f6b..e9cac6d61e 100644 --- a/CHANGELOG.org +++ b/CHANGELOG.org @@ -1,5 +1,6 @@ * Changelog ** Unreleased 8.0.1 + * Add support for wgsl using [[https://github.com/wgsl-analyzer/wgsl-analyzer][wgsl-analyzer]] * Add [[https://github.com/wader/jq-lsp][jq-lsp]] * Add architecture triples for [[https://github.com/WhatsApp/erlang-language-platform][erlang-language-platform]] file downloads, to support macos on ARM and X86. * Add semantic token support for [[https://github.com/WhatsApp/erlang-language-platform][erlang-language-platform]] in lsp-erlang client. From 253ef1fc8a048d3ba2aab714be00a9236dcf2441 Mon Sep 17 00:00:00 2001 From: Marie Katrine Ekeberg Date: Tue, 7 Nov 2023 11:51:01 +0100 Subject: [PATCH 7/8] Add lsp-clients docs entry --- docs/lsp-clients.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/lsp-clients.json b/docs/lsp-clients.json index 6d163cfd5a..2684362eb0 100644 --- a/docs/lsp-clients.json +++ b/docs/lsp-clients.json @@ -1029,6 +1029,14 @@ "lsp-install-server": "vue-semantic-server", "debugger": "Not available" }, + { + "name": "wgsl-analyzer", + "full-name": "wgsl", + "server-name": "wgsl-analyzer", + "server-url": "https://github.com/wgsl-analyzer/wgsl-analyzer", + "installation": "cargo install --git https://github.com/wgsl-analyzer/wgsl-analyzer wgsl_analyzer", + "debugger": "Not available" + }, { "name": "xml", "full-name": "XML", From 8c57bcfa4b0cf9187011425cf276aed006f27df4 Mon Sep 17 00:00:00 2001 From: Marie Katrine Ekeberg Date: Tue, 7 Nov 2023 11:52:54 +0100 Subject: [PATCH 8/8] Add missing mkdocs entry --- mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs.yml b/mkdocs.yml index 1ec46adc55..b5bccf9485 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -159,6 +159,7 @@ nav: - Vimscript: page/lsp-vimscript.md - Vue 2: page/lsp-vetur.md - Vue 3: page/lsp-volar.md + - wgsl: page/lsp-wgsl.md - XML: page/lsp-xml.md - YAML: page/lsp-yaml.md - Zig: page/lsp-zig.md