unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Dmitry Gutov <dgutov@yandex.ru>
To: Oleh Krehel <ohwoeowho@gmail.com>
Cc: emacs-devel <emacs-devel@gnu.org>
Subject: Re: A better UI than perform-replace
Date: Mon, 16 Nov 2015 20:01:00 +0200	[thread overview]
Message-ID: <564A19DC.5050707@yandex.ru> (raw)
In-Reply-To: <876112xj2i.fsf@gmail.com>

On 11/16/2015 01:47 PM, Oleh Krehel wrote:

> I think a better UI for `perform-replace' is warranted.  The current
> thing is very basic:
>
> - No good way to see how many matches there are.
> - No good way to get an overview of matches per buffer.
> - No good way to pause the replacement procedure.
> - No good way to undo a replacement.

Indeed.

> An idea to improve this would be with a permanent *replace* buffer,
> similar to `dired' or *Buffer List*. This buffer would be visible during
> the replacement operation, together with the actual buffers that contain
> the candidates. Here are some ideas for key bindings and the general
> interface:

Maybe a universal "replace buffer" is the way to go. I'd expected to 
have an xref-specific replace buffer first, though.

Or even modify the existing xref buffer inline when you press `r', to 
add some widgets to signify marks (maybe just a couple of columns), 
you'd be able to select the lines you want to rename, perform the 
rename, and then maybe see the xref results refreshed, with only those 
hits that you haven't changes, remaining (maybe you want to do something 
else with them).

But don't let me stop you from working on a generic feature - after all, 
query-replace is used in many places.

> 0. The *replace* buffer would be organized in branches by buffer, just
> like *xref* is currently.
>
> 1. "y" would mark the current item for replacement, which corresponds to
> the current line in the *replace* buffer, and advance to the next line.

Or `m', which we use for marks, usually.

> 2. "n" would mark the current item for non-replacement, and advance to
> the next line. This is to distinguish the items for which no decision
> was made yet: they don't have a `y' or `n' mark.

I see the keystroke-saving benefits, but maybe we should start with the 
usual approach of p/n for up/down, and m/u to mark/unmark. `% m' to mark 
by regexp, `U' to unmark all, `t' to toggle all marks. Press `m' while 
cursor is on a group header -> and its marks all its elements, and 
similar for `u'.

> 3. "Y" would mark all items from the current one until the end of the
> current buffer branch. "N" would work in a similar way.
>
> 4. "c" could change the replacement text for a single item. The mark
> would change appropriately.
>
> 5. "C" could change the replacement text for all following items.

That might be cool to try, too.

> 6. "x" would execute all requested changes.
>
> 7. "e" would launch an `ediff' session to review the changes that "x"
> would do.

Wouldn't hurt.

> 8. After "x", the *replace* buffer stays behind until the user kills it.
> It should serve to review the changes. Possibly "u" could be used to
> revert a performed change for the current item.

Sounds good.

> 9. "C-n", "C-p" and any other navigational commands should work as
> usual. Except changing the current item in *replace* should result in
> that item being displayed in its native buffer - exactly what "C-o"
> currently does in *xref*.

That description seems incomplete. Either we shouldn't mess with what's 
displayed in other buffers (and maybe implement a direct counterpart to 
"C-o"), or the *replace* buffer should always display the current item 
in the "other window". But I'm inclined toward the former.

As another alternative, we could should a few lines of context for the 
current match inside the *replace* buffer, if the user asks (e.g. with 
`+' increasing the context height, and `-' reducing it).

> To re-describe things in a shorter way, *replace* should be a staging
> area for the `perform-replace' operation. With the ability to quickly
> view and manipulate the separate replacements, the ability to defer it
> indefinitely, and the ability to finalize the operation with "x".

With the ability to "defer it", there'll also come a need to check 
whether the inputs (search matches?) are up-to-date. That puts some 
restrictions on what it can work with.

> I post this idea here for feedback. Maybe there's a better way to do
> this. Maybe there are ideas to further improve my *replace* proposal.

Another thing I haven't seen mentioned in this list, is the ability to 
rename a file, as a part of search-replace. It may not be needed if one 
performs a textual search, but for the "rename" refactoring operation, 
if I rename a class in Ruby or Java, I want to have its file to be 
renamed automatically as well.

So ideally, the replace buffer would allow to preview that operation as 
well. I'm still thinking how to better support that in xref data structures.

 > Maybe there's a wish to have this functionality in the core.

Where else?



  reply	other threads:[~2015-11-16 18:01 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-15  4:43 Rename refactoring, or something like that Dmitry Gutov
2015-11-16 10:03 ` joakim
2015-11-16 10:17   ` Dmitry Gutov
2015-11-16 11:47 ` A better UI than perform-replace (was: Rename refactoring, or something like that) Oleh Krehel
2015-11-16 18:01   ` Dmitry Gutov [this message]
2015-11-16 22:37   ` Drew Adams
2015-11-17 23:52     ` A better UI than perform-replace John Wiegley
2015-11-17 22:57   ` A better UI than perform-replace (was: Rename refactoring, or something like that) Richard Stallman
2015-11-18  0:55   ` A better UI than perform-replace Juri Linkov
2015-11-18  1:40     ` Drew Adams
2015-11-18 12:32     ` Dmitry Gutov
2015-11-19  0:57       ` Juri Linkov
2015-11-19  1:16         ` Dmitry Gutov
2015-11-20  0:40           ` Juri Linkov
2015-11-21 18:23             ` Dmitry Gutov
2015-11-19 12:46     ` John Yates
2015-11-19 16:31       ` John Wiegley
2015-11-19 19:11         ` John Yates
2015-11-19 19:18           ` John Wiegley
2015-11-20  8:06             ` Adrian.B.Robert
2015-11-19 19:46           ` David Kastrup
2015-11-19 22:03             ` Drew Adams
2015-11-20  0:42               ` Juri Linkov
2015-11-20  8:12                 ` Eli Zaretskii
2015-11-18  8:50   ` Andreas Schwab
2015-11-21  1:41   ` Eric Ludlam
2015-11-16 13:13 ` Rename refactoring, or something like that Óscar Fuentes
2015-11-16 20:53   ` Dmitry Gutov
2015-11-17 11:10     ` John Yates
2015-11-17 13:14       ` Dmitry Gutov
2015-11-17 15:57         ` John Yates
2015-11-16 16:01 ` Eli Zaretskii
2015-11-16 16:03   ` Dmitry Gutov
2015-11-16 17:18     ` Eli Zaretskii

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=564A19DC.5050707@yandex.ru \
    --to=dgutov@yandex.ru \
    --cc=emacs-devel@gnu.org \
    --cc=ohwoeowho@gmail.com \
    /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).