oantolin / embark

Emacs Mini-Buffer Actions Rooted in Keymaps
GNU General Public License v3.0
930 stars 56 forks source link

Generalize embark-mark and embark-unmark #253

Closed minad closed 1 year ago

minad commented 3 years ago

Very much related to #166, feel free to merge these feature requests.

This gives us convenient actions on multiple candidates.

oantolin commented 1 year ago

I was going to post exactly the same function that @minad did!

I have lots of Embark things in my muscle memory now, like C-. DEL to delete an entire s-expression. If suddenly C-. started acting on the selection that would certainly screw me up, since I sometimes do a little editing between selecting targets.

bdarcus commented 1 year ago

I want to emphasize it was a question, and I'm not set in my opinion.

But that seems incoherent at first glance. If you select multiple, you want to act on multiple.

I was surprised after selecting multiple, per my earlier question, that it only acted on one.

Obviously you'll have to see what others users says, but just wanted to put the idea out there, based on my initial experience.

oantolin commented 1 year ago

The way I see it, if I select multiple candidates I eventually want to act on them, but not necessarily right now. For example, yesterday I was editing some notes and wanted to add references for some claims I made, but I was also doing other editing, like rewording, reordering some paragraphs, etc., anf I didn't want to stop to look up the references. So instead I selected the sentences for which I needed to add a reference and was free to use embark anyway for editing (I use it a lot to reorder paragraphs and sentences for example, or to delete entire parenthetical remarks from anywhere inside the remark). Then when I finished editing I ran embark-collect to get a buffer with all the sentences needing a reference, and only then started looking them up.

More philosophically, if embark-act forced you to act on the selection it would become a modal interface: once you select anything you are now officially in selection mode and loose the ability to decide what to act on until you leave selection mode. I don't like modal interfaces and while I will happily provide building for others to build their own modal prisons, I wouldn't make that the default in Embark.

I find even the modal minibuffer a little constraining and thus recommend enabling recursive minibuffers.

oantolin commented 1 year ago

Plus that function that @minad wrote is short and sweet and solves your problem. We can add it to the wiki and even to the manual, but I I'd prefer to keep embark-act and embark-act-all separate.

oantolin commented 1 year ago

Oh, right @minad, with your embark-act-single-or-all you need a separate binding to select items. That's easily solved, but definitely worth pointing out.

minad commented 1 year ago

@bdarcus

But that seems incoherent at first glance. If you select multiple, you want to act on multiple.

FWIW I don't want that. To me the Embark design seems coherent as is. But I understand that your proposed workflow is useful and maybe preferrable. I would bind some key to a macro which directly selects and another key to such an embark-act dwim style command. For my taste this is not as nice as the current design, since one needs another key, the selection action is singled out as a separate action. Furthermore I usually want extra protection for embark-act-all.

@oantolin What about the proposed renaming in https://github.com/oantolin/embark/issues/253#issuecomment-1516468986? I saw that you already bumped the version.

minad commented 1 year ago

There were are few more things which came to my mind recently, but I forgot them over the discussion. I wonder if we can be sufficiently sure that embark--selections is valid. For example what happens if we select candidates in Vertico on an action which removes a candidate but isn't marked as embark--restart. Then we probably act on an invalid candidate, right? This is probably expected and solved via embark--restart. But what about candidates within a buffer - what if the user deletes or edits a marked overlay? Do we need some protection here? Did I understand correctly that embark--selections is always preserved after acting? Is this convenient and expected in normal buffers or would we need a post action hook which cleans the selection?

oantolin commented 1 year ago

Oh, no! I hadn't seen (or maybe I did and forgot) the proposal to rename embark-toggle-select to embark-select! I really like that idea (even though the name would be a little inaccurate since it doesn't select, it toggles!). Would it be awful if I changed it now?

oantolin commented 1 year ago

The question of the selection becoming invalid is tough. You are correct, @minad, that currently embark--selections is always preserved. I have taken advantage of that in fact. To move stuff around in a buffer you can delete-region and embark-insert, and that works even if you delete first. Right now it is the user's responsibility to understand that even if the highlighted stuff changes, the selection is still made up of the original candidates. 😬

