config

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

lsp-volar.el (6801B)


      1 ;;; lsp-volar.el --- A lsp-mode client for Vue3 -*- lexical-binding: t; -*-
      2 ;;
      3 ;; Copyright (C) 2021 JadeStrong
      4 ;;
      5 ;; Author: JadeStrong <https://github.com/jadestrong>
      6 ;; Maintainer: JadeStrong <jadestrong@163.com>
      7 ;; Created: November 08, 2021
      8 ;; Modified: November 08, 2021
      9 ;; Version: 0.0.1
     10 ;; Keywords: abbrev bib c calendar comm convenience data docs emulations extensions faces files frames games hardware help hypermedia i18n internal languages lisp local maint mail matching mouse multimedia news outlines processes terminals tex tools unix vc wp
     11 ;; Homepage: https://github.com/jadestrong/lsp-volar
     12 ;; Package-Requires: ((emacs "25.1"))
     13 ;;
     14 ;; This file is not part of GNU Emacs.
     15 
     16 ;; This file is free software; you can redistribute it and/or modify
     17 ;; it under the terms of the GNU General Public License as published by
     18 ;; the Free Software Foundation; either version 3, or (at your option)
     19 ;; any later version.
     20 
     21 ;; This program is distributed in the hope that it will be useful,
     22 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     23 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     24 ;; GNU General Public License for more details.
     25 
     26 ;; For a full copy of the GNU General Public License
     27 ;; see <http://www.gnu.org/licenses/>.
     28 
     29 ;;
     30 ;;; Commentary:
     31 ;;
     32 ;; provide the connection to lsp-mode and volar language server
     33 ;;
     34 ;;; Code:
     35 (require 'lsp-mode)
     36 (require 'json)
     37 
     38 (defgroup lsp-volar nil
     39   "Lsp support for vue3."
     40   :group 'lsp-mode
     41   :link '(url-link "https://github.com/vuejs/language-tools")
     42   :package-version '(lsp-mode . "9.0.0"))
     43 
     44 (defcustom lsp-volar-take-over-mode t
     45   "Enable Take Over Mode."
     46   :type 'boolean
     47   :group 'lsp-volar
     48   :package-version '(lsp-mode . "9.0.0"))
     49 
     50 (defcustom lsp-volar-hybrid-mode nil
     51   "Enable Hybrid Mode."
     52   :type 'boolean
     53   :group 'lsp-volar
     54   :package-version '(lsp-mode . "9.0.1"))
     55 
     56 (defcustom lsp-volar-activate-file ".volarrc"
     57   "A file with a custom name placed in WORKSPACE-ROOT is used to force enable
     58  volar when there is no package.json in the WORKSPACE-ROOT."
     59   :type 'string
     60   :group 'lsp-volar
     61   :package-version '(lsp-mode . "9.0.0"))
     62 
     63 (defconst lsp-volar--is-windows (memq system-type '(cygwin windows-nt ms-dos)))
     64 (defun lsp-volar-get-typescript-tsdk-path ()
     65   "Get tsserver lib*.d.ts directory path."
     66   (if-let ((package-path (lsp-package-path 'typescript))
     67            (system-tsdk-path (f-join (file-truename package-path)
     68                                      (if lsp-volar--is-windows
     69                                          "../node_modules/typescript/lib"
     70                                        "../../lib")))
     71            ((file-exists-p system-tsdk-path)))
     72       system-tsdk-path
     73     (prog1 ""
     74       (lsp--error "[lsp-volar] Typescript is not detected correctly. Please ensure the npm package typescript is installed in your project or system (npm install -g typescript), otherwise open an issue"))))
     75 
     76 (lsp-dependency 'typescript
     77                 '(:system "tsserver")
     78                 '(:npm :package "typescript"
     79                        :path "tsserver"))
     80 
     81 (lsp-dependency 'volar-language-server
     82                 '(:system "vue-language-server")
     83                 '(:npm :package "@vue/language-server" :path "vue-language-server"))
     84 
     85 (lsp-register-custom-settings
     86  '(("typescript.tsdk"
     87     (lambda ()
     88       (if-let ((project-root (lsp-workspace-root))
     89                (tsdk-path (f-join project-root "node_modules/typescript/lib"))
     90                ((file-exists-p tsdk-path)))
     91           tsdk-path
     92         (lsp-volar-get-typescript-tsdk-path)))
     93     t)))
     94 
     95 (lsp-register-custom-settings
     96  '(("vue.hybridMode" lsp-volar-hybrid-mode t)))
     97 
     98 (defun lsp-volar--vue-project-p (workspace-root)
     99   "Check if the `Vue' package is present in the package.json file
    100 in the WORKSPACE-ROOT."
    101   (if-let ((package-json (f-join workspace-root "package.json"))
    102            (exist (f-file-p package-json))
    103            (config (json-read-file package-json))
    104            (dependencies (alist-get 'dependencies config)))
    105       (alist-get 'vue (append dependencies (alist-get 'devDependencies config)))
    106   nil))
    107 
    108 (defun lsp-volar--activate-p (filename &optional _)
    109   "Check if the volar-language-server should be enabled base on FILENAME."
    110   (if lsp-volar-take-over-mode
    111       (or (or
    112            (and (lsp-workspace-root) (lsp-volar--vue-project-p (lsp-workspace-root)))
    113            (and (lsp-workspace-root) lsp-volar-activate-file (f-file-p (f-join (lsp-workspace-root) lsp-volar-activate-file))))
    114           (or (or (string-match-p "\\.mjs\\|\\.[jt]sx?\\'" filename)
    115                   (and (derived-mode-p 'js-mode 'typescript-mode 'typescript-ts-mode)
    116                        (not (derived-mode-p 'json-mode))))
    117               (string= (file-name-extension filename) "vue")))
    118     (string= (file-name-extension filename) "vue")))
    119 
    120 (lsp-register-client
    121  (make-lsp-client
    122   :new-connection (lsp-stdio-connection
    123                    (lambda ()
    124                      `(,(lsp-package-path 'volar-language-server) "--stdio")))
    125   :activation-fn 'lsp-volar--activate-p
    126   :priority 0
    127   :multi-root nil
    128   :server-id 'vue-semantic-server
    129   :initialization-options (lambda () (ht-merge (lsp-configuration-section "typescript")
    130                                                (lsp-configuration-section "vue")
    131                                                (ht ("serverMode" 0)
    132                                                    ("diagnosticModel" 1)
    133                                                    ("textDocumentSync" 2))))
    134   :initialized-fn (lambda (workspace)
    135                     (with-lsp-workspace workspace
    136                       (lsp--server-register-capability
    137                        (lsp-make-registration
    138                         :id "random-id"
    139                         :method "workspace/didChangeWatchedFiles"
    140                         :register-options? (lsp-make-did-change-watched-files-registration-options
    141                                             :watchers
    142                                             `[,(lsp-make-file-system-watcher :glob-pattern "**/*.js")
    143                                               ,(lsp-make-file-system-watcher :glob-pattern "**/*.ts")
    144                                               ,(lsp-make-file-system-watcher :glob-pattern "**/*.vue")
    145                                               ,(lsp-make-file-system-watcher :glob-pattern "**/*.jsx")
    146                                               ,(lsp-make-file-system-watcher :glob-pattern "**/*.tsx")
    147                                               ,(lsp-make-file-system-watcher :glob-pattern "**/*.json")])))))
    148   :download-server-fn (lambda (_client callback error-callback _update?)
    149                         (lsp-package-ensure 'volar-language-server
    150                                             callback error-callback))))
    151 
    152 (provide 'lsp-volar)
    153 ;;; lsp-volar.el ends here