[vue] Make vue lsp integration adhere to current standards

this includes requiring the lsp layer if not
already loaded and not changing settings
controlled by auto complete layer.

In addition diagnostics from lsp servers will
not longer be ignored if not specifically
requested, see the layer readme for details.
This commit is contained in:
Maxi Wolff 2022-12-22 12:13:47 +01:00
parent 37cdd5069f
commit 445e0d40eb
5 changed files with 56 additions and 47 deletions

View File

@ -11,7 +11,7 @@
- [[#backends][Backends]]
- [[#dumb][dumb]]
- [[#lsp][lsp]]
- [[#optional-configuration][Optional Configuration]]
- [[#indentation][Indentation]]
- [[#key-bindings][Key bindings]]
- [[#web-mode][web-mode]]
- [[#formatting-prettier][Formatting (prettier)]]
@ -64,7 +64,7 @@ To use automatic code formatting you need to install =prettier= with:
#+END_SRC
If you want to use local =eslint= and =prettier= in your project, turn on node
layer =dotspacemacs-configuration-layers= function:
layer =dotspacemacs-configuration-layers= function:
#+BEGIN_SRC elisp
(node :variables node-add-modules-path t)
@ -74,42 +74,36 @@ If you want to use local =eslint= and =prettier= in your project, turn on node
** dumb
dumb backend is light weight and fast. =dumb-jump= is used to handled go to
definition (=gd= vim key binding). Because of the template nature of Vue, it
works very well.
works very well.
Company backend is set to be very eager in suggestions.
Company backend is set to be very eager in suggestions.
=eslint= is used for linting.
** lsp
Vue language server needs to be installed
Vue language server needs to be installed which one depends on the version of
Vue you are using. For vue2 use:
#+BEGIN_SRC sh
$ npm install -g vls
#+END_SRC
This backend provides all the fancy features like: jump to definition,
references, type inference... However, =eslint= is explicitly selected for
linting because it works better than =lsp= linter.
for vue3 use:
* Optional Configuration
~web-mode-script-padding~ is set to 0, so indent is zero at root level inside
~script~ tag
Same as =react= layer, you may refer to the =web-mode= configuration for fine
tuning the indenting behaviour.
For example, if you wan't two space indentation, put this in your
=dotspacemacs/user-config=
#+BEGIN_SRC emacs-lisp
(setq-default
;; web-mode
web-mode-markup-indent-offset 2
web-mode-css-indent-offset 2
web-mode-code-indent-offset 2
web-mode-attr-indent-offset 2)
#+BEGIN_SRC sh
$ npm install -g volar
#+END_SRC
These backends provide all the fancy features like: jump to definition,
references, type inference...
If you are not happy with the linting behaviour of your lsp server you can
fallback to =eslint= by setting =vue-ignore-lsp-diagnostics= to =t=.
* Indentation
~web-mode-script-padding~ is set to 0, so indent is zero at root level inside
~script~ tag.
* Key bindings
** web-mode
Free stuff from `html' layer, with minor change to avoid conflict with =lsp= layer

View File

@ -20,9 +20,14 @@
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
(spacemacs|defc vue-backend (if (configuration-layer/layer-used-p 'lsp) 'lsp 'dumb)
"The backend to use for IDE features.
Possible values are `lsp' and `dumb'.
If not set then `dumb' is the default backend unless `lsp' layer is used."
'(choice (const lsp) (const dumb)) nil t)
(defvar vue-backend 'dumb
"The backend to use for IDE features. Possible values are `dumb' and `lsp'.")
(spacemacs|defc vue-ignore-lsp-diagnostics nil
"If VUE-BACKEND is `lsp' the server will handle the linters, if you prefer to have emacs handle these instead set this to `t'"
'boolean nil t)
(spacemacs|define-jump-handlers vue-mode)

View File

@ -20,8 +20,6 @@
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;; backend
(defun spacemacs//vue-setup-backend ()
"Conditionally setup vue backend."
@ -31,8 +29,13 @@
(defun spacemacs//vue-setup-company ()
"Conditionally setup company based on backend."
(when (eq vue-backend 'dumb)
(spacemacs//vue-setup-dumb-company)))
(pcase vue-backend
('dumb (spacemacs|add-company-backends
:backends (company-web-html company-css company-files company-dabbrev)
:modes vue-mode))
('lsp (spacemacs|add-company-backends
:backends company-capf
:modes vue-mode))))
;; lsp
@ -42,14 +45,14 @@
(progn
;; error checking from lsp langserver sucks, turn it off
;; so eslint won't be overriden
(setq-local lsp-diagnostics-provider :none)
(when vue-ignore-lsp-diagnostics
(setq-local lsp-diagnostics-provider :none))
(lsp-deferred))
(message (concat "`lsp' layer is not installed, "
"please add `lsp' layer to your dotfile."))))
;; dumb
(defun spacemacs//vue-setup-dumb ()
(setq imenu-generic-expression '(("html" "^<template>$" 0)
("js" "^<script>$" 0)
@ -65,13 +68,8 @@
("css" "^<css>$" 0))
imenu-create-index-function #'imenu-default-create-index-function))
(defun spacemacs//vue-setup-dumb-company ()
(spacemacs|add-company-backends :backends (company-web-html company-css company-files company-dabbrev)
:modes vue-mode
:variables company-minimum-prefix-length 2)
(company-mode))
;; Others
(defun spacemacs//vue-setup-yasnippet ()
(spacemacs/load-yasnippet)

View File

@ -22,3 +22,7 @@
(configuration-layer/declare-layers '(node html prettier javascript))
(when (and (boundp 'vue-backend)
(eq vue-backend 'lsp))
(configuration-layer/declare-layer-dependencies '(lsp)))

View File

@ -20,8 +20,6 @@
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
(defconst vue-packages
'(web-mode
add-node-modules-path
@ -33,11 +31,17 @@
yasnippet))
(defun vue/post-init-web-mode ()
;; Define vue-mode as kind of web-mode
(define-derived-mode vue-mode web-mode "Vue")
(add-to-list 'auto-mode-alist '("\\.vue\\'" . vue-mode))
(spacemacs/add-to-hook 'vue-mode-hook '(spacemacs//vue-setup-editor-style
spacemacs//vue-setup-keybindings))
;; Setup stuff to be run each time we load the mode
(add-hook 'vue-mode-local-vars-hook #'spacemacs//vue-setup-backend)
(spacemacs/add-to-hook 'vue-mode-hook '(spacemacs//vue-setup-editor-style))
;; Add stuff to run just once
(spacemacs//vue-setup-keybindings)
(spacemacs//vue-setup-transient-state))
(defun vue/post-init-add-node-modules-path ()
@ -51,10 +55,14 @@
(add-hook 'vue-mode-hook 'turn-on-evil-matchit-mode))
(defun vue/post-init-flycheck ()
(with-eval-after-load 'flycheck
(flycheck-add-mode 'javascript-eslint 'vue-mode))
(spacemacs/enable-flycheck 'vue-mode)
(add-hook 'vue-mode-hook #'spacemacs//javascript-setup-checkers 'append))
;; Load eslint in case lsp diagnostics are not used
(when (or (and vue-ignore-lsp-diagnostics (equal vue-backend 'lsp))
(equal vue-backend 'dumb))
(with-eval-after-load 'flycheck
(flycheck-add-mode 'javascript-eslint 'vue-mode)
(add-hook 'vue-mode-hook #'spacemacs//javascript-setup-checkers 'append))))
(defun vue/pre-init-prettier-js ()
(add-to-list 'spacemacs--prettier-modes 'vue-mode))