config

Personal configuration.
git clone git://code.dwrz.net/config
Log | Files | Refs

lsp-zig.el (10589B)


      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 "zls.exe") (_ "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