bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#60338: [PATCH] Add option to present server changes as diffs


From: Philip Kaludercic
Subject: bug#60338: [PATCH] Add option to present server changes as diffs
Date: Mon, 12 Jun 2023 12:35:09 +0000

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Philip Kaludercic <philipk@posteo.net>
>> Date: Sun, 11 Jun 2023 21:33:40 +0000
>> 
>> +       ((eq confirm 'diff)
>> +        (with-current-buffer (get-buffer-create " *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))
>
> Isn't there a better way of presenting the edits in human-readable
> form than apply them and then run Diff?  What format is used by the
> server itself to send the edits?

The server sends a JSON message.  Here is an example from a little toy
project of mine in C, where I intentionally uncommented a #include
directive:

--8<---------------cut here---------------start------------->8---
(:id 51 :jsonrpc "2.0" :result
     [(:diagnostics
       [(:code "-Wimplicit-function-declaration" :message "Implicitly declaring 
library function 'strcmp' with type 'int (const char *, const char *)' (fix 
available)" :range
               (:end
                (:character 21 :line 63)
                :start
                (:character 15 :line 63))
               :severity 2 :source "clang")]
       :edit
       (:changes
        (:file:///home/philip/Source/sgo/sgo.c
         [(:newText "#include <string.h>\n" :range
                    (:end
                     (:character 0 :line 25)
                     :start
                     (:character 0 :line 25)))]))
       :isPreferred t :kind "quickfix" :title "Include <string.h> for symbol 
strcmp")])
--8<---------------cut here---------------end--------------->8---

The server gives me a diagnostic and suggests a change.  The change is
just a replacement of a text range with a string:

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

> Besides, this assumes the 'diff' command is available, which is not
> portable -- one more reason not to go that way, or at leas provide an
> alternative.

I am personally fond of this approach, because I get a regular text
buffer that I can store or send someone.  The fact that diff is not
available everywhere (even though I would guess any system with a
language server /should/ have diff installed), is an argument against
enabling this behaviour by default, not against providing this interface.

-- 
Philip Kaludercic





reply via email to

[Prev in Thread] Current Thread [Next in Thread]