unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Danny Freeman via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 59149@debbugs.gnu.org, stephen_leake@stephe-leake.org,
	joaotavora@gmail.com
Subject: bug#59149: [SPAM UNSURE] Re: bug#59149: Feature Request: Report progress of long requests in Eglot
Date: Fri, 25 Nov 2022 11:41:46 -0500	[thread overview]
Message-ID: <87ilj3x9we.fsf@dfreeman.email> (raw)
In-Reply-To: <834junuhae.fsf@gnu.org>

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


Eli Zaretskii <eliz@gnu.org> writes:

>> Cc: 59149@debbugs.gnu.org, joaotavora@gmail.com
>> Date: Fri, 25 Nov 2022 11:15:33 -0500
>> From:  Danny Freeman via "Bug reports for GNU Emacs,
>>  the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
>> 
>> +(defcustom eglot-report-progress t
>> +  "If non-nil, show progress of long running server work in the minibuffer."
>> +  :type 'boolean)
>
> Please add a :version tag.
>
> Thanks.

My bad, attached is a revised patch.

-- 
Danny Freeman


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Eglot progress report, now with version number! --]
[-- Type: text/x-patch, Size: 5596 bytes --]

From 95a7ca04d1c3b573cbc1cba3378f50450f090ab4 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

* lisp/progmodes/eglot.el (eglot-report-progress): New custom variable.
(eglot-lsp-server): New slot for tracking active progress reporters.
(eglot-handle-notification): New impl for $/progress server responses.
(eglot--format-markup): replace tab with spaces.
(eglot--TextDocumentItem): replace tab with spaces.

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 | 49 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 47 insertions(+), 2 deletions(-)

diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index a0fb253e10..1c991e5c35 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -386,6 +386,11 @@ eglot-menu-string
   "String displayed in mode line when Eglot is active."
   :type 'string)
 
+(defcustom eglot-report-progress t
+  "If non-nil, show progress of long running server work in the minibuffer."
+  :type 'boolean
+  :version "29.1")
+
 (defvar eglot-withhold-process-id nil
   "If non-nil, Eglot will not send the Emacs process id to the language server.
 This can be useful when using docker to run a language server.")
@@ -831,6 +836,9 @@ eglot-lsp-server
    (project
     :documentation "Project associated with server."
     :accessor eglot--project)
+   (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."
@@ -1569,7 +1577,7 @@ eglot--format-markup
       (setq-local markdown-fontify-code-blocks-natively t)
       (insert string)
       (let ((inhibit-message t)
-	    (message-log-max nil))
+            (message-log-max nil))
         (ignore-errors (delay-mode-hooks (funcall mode))))
       (font-lock-ensure)
       (string-trim (buffer-string)))))
@@ -2049,6 +2057,43 @@ 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."
+  (when eglot-report-progress
+    (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'
@@ -2172,7 +2217,7 @@ eglot--TextDocumentItem
   (append
    (eglot--VersionedTextDocumentIdentifier)
    (list :languageId
-	 (eglot--language-id (eglot--current-server-or-lose))
+         (eglot--language-id (eglot--current-server-or-lose))
          :text
          (eglot--widening
           (buffer-substring-no-properties (point-min) (point-max))))))
-- 
2.38.1


  reply	other threads:[~2022-11-25 16:41 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87ilj3x9we.fsf@dfreeman.email \
    --to=bug-gnu-emacs@gnu.org \
    --cc=59149@debbugs.gnu.org \
    --cc=danny@dfreeman.email \
    --cc=eliz@gnu.org \
    --cc=joaotavora@gmail.com \
    --cc=stephen_leake@stephe-leake.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).