Skip to content

Commit f3dcffb

Browse files
authored
Refine volar to support v3 (#4871)
1 parent d9057bf commit f3dcffb

File tree

3 files changed

+68
-88
lines changed

3 files changed

+68
-88
lines changed

clients/lsp-javascript.el

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050

5151
(defun lsp-typescript-javascript-tsx-jsx-activate-p (filename &optional _)
5252
"Check if the js-ts lsp server should be enabled based on FILENAME."
53-
(or (string-match-p "\\.[cm]js\\|\\.[jt]sx?\\'" filename)
53+
(or (string-match-p "\\.vue\\|\\.[cm]js\\|\\.[jt]sx?\\'" filename)
5454
(and (derived-mode-p 'js-mode 'js-ts-mode 'typescript-mode 'typescript-ts-mode)
5555
(not (derived-mode-p 'json-mode)))))
5656

clients/lsp-volar.el

Lines changed: 66 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -33,95 +33,80 @@
3333
;;
3434
;;; Code:
3535
(require 'lsp-mode)
36-
(require 'json)
36+
(require 'lsp-javascript)
37+
(require 'dash)
3738

3839
(defgroup lsp-volar nil
3940
"Lsp support for vue3."
4041
:group 'lsp-mode
4142
:link '(url-link "https://github.com/vuejs/language-tools")
4243
:package-version '(lsp-mode . "9.0.0"))
4344

44-
(defcustom lsp-volar-take-over-mode nil
45-
"Enable Take Over Mode."
46-
:type 'boolean
45+
(defcustom lsp-volar-typescript-server-id 'ts-ls
46+
"The server id of the typescript language server to use."
4747
:group 'lsp-volar
48-
:package-version '(lsp-mode . "9.0.0"))
48+
:package-version '(lsp-mode . "9.0.1")
49+
:type 'symbol)
4950

50-
(defcustom lsp-volar-hybrid-mode t
51-
"Enable Hybrid Mode."
52-
:type 'boolean
53-
:group 'lsp-volar
54-
:package-version '(lsp-mode . "9.0.1"))
51+
(defcustom lsp-volar-support-vue2 nil
52+
"Whether to ping Volar's version to ~3.0 to support vue2.
5553
56-
(defcustom lsp-volar-as-add-on nil
57-
"Run volar LSP server alongside other LSP server(s)"
58-
:type 'boolean
54+
Volar is dropping Vue 2 and vue-class-component Support in v3.1.
55+
Reference: https://github.com/vuejs/language-tools/discussions/5455"
5956
:group 'lsp-volar
60-
:package-version '(lsp-mode . "9.0.1"))
61-
62-
(defcustom lsp-volar-activate-file ".volarrc"
63-
"A file with a custom name placed in WORKSPACE-ROOT is used to force enable
64-
volar when there is no package.json in the WORKSPACE-ROOT."
65-
:type 'string
66-
:group 'lsp-volar
67-
:package-version '(lsp-mode . "9.0.0"))
68-
69-
(defconst lsp-volar--is-windows (memq system-type '(cygwin windows-nt ms-dos)))
70-
(defun lsp-volar-get-typescript-tsdk-path ()
71-
"Get tsserver lib*.d.ts directory path."
72-
(if-let* ((package-path (lsp-package-path 'typescript))
73-
(system-tsdk-path (f-join (file-truename package-path)
74-
(if lsp-volar--is-windows
75-
"../node_modules/typescript/lib"
76-
"../../lib")))
77-
((file-exists-p system-tsdk-path)))
78-
system-tsdk-path
79-
(prog1 ""
80-
(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"))))
81-
82-
(lsp-dependency 'typescript
83-
'(:system "tsserver")
84-
'(:npm :package "typescript"
85-
:path "tsserver"))
86-
87-
(lsp-dependency 'volar-language-server
88-
'(:system "vue-language-server")
89-
'(:npm :package "@vue/language-server" :path "vue-language-server"))
90-
91-
(lsp-register-custom-settings
92-
'(("typescript.tsdk"
93-
(lambda ()
94-
(if-let* ((project-root (lsp-workspace-root))
95-
(tsdk-path (f-join project-root "node_modules/typescript/lib"))
96-
((file-exists-p tsdk-path)))
97-
tsdk-path
98-
(lsp-volar-get-typescript-tsdk-path)))
99-
t)))
100-
101-
(lsp-register-custom-settings
102-
'(("vue.hybridMode" lsp-volar-hybrid-mode t)))
103-
104-
(defun lsp-volar--vue-project-p (workspace-root)
105-
"Check if the `Vue' package is present in the package.json file
106-
in the WORKSPACE-ROOT."
107-
(if-let* ((package-json (f-join workspace-root "package.json"))
108-
(exist (f-file-p package-json))
109-
(config (json-read-file package-json))
110-
(dependencies (alist-get 'dependencies config)))
111-
(alist-get 'vue (append dependencies (alist-get 'devDependencies config)))
112-
nil))
57+
:package-version '(lsp-mode . "9.0.1")
58+
:type 'boolean)
11359

11460
(defun lsp-volar--activate-p (filename &optional _)
11561
"Check if the volar-language-server should be enabled base on FILENAME."
116-
(if lsp-volar-take-over-mode
117-
(or (or
118-
(and (lsp-workspace-root) (lsp-volar--vue-project-p (lsp-workspace-root)))
119-
(and (lsp-workspace-root) lsp-volar-activate-file (f-file-p (f-join (lsp-workspace-root) lsp-volar-activate-file))))
120-
(or (or (string-match-p "\\.mjs\\|\\.[jt]sx?\\'" filename)
121-
(and (derived-mode-p 'js-mode 'typescript-mode 'typescript-ts-mode)
122-
(not (derived-mode-p 'json-mode))))
123-
(string= (file-name-extension filename) "vue")))
124-
(string= (file-name-extension filename) "vue")))
62+
(and filename (string-suffix-p ".vue" filename)))
63+
64+
(lsp-dependency 'volar-language-server
65+
'(:npm :package "@vue/language-server" :path "vue-language-server"
66+
:version (lambda () (when lsp-volar-support-vue2 "~3.0")))
67+
'(:system "vue-language-server"))
68+
69+
;; Set lsp-clients-typescript-plugins
70+
(condition-case nil
71+
(when-let* ((vue-language-server-path (lsp-package-path 'volar-language-server)))
72+
(let ((vue-plugin (list :name "@vue/typescript-plugin"
73+
:location (f-join vue-language-server-path "../.." "lib/node_modules/@vue/language-server/")
74+
:languages (vector "vue")
75+
:configNamespace "typescript"
76+
:enableForWorkspaceTypeScriptVersions t)))
77+
(setq lsp-clients-typescript-plugins
78+
(vconcat lsp-clients-typescript-plugins (vector vue-plugin)))))
79+
(error nil))
80+
81+
(defun lsp-volar--send-notify (workspace method params)
82+
"Send notification to WORKSPACE with METHOD PARAMS."
83+
(with-lsp-workspace workspace
84+
(let ((body (lsp--make-notification method params)))
85+
(lsp--send-no-wait body
86+
(lsp--workspace-proc lsp--cur-workspace)))))
87+
88+
(defun lsp-volar--tsserver-request-handler (volar-workspace params)
89+
"Handles `tsserver/request` notification from VOLAR-WORKSPACE.
90+
And forwarding PARAMS to the typescript LSP server.
91+
92+
Reference:
93+
- https://github.com/vuejs/language-tools/discussions/5456
94+
- https://github.com/vuejs/language-tools/wiki/Neovim#configuration"
95+
(if-let* ((ts-ls-workspace (lsp-find-workspace lsp-volar-typescript-server-id nil)))
96+
(with-lsp-workspace ts-ls-workspace
97+
(-let [[[id command payload]] params]
98+
(lsp-request-async
99+
"workspace/executeCommand"
100+
(list :command "typescript.tsserverRequest"
101+
:arguments (vector command payload))
102+
;; response callback
103+
(lambda (response)
104+
(let ((body (lsp-get response :body)))
105+
(lsp-volar--send-notify volar-workspace "tsserver/response" (vector (vector id body)))))
106+
;; error callback
107+
:error-handler (lambda (error-response)
108+
(lsp--warn "tsserver/request async error: %S" error-response)))))
109+
(lsp--error "[lsp-volar] Could not found `%s` lsp client, lsp-volar would not work without it" lsp-volar-typescript-server-id)))
125110

126111
(lsp-register-client
127112
(make-lsp-client
@@ -131,13 +116,10 @@ in the WORKSPACE-ROOT."
131116
:activation-fn 'lsp-volar--activate-p
132117
:priority 0
133118
:multi-root nil
134-
:add-on? lsp-volar-as-add-on
119+
:add-on? t ;; work with typescript server
135120
:server-id 'vue-semantic-server
136-
:initialization-options (lambda () (ht-merge (lsp-configuration-section "typescript")
137-
(lsp-configuration-section "vue")
138-
(ht ("serverMode" 0)
139-
("diagnosticModel" 1)
140-
("textDocumentSync" 2))))
121+
:initialization-options (lambda () (ht-merge (lsp-configuration-section "vue")))
122+
:notification-handlers (ht ("tsserver/request" #'lsp-volar--tsserver-request-handler))
141123
:initialized-fn (lambda (workspace)
142124
(with-lsp-workspace workspace
143125
(lsp--server-register-capability
@@ -146,12 +128,9 @@ in the WORKSPACE-ROOT."
146128
:method "workspace/didChangeWatchedFiles"
147129
:register-options? (lsp-make-did-change-watched-files-registration-options
148130
:watchers
149-
`[,(lsp-make-file-system-watcher :glob-pattern "**/*.js")
150-
,(lsp-make-file-system-watcher :glob-pattern "**/*.ts")
151-
,(lsp-make-file-system-watcher :glob-pattern "**/*.vue")
152-
,(lsp-make-file-system-watcher :glob-pattern "**/*.jsx")
153-
,(lsp-make-file-system-watcher :glob-pattern "**/*.tsx")
154-
,(lsp-make-file-system-watcher :glob-pattern "**/*.json")])))))
131+
`[
132+
,(lsp-make-file-system-watcher :glob-pattern "**/*.vue")
133+
])))))
155134
:download-server-fn (lambda (_client callback error-callback _update?)
156135
(lsp-package-ensure 'volar-language-server
157136
callback error-callback))))

test/lsp-javascript-test.el

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
(should (lsp-typescript-javascript-tsx-jsx-activate-p "abc.jsx"))
101101
(should (lsp-typescript-javascript-tsx-jsx-activate-p "abc.ts"))
102102
(should (lsp-typescript-javascript-tsx-jsx-activate-p "abc.tsx"))
103+
(should (lsp-typescript-javascript-tsx-jsx-activate-p "abc.vue"))
103104
(should (lsp-typescript-javascript-tsx-jsx-activate-p "a1.ts"))
104105
(should (lsp-typescript-javascript-tsx-jsx-activate-p "a1.d.ts"))
105106
(should-not (lsp-typescript-javascript-tsx-jsx-activate-p "abc.tsxx"))

0 commit comments

Comments
 (0)