Updating Doom Emacs.

This commit is contained in:
Derek Taylor
2020-06-19 22:43:40 -05:00
parent 0f664d532a
commit a5c86c514a
453 changed files with 13527 additions and 12455 deletions

View File

@@ -7,8 +7,10 @@
- [[#description][Description]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#hacks][Hacks]]
- [[#prerequisites][Prerequisites]]
- [[#features][Features]]
- [[#lsp-powered-project-search][LSP-powered project search]]
- [[#configuration][Configuration]]
- [[#troubleshooting][Troubleshooting]]
@@ -40,23 +42,36 @@ As of this writing, this is the state of LSP support in Doom Emacs:
| [[../../lang/haskell/README.org][:lang haskell]] | haskell-mode | haskell-ide-engine |
| [[../../lang/java/README.org][:lang java]] | java-mode | lsp-java |
| [[../../lang/javascript/README.org][:lang javascript]] | js2-mode, rjsx-mode, typescript-mode | typescript-language-server |
| [[../../lang/ocaml/README.org][:lang ocaml]] | taureg-mode | ocaml-language-server |
| [[../../lang/ocaml/README.org][:lang ocaml]] | tuareg-mode | ocaml-language-server |
| [[../../lang/php/README.org][:lang php]] | php-mode | php-language-server |
| [[../../lang/python/README.org][:lang python]] | python-mode | lsp-python-ms |
| [[../../lang/ruby/README.org][:lang ruby]] | ruby-mode, enh-ruby-mode | solargraph |
| [[../../lang/ruby/README.org][:lang ruby]] | ruby-mode | solargraph |
| [[../../lang/rust/README.org][:lang rust]] | rust-mode | rls |
| [[../../lang/scala/README.org][:lang scala]] | scala-mode | metals |
| [[../../lang/sh/README.org][:lang sh]] | sh-mode | bash-language-server |
| [[../../lang/swift/README.org][:lang swift]] | swift-mode | sourcekit |
| [[../../lang/web/README.org][:lang web]] | web-mode, css-mode, scss-mode, sass-mode, less-css-mode | vscode-css-languageserver-bin, vscode-html-languageserver-bin |
| [[../../lang/purescript/README.org][:lang purescript]] | purescript-mode | purescript-language-server |
** Module Flags
This module provides no flags.
+ =+peek= Use =lsp-ui-peek= when looking up definitions and references with
functionality from the =:tools lookup= module.
+ =+eglot= Use [[https://elpa.gnu.org/packages/eglot.html][Eglot]] instead of [[https://github.com/emacs-lsp/lsp-mode][LSP-mode]] to implement the LSP client in
Emacs.
** Plugins
+ [[https://github.com/emacs-lsp/lsp-mode][lsp-mode]]
+ [[https://github.com/emacs-lsp/lsp-ui][lsp-ui]]
+ [[https://github.com/tigersoldier/company-lsp][company-lsp]]*
+ [[https://github.com/emacs-lsp/lsp-ivy][lsp-ivy]]
+ [[https://github.com/emacs-lsp/helm-lsp][helm-lsp]]
+ [[https://github.com/joaotavora/eglot][eglot]]
** Hacks
+ ~lsp-mode~ has been modified not to automatically install missing LSP servers.
This is done to adhere to our "Your system, your rules" mantra, which insist
that it is better etiquette to let the user decide when their development
environment is modified. Use ~M-x lsp-install-server~ to install LSP servers
manually.
* Prerequisites
This module has no direct prerequisites, but major-modes require you to install
@@ -66,8 +81,37 @@ You'll find a table that lists available language servers and how to install
them [[https://github.com/emacs-lsp/lsp-mode#supported-languages][in the lsp-mode project README]]. The documentation of the module for your
targeted language will contain brief instructions as well.
For eglot users, you can see the list of [[https://github.com/joaotavora/eglot/blob/master/README.md#connecting-to-a-server][default servers supported in the README]].
There is also instructions to add another server easily.
* TODO Features
** LSP-powered project search
Without the =+eglot= flag, and when =:completion ivy= or =:completion helm= is
active, LSP is used to search a symbol indexed by the LSP server :
| Keybind | Description |
|-----------+-------------------------------------|
| =SPC c j= | Jump to symbol in current workspace |
| =SPC c J= | Jump to symbol in any workspace |
** Differences between eglot and lsp-mode
Entering the debate about which one to use would be useless. Doom provides an
easy way to switch out lsp client implementations so you can test for yourself
which one you prefer.
Mainly, from a code point of view, lsp-mode has a lot of custom code for UI
(=lsp-ui-peek=, =lsp-ui-sideline=, ...), while eglot is more barebones with a
closer integration with "more basic" emacs packages (=eldoc=, =xref=, ...).
* TODO Configuration
* TODO Troubleshooting
** My language server is not found
Check the entry in the [[../../../docs/faq.org][FAQ]] about "Doom can't find my executables/doesn't inherit
the correct ~PATH~"
** LSP/Eglot is not started automatically in my buffer
Make sure that you added the =+lsp= flag to the language you're using too in
your init.el :
#+BEGIN_SRC diff
:lang
-python
+(python +lsp)
#+END_SRC

View File

@@ -1,4 +0,0 @@
;;; feature/lsp/autoload.el -*- lexical-binding: t; -*-
;;;###autodef
(defalias 'lsp! #'lsp-deferred)

View File

@@ -1,150 +1,16 @@
;;; tools/lsp/config.el -*- lexical-binding: t; -*-
(defvar +lsp-company-backend 'company-lsp
"What backend to prepend to `company-backends' when `lsp-mode' is active.
(defvar +lsp-defer-shutdown 3
"If non-nil, defer shutdown of LSP servers for this many seconds after last
workspace buffer is closed.
This can be a single company backend or a list thereof. It can be anything
`company-backends' will accept.")
This delay prevents premature server shutdown when a user still intends on
working on that project after closing the last buffer.")
;;
;;; Packages
;;; Implementations
(use-package! lsp-mode
:defer t
:init
(setq lsp-session-file (concat doom-etc-dir "lsp-session"))
;; Don't prompt the user for the project root every time we open a new
;; lsp-worthy file, instead, try to guess it with projectile.
(setq lsp-auto-guess-root t)
;; Auto-kill LSP server once you've killed the last buffer associated with its
;; project.
(setq lsp-keep-workspace-alive nil)
;; For `lsp-clients'
(setq lsp-fsharp-server-install-dir (concat doom-etc-dir "lsp-fsharp/")
lsp-groovy-server-install-dir (concat doom-etc-dir "lsp-groovy/")
lsp-intelephense-storage-path (concat doom-cache-dir "lsp-intelephense/"))
:config
(set-lookup-handlers! 'lsp-mode :async t
:documentation 'lsp-describe-thing-at-point
:definition 'lsp-find-definition
:references 'lsp-find-references)
(defvar +lsp--deferred-shutdown-timer nil)
(defadvice! +lsp-defer-server-shutdown-a (orig-fn)
"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 usually an expensive process)."
:around #'lsp--shutdown-workspace
(if (or lsp-keep-workspace-alive
(eq (lsp--workspace-shutdown-action lsp--cur-workspace)
'restart))
(funcall orig-fn)
(when (timerp +lsp--deferred-shutdown-timer)
(cancel-timer +lsp--deferred-shutdown-timer))
(setq +lsp--deferred-shutdown-timer
(run-at-time
3 nil (lambda (workspace)
(let ((lsp--cur-workspace workspace))
(unless (lsp--workspace-buffers lsp--cur-workspace)
(funcall orig-fn))))
lsp--cur-workspace))))
(defadvice! +lsp-prompt-if-no-project-a (session file-name)
"Prompt for the project root only if no project was found."
:after-until #'lsp--calculate-root
(cond ((not lsp-auto-guess-root)
nil)
((cl-find-if (lambda (dir)
(and (lsp--files-same-host dir file-name)
(file-in-directory-p file-name dir)))
(lsp-session-folders-blacklist session))
nil)
((lsp--find-root-interactively session))))
(defadvice! +lsp-init-a (&optional arg)
"Enable `lsp-mode' in the current buffer.
Meant to be a lighter alternative to `lsp', which is too eager about
initializing lsp-ui-mode, company, yasnippet and flycheck. Instead, these have
been moved out to their respective modules, or these hooks:
+ `+lsp-init-company-h' (on `lsp-mode-hook')
+ `+lsp-init-ui-flycheck-or-flymake-h' (on `lsp-ui-mode-hook')
Also logs the resolved project root, if found."
:override #'lsp
(interactive "P")
(require 'lsp-mode)
(when lsp-auto-configure
(require 'lsp-clients))
(and (buffer-file-name)
(setq-local
lsp--buffer-workspaces
(or (lsp--try-open-in-library-workspace)
(lsp--try-project-root-workspaces
(equal arg '(4))
(and arg (not (equal arg 1))))))
(prog1 (lsp-mode 1)
;; Announce what project root we're using, for diagnostic purposes
(if-let (root (lsp--calculate-root (lsp-session) (buffer-file-name)))
(lsp--info "Guessed project root is %s" (abbreviate-file-name root))
(lsp--info "Could not guess project root."))
(lsp--info "Connected to %s."
(apply #'concat
(mapcar
(lambda (it) (format "[%s]" (lsp--workspace-print it)))
lsp--buffer-workspaces))))))
;; Don't prompt to restart LSP servers while quitting Emacs
(add-hook! 'kill-emacs-hook (setq lsp-restart 'ignore)))
(use-package! lsp-ui
:hook (lsp-mode . lsp-ui-mode)
:init
(add-hook! 'lsp-ui-mode-hook
(defun +lsp-init-ui-flycheck-or-flymake-h ()
"Sets up flymake-mode or flycheck-mode, depending on `lsp-prefer-flymake'."
(cond ((eq :none lsp-prefer-flymake))
(lsp-prefer-flymake
(lsp--flymake-setup))
((require 'flycheck nil t)
(require 'lsp-ui-flycheck)
(lsp-ui-flycheck-enable t)))))
:config
(setq lsp-prefer-flymake nil
lsp-ui-doc-max-height 8
lsp-ui-doc-max-width 35
lsp-ui-sideline-ignore-duplicate t
;; lsp-ui-doc is redundant with and more invasive than
;; `+lookup/documentation'
lsp-ui-doc-enable nil
;; 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)
(set-lookup-handlers! 'lsp-ui-mode :async t
:definition 'lsp-ui-peek-find-definitions
:references 'lsp-ui-peek-find-references))
(use-package! company-lsp
:when (featurep! :completion company)
:defer t
:init
;; Make sure that `company-capf' is disabled since it is incompatible with
;; `company-lsp' (see lsp-mode#884)
(add-hook! 'lsp-mode-hook
(defun +lsp-init-company-h ()
(if (not (bound-and-true-p company-mode))
(add-hook 'company-mode-hook #'+lsp-init-company-h t t)
(setq-local company-backends
(cons +lsp-company-backend
(remq 'company-capf company-backends)))
(remove-hook 'company-mode-hook #'+lsp-init-company-h t))))
:config
(setq company-lsp-cache-candidates 'auto)) ;; cache candidates for better performance
(if (featurep! +eglot)
(load! "+eglot")
(load! "+lsp"))

View File

@@ -1,7 +1,15 @@
;; -*- no-byte-compile: t; -*-
;;; tools/lsp/packages.el
(package! lsp-mode)
(package! lsp-ui)
(when (featurep! :completion company)
(package! company-lsp))
(if (featurep! +eglot)
(progn
(package! eglot :pin "ac9239bed5e3bfbf057382d1a75cdfa23f2caddd")
(package! project
:recipe (:host github :repo "emacs-straight/project")
:pin "da0333a697b18f0a863c1b1523d2fc7991b31174"))
(package! lsp-mode :pin "5f3f9848b2d4afc69049121c60126a6405447106")
(package! lsp-ui :pin "d92cf83d95c9ca177b735500ead88cf68dc2e2db")
(when (featurep! :completion ivy)
(package! lsp-ivy :pin "dce58b5509271bbedb53ba9d0278dcb563a43977"))
(when (featurep! :completion helm)
(package! helm-lsp :pin "5018af9c709a783de1b9e101e07c948cceed67f1")))