unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#63372: [PATCH] Add variable: eglot-apply-text-edits-function
       [not found]               ` <83ild5fpj5.fsf@gnu.org>
@ 2023-05-08 14:28                 ` Felician Nemeth
  2023-05-08 14:54                   ` Felician Nemeth
  2023-05-08 16:33                   ` João Távora
  0 siblings, 2 replies; 6+ messages in thread
From: Felician Nemeth @ 2023-05-08 14:28 UTC (permalink / raw)
  To: 63372; +Cc: joaotavora, Eli Zaretskii

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

In https://lists.gnu.org/archive/html/emacs-devel/2023-05/msg00173.html
Eli Zaretskii <eliz@gnu.org> writes:

>> From: Felician Nemeth <felician.nemeth@gmail.com>
>> Cc: joaotavora@gmail.com,  emacs-devel@gnu.org
>> Date: Sat, 06 May 2023 17:17:14 +0200
>> 
>> 3. Eglot uses the eglot--apply-text-edits defun to apply server
>>    initiated edits.  There is an extension that allows the server to
>>    send the edits in a different format (snippet-text-edits).
>> 
>>    Eglot-x puts an advise on eglot--apply-text-edits to check the format
>>    of the edits and act accordingly.
>> 
>>    I don't know how to avoid this advice.
>
> Some hook or function variable, perhaps?  If they don't exist, perhaps
> they could be added?

I've attached a patch with my first attempt at this.  João, what do you
think of this approach?

(Independently of this issue, maybe a configurable
apply-workspace-edit-function would be useful as well.  One alternative
implementation of the current eglot--apply-workspace-edit could be to
apply all edits without asking for confirmation and then show a
`vc-diff'-like interface allowing the user to revert/accept all of the
changes with a single keystroke.)

Thank you.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-variable-eglot-apply-text-edits-function.patch --]
[-- Type: text/x-diff, Size: 1963 bytes --]

From 1a5c534a291a9ee247cb142a4816b75a9cff3ff1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felici=C3=A1n=20N=C3=A9meth?= <felician.nemeth@gmail.com>
Date: Mon, 8 May 2023 15:57:56 +0200
Subject: [PATCH] Add variable: eglot-apply-text-edits-function

This allows third parties to experiment with UI, or implement the
SnippetTextEdits LSP extension.

* lisp/progmodes/eglot.el (eglot-apply-text-edits-function): New
defvar defaulting to eglot--apply-lsp-text-edits.
(eglot--apply-text-edits): Delegate the editing task to
eglot-apply-text-edits-function.
(eglot--apply-lsp-text-edits): New defun containing most of the
old eglot--apply-text-edits.
---
 lisp/progmodes/eglot.el | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index 95a5b325fb..eb79a8d2d3 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -895,6 +895,11 @@ eglot--language-ids
 (cl-defmethod initialize-instance :before ((_server eglot-lsp-server) &optional args)
   (cl-remf args :initializationOptions))
 
+(defvar eglot-apply-text-edits-function #'eglot--apply-lsp-text-edits
+  "Function to call to apply text edits to the current buffer.
+The fuction must have a single argument holding the \"edits\"
+value of a TextDocumentEdit LSP object, i.e., a TextEdit or an
+AnnotatedTextEdit LSP object.")
 
 ;;; Process management
 (defvar eglot--servers-by-project (make-hash-table :test #'equal)
@@ -3349,6 +3354,10 @@ eglot--apply-text-edits
   (unless (or (not version) (equal version eglot--versioned-identifier))
     (jsonrpc-error "Edits on `%s' require version %d, you have %d"
                    (current-buffer) version eglot--versioned-identifier))
