To: vim-dev@vim.org Subject: Patch 6.0.029 Fcc: outbox From: Bram Moolenaar MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.0.029 Problem: When making a change in line 1, then in line 2 and then deleting line 1, undo info could be wrong. Only when the changes are undone at once. (Gerhard Hochholzer) Solution: When not saving a line for undo because it was already done before, remember for which entry the last line must be computed. Added ue_getbot_entry pointer for this. When the number of lines changes, adjust the position of newer undo entries. Files: src/structs.h, src/undo.c *** ../vim60.28/src/structs.h Sun Sep 16 14:45:18 2001 --- src/structs.h Sun Oct 28 20:08:24 2001 *************** *** 232,237 **** --- 232,238 ---- u_header_T *uh_next; /* pointer to next header in list */ u_header_T *uh_prev; /* pointer to previous header in list */ u_entry_T *uh_entry; /* pointer to first entry */ + u_entry_T *uh_getbot_entry; /* pointer to where ue_bot must be set */ pos_T uh_cursor; /* cursor position before saving */ #ifdef FEAT_VIRTUALEDIT long uh_cursor_vcol; *** ../vim60.28/src/undo.c Fri Aug 24 09:57:23 2001 --- src/undo.c Sun Oct 28 21:03:26 2001 *************** *** 224,229 **** --- 224,230 ---- if (curbuf->b_u_newhead != NULL) curbuf->b_u_newhead->uh_prev = uhp; uhp->uh_entry = NULL; + uhp->uh_getbot_entry = NULL; uhp->uh_cursor = curwin->w_cursor; /* save cursor pos. for undo */ #ifdef FEAT_VIRTUALEDIT if (virtual_active() && curwin->w_cursor.coladd > 0) *************** *** 263,269 **** break; /* If lines have been inserted/deleted we give up. */ ! if (uep->ue_lcount == 0 ? (uep->ue_top + uep->ue_size + 1 != (uep->ue_bot == 0 ? curbuf->b_ml.ml_line_count + 1 --- 264,270 ---- break; /* If lines have been inserted/deleted we give up. */ ! if (curbuf->b_u_newhead->uh_getbot_entry != uep ? (uep->ue_top + uep->ue_size + 1 != (uep->ue_bot == 0 ? curbuf->b_ml.ml_line_count + 1 *************** *** 274,287 **** /* If it's the same line we can skip saving it again. */ if (uep->ue_size == 1 && uep->ue_top == top) { ! /* The line count might change. */ ! uep->ue_lcount = 0; if (newbot != 0) uep->ue_bot = newbot; else if (bot > curbuf->b_ml.ml_line_count) uep->ue_bot = 0; else uep->ue_lcount = curbuf->b_ml.ml_line_count; return OK; } uep = uep->ue_next; --- 275,313 ---- /* If it's the same line we can skip saving it again. */ if (uep->ue_size == 1 && uep->ue_top == top) { ! /* If it's not the last entry, get ue_bot for the last ! * entry now. Following deleted/inserted lines go to the ! * re-used entry. */ ! if (i > 0) ! u_getbot(); ! ! /* The line count might change afterwards. */ if (newbot != 0) + { + /* When changing the line count and it's not the + * newest entry, must adjust the line numbers of older + * entries. */ + if (uep != curbuf->b_u_newhead->uh_entry + && uep->ue_bot != newbot) + { + u_entry_T *p; + + for (p = curbuf->b_u_newhead->uh_entry; + p != uep; p = p->ue_next) + { + p->ue_bot -= uep->ue_bot - newbot; + p->ue_top -= uep->ue_bot - newbot; + } + } uep->ue_bot = newbot; + } else if (bot > curbuf->b_ml.ml_line_count) uep->ue_bot = 0; else + { uep->ue_lcount = curbuf->b_ml.ml_line_count; + curbuf->b_u_newhead->uh_getbot_entry = uep; + } return OK; } uep = uep->ue_next; *************** *** 310,316 **** uep->ue_size = size; uep->ue_top = top; - uep->ue_lcount = 0; if (newbot) uep->ue_bot = newbot; /* --- 336,341 ---- *************** *** 320,326 **** --- 345,354 ---- else if (bot > curbuf->b_ml.ml_line_count) uep->ue_bot = 0; else + { uep->ue_lcount = curbuf->b_ml.ml_line_count; + curbuf->b_u_newhead->uh_getbot_entry = uep; + } if (size) { *************** *** 732,751 **** u_getbot() { u_entry_T *uep; ! uep = u_get_headentry(); if (uep == NULL) return; ! if (uep->ue_lcount != 0) { /* * the new ue_bot is computed from the number of lines that has been * inserted (0 - deleted) since calling u_save. This is equal to the old * line count subtracted from the current line count. */ ! uep->ue_bot = uep->ue_top + uep->ue_size + 1 + ! (curbuf->b_ml.ml_line_count - uep->ue_lcount); if (uep->ue_bot < 1 || uep->ue_bot > curbuf->b_ml.ml_line_count) { EMSG(_("E440: undo line missing")); --- 760,781 ---- u_getbot() { u_entry_T *uep; + linenr_T extra; ! uep = u_get_headentry(); /* check for corrupt undo list */ if (uep == NULL) return; ! uep = curbuf->b_u_newhead->uh_getbot_entry; ! if (uep != NULL) { /* * the new ue_bot is computed from the number of lines that has been * inserted (0 - deleted) since calling u_save. This is equal to the old * line count subtracted from the current line count. */ ! extra = curbuf->b_ml.ml_line_count - uep->ue_lcount; ! uep->ue_bot = uep->ue_top + uep->ue_size + 1 + extra; if (uep->ue_bot < 1 || uep->ue_bot > curbuf->b_ml.ml_line_count) { EMSG(_("E440: undo line missing")); *************** *** 754,760 **** * without deleting the current * ones */ } ! uep->ue_lcount = 0; } curbuf->b_u_synced = TRUE; --- 784,802 ---- * without deleting the current * ones */ } ! ! /* If not the newest entry and lines have been inserted or deleted, ! * newer entries must have their line numbers adjusted. */ ! if (extra != 0) ! for (uep = curbuf->b_u_newhead->uh_entry; ! uep != curbuf->b_u_newhead->uh_getbot_entry; ! uep = uep->ue_next) ! { ! uep->ue_bot -= extra; ! uep->ue_top -= extra; ! } ! ! curbuf->b_u_newhead->uh_getbot_entry = NULL; } curbuf->b_u_synced = TRUE; *** ../vim60.28/src/version.c Sun Oct 28 16:41:29 2001 --- src/version.c Sun Oct 28 21:11:52 2001 *************** *** 608,609 **** --- 608,611 ---- { /* Add new patch number below this line */ + /**/ + 29, /**/ -- f y cn rd ths thn y cn hv grt jb n cmptr prgrmmng /// Bram Moolenaar -- Bram@moolenaar.net -- http://www.moolenaar.net \\\ ((( Creator of Vim -- http://vim.sf.net -- ftp://ftp.vim.org/pub/vim ))) \\\ Help me helping AIDS orphans in Uganda - http://iccf-holland.org ///