Mercurial > vim
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 |