Add: add lsp-javascript backend for javascript layer

This commit is contained in:
Ting Zhou 2018-04-26 16:33:41 -07:00 committed by syl20bnr
parent 2be6e4e338
commit f3ee2edf1b
4 changed files with 128 additions and 22 deletions

View File

@ -6,8 +6,11 @@
- [[#description][Description]]
- [[#features][Features:]]
- [[#install][Install]]
- [[#configuration][Configuration]]
- [[#choosing-a-backend][Choosing a backend]]
- [[#backends][Backends]]
- [[#tern][Tern]]
- [[#language-server-protocol][Language Server Protocol]]
- [[#configuration][Configuration]]
- [[#indentation][Indentation]]
- [[#repl][REPL]]
- [[#node-modules][Node Modules]]
@ -39,12 +42,6 @@ To use this configuration layer, add it to your =~/.spacemacs=. You will need to
add =javascript= to the existing =dotspacemacs-configuration-layers= list in
this file.
You will also need to install =tern= to use the auto-completion and
documentation features:
#+BEGIN_SRC sh
$ npm install -g tern
#+END_SRC
To use the formatting features, install =js-beautify=:
#+BEGIN_SRC sh
$ npm install -g js-beautify
@ -63,8 +60,33 @@ If you install these in non-standard locations, then add the following to your =
(add-to-list 'exec-path "/path/to/node/bins" t)
#+END_SRC
* Configuration
** Choosing a backend
To choose a default backend set the layer variable =javascript-backend=:
#+BEGIN_SRC elisp
(javascript :variables javascript-backend 'tern)
#+END_SRC
Backend can be chosen on a per project basis using directory local variables
(files named =.dir-locals.el= at the root of a project), an example to use the
=lsp= backend:
#+BEGIN_SRC elisp
;;; Directory Local Variables
;;; For more information see (info "(emacs) Directory Variables")
((js2-mode (javascript-backend . lsp)))
#+END_SRC
*Note:* you can easily add a directory local variable with ~SPC f v d~.
* Backends
** Tern
Install =tern= to use the auto-completion and documentation features:
#+BEGIN_SRC sh
$ npm install -g tern
#+END_SRC
To make tern re-use the server across multiple different editing sessions (thus
creating multiple =.tern-port= files for each document you have open [[http://ternjs.net/doc/manual.html][see here
for more details]]):
@ -85,6 +107,14 @@ layer:
(javascript :variables tern-command '("node" "/path/to/tern/bin/tern"))
#+END_SRC
** Language Server Protocol
You just have to install python language server package:
#+begin_src sh
npm i -g typescript javascript-typescript-langserver flow-language-server typescript-language-server
#+end_src
* Configuration
** Indentation
To change how js2-mode indents code, set the variable =js2-basic-offset=, as
such:

View File

@ -15,3 +15,7 @@
(defvar javascript-disable-tern-port-files t
"Stops tern from creating tern port files.")
(defvar javascript-backend 'tern
"The backend to use for IDE features. Possible values are `tern'
and `lsp'.")

View File

@ -80,13 +80,44 @@
(skewer-repl)
(evil-insert-state))
;; backend
(defun spacemacs//javascript-setup-backend ()
"Conditionally setup javascript backend."
(pcase javascript-backend
(`tern(spacemacs//javascript-setup-tern))
(`lsp (spacemacs//javascript-setup-lsp))))
(defun spacemacs//javascript-setup-company ()
"Conditionally setup company based on backend."
(pcase javascript-backend
(`tern (spacemacs//javascript-setup-tern-company))
(`lsp (spacemacs//javascript-setup-lsp-company))))
;; tern
(defun spacemacs//javascript-setup-tern ()
"Setup tern backend."
(add-hook 'js2-mode-hook 'tern-mode)
(progn
(spacemacs|hide-lighter tern-mode)
(when javascript-disable-tern-port-files
(add-to-list 'tern-command "--no-port-file" 'append))
(spacemacs//set-tern-key-bindings 'js2-mode)))
(defun spacemacs//javascript-setup-tern-company ()
"Setup tern auto-completion."
(spacemacs|add-company-backends
:backends company-tern
:modes js2-mode)
(company-mode))
(defun spacemacs//set-tern-key-bindings (mode)
"Set the key bindings for tern and the given MODE."
(add-to-list (intern (format "spacemacs-jump-handlers-%S" mode))
'(tern-find-definition :async t))
'(tern-find-definition :async t))
(spacemacs/set-leader-keys-for-major-mode mode
"rrV" 'tern-rename-variable
"hd" 'tern-get-docs
@ -100,3 +131,45 @@
(unless found
(spacemacs-buffer/warning "tern binary not found!"))
found))
;; lsp
(defun spacemacs//javascript-setup-lsp ()
"Setup lsp backend."
(if (configuration-layer/layer-used-p 'lsp)
(progn
(add-hook 'js-mode-hook #'lsp-javascript-typescript-enable)
(require 'lsp-javascript-flow)
(add-hook 'js-mode-hook #'lsp-javascript-flow-enable)
(add-hook 'js2-mode-hook #'lsp-javascript-flow-enable) ;; for js2-mode support
(require 'lsp-typescript)
(add-hook 'js-mode-hook #'lsp-typescript-enable)
(add-hook 'js2-mode-hook #'lsp-typescript-enable) ;; for js2-mode support
(spacemacs//set-lsp-key-bindings 'js2-mode))
(message "`lsp' layer is not installed, please add `lsp' layer to your dofile.")))
(defun spacemacs//javascript-setup-lsp-company ()
"Setup lsp auto-completion."
(if (configuration-layer/layer-used-p 'lsp)
(progn
;; fix lsp-javascript company prefix
;; https://github.com/emacs-lsp/lsp-javascript/issues/9#issuecomment-379515379
(defun my-company-transformer (candidates)
(let ((completion-ignore-case t))
(all-completions (company-grab-symbol) candidates)))
(defun my-js-hook nil
(make-local-variable 'company-transformers)
(push 'my-company-transformer company-transformers))
(add-hook 'js-mode-hook 'my-js-hook)
(spacemacs|add-company-backends
:backends company-lsp
:modes js2-mode)
(company-mode))
(message "`lsp' layer is not installed, please add `lsp' layer to your dofile.")))
(defun spacemacs//set-lsp-key-bindings (mode)
"Set the key bindings for tern and the given MODE."
(add-to-list (intern (format "spacemacs-jump-handlers-%S" mode))
'(lsp-ui-peek-find-definitions)))

View File

@ -30,6 +30,7 @@
web-beautify
skewer-mode
livid-mode
(lsp-javascript-typescript :requires lsp-mode)
))
(defun javascript/post-init-add-node-modules-path ()
@ -66,12 +67,10 @@
(use-package company-tern
:if (and (configuration-layer/package-used-p 'company)
(configuration-layer/package-used-p 'tern))
:defer t
:init (spacemacs|add-company-backends
:backends company-tern
:modes js2-mode)))
:defer t))
(defun javascript/post-init-company ()
(add-hook 'js2-mode-hook #'spacemacs//javascript-setup-company)
(spacemacs|add-company-backends
:backends company-capf
:modes coffee-mode))
@ -104,7 +103,9 @@
(progn
(add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))
;; Required to make imenu functions work correctly
(add-hook 'js2-mode-hook 'js2-imenu-extras-mode))
(add-hook 'js2-mode-hook 'js2-imenu-extras-mode)
;; setup javascript backend
(add-hook 'js2-mode-hook 'spacemacs//javascript-setup-backend))
:config
(progn
;; prefixes
@ -193,14 +194,7 @@
(defun javascript/init-tern ()
(use-package tern
:defer t
:init (add-hook 'js2-mode-hook 'tern-mode)
:config
(progn
(spacemacs|hide-lighter tern-mode)
(when javascript-disable-tern-port-files
(add-to-list 'tern-command "--no-port-file" 'append))
(spacemacs//set-tern-key-bindings 'js2-mode))))
:defer t))
(defun javascript/init-web-beautify ()
(use-package web-beautify
@ -253,3 +247,8 @@
:documentation "Live evaluation of JS buffer change."
:evil-leader-for-mode (js2-mode . "Tl"))
(spacemacs|diminish livid-mode " 🅻" " [l]"))))
(defun javascript/init-lsp-javascript-typescript ()
(use-package lsp-javascript-typescript
:commands lsp-javascript-typescript-enable
:defer t))