Skip to content

Commit 025e3e0

Browse files
committed
patch 8.0.0044
Problem: In diff mode the cursor may end up below the last line, resulting in an ml_get error. Solution: Check the line to be valid.
1 parent 9ec7fa8 commit 025e3e0

File tree

5 files changed

+54
-36
lines changed

5 files changed

+54
-36
lines changed

src/diff.c

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,10 +1100,7 @@ ex_diffsplit(exarg_T *eap)
11001100
if (bufref_valid(&old_curbuf))
11011101
/* Move the cursor position to that of the old window. */
11021102
curwin->w_cursor.lnum = diff_get_corresponding_line(
1103-
old_curbuf.br_buf,
1104-
old_curwin->w_cursor.lnum,
1105-
curbuf,
1106-
curwin->w_cursor.lnum);
1103+
old_curbuf.br_buf, old_curwin->w_cursor.lnum);
11071104
}
11081105
/* Now that lines are folded scroll to show the cursor at the same
11091106
* relative position. */
@@ -2524,21 +2521,22 @@ diff_move_to(int dir, long count)
25242521
return OK;
25252522
}
25262523

2527-
linenr_T
2528-
diff_get_corresponding_line(
2524+
/*
2525+
* Return the line number in the current window that is closest to "lnum1" in
2526+
* "buf1" in diff mode.
2527+
*/
2528+
static linenr_T
2529+
diff_get_corresponding_line_int(
25292530
buf_T *buf1,
2530-
linenr_T lnum1,
2531-
buf_T *buf2,
2532-
linenr_T lnum3)
2531+
linenr_T lnum1)
25332532
{
25342533
int idx1;
25352534
int idx2;
25362535
diff_T *dp;
25372536
int baseline = 0;
2538-
linenr_T lnum2;
25392537

25402538
idx1 = diff_buf_idx(buf1);
2541-
idx2 = diff_buf_idx(buf2);
2539+
idx2 = diff_buf_idx(curbuf);
25422540
if (idx1 == DB_COUNT || idx2 == DB_COUNT || curtab->tp_first_diff == NULL)
25432541
return lnum1;
25442542

@@ -2551,15 +2549,8 @@ diff_get_corresponding_line(
25512549
for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next)
25522550
{
25532551
if (dp->df_lnum[idx1] > lnum1)
2554-
{
2555-
lnum2 = lnum1 - baseline;
2556-
/* don't end up past the end of the file */
2557-
if (lnum2 > buf2->b_ml.ml_line_count)
2558-
lnum2 = buf2->b_ml.ml_line_count;
2559-
2560-
return lnum2;
2561-
}
2562-
else if ((dp->df_lnum[idx1] + dp->df_count[idx1]) > lnum1)
2552+
return lnum1 - baseline;
2553+
if ((dp->df_lnum[idx1] + dp->df_count[idx1]) > lnum1)
25632554
{
25642555
/* Inside the diffblock */
25652556
baseline = lnum1 - dp->df_lnum[idx1];
@@ -2568,29 +2559,40 @@ diff_get_corresponding_line(
25682559

25692560
return dp->df_lnum[idx2] + baseline;
25702561
}
2571-
else if ( (dp->df_lnum[idx1] == lnum1)
2572-
&& (dp->df_count[idx1] == 0)
2573-
&& (dp->df_lnum[idx2] <= lnum3)
2574-
&& ((dp->df_lnum[idx2] + dp->df_count[idx2]) > lnum3))
2562+
if ( (dp->df_lnum[idx1] == lnum1)
2563+
&& (dp->df_count[idx1] == 0)
2564+
&& (dp->df_lnum[idx2] <= curwin->w_cursor.lnum)
2565+
&& ((dp->df_lnum[idx2] + dp->df_count[idx2])
2566+
> curwin->w_cursor.lnum))
25752567
/*
25762568
* Special case: if the cursor is just after a zero-count
25772569
* block (i.e. all filler) and the target cursor is already
25782570
* inside the corresponding block, leave the target cursor
25792571
* unmoved. This makes repeated CTRL-W W operations work
25802572
* as expected.
25812573
*/
2582-
return lnum3;
2574+
return curwin->w_cursor.lnum;
25832575
baseline = (dp->df_lnum[idx1] + dp->df_count[idx1])
25842576
- (dp->df_lnum[idx2] + dp->df_count[idx2]);
25852577
}
25862578

25872579
/* If we get here then the cursor is after the last diff */
2588-
lnum2 = lnum1 - baseline;
2589-
/* don't end up past the end of the file */
2590-
if (lnum2 > buf2->b_ml.ml_line_count)
2591-
lnum2 = buf2->b_ml.ml_line_count;
2580+
return lnum1 - baseline;
2581+
}
25922582

2593-
return lnum2;
2583+
/*
2584+
* Return the line number in the current window that is closest to "lnum1" in
2585+
* "buf1" in diff mode. Checks the line number to be valid.
2586+
*/
2587+
linenr_T
2588+
diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1)
2589+
{
2590+
linenr_T lnum = diff_get_corresponding_line_int(buf1, lnum1);
2591+
2592+
/* don't end up past the end of the file */
2593+
if (lnum > curbuf->b_ml.ml_line_count)
2594+
return curbuf->b_ml.ml_line_count;
2595+
return lnum;
25942596
}
25952597

25962598
#if defined(FEAT_FOLDING) || defined(PROTO)

src/move.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2824,11 +2824,8 @@ do_check_cursorbind(void)
28242824
{
28252825
# ifdef FEAT_DIFF
28262826
if (curwin->w_p_diff)
2827-
curwin->w_cursor.lnum
2828-
= diff_get_corresponding_line(old_curbuf,
2829-
line,
2830-
curbuf,
2831-
curwin->w_cursor.lnum);
2827+
curwin->w_cursor.lnum =
2828+
diff_get_corresponding_line(old_curbuf, line);
28322829
else
28332830
# endif
28342831
curwin->w_cursor.lnum = line;

src/proto/diff.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ void nv_diffgetput(int put, long count);
2222
void ex_diffgetput(exarg_T *eap);
2323
int diff_mode_buf(buf_T *buf);
2424
int diff_move_to(int dir, long count);
25-
linenr_T diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1, buf_T *buf2, linenr_T lnum3);
25+
linenr_T diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1);
2626
linenr_T diff_lnum_win(linenr_T lnum, win_T *wp);
2727
/* vim: set ft=c : */

src/testdir/test_diffmode.vim

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,3 +218,20 @@ func Test_diffoff()
218218
bwipe!
219219
bwipe!
220220
endfunc
221+
222+
func Test_setting_cursor()
223+
new Xtest1
224+
put =range(1,90)
225+
wq
226+
new Xtest2
227+
put =range(1,100)
228+
wq
229+
230+
tabe Xtest2
231+
$
232+
diffsp Xtest1
233+
tabclose
234+
235+
call delete('Xtest1')
236+
call delete('Xtest2')
237+
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,8 @@ static char *(features[]) =
764764

765765
static int included_patches[] =
766766
{ /* Add new patch number below this line */
767+
/**/
768+
44,
767769
/**/
768770
43,
769771
/**/

0 commit comments

Comments
 (0)