Hacker News new | ask | show | jobs
by mixedmath 928 days ago
I'll summarize my understanding.

A commit that changes how copying (actually "registers", which is a bit more general than copying) works in emacs was recently accepted. Now emacs opens up a minibuffer that shows what is happening, requiring one to accept the change by hitting enter or equivalent. The OP thinks this is a terrible, breaking change as it changes default behavior (and possibly without the possibility of easily configuring this away). Further, this happened without much discussion.

Let's state a vim analogy. If I want to copy the current line into my `d` register, I can type `"dyy`. This proposal would do something like, after typing `"dyy`, open up a scratch buffer that tells the user the text and the buffer, requiring a keystroke to close. This is terrible for people who understand registers (the typical vim user). But I acknowledge that sometimes I don't copy the intended text into registers and have to try again. I also know many vim people who only yank from visual mode, which has a similar show-explicitly-what-is-being-copied behavior.

The rest of this article is a description of how the OP tried to raise discussion, but the commit-author, Thierry, shot it down. Implicitly the rest of the emacs dev community is at fault too.

9 comments

Also, registers are a relatively advanced feature mostly used for rapid edits. Registers aren't aimed at first-time users using a mouse. They're aimed at high-speed typists doing complex things.

I used Emacs for decades, and never really got into registers. Personally, I tended to use kill&yank for copying, and to use either multiple cursors or one-off keyboard macros for complex edits. But Emacs has tons of optional, advanced editing features for people who want to rely on muscle memory.

Adding a confirmation keystroke here is a bit weird. It's a bit like taking an electric piano and adding a confirmation pedal to confirm unusual chords. It just adds one more step to a rapid, complex input operation.

But the other important thing to remember is that Emacs has excellent undo. You don't need to ask users, "Do you want to paste register 'd' containing '...'?", because you can just paste it, and let the user undo it if they chose the wrong register.

So making a breaking change here is odd, and offering no way to disable it would make a lot of users upset.

Emacs predates modern GUI conventions. It's never going to be as familiar to new users as vscodium. So I think there's a good argument for serving power users as well as possible. That isn't to say that Emacs should never tweak the default config or add user-friendly features like the menu bar or visible selections. But it does suggest leaving things like registers mostly alone.

> But the other important thing to remember is that Emacs has excellent undo. You don't need to ask users, "Do you want to paste register 'd' containing '...'?", because you can just paste it, and let the user undo it if they chose the wrong register.

With paste you can see what got pasted, so you've got a chance to realize it is not what you wanted.

But how about for copy? If you meant to copy into register 'r' but missed by a key and typed 't' would it be noticeable right away?

I don't use Emacs so don't know how its undo works, but when I use named registers in Vim it is often to hold something that I'm not going to paste for quite a while. By the time I notice the error it would be annoying to undo all the way back to the mis-copy.

If copying into the wrong register was common enough to need to be addressed, my first thought would be something like adding a status message pups up for a short time near the cursor that says something like "Copied to 't'".

> I don't use Emacs so don't know how its undo works, but when I use named registers in Vim it is often to hold something that I'm not going to paste for quite a while.

Hm, I use consult-yank for this and order less search things I've yanked (copied).

I suppose registers could be more efficient if you copy a lot making narrowing more difficult.

Great points! If you don't participate in emacs development, maybe it's time to consider it.
> A commit that changes how copying (...) works in emacs

To people who don't use Emacs, it should be made clear that standard copying (kill-ring-save, M-w by default) isn't affected, only more advanced saving to registers is. Registers aren't a superset of the clipboard (kill ring).

Edit: In addition, those in this thread claiming that the change won’t be configurable must have no idea of Emacs’ customizability, namely the “settings” are for convenience only, you can switch out all the code if you want to. This is in the elisp part of Emacs, even if it lands without change (doubt it, after reading the actual mailing list thread rather than this one-sided tantrum), someone will have a package within minutes changing the behavior. No, you don’t need a fork for that, the forking here is performative at best.

That is my understanding, and the change for v30 would very much annoy me also. I know nothing about lisp but I save items to registers all the time.

I hope if this change is not reverted I can find a macro snippet that would do that extract key for me. Already in Emacs to do simple things involves lots of keys. Some I have created macros to avoid the keys, but I am not expert enough to create one for this change.

I think this is a good summary of the article, but not a good summary of the problem if you look at the mailing list.

This whole thing seems to have started because Thierry found a few problems with the way registers work, and wanted to address them.

The most important flaw was that after you hit C-x r SPC (save-to-register), whatever key you hit next, you'd save the text into the register associated with that key. In particular, the universal Emacs cancel key, C-g, would not work here: instead, the text or position would be saved to a register called ^g. Similarly, if you accidentally hit "jump-to-register" or "insert-register", you couldn't cancel with C-g (or with any other key), you'd be forced to select a register and it's contents would be jumped to/ inserted (if any).

Secondly, registers can hold text, a position, or nothing. jump-to-register only works if a register holds a position, while insert-register expects a text. Emacs includes a preview of registers which are non-empty when invoking these commands, but it doesn't distinguish - it will show you a register that includes strings as an option for jump-to-register, even though it knows it won't work.

So, Thierry took the time to address all of these concerns, and to address other feedback about the code. The reviewers agreed that these are important changes even though they add some extra interaction, and that the breaking change (having to hit RET after selecting a normal registry, or having to use an extra key to save to a weird register like ^g) are worth the gains. After it was done, and compiled, it was added by the Emacs maintainers to the development branch.

