- Deprecates the doom-private-dir variable in favor of doom-user-dir. - Renames the pseudo category for the user's module: :private -> :user. - Renames the doom-private-error error type to doom-user-error. Emacs uses the term "user" to refer to the "things" in user space (e.g. user-init-file, user-emacs-directory, user-mail-address, xdg-user-dirs, package-user-dir, etc), and I'd like to be consistent with that. It also has the nice side-effect of being slightly shorter. I also hope 'doom-user-error' will be less obtuse to beginners than 'doom-private-error'.
200 lines
7.9 KiB
EmacsLisp
200 lines
7.9 KiB
EmacsLisp
;;; tools/lsp/+lsp.el -*- lexical-binding: t; -*-
|
|
|
|
(defvar +lsp-company-backends
|
|
(if (modulep! :editor snippets)
|
|
'(:separate company-capf company-yasnippet)
|
|
'company-capf)
|
|
"The backends to prepend to `company-backends' in `lsp-mode' buffers.
|
|
Can be a list of backends; accepts any value `company-backends' accepts.")
|
|
|
|
|
|
;;
|
|
;;; Packages
|
|
|
|
(use-package! lsp-mode
|
|
:commands lsp-install-server
|
|
:init
|
|
;; Don't touch ~/.emacs.d, which could be purged without warning
|
|
(setq lsp-session-file (concat doom-cache-dir "lsp-session")
|
|
lsp-server-install-dir (concat doom-etc-dir "lsp"))
|
|
;; Don't auto-kill LSP server after last workspace buffer is killed, because I
|
|
;; will do it for you, after `+lsp-defer-shutdown' seconds.
|
|
(setq lsp-keep-workspace-alive nil)
|
|
|
|
;; NOTE I tweak LSP's defaults in order to make its more expensive or imposing
|
|
;; features opt-in. Some servers implement these poorly and, in most
|
|
;; cases, it's safer to rely on Emacs' native mechanisms (eldoc vs
|
|
;; lsp-ui-doc, open in popup vs sideline, etc).
|
|
|
|
;; Disable features that have great potential to be slow.
|
|
(setq lsp-enable-folding nil
|
|
lsp-enable-text-document-color nil)
|
|
;; Reduce unexpected modifications to code
|
|
(setq lsp-enable-on-type-formatting nil)
|
|
;; Make breadcrumbs opt-in; they're redundant with the modeline and imenu
|
|
(setq lsp-headerline-breadcrumb-enable nil)
|
|
|
|
;; Let doom bind the lsp keymap.
|
|
(when (modulep! :config default +bindings)
|
|
(setq lsp-keymap-prefix nil))
|
|
|
|
:config
|
|
(add-to-list 'doom-debug-variables 'lsp-log-io)
|
|
|
|
(setq lsp-intelephense-storage-path (concat doom-etc-dir "lsp-intelephense/")
|
|
lsp-vetur-global-snippets-dir
|
|
(expand-file-name
|
|
"vetur" (or (bound-and-true-p +snippets-dir)
|
|
(concat doom-user-dir "snippets/")))
|
|
lsp-xml-jar-file (expand-file-name "org.eclipse.lsp4xml-0.3.0-uber.jar" lsp-server-install-dir)
|
|
lsp-groovy-server-file (expand-file-name "groovy-language-server-all.jar" lsp-server-install-dir))
|
|
|
|
;; REVIEW Remove this once this is fixed upstream.
|
|
(add-to-list 'lsp-client-packages 'lsp-racket)
|
|
|
|
(add-hook! 'doom-escape-hook
|
|
(defun +lsp-signature-stop-maybe-h ()
|
|
"Close the displayed `lsp-signature'."
|
|
(when lsp-signature-mode
|
|
(lsp-signature-stop)
|
|
t)))
|
|
|
|
(set-popup-rule! "^\\*lsp-\\(help\\|install\\)" :size 0.35 :quit t :select t)
|
|
(set-lookup-handlers! 'lsp-mode
|
|
:definition #'+lsp-lookup-definition-handler
|
|
:references #'+lsp-lookup-references-handler
|
|
:documentation '(lsp-describe-thing-at-point :async t)
|
|
:implementations '(lsp-find-implementation :async t)
|
|
:type-definition #'lsp-find-type-definition)
|
|
|
|
(defadvice! +lsp--respect-user-defined-checkers-a (fn &rest args)
|
|
"Ensure user-defined `flycheck-checker' isn't overwritten by `lsp'."
|
|
:around #'lsp-diagnostics-flycheck-enable
|
|
(if flycheck-checker
|
|
(let ((old-checker flycheck-checker))
|
|
(apply fn args)
|
|
(setq-local flycheck-checker old-checker))
|
|
(apply fn args)))
|
|
|
|
(add-hook! 'lsp-mode-hook
|
|
(defun +lsp-display-guessed-project-root-h ()
|
|
"Log what LSP things is the root of the current project."
|
|
;; Makes it easier to detect root resolution issues.
|
|
(when-let (path (buffer-file-name (buffer-base-buffer)))
|
|
(if-let (root (lsp--calculate-root (lsp-session) path))
|
|
(lsp--info "Guessed project root is %s" (abbreviate-file-name root))
|
|
(lsp--info "Could not guess project root."))))
|
|
#'+lsp-optimization-mode)
|
|
|
|
(when (modulep! :completion company)
|
|
(add-hook! 'lsp-completion-mode-hook
|
|
(defun +lsp-init-company-backends-h ()
|
|
(when lsp-completion-mode
|
|
(set (make-local-variable 'company-backends)
|
|
(cons +lsp-company-backends
|
|
(remove +lsp-company-backends
|
|
(remq 'company-capf company-backends))))))))
|
|
|
|
(defvar +lsp--deferred-shutdown-timer nil)
|
|
(defadvice! +lsp-defer-server-shutdown-a (fn &optional restart)
|
|
"Defer server shutdown for a few seconds.
|
|
This gives the user a chance to open other project files before the server is
|
|
auto-killed (which is a potentially expensive process). It also prevents the
|
|
server getting expensively restarted when reverting buffers."
|
|
:around #'lsp--shutdown-workspace
|
|
(if (or lsp-keep-workspace-alive
|
|
restart
|
|
(null +lsp-defer-shutdown)
|
|
(= +lsp-defer-shutdown 0))
|
|
(prog1 (funcall fn restart)
|
|
(+lsp-optimization-mode -1))
|
|
(when (timerp +lsp--deferred-shutdown-timer)
|
|
(cancel-timer +lsp--deferred-shutdown-timer))
|
|
(setq +lsp--deferred-shutdown-timer
|
|
(run-at-time
|
|
(if (numberp +lsp-defer-shutdown) +lsp-defer-shutdown 3)
|
|
nil (lambda (workspace)
|
|
(with-lsp-workspace workspace
|
|
(unless (lsp--workspace-buffers workspace)
|
|
(let ((lsp-restart 'ignore))
|
|
(funcall fn))
|
|
(+lsp-optimization-mode -1))))
|
|
lsp--cur-workspace))))
|
|
|
|
(when (modulep! :ui modeline +light)
|
|
(defvar-local lsp-modeline-icon nil)
|
|
|
|
(add-hook! '(lsp-before-initialize-hook
|
|
lsp-after-initialize-hook
|
|
lsp-after-uninitialized-functions
|
|
lsp-before-open-hook
|
|
lsp-after-open-hook)
|
|
(defun +lsp-update-modeline (&rest _)
|
|
"Update modeline with lsp state."
|
|
(let* ((workspaces (lsp-workspaces))
|
|
(face (if workspaces 'success 'warning))
|
|
(label (if workspaces "LSP Connected" "LSP Disconnected")))
|
|
(setq lsp-modeline-icon (concat
|
|
" "
|
|
(+modeline-format-icon 'faicon "rocket" "" face label -0.0575)
|
|
" "))
|
|
(add-to-list 'global-mode-string
|
|
'(t (:eval lsp-modeline-icon))
|
|
'append))))))
|
|
|
|
|
|
(use-package! lsp-ui
|
|
:hook (lsp-mode . lsp-ui-mode)
|
|
:init
|
|
(defadvice! +lsp--use-hook-instead-a (fn &rest args)
|
|
"Change `lsp--auto-configure' to not force `lsp-ui-mode' on us. Using a hook
|
|
instead is more sensible."
|
|
:around #'lsp--auto-configure
|
|
(letf! ((#'lsp-ui-mode #'ignore))
|
|
(apply fn args)))
|
|
|
|
:config
|
|
(when (modulep! +peek)
|
|
(set-lookup-handlers! 'lsp-ui-mode
|
|
:definition 'lsp-ui-peek-find-definitions
|
|
:implementations 'lsp-ui-peek-find-implementation
|
|
:references 'lsp-ui-peek-find-references
|
|
:async t))
|
|
|
|
(setq lsp-ui-peek-enable (modulep! +peek)
|
|
lsp-ui-doc-max-height 8
|
|
lsp-ui-doc-max-width 72 ; 150 (default) is too wide
|
|
lsp-ui-doc-delay 0.75 ; 0.2 (default) is too naggy
|
|
lsp-ui-doc-show-with-mouse nil ; don't disappear on mouseover
|
|
lsp-ui-doc-position 'at-point
|
|
lsp-ui-sideline-ignore-duplicate t
|
|
;; Don't show symbol definitions in the sideline. They are pretty noisy,
|
|
;; and there is a bug preventing Flycheck errors from being shown (the
|
|
;; errors flash briefly and then disappear).
|
|
lsp-ui-sideline-show-hover nil
|
|
;; Re-enable icon scaling (it's disabled by default upstream for Emacs
|
|
;; 26.x compatibility; see emacs-lsp/lsp-ui#573)
|
|
lsp-ui-sideline-actions-icon lsp-ui-sideline-actions-icon-default)
|
|
|
|
(map! :map lsp-ui-peek-mode-map
|
|
"j" #'lsp-ui-peek--select-next
|
|
"k" #'lsp-ui-peek--select-prev
|
|
"C-k" #'lsp-ui-peek--select-prev-file
|
|
"C-j" #'lsp-ui-peek--select-next-file))
|
|
|
|
|
|
(use-package! helm-lsp
|
|
:when (modulep! :completion helm)
|
|
:commands helm-lsp-workspace-symbol helm-lsp-global-workspace-symbol)
|
|
|
|
|
|
(use-package! lsp-ivy
|
|
:when (modulep! :completion ivy)
|
|
:commands lsp-ivy-workspace-symbol lsp-ivy-global-workspace-symbol)
|
|
|
|
|
|
(use-package! consult-lsp
|
|
:defer t
|
|
:when (modulep! :completion vertico)
|
|
:init
|
|
(map! :map lsp-mode-map [remap xref-find-apropos] #'consult-lsp-symbols))
|