How to speed up lsp-mode
Here is my setup,
(with-eval-after-load 'lsp-mode
;; enable log only for debug
(setq lsp-log-io nil)
;; use `evil-matchit' instead
(setq lsp-enable-folding nil)
;; no real time syntax check
(setq lsp-diagnostic-package :none)
;; handle yasnippet by myself
(setq lsp-enable-snippet nil)
;; use `company-ctags' only.
;; Please note `company-lsp' is automatically enabled if installed
(setq lsp-enable-completion-at-point nil)
;; turn off for better performance
(setq lsp-enable-symbol-highlighting nil)
;; use ffip instead
(setq lsp-enable-links nil)
;; auto restart lsp
(setq lsp-restart 'auto-restart)
;; @see https://github.com/emacs-lsp/lsp-mode/pull/1498 and code related to auto configure.
;; Require clients could be slow.
;; I only load `lsp-clients' because it includes the js client which I'm interested
(setq lsp-client-packages '(lsp-clients))
;; don't scan 3rd party javascript libraries
(push "[/\\\\][^/\\\\]*\\.\\(json\\|html\\|jade\\)$" lsp-file-watch-ignored) ; json
;; don't ping LSP lanaguage server too frequently
(defvar lsp-on-touch-time 0)
(defadvice lsp-on-change (around lsp-on-change-hack activate)
;; don't run `lsp-on-change' too frequently
(when (> (- (float-time (current-time))
lsp-on-touch-time) 30) ;; 30 seconds
(setq lsp-on-touch-time (float-time (current-time)))
ad-do-it)))
(defun my-connect-lsp (&optional no-reconnect)
"Connect lsp server. If NO-RECONNECT is t, don't shutdown existing lsp connection."
(interactive "P")
(when (and (not no-reconnect)
(fboundp 'lsp-disconnect))
(lsp-disconnect))
(when (and buffer-file-name
(not (member (file-name-extension buffer-file-name)
'("json"))))
(unless (and (boundp 'lsp-mode) lsp-mode)
(if (derived-mode-p 'js2-mode) (setq-local lsp-enable-imenu nil))
(lsp-deferred))))
To enable lsp
for the major mode XXX-mode
needs only one line,
(add-hook 'XXX-mode-hook #'my-connect-lsp)
You also need install three packages,
- counsel-etags for code navigation
- company-ctags for code completion
- find-file-in-project (ffip) for searching file in project
Explanation,
Ctags is used to generate tags file for company-ctags
and counsel-etags
. GNU Find is required for find-file-in-project
.
These three packages are faster and can replace the corresponding functionalities in lsp-mode
.
I don't need any lint tools from lsp-mode
because the lint tool is already included in our build script. I can see the syntax error from terminal.
I advice the lsp-on-change
in order to notify the language server less frequently.
js2-mode
has its own javascript parser extract imenu items. So I don't need javascript language server's parser to send back imenu items.
By default lsp-client-packages
contains many clients, but I only code in javascript which is included in lsp-clients
.
Here is code quoted from lsp-mode,
;;;###autoload
(defun lsp (&optional arg)
;; ...
(when (and lsp-auto-configure)
(seq-do (lambda (package) (require package nil t))
lsp-client-packages))
;; ...
)
I have done some profiling by insert (profiler-report-cpu)
at the end of lsp
(the bottlenecks is highlighted).
The language server I used can read jsconfig.json in project root. I can specify the directories to exclude in it.