Add command to show the previous version of the hunk
I propose adding a new command show-diff-change to show the previous version of the git hunk under the cursor. This would allow for a quick, inline preview of what has been changed at a specific point in the file.
I believe this feature fits as part of the Helix core rather than being a plugin considering that:
- the vision for git-related features, as expressed in this comment on #2261 , is that read-only operations are fine for core
- it's intrinsically coupled with the gutter implementation and the :reset-diff-change command, as the hunks should be exactly the same for consistency
I have a draft implementation in this PR, of course open to any feedback.
https://github.com/user-attachments/assets/38d71c32-d002-4d3e-8e72-01e85ac18a9b
https://github.com/helix-editor/helix/issues/405#issuecomment-3157153945
#405 is about diffs between files in general, while this is about seeing what the hunk shown in the gutter actually represents. I might be wrong, but I feel they are two very different features that respond to two different needs.
You are not wrong. We need a set of proper diff tools within Helix.
@Axlefublr moving the discussion from the PR to this issue. You proposed opening the previous version of the hunk in a new buffer. That was my initial idea as well, but a popup seemed like a better option from a UX perspective. Out of curiosity, why do you prefer a new buffer?
In any case, this is just a draft proposal. We'll need input from the core developers to understand their vision for this. To be honest, I don't expect this to be merged soon, at least not in its current form, and I'm completely fine with that. I prefer a slower development process that maintains a consistent UX over quickly merging features that don't integrate well.
That being said, another way to solve this would be to expose the previous version of the hunk and leave it to the user's configuration or plugins to decide how to show it.
For example, a yank-hunk-before <reg> command would allow users to configure their own keybindings to show the content in a popup or open it in a new buffer.
Config for a popup:
[keys.normal]
A-S-x = ":yank-hunk-before x"
A-S-h = "@<A-S-x> @:sh echo '<C-r>x' <ret>"
Config for a new buffer:
[keys.normal]
A-S-x = ":yank-hunk-before x"
A-S-h = "@<A-S-x> @:new <ret> @\"xP"
Furthermore, the current version of the hunk can already be yanked via mig, so it would also be possible to show a diff instead of just the previous version.
I'm adding the yank-hunk-before command to the PR as an alternative proposal.
why do you prefer a new buffer?
mainly, there's no way to interact with the text in a popup, but in a normal buffer you can do whatever you want
often when viewing a diff, it's because I want to copy it, or do some other editing on it
say for example I want to bring back the old version of some piece of code, and comment out the new one
can't exactly just :reset-diff, cause that will specifically remove the new code; well if the diff opened in a new buffer, I could easily copy it (maybe after making some changes), as well as literally anything else I would ever want
another workflow that comes to mind:
maybe you're working on a feature, and can't quite figure out how to best do some diff. instead of juggling around stashes, you can just open the diff in a buffer for storage, and then reset it in the original place, to try a different approach
after a couple of such iterations, you go “yeah, approach #7 was best after all”, copy it out and replace — blammo
basically, opening the diff in a new buffer is so much more flexible that it doesn't quite make sense to not do it;
neatly, the user can set a hotkey that splits the current buffer, before executing :show-diff-change, which would in effect make the command show the buffer in a split, instead of the current buffer. so you would be giving more freedom to the users, in deciding how they want to interact with the viewed diff
your register idea
this is neat conceptually, but imo puts more configuration strain on a feature that is ultimately not that important... no offence hahaha
I think it would be better to have something that has both flexible and reasonable default behavior, without requiring the user to do anything if they're fine with the default
the default of putting the diff into a register is a bit inconvenient :/