unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Dmitry Gutov <dmitry@gutov.dev>
To: "João Távora" <joaotavora@gmail.com>
Cc: Eli Zaretskii <eliz@gnu.org>, "Philip K." <philipk@posteo.net>,
	Stefan Monnier <monnier@iro.umontreal.ca>,
	emacs-devel@gnu.org
Subject: Re: Adding refactoring capabilities to Emacs
Date: Sat, 9 Sep 2023 01:35:35 +0300	[thread overview]
Message-ID: <858c929d-61c3-633e-ae9a-de8c5e5c40d1@gutov.dev> (raw)
In-Reply-To: <CALDnm53=QdGZGvzZqvL=vsdyK=mQzTBRzgKNHZE8d_9SBfoQbA@mail.gmail.com>

On 08/09/2023 14:10, João Távora wrote:
> On Thu, Sep 7, 2023 at 11:39 PM Dmitry Gutov <dmitry@gutov.dev> wrote:
> 
>> Not that many: these are 260 edits just across 3 files.
> 
> glyph_row? As in 'struct glyph_row' of src/dispextern.h?  My clangd
> suggested changes to 7 files.   Maybe not contrived but certainly
> not common either, and well worth the subsecond latency considering
> the time you'd want to spend reviewing such a mammoth change.

Not the type but the identifier with the same name (struct glyph_row 
*glyph_row). Anyway, 3 or 7, it might as well be 70 files in another case.

Although the impact somewhat depends on whether the current performance 
is proportional to the number of files, or the number of edits.

>>> A much more typical example of renaming ab symbol in a single function
>>> resolved in 0.02s.  Most examples of applying quick fixes and moving
>>> .hpp inlined member functions to out-of-line in .cpp resolve in similar
>>> quasi-instantaneous fashion.
>>
>> That's great, but for such small examples one could almost do without
>> advanced interfaces too, couldn't they?
> 
> For local renames, yes, which is precisely why the reason why eglot-rename
> has a special 'maybe-summary' confirmation method (I use maybe-diff)
> whose point is to skips the confirmation if it detects the change to be "local
> enough"

But a rename can just as well be global. Which is simple in theory, but 
it can be a good idea to double-check whether all identifiers are found 
anyway (or check for false positives). Though perhaps it's my habit due 
to working with Grep-based renames a lot.

> For others,  like extracting methods, etc, not at all.  They may be
> simple, but you generally still want to have a look at what's being
> especially if it targets on or

Sure.

>>> Now, let me clarify what I meant by "shiny new refactoring interface".
>>> It's not what you think I meant, I believe. What I meant is a framework
>>> for:
>>>
>>> 1. collecting 'potential sets of changes' -- for clarity let's call
>>>      "actions" after LSP nomenclature -- from a number of different
>>>      backends.  Examples of actions: "rename thing at point", "organize
>>>      imports", "write as while loops as cl-loop"
>>>
>>> 2. presenting actions names to the user -- either via the minibuffer
>>>      or by annotating buffer position where these tweaks apply.
>> - Some way (possibly also a hook) to find all the "points of interest"
>> in a buffer -- these could also be annotated with a lightbulb or etc in
> 
> That's what I meant yes "annotate".  But I'd leave the annotation
> interface to a second phase.  As you note, it's not obvious when to collect
> these actions with special affinity to buffer positions .  In LSP, some of
> them are already being collected because of diagnostics.

Yes, when to collect and how to display. The collection method could 
also be "pull" or "push": with hooks we usually do the "pull" thing, but 
since flymake (and often other diagnostics) work asynchronously a "push" 
mechanism might make more sense.

> Flymake is the main existing Emacs interface that periodically annotates
> the buffer with pieces of information about your code gotten from a server.
> It knows how to display things in the fringe, and is fairly customizable.
> You can have multiple backends, etc, it works asynchronously and generally
> has a lot of common logic for knowing how to update only parts of the
> buffer etc.
> 
> It could be argued we should use it for this purpose, but then again, it
> could be argued we shouldn't, especially if we suspect equating "localized
> actions" to diagnostics is simply wrong.  This feature request came up in the
> past in the Eglot tracker and I gave it a go once or twice with Flymake.
> But maybe I just didn't try hard enough.

We should probably abstract over Flymake either way. But I agree that 
all this can be left until later.

