new and impruved
This commit is contained in:
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))
|
||||
Reference in New Issue
Block a user