lsp-elixir.el (8016B)
1 ;;; lsp-elixir.el --- description -*- lexical-binding: t; -*- 2 3 ;; Copyright (C) 2021 emacs-lsp maintainers 4 5 ;; Author: emacs-lsp maintainers 6 ;; Keywords: lsp, elixir 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 ;; LSP Clients for the Elixir Programming Language. 24 25 ;;; Code: 26 27 (require 'lsp-mode) 28 (require 'ht) 29 30 (defcustom lsp-elixir-dialyzer-enabled t 31 "Run ElixirLS's rapid Dialyzer when code is saved." 32 :type 'boolean 33 :group 'lsp-elixir 34 :package-version '(lsp-mode . "8.0.0")) 35 36 (defcustom lsp-elixir-dialyzer-warn-opts '() 37 "Dialyzer options to enable or disable warnings. 38 39 See Dialyzer's documentation for options. Note that the \"race_conditions\" 40 option is unsupported" 41 :type '(repeat string) 42 :group 'lsp-elixir 43 :package-version '(lsp-mode . "8.0.0")) 44 45 (defcustom lsp-elixir-dialyzer-format "dialyxir_long" 46 "Formatter to use for Dialyzer warnings." 47 :type 'string 48 :group 'lsp-elixir 49 :package-version '(lsp-mode . "8.0.0")) 50 51 (defcustom lsp-elixir-mix-env "test" 52 "Mix environment to use for compilation." 53 :type 'string 54 :group 'lsp-elixir 55 :package-version '(lsp-mode . "8.0.0")) 56 57 (defcustom lsp-elixir-mix-target nil 58 "Mix target to use for compilation (requires Elixir >= 1.8)." 59 :type 'string 60 :group 'lsp-elixir 61 :package-version '(lsp-mode . "8.0.0")) 62 63 (defcustom lsp-elixir-project-dir nil 64 "Subdirectory containing Mix project if not in the project root. 65 66 If value is `\"\"` then defaults to the workspace rootUri." 67 :type 'string 68 :group 'lsp-elixir 69 :package-version '(lsp-mode . "8.0.0")) 70 71 (defcustom lsp-elixir-fetch-deps nil 72 "Automatically fetch project dependencies when compiling." 73 :type 'boolean 74 :group 'lsp-elixir 75 :package-version '(lsp-mode . "8.0.0")) 76 77 (defcustom lsp-elixir-suggest-specs t 78 "Suggest @spec annotations inline using Dialyzer's inferred success typings. 79 This requires Dialyzer." 80 :type 'boolean 81 :group 'lsp-elixir 82 :package-version '(lsp-mode . "8.0.0")) 83 84 (defcustom lsp-elixir-signature-after-complete t 85 "Show signature help after confirming autocomplete." 86 :type 'boolean 87 :group 'lsp-elixir 88 :package-version '(lsp-mode . "8.0.0")) 89 90 (defgroup lsp-elixir nil 91 "LSP support for Elixir, using elixir-ls." 92 :group 'lsp-mode 93 :link '(url-link "https://github.com/elixir-lsp/elixir-ls")) 94 95 (define-obsolete-variable-alias 'lsp-clients-elixir-server-executable 'lsp-elixir-server-command "2021-04-05") 96 97 (defcustom lsp-elixir-server-command 98 (if (equal system-type 'windows-nt) 99 '("language_server.bat") 100 '("language_server.sh")) 101 "Command to start elixir-ls. 102 103 Leave as default to let `executable-find' search for it." 104 :group 'lsp-elixir 105 :type '(repeat string) 106 :package-version '(lsp-mode . "8.0.0")) 107 108 (defcustom lsp-elixir-ls-version "v0.20.0" 109 "Elixir-Ls version to download. 110 It has to be set before `lsp-elixir.el' is loaded and it has to 111 be available here: https://github.com/elixir-lsp/elixir-ls/releases/" 112 :type 'string 113 :group 'lsp-elixir 114 :package-version '(lsp-mode . "9.0.0")) 115 116 (defcustom lsp-elixir-ls-download-url 117 (format "https://github.com/elixir-lsp/elixir-ls/releases/download/%1$s/elixir-ls-%1$s.zip" 118 lsp-elixir-ls-version) 119 "Automatic download url for elixir-ls." 120 :type 'string 121 :group 'lsp-elixir 122 :package-version '(lsp-mode . "9.0.0")) 123 124 125 (defconst lsp-elixir-ls-server-dir 126 (f-join lsp-server-install-dir "elixir-ls") 127 "Elixir-ls local server Directory.") 128 129 (defcustom lsp-elixir-local-server-command 130 (f-join lsp-elixir-ls-server-dir 131 (cl-first lsp-elixir-server-command)) 132 "Command to start local elixir-ls binary." 133 :group 'lsp-elixir 134 :type '(repeat string) 135 :package-version '(lsp-mode . "8.0.0")) 136 137 (defcustom lsp-elixir-enable-test-lenses t 138 "Suggest Tests." 139 :type 'boolean 140 :group 'lsp-elixir 141 :package-version '(lsp-mode . "8.0.0")) 142 143 (defun lsp-elixir--build-test-command (argument) 144 "Builds the test command from the ARGUMENT." 145 (let ((test-name (lsp-get argument :testName)) 146 (module (lsp-get argument :module)) 147 (describe (lsp-get argument :describe))) 148 (cond (module (concat "\"" "module:" module "\"")) 149 ((not test-name) (concat "\"" "describe:" describe "\"")) 150 (describe (concat "\"" "test:test " describe " " test-name "\"" )) 151 (t (concat "\"" "test:test " test-name "\"" ))))) 152 153 (lsp-defun lsp-elixir--run-test ((&Command :arguments?)) 154 "Runs tests." 155 (let* ((argument (lsp-seq-first arguments?)) 156 (file-path (lsp-get argument :filePath)) 157 (test-command (lsp-elixir--build-test-command argument))) 158 (compile 159 (concat "cd " (lsp-workspace-root file-path) " && " 160 "mix test --exclude test --include " test-command " " file-path 161 " --no-color")) 162 file-path)) 163 164 (lsp-dependency 165 'elixir-ls 166 `(:download :url lsp-elixir-ls-download-url 167 :decompress :zip 168 :store-path ,(f-join lsp-server-install-dir "elixir-ls" "elixir-ls.zip") 169 :binary-path lsp-elixir-server-command 170 :set-executable? t)) 171 172 (lsp-register-custom-settings 173 '(("elixirLS.dialyzerEnabled" lsp-elixir-dialyzer-enabled t) 174 ("elixirLS.dialyzerWarnOpts" lsp-elixir-dialyzer-warn-opts) 175 ("elixirLS.dialyzerFormat" lsp-elixir-dialyzer-format) 176 ("elixirLS.mixEnv" lsp-elixir-mix-env) 177 ("elixirLS.mixTarget" lsp-elixir-mix-target) 178 ("elixirLS.projectDir" lsp-elixir-project-dir) 179 ("elixirLS.fetchDeps" lsp-elixir-fetch-deps t) 180 ("elixirLS.suggestSpecs" lsp-elixir-suggest-specs t) 181 ("elixirLS.signatureAfterComplete" lsp-elixir-signature-after-complete t) 182 ("elixirLS.enableTestLenses" lsp-elixir-enable-test-lenses t))) 183 184 (lsp-register-client 185 (make-lsp-client :new-connection (lsp-stdio-connection 186 (lambda () 187 `(,(or (when (f-exists? lsp-elixir-local-server-command) 188 lsp-elixir-local-server-command) 189 (or (executable-find 190 (cl-first lsp-elixir-server-command)) 191 (lsp-package-path 'elixir-ls)) 192 "language_server.bat") 193 ,@(cl-rest lsp-elixir-server-command)))) 194 :activation-fn (lsp-activate-on "elixir") 195 :priority -1 196 :server-id 'elixir-ls 197 :action-handlers (ht ("elixir.lens.test.run" 'lsp-elixir--run-test)) 198 :download-server-fn (lambda (_client callback error-callback _update?) 199 (lsp-package-ensure 'elixir-ls callback error-callback)) 200 :initialized-fn (lambda (workspace) 201 (with-lsp-workspace workspace 202 (lsp--set-configuration 203 (lsp-configuration-section "elixirLS"))) 204 (lsp-put 205 (lsp--workspace-server-capabilities workspace) 206 :textDocumentSync 207 (lsp-make-text-document-sync-options 208 :save t 209 :change 2))))) 210 211 (lsp-consistency-check lsp-elixir) 212 213 (provide 'lsp-elixir) 214 ;;; lsp-elixir.el ends here