+  (funcall eglot-apply-text-edits-function edits))
+
+(cl-defun eglot--apply-lsp-text-edits (edits)
+  "Apply EDITS for current buffer."
   (atomic-change-group
     (let* ((change-group (prepare-change-group))
            (howmany (length edits))
-- 
2.30.2


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

* bug#63372: [PATCH] Add variable: eglot-apply-text-edits-function
  2023-05-08 14:28                 ` bug#63372: [PATCH] Add variable: eglot-apply-text-edits-function Felician Nemeth
@ 2023-05-08 14:54                   ` Felician Nemeth
  2023-05-08 16:33                   ` João Távora
  1 sibling, 0 replies; 6+ messages in thread
From: Felician Nemeth @ 2023-05-08 14:54 UTC (permalink / raw)
  To: 63372; +Cc: Eli Zaretskii, joaotavora

Felician Nemeth <felician.nemeth@gmail.com> writes:

> I've attached a patch with my first attempt at this.  João, what do you
> think of this approach?

I forgot to add that alternatively SnippetTextEdit support can be added
to Eglot as well.  The patch without the boring parts would look like
the following.

diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index eb79a8d2d3..0a4738b3b9 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -3350,14 +3350,13 @@ eglot-imenu
 
 (cl-defun eglot--apply-text-edits (edits &optional version)
   "Apply EDITS for current buffer if at VERSION, or if it's nil."
+  ;; This is quite rust-analyzer specific.  It assumes there is at
+  ;; most one meaningful SnippetTextEdit and that can be identified by
+  ;; searching for "$0".
   (unless edits (cl-return-from eglot--apply-text-edits))
   (unless (or (not version) (equal version eglot--versioned-identifier))
     (jsonrpc-error "Edits on `%s' require version %d, you have %d"
                    (current-buffer) version eglot--versioned-identifier))
   (atomic-change-group
     (let* ((change-group (prepare-change-group))
            (howmany (length edits))
@@ -3366,7 +3365,7 @@ eglot--apply-lsp-text-edits
                               howmany (current-buffer))
                       0 howmany))
-           (done 0))
-      (mapc (pcase-lambda (`(,newText ,beg . ,end))
+           (done 0)
+           snippet snippet-beg snippet-end)
+      (mapc (pcase-lambda (`(,newText ,insertTextFormat (,beg . ,end)))
               (let ((source (current-buffer)))
                 (with-temp-buffer
                   (insert newText)
@@ -3375,11 +3374,30 @@ eglot--apply-lsp-text-edits
                       (save-excursion
                         (save-restriction
                           (narrow-to-region beg end)
-                          (replace-buffer-contents temp)))
+                          (replace-buffer-contents temp))
+                                                  (when (and (eql insertTextFormat 2)
+                                     (string-match "\\$\\(0\\|{0[^}]*}\\)"
+                                                   newText))
+                            ;; "At the moment, rust-analyzer
+                            ;; guarantees that only a single edit will
+                            ;; have InsertTextFormat.Snippet.", but:
+                            ;; https://github.com/rust-analyzer/rust-analyzer/issues/11006
+                            ;; Every one of them has insertTextFormat
+                            ;; = 2, and there's no easy, reliable way
+                            ;; to tell, which one contains a real
+                            ;; snippet. RA's own .ts implementation
+                            ;; uses the regexp above.
+                            (setq snippet newText)
+                            (setq snippet-beg (point-min-marker))
+                            (setq snippet-end (point-max-marker))))
                       (eglot--reporter-update reporter (cl-incf done)))))))
