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.
Files: src/move.c, src/diff.c, src/proto/diff.pro,
src/testdir/test_diffmode.vim
*** ../vim-8.0.0043/src/move.c 2016-09-04 14:29:37.000000000 +0200
--- src/move.c 2016-10-18 14:28:15.793415019 +0200
***************
*** 2824,2834 ****
{
# ifdef FEAT_DIFF
if (curwin->w_p_diff)
! curwin->w_cursor.lnum
! = diff_get_corresponding_line(old_curbuf,
! line,
! curbuf,
! curwin->w_cursor.lnum);
else
# endif
curwin->w_cursor.lnum = line;
--- 2824,2831 ----
{
# ifdef FEAT_DIFF
if (curwin->w_p_diff)
! curwin->w_cursor.lnum =
! diff_get_corresponding_line(old_curbuf, line);
else
# endif
curwin->w_cursor.lnum = line;
*** ../vim-8.0.0043/src/diff.c 2016-08-29 22:42:20.000000000 +0200
--- src/diff.c 2016-10-18 14:48:59.700247046 +0200
***************
*** 1100,1109 ****
if (bufref_valid(&old_curbuf))
/* Move the cursor position to that of the old window. */
curwin->w_cursor.lnum = diff_get_corresponding_line(
! old_curbuf.br_buf,
! old_curwin->w_cursor.lnum,
! curbuf,
! curwin->w_cursor.lnum);
}
/* Now that lines are folded scroll to show the cursor at the same
* relative position. */
--- 1100,1106 ----
if (bufref_valid(&old_curbuf))
/* Move the cursor position to that of the old window. */
curwin->w_cursor.lnum = diff_get_corresponding_line(
! old_curbuf.br_buf, old_curwin->w_cursor.lnum);
}
/* Now that lines are folded scroll to show the cursor at the same
* relative position. */
***************
*** 2524,2544 ****
return OK;
}
! linenr_T
! diff_get_corresponding_line(
buf_T *buf1,
! linenr_T lnum1,
! buf_T *buf2,
! linenr_T lnum3)
{
int idx1;
int idx2;
diff_T *dp;
int baseline = 0;
- linenr_T lnum2;
idx1 = diff_buf_idx(buf1);
! idx2 = diff_buf_idx(buf2);
if (idx1 == DB_COUNT || idx2 == DB_COUNT || curtab->tp_first_diff == NULL)
return lnum1;
--- 2521,2542 ----
return OK;
}
! /*
! * Return the line number in the current window that is closest to "lnum1" in
! * "buf1" in diff mode.
! */
! static linenr_T
! diff_get_corresponding_line_int(
buf_T *buf1,
! linenr_T lnum1)
{
int idx1;
int idx2;
diff_T *dp;
int baseline = 0;
idx1 = diff_buf_idx(buf1);
! idx2 = diff_buf_idx(curbuf);
if (idx1 == DB_COUNT || idx2 == DB_COUNT || curtab->tp_first_diff == NULL)
return lnum1;
***************
*** 2551,2565 ****
for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next)
{
if (dp->df_lnum[idx1] > lnum1)
! {
! lnum2 = lnum1 - baseline;
! /* don't end up past the end of the file */
! if (lnum2 > buf2->b_ml.ml_line_count)
! lnum2 = buf2->b_ml.ml_line_count;
!
! return lnum2;
! }
! else if ((dp->df_lnum[idx1] + dp->df_count[idx1]) > lnum1)
{
/* Inside the diffblock */
baseline = lnum1 - dp->df_lnum[idx1];
--- 2549,2556 ----
for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next)
{
if (dp->df_lnum[idx1] > lnum1)
! return lnum1 - baseline;
! if ((dp->df_lnum[idx1] + dp->df_count[idx1]) > lnum1)
{
/* Inside the diffblock */
baseline = lnum1 - dp->df_lnum[idx1];
***************
*** 2568,2577 ****
return dp->df_lnum[idx2] + baseline;
}
! else if ( (dp->df_lnum[idx1] == lnum1)
! && (dp->df_count[idx1] == 0)
! && (dp->df_lnum[idx2] <= lnum3)
! && ((dp->df_lnum[idx2] + dp->df_count[idx2]) > lnum3))
/*
* Special case: if the cursor is just after a zero-count
* block (i.e. all filler) and the target cursor is already
--- 2559,2569 ----
return dp->df_lnum[idx2] + baseline;
}
! if ( (dp->df_lnum[idx1] == lnum1)
! && (dp->df_count[idx1] == 0)
! && (dp->df_lnum[idx2] <= curwin->w_cursor.lnum)
! && ((dp->df_lnum[idx2] + dp->df_count[idx2])
! > curwin->w_cursor.lnum))
/*
* Special case: if the cursor is just after a zero-count
* block (i.e. all filler) and the target cursor is already
***************
*** 2579,2596 ****
* unmoved. This makes repeated CTRL-W W operations work
* as expected.
*/
! return lnum3;
baseline = (dp->df_lnum[idx1] + dp->df_count[idx1])
- (dp->df_lnum[idx2] + dp->df_count[idx2]);
}
/* If we get here then the cursor is after the last diff */
! lnum2 = lnum1 - baseline;
! /* don't end up past the end of the file */
! if (lnum2 > buf2->b_ml.ml_line_count)
! lnum2 = buf2->b_ml.ml_line_count;
! return lnum2;
}
#if defined(FEAT_FOLDING) || defined(PROTO)
--- 2571,2598 ----
* unmoved. This makes repeated CTRL-W W operations work
* as expected.
*/
! return curwin->w_cursor.lnum;
baseline = (dp->df_lnum[idx1] + dp->df_count[idx1])
- (dp->df_lnum[idx2] + dp->df_count[idx2]);
}
/* If we get here then the cursor is after the last diff */
! return lnum1 - baseline;
! }
! /*
! * Return the line number in the current window that is closest to "lnum1" in
! * "buf1" in diff mode. Checks the line number to be valid.
! */
! linenr_T
! diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1)
! {
! linenr_T lnum = diff_get_corresponding_line_int(buf1, lnum1);
!
! /* don't end up past the end of the file */
! if (lnum > curbuf->b_ml.ml_line_count)
! return curbuf->b_ml.ml_line_count;
! return lnum;
}
#if defined(FEAT_FOLDING) || defined(PROTO)
*** ../vim-8.0.0043/src/proto/diff.pro 2016-09-12 13:03:59.000000000 +0200
--- src/proto/diff.pro 2016-10-18 14:30:25.208461191 +0200
***************
*** 22,27 ****
void ex_diffgetput(exarg_T *eap);
int diff_mode_buf(buf_T *buf);
int diff_move_to(int dir, long count);
! linenr_T diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1, buf_T
*buf2, linenr_T lnum3);
linenr_T diff_lnum_win(linenr_T lnum, win_T *wp);
/* vim: set ft=c : */
--- 22,27 ----
void ex_diffgetput(exarg_T *eap);
int diff_mode_buf(buf_T *buf);
int diff_move_to(int dir, long count);
! linenr_T diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1);
linenr_T diff_lnum_win(linenr_T lnum, win_T *wp);
/* vim: set ft=c : */
*** ../vim-8.0.0043/src/testdir/test_diffmode.vim 2016-08-27
22:20:56.000000000 +0200
--- src/testdir/test_diffmode.vim 2016-10-18 14:48:01.108678884 +0200
***************
*** 218,220 ****
--- 218,237 ----
bwipe!
bwipe!
endfunc
+
+ func Test_setting_cursor()
+ new Xtest1
+ put =range(1,90)
+ wq
+ new Xtest2
+ put =range(1,100)
+ wq
+
+ tabe Xtest2
+ $
+ diffsp Xtest1
+ tabclose
+
+ call delete('Xtest1')
+ call delete('Xtest2')
+ endfunc
*** ../vim-8.0.0043/src/version.c 2016-10-18 13:06:33.377547323 +0200
--- src/version.c 2016-10-18 14:28:23.337359418 +0200
***************
*** 766,767 ****
--- 766,769 ----
{ /* Add new patch number below this line */
+ /**/
+ 44,
/**/
--
Zen Microsystems: we're the om in .commmmmmmmm
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.