config

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

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