Hi, I noticed one scenario where vim is not showing me the diff as I expect.
I have 2 files, a.txt and b.txt that for that test (I have seen it on "real" files" ) a.txt has 100 lines, each line with just a number. Looks like this 0 1 2 [...]
b.txt is same as on a, but I added a few lines at the top, all with just a -1. Looks like this -1 -1 -1 0 1 2 3 [...]
If I run gvim -d b.txt a.txt, things are as I expect: I see the added block of -1, few common lines, then the rest is folded.
But if I run gvim -d a.txt b.txt, I don't initially see the block of -1. The vertical scrollbar is all the way to the top (I can't scroll up), the first 6 lines are shown with no diff, the rest is folded. If I just scroll with the mouse while on window of file a, nothing happens. Same if gg on a. But if click on the window where b is, the scroll bar is not partly down, and I can scroll up (or gg) to the top of b and see the diff.
I guess it make sense: by default the active window is for a, and it is showing the top of a; but it forces me to click on b and scroll every time to make sure that I am not missing diffs. And I have forgotten a few times...
Am I the only one to see that? If not, would it be possible to have vim automatically scroll to show the top of the first diff block, regardless of which window it is in?
I am using gvim 7.3.646, on Windows XP. I have diffopt=filler. I have tried other settings, including horizontal diffing, but none helped for that particular issue.
> If I run gvim -d b.txt a.txt, things are as I expect: I see the
> added block of -1, few common lines, then the rest is folded.
> But if I run gvim -d a.txt b.txt, I don't initially see the block
> of -1. The vertical scrollbar is all the way to the top (I can't
> scroll up), the first 6 lines are shown with no diff, the rest is
> folded. If I just scroll with the mouse while on window of file
> a, nothing happens. Same if gg on a. But if click on the window
> where b is, the scroll bar is not partly down, and I can scroll
> up (or gg) to the top of b and see the diff.
> Am I the only one to see that?
I see it here (Vim7.2.445 on Linux, both vim and gvim) as well. I
also find it an unfortunate interface confusion.
> If not, would it be possible to have vim automatically scroll to
> show the top of the first diff block, regardless of which window
> it is in?
My first thought would be some autocmd or a manually-triggered
mapping, would ":windo if &diff | 0 | endif" to ensure that all diff
windows are at the top.
> My first thought would be some autocmd or a manually-triggered > mapping, would ":windo if &diff | 0 | endif" to ensure that all diff > windows are at the top.
Thanks for the idea! Based on your suggestion, this is how I launch the diff now: gvim.exe -d a.txt b.txt +"windo 0"
and things *seemed* to work, until I switch a and b: gvim.exe -d b.txt a.txt +"windo 0"
> Hi,
> I noticed one scenario where vim is not showing me the diff as I expect.
> I have 2 files, a.txt and b.txt that for that test (I have seen it on
> "real" files")
> a.txt has 100 lines, each line with just a number. Looks like this
> 0
> 1
> 2
> [...]
> b.txt is same as on a, but I added a few lines at the top, all with just
> a -1. Looks like this
> -1
> -1
> -1
> 0
> 1
> 2
> 3
> [...]
> If I run gvim -d b.txt a.txt, things are as I expect: I see the added
> block of -1, few common lines, then the rest is folded.
> But if I run gvim -d a.txt b.txt, I don't initially see the block of -1.
> The vertical scrollbar is all the way to the top (I can't scroll up),
> the first 6 lines are shown with no diff, the rest is folded. If I just
> scroll with the mouse while on window of file a, nothing happens. Same
> if gg on a. But if click on the window where b is, the scroll bar is not
> partly down, and I can scroll up (or gg) to the top of b and see the diff.
> I guess it make sense: by default the active window is for a, and it is
> showing the top of a; but it forces me to click on b and scroll every
> time to make sure that I am not missing diffs. And I have forgotten a
> few times...
> Am I the only one to see that? If not, would it be possible to have vim
> automatically scroll to show the top of the first diff block, regardless
> of which window it is in?
> I am using gvim 7.3.646, on Windows XP. I have diffopt=filler. I have
> tried other settings, including horizontal diffing, but none helped for
> that particular issue.
In each of the edited files these options are set:
'diff' on
'scrollbind' on
'cursorbind' on
'scrollopt' includes "hor"
'wrap' off
'foldmethod' "diff"
'foldcolumn' value from 'diffopt', default is 2
These options are set local to the window. When editing another file they are
reset to the global value.
:help 'scrollbind'
[...]
See also |scroll-binding|. When this option is set, the current
window scrolls as other scrollbind windows (windows that also have
this option set) scroll. This option is useful for viewing the
differences between two versions of a file, see 'diff'.
[...]
Occasionally, it is desirable to bind two or more windows together such that
when one window is scrolled, the other windows are also scrolled. In Vim,
windows can be given this behavior by setting the (window-specific)
'scrollbind' option. When a window that has 'scrollbind' set is scrolled, all
other 'scrollbind' windows are scrolled the same amount, if possible. The
behavior of 'scrollbind' can be modified by the 'scrollopt' option.
When using the scrollbars, the binding only happens when scrolling the window
with focus (where the cursor is). You can use this to avoid scroll-binding
for a moment without resetting options.
When a window also has the 'diff' option set, the scroll-binding uses the
differences between the two buffers to synchronize the position precisely.
Otherwise the following method is used.
*scrollbind-relative*
Each 'scrollbind' window keeps track of its "relative offset," which can be
thought of as the difference between the current window's vertical scroll
position and the other window's vertical scroll position. When one of the
'scrollbind' windows is asked to vertically scroll past the beginning or end
limit of its text, the window no longer scrolls, but remembers how far past
the limit it wishes to be. The window keeps this information so that it can
maintain the same relative offset, regardless of its being asked to scroll
past its buffer's limits.
However, if a 'scrollbind' window that has a relative offset that is past its
buffer's limits is given the cursor focus, the other 'scrollbind' windows must
jump to a location where the current window's relative offset is valid. This
behavior can be changed by clearing the 'jump' flag from the 'scrollopt'
option.
Best regards,
Tony.
-- Great minds run in great circles.
Thank you, I had looked at the help, and tried to play with sbo and diffopt, but no success. I also tried to have both right and left scrollbars (using go+=rl) but again, no success. I tried those setting from the command line, e.g.
gvim -d b.txt a.txt +"set go+=rl | windo 0"
but I have not found a solution...
Did you see something specific in the help that I missed (BTW, I am not sure I fully understand the help...)
Thanks
Christophe
> Thank you, I had looked at the help, and tried to play with sbo and diffopt, but no success. I also tried to have both right and left scrollbars (using go+=rl) but again, no success. I tried those setting from the command line, e.g.
> gvim -d b.txt a.txt +"set go+=rl | windo 0"
> but I have not found a solution...
> Did you see something specific in the help that I missed (BTW, I am not sure I fully understand the help...)
> Thanks
> Christophe
Diff mode sets 'scrollbind', which in turn makes both windows scroll together; however, you cannot scroll a window farther up than line 1.
By keyboard or mouse wheel (except by using the mouse wheel with the mouse pointer on a scrollbar), you can scroll only the current window. If its first line corresponds diff-wise to some line other than the first in the other window, you cannot scroll the other window all the way up that way.
There are two ways to scroll the other window farther up than the current window's first line:
(a) Give it focus (by clicking in it, or by Ctrl-W w, etc.);
(b) Scroll it by its scrollbar. However, I haven't checked how this works in diff mode.
Of course, there are only at most two scrollbars: if there are three or more vertically split windows, only two of them (including the current window) will have a scrollbar. If there are exactly three, the middle one won't have a scrollbar unless it is current, in which case you may have to experiment to see which side scrollbar corresponds to it.
To have both left and right scrollbars in gvim whenever there are vertically split windows, make sure that 'guioptions' includes one of the following (in any order):
lr always have scrollbars on both sides
lR scrollbar always on the left, also on the right when split
Lr scrollbar always on the right, also on the left when split
The default includes rL which is the latter case. I use
set go=gimrLTtc
which differs from the GTK default as follows (YMMV):
no a don't use autoselect
no e use a text-style tab bar, even in the GUI
c use console dialogs for simple choices
If you want to keep the existing 'guioptions' settings and add rl to them, you should use
set go-=R go-=L go-=r go-=l go+=rl
Flags must be removed one by one because they can be in any order or even some of them may be absent; using :set go-=RL go+=rl would only remove RL if present next to each order in that sequence, and it would add rl at the end even if either or both of them were already present. (There is no error if you try to remove a flag that isn't there.)
And finally, if your vimrc invokes the vimrc_example.vim, you should place your :set go=something command after coming back from the vimrc_example.vim; or if your vimrc is a modified version of the vimrc_example.vim, search for /guio/ and place your changes just after that.
If I shot beside the mark, then please explain better; maybe I hadn't drunk enough black tea.
Best regards,
Tony.
-- ARTHUR: Be quiet!
DENNIS: --but by a two-thirds majority in the case of more--
ARTHUR: Be quiet! I order you to be quiet!
WOMAN: Order, eh -- who does he think he is?
ARTHUR: I am your king!
The Quest for the Holy Grail (Monty Python)
> If I shot beside the mark, then please explain better; maybe I hadn't > drunk enough black tea. > Best regards,
> Tony.
Thank you Tony, I appreciate your time giving me all those details. I will try a couple more things (I might have misused set go+=/set go-=).
But with my original settings, and others I tried (including left and right scroll bars) , I can always see the diff, but *not* initially: I have to click and scroll, and that's too much intervention, too easy to forget.
Background: I have been using gvim as my diff viewer for tortoise svn. It works great, except that recently I committed unwanted changes (at the top of a file) because I forgot to click on the correct window and scroll. The diff initially displays like there is no line added at the top of the file (and I did not expect any either).
I would like vim to automatically scroll to the "highest" of the 2 files (either by code change, auto command, script, whatever...).
I was really happy about using gvim -d file1 file2 +"windo 0" but it only works when file1 has more lines (or maybe the reverse, I forgot). I want a reliable way to start my diff.
I'm fairly sure this can be explained with the current mechanisms in vim, but it does not give me the behavior that I would like.
I'll try looking at which vim functions are available and see if this could be done with a script (focus on the windows where the first added block is and scroll to the top of that window?).
> > My first thought would be some autocmd or a manually-triggered
> > mapping, would ":windo if &diff | 0 | endif" to ensure that all
> > diff windows are at the top.
> Thanks for the idea! Based on your suggestion, this is how I
> launch the diff now:
> gvim.exe -d a.txt b.txt +"windo 0"
> and things *seemed* to work, until I switch a and b:
> gvim.exe -d b.txt a.txt +"windo 0"
> and I run in the same issue...
I thought I had a solution. If I start vim like this,
then I get the desired display of the top of b.txt with a.txt and
b.txt in either order. However, I've been unable to find an
autocommand that will do the same thing. I have tried
au BufWinEnter * exe "normal 9999\<C-Y>"
and
au FilterWritePost * exe "normal 9999\<C-Y>"
without success.
":help -c" says,
-c {command} {command} will be executed after the first file
has been read (and after autocommands and
modelines for that file have been processed).
...
so it is apparently important to wait until late in the startup
sequence before scrolling, but I don't know why a "late" autocommand
event such as BufWinEnter or FilterWritePost wouldn't be late
enough.
>> If I shot beside the mark, then please explain better; maybe I hadn't
>> drunk enough black tea.
>> Best regards,
>> Tony.
> Thank you Tony, I appreciate your time giving me all those details. I will try a couple more things (I might have misused set go+=/set go-=).
> But with my original settings, and others I tried (including left and right scroll bars) , I can always see the diff, but *not* initially: I have to click and scroll, and that's too much intervention, too easy to forget.
> Background: I have been using gvim as my diff viewer for tortoise svn. It works great, except that recently I committed unwanted changes (at the top of a file) because I forgot to click on the correct window and scroll. The diff initially displays like there is no line added at the top of the file (and I did not expect any either).
> I would like vim to automatically scroll to the "highest" of the 2 files (either by code change, auto command, script, whatever...).
> I was really happy about using gvim -d file1 file2 +"windo 0" but it only works when file1 has more lines (or maybe the reverse, I forgot). I want a reliable way to start my diff.
> I'm fairly sure this can be explained with the current mechanisms in vim, but it does not give me the behavior that I would like.
> I'll try looking at which vim functions are available and see if this could be done with a script (focus on the windows where the first added block is and scroll to the top of that window?).
> Thanks again,
> Christophe
Try loading the two files without the diff mode:
gvim -O2 "+windo 1" file1.txt file2.txt
This will display both files side by side and both scrolled to the top. (in -O2 the O is a capital letter O, not a zero, to split vertically.) Then you can do
:windo diffthis
if you want to set diff mode in all (i.e. both) files currently being viewed. You can of course reduce the number of keystrokes by assigning this to a key:
:map <F4> :windo diffthis<CR>
Similarly, you can create a command to invoke gvim as above as if it were a simple command:
-Windows- gvimnodiff.bat (in some directory in the %PATH%)
"C:\Program Files\vim\gvim.exe" -O2 "+windo 1" %1 %2
On Wed, September 5, 2012 19:29, chro...@comcast.net wrote:
> Hi,
> I noticed one scenario where vim is not showing me the diff as I expect.
> I have 2 files, a.txt and b.txt that for that test (I have seen it on
> "real" files" )
> a.txt has 100 lines, each line with just a number. Looks like this
> 0
> 1
> 2
> [...]
> b.txt is same as on a, but I added a few lines at the top, all with just a
> -1. Looks like this
> -1
> -1
> -1
> 0
> 1
> 2
> 3
> [...]
> If I run gvim -d b.txt a.txt, things are as I expect: I see the added
> block of -1, few common lines, then the rest is folded.
> But if I run gvim -d a.txt b.txt, I don't initially see the block of -1.
> The vertical scrollbar is all the way to the top (I can't scroll up), the
> first 6 lines are shown with no diff, the rest is folded. If I just scroll
> with the mouse while on window of file a, nothing happens. Same if gg on
> a. But if click on the window where b is, the scroll bar is not partly
> down, and I can scroll up (or gg) to the top of b and see the diff.
> I guess it make sense: by default the active window is for a, and it is
> showing the top of a; but it forces me to click on b and scroll every time
> to make sure that I am not missing diffs. And I have forgotten a few
> times...
> Am I the only one to see that? If not, would it be possible to have vim
> automatically scroll to show the top of the first diff block, regardless
> of which window it is in?
> I am using gvim 7.3.646, on Windows XP. I have diffopt=filler. I have
> tried other settings, including horizontal diffing, but none helped for
> that particular issue.
> I searched around, but no success, sorry.
I also have noticed this behaviour and found it quite disturbing.
I don't think, every user needs to mess with autocommands to find a
solution that works for him, but rather Vim should make it right. So
here is a patch:
diff --git a/src/diff.c b/src/diff.c
--- a/src/diff.c
+++ b/src/diff.c
@@ -622,6 +622,9 @@
wp->w_topfill = (n < 0 ? 0 : n);
}
}
+
+ /* Make sure, filler lines on top are correctly displayed */
+ check_scrollbind((linenr_T)0, 0L);
}
/*
@@ -1861,10 +1864,6 @@
diff_redraw(TRUE);
- /* recompute the scroll binding with the new option value, may
- * remove or add filler lines */
- check_scrollbind((linenr_T)0, 0L);
-
return OK;
}
> I don't think, every user needs to mess with autocommands to find a
> solution that works for him, but rather Vim should make it right. So
Thank You! I completely agree! (Vim is already doing just about anything else right!)
> here is a patch: [...] > Christian
Thank you, I tried your patch, and I think it only works when I call gvim -d a.txt b.txt
If I switch a and b, I have the same issue... gvim -d b.txt a.txt
In the meantime (as I still prefer a patch), this seems to be working when calling from the command line: gvim -d b.txt a.txt +"if diff_filler(1) | winc w |endif | 0"
in my case, I only compare 2 files, so I check if the file in the current window as filler lines above line 1; if so, I move to the other window. Then, in the active window after that, I go to the top of the file.
> In the meantime (as I still prefer a patch), this seems to be working when calling from the command line: > gvim -d b.txt a.txt +"if diff_filler(1) | winc w |endif | 0"
FYI, I am now using an auto command instead so that it does not matter how I call the diff (on Windows, I also wanted this to behave properly when using gvimext "diff with vim". Here is what I have in my _vimrc until something better comes up; au VimEnter * if &diff && diff_filler(1) | winc w | endif | 0
> I tried your patch, and I think it only works when I call
> gvim -d a.txt b.txt
> If I switch a and b, I have the same issue...
> gvim -d b.txt a.txt
Could you please check the updated patch?
regards,
Christian
-- Physiker:
Das At wurde ja auch abgeschafft, jetzt soll man nur noch das Bar
verwenden. Seither macht die Feuerwehr "Tbartata Tbartata."
Christian Brabandt wrote:
> here is an updated patch, including a test. I have tested it against all > issues mentioned in this thread and it works so far.