The author of this article came along, asked for a switch to revert between the new and the old behavior, and was asked for a patch. They provided a patch that reverted all of the changes I mentioned before (so, no way to cancel the register commands, no way to get contextual help about which registers contain text VS position, nothing) and instead implemented an entirely different feature (confirmation on overwriting a non-empty register based on a flag). Thierry installed the author's new patch and gave this simple feedback, to which the author basically replied "you don't need all that".

Now, as more people started using the feature, the belief by Thierry and the original reviewers that the breaking change had minimal impact was proven wrong. Thierry started working on a new improvement to create a flag that keeps both all of his new work, but allows the previous workflow too (particularly, removing the extra RET, which was ultimately a side effect, not the main point). The patch missed the mark, but it is still being worked on.

Overall, it seems the process is working quite well, and it is only the author of this article that is trying to bully his way into the discussion and ignore the context, with a very anti-hacker attitude of "if it kinda works, we shouldn't change it in any way", which is very much against the spirit of Emacs.

> Thierry started working on a new improvement to create a flag that keeps both all of his new work, but allows the previous workflow too (particularly, removing the extra RET, which was ultimately a side effect, not the main point). The patch missed the mark, but it is still being worked on.

I think that if the author of this rant did not come along and rant, there would be no "but is still being worked on" done. My reading is that the maintainer (Theirry) was happy with the extra RET.

NOW it is getting worked on because of the dogged and emotional criticism by the rant's author, prior to him writing his rant.

If he didn't make such an emotionally charged and disruptive arguments and patches, the rest of us poor Emacs users would have only found out about the broken workflow (extra RET) once the bug was fully baked in, requiring waiting for the next release in order to get a fix.

Makes me wonder why they didn't decree, "no using a register called ^g, that's a special character" and add a check when specifying a register. I bet it would break fewer workflows.
Well, exceptions for C-g shouldn't have to be hardcoded everywhere, because that makes it harder to move the C-g behavior to some other key. If going this route, I'd first implement a list of "keys with C-g-like behavior" that can be given more members than just C-g, via a startup flag or some such.

Then commands could just reference that list if needed.

> The most important flaw was that after you hit C-x r SPC (save-to-register), whatever key you hit next, you'd save the text into the register associated with that key. In particular, the universal Emacs cancel key, C-g, would not work here: instead, the text or position would be saved to a register called ^g

I'm not very familiar with Emacs, so possibly stupid questions incoming.

If you start to type C-x r SPC t to save to register t, does C-g work right after the C-X and the r?

If so is that because the C-x, r, and SPC are part of the command sequence whereas the t is just an argument used by the command, and the C-g handling is done in the command sequence processing?

Emacs is pretty famous for its flexibility in letting users bind and unbind key sequences to commands. Could people who like the old behavior fairly easily effectively restore it by unbinding the handler for C-x r SPC, and then bind handlers for C-x r SPC a, C-x r SPC b, C-X r SPC c, and so on for all registers they want to use, with each of those handlers just copying to the appropriate register?

That should let them use the same keystrokes they now use, and if my guess above about C-g handling is right also make C-g work to cancel after C-x r SPC.

> The author of this article came along, ...

You mean, "luckily for the entire fucking Emacs community, one of the small number of people who pick up unreleased master commits came along and happens to be a user of registers ..."

Actually multiple people have complained, some less hyperbolically than this author. And, unless you think the people who build their own Emacs from head of master are less likely to use more obscure features of Emacs, then this feedback was always going to come before anything that actually hurts the Emacs community made it even close to a release.
Having read/skimmed the bug I see now that the issues objected to by Eschel were all raised early, back in October, by the other developer looking at the work, Michael H. He pointed out the RET thing and the issue with using control characters as a registers.
This extra context is very informative, thanks!
thank you for this down to the facts summary.
This is basically the only reply that everyone on this thread should read. Thanks for your research.
As a perpetually novice vim user, I actually would have expected "dyy" to mean Delete the current line.

But that probably just proves my novice status.

You’re missing the double quote before the ‘d’ which means you’re talking about a register.
Ah, thanks. You're right, my brain parsed the gp's comment as simply "dyy".
Just for completion, `dd` deletes the current line in vim. I'm not sure what `dyy` should do, if anything.
> I'm not sure what `dyy` should do, if anything.

Currently, nothing. `y` isn't a defined motion.

Maybe it should remove the top item from the list of copied items? Assuming that vim has one of those (in Emacs parlance it's called the kill ring).
> Implicitly the rest of the emacs dev community is at fault too.

?

I can’t tell what this comment is supposed to mean.

He disagrees; other people also felt similarly about it but, they were ignored.

They say, if you don’t like it, why don’t you contribute? …but he did and that wasn’t acceptable either, so he’s forked it.

Do you feel it’s out of order to walk your own path with free software if you disagree with the maintainers? Isn’t that the whole point of GNU?

I just learned a new feature of Vim. Thank you!
vimtutor is absolutely worth the time
I don't think that feature is covered in vimtutor. As far as I can tell vimtutor mentions registers only once in passing and buffers not at all.
> yank from visual mode, which has a similar show-explicitly-what-is-being-copied behavior.

Even better: vim.highlight.on_yank

Fortunately I use evil mode so my workflow is unaffected, for now.
The way I read it, both methods will continue to be available, so I guess it's a question of defaults. (So it doesn't really affect anyone's workflow)