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 From dec165b268803d08425e0f173b2487c76a2c440c Mon Sep 17 00:00:00 2001 From: Husain Alshehhi Date: Wed, 1 Jan 2020 07:59:37 -0600 Subject: PVS/V618: fix emsgf format specifier #11643 --- src/nvim/undo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/undo.c') diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 539d42765d..980399a3ef 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -1057,7 +1057,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf, if (file_name == NULL) { if (p_verbose > 0) { verbose_enter(); - smsg(_("Cannot write undo file in any directory in 'undodir'")); + smsg("%s", _("Cannot write undo file in any directory in 'undodir'")); verbose_leave(); } return; -- cgit From ca1a00edd6d6345b848a28d077d6a192528f811e Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Tue, 14 Jan 2020 12:45:09 +0100 Subject: extmarks/bufhl: reimplement using new marktree data structure Add new "splice" interface for tracking buffer changes at the byte level. This will later be reused for byte-resolution buffer updates. (Implementation has been started, but using undocumented "_on_bytes" option now as interface hasn't been finalized). Use this interface to improve many edge cases of extmark adjustment. Changed tests indicate previously incorrect behavior. Adding tests for more edge cases will be follow-up work (overlaps on_bytes tests) Don't consider creation/deletion of marks an undoable event by itself. This behavior was never documented, and imposes complexity for little gain. Add nvim__buf_add_decoration temporary API for direct access to the new implementation. This should be refactored into a proper API for decorations, probably involving a huge dict. fixes #11598 --- src/nvim/undo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/undo.c') diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 980399a3ef..fda647106d 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -2244,7 +2244,7 @@ static void u_undoredo(int undo, bool do_buf_event) // Adjust marks if (oldsize != newsize) { mark_adjust(top + 1, top + oldsize, (long)MAXLNUM, - (long)newsize - (long)oldsize, false, kExtmarkNOOP); + (long)newsize - (long)oldsize, kExtmarkNOOP); if (curbuf->b_op_start.lnum > top + oldsize) { curbuf->b_op_start.lnum += newsize - oldsize; } -- cgit From 48a869dc6d29514e943070da9f22f702f5179826 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Mon, 20 Jan 2020 19:29:12 +0100 Subject: shed biking: it's always extmarks, never marks extended --- src/nvim/undo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/undo.c') diff --git a/src/nvim/undo.c b/src/nvim/undo.c index fda647106d..1f74bada41 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -93,7 +93,7 @@ #include "nvim/buffer_updates.h" #include "nvim/pos.h" // MAXLNUM #include "nvim/mark.h" -#include "nvim/mark_extended.h" +#include "nvim/extmark.h" #include "nvim/memline.h" #include "nvim/message.h" #include "nvim/misc1.h" -- cgit From aec3d7915c55fc0b7dc73f6186cf0ae45d416d33 Mon Sep 17 00:00:00 2001 From: erw7 Date: Sat, 25 May 2019 11:14:35 +0900 Subject: vim-patch:8.1.0091: MS-Windows: Cannot interrupt gdb when program is running Problem: MS-Windows: Cannot interrupt gdb when program is running. Solution: Add debugbreak() and use it in the terminal debugger. Respect 'modified' in a prompt buffer. https://github.com/vim/vim/commit/4551c0a9fcdbdef52836d4852686d54b5e47fdaf --- src/nvim/undo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/nvim/undo.c') diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 1f74bada41..df92b2c036 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -2971,7 +2971,10 @@ static char_u *u_save_line(linenr_T lnum) bool bufIsChanged(buf_T *buf) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { - return !bt_dontwrite(buf) && (buf->b_changed || file_ff_differs(buf, true)); + // In a "prompt" buffer we do respect 'modified', so that we can control + // closing the window by setting or resetting that option. + return (!bt_dontwrite(buf) || bt_prompt(buf)) + && (buf->b_changed || file_ff_differs(buf, true)); } // Return true if any buffer has changes. Also buffers that are not written. -- cgit From 978a6bcaf2b98b3c89381a3eacf642b4f61db033 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Sun, 22 Mar 2020 21:40:12 +0000 Subject: vim-patch:8.1.2225: the "last used" info of a buffer is under used Problem: The "last used" info of a buffer is under used. Solution: Add "lastused" to getbufinfo(). List buffers sorted by last-used field. (Andi Massimino, closes vim/vim#4722) https://github.com/vim/vim/commit/52410575be50d5c40bbe6380159df48cfc382ceb --- src/nvim/undo.c | 35 ++++++----------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) (limited to 'src/nvim/undo.c') diff --git a/src/nvim/undo.c b/src/nvim/undo.c index df92b2c036..97018f6c02 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -2441,10 +2441,11 @@ static void u_undo_end( uhp = curbuf->b_u_newhead; } - if (uhp == NULL) + if (uhp == NULL) { *msgbuf = NUL; - else - u_add_time(msgbuf, sizeof(msgbuf), uhp->uh_time); + } else { + add_time(msgbuf, sizeof(msgbuf), uhp->uh_time); + } { FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { @@ -2509,8 +2510,8 @@ void ex_undolist(exarg_T *eap) && uhp->uh_walk != mark) { vim_snprintf((char *)IObuff, IOSIZE, "%6ld %7d ", uhp->uh_seq, changes); - u_add_time(IObuff + STRLEN(IObuff), IOSIZE - STRLEN(IObuff), - uhp->uh_time); + add_time(IObuff + STRLEN(IObuff), IOSIZE - STRLEN(IObuff), + uhp->uh_time); if (uhp->uh_save_nr > 0) { while (STRLEN(IObuff) < 33) STRCAT(IObuff, " "); @@ -2574,30 +2575,6 @@ void ex_undolist(exarg_T *eap) } } -/* - * Put the timestamp of an undo header in "buf[buflen]" in a nice format. - */ -static void u_add_time(char_u *buf, size_t buflen, time_t tt) -{ - struct tm curtime; - - if (time(NULL) - tt >= 100) { - os_localtime_r(&tt, &curtime); - if (time(NULL) - tt < (60L * 60L * 12L)) - /* within 12 hours */ - (void)strftime((char *)buf, buflen, "%H:%M:%S", &curtime); - else - /* longer ago */ - (void)strftime((char *)buf, buflen, "%Y/%m/%d %H:%M:%S", &curtime); - } else { - int64_t seconds = time(NULL) - tt; - vim_snprintf((char *)buf, buflen, - NGETTEXT("%" PRId64 " second ago", - "%" PRId64 " seconds ago", (uint32_t)seconds), - seconds); - } -} - /* * ":undojoin": continue adding to the last entry list */ -- cgit