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

Undo part of hunk #902

Open
ccjmne opened this issue Feb 7, 2025 · 4 comments
Open

Undo part of hunk #902

ccjmne opened this issue Feb 7, 2025 · 4 comments

Comments

@ccjmne
Copy link

ccjmne commented Feb 7, 2025

Thank you for this gem of a project!

Wouldn't it be nice to be able to undo only parts of a hunk, by visually selecting the lines we want?
I could see it working precisely the way you have laid out for staging parts of an additions-only hunk.

Although, now that I say that, I'm growing increasingly suspicious of the possibility that you've already considered this but chosen not to go through with supporting this feature, possibly because it's a lot more complex to get right than I would naively think.

It looks like mini.diff can, however—I'll experiment a bit with that in the coming days.
Let me know if there's anything I can do otherwise to support in any way.

Cheers!

@airblade
Copy link
Owner

airblade commented Feb 7, 2025

I've never considered undoing part of a hunk.

Undoing a hunk is much easier than staging (part of) one because you don't need to calculate line number offsets or send anything to git.

This is the hunk-undo code:

function! s:undo(hunk_diff)
" Apply reverse patch to buffer.
let hunk = gitgutter#diff#parse_hunk(split(a:hunk_diff, '\n')[4])
let lines = map(split(a:hunk_diff, '\r\?\n')[5:], 'v:val[1:]')
let lnum = hunk[2]
let added_only = hunk[1] == 0 && hunk[3] > 0
let removed_only = hunk[1] > 0 && hunk[3] == 0
if removed_only
call append(lnum, lines)
elseif added_only
execute lnum .','. (lnum+len(lines)-1) .'d _'
else
call append(lnum-1, lines[0:hunk[1]])
execute (lnum+hunk[1]) .','. (lnum+hunk[1]+hunk[3]) .'d _'
endif
" Refresh gitgutter's view of buffer.
call gitgutter#process_buffer(bufnr(''), 1)
endfunction

It works with the hunk diff from git but one could change it to also support working with the contents of the hunk preview window. Perhaps the logic could be: if the cursor is in a buffer, use the diff from git; else if the cursor is in the preview window, use its contents. And that would allow you to edit the hunk diff however you wanted (it's up to the user to make sensible edits).

I don't have time now to work on this but generally speaking I'd be happy for it to be in gitgutter.

@ccjmne
Copy link
Author

ccjmne commented Feb 7, 2025

Excellent, thank you very much for your detailed response!

I'm frankly sheepish about wielding Vimscript, but... I suppose the one way to get past that hurdle is to just give it a go. I intend to look into it one of these days and see whether I can muster something adequate.

@airblade
Copy link
Owner

airblade commented Feb 7, 2025

Is it actually worth the time? Maybe it's easier and faster to just edit the hunk in the buffer by hand.

@ccjmne
Copy link
Author

ccjmne commented Feb 7, 2025

I found myself reaching for this functionality, but I cannot remember what the context was.
In any case, it's always worth my time; I like to try and figure things out for myself, even if it doesn't yield anything usable in the end ;)

I'll keep you posted here if there's any progress worth sharing, possibly including a "heh, you were right, it's not that interesting" if appropriate.
Cheers!

--
EDIT:
Actually, thinking about this already... because this extension allows you to quickly access in a preview window the version in the index, you can yank from there right away... as far as my succinct research indicated, other "in-place Git hunks indicators" plug-ins don't offer that.

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

No branches or pull requests

2 participants