It would be easy to implement an alternative model in which:

Would that be better?

minad commented 1 year ago

@oantolin

Oh, no! I hadn't seen (or maybe I did and forgot) the proposal to rename embark-toggle-select to embark-select! I really like that idea (even though the name would be a little inaccurate since it doesn't select, it toggles!). Would it be awful if I changed it now?

You could change it now, update it everywhere including the changelog and then tag version 0.23. This has also happened to me, that I tagged multiple versions in quick succession because a mistake got in first. I usually avoid tagging a new stable version directly after making any kind of significant change. I usually wait a few days or a week. Many users will pull your package anyway from MELPA or ELPA-devel. Then incoming feedback can be addressed before the release.

minad commented 1 year ago

It would be easy to implement an alternative model in which:

I think we should first gain some experience with the current model and maybe only then make changes afterwards. If the decision is made to use another model I would try something simpler - candidates without bounds are always preserved and candidates with bounds are automatically deselected when they are edited. One can use simple overlay modification hooks for that, such that this would be a trivial change. See https://github.com/minad/jinx/blob/2f7f4ac9ce3f69a0d086e2600406c36f46ff3a07/jinx.el#L266-L268.

minad commented 1 year ago

My main concern about the current model is that one somehow loses track of the selected candidates. But in order to tell this, I have to gain more experience with the workflow. But anyway, one can always easily inspect embark--selections.

oantolin commented 1 year ago

I usually avoid tagging a new stable version directly after making any kind of significant change. I usually wait a few days or a week.

I should definitely start doing that. I have done that most of the time, in fact. Here I jumped the gun and it also happened to me once before.

Do you describe the changes in the changelog even before bumping the version number? That sounds like a good idea for early adopters.

oantolin commented 1 year ago

I agree with using the current system for a while before changing the model.

oantolin commented 1 year ago

candidates with bounds are always preserved and candidates without bounds are automatically deselected when they are edited

You have those two swapped, right?

minad commented 1 year ago

You have those two swapped, right?

Right, edited.

minad commented 1 year ago

I should definitely start doing that. I have done that most of the time, in fact. Here I jumped the gun and it also happened to me once before.

Yes, this has happened before. But it is usual that it takes some time to develop a robust release workflow. I am regularly tagging new releases for my packages if new features got in, but almost never right away. Then I usually inspect the last release in order to ensure that I don't forget anything, basically git show --stat <tag>.

Do you describe the changes in the changelog even before bumping the version number? That sounds like a good idea for early adopters.

Yes, see for example https://github.com/minad/vertico/blob/main/CHANGELOG.org.

minad commented 1 year ago

There are also many different "philosophies" about how a changelog should look like. I only describe user-facing changes or very relevant technical changes. I also try to keep the changelog concise and usually don't reference the issue tracker. It should be somewhat readable.

There are also more formal changelogs which always reference the issues (https://github.com/radian-software/selectrum/blob/master/CHANGELOG.md), but for me this hurts readability. It may be better in the long run if you want to investigate something. But there is still always the git log for that. For me the worst example are the Emacs "changelogs" which are just extracted from the git log, e.g., https://github.com/emacs-mirror/emacs/blob/master/lisp/ChangeLog.16. Totally useless. The NEWS files on the other hand are very useful, but are often lacking information.

oantolin commented 1 year ago

I think I agree with what you put into the changelog. Maybe except in being very brief always. For a major new feature, I'd like to not send people to the manual.

I did the renaming and bumped the version again. 😬

minad commented 1 year ago

I think I agree with what you put into the changelog. Maybe except in being very brief always. For a major new feature, I'd like to not send people to the manual.

Makes sense. Your changelog entry looks very good. The only danger is that you will end up with a massive log after a few releases, which takes a lot of time to read. I am still finding my best style for changelogs. :)

I did the renaming and bumped the version again.

Great!