lsp-xml.el (13632B)
1 ;;; lsp-xml.el --- LSP XML server integration -*- lexical-binding: t; -*- 2 3 ;; Copyright (C) 2019 Ivan Yonchovski 4 5 ;; Author: Ivan Yonchovski <yyoncho@gmail.com> 6 ;; Keywords: 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 ;; 24 25 ;;; Code: 26 27 (require 'lsp-mode) 28 29 (defgroup lsp-xml nil 30 "Settings for rls." 31 :group 'tools 32 :tag "Language Server" 33 :package-version '(lsp-mode . "6.1")) 34 35 (defcustom lsp-xml-trace-server "off" 36 "Traces the communication between VS Code and the XML language server." 37 :type '(choice 38 (const "off") 39 (const "messages") 40 (const "verbose")) 41 :group 'lsp-xml 42 :package-version '(lsp-mode . "6.1")) 43 44 (defcustom lsp-xml-catalogs nil 45 "Array of XML Catalogs" 46 :type '(repeat string) 47 :group 'lsp-xml 48 :package-version '(lsp-mode . "6.1")) 49 50 (defcustom lsp-xml-logs-client t 51 "Should the server log to client output" 52 :type 'boolean 53 :group 'lsp-xml 54 :package-version '(lsp-mode . "6.1")) 55 56 (defcustom lsp-xml-format-split-attributes nil 57 "Split multiple attributes each onto a new line" 58 :type 'boolean 59 :group 'lsp-xml 60 :package-version '(lsp-mode . "6.1")) 61 62 (defcustom lsp-xml-format-join-cdata-lines nil 63 "Join lines in a CDATA tag's content" 64 :type 'boolean 65 :group 'lsp-xml 66 :package-version '(lsp-mode . "6.1")) 67 68 (defcustom lsp-xml-format-join-comment-lines nil 69 "Join comment content on format" 70 :type 'boolean 71 :group 'lsp-xml 72 :package-version '(lsp-mode . "6.1")) 73 74 (defcustom lsp-xml-format-space-before-empty-close-tag t 75 "Insert space before end of self closing tag. 76 Example: <tag/> -> <tag />" 77 :type 'boolean 78 :group 'lsp-xml 79 :package-version '(lsp-mode . "6.1")) 80 81 (defcustom lsp-xml-format-join-content-lines nil 82 "Normalize the whitespace of content inside an element. 83 Newlines and excess whitespace are removed." 84 :type 'boolean 85 :group 'lsp-xml 86 :package-version '(lsp-mode . "6.1")) 87 88 (defcustom lsp-xml-format-preserve-empty-content nil 89 "Preserve empty content/whitespace in a tag." 90 :type 'boolean 91 :group 'lsp-xml 92 :package-version '(lsp-mode . "6.1")) 93 94 (defcustom lsp-xml-format-enabled t 95 "Enable/disable ability to format document" 96 :type 'boolean 97 :group 'lsp-xml 98 :package-version '(lsp-mode . "6.1")) 99 100 (defcustom lsp-xml-preferences-quote-style "double" 101 "The preferred quote style for attribute values." 102 :type '(choice 103 (const "double") 104 (const "single")) 105 :group 'lsp-xml 106 :package-version '(lsp-mode . "9.0.0")) 107 108 (defcustom lsp-xml-format-comments t 109 "Enable/disable comment formatting." 110 :type 'boolean 111 :group 'lsp-xml 112 :package-version '(lsp-mode . "9.0.0")) 113 114 (defcustom lsp-xml-format-closing-bracket-new-line nil 115 "Enable/disable moving the closing bracket. 116 117 This only affects tags with two or more (split) attributes." 118 :type 'boolean 119 :group 'lsp-xml 120 :package-version '(lsp-mode . "9.0.0")) 121 122 (defcustom lsp-xml-format-split-attributes-indent-size 2 123 "The indentation used for split attributes." 124 :type 'integer 125 :group 'lsp-xml 126 :package-version '(lsp-mode . "9.0.0")) 127 128 (defcustom lsp-xml-format-preserve-attribute-line-breaks t 129 "Enable/disable preserving line breaks in attributes." 130 :type 'boolean 131 :group 'lsp-xml 132 :package-version '(lsp-mode . "9.0.0")) 133 134 (defcustom lsp-xml-format-enforce-quote-style "ignore" 135 "The way in which quote style should be enforced." 136 :type '(choice 137 (const "ignore") 138 (const "preferred")) 139 :group 'lsp-xml 140 :package-version '(lsp-mode . "9.0.0")) 141 142 (defcustom lsp-xml-format-preserved-newlines 2 143 "The number of empty newlines to be preserved." 144 :type 'integer 145 :group 'lsp-xml 146 :package-version '(lsp-mode . "9.0.0")) 147 148 (defcustom lsp-xml-format-xsi-schema-location-split "onPair" 149 "XSI schema location split settings." 150 :type '(choice 151 (const "onElement") 152 (const "onPair") 153 (const "none")) 154 :group 'lsp-xml 155 :package-version '(lsp-mode . "9.0.0")) 156 157 (defcustom lsp-xml-format-experimental nil 158 "Enable/disable experimental formatter." 159 :type 'boolean 160 :group 'lsp-xml 161 :package-version '(lsp-mode . "9.0.0")) 162 163 (defcustom lsp-xml-format-max-line-width 80 164 "Max line width. 165 166 This only applies to experimental formatter." 167 :type 'integer 168 :group 'lsp-xml 169 :package-version '(lsp-mode . "9.0.0")) 170 171 (defcustom lsp-xml-format-preserve-space ["xsl:text" 172 "xsl:comment" 173 "xsl:processing-instruction" 174 "literallayout" 175 "programlisting" 176 "screen" 177 "synopsis" 178 "pre" 179 "xd:pre"] 180 "List of elements which must preserve space. 181 182 This option only affects the experimental formatter." 183 :type 'lsp-string-vector 184 :group 'lsp-xml 185 :package-version '(lsp-mode . "9.0.0")) 186 187 (defcustom lsp-xml-format-grammar-aware-formatting t 188 "Enable/disable grammar aware formatting. 189 190 This only affects the experimental formatter." 191 :type 'boolean 192 :group 'lsp-xml 193 :package-version '(lsp-mode . "9.0.0")) 194 195 (defcustom lsp-xml-file-associations nil 196 "Allows XML schemas to be associated to file name patterns. 197 Example: [{ \"systemId\":\"path/to/file.xsd\",\"pattern\": 198 \"file1.xml\" },{ \"systemId\": 199 \"http://www.w3.org/2001/XMLSchema.xsd\",\"pattern\": 200 \"**/*.xsd\" }]" 201 :type '(repeat string) 202 :group 'lsp-xml 203 :package-version '(lsp-mode . "6.1")) 204 205 (defcustom lsp-xml-completion-auto-close-tags t 206 "Enable/disable autoclosing of XML tags. IMPORTANT: Turn off 207 editor.autoClosingTags for this to work" 208 :type 'boolean 209 :group 'lsp-xml 210 :package-version '(lsp-mode . "6.1")) 211 212 (defcustom lsp-xml-server-vmargs ["-noverify" "-Xmx64M" "-XX:+UseG1GC" 213 "-XX:+UseStringDeduplication"] 214 "Specifies extra VM arguments used to launch the XML Language 215 Server. Eg. use `-noverify -Xmx1G -XX:+UseG1GC 216 -XX:+UseStringDeduplication` to bypass class verification, 217 increase the heap size to 1GB and enable String deduplication 218 with the G1 Garbage collector" 219 :type 'lsp-string-vector 220 :group 'lsp-xml 221 :package-version '(lsp-mode . "6.1")) 222 223 (defcustom lsp-xml-server-work-dir (expand-file-name ".lsp4xml" "~") 224 "Set a custom folder path for cached XML Schemas. An absolute 225 path is expected, although the ~ prefix (for the user home 226 directory) is supported." 227 :type 'string 228 :group 'lsp-xml 229 :package-version '(lsp-mode . "6.1")) 230 231 (defcustom lsp-xml-validation-no-grammar "hint" 232 "The message severity when a document has no associated 233 grammar." 234 :type '(choice (:tag "ignore" "hint" "info" "warning" "error")) 235 :group 'lsp-xml 236 :package-version '(lsp-mode . "6.1")) 237 238 (defcustom lsp-xml-validation-enabled t 239 "Enable/disable all validation." 240 :type 'boolean 241 :group 'lsp-xml 242 :package-version '(lsp-mode . "6.1")) 243 244 (defcustom lsp-xml-validation-resolve-external-entities nil 245 "Enable/disable resolution (downloading) of external entities from the internet." 246 :type 'boolean 247 :group 'lsp-xml 248 :package-version '(lsp-mode . "8.0.0")) 249 250 (defcustom lsp-xml-validation-schema '((enabled . "always")) 251 "The XML schema settings. 252 253 The value for `enabled' can be always, never or onValidSchema." 254 :type 'alist 255 :group 'lsp-xml 256 :package-version '(lsp-mode . "6.1")) 257 258 (lsp-register-custom-settings ' 259 (("xml.validation.schema" lsp-xml-validation-schema) 260 ("xml.validation.resolveExternalEntities" lsp-xml-validation-resolve-external-entities) 261 ("xml.validation.enabled" lsp-xml-validation-enabled t) 262 ("xml.validation.noGrammar" lsp-xml-validation-no-grammar) 263 ("xml.server.workDir" lsp-xml-server-work-dir) 264 ("xml.server.vmargs" lsp-xml-server-vmargs) 265 ("xml.completion.autoCloseTags" lsp-xml-completion-auto-close-tags t) 266 ("xml.fileAssociations" lsp-xml-file-associations) 267 ("xml.preferences.quoteStyle" lsp-xml-preferences-quote-style) 268 ("xml.format.enabled" lsp-xml-format-enabled t) 269 ("xml.format.preserveEmptyContent" lsp-xml-format-preserve-empty-content t) 270 ("xml.format.joinContentLines" lsp-xml-format-join-content-lines t) 271 ("xml.format.spaceBeforeEmptyCloseTag" lsp-xml-format-space-before-empty-close-tag t) 272 ("xml.format.joinCommentLines" lsp-xml-format-join-comment-lines t) 273 ("xml.format.joinCDATALines" lsp-xml-format-join-cdata-lines t) 274 ("xml.format.splitAttributes" lsp-xml-format-split-attributes t) 275 ("xml.format.formatComments" lsp-xml-format-comments t) 276 ("xml.format.closingBracketNewLine" lsp-xml-format-closing-bracket-new-line t) 277 ("xml.format.splitAttributesIndentSize" lsp-xml-format-split-attributes-indent-size) 278 ("xml.format.preserveAttributeLineBreaks" lsp-xml-format-preserve-attribute-line-breaks t) 279 ("xml.format.enforceQuoteStyle" lsp-xml-format-enforce-quote-style) 280 ("xml.format.preservedNewlines" lsp-xml-format-preserved-newlines) 281 ("xml.format.xsiSchemaLocationSplit" lsp-xml-format-xsi-schema-location-split) 282 ("xml.format.experimental" lsp-xml-format-experimental t) 283 ("xml.format.maxLineWidth" lsp-xml-format-max-line-width) 284 ("xml.format.preserveSpace" lsp-xml-format-preserve-space) 285 ("xml.format.grammarAwareFormatting" lsp-xml-format-grammar-aware-formatting t) 286 ("xml.logs.client" lsp-xml-logs-client t) 287 ("xml.catalogs" lsp-xml-catalogs) 288 ("xml.trace.server" lsp-xml-trace-server))) 289 290 (defcustom lsp-xml-prefer-jar t 291 "Prefer using the jar file instead of the native binary." 292 :type 'boolean 293 :group 'lsp-xml 294 :package-version '(lsp-mode . "8.0.2")) 295 296 (defconst lsp-xml-jar-version "0.27.0") 297 298 (defconst lsp-xml-jar-name "org.eclipse.lemminx-uber.jar") 299 300 (defcustom lsp-xml-jar-file (f-join lsp-server-install-dir "xmlls" lsp-xml-jar-name) 301 "Xml server jar command." 302 :group 'lsp-xml 303 :type 'file 304 :package-version '(lsp-mode . "6.1")) 305 306 (defcustom lsp-xml-jar-download-url 307 (format 308 "https://download.eclipse.org/lemminx/releases/%s/%s" 309 lsp-xml-jar-version 310 lsp-xml-jar-name) 311 "Automatic download url for lsp-xml." 312 :type 'string 313 :group 'lsp-xml 314 :package-version '(lsp-mode . "8.0.0")) 315 316 (lsp-dependency 317 'xmlls 318 '(:system lsp-xml-jar-file) 319 `(:download :url lsp-xml-jar-download-url 320 :store-path lsp-xml-jar-file)) 321 322 (defconst lsp-xml-bin-base-name 323 (format "lemminx-%s" (let ((arch (if (string-prefix-p "x86_64" system-configuration) "x86_64" "aarch_64"))) 324 (pcase system-type 325 ('darwin (format "osx-%s" arch)) 326 ('gnu/linux "linux") 327 ('windows-nt "win32"))))) 328 329 (defconst lsp-xml-bin-name (format "%s%s" lsp-xml-bin-base-name (if (eq system-type 'windows-nt) ".exe" ""))) 330 331 (defcustom lsp-xml-bin-file (f-join lsp-server-install-dir "xmlls" lsp-xml-bin-name) 332 "Xml server binary." 333 :group 'lsp-xml 334 :type 'file 335 :package-version '(lsp-mode . "8.0.2")) 336 337 (defcustom lsp-xml-bin-download-url 338 ;; This is the version with `latest` tag 339 (format "https://github.com/redhat-developer/vscode-xml/releases/download/latest/%s.zip" 340 lsp-xml-bin-base-name) 341 "Automatic download url for lsp-xml's native binary." 342 :type 'string 343 :group 'lsp-xml 344 :package-version '(lsp-mode . "8.0.2")) 345 346 (lsp-dependency 347 'xmlls-bin 348 '(:system ,(file-name-nondirectory lsp-xml-bin-file)) 349 `(:download :url lsp-xml-bin-download-url 350 :decompress :zip 351 :store-path lsp-xml-bin-file)) 352 353 (defsubst lsp-xml-has-java? () (executable-find "java")) 354 355 (defcustom lsp-xml-server-command 356 (lambda () (or (and (lsp-xml-has-java?) lsp-xml-prefer-jar `("java" "-jar" ,lsp-xml-jar-file)) 357 `(,lsp-xml-bin-file))) 358 "Xml server command." 359 :type '(choice (repeat string) (function)) 360 :group 'lsp-xml 361 :package-version '(lsp-mode . "6.1")) 362 363 (defun lsp-xml--create-connection () 364 "Create a connection for the XML language server." 365 (lsp-stdio-connection 366 (lambda () (lsp-resolve-value lsp-xml-server-command)) 367 (lambda () (or (and (lsp-xml-has-java?) lsp-xml-prefer-jar (f-exists? lsp-xml-jar-file)) 368 (f-exists? lsp-xml-bin-file))))) 369 370 (lsp-register-client 371 (make-lsp-client :new-connection (lsp-xml--create-connection) 372 :activation-fn (lsp-activate-on "xml") 373 :priority 0 374 :server-id 'xmlls 375 :multi-root t 376 :initialized-fn (lambda (workspace) 377 (with-lsp-workspace workspace 378 (lsp--set-configuration (lsp-configuration-section "xml")))) 379 :download-server-fn (lambda (_client callback error-callback _update?) 380 (lsp-package-ensure (or (and (lsp-xml-has-java?) lsp-xml-prefer-jar 'xmlls) 381 'xmlls-bin) 382 callback error-callback)))) 383 384 (lsp-consistency-check lsp-xml) 385 386 (provide 'lsp-xml) 387 ;;; lsp-xml.el ends here