lsp-zig.el (10597B)
1 ;;; lsp-zig.el --- lsp-mode Zig integration -*- lexical-binding: t; -*- 2 3 ;; Copyright (C) 2021 Riccardo Binetti 4 5 ;; Author: Riccardo Binetti <rbino@gmx.com> 6 ;; Keywords: languages,tools 7 8 ;; This program is free software; you can redistribute it and/or modify 9 ;; it under the terms of the GNU General Public License as published by 10 ;; the Free Software Foundation, either version 3 of the License, or 11 ;; (at your option) any later version. 12 13 ;; This program is distributed in the hope that it will be useful, 14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 ;; GNU General Public License for more details. 17 18 ;; You should have received a copy of the GNU General Public License 19 ;; along with this program. If not, see <https://www.gnu.org/licenses/>. 20 21 ;;; Commentary: 22 23 ;; client for zls, the Zig language server 24 25 ;;; Code: 26 27 (require 'lsp-mode) 28 29 (defgroup lsp-zig nil 30 "LSP support for Zig via zls." 31 :group 'lsp-mode 32 :link '(url-link "https://github.com/zigtools/zls")) 33 34 (defcustom lsp-zig-zls-executable "zls" 35 "The zls executable to use. 36 37 Leave as just the executable name to use the default behavior of finding the 38 executable with variable `exec-path'." 39 :group 'lsp-zig 40 :type 'string) 41 42 (defcustom lsp-zig-trace-server "off" 43 "Traces the communication between Emacs and the language server." 44 :group 'lsp-zig 45 :type '(choice (const "off") 46 (const "messages") 47 (const "verbose"))) 48 49 (defcustom lsp-zls-enable-snippets t 50 "Enables snippet completions when the client also supports them." 51 :group 'lsp-zig 52 :type 'boolean) 53 54 (defcustom lsp-zig-enable-argument-placeholders t 55 "Whether to enable function argument placeholder completions." 56 :group 'lsp-zig 57 :type 'boolean) 58 59 (defcustom lsp-zig-enable-build-on-save nil 60 "Whether to enable build-on-save diagnostics." 61 :group 'lsp-zig 62 :type 'boolean) 63 64 (defcustom lsp-zig-build-on-save-step "install" 65 "Select which step should be executed on build-on-save." 66 :group 'lsp-zig 67 :type 'string) 68 69 (defcustom lsp-zig-enable-autofix nil 70 "Whether to automatically fix errors on save. 71 Currently supports adding and removing discards." 72 :group 'lsp-zig 73 :type 'boolean) 74 75 (defcustom lsp-zig-semantic-tokens "partial" 76 "Traces the communication between Emacs and the language server." 77 :group 'lsp-zig 78 :type '(choice (const "off") 79 (const "messages") 80 (const "verbose"))) 81 82 (defcustom lsp-zig-enable-inlay-hints t 83 "Enables inlay hint support when the client also supports it." 84 :group 'lsp-zig 85 :type 'boolean) 86 87 (defcustom lsp-zig-inlay-hints-show-variable-type-hints t 88 "Enable inlay hints for variable type." 89 :group 'lsp-zig 90 :type 'boolean) 91 92 (defcustom lsp-zig-inlay-hints-show-parameter-name t 93 "Enable inlay hints for parameter names." 94 :group 'lsp-zig 95 :type 'boolean) 96 97 (defcustom lsp-zig-inlay-hints-exclude-single-argument t 98 "Don't show inlay hints for single argument calls." 99 :group 'lsp-zig 100 :type 'boolean) 101 102 (defcustom lsp-zig-inlay-hints-show-builtin t 103 "Don't show inlay hints for single argument calls." 104 :group 'lsp-zig 105 :type 'boolean) 106 107 (defcustom lsp-zig-inlay-hints-hide-redundant-param-names nil 108 "Hides inlay hints when parameter name matches the identifier (e.g. foo: foo)." 109 :group 'lsp-zig 110 :type 'boolean) 111 112 (defcustom lsp-zig-inlay-hints-hide-redundant-param-names-last-token nil 113 "Hides inlay hints when parameter name matches the last token of a parameter 114 node (e.g. foo: bar.foo, foo: &foo)." 115 :group 'lsp-zig 116 :type 'boolean) 117 118 (defcustom lsp-zig-warn-style nil 119 "Enables warnings for style guideline mismatches." 120 :group 'lsp-zig 121 :type 'boolean) 122 123 (defcustom lsp-zig-highlight-global-var-declarations nil 124 "Whether to highlight global var declarations." 125 :group 'lsp-zig 126 :type 'boolean) 127 128 (defcustom lsp-zig-dangerous-comptime-experiments-do-not-enable nil 129 "When true, skips searching for references in std. 130 Improves lookup speed for functions in user's code. Renaming and 131 go-to-definition will continue to work as is." 132 :group 'lsp-zig 133 :type 'boolean) 134 135 (defcustom lsp-zig-skip-std-references nil 136 "hen true, skips searching for references in std. 137 Improves lookup speed for functions in user's code. Renaming and 138 go-to-definition will continue to work as is." 139 :group 'lsp-zig 140 :type 'boolean) 141 142 (defcustom lsp-zig-prefer-ast-check-as-child-process t 143 "Favor using `zig ast-check` instead of ZLS's fork." 144 :group 'lsp-zig 145 :type 'boolean) 146 147 (defcustom lsp-zig-record-session nil 148 "When true, zls will record all request is receives and write in into 149 `record_session_path`, so that they can replayed with `zls replay`." 150 :group 'lsp-zig 151 :type 'boolean) 152 153 (defcustom lsp-zig-record-session-path "" 154 "Output file path when `record_session` is set. 155 The recommended file extension *.zlsreplay." 156 :group 'lsp-zig 157 :type 'string) 158 159 (defcustom lsp-zig-replay-session-path "" 160 "Used when calling `zls replay` for specifying the replay file. 161 If no extra argument is given `record_session_path` is used as the default path." 162 :group 'lsp-zig 163 :type 'string) 164 165 (defcustom lsp-zig-builtin-path "" 166 "Path to `builtin'; useful for debugging, automatically set if let null." 167 :group 'lsp-zig 168 :type 'string) 169 170 (defcustom lsp-zig-zig-lib-path "" 171 "Zig library path. 172 e.g. `/path/to/zig/lib/zig`, used to analyze std library imports." 173 :group 'lsp-zig 174 :type 'string) 175 176 (defcustom lsp-zig-zig-exe-path "" 177 " Zig executable path. 178 e.g. /path/to/zig/zig, used to run the custom build runner. If null, zig is 179 looked up in PATH. Will be used to infer the zig standard library path if none 180 is provided." 181 :group 'lsp-zig 182 :type 'string) 183 184 (defcustom lsp-zig-build-runner-path "" 185 "Path to the `build_runner.zig` file provided by zls. 186 null is equivalent to `${executable_directory}/build_runner.zig`." 187 :group 'lsp-zig 188 :type 'string) 189 190 (defcustom lsp-zig-global-cache-path "" 191 "Path to a directory that will be used as zig's cache. 192 null is equivalent to `${KnownFolders.Cache}/zls`." 193 :group 'lsp-zig 194 :type 'string) 195 196 (defcustom lsp-zig-build-runner-global-cache-path "" 197 "Path to a directory that will be used as the global cache path when executing 198 a projects build.zig. null is equivalent to the path shown by `zig env`." 199 :group 'lsp-zig 200 :type 'string) 201 202 (defcustom lsp-zig-completions-with-replace nil 203 "Completions confirm behavior. 204 If `true', replace the text after the cursor." 205 :group 'lsp-zig 206 :type 'boolean) 207 208 ;; 209 ;;; Installation 210 211 (defcustom lsp-zig-server-store-path 212 (expand-file-name "zig/" lsp-server-install-dir) 213 "The path to the file in which zls will be stored." 214 :type 'file 215 :group 'lsp-zig) 216 217 (defconst lsp-zig-download-url-format 218 "https://github.com/zigtools/zls/releases/latest/download/zls-%s-%s.%s" 219 "Format to the download url link.") 220 221 (defun lsp-zig--zls-url () 222 "Return Url points to the zls' zip/tar file." 223 (let* ((x86 (string-prefix-p "x86_64" system-configuration)) 224 (arch (if x86 "x86_64" "aarch64"))) 225 (cl-case system-type 226 ((cygwin windows-nt ms-dos) 227 (format lsp-zig-download-url-format arch "windows" "zip")) 228 (darwin 229 (format lsp-zig-download-url-format arch "macos" "tar.gz")) 230 (gnu/linux 231 (format lsp-zig-download-url-format arch "linux" "tar.gz"))))) 232 233 (defun lsp-zig--stored-zls-executable () 234 "Return the stored zls executable. 235 236 This is differ from the variable `lsp-zig-zls-executable'; this is local storage 237 and not the global storage." 238 (f-join lsp-zig-server-store-path 239 (pcase system-type ('windows-nt "bin/zls.exe") (_ "bin/zls")))) 240 241 (lsp-dependency 242 'zls 243 '(:system "zls") 244 `(:download :url ,(lsp-zig--zls-url) 245 :decompress ,(pcase system-type ('windows-nt :zip) (_ :targz)) 246 :store-path ,(f-join lsp-zig-server-store-path "temp") 247 :set-executable? t) 248 `(:system ,(lsp-zig--stored-zls-executable))) 249 250 ;; 251 ;;; Core 252 253 (lsp-register-custom-settings 254 '(("zls.enable_snippets" lsp-zls-enable-snippets t) 255 ("zls.enable_argument_placeholders" lsp-zig-enable-argument-placeholders t) 256 ("zls.enable_build_on_save" lsp-zig-enable-build-on-save t) 257 ("zls.build_on_save_step" lsp-zig-build-on-save-step) 258 ("zls.enable_autofix" lsp-zig-enable-autofix t) 259 ("zls.semantic_tokens" lsp-zig-semantic-tokens) 260 ("zls.enable_inlay_hints" lsp-zig-enable-inlay-hints t) 261 ("zls.inlay_hints_show_variable_type_hints" lsp-zig-inlay-hints-show-variable-type-hints t) 262 ("zls.inlay_hints_show_parameter_name" lsp-zig-inlay-hints-show-parameter-name t) 263 ("zls.inlay_hints_show_builtin" lsp-zig-inlay-hints-show-builtin t) 264 ("zls.inlay_hints_exclude_single_argument" lsp-zig-inlay-hints-exclude-single-argument t) 265 ("zls.inlay_hints_hide_redundant_param_names" lsp-zig-inlay-hints-hide-redundant-param-names t) 266 ("zls.inlay_hints_hide_redundant_param_names_last_token" lsp-zig-inlay-hints-hide-redundant-param-names-last-token t) 267 ("zls.warn_style" lsp-zig-warn-style t) 268 ("zls.highlight_global_var_declarations" lsp-zig-highlight-global-var-declarations t) 269 ("zls.dangerous_comptime_experiments_do_not_enable" lsp-zig-dangerous-comptime-experiments-do-not-enable t) 270 ("zls.skip_std_references" lsp-zig-skip-std-references t) 271 ("zls.prefer_ast_check_as_child_process" lsp-zig-prefer-ast-check-as-child-process t) 272 ("zls.record_session" lsp-zig-record-session t) 273 ("zls.record_session_path" lsp-zig-record-session-path) 274 ("zls.replay_session_path" lsp-zig-replay-session-path) 275 ("zls.builtin_path" lsp-zig-builtin-path) 276 ("zls.zig_lib_path" lsp-zig-zig-lib-path) 277 ("zls.zig_exe_path" lsp-zig-zig-exe-path) 278 ("zls.build_runner_path" lsp-zig-build-runner-path) 279 ("zls.global_cache_path" lsp-zig-global-cache-path) 280 ("zls.build_runner_global_cache_path" lsp-zig-build-runner-global-cache-path) 281 ("zls.completion_label_details" lsp-zig-completions-with-replace t))) 282 283 (lsp-register-client 284 (make-lsp-client 285 :new-connection (lsp-stdio-connection 286 (lambda () (or (executable-find lsp-zig-zls-executable) 287 (lsp-zig--stored-zls-executable))) 288 (lambda () 289 (or (executable-find lsp-zig-zls-executable) 290 (file-executable-p (lsp-zig--stored-zls-executable))))) 291 :activation-fn (lsp-activate-on "zig") 292 :priority -1 293 :server-id 'zls 294 :download-server-fn 295 (lambda (_client callback error-callback _update?) 296 (lsp-package-ensure 'zls callback error-callback)))) 297 298 (lsp-consistency-check lsp-zig) 299 300 (provide 'lsp-zig) 301 ;;; lsp-zig.el ends here