When doing diffs it often occurs to me the diff output could be
more readable if it showed the actual changes within lines.
Something like this (I mean the concept, the actual implemenation shown
may not be the best output which can be achieved), so you don't have to
search for the changes within the line:
It doesn't even necessarily need support from the external diff tool,
because diffs are usually not huge, so the highlighting of the changes
could be done in lisp by parsing the diff output.
Has anyone tried improving diff like this? Is there a package which does this?
> > Has anyone tried improving diff like this? Is there a package > > which does this?
> ediff
> E.g. `M-x ediff-buffers'
Okay, but I mean output from git/mercurial/etc. when I get
a file history from emacs, or diff between versions, etc.
These commands invoke diff, and I like the single buffer diff
output, I don't need ediff showing diffs in two windows, etc.
that's why I think improving the regular diff output could be useful.
Tom <adatgyu...@gmail.com> writes:
> When doing diffs it often occurs to me the diff output could be
> more readable if it showed the actual changes within lines.
> Something like this (I mean the concept, the actual implemenation shown
> may not be the best output which can be achieved), so you don't have to
> search for the changes within the line:
> It doesn't even necessarily need support from the external diff tool,
> because diffs are usually not huge, so the highlighting of the changes
> could be done in lisp by parsing the diff output.
> Has anyone tried improving diff like this? Is there a package which does > this?
> -----Original Message-----
> From: help-gnu-emacs-bounces+dougl=shubertticketing....@gnu.org
> [mailto:help-gnu-emacs-bounces+dougl=shubertticketing....@gnu.org] On
> Behalf Of Drew Adams
> Sent: Friday, 2012 October 05 10:40
> To: 'Tom'; help-gnu-em...@gnu.org
> Subject: RE: Diff could also show the changes within lines
> > Has anyone tried improving diff like this? Is there a package
> > which does this?
Turns out it only refines one hunk (the current) and the others only
if you use hunk navigation commands (diff-auto-refine-mode does this which is on by default in Emacs 24). So to refine all hunks automatically,
do this in the diff hook:
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:
> > Looks like it does not work with DVC diff, so it needs to be disabled for
> > that:
> If you describe the problem, maybe it can be fixed instead.
It seems dvc-diff calls the diff hooks early, when the diff
buffer is still empty (I guess it's because it starts an external async
process to get the diff ouput), so diff refine cannot find the diff
headers in the buffer.
Tom wrote:
> Tom <adatgyujto <at> gmail.com> writes:
>> (diff-auto-refine-mode 1)
> Turns out it only refines one hunk (the current) and the others only if you
> use hunk navigation commands (diff-auto-refine-mode does this which is on by
> default in Emacs 24). So to refine all hunks automatically, do this in the
> diff hook:
It works well for me, it highlights the changes in all hunks
automatically. I use it only for diffing before checkin.
But. It works only because the VC mercurial implementation calls
the backend synchronously. In case of DVC it doesn't work for
me, because DVC calls the backend asynchronously, so when the diff
hook is run the output is not there yet and I did not find a hook
which is called when the async diff command is finished
You may want to check how the diff output is produced in your use
cases. If it is done asynchronously then the diff hook is not a suitable place to call the highlighting code from.
> I found that with code (more precisely 'diff-refine-hunk') hung up Emacs on
> large chunks (10-20 KiB).
> So I just use "C-c C-b" instead when I need refine-hunk.
I should have added that I have an additional check in my
diff hook, which calls the automatic highlighting of hunks
only if the diff is below a certain size, so I have
automatic highlighting for the majority of my diffs which
are small and for the big ones I toggle the highlight manually
if needed.
> It works well for me, it highlights the changes in all hunks automatically.
> I use it only for diffing before checkin.
> But. It works only because the VC mercurial implementation calls the backend
> synchronously. In case of DVC it doesn't work for me, because DVC calls the
> backend asynchronously, so when the diff hook is run the output is not there
> yet and I did not find a hook which is called when the async diff command is
> finished
> You may want to check how the diff output is produced in your use cases. If
> it is done asynchronously then the diff hook is not a suitable place to call
> the highlighting code from.
I'm not sure how to check for that, but I could reduce all my `.emacs' file to
an example file which shows the problem on the current development snapshot of
the future Emacs 24.3 (from 2012-10-22):
The last two lines show that if diff-auto-refine-mode is t
(which is by default) then it should do the highlighting.
If it doesn't the you may want to ask the emacs developers about it.
> The last two lines show that if diff-auto-refine-mode is t (which is by
> default) then it should do the highlighting. If it doesn't the you may want
> to ask the emacs developers about it.
The variable diff-auto-refine-mode is as well t on my side. But... that does
not help.
BTW, how do you explain that your cursor is not at the end of the buffer, in
your case, after the refine process?
> Going to the beginning of the diff buffer and hitting TAB, does indeed moves
> over every hunk, in turn, and refines the differences at the same time.
My function does the same, so I can't explain why it
does not work for you when you call it from M-x.
I guess you also use Emacs 24, so it's not about an old emacs version
behaving differently.
> BTW, how do you explain that your cursor is not at the end of the buffer, in
> your case, after the refine process?
I use save-excursion in the function which puts the cursor back to where it was before the function was called.
I don't know why it is at the end of the buffer for you. There are
some emacs gurus on this list. Hopefully some of them will chime in and helps you to solve this mistery, because I'm out of ideas.
Tom wrote:
> Sebastien Vauban <wxhgmqzgwmuf@...> writes:
>> Going to the beginning of the diff buffer and hitting TAB, does indeed
>> moves over every hunk, in turn, and refines the differences at the same
>> time.
> My function does the same, so I can't explain why it does not work for you
> when you call it from M-x.
That's very weird, indeed.
> I guess you also use Emacs 24, so it's not about an old emacs version
> behaving differently.
Yep, sort of future Emacs 24.3, that is:
GNU Emacs 24.2.50.1 (i386-mingw-nt5.1.2600) of 2012-10-22 on DANI-PC
>> BTW, how do you explain that your cursor is not at the end of the buffer,
>> in your case, after the refine process?
> I use save-excursion in the function which puts the cursor back to where it
> was before the function was called.
I had overlooked it. Of course.
> I don't know why it is at the end of the buffer for you. There are some
> emacs gurus on this list. Hopefully some of them will chime in and helps you
> to solve this mistery, because I'm out of ideas.
Thanks for your help so far...
Last thing: can you post your complete chunk of code regarding this? I mean
with your additional check which calls the automatic highlighting of hunks
only if the diff is below a certain size? Thanks a lot...
> Last thing: can you post your complete chunk of code regarding this? I mean
> with your additional check which calls the automatic highlighting of hunks
> only if the diff is below a certain size? Thanks a lot...
It's quite straightforward:
(add-hook 'diff-mode-hook 'my-diff-stuff)
(defun my-diff-stuff ()
(unless (or (eq this-command 'dvc-diff) ; does not work with DVC
(eq this-command 'dvc-generic-refresh)
(> (buffer-size) 20000))
(my-refine-all-diff-hunks)))
Tom wrote:
> Sebastien Vauban <wxhgmqzgwmuf@...> writes:
>> Last thing: can you post your complete chunk of code regarding this? I mean
>> with your additional check which calls the automatic highlighting of hunks
>> only if the diff is below a certain size? Thanks a lot...
> It's quite straightforward:
> (add-hook 'diff-mode-hook 'my-diff-stuff)
> (defun my-diff-stuff ()
> (unless (or (eq this-command 'dvc-diff) ; does not work with DVC
> (eq this-command 'dvc-generic-refresh)
> (> (buffer-size) 20000))
> (my-refine-all-diff-hunks)))
That explains it. I'm on Emacs 24.1 and it does not have this
scheduling code, so that's why it works for me. I didn't think
they changed this recently.
Anyway, you can try calling diff-refine-hunk explicitly after
diff-hunk-next then:
> That explains it. I'm on Emacs 24.1 and it does not have this
> scheduling code, so that's why it works for me. I didn't think
> they changed this recently.
> Anyway, you can try calling diff-refine-hunk explicitly after
> diff-hunk-next then:
> I can't try it, because I use 24.1, but it may work.
I wasn't sure how to adapt the code. Thanks for trying...
And the results of the jury are:
- it works for the refining of *all* hunks
- it does not work wrt the position of the cursor, that is it's at the end of
the buffer...