new and impruved
This commit is contained in:
153
dots/doom/.back.modules/completion/corfu/README.org
Executable file
153
dots/doom/.back.modules/completion/corfu/README.org
Executable file
@@ -0,0 +1,153 @@
|
||||
#+title: :completion corfu
|
||||
#+subtitle: Complete with cap(f), cape and a flying feather
|
||||
#+created: September 9, 2022
|
||||
#+since: 3.0.0 (#7002)
|
||||
|
||||
* Description :unfold:
|
||||
This module provides code completion, powered by [[https://github.com/minad/corfu][corfu]].
|
||||
|
||||
It is recommended to enable either this or [[doom-module:][:completion company]], in case you
|
||||
desire pre-configured auto-completion. Corfu is much lighter weight and focused,
|
||||
plus it's built on native Emacs functionality, whereas company is heavy and
|
||||
highly non-native, but has some extra features and more maturity.
|
||||
|
||||
** Maintainers
|
||||
- [[doom-user:][@LuigiPiucco]]
|
||||
|
||||
[[doom-contrib-maintainer:][Become a maintainer?]]
|
||||
|
||||
** Module flags
|
||||
- +icons ::
|
||||
Display icons beside completion suggestions.
|
||||
- +tng ::
|
||||
Invoke completion on [[kbd:][TAB]]. When corfu is active, [[kbd:][TAB]] and [[kbd:][S-TAB]] will navigate
|
||||
the completion candidates. Arrow keys and evil-style movement are still
|
||||
supported.
|
||||
|
||||
** Packages
|
||||
- [[doom-package:][corfu]]
|
||||
- [[doom-package:][cape]]
|
||||
- [[doom-package:][kind-icon]] if [[doom-module:][:completion corfu +icons]]
|
||||
- [[doom-package:][corfu-terminal]] if [[doom-module:][:os tty]]
|
||||
|
||||
** Hacks
|
||||
/No hacks documented for this module./
|
||||
|
||||
** TODO Changelog
|
||||
# This section will be machine generated. Don't edit it by hand.
|
||||
/This module does not have a changelog yet./
|
||||
|
||||
* Installation
|
||||
Enable this module in your ~doom!~ block.
|
||||
|
||||
This module has no direct requirements, but some languages may have their own
|
||||
requirements to fulfill before you get code completion in them (and some
|
||||
languages may lack code completion support altogether). Run ~$ doom doctor~ to
|
||||
find out if you're missing any dependencies. Note that corfu may have support
|
||||
for completions in languages that have no development intelligence, since it
|
||||
supports generic, context insensitive candidates such as file names or recurring
|
||||
words.
|
||||
|
||||
* TODO Usage
|
||||
#+begin_quote
|
||||
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||
#+end_quote
|
||||
|
||||
** Code completion
|
||||
By default, completion gets triggered after typing 2 non-space consecutive
|
||||
characters, or by means of the [[kbd:][C-SPC]] keybinding at any moment. While the popup
|
||||
is visible, the following relevant keys are available:
|
||||
|
||||
| Keybind | Description |
|
||||
|----------+------------------------------------------------------|
|
||||
| [[kbd:][<down>]] | Go to next candidate |
|
||||
| [[kbd:][<up>]] | Go to previous candidate |
|
||||
| [[kbd:][C-n]] | Go to next candidate |
|
||||
| [[kbd:][C-p]] | Go to previous candidate |
|
||||
| [[kbd:][C-j]] | (evil) Go to next candidate |
|
||||
| [[kbd:][C-k]] | (evil) Go to previous candidate |
|
||||
| [[kbd:][C-<down>]] | Go to next doc line |
|
||||
| [[kbd:][C-<up>]] | Go to previous doc line |
|
||||
| [[kbd:][C-S-n]] | Go to next doc line |
|
||||
| [[kbd:][C-S-p]] | Go to previous doc line |
|
||||
| [[kbd:][C-S-j]] | (evil) Go to next doc line |
|
||||
| [[kbd:][C-S-k]] | (evil) Go to previous doc line |
|
||||
| [[kbd:][C-h]] | Toggle documentation (if available) |
|
||||
| [[kbd:][s-<down>]] | Export to minibuffer (if [[doom-module:][:completion vertico]]) |
|
||||
| [[kbd:][s-j]] | (evil) Export to minibuffer (if [[doom-module:][:completion vertico]]) |
|
||||
| [[kbd:][RET]] | Insert candidate |
|
||||
| [[kbd:][C-SPC]] | (when completing) Insert separator (see below) |
|
||||
| [[kbd:][C-SPC]] | Complete (unless [[doom-module:][:completion corfu +tng]]) |
|
||||
|
||||
If you prefer a [[kbd:][TAB]]-centric completion style, enable the [[doom-module:][:completion corfu +tng]]
|
||||
flag so that, instead, you trigger completion with [[kbd:][TAB]], getting the following
|
||||
additional binds:
|
||||
|
||||
| Keybind | Description |
|
||||
|---------+--------------------------------------------|
|
||||
| [[kbd:][TAB]] | Complete |
|
||||
| [[kbd:][TAB]] | (when completing) Go to next candidate |
|
||||
| [[kbd:][S-TAB]] | (when completing) Go to previous candidate |
|
||||
|
||||
** Searching with multiple keywords
|
||||
If the [[doom-module:][:completion vertico]] module is enabled, users can perform code completion
|
||||
with multiple search keywords by use of space as separator. More information can
|
||||
be found [[https://github.com/oantolin/orderless#company][here]]. Pressing [[kdb:][C-SPC]] again while completing inserts a space as
|
||||
separator. This allows searching with space-separated terms; each piece will
|
||||
match individually and in any order, with smart casing. Pressing just [[kbd:][SPC]] acts
|
||||
as normal and restarts completion, so that when typing sentences it doesn't try
|
||||
to complete the whole sentence instead of just the word.
|
||||
|
||||
Without [[doom-module:][:completion vertico]], it still works, just not as intelligently, due to
|
||||
the lack of orderless.
|
||||
|
||||
** Exporting to the minibuffer (requires [[doom-module:][:completion vertico]])
|
||||
When using the [[doom-module:][:completion vertico]] module, which pulls in the [[doom-package:][consult]] package,
|
||||
the entries shown in the completion popup can be exported to a consult
|
||||
minibuffer, giving access to all the manipulations the vertico suite allows. For
|
||||
instance, one could use this to export with [[doom-package:][embark]] via [[kbd:][C-c C-l]] and get a buffer
|
||||
with all candidates.
|
||||
|
||||
** Ispell completion
|
||||
Ispell completion is supported, so long as you point to the right ~.dic~ file in
|
||||
~ispell-alternate-dictionary~. For selected text modes (see the configuration
|
||||
section) it completes everywhere, for programming modes it can complete in
|
||||
comments and strings.
|
||||
|
||||
* Configuration
|
||||
A few variables may be set to change behavior of this module:
|
||||
|
||||
- +corfu-auto-delay ::
|
||||
Number of seconds till completion occurs automatically. Defaults to 0.1.
|
||||
- +corfu-auto-prefix ::
|
||||
Number of characters till auto-completion starts to happen. Defaults to 2.
|
||||
- +corfu-want-multi-component ::
|
||||
Sets whether orderless-style matching should be supported with space as a
|
||||
separator.
|
||||
- +corfu-ispell-completion-modes ::
|
||||
Lists modes in which to add ~cape-ispell~ as a capf. These show be majorly
|
||||
text modes, else you will get lots of bad suggestions, since when this matches
|
||||
it interrupts the flow of candidate selection.
|
||||
- +corfu-ispell-in-comments-and-strings ::
|
||||
Whether we should complete when point is inside a string or comment. If
|
||||
non-nil, works as in a text mode, else gives programming completions just like
|
||||
in the rest of the buffer.
|
||||
|
||||
Additionally, if you prefer to never stop completion on [[kbd:][SPC]], add the following
|
||||
to your ~config.el~:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(map! :map corfu-map
|
||||
:desc "insert separator" "C-SPC" #'corfu-insert-separator)
|
||||
#+end_src
|
||||
|
||||
* Troubleshooting
|
||||
[[doom-report:][Report an issue?]]
|
||||
|
||||
* Frequently asked questions
|
||||
/This module has no FAQs yet./ [[doom-suggest-faq:][Ask one?]]
|
||||
|
||||
* TODO Appendix
|
||||
#+begin_quote
|
||||
🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
||||
#+end_quote
|
||||
188
dots/doom/.back.modules/completion/corfu/config.el
Executable file
188
dots/doom/.back.modules/completion/corfu/config.el
Executable file
@@ -0,0 +1,188 @@
|
||||
;;; completion/corfu/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +corfu-auto-delay 0.1
|
||||
"How long after point stands still will completion be called automatically,
|
||||
in seconds.
|
||||
|
||||
Setting `corfu-auto-delay' directly may not work, as it needs to be set *before*
|
||||
enabling `corfu-mode'.")
|
||||
(defvar +corfu-auto-prefix 2
|
||||
"How many characters should be typed before auto-complete starts to kick in.
|
||||
|
||||
Setting `corfu-auto-prefix' directly may not work, as it needs to be set
|
||||
*before* enabling `corfu-mode'.")
|
||||
(defvar +corfu-want-multi-component t
|
||||
"Enables multiple component search, with pieces separated by spaces.
|
||||
|
||||
This allows search of non-contiguous unordered bits, for instance by typing
|
||||
\"tear rip\" to match \"rip-and-tear\". Notice the space, it does not break
|
||||
completion in this case.")
|
||||
(defvar +corfu-icon-height 0.9
|
||||
"The height applied to the icons (it is passed to both svg-lib and kind-icon).
|
||||
|
||||
It may need tweaking for the completions to not become cropped at the end.
|
||||
Note that changes are applied only after a cache reset, via
|
||||
`kind-icon-reset-cache'.")
|
||||
|
||||
(defvar +corfu-ispell-completion-modes '(org-mode markdown-mode text-mode)
|
||||
"Modes to enable ispell completion in.
|
||||
|
||||
For completion in comments, see `+corfu-ispell-in-comments-and-strings'.")
|
||||
(defvar +corfu-ispell-in-comments-and-strings t
|
||||
"Enable completion with ispell inside comments when in a `prog-mode'
|
||||
derivative.")
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
(use-package! corfu
|
||||
:hook (doom-first-buffer . global-corfu-mode)
|
||||
:init
|
||||
;; Auto-completion settings, must be set before calling `global-corfu-mode'.
|
||||
(setq corfu-auto t
|
||||
corfu-auto-delay +corfu-auto-delay
|
||||
corfu-auto-prefix +corfu-auto-prefix
|
||||
corfu-excluded-modes '(erc-mode
|
||||
circe-mode
|
||||
help-mode
|
||||
gud-mode
|
||||
vterm-mode))
|
||||
|
||||
:config
|
||||
(when (and (modulep! :tools lsp) (not (modulep! :tools lsp +eglot)))
|
||||
(add-hook 'lsp-mode-hook (defun doom--add-lsp-capf ()
|
||||
(add-to-list 'completion-at-point-functions (cape-capf-buster #'lsp-completion-at-point)))
|
||||
;; Below is so that context specific completions in cape come first.
|
||||
:depth 1))
|
||||
(add-to-list 'completion-styles 'partial-completion t)
|
||||
(add-to-list 'completion-styles 'initials t)
|
||||
(setq corfu-cycle t
|
||||
corfu-separator (when +corfu-want-multi-component ?\s)
|
||||
corfu-preselect t
|
||||
corfu-count 16
|
||||
corfu-max-width 120
|
||||
corfu-preview-current 'insert
|
||||
corfu-quit-at-boundary (if +corfu-want-multi-component 'separator t)
|
||||
corfu-quit-no-match (if +corfu-want-multi-component 'separator t)
|
||||
;; In the case of +tng, TAB should be smart regarding completion;
|
||||
;; However, it should otherwise behave like normal, whatever normal was.
|
||||
tab-always-indent (if (modulep! +tng) 'complete tab-always-indent))
|
||||
;; Only done with :tools vertico active due to orderless. Alternatively, we
|
||||
;; could set it up here if it's not there.
|
||||
(when (and +corfu-want-multi-component (modulep! :completion vertico))
|
||||
(cond ((modulep! :tools lsp +eglot) (add-to-list 'completion-category-overrides '(eglot (styles orderless))))
|
||||
((modulep! :tools lsp) (add-hook 'lsp-completion-mode-hook
|
||||
(defun doom--use-orderless-lsp-capf ()
|
||||
(setf (alist-get 'styles (alist-get 'lsp-capf completion-category-defaults))
|
||||
'(orderless)))))))
|
||||
(map! (:unless (modulep! +tng)
|
||||
:desc "complete" "C-SPC" #'completion-at-point)
|
||||
(:map 'corfu-map
|
||||
(:when +corfu-want-multi-component
|
||||
:desc "insert separator" "C-SPC" #'corfu-insert-separator)
|
||||
(:when (modulep! :completion vertico)
|
||||
:desc "move to minibuffer" "s-<down>" #'corfu-move-to-minibuffer
|
||||
(:when (modulep! :editor evil)
|
||||
:desc "move to minibuffer" "s-j" #'corfu-move-to-minibuffer))
|
||||
(:when (modulep! +tng)
|
||||
:desc "next" [tab] #'corfu-next
|
||||
:desc "previous" [backtab] #'corfu-previous
|
||||
:desc "next" "TAB" #'corfu-next
|
||||
:desc "previous" "S-TAB" #'corfu-previous))))
|
||||
|
||||
;; Taken from corfu's README.
|
||||
;; TODO: extend this to other completion front-ends, mainly helm and ido, since
|
||||
;; ivy is being considered for removal.
|
||||
(when (modulep! :completion vertico)
|
||||
(defun corfu-move-to-minibuffer ()
|
||||
(interactive)
|
||||
(let ((completion-extra-properties corfu--extra)
|
||||
completion-cycle-threshold completion-cycling)
|
||||
(apply #'consult-completion-in-region completion-in-region--data))))
|
||||
|
||||
(use-package! cape
|
||||
:after corfu
|
||||
:commands (cape-dabbrev
|
||||
cape-file
|
||||
cape-history
|
||||
cape-keyword
|
||||
cape-tex
|
||||
cape-sgml
|
||||
cape-rfc1345
|
||||
cape-abbrev
|
||||
cape-ispell
|
||||
cape-dict
|
||||
cape-symbol
|
||||
cape-line)
|
||||
:init
|
||||
(add-to-list 'completion-at-point-functions #'cape-file)
|
||||
(when +corfu-ispell-in-comments-and-strings
|
||||
(defalias 'corfu--ispell-in-comments-and-strings
|
||||
(cape-super-capf (cape-capf-inside-comment #'cape-ispell)
|
||||
(cape-capf-inside-string #'cape-ispell)))
|
||||
(add-hook 'prog-mode-hook
|
||||
(lambda ()
|
||||
(add-to-list 'completion-at-point-functions #'corfu--ispell-in-comments-and-strings))))
|
||||
(dolist (sym +corfu-ispell-completion-modes)
|
||||
(add-hook (intern (concat (symbol-name sym) "-hook"))
|
||||
(lambda ()
|
||||
(add-to-list 'completion-at-point-functions #'cape-ispell))))
|
||||
(add-hook! '(TeX-mode-hook LaTeX-mode-hook org-mode-hook)
|
||||
(lambda ()
|
||||
(add-to-list 'completion-at-point-functions #'cape-tex t))
|
||||
:depth 2)
|
||||
(add-hook! '(html-mode-hook +web-react-mode-hook typescript-tsx-mode-hook org-mode-hook markdown-mode-hook)
|
||||
(lambda ()
|
||||
(add-to-list 'completion-at-point-functions #'cape-sgml t))
|
||||
:depth 2)
|
||||
(add-to-list 'completion-at-point-functions #'cape-dabbrev)
|
||||
(add-to-list 'completion-at-point-functions #'cape-keyword)
|
||||
:config
|
||||
;; Enhances speed on large projects, for which many buffers may be open.
|
||||
(setq cape-dabbrev-check-other-buffers nil))
|
||||
|
||||
(use-package! kind-icon
|
||||
:when (modulep! +icons)
|
||||
:commands kind-icon-margin-formatter
|
||||
:init
|
||||
(add-hook 'corfu-margin-formatters #'kind-icon-margin-formatter)
|
||||
:config
|
||||
(setq kind-icon-default-face 'corfu-default
|
||||
kind-icon-blend-background t
|
||||
kind-icon-blend-frac 0.2)
|
||||
(plist-put kind-icon-default-style :height +corfu-icon-height)
|
||||
(plist-put svg-lib-style-default :height +corfu-icon-height))
|
||||
|
||||
(use-package! corfu-terminal
|
||||
:when (and (modulep! :os tty) (not (display-graphic-p)))
|
||||
:hook (corfu-mode . corfu-terminal-mode))
|
||||
|
||||
(use-package! dabbrev
|
||||
:config
|
||||
(setq dabbrev-ignored-buffer-regexps '("\\.\\(?:pdf\\|jpe?g\\|png\\)\\'")))
|
||||
|
||||
(setq read-extended-command-predicate
|
||||
#'command-completion-default-include-p)
|
||||
|
||||
;;
|
||||
;;; Extensions
|
||||
(use-package! corfu-history
|
||||
:after savehist
|
||||
:hook (corfu-mode . corfu-history-mode)
|
||||
:config
|
||||
(add-to-list 'savehist-additional-variables 'corfu-history))
|
||||
(use-package! corfu-popupinfo
|
||||
:hook (corfu-mode . corfu-popupinfo-mode)
|
||||
:config
|
||||
(setq corfu-popupinfo-delay '(0.5 . 1.0))
|
||||
(map! (:map 'corfu-map
|
||||
:desc "scroll info up" "C-<up>" #'corfu-popupinfo-scroll-down
|
||||
:desc "scroll info down" "C-<down>" #'corfu-popupinfo-scroll-up
|
||||
:desc "scroll info up" "C-S-p" #'corfu-popupinfo-scroll-down
|
||||
:desc "scroll info down" "C-S-n" #'corfu-popupinfo-scroll-up
|
||||
:desc "toggle info" "C-h" #'corfu-popupinfo-toggle)
|
||||
(:map 'corfu-popupinfo-map
|
||||
:when (modulep! :editor evil)
|
||||
;; Reversed because popupinfo assumes opposite of what feels intuitive
|
||||
;; with evil.
|
||||
:desc "scroll info up" "C-S-k" #'corfu-popupinfo-scroll-down
|
||||
:desc "scroll info down" "C-S-j" #'corfu-popupinfo-scroll-up)))
|
||||
10
dots/doom/.back.modules/completion/corfu/packages.el
Executable file
10
dots/doom/.back.modules/completion/corfu/packages.el
Executable file
@@ -0,0 +1,10 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; completion/corfu/packages.el
|
||||
|
||||
(package! corfu :recipe (:files ("*.el" "extensions/*.el")))
|
||||
(package! cape)
|
||||
(package! dabbrev)
|
||||
(when (modulep! +icons)
|
||||
(package! kind-icon))
|
||||
(when (modulep! :os tty)
|
||||
(package! corfu-terminal))
|
||||
57
dots/doom/.back.modules/tools/lsp2/+eglot.el
Executable file
57
dots/doom/.back.modules/tools/lsp2/+eglot.el
Executable file
@@ -0,0 +1,57 @@
|
||||
;;; tools/lsp/+eglot.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package! eglot
|
||||
:commands eglot eglot-ensure
|
||||
:hook (eglot-managed-mode . +lsp-optimization-mode)
|
||||
:init
|
||||
(setq eglot-sync-connect 1
|
||||
eglot-connect-timeout 10
|
||||
eglot-autoshutdown t
|
||||
eglot-send-changes-idle-time 0.5
|
||||
;; NOTE We disable eglot-auto-display-help-buffer because :select t in
|
||||
;; its popup rule causes eglot to steal focus too often.
|
||||
eglot-auto-display-help-buffer nil)
|
||||
(when (modulep! :checkers syntax)
|
||||
(setq eglot-stay-out-of '(flymake)))
|
||||
|
||||
:config
|
||||
(set-popup-rule! "^\\*eglot-help" :size 0.15 :quit t :select t)
|
||||
(set-lookup-handlers! 'eglot--managed-mode
|
||||
:definition #'xref-find-definitions
|
||||
:references #'xref-find-references
|
||||
:implementations #'eglot-find-implementation
|
||||
:type-definition #'eglot-find-typeDefinition
|
||||
:documentation #'+eglot-lookup-documentation)
|
||||
|
||||
(add-to-list 'doom-debug-variables '(eglot-events-buffer-size . 0))
|
||||
|
||||
(when (modulep! :checkers syntax)
|
||||
(after! flycheck
|
||||
(load! "autoload/flycheck-eglot")))
|
||||
|
||||
(defadvice! +lsp--defer-server-shutdown-a (fn &optional server)
|
||||
"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 #'eglot--managed-mode
|
||||
(letf! (defun eglot-shutdown (server)
|
||||
(if (or (null +lsp-defer-shutdown)
|
||||
(eq +lsp-defer-shutdown 0))
|
||||
(prog1 (funcall eglot-shutdown server)
|
||||
(+lsp-optimization-mode -1))
|
||||
(run-at-time
|
||||
(if (numberp +lsp-defer-shutdown) +lsp-defer-shutdown 3)
|
||||
nil (lambda (server)
|
||||
(unless (eglot--managed-buffers server)
|
||||
(prog1 (funcall eglot-shutdown server)
|
||||
(+lsp-optimization-mode -1))))
|
||||
server)))
|
||||
(funcall fn server))))
|
||||
|
||||
|
||||
(use-package! consult-eglot
|
||||
:defer t
|
||||
:when (modulep! :completion vertico)
|
||||
:init
|
||||
(map! :map eglot-mode-map [remap xref-find-apropos] #'consult-eglot-symbols))
|
||||
193
dots/doom/.back.modules/tools/lsp2/+lsp.el
Executable file
193
dots/doom/.back.modules/tools/lsp2/+lsp.el
Executable file
@@ -0,0 +1,193 @@
|
||||
;;; 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-data-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-data-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 #'+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)))))))
|
||||
(when (modulep! :completion corfu)
|
||||
(setq lsp-completion-provider :none)
|
||||
(add-hook 'lsp-mode-hook #'lsp-completion-mode)))
|
||||
|
||||
(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))
|
||||
155
dots/doom/.back.modules/tools/lsp2/README.org
Executable file
155
dots/doom/.back.modules/tools/lsp2/README.org
Executable file
@@ -0,0 +1,155 @@
|
||||
#+title: :tools lsp
|
||||
#+subtitle: M-x vscode
|
||||
#+created: March 05, 2019
|
||||
#+since: 21.12.0
|
||||
|
||||
* Description :unfold:
|
||||
This module integrates [[https://langserver.org/][language servers]] into Doom Emacs. They provide features
|
||||
you'd expect from IDEs, like code completion, realtime linting, language-aware
|
||||
[[doom-package:imenu]]/[[doom-package:xref]] integration, jump-to-definition/references support, and more.
|
||||
|
||||
As of this writing, this is the state of LSP support in Doom Emacs:
|
||||
|
||||
| Module | Major modes | Default language server |
|
||||
|------------------+---------------------------------------------------------+---------------------------------------------------------------|
|
||||
| [[doom-module::lang cc]] | c-mode, c++-mode, objc-mode | ccls, clangd |
|
||||
| [[doom-module::lang clojure]] | clojure-mode | clojure-lsp |
|
||||
| [[doom-module::lang csharp]] | csharp-mode | omnisharp |
|
||||
| [[doom-module::lang elixir]] | elixir-mode | elixir-ls |
|
||||
| [[doom-module::lang fsharp]] | fsharp-mode | Mono, .NET core |
|
||||
| [[doom-module::lang go]] | go-mode | go-langserver |
|
||||
| [[doom-module::lang haskell]] | haskell-mode | haskell-language-server |
|
||||
| [[doom-module::lang java]] | java-mode | lsp-java |
|
||||
| [[doom-module::lang javascript]] | js2-mode, rjsx-mode, typescript-mode | ts-ls, deno-ls |
|
||||
| [[doom-module::lang julia]] | julia-mode | LanguageServer.jl |
|
||||
| [[doom-module::lang ocaml]] | tuareg-mode | ocaml-language-server |
|
||||
| [[doom-module::lang php]] | php-mode | php-language-server |
|
||||
| [[doom-module::lang purescript]] | purescript-mode | purescript-language-server |
|
||||
| [[doom-module::lang python]] | python-mode | lsp-python-ms |
|
||||
| [[doom-module::lang ruby]] | ruby-mode | solargraph |
|
||||
| [[doom-module::lang rust]] | rust-mode | rls |
|
||||
| [[doom-module::lang scala]] | scala-mode | metals |
|
||||
| [[doom-module::lang sh]] | sh-mode | bash-language-server |
|
||||
| [[doom-module::lang swift]] | swift-mode | sourcekit |
|
||||
| [[doom-module::lang web]] | web-mode, css-mode, scss-mode, sass-mode, less-css-mode | vscode-css-languageserver-bin, vscode-html-languageserver-bin |
|
||||
| [[doom-module::lang zig]] | zig-mode | zls |
|
||||
|
||||
** Maintainers
|
||||
/This module has no dedicated maintainers./ [[doom-contrib-maintainer:][Become a maintainer?]]
|
||||
|
||||
** Module flags
|
||||
- +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.
|
||||
- +peek ::
|
||||
Use ~lsp-ui-peek~ when looking up definitions and references with
|
||||
functionality from the [[doom-module::tools lookup]] module.
|
||||
|
||||
** Packages
|
||||
- [[doom-package:lsp-mode]]
|
||||
- [[doom-package:lsp-ui]]
|
||||
- [[doom-package:lsp-ivy]] ([[doom-module::completion ivy]])
|
||||
- [[doom-package:helm-lsp]] ([[doom-module::completion helm]])
|
||||
- [[doom-package:consult-lsp]] ([[doom-module::completion vertico]])
|
||||
- [[doom-package:eglot]]
|
||||
|
||||
** Hacks
|
||||
/No hacks documented for this module./
|
||||
|
||||
** TODO Changelog
|
||||
# This section will be machine generated. Don't edit it by hand.
|
||||
/This module does not have a changelog yet./
|
||||
|
||||
* Installation
|
||||
[[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]]
|
||||
|
||||
To get LSP working, you'll need to do three things:
|
||||
|
||||
1. Enable this module,
|
||||
2. Install a language server appropriate for your targeted language(s).
|
||||
3. Enable the [[doom-module:+lsp]] flag on the [[doom-module::lang]] modules you want to enable LSP support for.
|
||||
|
||||
Different languages will need different language servers, some of which [[doom-package:lsp-mode]]
|
||||
will prompt you to auto-install, but [[doom-package:eglot]] will not.
|
||||
|
||||
A table that lists available language servers and how to install them can be
|
||||
found [[https://emacs-lsp.github.io/lsp-mode/page/languages/][on the lsp-mode project README]]. The documentation of the module for your
|
||||
targeted language will contain brief instructions as well.
|
||||
|
||||
For eglot users, a list of [[https://github.com/joaotavora/eglot/blob/master/README.md#connecting-to-a-server][default servers supported is on Eglot's README]],
|
||||
including instructions to register your own.
|
||||
|
||||
* TODO Usage
|
||||
#+begin_quote
|
||||
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||
#+end_quote
|
||||
|
||||
** LSP-powered project search
|
||||
Without the [[doom-module:+eglot]] flag, and when [[doom-module::completion ivy]], [[doom-module::completion helm]] or
|
||||
[[doom-module::completion vertico]] is active, LSP is used to search a symbol indexed by the LSP
|
||||
server:
|
||||
| Keybind | Description |
|
||||
|---------+-------------------------------------|
|
||||
| [[kbd:][SPC c j]] | Jump to symbol in current workspace |
|
||||
| [[kbd:][SPC c J]] | Jump to symbol in any workspace |
|
||||
|
||||
** Differences between eglot and lsp-mode
|
||||
The two projects are large and actively developed, so without writing a novel,
|
||||
it can only be compared in (very) broad strokes:
|
||||
|
||||
- [[doom-package:lsp-mode]] tends to be more featureful, beginner-friendly (e.g. offers to
|
||||
install servers for you and has more [[https://emacs-lsp.github.io/lsp-mode][helpful documentation]]), and has a user
|
||||
experience that feels familiar to modern editors/IDEs, but at the cost of
|
||||
performance (at baseline) and complexity (it has more moving parts and
|
||||
reinvents a number of wheels to achieve a slicker UI, like ~lsp-ui-peek~,
|
||||
~lsp-ui-sideline~, etc).
|
||||
|
||||
- [[doom-package:eglot]] has fewer bells and whistles: it relies on built-in Emacs functionality
|
||||
more (eldoc, xref, capf, project.el, etc), offers less pre-configuration for
|
||||
you, and is more performant than lsp-mode (again, at baseline). It also works
|
||||
with TRAMP out-of-the-box (lsp-mode needs some extra configuration).
|
||||
|
||||
#+begin_quote
|
||||
💬 I recommend beginners use lsp-mode. More experienced users may also opt to
|
||||
disable many of [[https://emacs-lsp.github.io/lsp-mode/tutorials/how-to-turn-off/][its inessential features]] to gain back some ground on
|
||||
performance and complexity costs.
|
||||
#+end_quote
|
||||
|
||||
All that said, it's easy to switch between the two implementations by swapping
|
||||
in/out the [[doom-module:+lsp]] or [[doom-module:+eglot]] flag when [[id:01cffea4-3329-45e2-a892-95a384ab2338][enabling this module]].
|
||||
|
||||
* TODO Configuration
|
||||
#+begin_quote
|
||||
🔨 /This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||
#+end_quote
|
||||
|
||||
** Turn off lsp-mode's intrusive features
|
||||
Many users may not like how many UI elements that lsp-mode adds. They have [[https://emacs-lsp.github.io/lsp-mode/tutorials/how-to-turn-off/][some
|
||||
excellent documentation]] outlining what these features are called and how to turn
|
||||
them off.
|
||||
|
||||
* Troubleshooting
|
||||
[[doom-report:][Report an issue?]]
|
||||
|
||||
** 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 have enabled the [[doom-module:+lsp]] flag on the appropriate module(s) (in
|
||||
your ~doom!~ block in =$DOOMDIR/init.el=):
|
||||
#+begin_src diff
|
||||
:lang
|
||||
-python
|
||||
+(python +lsp)
|
||||
#+end_src
|
||||
|
||||
** LSP is slow
|
||||
Follow [[https://emacs-lsp.github.io/lsp-mode/page/performance/#tuning][lsp-tuning-guide]] to further fine-tune LSP mode performance.
|
||||
|
||||
* Frequently asked questions
|
||||
/This module has no FAQs yet./ [[doom-suggest-faq:][Ask one?]]
|
||||
|
||||
* TODO Appendix
|
||||
#+begin_quote
|
||||
🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
||||
#+end_quote
|
||||
10
dots/doom/.back.modules/tools/lsp2/autoload/common.el
Executable file
10
dots/doom/.back.modules/tools/lsp2/autoload/common.el
Executable file
@@ -0,0 +1,10 @@
|
||||
;;; tools/lsp/autoload/common.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autodef (fset 'lsp! #'ignore)
|
||||
(defun lsp! ()
|
||||
"Dispatch to call the currently used lsp client entrypoint"
|
||||
(interactive)
|
||||
(if (modulep! +eglot)
|
||||
(eglot-ensure)
|
||||
(unless (bound-and-true-p lsp-mode)
|
||||
(lsp-deferred))))
|
||||
39
dots/doom/.back.modules/tools/lsp2/autoload/eglot.el
Executable file
39
dots/doom/.back.modules/tools/lsp2/autoload/eglot.el
Executable file
@@ -0,0 +1,39 @@
|
||||
;;; tools/lsp/autoload/eglot.el -*- lexical-binding: t; -*-
|
||||
;;;###if (modulep! +eglot)
|
||||
|
||||
;;;###autodef
|
||||
(defun set-eglot-client! (mode server-call)
|
||||
"Add SERVER-CALL list as a possible lsp server for given major MODE.
|
||||
|
||||
Example : (set-eglot-client! 'python-mode `(,(concat doom-data-dir \"lsp/mspyls/Microsoft.Python.LanguageServer\")))"
|
||||
(after! eglot
|
||||
(add-to-list 'eglot-server-programs `(,mode . ,server-call))))
|
||||
|
||||
;; HACK Eglot removed `eglot-help-at-point' in joaotavora/eglot@a044dec for a
|
||||
;; more problematic approach of deferred to eldoc. Here, I've restored it.
|
||||
;; Doom's lookup handlers try to open documentation in a separate window
|
||||
;; (so they can be copied or kept open), but doing so with an eldoc buffer
|
||||
;; is difficult because a) its contents are generated asynchronously,
|
||||
;; making them tough to scrape, and b) their contents change frequently
|
||||
;; (every time you move your cursor).
|
||||
(defvar +eglot--help-buffer nil)
|
||||
;;;###autoload
|
||||
(defun +eglot-lookup-documentation (_identifier)
|
||||
"Request documentation for the thing at point."
|
||||
(eglot--dbind ((Hover) contents range)
|
||||
(jsonrpc-request (eglot--current-server-or-lose) :textDocument/hover
|
||||
(eglot--TextDocumentPositionParams))
|
||||
(let ((blurb (and (not (seq-empty-p contents))
|
||||
(eglot--hover-info contents range)))
|
||||
(hint (thing-at-point 'symbol)))
|
||||
(if blurb
|
||||
(with-current-buffer
|
||||
(or (and (buffer-live-p +eglot--help-buffer)
|
||||
+eglot--help-buffer)
|
||||
(setq +eglot--help-buffer (generate-new-buffer "*eglot-help*")))
|
||||
(with-help-window (current-buffer)
|
||||
(rename-buffer (format "*eglot-help for %s*" hint))
|
||||
(with-current-buffer standard-output (insert blurb))
|
||||
(setq-local nobreak-char-display nil)))
|
||||
(display-local-help))))
|
||||
'deferred)
|
||||
76
dots/doom/.back.modules/tools/lsp2/autoload/flycheck-eglot.el
Executable file
76
dots/doom/.back.modules/tools/lsp2/autoload/flycheck-eglot.el
Executable file
@@ -0,0 +1,76 @@
|
||||
;;; flycheck-eglot --- Hacky eglot support in flycheck -*- lexical-binding: t; -*-
|
||||
;;; Commentary:
|
||||
;; This file sets up flycheck so that, when eglot receives a publishDiagnostics method
|
||||
;; from the server, flycheck updates the reports.
|
||||
;;
|
||||
;; Thanks to:
|
||||
;; - joaotavora for adding a handle to plug flycheck, and
|
||||
;; - purcell for finding out the initial stub and the current implementation
|
||||
;;
|
||||
;; It works by creating a bridge function which can be used as the argument of
|
||||
;; `eglot-flymake-backend', which both consumes diagnostics and queue a call to
|
||||
;; 'flycheck-buffer'
|
||||
;;
|
||||
;;; Code:
|
||||
|
||||
(defvar-local +lsp--flycheck-eglot--current-errors nil)
|
||||
|
||||
(defun +lsp--flycheck-eglot-init (checker callback)
|
||||
"CHECKER is the checker (eglot).
|
||||
CALLBACK is the function that we need to call when we are done, on all the errors."
|
||||
(eglot-flymake-backend #'+lsp--flycheck-eglot--on-diagnostics)
|
||||
(funcall callback 'finished +lsp--flycheck-eglot--current-errors))
|
||||
|
||||
(defun +lsp--flycheck-eglot--on-diagnostics (diags &rest _)
|
||||
(cl-labels
|
||||
((flymake-diag->flycheck-err
|
||||
(diag)
|
||||
(with-current-buffer (flymake--diag-buffer diag)
|
||||
(flycheck-error-new-at-pos
|
||||
(flymake--diag-beg diag)
|
||||
(pcase (flymake--diag-type diag)
|
||||
('eglot-note 'info)
|
||||
('eglot-warning 'warning)
|
||||
('eglot-error 'error)
|
||||
(_ (error "Unknown diagnostic type, %S" diag)))
|
||||
(flymake--diag-text diag)
|
||||
:end-pos (flymake--diag-end diag)
|
||||
:checker 'eglot
|
||||
:buffer (current-buffer)
|
||||
:filename (buffer-file-name)))))
|
||||
(setq +lsp--flycheck-eglot--current-errors
|
||||
(mapcar #'flymake-diag->flycheck-err diags))
|
||||
;; Call Flycheck to update the diagnostics annotations
|
||||
(flycheck-buffer-deferred)))
|
||||
|
||||
(defun +lsp--flycheck-eglot-available-p ()
|
||||
(bound-and-true-p eglot--managed-mode))
|
||||
|
||||
(flycheck-define-generic-checker 'eglot
|
||||
"Report `eglot' diagnostics using `flycheck'."
|
||||
:start #'+lsp--flycheck-eglot-init
|
||||
:predicate #'+lsp--flycheck-eglot-available-p
|
||||
:modes '(prog-mode text-mode))
|
||||
|
||||
(push 'eglot flycheck-checkers)
|
||||
|
||||
(add-hook! 'eglot-managed-mode-hook
|
||||
(defun +lsp-eglot-prefer-flycheck-h ()
|
||||
(when eglot--managed-mode
|
||||
(flymake-mode -1)
|
||||
(when-let ((current-checker (flycheck-get-checker-for-buffer)))
|
||||
(unless (equal current-checker 'eglot)
|
||||
(flycheck-add-next-checker 'eglot current-checker)))
|
||||
(flycheck-add-mode 'eglot major-mode)
|
||||
(flycheck-mode 1)
|
||||
;; Call flycheck on initilization to make sure to display initial
|
||||
;; errors
|
||||
(flycheck-buffer-deferred))))
|
||||
|
||||
(after! flymake
|
||||
(when (and
|
||||
(not (fboundp 'flymake--diag-buffer))
|
||||
(fboundp 'flymake--diag-locus))
|
||||
(defalias 'flymake--diag-buffer 'flymake--diag-locus)))
|
||||
|
||||
;;; flycheck-eglot.el ends here
|
||||
75
dots/doom/.back.modules/tools/lsp2/autoload/lsp-mode.el
Executable file
75
dots/doom/.back.modules/tools/lsp2/autoload/lsp-mode.el
Executable file
@@ -0,0 +1,75 @@
|
||||
;;; tools/lsp/autoload/lsp-mode.el -*- lexical-binding: t; -*-
|
||||
;;;###if (not (modulep! +eglot))
|
||||
|
||||
;;;###autodef
|
||||
(defun set-lsp-priority! (client priority)
|
||||
"Change the PRIORITY of lsp CLIENT."
|
||||
(require 'lsp-mode)
|
||||
(if-let (client (gethash client lsp-clients))
|
||||
(setf (lsp--client-priority client)
|
||||
priority)
|
||||
(error "No LSP client named %S" client)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +lsp/uninstall-server (dir)
|
||||
"Delete a LSP server from `lsp-server-install-dir'."
|
||||
(interactive
|
||||
(list (read-directory-name "Uninstall LSP server: " lsp-server-install-dir nil t)))
|
||||
(unless (file-directory-p dir)
|
||||
(user-error "Couldn't find %S directory" dir))
|
||||
(delete-directory dir 'recursive)
|
||||
(message "Uninstalled %S" (file-name-nondirectory dir)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +lsp/switch-client (client)
|
||||
"Switch to another LSP server."
|
||||
(interactive
|
||||
(progn
|
||||
(require 'lsp-mode)
|
||||
(list (completing-read
|
||||
"Select server: "
|
||||
(or (mapcar #'lsp--client-server-id (lsp--filter-clients (-andfn #'lsp--supports-buffer?
|
||||
#'lsp--server-binary-present?)))
|
||||
(user-error "No available LSP clients for %S" major-mode))))))
|
||||
(require 'lsp-mode)
|
||||
(let* ((client (if (symbolp client) client (intern client)))
|
||||
(match (car (lsp--filter-clients (lambda (c) (eq (lsp--client-server-id c) client)))))
|
||||
(workspaces (lsp-workspaces)))
|
||||
(unless match
|
||||
(user-error "Couldn't find an LSP client named %S" client))
|
||||
(let ((old-priority (lsp--client-priority match)))
|
||||
(setf (lsp--client-priority match) 9999)
|
||||
(unwind-protect
|
||||
(if workspaces
|
||||
(lsp-workspace-restart
|
||||
(if (cdr workspaces)
|
||||
(lsp--completing-read "Select server: "
|
||||
workspaces
|
||||
'lsp--workspace-print
|
||||
nil t)
|
||||
(car workspaces)))
|
||||
(lsp-mode +1))
|
||||
(add-transient-hook! 'lsp-after-initialize-hook
|
||||
(setf (lsp--client-priority match) old-priority))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +lsp-lookup-definition-handler ()
|
||||
"Find definition of the symbol at point using LSP."
|
||||
(interactive)
|
||||
(when-let (loc (lsp-request "textDocument/definition"
|
||||
(lsp--text-document-position-params)))
|
||||
(lsp-show-xrefs (lsp--locations-to-xref-items loc) nil nil)
|
||||
'deferred))
|
||||
|
||||
;;;###autoload
|
||||
(defun +lsp-lookup-references-handler (&optional include-declaration)
|
||||
"Find project-wide references of the symbol at point using LSP."
|
||||
(interactive "P")
|
||||
(when-let
|
||||
(loc (lsp-request "textDocument/references"
|
||||
(append (lsp--text-document-position-params)
|
||||
(list
|
||||
:context `(:includeDeclaration
|
||||
,(lsp-json-bool include-declaration))))))
|
||||
(lsp-show-xrefs (lsp--locations-to-xref-items loc) nil t)
|
||||
'deferred))
|
||||
47
dots/doom/.back.modules/tools/lsp2/config.el
Executable file
47
dots/doom/.back.modules/tools/lsp2/config.el
Executable file
@@ -0,0 +1,47 @@
|
||||
;;; tools/lsp/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +lsp-defer-shutdown 3
|
||||
"If non-nil, defer shutdown of LSP servers for this many seconds after last
|
||||
workspace buffer is closed.
|
||||
|
||||
This delay prevents premature server shutdown when a user still intends on
|
||||
working on that project after closing the last buffer, or when programmatically
|
||||
killing and opening many LSP/eglot-powered buffers.")
|
||||
|
||||
|
||||
;;
|
||||
;;; Common
|
||||
|
||||
(defvar +lsp--default-read-process-output-max nil)
|
||||
(defvar +lsp--default-gcmh-high-cons-threshold nil)
|
||||
(defvar +lsp--optimization-init-p nil)
|
||||
|
||||
(define-minor-mode +lsp-optimization-mode
|
||||
"Deploys universal GC and IPC optimizations for `lsp-mode' and `eglot'."
|
||||
:global t
|
||||
:init-value nil
|
||||
(if (not +lsp-optimization-mode)
|
||||
(setq-default read-process-output-max +lsp--default-read-process-output-max
|
||||
gcmh-high-cons-threshold +lsp--default-gcmh-high-cons-threshold
|
||||
+lsp--optimization-init-p nil)
|
||||
;; Only apply these settings once!
|
||||
(unless +lsp--optimization-init-p
|
||||
(setq +lsp--default-read-process-output-max (default-value 'read-process-output-max)
|
||||
+lsp--default-gcmh-high-cons-threshold (default-value 'gcmh-high-cons-threshold))
|
||||
(setq-default read-process-output-max (* 1024 1024))
|
||||
;; REVIEW LSP causes a lot of allocations, with or without the native JSON
|
||||
;; library, so we up the GC threshold to stave off GC-induced
|
||||
;; slowdowns/freezes. Doom uses `gcmh' to enforce its GC strategy,
|
||||
;; so we modify its variables rather than `gc-cons-threshold'
|
||||
;; directly.
|
||||
(setq-default gcmh-high-cons-threshold (* 2 +lsp--default-gcmh-high-cons-threshold))
|
||||
(gcmh-set-high-threshold)
|
||||
(setq +lsp--optimization-init-p t))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Implementations
|
||||
|
||||
(if (modulep! +eglot)
|
||||
(load! "+eglot")
|
||||
(load! "+lsp"))
|
||||
9
dots/doom/.back.modules/tools/lsp2/doctor.el
Executable file
9
dots/doom/.back.modules/tools/lsp2/doctor.el
Executable file
@@ -0,0 +1,9 @@
|
||||
;;; tools/lsp/doctor.el -*- lexical-binding: t; -*-
|
||||
|
||||
(assert! (not (and (modulep! +eglot)
|
||||
(modulep! +peek)))
|
||||
"+eglot and +peek flags are not compatible. Peek uses lsp-mode, while Eglot is another package altogether for LSP.")
|
||||
|
||||
(unless (executable-find "npm")
|
||||
(warn! "Couldn't find npm, most server installers won't work and will have to be installed manually.
|
||||
For more information, see https://emacs-lsp.github.io/lsp-mode/page/languages/."))
|
||||
16
dots/doom/.back.modules/tools/lsp2/packages.el
Executable file
16
dots/doom/.back.modules/tools/lsp2/packages.el
Executable file
@@ -0,0 +1,16 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/lsp/packages.el
|
||||
|
||||
(if (modulep! +eglot)
|
||||
(progn
|
||||
(package! eglot :pin "e501275e06952889056268dabe08ccd0dbaf23e5")
|
||||
(when (modulep! :completion vertico)
|
||||
(package! consult-eglot :pin "0da8801dd8435160ce1f62ad8066bd52e38f5cbd")))
|
||||
(package! lsp-mode :pin "a3b3c15359405f442fc51a2db09e503ca3b39f3d")
|
||||
(package! lsp-ui :pin "3cd7cc61273341023b863dcf45906ac9142fd1aa")
|
||||
(when (modulep! :completion ivy)
|
||||
(package! lsp-ivy :pin "9ecf4dd9b1207109802bd1882aa621eb1c385106"))
|
||||
(when (modulep! :completion helm)
|
||||
(package! helm-lsp :pin "c2c6974dadfac459b1a69a1217441283874cea92"))
|
||||
(when (modulep! :completion vertico)
|
||||
(package! consult-lsp :pin "58b541476203fa68e9e7682531f2a10e11780857")))
|
||||
Reference in New Issue
Block a user