-            (mapcar (eglot--lambda ((TextEdit) range newText)
-                      (cons newText (eglot--range-region range 'markers)))
+            (mapcar (eglot--lambda ((SnippetTextEdit) range newText insertTextFormat)
+                      (list newText insertTextFormat (eglot--range-region range 'markers)))
                     (reverse edits)))
+      (when snippet
+        (goto-char snippet-beg)
+        (delete-region snippet-beg snippet-end)
+        (funcall (eglot--snippet-expansion-fn) snippet))
       (undo-amalgamate-change-group change-group)
       (progress-reporter-done reporter))))





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

* bug#63372: [PATCH] Add variable: eglot-apply-text-edits-function
  2023-05-08 14:28                 ` bug#63372: [PATCH] Add variable: eglot-apply-text-edits-function Felician Nemeth
  2023-05-08 14:54                   ` Felician Nemeth
@ 2023-05-08 16:33                   ` João Távora
  2023-05-10 19:35                     ` Felician Nemeth
  1 sibling, 1 reply; 6+ messages in thread
From: João Távora @ 2023-05-08 16:33 UTC (permalink / raw)
  To: Felician Nemeth; +Cc: 63372, Eli Zaretskii

On Mon, May 8, 2023 at 3:30 PM Felician Nemeth
<felician.nemeth@gmail.com> wrote:
>
> In https://lists.gnu.org/archive/html/emacs-devel/2023-05/msg00173.html
> Eli Zaretskii <eliz@gnu.org> writes:
>
> >> From: Felician Nemeth <felician.nemeth@gmail.com>
> >> Cc: joaotavora@gmail.com,  emacs-devel@gnu.org
> >> Date: Sat, 06 May 2023 17:17:14 +0200
> >>
> >> 3. Eglot uses the eglot--apply-text-edits defun to apply server
> >>    initiated edits.  There is an extension that allows the server to
> >>    send the edits in a different format (snippet-text-edits).
> >>
> >>    Eglot-x puts an advise on eglot--apply-text-edits to check the format
> >>    of the edits and act accordingly.
> >>
> >>    I don't know how to avoid this advice.
> >
> > Some hook or function variable, perhaps?  If they don't exist, perhaps
> > they could be added?
>
> I've attached a patch with my first attempt at this.  João, what do you
> think of this approach?

It could work.  But I think   Some comments

? +(defvar eglot-apply-text-edits-function #'eglot--apply-lsp-text-edits

eglot--apply-lsp-text-edits should in theory be external, because it
is something pluggable on and off.

IME these things also tend lend themselves to "multiple handlers"
in the future, so maybe a generalized "special" hook (ending in
"functions", plural) is better.  Then some `run-hook-wrapped`
would iterate through it.

But then, I wonder, since most of Eglot's API is already CLOS
based, isn't a generic function best?  A generic function can
have :around methods, and if we follow the convention of
passing the server as the first argument, third parties
can make server-specific extensions.

Also, in some CLOS versions (not eieio.el's yet) there
are even method combinations that simulate hooks.

> +(cl-defun eglot--apply-lsp-text-edits (edits)
> +  "Apply EDITS for current buffer."
>    (atomic-change-group
>     (let* ((change-group (prepare-change-group))

Won't every "apply edit" function need this as boilerplate to
guarantee undo-stability?  Likely this should be popped to
around the call to the generic function.

> (Independently of this issue, maybe a configurable
> apply-workspace-edit-function would be useful as well.  One alternative
> implementation of the current eglot--apply-workspace-edit could be to
> apply all edits without asking for confirmation and then show a
> `vc-diff'-like interface allowing the user to revert/accept all of the
> changes with a single keystroke.)

If this is truly independent, request it in a different bug report
(or a different thread within this bug) with a different patch.
If it is not  independent, let's focus on the infrastructure functionality
first.

João





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

* bug#63372: [PATCH] Add variable: eglot-apply-text-edits-function
  2023-05-08 16:33                   ` João Távora
@ 2023-05-10 19:35                     ` Felician Nemeth
  2023-05-11 19:54                       ` João Távora
  0 siblings, 1 reply; 6+ messages in thread
From: Felician Nemeth @ 2023-05-10 19:35 UTC (permalink / raw)
  To: João Távora; +Cc: 63372, Eli Zaretskii

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

João Távora <joaotavora@gmail.com> writes:

>> >> 3. Eglot uses the eglot--apply-text-edits defun to apply server
>> >>    initiated edits.  There is an extension that allows the server to
>> >>    send the edits in a different format (snippet-text-edits).
>> >>
>> >>    Eglot-x puts an advise on eglot--apply-text-edits to check the format
>> >>    of the edits and act accordingly.
>> >>
>> >>    I don't know how to avoid this advice.
>> >
>> > Some hook or function variable, perhaps?  If they don't exist, perhaps
>> > they could be added?

> But then, I wonder, since most of Eglot's API is already CLOS
> based, isn't a generic function best?  A generic function can
> have :around methods, and if we follow the convention of
> passing the server as the first argument, third parties
> can make server-specific extensions.

You're right, I think.  In the attached patch, I simply changed
eglot--apply-text-edits to a cl-defgeneric and renamed it.  The patch is
straightforward, but I had to eliminate a cl-return-from call, because
generic functions don't seem to support that.

Thanks.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Eglot-Replace-eglot-apply-text-edits-with-a-public-f.patch --]
[-- Type: text/x-diff, Size: 7186 bytes --]

From 4c5e62c901ada66a1ad59e4484cd0be17af64aa4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felici=C3=A1n=20N=C3=A9meth?= <felician.nemeth@gmail.com>
Date: Wed, 10 May 2023 20:58:33 +0200
Subject: [PATCH] Eglot: Replace eglot--apply-text-edits with a public function

This allows third parties, for example, to cleanly implement the
non-standard snippet-text-edit feature.

* lisp/progmodes/eglot.el (eglot--apply-text-edits): Rename to ...
(eglot-apply-text-edits): ... this, also change to cl-defgeneric,
and relocate the code next to the other defgenerics.
(eglot--signal-textDocument/willSave, eglot-format)
(eglot-completion-at-point, eglot--apply-workspace-edit): Call
renamed function.
---
 lisp/progmodes/eglot.el | 81 +++++++++++++++++++++--------------------
 1 file changed, 42 insertions(+), 39 deletions(-)

diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index 32626634b7..1c26acfe1f 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -859,6 +859,37 @@ eglot-workspace-folders
                      :name (abbreviate-file-name dir)))
              `(,(project-root project) ,@(project-external-roots project))))))
 
+(cl-defgeneric eglot-apply-text-edits (_server edits &optional version)
+  "Apply EDITS for current buffer if at VERSION, or if it's nil."
+  (when edits
+    (unless (or (not version) (equal version eglot--versioned-identifier))
+      (jsonrpc-error "Edits on `%s' require version %d, you have %d"
+                     (current-buffer) version eglot--versioned-identifier))
+    (atomic-change-group
+      (let* ((change-group (prepare-change-group))
+             (howmany (length edits))
+             (reporter (make-progress-reporter
+                        (format "[eglot] applying %s edits to `%s'..."
+                                howmany (current-buffer))
+                        0 howmany))
+             (done 0))
+        (mapc (pcase-lambda (`(,newText ,beg . ,end))
+                (let ((source (current-buffer)))
+                  (with-temp-buffer
+                    (insert newText)
+                    (let ((temp (current-buffer)))
+                      (with-current-buffer source
+                        (save-excursion
+                          (save-restriction
+                            (narrow-to-region beg end)
+                            (replace-buffer-contents temp)))
+                        (eglot--reporter-update reporter (cl-incf done)))))))
+              (mapcar (eglot--lambda ((TextEdit) range newText)
+                        (cons newText (eglot--range-region range 'markers)))
+                      (reverse edits)))
+        (undo-amalgamate-change-group change-group)
+        (progress-reporter-done reporter)))))
+
 (defclass eglot-lsp-server (jsonrpc-process-connection)
   ((project-nickname
     :documentation "Short nickname for the associated project."
@@ -2680,9 +2711,9 @@ eglot--signal-textDocument/willSave
       (jsonrpc-notify server :textDocument/willSave params))
     (when (eglot--server-capable :textDocumentSync :willSaveWaitUntil)
       (ignore-errors
-        (eglot--apply-text-edits
-         (eglot--request server :textDocument/willSaveWaitUntil params
-                         :timeout 0.5))))))
+        (eglot-apply-text-edits
+         server (eglot--request server :textDocument/willSaveWaitUntil params
+                                :timeout 0.5))))))
 
 (defun eglot--signal-textDocument/didSave ()
   "Maybe send textDocument/didSave to server."
@@ -2945,11 +2976,13 @@ eglot-format
                    (:range ,(list :start (eglot--pos-to-lsp-position beg)
                                   :end (eglot--pos-to-lsp-position end)))))
                 (t
-                 '(:textDocument/formatting :documentFormattingProvider nil)))))
+                 '(:textDocument/formatting :documentFormattingProvider nil))))
+              (server (eglot--current-server-or-lose)))
     (eglot--server-capable-or-lose cap)
-    (eglot--apply-text-edits
+    (eglot-apply-text-edits
+     server
      (eglot--request
-      (eglot--current-server-or-lose)
+      server
       method
       (cl-list*
        :textDocument (eglot--TextDocumentIdentifier)
@@ -3172,7 +3205,7 @@ eglot-completion-at-point
                         (delete-region (- (point) (length proxy)) (point))
                         (funcall snippet-fn (or insertText label))))
                  (when (cl-plusp (length additionalTextEdits))
-                   (eglot--apply-text-edits additionalTextEdits)))
+                   (eglot-apply-text-edits server additionalTextEdits)))
                (eglot--signal-textDocument/didChange)))))))))
 
 (defun eglot--hover-info (contents &optional _range)
@@ -3351,37 +3384,6 @@ eglot-imenu
         (((SymbolInformation)) (eglot--imenu-SymbolInformation res))
         (((DocumentSymbol)) (eglot--imenu-DocumentSymbol res))))))
 
-(cl-defun eglot--apply-text-edits (edits &optional version)
-  "Apply EDITS for current buffer if at VERSION, or if it's nil."
-  (unless edits (cl-return-from eglot--apply-text-edits))
-  (unless (or (not version) (equal version eglot--versioned-identifier))
-    (jsonrpc-error "Edits on `%s' require version %d, you have %d"
-                   (current-buffer) version eglot--versioned-identifier))
-  (atomic-change-group
-    (let* ((change-group (prepare-change-group))
-           (howmany (length edits))
-           (reporter (make-progress-reporter
-                      (format "[eglot] applying %s edits to `%s'..."
-                              howmany (current-buffer))
-                      0 howmany))
-           (done 0))
-      (mapc (pcase-lambda (`(,newText ,beg . ,end))
-              (let ((source (current-buffer)))
-                (with-temp-buffer
-                  (insert newText)
-                  (let ((temp (current-buffer)))
-                    (with-current-buffer source
-                      (save-excursion
-                        (save-restriction
-                          (narrow-to-region beg end)
-                          (replace-buffer-contents temp)))
-                      (eglot--reporter-update reporter (cl-incf done)))))))
-            (mapcar (eglot--lambda ((TextEdit) range newText)
-                      (cons newText (eglot--range-region range 'markers)))
-                    (reverse edits)))
-      (undo-amalgamate-change-group change-group)
-      (progress-reporter-done reporter))))
-
 (defun eglot--apply-workspace-edit (wedit &optional confirm)
   "Apply the workspace edit WEDIT.  If CONFIRM, ask user first."
   (eglot--dbind ((WorkspaceEdit) changes documentChanges) wedit
@@ -3407,7 +3409,8 @@ eglot--apply-workspace-edit
       (cl-loop for edit in prepared
                for (path edits version) = edit
                do (with-current-buffer (find-file-noselect path)
-                    (eglot--apply-text-edits edits version))
+                    (eglot-apply-text-edits (eglot--current-server-or-lose)
+                                            edits version))
                finally (eldoc) (eglot--message "Edit successful!")))))
 
 (defun eglot-rename (newname)
-- 
2.30.2


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

* bug#63372: [PATCH] Add variable: eglot-apply-text-edits-function
  2023-05-10 19:35                     ` Felician Nemeth
@ 2023-05-11 19:54                       ` João Távora
  2023-05-15 20:03                         ` Felician Nemeth
  0 siblings, 1 reply; 6+ messages in thread
From: João Távora @ 2023-05-11 19:54 UTC (permalink / raw)
  To: Felician Nemeth; +Cc: 63372, Eli Zaretskii

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

After having another look at eglot-x.el i don't
think eglot--apply-text-edits (plural) is the right
place to put the generic.  You'd just repeat a lot
of code of the original, with no clear way to reuse it.

Maybe you want something more akin to the attached patch,
which introduces eglot-apply-text-edit (singular).  In your
override for this function you can check conditions to either
proceed with the non-standard edit or delegate to the default
implementation with (cl-call-next-method).

João

[-- Attachment #2: 0001-Eglot-allow-extensions-to-application-of-LSP-edits-b.patch --]
[-- Type: application/octet-stream, Size: 3543 bytes --]

From d51a12156b6278a1ff1f4dbf0d8991d79749ae00 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20T=C3=A1vora?= <joaotavora@gmail.com>
Date: Thu, 11 May 2023 20:50:20 +0100
Subject: [PATCH] Eglot: allow extensions to application of LSP edits
 (bug#63372)

* lisp/progmodes/eglot.el (eglot-apply-text-edit): New function.
(eglot--apply-text-edits): Rework.
---
 lisp/progmodes/eglot.el | 47 ++++++++++++++++++++++-------------------
 1 file changed, 25 insertions(+), 22 deletions(-)

diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index dc8d4674425..c045f71fe9b 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -843,6 +843,20 @@ eglot-workspace-folders
                      :name (abbreviate-file-name dir)))
              `(,(project-root project) ,@(project-external-roots project))))))
 
+(cl-defgeneric eglot-apply-text-edit (_server edit)
+  "Apply EDIT supplied by SERVER in current buffer."
+  (eglot--dbind ((TextEdit) range newText) edit
+    (cl-destructuring-bind (beg . end) (eglot--range-region range 'markers)
+      (let ((source (current-buffer)))
+        (with-temp-buffer
+          (insert newText)
+          (let ((temp (current-buffer)))
+            (with-current-buffer source
+              (save-excursion
+                (save-restriction
+                  (narrow-to-region beg end)
+                  (replace-buffer-contents temp))))))))))
+
 (defclass eglot-lsp-server (jsonrpc-process-connection)
   ((project-nickname
     :documentation "Short nickname for the associated project."
@@ -3327,29 +3341,18 @@ eglot--apply-text-edits
     (jsonrpc-error "Edits on `%s' require version %d, you have %d"
                    (current-buffer) version eglot--versioned-identifier))
   (atomic-change-group
-    (let* ((change-group (prepare-change-group))
-           (howmany (length edits))
-           (reporter (make-progress-reporter
+    (cl-loop
+     with change-group = (prepare-change-group)
+     with reporter = (make-progress-reporter
                       (format "[eglot] applying %s edits to `%s'..."
-                              howmany (current-buffer))
-                      0 howmany))
-           (done 0))
-      (mapc (pcase-lambda (`(,newText ,beg . ,end))
-              (let ((source (current-buffer)))
-                (with-temp-buffer
-                  (insert newText)
-                  (let ((temp (current-buffer)))
-                    (with-current-buffer source
-                      (save-excursion
-                        (save-restriction
-                          (narrow-to-region beg end)
-                          (replace-buffer-contents temp)))
-                      (eglot--reporter-update reporter (cl-incf done)))))))
-            (mapcar (eglot--lambda ((TextEdit) range newText)
-                      (cons newText (eglot--range-region range 'markers)))
-                    (reverse edits)))
-      (undo-amalgamate-change-group change-group)
-      (progress-reporter-done reporter))))
+                              (length edits) (current-buffer))
+                      0 (length edits))
+     for e across (reverse edits) for done from 1
+     do (eglot-apply-text-edit (eglot--current-server-or-lose) e)
+     (eglot--reporter-update reporter done)
+     finally
+     (undo-amalgamate-change-group change-group)
+     (progress-reporter-done reporter))))
 
 (defun eglot--apply-workspace-edit (wedit &optional confirm)
   "Apply the workspace edit WEDIT.  If CONFIRM, ask user first."
-- 
2.36.1.windows.1


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

* bug#63372: [PATCH] Add variable: eglot-apply-text-edits-function
  2023-05-11 19:54                       ` João Távora
@ 2023-05-15 20:03                         ` Felician Nemeth
  0 siblings, 0 replies; 6+ messages in thread
From: Felician Nemeth @ 2023-05-15 20:03 UTC (permalink / raw)
  To: João Távora; +Cc: 63372, Eli Zaretskii

João Távora <joaotavora@gmail.com> writes:

> After having another look at eglot-x.el i don't
> think eglot--apply-text-edits (plural) is the right
> place to put the generic.  You'd just repeat a lot
> of code of the original, with no clear way to reuse it.
>
> Maybe you want something more akin to the attached patch,
> which introduces eglot-apply-text-edit (singular).  In your
> override for this function you can check conditions to either
> proceed with the non-standard edit or delegate to the default
> implementation with (cl-call-next-method).

Unfortunately, I think this won't help me cleanly implement the
snippet-text-edits feature.  The server can send many text-edits and at
most one of them can be a snippet-text-edit, which currently means that
it contains a "$0" to tell the client where to put the point after
applying the edits.

My implementation applied all the edits and save the snippet (if there
was any) for later use.  Then it called eglot--snippet-expansion-fn on
the saved snippet.  This way the user saw results of all the edits
before the snippet expansion.

If the latest patch is merged, then I can I override the singular
eglot-apply-text-edit, but I think I have no way to run a custom code
after all the edits are applied.

Thanks,
Felicián





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

end of thread, other threads:[~2023-05-15 20:03 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <874jorc7q2.fsf@betli.tmit.bme.hu>
     [not found] ` <83h6sqj4ed.fsf@gnu.org>
     [not found]   ` <87354auafu.fsf@gmail.com>
     [not found]     ` <835y96j10l.fsf@gnu.org>
     [not found]       ` <87y1m2spbd.fsf@gmail.com>
     [not found]         ` <87pm7dbo41.fsf@betli.tmit.bme.hu>
     [not found]           ` <83r0rtfv3m.fsf@gnu.org>
     [not found]             ` <87h6spbibp.fsf@betli.tmit.bme.hu>
     [not found]               ` <83ild5fpj5.fsf@gnu.org>
2023-05-08 14:28                 ` bug#63372: [PATCH] Add variable: eglot-apply-text-edits-function Felician Nemeth
2023-05-08 14:54                   ` Felician Nemeth
2023-05-08 16:33                   ` João Távora
2023-05-10 19:35                     ` Felician Nemeth
2023-05-11 19:54                       ` João Távora
2023-05-15 20:03                         ` Felician Nemeth

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).