aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/buffer_defs.h1
-rw-r--r--src/nvim/change.c18
-rw-r--r--src/nvim/diff.c6
-rw-r--r--src/nvim/edit.c2
-rw-r--r--src/nvim/eval/funcs.c7
-rw-r--r--src/nvim/ex_cmds.c6
-rw-r--r--src/nvim/ex_getln.c12
-rw-r--r--src/nvim/fileio.c10
-rw-r--r--src/nvim/globals.h3
-rw-r--r--src/nvim/quickfix.c4
-rw-r--r--src/nvim/undo.c333
11 files changed, 216 insertions, 186 deletions
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 17bd81b230..a4d9229b51 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -525,6 +525,7 @@ struct file_buffer {
int b_flags; // various BF_ flags
int b_locked; // Buffer is being closed or referenced, don't
// let autocommands wipe it out.
+ int b_ro_locked; // Replacement for curbuf_lock
//
// b_ffname has the full path of the file (NULL for no name).
diff --git a/src/nvim/change.c b/src/nvim/change.c
index c0183d4317..ca98d8f40b 100644
--- a/src/nvim/change.c
+++ b/src/nvim/change.c
@@ -40,18 +40,18 @@
/// "col" is the column for the message; non-zero when in insert mode and
/// 'showmode' is on.
/// Careful: may trigger autocommands that reload the buffer.
-void change_warning(int col)
+void change_warning(buf_T *buf, int col)
{
static char *w_readonly = N_("W10: Warning: Changing a readonly file");
- if (curbuf->b_did_warn == false
+ if (buf->b_did_warn == false
&& curbufIsChanged() == 0
&& !autocmd_busy
- && curbuf->b_p_ro) {
- curbuf_lock++;
- apply_autocmds(EVENT_FILECHANGEDRO, NULL, NULL, false, curbuf);
- curbuf_lock--;
- if (!curbuf->b_p_ro) {
+ && buf->b_p_ro) {
+ buf->b_ro_locked++;
+ apply_autocmds(EVENT_FILECHANGEDRO, NULL, NULL, false, buf);
+ buf->b_ro_locked--;
+ if (!buf->b_p_ro) {
return;
}
// Do what msg() does, but with a column offset if the warning should
@@ -70,7 +70,7 @@ void change_warning(int col)
ui_flush();
os_delay(1002L, true); // give the user time to think about it
}
- curbuf->b_did_warn = true;
+ buf->b_did_warn = true;
redraw_cmdline = false; // don't redraw and erase the message
if (msg_row < Rows - 1) {
showmode();
@@ -91,7 +91,7 @@ void changed(void)
// Give a warning about changing a read-only file. This may also
// check-out the file, thus change "curbuf"!
- change_warning(0);
+ change_warning(curbuf, 0);
// Create a swap file if that is wanted.
// Don't do this for "nofile" and "nowrite" buffer types.
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index 53cb14bcc7..d462cea9dd 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -1334,9 +1334,9 @@ static void set_diff_option(win_T *wp, int value)
curwin = wp;
curbuf = curwin->w_buffer;
- curbuf_lock++;
+ curbuf->b_ro_locked++;
set_option_value("diff", (long)value, NULL, OPT_LOCAL);
- curbuf_lock--;
+ curbuf->b_ro_locked--;
curwin = old_curwin;
curbuf = curwin->w_buffer;
}
@@ -2603,7 +2603,7 @@ void ex_diffgetput(exarg_T *eap)
// FileChangedRO autocommand, which may do nasty things and mess
// everything up.
if (!curbuf->b_changed) {
- change_warning(0);
+ change_warning(curbuf, 0);
if (diff_buf_idx(curbuf) != idx_to) {
EMSG(_("E787: Buffer changed unexpectedly"));
goto theend;
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 5887817ec3..1fe8c0e8e9 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -467,7 +467,7 @@ static void insert_enter(InsertState *s)
}
if (!p_im && did_restart_edit == 0) {
- change_warning(s->i == 0 ? 0 : s->i + 1);
+ change_warning(curbuf, s->i == 0 ? 0 : s->i + 1);
}
ui_cursor_shape(); // may show different cursor shape
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 1ba31bfe68..3cda7ec5d4 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -1078,10 +1078,11 @@ static void f_complete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- /* Check for undo allowed here, because if something was already inserted
- * the line was already saved for undo and this check isn't done. */
- if (!undo_allowed())
+ // Check for undo allowed here, because if something was already inserted
+ // the line was already saved for undo and this check isn't done.
+ if (!undo_allowed(curbuf)) {
return;
+ }
if (argvars[1].v_type != VAR_LIST) {
EMSG(_(e_invarg));
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 4af7794317..c5400f8781 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -2607,7 +2607,7 @@ int do_ecmd(
&& (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur)) {
// Sync first so that this is a separate undo-able action.
u_sync(false);
- if (u_savecommon(0, curbuf->b_ml.ml_line_count + 1, 0, true)
+ if (u_savecommon(curbuf, 0, curbuf->b_ml.ml_line_count + 1, 0, true)
== FAIL) {
xfree(new_name);
goto theend;
@@ -5159,9 +5159,9 @@ void fix_help_buffer(void)
// Set filetype to "help".
if (STRCMP(curbuf->b_p_ft, "help") != 0) {
- curbuf_lock++;
+ curbuf->b_ro_locked++;
set_option_value("ft", 0L, "help", OPT_LOCAL);
- curbuf_lock--;
+ curbuf->b_ro_locked--;
}
if (!syntax_present(curwin)) {
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index f63987136f..2dfe2950fc 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -2412,13 +2412,11 @@ char_u * get_text_locked_msg(void) {
}
}
-/*
- * Check if "curbuf_lock" or "allbuf_lock" is set and return TRUE when it is
- * and give an error message.
- */
+/// Check if "curbuf_lock" or "allbuf_lock" is set and return TRUE when it is
+/// and give an error message.
int curbuf_locked(void)
{
- if (curbuf_lock > 0) {
+ if (curbuf->b_ro_locked > 0) {
EMSG(_("E788: Not allowed to edit another buffer now"));
return TRUE;
}
@@ -6513,7 +6511,7 @@ static int open_cmdwin(void)
curwin->w_p_fen = false;
// Don't allow switching to another buffer.
- curbuf_lock++;
+ curbuf->b_ro_locked++;
// Showing the prompt may have set need_wait_return, reset it.
need_wait_return = false;
@@ -6526,7 +6524,7 @@ static int open_cmdwin(void)
}
set_option_value("ft", 0L, "vim", OPT_LOCAL);
}
- curbuf_lock--;
+ curbuf->b_ro_locked--;
// Reset 'textwidth' after setting 'filetype' (the Vim filetype plugin
// sets 'textwidth' to 78).
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 645423eafe..5d44a70a05 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -4687,7 +4687,7 @@ check_timestamps(
}
if (!stuff_empty() || global_busy || !typebuf_typed()
- || autocmd_busy || curbuf_lock > 0 || allbuf_lock > 0
+ || autocmd_busy || curbuf->b_ro_locked > 0 || allbuf_lock > 0
) {
need_check_timestamps = true; // check later
} else {
@@ -5015,10 +5015,10 @@ void buf_reload(buf_T *buf, int orig_mode)
old_topline = curwin->w_topline;
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. */
- u_sync(FALSE);
- saved = u_savecommon(0, curbuf->b_ml.ml_line_count + 1, 0, TRUE);
+ // Save all the text, so that the reload can be undone.
+ // Sync first so that this is a separate undo-able action.
+ u_sync(false);
+ saved = u_savecommon(curbuf, 0, curbuf->b_ml.ml_line_count + 1, 0, true);
flags |= READ_KEEP_UNDO;
}
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 7c7ce5e65f..a7959bcfe3 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -508,9 +508,6 @@ EXTERN int secure INIT(= false);
/// allowed.
EXTERN int textlock INIT(= 0);
-/// Non-zero when the current buffer can't be changed. Used for FileChangedRO.
-EXTERN int curbuf_lock INIT(= 0);
-
/// Non-zero when no buffer name can be changed, no buffer can be deleted and
/// current directory can't be changed. Used for SwapExists et al.
EXTERN int allbuf_lock INIT(= 0);
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 71624baaf4..77f86e75cc 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -4180,7 +4180,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last,
// Set the 'filetype' to "qf" each time after filling the buffer. This
// resembles reading a file into a buffer, it's more logical when using
// autocommands.
- curbuf_lock++;
+ curbuf->b_locked++;
set_option_value("ft", 0L, "qf", OPT_LOCAL);
curbuf->b_p_ma = false;
@@ -4190,7 +4190,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last,
apply_autocmds(EVENT_BUFWINENTER, (char_u *)"quickfix", NULL,
false, curbuf);
keep_filetype = false;
- curbuf_lock--;
+ curbuf->b_locked--;
// make sure it will be redrawn
redraw_curbuf_later(NOT_VALID);
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index 2010aa42d8..ea254033f1 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -234,7 +234,7 @@ int u_save(linenr_T top, linenr_T bot)
if (top + 2 == bot)
u_saveline((linenr_T)(top + 1));
- return u_savecommon(top, bot, (linenr_T)0, FALSE);
+ return u_savecommon(curbuf, top, bot, (linenr_T)0, false);
}
/*
@@ -245,7 +245,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(curbuf, lnum - 1, lnum + 1, lnum + 1, false);
}
/*
@@ -256,7 +256,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(curbuf, lnum - 1, lnum, lnum + 1, false);
}
/*
@@ -268,18 +268,19 @@ int u_inssub(linenr_T lnum)
*/
int u_savedel(linenr_T lnum, long nlines)
{
- return u_savecommon(lnum - 1, lnum + nlines,
- nlines == curbuf->b_ml.ml_line_count ? 2 : lnum, FALSE);
+ return u_savecommon(
+ curbuf, lnum - 1, lnum + nlines,
+ nlines == curbuf->b_ml.ml_line_count ? 2 : lnum, false);
}
/// Return true when undo is allowed. Otherwise print an error message and
/// return false.
///
/// @return true if undo is allowed.
-bool undo_allowed(void)
+bool undo_allowed(buf_T *buf)
{
- /* Don't allow changes when 'modifiable' is off. */
- if (!MODIFIABLE(curbuf)) {
+ // Don't allow changes when 'modifiable' is off.
+ if (!MODIFIABLE(buf)) {
EMSG(_(e_modifiable));
return false;
}
@@ -301,12 +302,12 @@ bool undo_allowed(void)
}
/// Get the 'undolevels' value for the current buffer.
-static long get_undolevel(void)
+static long get_undolevel(buf_T *buf)
{
- if (curbuf->b_p_ul == NO_LOCAL_UNDOLEVEL) {
+ if (buf->b_p_ul == NO_LOCAL_UNDOLEVEL) {
return p_ul;
}
- return curbuf->b_p_ul;
+ return buf->b_p_ul;
}
static inline void zero_fmark_additional_data(fmark_T *fmarks)
@@ -326,7 +327,9 @@ static inline void zero_fmark_additional_data(fmark_T *fmarks)
* Careful: may trigger autocommands that reload the buffer.
* Returns FAIL when lines could not be saved, OK otherwise.
*/
-int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
+int u_savecommon(buf_T *buf,
+ linenr_T top, linenr_T bot,
+ linenr_T newbot, int reload)
{
linenr_T lnum;
long i;
@@ -337,22 +340,24 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
long size;
if (!reload) {
- /* When making changes is not allowed return FAIL. It's a crude way
- * to make all change commands fail. */
- if (!undo_allowed())
+ // When making changes is not allowed return FAIL. It's a crude way
+ // to make all change commands fail.
+ if (!undo_allowed(buf)) {
return FAIL;
+ }
+ // Saving text for undo means we are going to make a change. Give a
+ // warning for a read-only file before making the change, so that the
+ // FileChangedRO event can replace the buffer with a read-write version
+ // (e.g., obtained from a source control system).
+ // TODO(vigoux): change_warning is tricky because of curbuf_lock...
+ if (buf == curbuf) {
+ change_warning(buf, 0);
+ }
- /*
- * Saving text for undo means we are going to make a change. Give a
- * warning for a read-only file before making the change, so that the
- * FileChangedRO event can replace the buffer with a read-write version
- * (e.g., obtained from a source control system).
- */
- change_warning(0);
- if (bot > curbuf->b_ml.ml_line_count + 1) {
- /* This happens when the FileChangedRO autocommand changes the
- * file in a way it becomes shorter. */
+ if (bot > buf->b_ml.ml_line_count + 1) {
+ // This happens when the FileChangedRO autocommand changes the
+ // file in a way it becomes shorter.
EMSG(_("E881: Line count changed unexpectedly"));
return FAIL;
}
@@ -364,18 +369,14 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
size = bot - top - 1;
- /*
- * If curbuf->b_u_synced == true make a new header.
- */
- if (curbuf->b_u_synced) {
- /* Need to create new entry in b_changelist. */
- curbuf->b_new_change = true;
-
- if (get_undolevel() >= 0) {
- /*
- * Make a new header entry. Do this first so that we don't mess
- * up the undo info when out of memory.
- */
+ // If curbuf->b_u_synced == true make a new header.
+ if (buf->b_u_synced) {
+ // Need to create new entry in b_changelist.
+ buf->b_new_change = true;
+
+ if (get_undolevel(buf) >= 0) {
+ // Make a new header entry. Do this first so that we don't mess
+ // up the undo info when out of memory.
uhp = xmalloc(sizeof(u_header_T));
kv_init(uhp->uh_extmark);
#ifdef U_DEBUG
@@ -388,63 +389,73 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
* If we undid more than we redid, move the entry lists before and
* including curbuf->b_u_curhead to an alternate branch.
*/
- old_curhead = curbuf->b_u_curhead;
+ old_curhead = buf->b_u_curhead;
if (old_curhead != NULL) {
- curbuf->b_u_newhead = old_curhead->uh_next.ptr;
- curbuf->b_u_curhead = NULL;
+ buf->b_u_newhead = old_curhead->uh_next.ptr;
+ buf->b_u_curhead = NULL;
}
/*
* free headers to keep the size right
*/
- while (curbuf->b_u_numhead > get_undolevel()
- && curbuf->b_u_oldhead != NULL) {
- u_header_T *uhfree = curbuf->b_u_oldhead;
-
- if (uhfree == old_curhead)
- /* Can't reconnect the branch, delete all of it. */
- u_freebranch(curbuf, uhfree, &old_curhead);
- else if (uhfree->uh_alt_next.ptr == NULL)
- /* There is no branch, only free one header. */
- u_freeheader(curbuf, uhfree, &old_curhead);
- else {
- /* Free the oldest alternate branch as a whole. */
- while (uhfree->uh_alt_next.ptr != NULL)
+ while (buf->b_u_numhead > get_undolevel(buf)
+ && buf->b_u_oldhead != NULL) {
+ u_header_T *uhfree = buf->b_u_oldhead;
+
+ if (uhfree == old_curhead) {
+ // Can't reconnect the branch, delete all of it.
+ u_freebranch(buf, uhfree, &old_curhead);
+ } else if (uhfree->uh_alt_next.ptr == NULL) {
+ // There is no branch, only free one header.
+ u_freeheader(buf, uhfree, &old_curhead);
+ } else {
+ // Free the oldest alternate branch as a whole.
+ while (uhfree->uh_alt_next.ptr != NULL) {
uhfree = uhfree->uh_alt_next.ptr;
- u_freebranch(curbuf, uhfree, &old_curhead);
+ }
+ u_freebranch(buf, uhfree, &old_curhead);
}
#ifdef U_DEBUG
u_check(TRUE);
#endif
}
- if (uhp == NULL) { /* no undo at all */
- if (old_curhead != NULL)
- u_freebranch(curbuf, old_curhead, NULL);
- curbuf->b_u_synced = false;
+ if (uhp == NULL) { // no undo at all
+ if (old_curhead != NULL) {
+ u_freebranch(buf, old_curhead, NULL);
+ }
+ buf->b_u_synced = false;
return OK;
}
uhp->uh_prev.ptr = NULL;
- uhp->uh_next.ptr = curbuf->b_u_newhead;
+ uhp->uh_next.ptr = buf->b_u_newhead;
uhp->uh_alt_next.ptr = old_curhead;
if (old_curhead != NULL) {
uhp->uh_alt_prev.ptr = old_curhead->uh_alt_prev.ptr;
- if (uhp->uh_alt_prev.ptr != NULL)
+
+ if (uhp->uh_alt_prev.ptr != NULL) {
uhp->uh_alt_prev.ptr->uh_alt_next.ptr = uhp;
+ }
+
old_curhead->uh_alt_prev.ptr = uhp;
- if (curbuf->b_u_oldhead == old_curhead)
- curbuf->b_u_oldhead = uhp;
- } else
+
+ if (buf->b_u_oldhead == old_curhead) {
+ buf->b_u_oldhead = uhp;
+ }
+ } else {
uhp->uh_alt_prev.ptr = NULL;
- if (curbuf->b_u_newhead != NULL)
- curbuf->b_u_newhead->uh_prev.ptr = uhp;
+ }
- uhp->uh_seq = ++curbuf->b_u_seq_last;
- curbuf->b_u_seq_cur = uhp->uh_seq;
+ if (buf->b_u_newhead != NULL) {
+ buf->b_u_newhead->uh_prev.ptr = uhp;
+ }
+
+ uhp->uh_seq = ++buf->b_u_seq_last;
+ buf->b_u_seq_cur = uhp->uh_seq;
uhp->uh_time = time(NULL);
uhp->uh_save_nr = 0;
- curbuf->b_u_time_cur = uhp->uh_time + 1;
+ buf->b_u_time_cur = uhp->uh_time + 1;
uhp->uh_walk = 0;
uhp->uh_entry = NULL;
@@ -455,23 +466,26 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
else
uhp->uh_cursor_vcol = -1;
- /* save changed and buffer empty flag for undo */
- uhp->uh_flags = (curbuf->b_changed ? UH_CHANGED : 0) +
- ((curbuf->b_ml.ml_flags & ML_EMPTY) ? UH_EMPTYBUF : 0);
+ // save changed and buffer empty flag for undo
+ uhp->uh_flags = (buf->b_changed ? UH_CHANGED : 0) +
+ ((buf->b_ml.ml_flags & ML_EMPTY) ? UH_EMPTYBUF : 0);
+
+ // save named marks and Visual marks for undo
+ zero_fmark_additional_data(buf->b_namedm);
+ memmove(uhp->uh_namedm, buf->b_namedm,
+ sizeof(buf->b_namedm[0]) * NMARKS);
+ uhp->uh_visual = buf->b_visual;
- /* save named marks and Visual marks for undo */
- zero_fmark_additional_data(curbuf->b_namedm);
- memmove(uhp->uh_namedm, curbuf->b_namedm,
- sizeof(curbuf->b_namedm[0]) * NMARKS);
- uhp->uh_visual = curbuf->b_visual;
+ buf->b_u_newhead = uhp;
- curbuf->b_u_newhead = uhp;
- if (curbuf->b_u_oldhead == NULL)
- curbuf->b_u_oldhead = uhp;
- ++curbuf->b_u_numhead;
+ if (buf->b_u_oldhead == NULL) {
+ buf->b_u_oldhead = uhp;
+ }
+ buf->b_u_numhead++;
} else {
- if (get_undolevel() < 0) /* no undo at all */
+ if (get_undolevel(buf) < 0) { // no undo at all
return OK;
+ }
/*
* When saving a single line, and it has been saved just before, it
@@ -483,7 +497,7 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
* long.
*/
if (size == 1) {
- uep = u_get_headentry();
+ uep = u_get_headentry(buf);
prev_uep = NULL;
for (i = 0; i < 10; ++i) {
if (uep == NULL)
@@ -491,16 +505,17 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
/* If lines have been inserted/deleted we give up.
* Also when the line was included in a multi-line save. */
- if ((curbuf->b_u_newhead->uh_getbot_entry != uep
+ if ((buf->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
+ ? buf->b_ml.ml_line_count + 1
: uep->ue_bot))
- : uep->ue_lcount != curbuf->b_ml.ml_line_count)
+ : uep->ue_lcount != buf->b_ml.ml_line_count)
|| (uep->ue_size > 1
&& top >= uep->ue_top
- && top + 2 <= uep->ue_top + uep->ue_size + 1))
+ && top + 2 <= uep->ue_top + uep->ue_size + 1)) {
break;
+ }
/* If it's the same line we can skip saving it again. */
if (uep->ue_size == 1 && uep->ue_top == top) {
@@ -508,8 +523,8 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
/* It's not the last entry: get ue_bot for the last
* entry now. Following deleted/inserted lines go to
* the re-used entry. */
- u_getbot();
- curbuf->b_u_synced = false;
+ u_getbot(buf);
+ buf->b_u_synced = false;
/* Move the found entry to become the last entry. The
* order of undo/redo doesn't matter for the entries
@@ -518,18 +533,18 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
* for the found entry if the line count is changed by
* the executed command. */
prev_uep->ue_next = uep->ue_next;
- uep->ue_next = curbuf->b_u_newhead->uh_entry;
- curbuf->b_u_newhead->uh_entry = uep;
+ uep->ue_next = buf->b_u_newhead->uh_entry;
+ buf->b_u_newhead->uh_entry = uep;
}
- /* The executed command may change the line count. */
- if (newbot != 0)
+ // The executed command may change the line count.
+ if (newbot != 0) {
uep->ue_bot = newbot;
- else if (bot > curbuf->b_ml.ml_line_count)
+ } else if (bot > buf->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;
+ } else {
+ uep->ue_lcount = buf->b_ml.ml_line_count;
+ buf->b_u_newhead->uh_getbot_entry = uep;
}
return OK;
}
@@ -538,8 +553,8 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
}
}
- /* find line number for ue_bot for previous u_save() */
- u_getbot();
+ // find line number for ue_bot for previous u_save()
+ u_getbot(buf);
}
/*
@@ -553,17 +568,15 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
uep->ue_size = size;
uep->ue_top = top;
- if (newbot != 0)
+ if (newbot != 0) {
uep->ue_bot = newbot;
- /*
- * Use 0 for ue_bot if bot is below last line.
- * Otherwise we have to compute ue_bot later.
- */
- else if (bot > curbuf->b_ml.ml_line_count)
+ // Use 0 for ue_bot if bot is below last line.
+ // Otherwise we have to compute ue_bot later.
+ } else if (bot > buf->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;
+ } else {
+ uep->ue_lcount = buf->b_ml.ml_line_count;
+ buf->b_u_newhead->uh_getbot_entry = uep;
}
if (size > 0) {
@@ -574,17 +587,19 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
u_freeentry(uep, i);
return FAIL;
}
- uep->ue_array[i] = u_save_line(lnum++);
+ uep->ue_array[i] = u_save_line_buf(buf, lnum++);
}
- } else
+ } else {
uep->ue_array = NULL;
- uep->ue_next = curbuf->b_u_newhead->uh_entry;
- curbuf->b_u_newhead->uh_entry = uep;
+ }
+
+ uep->ue_next = buf->b_u_newhead->uh_entry;
+ buf->b_u_newhead->uh_entry = uep;
if (reload) {
// buffer was reloaded, notify text change subscribers
curbuf->b_u_newhead->uh_flags |= UH_RELOAD;
}
- curbuf->b_u_synced = false;
+ buf->b_u_synced = false;
undo_undoes = false;
#ifdef U_DEBUG
@@ -1846,8 +1861,9 @@ static void u_doit(int startcount, bool quiet, bool do_buf_event)
{
int count = startcount;
- if (!undo_allowed())
+ if (!undo_allowed(curbuf)) {
return;
+ }
u_newcount = 0;
u_oldcount = 0;
@@ -1858,15 +1874,16 @@ static void u_doit(int startcount, bool quiet, bool do_buf_event)
* needed. This may cause the file to be reloaded, that must happen
* before we do anything, because it may change curbuf->b_u_curhead
* and more. */
- change_warning(0);
+ change_warning(curbuf, 0);
if (undo_undoes) {
- if (curbuf->b_u_curhead == NULL) /* first undo */
+ if (curbuf->b_u_curhead == NULL) { // first undo
curbuf->b_u_curhead = curbuf->b_u_newhead;
- else if (get_undolevel() > 0) /* multi level undo */
- /* get next undo */
+ } else if (get_undolevel(curbuf) > 0) { // multi level undo
+ // get next undo
curbuf->b_u_curhead = curbuf->b_u_curhead->uh_next.ptr;
- /* nothing to undo */
+ }
+ // nothing to undo
if (curbuf->b_u_numhead == 0 || curbuf->b_u_curhead == NULL) {
/* stick curbuf->b_u_curhead at end */
curbuf->b_u_curhead = curbuf->b_u_oldhead;
@@ -1880,8 +1897,8 @@ static void u_doit(int startcount, bool quiet, bool do_buf_event)
u_undoredo(true, do_buf_event);
} else {
- if (curbuf->b_u_curhead == NULL || get_undolevel() <= 0) {
- beep_flush(); /* nothing to redo */
+ if (curbuf->b_u_curhead == NULL || get_undolevel(curbuf) <= 0) {
+ beep_flush(); // nothing to redo
if (count == startcount - 1) {
MSG(_("Already at newest change"));
return;
@@ -2122,8 +2139,8 @@ target_zero:
if (uhp != NULL || target == 0) {
// First go up the tree as much as needed.
while (!got_int) {
- /* Do the change warning now, for the same reason as above. */
- change_warning(0);
+ // Do the change warning now, for the same reason as above.
+ change_warning(curbuf, 0);
uhp = curbuf->b_u_curhead;
if (uhp == NULL)
@@ -2147,7 +2164,7 @@ target_zero:
// And now go down the tree (redo), branching off where needed.
while (!got_int) {
// Do the change warning now, for the same reason as above.
- change_warning(0);
+ change_warning(curbuf, 0);
uhp = curbuf->b_u_curhead;
if (uhp == NULL) {
@@ -2591,13 +2608,15 @@ u_sync(
int force // Also sync when no_u_sync is set.
)
{
- /* Skip it when already synced or syncing is disabled. */
- if (curbuf->b_u_synced || (!force && no_u_sync > 0))
+ // Skip it when already synced or syncing is disabled.
+ if (curbuf->b_u_synced || (!force && no_u_sync > 0)) {
return;
- if (get_undolevel() < 0)
- curbuf->b_u_synced = true; /* no entries, nothing to do */
- else {
- u_getbot(); /* compute ue_bot of previous u_save */
+ }
+
+ if (get_undolevel(curbuf) < 0) {
+ curbuf->b_u_synced = true; // no entries, nothing to do
+ } else {
+ u_getbot(curbuf); // compute ue_bot of previous u_save
curbuf->b_u_curhead = NULL;
}
}
@@ -2708,7 +2727,7 @@ void ex_undojoin(exarg_T *eap)
if (!curbuf->b_u_synced) {
return; // already unsynced
}
- if (get_undolevel() < 0) {
+ if (get_undolevel(curbuf) < 0) {
return; // no entries, nothing to do
} else {
curbuf->b_u_synced = false; // Append next change to last entry
@@ -2792,38 +2811,39 @@ static void u_unch_branch(u_header_T *uhp)
* Get pointer to last added entry.
* If it's not valid, give an error message and return NULL.
*/
-static u_entry_T *u_get_headentry(void)
+static u_entry_T *u_get_headentry(buf_T *buf)
{
- if (curbuf->b_u_newhead == NULL || curbuf->b_u_newhead->uh_entry == NULL) {
+ if (buf->b_u_newhead == NULL || buf->b_u_newhead->uh_entry == NULL) {
IEMSG(_("E439: undo list corrupt"));
return NULL;
}
- return curbuf->b_u_newhead->uh_entry;
+ return buf->b_u_newhead->uh_entry;
}
/*
* u_getbot(): compute the line number of the previous u_save
* It is called only when b_u_synced is false.
*/
-static void u_getbot(void)
+static void u_getbot(buf_T *buf)
{
u_entry_T *uep;
linenr_T extra;
- uep = u_get_headentry(); /* check for corrupt undo list */
- if (uep == NULL)
+ uep = u_get_headentry(buf); // check for corrupt undo list
+ if (uep == NULL) {
return;
+ }
- uep = curbuf->b_u_newhead->uh_getbot_entry;
+ uep = buf->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;
+ extra = buf->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) {
+ if (uep->ue_bot < 1 || uep->ue_bot > buf->b_ml.ml_line_count) {
IEMSG(_("E440: undo line missing"));
uep->ue_bot = uep->ue_top + 1; // assume all lines deleted, will
// get all the old lines back
@@ -2831,10 +2851,10 @@ static void u_getbot(void)
// ones
}
- curbuf->b_u_newhead->uh_getbot_entry = NULL;
+ buf->b_u_newhead->uh_getbot_entry = NULL;
}
- curbuf->b_u_synced = true;
+ buf->b_u_synced = true;
}
/*
@@ -3014,10 +3034,12 @@ void u_undoline(void)
return;
}
- /* first save the line for the 'u' command */
- if (u_savecommon(curbuf->b_u_line_lnum - 1,
- curbuf->b_u_line_lnum + 1, (linenr_T)0, FALSE) == FAIL)
+ // first save the line for the 'u' command
+ if (u_savecommon(curbuf, curbuf->b_u_line_lnum - 1,
+ curbuf->b_u_line_lnum + 1, (linenr_T)0, false) == FAIL) {
return;
+ }
+
oldp = u_save_line(curbuf->b_u_line_lnum);
ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, true);
changed_bytes(curbuf->b_u_line_lnum, 0);
@@ -3048,12 +3070,21 @@ void u_blockfree(buf_T *buf)
xfree(buf->b_u_line_ptr);
}
-/*
- * u_save_line(): allocate memory and copy line 'lnum' into it.
- */
+/// Allocate memory and copy curbuf line into it.
+///
+/// @param lnum the line to copy
static char_u *u_save_line(linenr_T lnum)
{
- return vim_strsave(ml_get(lnum));
+ return u_save_line_buf(curbuf, lnum);
+}
+
+/// Allocate memory and copy line into it
+///
+/// @param lnum line to copy
+/// @param buf buffer to copy from
+static char_u *u_save_line_buf(buf_T *buf, linenr_T lnum)
+{
+ return vim_strsave(ml_get_buf(buf, lnum, false));
}
/// Check if the 'modified' flag is set, or 'ff' has changed (only need to
@@ -3146,11 +3177,13 @@ u_header_T *u_force_get_undo_header(buf_T *buf)
buf_T *save_curbuf = curbuf;
curbuf = buf;
// Args are tricky: this means replace empty range by empty range..
- u_savecommon(0, 1, 1, true);
+ u_savecommon(curbuf, 0, 1, 1, true);
+ curbuf = save_curbuf;
+
uhp = buf->b_u_curhead;
if (!uhp) {
uhp = buf->b_u_newhead;
- if (get_undolevel() > 0 && !uhp) {
+ if (get_undolevel(curbuf) > 0 && !uhp) {
abort();
}
}