>> Sure. Possibly carrying more-or-less same information that LSP's edits
>> do. Though we could see whether it can be useful to annotate them with
>> additional info, e.g. name/type/etc (where we'd deduce that a function
>> called X is being renamed, or a file is being moved, or both; which
>> could be reflects in the changeset's display more intelligently).
> 
> That's not a bad idea, but is an implementation detail.  We
> should probably not expose this representation (at least not too early)
> to conserve the freedom to change it.

You skipped over the remainder of my email where I explained why I liked 
to start with step 4.

We can still want to be able to tweak it during Emacs 30's development, 
of course, and maybe even later, but it's impossible not to discuss and 
document if we want customizable/swappable UIs for confirmation anyway.

>> Sure. I wouldn't know what position "organize imports" should apply to
>> anyway. But to do with backends which don't support it?
> 
> Maybe at least one of the backends will support it.  Else issue an
> error, that's not much more I can see.  Some backends may
> not even support rename.  It's not like in xref where "find definitions"
> and "find references" which are things that almost all xref backends
> would be able to do.

Backends which don't support rename could fall back to xref which worst 
case falls back to grep. Or something like that.

Anyway, I guess we'll implicitly decide that both "rename" and "organize 
imports" are always available and create commands with dedicated 
bindings for them?

Why the latter, BTW? Or are there more commands like that? From what I'm 
reading, "organize imports" is not a part of the official LSP protocol, 
though there are extensions.

>>> Regarding 4 (which seems to be the current focal point of the
>>> discussion) Eglot has three main types of confirmation strategies
>>> available.  See eglot-confirm-server-edits for more.
>>>
>>> * 'diff', which just presents the edits
>>> * 'summary', which summarizes the edits in the minibuffer and prompts
>>>     to apply.
>>> * nil, which means no confirmation at all
>>>
>>> There is also 'maybe-diff' and 'maybe-summary' which behave like
>>> nil if all the files in the change list are already visited buffers.
>>
>> Not sure why the cutoff is there: and not for example "if all the
>> changes are in the current file", or "are all visible on the screen".
>>
>> Anyway, the more the merrier, I suppose.
>>
>>> That said, it's the whole sequence 1 to 4, not just 4, that needs
>>> to be generalized out of Eglot and into Emacs.  Note that some parts
>>> of 1..4, like the annotation of actions in buffers or the support for
>>> file creation and deletion, aren't yet in Eglot, so there's good work
>>> to be done.  Some of the "annotation" logic already exists in Flymake,
>>> and Flymake must be taken into the equation too, and early.
>>
>> The reason for talking about 4 first is twofold:
>>
>> - I understand 4 better than the rest at this point of time, and it
>> could be plugged into some existing bits of functionality already (e.g.
>> Eglot's refactorings and Xref/Project names).
>>
>> - There will likely be two entry points to the new library, just like
>> with Xref we have xref-backend-functions and xref-show-xrefs. The former
>> depends on the latter. By choosing a good enough data model for step 4
>> (e.g. how changes are represented), we can better build requirements for
>> step 1, given that whatever hook(s) we add, they would already need to
>> be documented with the details about the data in/out flow.
>>
>>> Also, it would be very good if we could have an early backend which is
>>> *not* LSP.  An obvious candidate is Elisp.  I'd like to know what is
>>> the minimal effort to write a lisp function based on the new
>>> macroexpanding tricks that Stefan Monnier developed that says
>>> precisely where a given symbol is used as a variable in a function.
>>> As far as I understand,  these techniques are currently being used for
>>> accurate completion, but they could maybe be used for accurate
>>> refactorings.
>>
>> Xref could easily be an early backend which supports renaming only.
>> Eglisp's xref-backend-references could make use of the macroexpanding
>> thing to include local variables too.
>>
>>>> Not to belittle the new addition, though - it's a good step for Eglot.
>>>
>>> As someone who actually uses Eglot daily and is an avid consumer
>>> of refactoring functionality, my opinion is that the "diff"
>>> confirmation strategy that Philip proposed and implemented is freaking
>>> great, even if the implementation is a bit contorted (though mostly
>>> isolated).
>>>
>>> IMO diff is the lingua franca for communicating changes to source
>>> code around the world, even in those pretty web interfaces that
>>> you and many others like.  So it makes full sense to support it
>>> and to support it well.
>>
>> I'm okay with diffs myself obviously, and we should keep this UI option
>> if feasible, but I'd also prefer to have something more compact
>> available, for the "web interface lovers" of the world. Diffs do have
>> some barrier to understanding, even we are very much used to them. And
>> diff-with-context can be pretty long too.
>>
>>>> - I would probably want to bind the originally proposed
>>>> 'diff-apply-everything' to 'C-c C-c' (e.g. "commit the change to disk"),
>>>> but that's already taken in diff-mode.
>>>
>>>> - 'git diff' has a less-frequently used option called '--word-diff'
>>>> which could reduce the length of the diff in the case I am testing (but
>>>> I guess diff-mode would have to be updated to support that output). And
>>>> another way in that direction would be to reduce the size of the diff
>>>> context (e.g. to 0).
>>>
>>> I'm not at all opposed to implementing other confirmation strategies
>>> that look more like what VSCode or other editors show users.  Or
>>> augmenting the existing 'diff' strategy with new shortcuts and stuff.
>>> But I wouldn't overthink UI details at this point in the game either.
>>
>> The first suggestion in particular looked like a modest enough tweak
>> that does not depend on the rest of this discussion (and it would likely
>> have a diff-specific implementation). But if we try to make it atomic,
>> that's an increase in complexity, of course.
> 
> 
> 
> --
> João Távora




  reply	other threads:[~2023-09-08 22:35 UTC|newest]

Thread overview: 147+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-19  6:03 Adding refactoring capabilities to Emacs Eli Zaretskii
2023-08-19 10:58 ` Eshel Yaron
2023-08-19 11:18   ` Eli Zaretskii
2023-08-20  1:19 ` Dmitry Gutov
2023-08-20  6:39   ` Eli Zaretskii
2023-08-20  6:42     ` Ihor Radchenko
2023-08-20  8:44   ` Yuri Khan
2023-08-20 22:51     ` Dmitry Gutov
2023-08-29 10:53       ` João Távora
2023-08-29 11:35         ` Dr. Arne Babenhauserheide
2023-08-30  0:52         ` Dmitry Gutov
2023-08-30 18:46           ` Stefan Kangas
2023-08-30 19:59             ` Dmitry Gutov
2023-08-30 20:37           ` João Távora
2023-08-30 21:49             ` Dmitry Gutov
2023-08-30 22:01               ` Stefan Kangas
2023-08-30 22:04                 ` Dmitry Gutov
2023-09-04  6:03                 ` Rudolf Schlatte
2023-09-04 11:04                   ` João Távora
2023-09-04 12:18                     ` Rudolf Schlatte
2023-08-31  5:03               ` Eli Zaretskii
2023-08-31  8:02                 ` João Távora
2023-09-04 15:45                   ` Dmitry Gutov
2023-09-04 23:34                     ` Dmitry Gutov
2023-09-04 17:23               ` Juri Linkov
2023-09-04 17:53                 ` Alfred M. Szmidt
2023-09-05  6:38                   ` Juri Linkov
2023-09-05  7:46                     ` Alfred M. Szmidt
2023-09-04 18:04                 ` Dmitry Gutov
2023-09-05  6:43                   ` Juri Linkov
2023-09-04 20:49                 ` Philip Kaludercic
2023-09-04 17:15   ` Juri Linkov
2023-09-04 18:02     ` Dmitry Gutov
2023-09-05 13:56       ` Alexander Adolf
2023-09-05 14:00         ` Dmitry Gutov
2023-09-06 13:25           ` Alexander Adolf
2023-08-20 13:00 ` sbaugh
2023-09-07 14:39 ` João Távora
2023-09-07 16:20   ` Stefan Monnier
2023-09-07 16:49     ` João Távora
2023-09-07 17:06       ` Stefan Monnier
2023-09-07 17:24         ` João Távora
2023-09-07 17:54           ` Stefan Monnier
2023-09-07 18:12             ` João Távora
2023-09-07 21:56               ` Stefan Monnier
2023-09-07 23:46         ` Lynn Winebarger
2023-09-07 20:41     ` Dmitry Gutov
2023-09-07 22:03       ` Stefan Monnier
2023-09-07 22:43         ` Dmitry Gutov
2023-09-07 22:18     ` João Távora
2023-09-07 22:39       ` Dmitry Gutov
2023-09-08  6:18         ` Eli Zaretskii
2023-09-08 18:25           ` Dmitry Gutov
2023-09-08 18:35             ` João Távora
2023-09-08 18:38               ` Dmitry Gutov
2023-09-08 18:44                 ` João Távora
2023-09-08 19:29                   ` Dmitry Gutov
2023-09-08 18:57               ` Eli Zaretskii
2023-09-08 19:01                 ` João Távora
2023-09-08  6:55         ` João Távora
2023-09-08 15:42           ` Stefan Monnier
2023-09-08 16:05             ` João Távora
2023-09-08 16:20               ` João Távora
2023-09-25 23:11                 ` Dmitry Gutov
2023-09-25 23:32                   ` Dmitry Gutov
2023-09-26  5:36                   ` Alfred M. Szmidt
2023-09-26  8:06                     ` João Távora
2023-09-26 10:57                       ` Dmitry Gutov
2023-09-26 11:24                         ` João Távora
2023-09-26 11:33                           ` Alfred M. Szmidt
2023-09-26 11:34                           ` Dmitry Gutov
2023-09-26 12:57                             ` João Távora
2023-09-26 13:09                               ` Alfred M. Szmidt
2023-09-26 13:52                                 ` Dmitry Gutov
2023-09-26 13:38                           ` Philip Kaludercic
2023-09-26 14:06                             ` João Távora
2023-09-26 14:31                               ` Dmitry Gutov
2023-09-26 14:51                                 ` João Távora
2023-09-26 14:54                                   ` Dmitry Gutov
2023-09-26 15:17                                     ` João Távora
2023-09-26 15:35                                       ` Alfred M. Szmidt
2023-09-26 15:38                                         ` Dmitry Gutov
2023-09-26 15:47                                           ` Alfred M. Szmidt
2023-09-26 16:01                                             ` Dmitry Gutov
2023-09-26 16:10                                               ` Alfred M. Szmidt
2023-09-29 10:55                                                 ` Eli Zaretskii
2023-09-29 12:36                                                   ` Alfred M. Szmidt
2023-09-29 15:32                                                     ` Eli Zaretskii
2023-09-26 16:31                                               ` Yuri Khan
2023-09-26 17:28                                                 ` Dmitry Gutov
2023-09-29 11:10                                                 ` Eli Zaretskii
2023-09-29 10:49                                             ` Eli Zaretskii
2023-09-29 12:36                                               ` Alfred M. Szmidt
2023-09-26 15:01                                 ` [External] : " Drew Adams
2023-09-26 15:22                                   ` Alfred M. Szmidt
2023-09-29 10:36                                     ` Eli Zaretskii
2023-09-29 12:30                                       ` Robert Pluim
2023-09-29 13:11                                         ` Stefan Monnier
2023-09-29 13:13                                           ` Alfred M. Szmidt
2023-09-29 13:16                                           ` João Távora
2023-09-29 13:19                                             ` João Távora
2023-09-29 15:20                                               ` Stefan Monnier
2023-10-01 12:07                                                 ` Stefan Kangas
2023-10-01 18:43                                                   ` Howard Melman
2023-09-29 15:47                                           ` Drew Adams
2023-09-29 15:30                                         ` Eli Zaretskii
2023-09-26 15:27                                   ` Alfred M. Szmidt
2023-09-29 10:40                                     ` Eli Zaretskii
2023-09-29 12:36                                       ` Alfred M. Szmidt
2023-09-29 15:34                                         ` Eli Zaretskii
2023-09-29 15:40                                           ` Alfred M. Szmidt
2023-09-29 16:22                                             ` Eli Zaretskii
2023-09-29 16:32                                               ` Alfred M. Szmidt
2023-09-29 16:51                                                 ` Eli Zaretskii
2023-09-29 17:32                                                   ` Alfred M. Szmidt
2023-09-29 17:56                                                     ` Eli Zaretskii
2023-09-29 18:02                                                   ` Stefan Monnier
2023-09-26 10:55                     ` Dmitry Gutov
2023-09-26 12:03                       ` Alfred M. Szmidt
2023-09-26 12:11                         ` Dmitry Gutov
2023-09-26 12:20                           ` Alfred M. Szmidt
2023-09-29  6:52                           ` Eli Zaretskii
2023-09-29 10:21                             ` Dmitry Gutov
2023-09-29 15:20                               ` Eli Zaretskii
2023-09-29 17:20                                 ` Dmitry Gutov
2023-09-29 17:36                                   ` Eli Zaretskii
2023-09-29 17:44                                     ` Dmitry Gutov
2023-09-08 18:35               ` Dmitry Gutov
     [not found]                 ` <CALDnm52Wtat24JFu=o6m_eJVamub+1H1BxNd5eELQ2j--7OetA@mail.gmail.com>
     [not found]                   ` <da4cb294-39eb-c4a1-a625-da5ee183170c@gutov.dev>
2023-09-08 18:57                     ` João Távora
2023-09-07 19:06   ` Felician Nemeth
2023-09-07 19:19     ` João Távora
2023-09-07 19:25     ` Ihor Radchenko
2023-09-07 19:28       ` Ihor Radchenko
2023-09-07 22:14         ` João Távora
2023-09-07 20:43     ` Dmitry Gutov
2023-09-07 22:39   ` Dmitry Gutov
2023-09-08 11:10     ` João Távora
2023-09-08 22:35       ` Dmitry Gutov [this message]
2023-09-08 23:17         ` João Távora
2023-09-08 12:46   ` Eshel Yaron
2023-09-08 12:52     ` João Távora
2023-09-08 13:18       ` Eshel Yaron
2023-10-01 15:07         ` Extract to new definition (was: Adding refactoring capabilities to Emacs) Eshel Yaron
2023-09-08 13:30       ` [semi off topic] grep-based refactoring [was: Adding refactoring capabilities to Emacs] tomas
2023-09-08 17:53         ` João Távora
2023-09-08 18:24           ` Dmitry Gutov
2023-09-08 18:51             ` tomas

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=858c929d-61c3-633e-ae9a-de8c5e5c40d1@gutov.dev \
    --to=dmitry@gutov.dev \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    --cc=joaotavora@gmail.com \
    --cc=monnier@iro.umontreal.ca \
    --cc=philipk@posteo.net \
    /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).