mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-24 05:22:04 -08:00
Eglot: rework Flymake integration ahead of more changes
LSP Diagnostics are converted to Flymake diagnostics just-in-time. Introduce helpers that allow precise control over the type of the reports (clearing or incremental) and the inhibition of reports. * lisp/progmodes/eglot.el (eglot--pulled-diagnostics) (eglot--pushed-diagnostics): Rework docstring. (eglot--flymake-sniff-diagnostics): Rename from eglot--flymake-diagnostics. (eglot--diagnostics-map, cl-loop, eglot-warning) (eglot-note, eglot-error): Move to Flymake section. (eglot--find-buffer-visiting): New helper.. (eglot--flymake-handle-push): New helper. (eglot--flymake-report-1, eglot--flymake-report-2) (eglot--flymake-report-push+pulled): New helpers. (eglot--flymake-make-diag): Take REGION arg. (eglot--handle-notification<textDocument/PublishDiagnostics>): Use eglot--flymake-handle-push. (eglot--flymake-pull): Call eglot--flymake-report-push+pulled. (eglot--flymake-report): Delete. (eglot--flymake-reset): New helper. (eglot--managed-mode): Use eglot--flymake-reset. (eglot--diag-to-lsp-diag): Delete. (eglot--signal-textDocument/didOpen) (eglot--managed-mode): Use eglot--flymake-reset. (eglot--maybe-activate-editing-mode): Don't reset Flymake things here. (eglot--code-action-params): Tweak. (eglot--code-action-bounds): Use eglot--flymake-sniff-diagnostics. (eglot--capf-session-flush): Tweak.
This commit is contained in:
parent
6921244718
commit
89633fef71
1 changed files with 182 additions and 139 deletions
|
|
@ -2227,15 +2227,16 @@ Use `eglot-managed-p' to determine if current buffer is managed.")
|
|||
(defvar eglot--highlights nil "Overlays for `eglot-highlight-eldoc-function'.")
|
||||
|
||||
(defvar-local eglot--pulled-diagnostics nil
|
||||
"A list (DIAGNOSTICS RESULT-ID) \"pulled\" for current buffer.
|
||||
DIAGNOSTICS is a list of Flymake diagnostics objects. RESULT-ID
|
||||
identifies this diagnostic result as is used for incremental updates.")
|
||||
"A list (DIAGNOSTICS VERSION RESULT-ID) \"pulled\" for current buffer.
|
||||
DIAGNOSTICS is a sequence of LSP or Flymake diagnostics objects.
|
||||
RESULT-ID identifies this diagnostic result as is used for incremental
|
||||
updates.")
|
||||
|
||||
(defvar-local eglot--pushed-diagnostics nil
|
||||
"A list (DIAGNOSTICS VERSION) \"pushed\" for current buffer.
|
||||
DIAGNOSTICS is a list of Flymake diagnostics objects. VERSION is the
|
||||
LSP Document version reported for DIAGNOSTICS (comparable to
|
||||
`eglot--docver') or nil if server didn't bother.")
|
||||
DIAGNOSTICS is a sequence of LSP or Flymake diagnostics objects.
|
||||
VERSION is the LSP Document version reported for DIAGNOSTICS (comparable
|
||||
to `eglot--docver') or nil if server didn't bother.")
|
||||
|
||||
(defvar-local eglot--suggestion-overlay (make-overlay 0 0)
|
||||
"Overlay for `eglot-code-action-suggestion'.")
|
||||
|
|
@ -2316,11 +2317,8 @@ LSP Document version reported for DIAGNOSTICS (comparable to
|
|||
(cl-loop for (var . saved-binding) in eglot--saved-bindings
|
||||
do (set (make-local-variable var) saved-binding))
|
||||
(remove-function (local 'imenu-create-index-function) #'eglot-imenu)
|
||||
(when eglot--flymake-report-fn
|
||||
(setq eglot--pulled-diagnostics nil
|
||||
eglot--pushed-diagnostics nil)
|
||||
(eglot--flymake-report)
|
||||
(setq eglot--flymake-report-fn nil))
|
||||
(eglot--flymake-reset)
|
||||
(setq eglot--flymake-report-fn nil)
|
||||
(run-hooks 'eglot-managed-mode-hook)
|
||||
(let ((server eglot--cached-server))
|
||||
(setq eglot--cached-server nil)
|
||||
|
|
@ -2373,8 +2371,6 @@ If it is activated, also signal textDocument/didOpen."
|
|||
;; Called when `revert-buffer-in-progress-p' is t but
|
||||
;; `revert-buffer-preserve-modes' is nil.
|
||||
(when (and buffer-file-name (eglot-current-server))
|
||||
(setq eglot--pulled-diagnostics nil
|
||||
eglot--pushed-diagnostics nil)
|
||||
(eglot--managed-mode)
|
||||
(eglot--signal-textDocument/didOpen)
|
||||
;; Run user hook after 'textDocument/didOpen' so server knows
|
||||
|
|
@ -2643,40 +2639,6 @@ still unanswered LSP requests to the server\n"))))
|
|||
when rest concat (if titlep ":" "/")))))
|
||||
"] ")))
|
||||
|
||||
|
||||
;;; Flymake customization
|
||||
;;;
|
||||
(put 'eglot-note 'flymake-category 'flymake-note)
|
||||
(put 'eglot-warning 'flymake-category 'flymake-warning)
|
||||
(put 'eglot-error 'flymake-category 'flymake-error)
|
||||
|
||||
(defun eglot--flymake-diagnostics (beg &optional end)
|
||||
"Like `flymake-diagnostics', but for Eglot-specific diagnostics."
|
||||
(cl-loop for diag in (flymake-diagnostics beg end)
|
||||
for data = (flymake-diagnostic-data diag)
|
||||
for lsp-diag = (alist-get 'eglot-lsp-diag data)
|
||||
for version = (alist-get 'eglot--doc-version data)
|
||||
when (and lsp-diag (or (null version)
|
||||
(= version eglot--docver)))
|
||||
collect diag))
|
||||
|
||||
(defun eglot--diag-to-lsp-diag (diag)
|
||||
(alist-get 'eglot-lsp-diag (flymake-diagnostic-data diag)))
|
||||
|
||||
(defvar eglot-diagnostics-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [mouse-2] #'eglot-code-actions-at-mouse)
|
||||
(define-key map [left-margin mouse-1] #'eglot-code-actions-at-mouse)
|
||||
map)
|
||||
"Keymap active in Eglot-backed Flymake diagnostic overlays.")
|
||||
|
||||
(cl-loop for i from 1
|
||||
for type in '(eglot-note eglot-warning eglot-error)
|
||||
do (put type 'flymake-overlay-control
|
||||
`((mouse-face . highlight)
|
||||
(priority . ,(+ 50 i))
|
||||
(keymap . ,eglot-diagnostics-map))))
|
||||
|
||||
|
||||
;;; Protocol implementation (Requests, notifications, etc)
|
||||
;;;
|
||||
|
|
@ -2765,56 +2727,6 @@ Value is (TRUENAME . (:uri STR)), where STR is what is sent to the
|
|||
server on textDocument/didOpen and similar calls. TRUENAME is the
|
||||
expensive cached value of `file-truename'.")
|
||||
|
||||
(cl-defmethod eglot-handle-notification
|
||||
(server (_method (eql textDocument/publishDiagnostics))
|
||||
&key uri diagnostics version
|
||||
&allow-other-keys) ; FIXME: doesn't respect `eglot-strict-mode'
|
||||
"Handle notification publishDiagnostics."
|
||||
(cl-flet ((find-it (abspath)
|
||||
;; `find-buffer-visiting' would be natural, but calls the
|
||||
;; potentially slow `file-truename' (bug#70036).
|
||||
(cl-loop for b in (eglot--managed-buffers server)
|
||||
when (with-current-buffer b
|
||||
(equal (car eglot--TextDocumentIdentifier-cache)
|
||||
abspath))
|
||||
return b)))
|
||||
(if-let* ((path (expand-file-name (eglot-uri-to-path uri)))
|
||||
(buffer (find-it path)))
|
||||
(with-current-buffer buffer
|
||||
(cl-loop
|
||||
initially
|
||||
(if (and version (/= version eglot--docver))
|
||||
(cl-return))
|
||||
(setq
|
||||
;; if no explicit version received, assume it's current.
|
||||
version eglot--docver
|
||||
flymake-list-only-diagnostics
|
||||
(assoc-delete-all path flymake-list-only-diagnostics))
|
||||
for diag-spec across diagnostics
|
||||
collect (eglot--flymake-make-diag diag-spec version)
|
||||
into diags
|
||||
finally
|
||||
(setq eglot--pushed-diagnostics (list diags version))
|
||||
(when (not (null flymake-no-changes-timeout ))
|
||||
;; only add to current report if Flymake
|
||||
;; starts on idle-timer (github#957)
|
||||
(eglot--flymake-report))))
|
||||
(cl-loop
|
||||
for diag-spec across diagnostics
|
||||
collect (eglot--dbind ((Diagnostic) code range message severity source) diag-spec
|
||||
(let* ((start (plist-get range :start))
|
||||
(line (1+ (plist-get start :line)))
|
||||
(char (1+ (plist-get start :character))))
|
||||
(flymake-make-diagnostic
|
||||
path (cons line char) nil
|
||||
(eglot--flymake-diag-type severity)
|
||||
(list source code message))))
|
||||
into diags
|
||||
finally
|
||||
(setq flymake-list-only-diagnostics
|
||||
(assoc-delete-all path flymake-list-only-diagnostics))
|
||||
(push (cons path diags) flymake-list-only-diagnostics)))))
|
||||
|
||||
(cl-defun eglot--register-unregister (server things how)
|
||||
"Helper for `registerCapability'.
|
||||
THINGS are either registrations or unregisterations (sic)."
|
||||
|
|
@ -3155,6 +3067,7 @@ When called interactively, use the currently active server"
|
|||
(setq eglot--recent-changes nil
|
||||
eglot--docver 0
|
||||
eglot--TextDocumentIdentifier-cache nil)
|
||||
(eglot--flymake-reset)
|
||||
(jsonrpc-notify
|
||||
(eglot--current-server-or-lose)
|
||||
:textDocument/didOpen `(:textDocument ,(eglot--TextDocumentItem))))
|
||||
|
|
@ -3192,6 +3105,80 @@ When called interactively, use the currently active server"
|
|||
:text (buffer-substring-no-properties (point-min) (point-max))
|
||||
:textDocument (eglot--TextDocumentIdentifier)))))
|
||||
|
||||
(defun eglot--find-buffer-visiting (server abspath)
|
||||
;; `find-buffer-visiting' would be natural, but calls the
|
||||
;; potentially slow `file-truename' (bug#70036).
|
||||
(cl-loop for b in (eglot--managed-buffers server)
|
||||
when (with-current-buffer b
|
||||
(equal (car eglot--TextDocumentIdentifier-cache)
|
||||
abspath))
|
||||
return b))
|
||||
|
||||
|
||||
;;; Flymake integration
|
||||
|
||||
(put 'eglot-note 'flymake-category 'flymake-note)
|
||||
(put 'eglot-warning 'flymake-category 'flymake-warning)
|
||||
(put 'eglot-error 'flymake-category 'flymake-error)
|
||||
|
||||
(defvar eglot-diagnostics-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [mouse-2] #'eglot-code-actions-at-mouse)
|
||||
(define-key map [left-margin mouse-1] #'eglot-code-actions-at-mouse)
|
||||
map)
|
||||
"Keymap active in Eglot-backed Flymake diagnostic overlays.")
|
||||
|
||||
(cl-loop for i from 1
|
||||
for type in '(eglot-note eglot-warning eglot-error)
|
||||
do (put type 'flymake-overlay-control
|
||||
`((mouse-face . highlight)
|
||||
(priority . ,(+ 50 i))
|
||||
(keymap . ,eglot-diagnostics-map))))
|
||||
|
||||
(defun eglot--flymake-sniff-diagnostics (beg &optional end)
|
||||
"Like `flymake-diagnostics', but for Eglot-specific diagnostics."
|
||||
(cl-loop for diag in (flymake-diagnostics beg end)
|
||||
for data = (flymake-diagnostic-data diag)
|
||||
for lsp-diag = (alist-get 'eglot-lsp-diag data)
|
||||
for version = (alist-get 'eglot--doc-version data)
|
||||
when (and lsp-diag (or (null version)
|
||||
(= version eglot--docver)))
|
||||
collect diag))
|
||||
|
||||
(cl-defmacro eglot--flymake-report-1 (diags mode &key (version 'eglot--docver) force)
|
||||
"Maybe convert, report and store the diagnostics objects DIAGS.
|
||||
DIAGS is either a vector of LSP diagnostics or a list of Flymake
|
||||
diagnostics. MODE can be `:stay' or `:clear' depending on whether we
|
||||
want to accumulate or reset diagnostics in the buffer. VERSION is the
|
||||
version the diagnostics pertain to."
|
||||
;; JT@2026-01-10: criteria for "incremental" reports could be
|
||||
;; tightened to e.g. check eglot--capf-session nillness, but we'd have
|
||||
;; to schedule an after-session re-report, and that's way too complex
|
||||
`(when (and (or ,force flymake-no-changes-timeout)
|
||||
eglot--flymake-report-fn)
|
||||
(when (and ,diags (vectorp ,diags))
|
||||
(setf ,diags
|
||||
(cl-loop
|
||||
for d across ,diags
|
||||
collect (eglot--flymake-make-diag
|
||||
d
|
||||
,version (eglot-range-region (plist-get d :range))))))
|
||||
(eglot--flymake-report-2 ,diags ,mode)))
|
||||
|
||||
(cl-defmethod eglot-handle-notification
|
||||
(server (_method (eql textDocument/publishDiagnostics))
|
||||
&key uri diagnostics version
|
||||
&allow-other-keys)
|
||||
"Handle notification publishDiagnostics."
|
||||
(eglot--flymake-handle-push
|
||||
server uri diagnostics version
|
||||
(lambda (diags)
|
||||
(setq eglot--pushed-diagnostics (list diags eglot--docver))
|
||||
(when (not (null flymake-no-changes-timeout ))
|
||||
;; only add to current report if Flymake
|
||||
;; starts on idle-timer (github#957)
|
||||
(eglot--flymake-report-push+pulled)))))
|
||||
|
||||
(defun eglot--flymake-diag-type (severity)
|
||||
"Convert LSP diagnostic SEVERITY to Eglot/Flymake diagnostic type."
|
||||
(cond ((null severity) 'eglot-error)
|
||||
|
|
@ -3199,13 +3186,14 @@ When called interactively, use the currently active server"
|
|||
((= severity 2) 'eglot-warning)
|
||||
(t 'eglot-note)))
|
||||
|
||||
(defun eglot--flymake-make-diag (diag-spec version)
|
||||
(defun eglot--flymake-make-diag (diag-spec version region)
|
||||
"Convert LSP diagnostic DIAG-SPEC to Flymake diagnostic.
|
||||
VERSION is the document version number."
|
||||
REGION is the (BEG . END) region the diagnostics pertina to. VERSION is
|
||||
the document version number."
|
||||
(eglot--dbind ((Diagnostic) range code message severity source tags)
|
||||
diag-spec
|
||||
(pcase-let
|
||||
((`(,beg . ,end) (eglot-range-region range)))
|
||||
((`(,beg . ,end) region))
|
||||
;; Fallback to `flymake-diag-region' if server botched the range
|
||||
(when (= beg end)
|
||||
(if-let* ((st (plist-get range :start))
|
||||
|
|
@ -3247,11 +3235,48 @@ may be called multiple times (respecting the protocol of
|
|||
((eglot-server-capable :diagnosticProvider)
|
||||
(eglot--flymake-pull))
|
||||
;; Otherwise push whatever we might have, and wait for
|
||||
;; `textDocument/publishDiagnostics'.
|
||||
(t (eglot--flymake-report))))
|
||||
;; further `textDocument/publishDiagnostics'.
|
||||
(t (eglot--flymake-report-push+pulled :force t))))
|
||||
(t
|
||||
(funcall report-fn nil))))
|
||||
|
||||
(cl-defun eglot--flymake-handle-push (server uri diagnostics version then)
|
||||
"Handle a diagnostics \"push\" from SERVER for document URI.
|
||||
DIAGNOSTICS is a list of LSP diagnostic objects. VERSION is the
|
||||
LSP-reported version comparable to `eglot--docver' for which these
|
||||
objects presumably pertain. If diagnostics are thought to belong to
|
||||
`eglot--docver' THEN is a unary function taking DIAGNOSTICS and tasked
|
||||
to eventually report the corresponding Flymake conversions of each
|
||||
object. The originator of this \"push\" is usually either regular
|
||||
`textDocument/publishDiagnostics' or an experimental
|
||||
`$/streamDiagnostics' notification."
|
||||
(if-let* ((path (expand-file-name (eglot-uri-to-path uri)))
|
||||
(buffer (eglot--find-buffer-visiting server path)))
|
||||
(with-current-buffer buffer
|
||||
(if (and version (/= version eglot--docver))
|
||||
(cl-return-from eglot--flymake-handle-push))
|
||||
(setq
|
||||
;; if no explicit version received, assume it's current.
|
||||
version eglot--docver
|
||||
flymake-list-only-diagnostics
|
||||
(assoc-delete-all path flymake-list-only-diagnostics))
|
||||
(funcall then diagnostics))
|
||||
(cl-loop
|
||||
for diag-spec across diagnostics
|
||||
collect (eglot--dbind ((Diagnostic) code range message severity source) diag-spec
|
||||
(let* ((start (plist-get range :start))
|
||||
(line (1+ (plist-get start :line)))
|
||||
(char (1+ (plist-get start :character))))
|
||||
(flymake-make-diagnostic
|
||||
path (cons line char) nil
|
||||
(eglot--flymake-diag-type severity)
|
||||
(list source code message))))
|
||||
into diags
|
||||
finally
|
||||
(setq flymake-list-only-diagnostics
|
||||
(assoc-delete-all path flymake-list-only-diagnostics))
|
||||
(push (cons path diags) flymake-list-only-diagnostics))))
|
||||
|
||||
(cl-defun eglot--flymake-pull (&aux (server (eglot--current-server-or-lose))
|
||||
(origin (current-buffer)))
|
||||
"Pull diagnostics from server, for all managed buffers.
|
||||
|
|
@ -3260,7 +3285,7 @@ When response arrives call registered `eglot--flymake-report-fn'."
|
|||
((pull-for (buf &optional then)
|
||||
(with-current-buffer buf
|
||||
(let ((version eglot--docver)
|
||||
(prev-result-id (cadr eglot--pulled-diagnostics)))
|
||||
(prev-result-id (caddr eglot--pulled-diagnostics)))
|
||||
(eglot--async-request
|
||||
server
|
||||
:textDocument/diagnostic
|
||||
|
|
@ -3274,14 +3299,11 @@ When response arrives call registered `eglot--flymake-report-fn'."
|
|||
(pcase kind
|
||||
("full"
|
||||
(setq eglot--pulled-diagnostics
|
||||
(list
|
||||
(cl-loop
|
||||
for spec across items
|
||||
collect (eglot--flymake-make-diag spec version))
|
||||
resultId))
|
||||
(eglot--flymake-report))
|
||||
(list items version resultId))
|
||||
(eglot--flymake-report-push+pulled :force t))
|
||||
("unchanged"
|
||||
(when (eq buf origin) (eglot--flymake-report 'void)))))
|
||||
(when (eq buf origin)
|
||||
(eglot--flymake-report-1 nil :stay :force t)))))
|
||||
(when then (funcall then)))
|
||||
:hint :textDocument/diagnostic)))))
|
||||
;; JT@2025-12-15: No known server yet supports "relatedDocuments" so
|
||||
|
|
@ -3294,38 +3316,47 @@ When response arrives call registered `eglot--flymake-report-fn'."
|
|||
(mapc #'pull-for
|
||||
(remove origin (eglot--managed-buffers server))))))))
|
||||
|
||||
(cl-defun eglot--flymake-report
|
||||
(&optional keep
|
||||
(defun eglot--flymake-reset ()
|
||||
(setq eglot--pulled-diagnostics nil
|
||||
eglot--pushed-diagnostics nil)
|
||||
(when eglot--flymake-report-fn
|
||||
(eglot--flymake-report-1 nil :clear :force t)))
|
||||
|
||||
(cl-defun eglot--flymake-report-2 (diags mode)
|
||||
"Really report the Flymake diagnostics objects DIAGS.
|
||||
MODE is like `eglot--flymake-report-1'."
|
||||
(apply eglot--flymake-report-fn
|
||||
diags
|
||||
(cond ((eq mode :clear)
|
||||
`(:region ,(cons (point-min) (point-max))))
|
||||
((eq mode :stay)
|
||||
`(:region ,(cons (point-min) (point-min)))))))
|
||||
|
||||
(cl-defun eglot--flymake-report-push+pulled
|
||||
(&key force
|
||||
&aux
|
||||
(pushed-docver (cadr eglot--pushed-diagnostics))
|
||||
(pushed-outdated-p (and pushed-docver (< pushed-docver eglot--docver))))
|
||||
"Push previously collected diagnostics to `eglot--flymake-report-fn'.
|
||||
If KEEP, knowingly push a dummy do-nothing update."
|
||||
(unless eglot--flymake-report-fn
|
||||
;; Occasionally called from contexts where report-fn not setup, such
|
||||
;; as a `didOpen''ed but yet undisplayed buffer.
|
||||
(cl-return-from eglot--flymake-report))
|
||||
(eglot--widening
|
||||
(if (or keep (and (null eglot--pulled-diagnostics) pushed-outdated-p))
|
||||
;; Here, we don't have anything interesting to give to
|
||||
;; Flymake. Either a textDocument/diagnostics response
|
||||
;; specifically told use that nothing changed, or
|
||||
;; `flymake-start' kicked in before server had a chance to
|
||||
;; push something. We just want to keep whatever diagnostics
|
||||
;; it has annotated in the buffer but as a nice-to-have, we
|
||||
;; want to signal we're alive and clear a possible "Wait"
|
||||
;; state. We hackingly achieve this by reporting an empty
|
||||
;; list and making sure it pertains to a 0-length region.
|
||||
(funcall eglot--flymake-report-fn nil
|
||||
:region (cons (point-min) (point-min)))
|
||||
;; Using :region keyword always forces Flymake to delete them
|
||||
;; (github#159).
|
||||
(funcall eglot--flymake-report-fn
|
||||
(append (car eglot--pulled-diagnostics)
|
||||
(unless pushed-outdated-p
|
||||
(car eglot--pushed-diagnostics)))
|
||||
:region (cons (point-min) (point-max))))))
|
||||
(if (and (null eglot--pulled-diagnostics) pushed-outdated-p)
|
||||
;; Here, we don't have anything interesting to give to Flymake.
|
||||
;; Either a textDocument/diagnostics response specifically told
|
||||
;; use that nothing changed, or `flymake-start' kicked in before
|
||||
;; server had a chance to push something. We just want to keep
|
||||
;; whatever diagnostics it has annotated in the buffer and and
|
||||
;; clear a possible "Wait" state.
|
||||
(eglot--flymake-report-2 nil :stay)
|
||||
(cl-macrolet ((report (x m)
|
||||
`(eglot--flymake-report-1
|
||||
(car ,x) ,m :force force)))
|
||||
(report eglot--pulled-diagnostics :clear)
|
||||
(unless pushed-outdated-p
|
||||
(report eglot--pushed-diagnostics :stay))))))
|
||||
|
||||
|
||||
;;; Xref integration
|
||||
(defun eglot-xref-backend () "Eglot xref backend." 'eglot)
|
||||
|
||||
(defvar eglot--temp-location-buffers (make-hash-table :test #'equal)
|
||||
|
|
@ -3523,6 +3554,8 @@ If BUFFER, switch to it before."
|
|||
:workspace/symbol
|
||||
`(:query ,pattern))))))
|
||||
|
||||
|
||||
;;; Eglot interactive commands and helpers
|
||||
(defun eglot-format-buffer ()
|
||||
"Format contents of current buffer."
|
||||
(interactive)
|
||||
|
|
@ -3565,12 +3598,15 @@ for which LSP on-type-formatting should be requested."
|
|||
nil
|
||||
on-type-format)))
|
||||
|
||||
|
||||
|
||||
;;; Completion
|
||||
(defvar eglot-cache-session-completions t
|
||||
"If non-nil Eglot caches data during completion sessions.")
|
||||
|
||||
(defvar eglot--capf-session :none "A cache used by `eglot-completion-at-point'.")
|
||||
|
||||
(defun eglot--capf-session-flush (&optional _) (setq eglot--capf-session :none))
|
||||
(defun eglot--capf-session-flush (&optional _) (setq eglot--capf-session nil))
|
||||
|
||||
(defun eglot--dumb-flex (pat comp ignorecase)
|
||||
"Return destructively fontified COMP iff PAT matches it."
|
||||
|
|
@ -3826,6 +3862,8 @@ for which LSP on-type-formatting should be requested."
|
|||
(eglot--apply-text-edits additionalTextEdits)))
|
||||
(eglot--signal-textDocument/didChange)))))))))
|
||||
|
||||
|
||||
;;; Eldoc integration
|
||||
(defun eglot--hover-info (contents &optional _range)
|
||||
(mapconcat #'eglot--format-markup
|
||||
(if (vectorp contents) contents (list contents)) "\n"))
|
||||
|
|
@ -3971,6 +4009,8 @@ for which LSP on-type-formatting should be requested."
|
|||
:hint :textDocument/documentHighlight)
|
||||
nil)))
|
||||
|
||||
|
||||
;;; Imenu integration
|
||||
(defun eglot--imenu-SymbolInformation (res)
|
||||
"Compute `imenu--index-alist' for RES vector of SymbolInformation."
|
||||
(mapcar
|
||||
|
|
@ -4032,6 +4072,8 @@ Returns a list as described in docstring of `imenu--index-alist'."
|
|||
(((SymbolInformation)) (eglot--imenu-SymbolInformation res))
|
||||
(((DocumentSymbol)) (eglot--imenu-DocumentSymbol res))))))
|
||||
|
||||
|
||||
;;; Code actions and rename
|
||||
(cl-defun eglot--apply-text-edits (edits &optional version silent)
|
||||
"Apply EDITS for current buffer if at VERSION, or if it's nil.
|
||||
If SILENT, don't echo progress in mode-line."
|
||||
|
|
@ -4187,7 +4229,7 @@ edit proposed by the server."
|
|||
"Calculate appropriate bounds depending on region and point."
|
||||
(let (diags boftap)
|
||||
(cond ((use-region-p) `(,(region-beginning) ,(region-end)))
|
||||
((setq diags (eglot--flymake-diagnostics (point)))
|
||||
((setq diags (eglot--flymake-sniff-diagnostics (point)))
|
||||
(cl-loop for d in diags
|
||||
minimizing (flymake-diagnostic-beg d) into beg
|
||||
maximizing (flymake-diagnostic-end d) into end
|
||||
|
|
@ -4203,8 +4245,9 @@ edit proposed by the server."
|
|||
:range (eglot-region-range beg end)
|
||||
:context
|
||||
`(:diagnostics
|
||||
[,@(mapcar #'eglot--diag-to-lsp-diag
|
||||
(eglot--flymake-diagnostics beg end))]
|
||||
[,@(mapcar (lambda (x)
|
||||
(alist-get 'eglot-lsp-diag (flymake-diagnostic-data x)))
|
||||
(eglot--flymake-sniff-diagnostics beg end))]
|
||||
,@(when only `(:only [,only]))
|
||||
,@(when triggerKind `(:triggerKind ,triggerKind)))))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue