all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#60338: [PATCH] Add option to present server changes as diffs
@ 2022-12-26 13:42 Philip Kaludercic
  2022-12-29  0:01 ` Yuan Fu
  2023-06-11 21:33 ` Philip Kaludercic
  0 siblings, 2 replies; 33+ messages in thread
From: Philip Kaludercic @ 2022-12-26 13:42 UTC (permalink / raw)
  To: 60338

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

X-CC-Debbugs: João Távora <joaotavora@gmail.com>

I'd like to propose adding an option that makes server modifications by
Eglot less invasive.  The current behaviour is to make the changes
directly in a buffer and open the remaining files to make the
modifications in those as well (?).  If `eglot-use-diffs' is enabled,
all confirmations are prepared as patches in a pop-up buffer that the
user can review and apply at will.  To my knowledge there is no general
`diff-apply-hunk' that will apply all the changes from a buffer, but
that is a separate issue that can be fixed in a separate patch.

(Note, I'm still testing emacs-29, so the patch was developed on that
branch.  But it should be applied to master)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: [PATCH] Add option to present server changes as diffs --]
[-- Type: text/x-patch, Size: 4834 bytes --]

From 88ba620b47b7987d203fc5b42716fa08be3b1d8f Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Mon, 26 Dec 2022 11:06:09 +0100
Subject: [PATCH] Add option to present server changes as diffs

* lisp/progmodes/eglot.el (eglot-use-diffs): Add new user option.
(eglot--apply-workspace-edit): Respect 'eglot-use-diffs'.
* doc/misc/eglot.texi (Customizing Eglot): Document 'eglot-use-diffs'.
---
 doc/misc/eglot.texi     |  7 ++++++
 lisp/progmodes/eglot.el | 54 ++++++++++++++++++++++++++++++++---------
 2 files changed, 49 insertions(+), 12 deletions(-)

diff --git a/doc/misc/eglot.texi b/doc/misc/eglot.texi
index 2aff038b9a..9150e1a879 100644
--- a/doc/misc/eglot.texi
+++ b/doc/misc/eglot.texi
@@ -955,6 +955,13 @@ Customizing Eglot
 to use Eglot in your @code{eglot-managed-mode-hook} or via some other
 mechanism.
 
+@vindex eglot-use-diffs
+@item eglot-use-diffs
+If this option is enabled, any server modifications (renames, code
+actions, refactoring, @dots{}) will be presented as diffs that the
+user can selectively apply.  The default is that all modifications are
+made in place.
+
 @vindex eglot-report-progress
 @cindex progress
 @item eglot-report-progress
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index 15cb1b6fad..74472b25ce 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -111,6 +111,8 @@
 (require 'ert)
 (require 'array)
 (require 'external-completion)
+(require 'diff-mode)
+(require 'diff)
 
 ;; ElDoc is preloaded in Emacs, so `require'-ing won't guarantee we are
 ;; using the latest version from GNU Elpa when we load eglot.el.  Use an
@@ -3160,6 +3162,11 @@ eglot--apply-text-edits
       (undo-amalgamate-change-group change-group)
       (progress-reporter-done reporter))))
 
+(defcustom eglot-use-diffs nil
+  "Non-nil means that server changes are presented as diffs."
+  :type 'boolean
+  :version "30.1")
+
 (defun eglot--apply-workspace-edit (wedit &optional confirm)
   "Apply the workspace edit WEDIT.  If CONFIRM, ask user first."
   (eglot--dbind ((WorkspaceEdit) changes documentChanges) wedit
@@ -3175,18 +3182,41 @@ eglot--apply-workspace-edit
         ;; prefer documentChanges over changes.
         (cl-loop for (uri edits) on changes by #'cddr
                  do (push (list (eglot--uri-to-path uri) edits) prepared)))
-      (if (or confirm
-              (cl-notevery #'find-buffer-visiting
-                           (mapcar #'car prepared)))
-          (unless (y-or-n-p
-                   (format "[eglot] Server wants to edit:\n  %s\n Proceed? "
-                           (mapconcat #'identity (mapcar #'car prepared) "\n  ")))
-            (jsonrpc-error "User canceled server 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))
-               finally (eldoc) (eglot--message "Edit successful!")))))
+      (if eglot-use-diffs
+          (with-current-buffer (get-buffer-create " *Server Changes*")
+            (buffer-disable-undo (current-buffer))
+            (let ((buffer-read-only t))
+              (diff-mode))
+            (let ((inhibit-read-only t)
+                  (target (current-buffer)))
+              (erase-buffer)
+              (pcase-dolist (`(,path ,edits ,_) prepared)
+                (with-temp-buffer
+                  (let ((diff (current-buffer)))
+                    (with-temp-buffer
+                      (insert-file-contents path)
+                      (eglot--apply-text-edits edits)
+                      (diff-no-select path (current-buffer)
+                                      nil t diff))
+                    (with-current-buffer target
+                      (insert-buffer-substring diff))))))
+            (setq-local buffer-read-only t)
+            (buffer-enable-undo (current-buffer))
+            (goto-char (point-min))
+            (pop-to-buffer (current-buffer))
+            (font-lock-ensure))
+        (if (or confirm
+                (cl-notevery #'find-buffer-visiting
+                             (mapcar #'car prepared)))
+            (unless (y-or-n-p
+                     (format "[eglot] Server wants to edit:\n  %s\n Proceed? "
+                             (mapconcat #'identity (mapcar #'car prepared) "\n  ")))
+              (jsonrpc-error "User canceled server 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))
+                 finally (eldoc) (eglot--message "Edit successful!"))))))
 
 (defun eglot-rename (newname)
   "Rename the current symbol to NEWNAME."
-- 
2.35.1


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

end of thread, other threads:[~2023-09-07 12:45 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-12-26 13:42 bug#60338: [PATCH] Add option to present server changes as diffs Philip Kaludercic
2022-12-29  0:01 ` Yuan Fu
2022-12-29 14:28   ` Philip Kaludercic
2022-12-29 14:36     ` João Távora
2022-12-29 14:39       ` Philip Kaludercic
2022-12-30 13:13         ` João Távora
2022-12-30 15:09           ` Philip Kaludercic
2023-01-04 20:56             ` Felician Nemeth
2023-06-09  7:55               ` Philip Kaludercic
2023-06-11 21:33 ` Philip Kaludercic
2023-06-12 11:56   ` Eli Zaretskii
2023-06-12 12:35     ` Philip Kaludercic
2023-06-12 12:52       ` Eli Zaretskii
2023-06-12 13:29         ` Philip Kaludercic
2023-06-12 13:41           ` Eli Zaretskii
2023-06-13 21:34             ` Philip Kaludercic
2023-06-14  6:00               ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-06-14 11:27                 ` Philip Kaludercic
2023-06-18 11:38                   ` Philip Kaludercic
2023-06-18 15:18                     ` João Távora
2023-06-18 22:37                       ` João Távora
2023-06-24 16:53                       ` Philip Kaludercic
2023-09-01  0:06                         ` João Távora
2023-09-01  5:18                           ` Philip Kaludercic
2023-09-01 21:12                           ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-09-01 21:19                             ` João Távora
2023-09-01 22:01                             ` João Távora
2023-09-02  6:13                               ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-09-02  9:55                                 ` João Távora
2023-09-07  1:00                                   ` Dmitry Gutov
2023-09-07  6:28                                     ` Juri Linkov
2023-09-07 12:41                                       ` Dmitry Gutov
2023-09-07 12:45                                       ` Dmitry Gutov

Code repositories for project(s) associated with this external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.