From a9065a50518ef59351f9d0d32041a991a751653f Mon Sep 17 00:00:00 2001 From: timeyyy Date: Wed, 18 Jan 2017 13:20:07 +0100 Subject: nsmarks: initial commit --- src/nvim/undo.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) (limited to 'src/nvim/undo.c') diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 035613c7fd..91a142214b 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -91,7 +91,9 @@ #include "nvim/fileio.h" #include "nvim/fold.h" #include "nvim/buffer_updates.h" +#include "nvim/pos.h" // MAXLNUM #include "nvim/mark.h" +#include "nvim/mark_extended.h" #include "nvim/memline.h" #include "nvim/message.h" #include "nvim/misc1.h" @@ -106,6 +108,7 @@ #include "nvim/types.h" #include "nvim/os/os.h" #include "nvim/os/time.h" +#include "nvim/lib/kvec.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "undo.c.generated.h" @@ -384,6 +387,7 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload) * up the undo info when out of memory. */ uhp = xmalloc(sizeof(u_header_T)); + kv_init(uhp->uh_extmark); #ifdef U_DEBUG uhp->uh_magic = UH_MAGIC; #endif @@ -2249,10 +2253,10 @@ static void u_undoredo(int undo, bool do_buf_event) xfree((char_u *)uep->ue_array); } - /* adjust marks */ + // Adjust marks if (oldsize != newsize) { mark_adjust(top + 1, top + oldsize, (long)MAXLNUM, - (long)newsize - (long)oldsize, false); + (long)newsize - (long)oldsize, false, kExtmarkNOOP); if (curbuf->b_op_start.lnum > top + oldsize) { curbuf->b_op_start.lnum += newsize - oldsize; } @@ -2285,6 +2289,23 @@ static void u_undoredo(int undo, bool do_buf_event) newlist = uep; } + // Adjust Extmarks + ExtmarkUndoObject undo_info; + if (undo) { + for (i = (int)kv_size(curhead->uh_extmark) - 1; i > -1; i--) { + undo_info = kv_A(curhead->uh_extmark, i); + extmark_apply_undo(undo_info, undo); + } + // redo + } else { + for (i = 0; i < (int)kv_size(curhead->uh_extmark); i++) { + undo_info = kv_A(curhead->uh_extmark, i); + extmark_apply_undo(undo_info, undo); + } + } + // finish Adjusting extmarks + + curhead->uh_entry = newlist; curhead->uh_flags = new_flags; if ((old_flags & UH_EMPTYBUF) && BUFEMPTY()) { @@ -2828,6 +2849,9 @@ u_freeentries( u_freeentry(uep, uep->ue_size); } + // TODO(timeyyy): is this the correct place? ... + kv_destroy(uhp->uh_extmark); + #ifdef U_DEBUG uhp->uh_magic = 0; #endif @@ -3022,3 +3046,28 @@ list_T *u_eval_tree(const u_header_T *const first_uhp) return list; } + +// Given the buffer, Return the undo header. If none is set, set one first. +// NULL will be returned if e.g undolevels = -1 (undo disabled) +u_header_T *force_get_undo_header(buf_T *buf) +{ + u_header_T *uhp = NULL; + if (buf->b_u_curhead != NULL) { + uhp = buf->b_u_curhead; + } else if (buf->b_u_newhead) { + uhp = buf->b_u_newhead; + } + // Create the first undo header for the buffer + if (!uhp) { + // TODO(timeyyy): there would be a better way to do this! + u_save_cursor(); + uhp = buf->b_u_curhead; + if (!uhp) { + uhp = buf->b_u_newhead; + if (get_undolevel() > 0) { + assert(uhp); + } + } + } + return uhp; +} -- cgit From 18a8b702c0ce7a8bacd84f6c95e440ae23a3299e Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sat, 9 Nov 2019 12:41:50 +0100 Subject: extmark: review changes --- src/nvim/undo.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/nvim/undo.c') diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 91a142214b..b00d2d505f 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -2849,7 +2849,6 @@ u_freeentries( u_freeentry(uep, uep->ue_size); } - // TODO(timeyyy): is this the correct place? ... kv_destroy(uhp->uh_extmark); #ifdef U_DEBUG @@ -3049,7 +3048,7 @@ list_T *u_eval_tree(const u_header_T *const first_uhp) // Given the buffer, Return the undo header. If none is set, set one first. // NULL will be returned if e.g undolevels = -1 (undo disabled) -u_header_T *force_get_undo_header(buf_T *buf) +u_header_T *u_force_get_undo_header(buf_T *buf) { u_header_T *uhp = NULL; if (buf->b_u_curhead != NULL) { @@ -3064,8 +3063,8 @@ u_header_T *force_get_undo_header(buf_T *buf) uhp = buf->b_u_curhead; if (!uhp) { uhp = buf->b_u_newhead; - if (get_undolevel() > 0) { - assert(uhp); + if (get_undolevel() > 0 && !uhp) { + abort(); } } } -- cgit From 6222cca36adbf09109987e27e58d025a00020f3a Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sat, 16 Nov 2019 11:03:43 +0100 Subject: undo: delete undo_off global without effect --- src/nvim/undo.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'src/nvim/undo.c') diff --git a/src/nvim/undo.c b/src/nvim/undo.c index b00d2d505f..b36d1ac3ec 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -225,9 +225,6 @@ int u_save_cursor(void) */ int u_save(linenr_T top, linenr_T bot) { - if (undo_off) - return OK; - if (top >= bot || bot > (curbuf->b_ml.ml_line_count + 1)) { return FAIL; /* rely on caller to do error messages */ } @@ -246,9 +243,6 @@ int u_save(linenr_T top, linenr_T bot) */ int u_savesub(linenr_T lnum) { - if (undo_off) - return OK; - return u_savecommon(lnum - 1, lnum + 1, lnum + 1, FALSE); } @@ -260,9 +254,6 @@ int u_savesub(linenr_T lnum) */ int u_inssub(linenr_T lnum) { - if (undo_off) - return OK; - return u_savecommon(lnum - 1, lnum, lnum + 1, FALSE); } @@ -275,9 +266,6 @@ int u_inssub(linenr_T lnum) */ int u_savedel(linenr_T lnum, long nlines) { - if (undo_off) - return OK; - return u_savecommon(lnum - 1, lnum + nlines, nlines == curbuf->b_ml.ml_line_count ? 2 : lnum, FALSE); } @@ -2925,9 +2913,6 @@ void u_undoline(void) colnr_T t; char_u *oldp; - if (undo_off) - return; - if (curbuf->b_u_line_ptr == NULL || curbuf->b_u_line_lnum > curbuf->b_ml.ml_line_count) { beep_flush(); -- cgit From ebdf90e7d7c97b4355f42e06769e9424c279d695 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sat, 16 Nov 2019 11:05:56 +0100 Subject: extmark: don't crash in RO buffer. --- src/nvim/undo.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/nvim/undo.c') diff --git a/src/nvim/undo.c b/src/nvim/undo.c index b36d1ac3ec..539d42765d 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -243,7 +243,7 @@ int u_save(linenr_T top, linenr_T bot) */ int u_savesub(linenr_T lnum) { - return u_savecommon(lnum - 1, lnum + 1, lnum + 1, FALSE); + return u_savecommon(lnum - 1, lnum + 1, lnum + 1, false); } /* @@ -254,7 +254,7 @@ int u_savesub(linenr_T lnum) */ int u_inssub(linenr_T lnum) { - return u_savecommon(lnum - 1, lnum, lnum + 1, FALSE); + return u_savecommon(lnum - 1, lnum, lnum + 1, false); } /* @@ -3043,8 +3043,14 @@ u_header_T *u_force_get_undo_header(buf_T *buf) } // Create the first undo header for the buffer if (!uhp) { - // TODO(timeyyy): there would be a better way to do this! - u_save_cursor(); + // Undo is normally invoked in change code, which already has swapped + // curbuf. + buf_T *save_curbuf = curbuf; + curbuf = buf; + // Args are tricky: this means replace empty range by empty range.. + u_savecommon(0, 1, 1, true); + curbuf = save_curbuf; + uhp = buf->b_u_curhead; if (!uhp) { uhp = buf->b_u_newhead; -- cgit