comparison src/diff.c @ 10295:d0b74b18e4b5 v8.0.0044

commit https://github.com/vim/vim/commit/025e3e0bafbc85cc4e365145af711edf99d0a90d Author: Bram Moolenaar <Bram@vim.org> Date: Tue Oct 18 14:50:18 2016 +0200 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.
author Christian Brabandt <cb@256bit.org>
date Tue, 18 Oct 2016 15:00:04 +0200
parents 4aead6a9b7a9
children d9e48fb5142f
comparison
equal deleted inserted replaced
10294:76376eb4cbe5 10295:d0b74b18e4b5
1098 diff_win_options(old_curwin, TRUE); 1098 diff_win_options(old_curwin, TRUE);
1099 1099
1100 if (bufref_valid(&old_curbuf)) 1100 if (bufref_valid(&old_curbuf))
1101 /* Move the cursor position to that of the old window. */ 1101 /* Move the cursor position to that of the old window. */
1102 curwin->w_cursor.lnum = diff_get_corresponding_line( 1102 curwin->w_cursor.lnum = diff_get_corresponding_line(
1103 old_curbuf.br_buf, 1103 old_curbuf.br_buf, old_curwin->w_cursor.lnum);
1104 old_curwin->w_cursor.lnum,
1105 curbuf,
1106 curwin->w_cursor.lnum);
1107 } 1104 }
1108 /* Now that lines are folded scroll to show the cursor at the same 1105 /* Now that lines are folded scroll to show the cursor at the same
1109 * relative position. */ 1106 * relative position. */
1110 scroll_to_fraction(curwin, curwin->w_height); 1107 scroll_to_fraction(curwin, curwin->w_height);
1111 } 1108 }
2522 curwin->w_cursor.col = 0; 2519 curwin->w_cursor.col = 0;
2523 2520
2524 return OK; 2521 return OK;
2525 } 2522 }
2526 2523
2527 linenr_T 2524 /*
2528 diff_get_corresponding_line( 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(
2529 buf_T *buf1, 2530 buf_T *buf1,
2530 linenr_T lnum1, 2531 linenr_T lnum1)
2531 buf_T *buf2,
2532 linenr_T lnum3)
2533 { 2532 {
2534 int idx1; 2533 int idx1;
2535 int idx2; 2534 int idx2;
2536 diff_T *dp; 2535 diff_T *dp;
2537 int baseline = 0; 2536 int baseline = 0;
2538 linenr_T lnum2;
2539 2537
2540 idx1 = diff_buf_idx(buf1); 2538 idx1 = diff_buf_idx(buf1);
2541 idx2 = diff_buf_idx(buf2); 2539 idx2 = diff_buf_idx(curbuf);
2542 if (idx1 == DB_COUNT || idx2 == DB_COUNT || curtab->tp_first_diff == NULL) 2540 if (idx1 == DB_COUNT || idx2 == DB_COUNT || curtab->tp_first_diff == NULL)
2543 return lnum1; 2541 return lnum1;
2544 2542
2545 if (curtab->tp_diff_invalid) 2543 if (curtab->tp_diff_invalid)
2546 ex_diffupdate(NULL); /* update after a big change */ 2544 ex_diffupdate(NULL); /* update after a big change */
2549 return lnum1; 2547 return lnum1;
2550 2548
2551 for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next) 2549 for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next)
2552 { 2550 {
2553 if (dp->df_lnum[idx1] > lnum1) 2551 if (dp->df_lnum[idx1] > lnum1)
2554 { 2552 return lnum1 - baseline;
2555 lnum2 = lnum1 - baseline; 2553 if ((dp->df_lnum[idx1] + dp->df_count[idx1]) > lnum1)
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)
2563 { 2554 {
2564 /* Inside the diffblock */ 2555 /* Inside the diffblock */
2565 baseline = lnum1 - dp->df_lnum[idx1]; 2556 baseline = lnum1 - dp->df_lnum[idx1];
2566 if (baseline > dp->df_count[idx2]) 2557 if (baseline > dp->df_count[idx2])
2567 baseline = dp->df_count[idx2]; 2558 baseline = dp->df_count[idx2];
2568 2559
2569 return dp->df_lnum[idx2] + baseline; 2560 return dp->df_lnum[idx2] + baseline;
2570 } 2561 }
2571 else if ( (dp->df_lnum[idx1] == lnum1) 2562 if ( (dp->df_lnum[idx1] == lnum1)
2572 && (dp->df_count[idx1] == 0) 2563 && (dp->df_count[idx1] == 0)
2573 && (dp->df_lnum[idx2] <= lnum3) 2564 && (dp->df_lnum[idx2] <= curwin->w_cursor.lnum)
2574 && ((dp->df_lnum[idx2] + dp->df_count[idx2]) > lnum3)) 2565 && ((dp->df_lnum[idx2] + dp->df_count[idx2])
2566 > curwin->w_cursor.lnum))
2575 /* 2567 /*
2576 * Special case: if the cursor is just after a zero-count 2568 * Special case: if the cursor is just after a zero-count
2577 * block (i.e. all filler) and the target cursor is already 2569 * block (i.e. all filler) and the target cursor is already
2578 * inside the corresponding block, leave the target cursor 2570 * inside the corresponding block, leave the target cursor
2579 * unmoved. This makes repeated CTRL-W W operations work 2571 * unmoved. This makes repeated CTRL-W W operations work
2580 * as expected. 2572 * as expected.
2581 */ 2573 */
2582 return lnum3; 2574 return curwin->w_cursor.lnum;
2583 baseline = (dp->df_lnum[idx1] + dp->df_count[idx1]) 2575 baseline = (dp->df_lnum[idx1] + dp->df_count[idx1])
2584 - (dp->df_lnum[idx2] + dp->df_count[idx2]); 2576 - (dp->df_lnum[idx2] + dp->df_count[idx2]);
2585 } 2577 }
2586 2578
2587 /* If we get here then the cursor is after the last diff */ 2579 /* If we get here then the cursor is after the last diff */
2588 lnum2 = lnum1 - baseline; 2580 return lnum1 - baseline;
2581 }
2582
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
2589 /* don't end up past the end of the file */ 2592 /* don't end up past the end of the file */
2590 if (lnum2 > buf2->b_ml.ml_line_count) 2593 if (lnum > curbuf->b_ml.ml_line_count)
2591 lnum2 = buf2->b_ml.ml_line_count; 2594 return curbuf->b_ml.ml_line_count;
2592 2595 return lnum;
2593 return lnum2;
2594 } 2596 }
2595 2597
2596 #if defined(FEAT_FOLDING) || defined(PROTO) 2598 #if defined(FEAT_FOLDING) || defined(PROTO)
2597 /* 2599 /*
2598 * For line "lnum" in the current window find the equivalent lnum in window 2600 * For line "lnum" in the current window find the equivalent lnum in window