# HG changeset patch # User Bram Moolenaar # Date 1280924994 -7200 # Node ID 88751831fa0a9f87ce3a500af89d805d590f8dcc # Parent 734196b073e01896262c7f1c40698562e0410311 When undoing a reload, move the cursor to the first changed line. diff --git a/src/fileio.c b/src/fileio.c --- a/src/fileio.c +++ b/src/fileio.c @@ -2605,6 +2605,11 @@ failed: */ write_no_eol_lnum = read_no_eol_lnum; + /* When reloading a buffer put the cursor at the first line that is + * different. */ + if (flags & READ_KEEP_UNDO) + u_find_first_changed(); + #ifdef FEAT_PERSISTENT_UNDO /* * When opening a new file locate undo info and read it. @@ -7095,7 +7100,7 @@ buf_reload(buf, orig_mode) old_cursor = curwin->w_cursor; old_topline = curwin->w_topline; - if (saved == OK && (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur)) + if (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur) { /* Save all the text, so that the reload can be undone. * Sync first so that this is a separate undo-able action. */ @@ -7169,8 +7174,10 @@ buf_reload(buf, orig_mode) u_clearall(buf); } else + { /* Mark all undo states as changed. */ u_unchanged(curbuf); + } } } vim_free(ea.cmd); diff --git a/src/proto/undo.pro b/src/proto/undo.pro --- a/src/proto/undo.pro +++ b/src/proto/undo.pro @@ -17,6 +17,7 @@ void u_sync __ARGS((int force)); void ex_undolist __ARGS((exarg_T *eap)); void ex_undojoin __ARGS((exarg_T *eap)); void u_unchanged __ARGS((buf_T *buf)); +void u_find_first_changed __ARGS((void)); void u_update_save_nr __ARGS((buf_T *buf)); void u_clearall __ARGS((buf_T *buf)); void u_saveline __ARGS((linenr_T lnum)); diff --git a/src/undo.c b/src/undo.c --- a/src/undo.c +++ b/src/undo.c @@ -2923,6 +2923,42 @@ u_unchanged(buf) } /* + * After reloading a buffer which was saved for 'undoreload': Find the first + * line that was changed and set the cursor there. + */ + void +u_find_first_changed() +{ + u_header_T *uhp = curbuf->b_u_newhead; + u_entry_T *uep; + linenr_T lnum; + + if (curbuf->b_u_curhead != NULL || uhp == NULL) + return; /* undid something in an autocmd? */ + + /* Check that the last undo block was for the whole file. */ + uep = uhp->uh_entry; + if (uep->ue_top != 0 || uep->ue_bot != 0) + return; + + for (lnum = 1; lnum < curbuf->b_ml.ml_line_count + && lnum <= uep->ue_size; ++lnum) + if (STRCMP(ml_get_buf(curbuf, lnum, FALSE), + uep->ue_array[lnum - 1]) != 0) + { + clearpos(&(uhp->uh_cursor)); + uhp->uh_cursor.lnum = lnum; + return; + } + if (curbuf->b_ml.ml_line_count != uep->ue_size) + { + /* lines added or deleted at the end, put the cursor there */ + clearpos(&(uhp->uh_cursor)); + uhp->uh_cursor.lnum = lnum; + } +} + +/* * Increase the write count, store it in the last undo header, what would be * used for "u". */