config

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

lsp-yaml.el (9428B)


      1 ;;; lsp-yaml.el --- LSP YAML server integration        -*- lexical-binding: t; -*-
      2 
      3 ;; Copyright (C) 2019  Aya Igarashi
      4 
      5 ;; Author: Aya Igarashi <ladiclexxx@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 (require 'dash)
     29 
     30 (defgroup lsp-yaml nil
     31   "LSP support for YAML, using yaml-language-server."
     32   :group 'lsp-mode
     33   :link '(url-link "https://github.com/redhat-developer/yaml-language-server")
     34   :package-version '(lsp-mode . "6.2"))
     35 
     36 (defcustom lsp-yaml-format-enable t
     37   "Enable/disable default YAML formatter."
     38   :type 'boolean
     39   :group 'lsp-yaml
     40   :package-version '(lsp-mode . "6.2"))
     41 
     42 (defcustom lsp-yaml-single-quote nil
     43   "Use single quote instead of double quotes."
     44   :type 'boolean
     45   :group 'lsp-yaml
     46   :package-version '(lsp-mode . "6.2"))
     47 
     48 (defcustom lsp-yaml-bracket-spacing t
     49   "Print spaces between brackets in objects."
     50   :type 'boolean
     51   :group 'lsp-yaml
     52   :package-version '(lsp-mode . "6.2"))
     53 
     54 (defcustom lsp-yaml-prose-wrap "preserve"
     55   "Options for prose-wrap.
     56    Always: wrap prose if it exceeds the print width.
     57    Never: never wrap the prose.
     58    Preserve: wrap prose as-is."
     59   :type '(choice
     60           (const "always")
     61           (const "never")
     62           (const "preserve"))
     63   :group 'lsp-yaml
     64   :package-version '(lsp-mode . "6.2"))
     65 
     66 (defcustom lsp-yaml-print-width 80
     67   "Specify the line length that the printer will wrap on."
     68   :type 'number
     69   :group 'lsp-yaml
     70   :package-version '(lsp-mode . "6.2"))
     71 
     72 (defcustom lsp-yaml-validate t
     73   "Enable/disable validation feature."
     74   :type 'boolean
     75   :group 'lsp-yaml
     76   :package-version '(lsp-mode . "6.2"))
     77 
     78 (defcustom lsp-yaml-hover t
     79   "Enable/disable hover feature."
     80   :type 'boolean
     81   :group 'lsp-yaml
     82   :package-version '(lsp-mode . "6.2"))
     83 
     84 (defcustom lsp-yaml-completion t
     85   "Enable/disable completion feature."
     86   :type 'boolean
     87   :group 'lsp-yaml
     88   :package-version '(lsp-mode . "6.2"))
     89 
     90 (defcustom lsp-yaml-schemas '()
     91   "Associate schemas to YAML files in a glob pattern."
     92   :type '(alist :key-type (symbol :tag "schema") :value-type (lsp-string-vector :tag "files (glob)"))
     93   :group 'lsp-yaml
     94   :package-version '(lsp-mode . "6.2"))
     95 
     96 (defcustom lsp-yaml-schema-store-enable t
     97   "Enable/disable JSON Schema store. When set to true, available YAML
     98    schemas will be automatically pulled from the store."
     99   :type 'boolean
    100   :group 'lsp-yaml
    101   :package-version '(lsp-mode . "6.2"))
    102 
    103 (defcustom lsp-yaml-custom-tags nil
    104   "Custom tags for the parser to use."
    105   :type '(lsp-repeatable-vector string)
    106   :group 'lsp-yaml
    107   :package-version '(lsp-mode . "6.2"))
    108 
    109 (defcustom lsp-yaml-schema-store-uri "https://www.schemastore.org/api/json/catalog.json"
    110   "URL of schema store catalog to use."
    111   :type 'string
    112   :group 'lsp-yaml)
    113 
    114 (defcustom lsp-yaml-schema-store-local-db (expand-file-name
    115                                            (locate-user-emacs-file
    116                                             (f-join ".cache" "lsp" "lsp-yaml-schemas.json")))
    117   "Cached database of schema store."
    118   :type 'file
    119   :group 'lsp-yaml)
    120 
    121 (defcustom lsp-yaml-max-items-computed 5000
    122   "The maximum number of outline symbols and folding regions computed.
    123 Limited for performance reasons."
    124   :type 'number
    125   :group 'lsp-yaml
    126   :package-version '(lsp-mode . "8.0.0"))
    127 
    128 
    129 (defvar lsp-yaml--schema-store-schemas-alist nil
    130   "A list of schemas fetched from schema stores.")
    131 
    132 (lsp-register-custom-settings
    133  '(("yaml.format.enable" lsp-yaml-format-enable t)
    134    ("yaml.format.singleQuote" lsp-yaml-single-quote t)
    135    ("yaml.format.bracketSpacing" lsp-yaml-bracket-spacing)
    136    ("yaml.format.proseWrap" lsp-yaml-prose-wrap)
    137    ("yaml.format.printWidth" lsp-yaml-print-width)
    138    ("yaml.validate" lsp-yaml-validate t)
    139    ("yaml.hover" lsp-yaml-hover t)
    140    ("yaml.completion" lsp-yaml-completion t)
    141    ("yaml.schemas" lsp-yaml-schemas)
    142    ("yaml.schemaStore.enable" lsp-yaml-schema-store-enable t)
    143    ("yaml.schemaStore.url" lsp-yaml-schema-store-uri)
    144    ("yaml.customTags" lsp-yaml-custom-tags)
    145    ("yaml.maxItemsComputed" lsp-yaml-max-items-computed)))
    146 
    147 (defcustom lsp-yaml-server-command '("yaml-language-server" "--stdio")
    148   "Command to start yaml-languageserver."
    149   :type '(repeat string)
    150   :group 'lsp-yaml
    151   :package-version '(lsp-mode . "6.2"))
    152 
    153 (lsp-dependency 'yaml-language-server
    154                 '(:system "yaml-language-server")
    155                 '(:npm :package "yaml-language-server"
    156                        :path "yaml-language-server"))
    157 
    158 (lsp-register-client
    159  (make-lsp-client :new-connection (lsp-stdio-connection
    160                                    (lambda ()
    161                                      `(,(or (executable-find (cl-first lsp-yaml-server-command))
    162                                             (lsp-package-path 'yaml-language-server))
    163                                        ,@(cl-rest lsp-yaml-server-command))))
    164                   :activation-fn (lsp-activate-on "yaml")
    165                   :priority 0
    166                   :server-id 'yamlls
    167                   :initialized-fn (lambda (workspace)
    168                                     (with-lsp-workspace workspace
    169                                       (lsp--set-configuration
    170                                        (lsp-configuration-section "yaml"))))
    171                   :download-server-fn (lambda (_client callback error-callback _update?)
    172                                         (lsp-package-ensure 'yaml-language-server
    173                                                             callback error-callback))))
    174 
    175 (defconst lsp-yaml--built-in-kubernetes-schema
    176   '((name . "Kubernetes")
    177     (description . "Built-in kubernetes manifest schema definition")
    178     (url . "kubernetes")
    179     (fileMatch . ["*-k8s.yaml" "*-k8s.yml"])))
    180 
    181 (defun lsp-yaml-download-schema-store-db (&optional force-downloading)
    182   "Download remote schema store at `lsp-yaml-schema-store-uri' into local cache.
    183 Set FORCE-DOWNLOADING to non-nil to force re-download the database."
    184   (interactive "P")
    185   (when (or force-downloading (not (file-exists-p lsp-yaml-schema-store-local-db)))
    186     (unless (file-directory-p (file-name-directory lsp-yaml-schema-store-local-db))
    187       (mkdir (file-name-directory lsp-yaml-schema-store-local-db) t))
    188     (url-copy-file lsp-yaml-schema-store-uri lsp-yaml-schema-store-local-db force-downloading)))
    189 
    190 (defun lsp-yaml--get-supported-schemas ()
    191   "Get out the list of supported schemas."
    192   (when (and lsp-yaml-schema-store-enable
    193              (not lsp-yaml--schema-store-schemas-alist))
    194     (lsp-yaml-download-schema-store-db)
    195     (setq lsp-yaml--schema-store-schemas-alist
    196           (alist-get 'schemas (json-read-file lsp-yaml-schema-store-local-db))))
    197   (seq-concatenate 'list (list lsp-yaml--built-in-kubernetes-schema) lsp-yaml--schema-store-schemas-alist))
    198 
    199 (defun lsp-yaml-set-buffer-schema (uri-string)
    200   "Set yaml schema for the current buffer to URI-STRING."
    201   (interactive "MURI: ")
    202   (let* ((uri (intern uri-string))
    203          (workspace-path (file-relative-name
    204                           (lsp--uri-to-path (lsp--buffer-uri))
    205                           (lsp-workspace-root (lsp--buffer-uri))))
    206          (glob (concat "/" workspace-path))
    207          (current-config (assoc uri lsp-yaml-schemas))
    208          (current-patterns (and current-config (cdr current-config))))
    209     (if current-config
    210         (or (member glob (append current-patterns nil))
    211             (setq lsp-yaml-schemas
    212                   (cl-acons uri
    213                             (vconcat (vector glob) current-patterns)
    214                             (assq-delete-all uri
    215                                              (mapcar (lambda (x) (lsp-yaml--remove-glob x glob))
    216                                                      lsp-yaml-schemas)))))
    217       (setq lsp-yaml-schemas
    218             (cl-acons uri (vector glob) (mapcar (lambda (x) (lsp-yaml--remove-glob x glob))
    219                                                 lsp-yaml-schemas))))
    220     (lsp--set-configuration (lsp-configuration-section "yaml"))))
    221 
    222 (defun lsp-yaml-select-buffer-schema ()
    223   "Select schema for the current buffer based on the list of supported schemas."
    224   (interactive)
    225   (let* ((schema (lsp--completing-read "Select buffer schema: "
    226                                        (lsp-yaml--get-supported-schemas)
    227                                        (lambda (schema)
    228                                          (format "%s: %s" (alist-get 'name schema)(alist-get 'description schema)))
    229                                        nil t))
    230          (uri (alist-get 'url schema)))
    231     (lsp-yaml-set-buffer-schema uri)))
    232 
    233 (defun lsp-yaml--remove-glob (mapping glob)
    234   (let ((patterns (cdr mapping)))
    235     (cons (car mapping)
    236           (vconcat (-filter (lambda (p) (not (equal p glob)))
    237                             (append patterns nil)) nil))))
    238 
    239 (lsp-consistency-check lsp-yaml)
    240 
    241 (provide 'lsp-yaml)
    242 ;;; lsp-yaml.el ends here