Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make swiper-query-replace a standalone command #2777

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

astoff
Copy link

@astoff astoff commented Jan 1, 2021

Apparently it's not possible to resume a previous swiper-query-replace operartion, so I would like to propose the attached change.

The candidates in the swiper-query-replace prompt will be the previous replacement texts used for the given replacement subject. The history in that query will be the full history of replacement texts.

I frankly never understood what that old :def parameter in the ivy-read call is supposed to be telling me, and I removed it. If I'm missing something clever here, let me know :-).

Another idea, which I could work on if there is interest, would be to modify swiper-query-replace so that it also makes sense when called outside of swiper. This would be a variant of swiper where hitting RET asks for a replacement text instead of just exiting the search. This is closer to the usual query-replace and might feel more familiar to some people.

@astoff
Copy link
Author

astoff commented Jan 3, 2021

I realized that providing candidates in the replacement text query isn't a great idea, because it's too easy to mistakenly select one of them instead of the current input. (If (ivy-read ... :preselect -1) was a thing, this could perhaps be fixed, but I don't think it would be the best UI anyway). So I removed that. It's still possible to access the history of replacement texts with C-r, which is already an improvement over the previous version.

More importantly, though, I implemented the idea sketched in my previous comment, and swiper-query-replace is now a standalone command and can be called from top level. It works as follows:

  • If called during a Swiper search, it behaves just as before. (With the caveat that C-g will quit altogether, instead of going back to the Swiper search).
  • For added discoverability, the above functionality can also be accessed as an ivy action, namely M-o q.
  • If called from outside the minibuffer, swiper-query-replace is similar to swiper-isearch, except that
    1. ivy-done takes you to the state where a replacement text is requested.
    2. query-replace-from-history-variable is used instead of swiper-history.
    3. A query-replace in region is arranged for if the region is active.
    4. A special regex builder is used, whose effect is to not change at all the inserted regex. This is because in a query-replace, one probably wants precision over convenience.
    5. Allows resuming the last query-replace with a prefix arg.

There's still something awry with the overlays (sometimes they stick around after the command quits). Unfortunately that part of the code looks quite arcane to me. If you like the general idea, we can see what to do about that part.

@astoff astoff changed the title Use query-replace history in swiper-query-replace Make swiper-query-replace a standalone command Jan 3, 2021
@basil-conto
Copy link
Collaborator

Thanks. I can't say whether or in what form these changes will be accepted, but I just wanted to inform you that large contributions require copyright to be assigned to the Free Software Foundation, as Ivy is copyrighted by the FSF. Do you have such a CA on file already? If not, would you be willing to submit one? If you're unfamiliar with this, the process is relatively straightforward, and there's more info at (info "(emacs) Copyright Assignment"). You can find the form itself at https://git.savannah.gnu.org/cgit/gnulib.git/tree/doc/Copyright/request-assign.future.

@astoff
Copy link
Author

astoff commented Jan 4, 2021

Of course I'm willing to sign the CA papers (which I haven't done so far), as long as there is some indication I'll need them :-)

@abo-abo
Copy link
Owner

abo-abo commented Jan 5, 2021

Hi. The PR looks good to me. Please proceed with the CA 👍

@astoff
Copy link
Author

astoff commented Jan 15, 2021

Ok, I completed the CA paperwork.

I've also pushed a commit to refine the start point of the replacement. With that in place, I think the logic of the command is good, but of course I'm happy to discuss all the details.

It remains to sort out some issues with the overlays. I think you can address those things more effectively and reliably, @abo-abo. How should we organize this?

swiper.el Outdated Show resolved Hide resolved
swiper.el Outdated Show resolved Hide resolved
swiper.el Outdated
"Swiper query replace: "
#'swiper-isearch-function
:initial-input initial-regexp
:keymap swiper-isearch-map
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This gives a "reference to free variable swiper-isearch-map" byte-compiler warning, which probably means you need to define that variable before this function.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've replaced this with swiper-map. Then M-n will not quote the query, but at least no large reorganizing of the code is needed.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know which is better, but FWIW moving a defvar verbatim doesn't qualify as "large reorganizing of the code".

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True; but then a random piece of swiper-isearch will be outside of the corresponding ;;*-section of the file. I was assuming this is undesired.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rules are made to be broken ;).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or rather, there are always exceptions that prove the rule.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants