Comments (8)
Hi!
I haven't been able to reproduce this exactly yet.
Does the committed state of the file contain the trailing newline?
When yes, the scenario works without issue.
When no (without trailing newline), I see the error right away: (Canβt find the beginning of the hunk)
, before the diff buffer is even shown.
Generally the absence of trailing newline is not a great idea for coding files, but we can support it here. I've pushed a patch that makes it work to master just now. Does it help in your scenario too?
from diff-hl.
Thanks for the quick response! I've pulled the latest changes but unfortunately they don't solve my issue.
Yes, both the commited and unstaged versions of the files have a trailing newline. I have require-final-newline
set to t
which enforces this on save, and this issue would occur in the middle of source files with 100s of LOC with the hunks nowhere close to the end of the file.
After some more digging I found that the error is caused by the default diff-hl-highlight-revert-hunk-function
narrowing the buffer and cutting off the hunk header. As a workaround, setting the variable to ignore
or manually performing M-x widen
before answering the prompt solves the issue.
Maybe the bug is an off-by-one error in diff-hl-split-away-changes
placing the point on the wrong line?
Another minimal repro with more context lines around the changes:
a
b
c
d
foo
bar
baz
w
x
y
z
After changing the foo and baz lines, I get the same error when attempting to revert the lower hunk, and see the same lack of header in the popup buffer.
Contents of the full widened *diff-hl*
buffer:
diff --git a/src/repro.txt b/src/repro.txt
index 7121797..7d1d16b 100644
--- a/src/repro.txt
+++ b/src/repro.txt
@@ -2,4 +2,4 @@ a
b
c
d
-foo
+foo*
@@ -6,5 +6,5 @@
bar
-baz
+baz*
w
x
y
I find it strange that we are parsing the diff output and manually splitting hunks, instead of calling diff
with the appropriate switches in the first place, or using a single source of truth for both the fringe highlights and applying changes. Running git diff -U0 repro.txt
in my terminal gives the expected output with 2 separate hunks.
from diff-hl.
After some more digging I found that the error is caused by the default diff-hl-highlight-revert-hunk-function narrowing the buffer and cutting off the hunk header. As a workaround, setting the variable to ignore or manually performing M-x widen before answering the prompt solves the issue.
Thanks! I reproduced it now. It was my fault: I have the variable customized to the other available value (diff-hl-revert-highlight-first-column
), which was the default before 2021.
Using widen
is not a workaround, it's the proper fix (another option would be to use save-restriction
), try this:
diff --git a/diff-hl.el b/diff-hl.el
index ce1f1ca..9960a51 100644
--- a/diff-hl.el
+++ b/diff-hl.el
@@ -609,6 +609,7 @@ in the source file, or the last line of the hunk above it."
(unless (yes-or-no-p (format "Revert current hunk in %s? "
file))
(user-error "Revert canceled")))
+ (widen)
(let ((diff-advance-after-apply-hunk nil))
(save-window-excursion
(diff-apply-hunk t)))
I find it strange that we are parsing the diff output and manually splitting hunks, instead of calling diff with the appropriate switches in the first place,
or using a single source of truth for both the fringe highlights and applying changes.
The splitting routine is fine (at least since the last commit), and we're using it to indeed have the fringe highlights and reverting changes use the same source of info. Calling the diff program one more time could have its own difficulties too, and note that it won't save us from having to find the bounds of the current hunk, to narrow to it, or to apply just that hunk.
There is another difference: using diff -U3
would coagulate hunks, but we do want to show some context around the minimal hunk when possible (when the other hunks are far away enough). There is no option for diff
that would do that.
from diff-hl.
I've pushed the change now. Let me know if something is still amiss.
from diff-hl.
Thanks! I can confirm the fix works, although there's still a minor inconsistency that the narrowed buffer does not show the hunk header, due to the off-by-one in the split-away-changes function.
The splitting routine is fine (at least since the last commit), and we're using it to indeed have the fringe highlights and reverting changes use the same source of info. Calling the diff program one more time could have its own difficulties too, and note that it won't save us from having to find the bounds of the current hunk, to narrow to it, or to apply just that hunk.
Unless I'm misunderstanding somethng, I stepped through the codebase and it looks like the fringes are updated using (diff-hl-changes)
, which calls either
diff-hl-changes-buffer
->diff-hl-diff-against-reference
on*diff-hl*
buffer, wrapped withdiff-hl-with-diff-switches
- or the overriden
diff-hl-flydiff-changes-buffer
->diff-hl-diff-buffer-with-reference
on*diff-hl-diff*
buffer
Whereas diff-hl-revert-hunk-1
generates a new temporary buffer and calls diff-hl-diff-against-reference
on it (without the -diff-switches macro) and displays it as a popup, then using it to actually apply the changes.
I don't completely understand the distinction between against-reference
and with-reference
, but clearly there's two different calls to the diff program happening.
If my cursor is on a line with a fringe highlight derived from the *diff-hl*
buffer, it shouldn't have to 're-derive' the current hunk, based on another call to diff with additional context lines and using parsing logic to 'split away' the hunk. That seems very unintuitive, even if the logic is sound 100% of the time. I shouldn't have to second-guess and check the popup buffer to verify if the hunk being reverted is indeed the one indicated by the fringe highlight. Hope that makes sense!
from diff-hl.
More generally, I don't know if displaying of context lines in the popup buffer is worth all this additional complexity? After all the user already has the full context in the original buffer that they are working from. By definition diff-hl-revert-hunk
is being called with the cursor in the midst of this context.
If I care about the wider context relative to other hunks in the buffer, I would use something like magit-status-here
which affords a much better UI to view and apply complex changes - I'm sure vc-diff has something similar.
from diff-hl.
You are right, the naming is a bit confusing here. diff-hl-diff-against-reference
and diff-hl-diff-buffer-with-reference
do almost the same thing, except one of them can do it a little faster because it doesn't need to deal with buffer contents not synchronized to disk (which is the flydiff situation).
diff-hl-revert-hunk-1
mostly does things its own way to copy the UI of vc-revert
, with its own alteration. It still calls diff-hl-diff-against-reference
, though.
You are right that we could possibly store the hunks inside the overlays to avoid re-retching them more often. That wouldn't avoid having the two aforementioned functions, though (unless we just decide to use the slower-but-more-flexible one).
Regarding additional context, I do think it both looks nicer and a little more useful. But also keep in mind that diff-hl-highlight-revert-hunk-function
is customizable and the other setting shows the full diff (with particular section highlighted in the first column). So we need a way to restore the full diff buffer anyway.
from diff-hl.
although there's still a minor inconsistency that the narrowed buffer does not show the hunk header, due to the off-by-one in the split-away-changes function
This is hopefully fixed now.
from diff-hl.
Related Issues (20)
- diff-hl-show-hunk-next tell "There is no next change", but, `diff-hl-next-hunk` can jump to it. HOT 3
- Feature Request: Support diff-buffer-with-file HOT 4
- Same hotkey binding to both next/revert when navigating use diff-hl-show-hunk HOT 4
- Startup dependency issue HOT 2
- Error on startup HOT 12
- Fringe indicator disappears when editing until buffer is saved, and `diff-hl-flydiff-mode` does not seem to work on Windows HOT 10
- Activate diff-hl-mode in file buffers using `project.el` HOT 8
- Will flydiff work after committing changes from terminal? HOT 4
- default theme? HOT 2
- when trying to compile the lastest commit the test fails HOT 10
- Is there a way to prevent diff-hl send the run git command log into *messages*? HOT 2
- question: diff-hl-margin-local-mode HOT 1
- Feature request: stage region HOT 23
- Improve Cross-Platform: Using absolute path to describe `patchfile`. HOT 15
- Feature request: provide more flexibility to set additional settings in vc-git-diff-switches HOT 4
- (un)staging changes in magit does not update file buffer fringe in `diff-hl-flydiff-mode` HOT 2
- diff-hl-flydiff-mode adds a new idle timer even if it already exists HOT 1
- diff-hl-dired-mode inside docker HOT 2
- `diff-hl-after-revert` is completely broken HOT 12
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from diff-hl.