From: Philip Kaludercic <philipk@posteo.net>
To: 60338@debbugs.gnu.org
Subject: bug#60338: [PATCH] Add option to present server changes as diffs
Date: Mon, 26 Dec 2022 13:42:04 +0000 [thread overview]
Message-ID: <87ilhy1dub.fsf@posteo.net> (raw)
[-- 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
next reply other threads:[~2022-12-26 13:42 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-26 13:42 Philip Kaludercic [this message]
2022-12-29 0:01 ` bug#60338: [PATCH] Add option to present server changes as diffs 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
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87ilhy1dub.fsf@posteo.net \
--to=philipk@posteo.net \
--cc=60338@debbugs.gnu.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 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.