unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#59149: Feature Request: Report progress of long requests in Eglot
@ 2022-11-09 14:13 Danny Freeman via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2022-11-10 15:50 ` João Távora
  2022-11-19  9:42 ` Stephen Leake
  0 siblings, 2 replies; 26+ messages in thread
From: Danny Freeman via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-11-09 14:13 UTC (permalink / raw)
  To: 59149; +Cc: João Távora

[-- Attachment #1: Type: text/plain, Size: 733 bytes --]

Something I think would be nice to have in eglot is some kind of
progress indicator for long running requests. Attached is my attempt at
implementing these. The patch contains links to relevant LSP specs in
the commit message.

Here is a link to an old github discussion about progress notifications:
https://github.com/joaotavora/eglot/discussions/835 

It uses the built in progress-reporter to display progress in the
echo area. Something that may be missing is a way for the user to
enable/disable this. Not sure what the right facilities are for that.
The eglot-stay-out-of pattern maybe? I didn't include that because I'm
not sure what to "stay out of". Maybe the symbol `progress-reporter'?
Happy to add something like that.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: progress notification patch --]
[-- Type: text/x-patch, Size: 4085 bytes --]

From b53753f611045bb44ef4d1d30d6f426be889f277 Mon Sep 17 00:00:00 2001
From: dannyfreeman <danny@dfreeman.email>
Date: Wed, 9 Nov 2022 08:46:45 -0500
Subject: [PATCH] Eglot: Display progress notifications in minibuffer as they
 arrive

The LSP spec describes methods for reporting progress on long running
jobs to the client:

https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#progress
https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workDoneProgress

This change reports those notifications in the minibuffer as they come
in. It shows a percent indicator (if the server provides theme), or a
spinner. This change should open the door for writing a "cancel long
running request" command, which are identified by these progress
notifications. See
https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#window_workDoneProgress_cancel
---
 lisp/progmodes/eglot.el | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index ecfede8fa6..b85d9fd445 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -820,6 +820,9 @@ eglot-lsp-server
    (spinner
     :documentation "List (ID DOING-WHAT DONE-P) representing server progress."
     :initform `(nil nil t) :accessor eglot--spinner)
+   (progress-reporter-alist
+    :documentation "Alist of (PROGRESS-TOKEN . PROGRESS-REPORTER)."
+    :accessor eglot--progress-reporter-alist)
    (inhibit-autoreconnect
     :initform t
     :documentation "Generalized boolean inhibiting auto-reconnection if true."
@@ -2035,6 +2038,42 @@ eglot-handle-notification
   (_server (_method (eql telemetry/event)) &rest _any)
   "Handle notification telemetry/event.") ;; noop, use events buffer
 
+(defun eglot--progress-report-message (title message)
+  "Format a $/progress report message, given a TITLE and/or MESSAGE string."
+  (cond
+   ((and title message) (format "%s %s" title message))
+   (title title)
+   (message message)))
+
+(defun eglot--progress-reporter (server token)
+  "Get a prgress-reporter identified by the progress TOKEN from the SERVER ."
+  (cdr (assoc token (eglot--progress-reporter-alist server))))
+
+(defun eglot--progress-reporter-delete (server token)
+  "Delete progress-reporters identified by the progress TOKEN from the SERVER."
+  (setf (eglot--progress-reporter-alist server)
+        (assoc-delete-all token (eglot--progress-reporter-alist server))))
+
+(cl-defmethod eglot-handle-notification
+  (server (_method (eql $/progress)) &key token value)
+  "Handle a $/progress notification identified by TOKEN from the SERVER."
+  (cl-destructuring-bind (&key kind title percentage message) value
+    (pcase kind
+      ("begin" (let* ((prefix (format (concat "[eglot] %s %s:" (when percentage " "))
+                                      (eglot-project-nickname server) token))
+                      (pr (if percentage
+                              (make-progress-reporter prefix 0 100 percentage 1 0)
+                            (make-progress-reporter prefix nil nil nil 1 0))))
+                 (eglot--progress-reporter-delete server token)
+                 (setf (eglot--progress-reporter-alist server)
+                       (cons (cons token pr) (eglot--progress-reporter-alist server)))
+                 (progress-reporter-update pr percentage (eglot--progress-report-message title message))))
+      ("report" (when-let ((pr (eglot--progress-reporter server token)))
+                  (progress-reporter-update pr percentage (eglot--progress-report-message title message))))
+      ("end" (when-let ((pr (eglot--progress-reporter server token)))
+               (progress-reporter-done pr)
+               (eglot--progress-reporter-delete server token))))))
+
 (cl-defmethod eglot-handle-notification
   (_server (_method (eql textDocument/publishDiagnostics)) &key uri diagnostics
            &allow-other-keys) ; FIXME: doesn't respect `eglot-strict-mode'
-- 
2.38.1


[-- Attachment #3: Type: text/plain, Size: 30 bytes --]


Thank you,
-- 
Danny Freeman

^ permalink raw reply related	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2022-12-09 13:38 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-09 14:13 bug#59149: Feature Request: Report progress of long requests in Eglot Danny Freeman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-10 15:50 ` João Távora
2022-11-11 13:07   ` Danny Freeman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-19  9:42 ` Stephen Leake
2022-11-19 18:03   ` Danny Freeman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-21 18:04     ` Stephen Leake
2022-11-23 14:12       ` Danny Freeman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-23 18:01         ` Stephen Leake
2022-11-23 19:36           ` Danny Freeman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-23 19:56             ` João Távora
2022-11-24 11:06               ` bug#59149: [SPAM UNSURE] " Stephen Leake
2022-11-24 14:16                 ` João Távora
2022-11-24 21:25                   ` Stephen Leake
2022-11-25 16:11                     ` João Távora
2022-11-25 16:15                     ` Danny Freeman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-25 16:31                       ` Eli Zaretskii
2022-11-25 16:41                         ` Danny Freeman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-25 16:44                           ` Danny Freeman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-26  1:03                           ` João Távora
2022-11-26 18:37                             ` Danny Freeman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-26 19:46                             ` Stefan Kangas
2022-12-01 13:29                               ` Danny Freeman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-12-03 13:23                                 ` João Távora
2022-12-09 13:06                                   ` João Távora
2022-12-09 13:38                                     ` Danny Freeman via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-22 18:45     ` Stephen Leake

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).