]> granicus.if.org Git - vim/commitdiff
patch 8.0.0044 v8.0.0044
authorBram Moolenaar <Bram@vim.org>
Tue, 18 Oct 2016 12:50:18 +0000 (14:50 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 18 Oct 2016 12:50:18 +0000 (14:50 +0200)
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.

src/diff.c
src/move.c
src/proto/diff.pro
src/testdir/test_diffmode.vim
src/version.c

index 9c12ea4e674f569033c2942804227b2a4af8cc5f..a4a2acb95f7f48fbce529165273cd5a4854b2da5 100644 (file)
@@ -1100,10 +1100,7 @@ ex_diffsplit(exarg_T *eap)
                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);
+                           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,21 +2521,22 @@ diff_move_to(int dir, long count)
     return OK;
 }
 
-    linenr_T
-diff_get_corresponding_line(
+/*
+ * 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,
-    buf_T      *buf2,
-    linenr_T   lnum3)
+    linenr_T   lnum1)
 {
     int                idx1;
     int                idx2;
     diff_T     *dp;
     int                baseline = 0;
-    linenr_T   lnum2;
 
     idx1 = diff_buf_idx(buf1);
-    idx2 = diff_buf_idx(buf2);
+    idx2 = diff_buf_idx(curbuf);
     if (idx1 == DB_COUNT || idx2 == DB_COUNT || curtab->tp_first_diff == NULL)
        return lnum1;
 
@@ -2551,15 +2549,8 @@ diff_get_corresponding_line(
     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)
+           return lnum1 - baseline;
+       if ((dp->df_lnum[idx1] + dp->df_count[idx1]) > lnum1)
        {
            /* Inside the diffblock */
            baseline = lnum1 - dp->df_lnum[idx1];
@@ -2568,10 +2559,11 @@ diff_get_corresponding_line(
 
            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))
+       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,18 +2571,28 @@ diff_get_corresponding_line(
             * unmoved. This makes repeated CTRL-W W operations work
             * as expected.
             */
-           return lnum3;
+           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 */
-    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 lnum1 - baseline;
+}
 
-    return lnum2;
+/*
+ * 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)
index a4d5f82997b648c09b6ac82256bbe8f1c0e214d0..c7acdfa68b42b011b05fddf59a4a374bd85a28e9 100644 (file)
@@ -2824,11 +2824,8 @@ do_check_cursorbind(void)
        {
 # ifdef FEAT_DIFF
            if (curwin->w_p_diff)
-               curwin->w_cursor.lnum
-                       = diff_get_corresponding_line(old_curbuf,
-                                                     line,
-                                                     curbuf,
-                                                     curwin->w_cursor.lnum);
+               curwin->w_cursor.lnum =
+                                diff_get_corresponding_line(old_curbuf, line);
            else
 # endif
                curwin->w_cursor.lnum = line;
index c7a7ebe579e84bbde69565402d9f87b7bda25b7e..718640152ffb0650450783ae67f6fed727d3a7cd 100644 (file)
@@ -22,6 +22,6 @@ void nv_diffgetput(int put, long count);
 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_get_corresponding_line(buf_T *buf1, linenr_T lnum1);
 linenr_T diff_lnum_win(linenr_T lnum, win_T *wp);
 /* vim: set ft=c : */
index 5de394de8ef7aeaec359dd1d6c58d5f865efd70f..f40e06ff3358b651604738a1357c3b2a0f96cda9 100644 (file)
@@ -218,3 +218,20 @@ func Test_diffoff()
   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
index e910845d1ccb4954f70599ee651f7c019959004a..80a837a381264d23e01e4cb3ca663e8de26770ba 100644 (file)
@@ -764,6 +764,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    44,
 /**/
     43,
 /**/