aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/buffer.c97
-rw-r--r--src/nvim/api/vim.c17
-rw-r--r--src/nvim/buffer.c20
-rw-r--r--src/nvim/change.c122
-rw-r--r--src/nvim/cursor.c20
-rw-r--r--src/nvim/diff.c15
-rw-r--r--src/nvim/drawscreen.c2
-rw-r--r--src/nvim/edit.c2
-rw-r--r--src/nvim/eval/buffer.c3
-rw-r--r--src/nvim/ex_cmds.c37
-rw-r--r--src/nvim/ex_docmd.c2
-rw-r--r--src/nvim/ex_getln.c6
-rw-r--r--src/nvim/fileio.c4
-rw-r--r--src/nvim/fold.c6
-rw-r--r--src/nvim/help.c2
-rw-r--r--src/nvim/indent.c4
-rw-r--r--src/nvim/insexpand.c2
-rw-r--r--src/nvim/log.c12
-rw-r--r--src/nvim/mark.c84
-rw-r--r--src/nvim/memline.c22
-rw-r--r--src/nvim/move.c21
-rw-r--r--src/nvim/normal.c8
-rw-r--r--src/nvim/ops.c36
-rw-r--r--src/nvim/optionstr.c13
-rw-r--r--src/nvim/quickfix.c11
-rw-r--r--src/nvim/sign.c19
-rw-r--r--src/nvim/terminal.c2
-rw-r--r--src/nvim/undo.c43
-rw-r--r--src/nvim/window.c8
29 files changed, 343 insertions, 297 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 4e3468f8d1..775b6e8ea7 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -386,27 +386,29 @@ void nvim_buf_set_lines(uint64_t channel_id, Buffer buffer, Integer start, Integ
}
try_start();
- aco_save_T aco;
- aucmd_prepbuf(&aco, buf);
if (!MODIFIABLE(buf)) {
api_set_error(err, kErrorTypeException, "Buffer is not 'modifiable'");
goto end;
}
- if (u_save((linenr_T)(start - 1), (linenr_T)end) == FAIL) {
+ if (!buf_ensure_loaded(buf)) {
+ goto end;
+ }
+
+ if (u_save_buf(buf, (linenr_T)(start - 1), (linenr_T)end) == FAIL) {
api_set_error(err, kErrorTypeException, "Failed to save undo information");
goto end;
}
- bcount_t deleted_bytes = get_region_bytecount(curbuf, (linenr_T)start, (linenr_T)end, 0, 0);
+ bcount_t deleted_bytes = get_region_bytecount(buf, (linenr_T)start, (linenr_T)end, 0, 0);
// If the size of the range is reducing (ie, new_len < old_len) we
// need to delete some old_len. We do this at the start, by
// repeatedly deleting line "start".
size_t to_delete = (new_len < old_len) ? old_len - new_len : 0;
for (size_t i = 0; i < to_delete; i++) {
- if (ml_delete((linenr_T)start, false) == FAIL) {
+ if (ml_delete_buf(buf, (linenr_T)start, false) == FAIL) {
api_set_error(err, kErrorTypeException, "Failed to delete line");
goto end;
}
@@ -428,7 +430,7 @@ void nvim_buf_set_lines(uint64_t channel_id, Buffer buffer, Integer start, Integ
goto end;
});
- if (ml_replace((linenr_T)lnum, lines[i], false) == FAIL) {
+ if (ml_replace_buf(buf, (linenr_T)lnum, lines[i], false) == FAIL) {
api_set_error(err, kErrorTypeException, "Failed to replace line");
goto end;
}
@@ -447,7 +449,7 @@ void nvim_buf_set_lines(uint64_t channel_id, Buffer buffer, Integer start, Integ
goto end;
});
- if (ml_append((linenr_T)lnum, lines[i], 0, false) == FAIL) {
+ if (ml_append_buf(buf, (linenr_T)lnum, lines[i], 0, false) == FAIL) {
api_set_error(err, kErrorTypeException, "Failed to insert line");
goto end;
}
@@ -462,20 +464,18 @@ void nvim_buf_set_lines(uint64_t channel_id, Buffer buffer, Integer start, Integ
// Adjust marks. Invalidate any which lie in the
// changed range, and move any in the remainder of the buffer.
- // Only adjust marks if we managed to switch to a window that holds
- // the buffer, otherwise line numbers will be invalid.
- mark_adjust((linenr_T)start,
- (linenr_T)(end - 1),
- MAXLNUM,
- (linenr_T)extra,
- kExtmarkNOOP);
-
- extmark_splice(curbuf, (int)start - 1, 0, (int)(end - start), 0,
+ mark_adjust_buf(buf, (linenr_T)start, (linenr_T)(end - 1), MAXLNUM, (linenr_T)extra,
+ true, true, kExtmarkNOOP);
+
+ extmark_splice(buf, (int)start - 1, 0, (int)(end - start), 0,
deleted_bytes, (int)new_len, 0, inserted_bytes,
kExtmarkUndo);
- changed_lines((linenr_T)start, 0, (linenr_T)end, (linenr_T)extra, true);
- fix_cursor((linenr_T)start, (linenr_T)end, (linenr_T)extra);
+ changed_lines(buf, (linenr_T)start, 0, (linenr_T)end, (linenr_T)extra, true);
+ if (curwin->w_buffer == buf) {
+ // mark_adjust_buf handles non-current windows
+ fix_cursor(curwin, (linenr_T)start, (linenr_T)end, (linenr_T)extra);
+ }
end:
for (size_t i = 0; i < new_len; i++) {
@@ -483,7 +483,6 @@ end:
}
xfree(lines);
- aucmd_restbuf(&aco);
try_end(err);
}
@@ -630,17 +629,19 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In
}
try_start();
- aco_save_T aco;
- aucmd_prepbuf(&aco, buf);
if (!MODIFIABLE(buf)) {
api_set_error(err, kErrorTypeException, "Buffer is not 'modifiable'");
goto end;
}
+ if (!buf_ensure_loaded(buf)) {
+ goto end;
+ }
+
// Small note about undo states: unlike set_lines, we want to save the
// undo state of one past the end_row, since end_row is inclusive.
- if (u_save((linenr_T)start_row - 1, (linenr_T)end_row + 1) == FAIL) {
+ if (u_save_buf(buf, (linenr_T)start_row - 1, (linenr_T)end_row + 1) == FAIL) {
api_set_error(err, kErrorTypeException, "Failed to save undo information");
goto end;
}
@@ -653,7 +654,7 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In
// repeatedly deleting line "start".
size_t to_delete = (new_len < old_len) ? old_len - new_len : 0;
for (size_t i = 0; i < to_delete; i++) {
- if (ml_delete((linenr_T)start_row, false) == FAIL) {
+ if (ml_delete_buf(buf, (linenr_T)start_row, false) == FAIL) {
api_set_error(err, kErrorTypeException, "Failed to delete line");
goto end;
}
@@ -674,7 +675,7 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In
goto end;
});
- if (ml_replace((linenr_T)lnum, lines[i], false) == FAIL) {
+ if (ml_replace_buf(buf, (linenr_T)lnum, lines[i], false) == FAIL) {
api_set_error(err, kErrorTypeException, "Failed to replace line");
goto end;
}
@@ -691,7 +692,7 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In
goto end;
});
- if (ml_append((linenr_T)lnum, lines[i], 0, false) == FAIL) {
+ if (ml_append_buf(buf, (linenr_T)lnum, lines[i], 0, false) == FAIL) {
api_set_error(err, kErrorTypeException, "Failed to insert line");
goto end;
}
@@ -702,35 +703,37 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In
extra++;
}
+ colnr_T col_extent = (colnr_T)(end_col
+ - ((end_row == start_row) ? start_col : 0));
+
// Adjust marks. Invalidate any which lie in the
// changed range, and move any in the remainder of the buffer.
- mark_adjust((linenr_T)start_row,
- (linenr_T)end_row,
- MAXLNUM,
- (linenr_T)extra,
- kExtmarkNOOP);
+ // Do not adjust any cursors. need to use column-aware logic (below)
+ mark_adjust_buf(buf, (linenr_T)start_row, (linenr_T)end_row, MAXLNUM, (linenr_T)extra,
+ true, false, kExtmarkNOOP);
- colnr_T col_extent = (colnr_T)(end_col
- - ((end_row == start_row) ? start_col : 0));
extmark_splice(buf, (int)start_row - 1, (colnr_T)start_col,
(int)(end_row - start_row), col_extent, old_byte,
(int)new_len - 1, (colnr_T)last_item.size, new_byte,
kExtmarkUndo);
- changed_lines((linenr_T)start_row, 0, (linenr_T)end_row + 1, (linenr_T)extra, true);
+ changed_lines(buf, (linenr_T)start_row, 0, (linenr_T)end_row + 1, (linenr_T)extra, true);
- // adjust cursor like an extmark ( i e it was inside last_part_len)
- if (curwin->w_cursor.lnum == end_row && curwin->w_cursor.col > end_col) {
- curwin->w_cursor.col -= col_extent - (colnr_T)last_item.size;
+ FOR_ALL_TAB_WINDOWS(tp, win) {
+ if (win->w_buffer == buf) {
+ // adjust cursor like an extmark ( i e it was inside last_part_len)
+ if (win->w_cursor.lnum == end_row && win->w_cursor.col > end_col) {
+ win->w_cursor.col -= col_extent - (colnr_T)last_item.size;
+ }
+ fix_cursor(win, (linenr_T)start_row, (linenr_T)end_row, (linenr_T)extra);
+ }
}
- fix_cursor((linenr_T)start_row, (linenr_T)end_row, (linenr_T)extra);
end:
for (size_t i = 0; i < new_len; i++) {
xfree(lines[i]);
}
xfree(lines);
- aucmd_restbuf(&aco);
try_end(err);
early_end:
@@ -1317,21 +1320,19 @@ Dictionary nvim__buf_stats(Buffer buffer, Error *err)
// Check if deleting lines made the cursor position invalid.
// Changed lines from `lo` to `hi`; added `extra` lines (negative if deleted).
-static void fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
+static void fix_cursor(win_T *win, linenr_T lo, linenr_T hi, linenr_T extra)
{
- if (curwin->w_cursor.lnum >= lo) {
+ if (win->w_cursor.lnum >= lo) {
// Adjust cursor position if it's in/after the changed lines.
- if (curwin->w_cursor.lnum >= hi) {
- curwin->w_cursor.lnum += extra;
- check_cursor_col();
+ if (win->w_cursor.lnum >= hi) {
+ win->w_cursor.lnum += extra;
} else if (extra < 0) {
- check_cursor();
- } else {
- check_cursor_col();
+ check_cursor_lnum(win);
}
- changed_cline_bef_curs();
+ check_cursor_col_win(win);
+ changed_cline_bef_curs(win);
}
- invalidate_botline();
+ invalidate_botline(win);
}
/// Initialise a string array either:
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 4179ae40b8..b278a21d8e 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -912,14 +912,17 @@ Buffer nvim_create_buf(Boolean listed, Boolean scratch, Error *err)
goto fail;
}
+ // Only strictly needed for scratch, but could just as well be consistent
+ // and do this now. buffer is created NOW, not when it latter first happen
+ // to reach a window or aucmd_prepbuf() ..
+ buf_copy_options(buf, BCO_ENTER | BCO_NOHELP);
+
if (scratch) {
- aco_save_T aco;
- aucmd_prepbuf(&aco, buf);
- set_option_value("bufhidden", STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL);
- set_option_value("buftype", STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL);
- set_option_value("swapfile", BOOLEAN_OPTVAL(false), OPT_LOCAL);
- set_option_value("modeline", BOOLEAN_OPTVAL(false), OPT_LOCAL); // 'nomodeline'
- aucmd_restbuf(&aco);
+ set_string_option_direct_in_buf(buf, "bufhidden", -1, "hide", OPT_LOCAL, 0);
+ set_string_option_direct_in_buf(buf, "buftype", -1, "nofile", OPT_LOCAL, 0);
+ assert(buf->b_ml.ml_mfp->mf_fd < 0); // ml_open() should not have opened swapfile already
+ buf->b_p_swf = false;
+ buf->b_p_ml = false;
}
return buf->b_fnum;
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 1e093916d3..9c061269f1 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -164,7 +164,7 @@ static int read_buffer(int read_stdin, exarg_T *eap, int flags)
// Set or reset 'modified' before executing autocommands, so that
// it can be changed there.
if (!readonlymode && !buf_is_empty(curbuf)) {
- changed();
+ changed(curbuf);
} else if (retval != FAIL) {
unchanged(curbuf, false, true);
}
@@ -175,20 +175,22 @@ static int read_buffer(int read_stdin, exarg_T *eap, int flags)
return retval;
}
-/// Ensure buffer "buf" is loaded. Does not trigger the swap-exists action.
-void buffer_ensure_loaded(buf_T *buf)
+/// Ensure buffer "buf" is loaded.
+bool buf_ensure_loaded(buf_T *buf)
{
if (buf->b_ml.ml_mfp != NULL) {
- return;
+ // already open (common case)
+ return true;
}
aco_save_T aco;
// Make sure the buffer is in a window.
aucmd_prepbuf(&aco, buf);
- swap_exists_action = SEA_NONE;
- open_buffer(false, NULL, 0);
+ // status can be OK or NOTDONE (which also means ok/done)
+ int status = open_buffer(false, NULL, 0);
aucmd_restbuf(&aco);
+ return (status != FAIL);
}
/// Open current buffer, that is: open the memfile and read the file into
@@ -343,7 +345,7 @@ int open_buffer(int read_stdin, exarg_T *eap, int flags_arg)
if ((got_int && vim_strchr(p_cpo, CPO_INTMOD) != NULL)
|| modified_was_set // ":set modified" used in autocmd
|| (aborting() && vim_strchr(p_cpo, CPO_INTMOD) != NULL)) {
- changed();
+ changed(curbuf);
} else if (retval != FAIL && !read_stdin && !read_fifo) {
unchanged(curbuf, false, true);
}
@@ -749,8 +751,6 @@ void buf_clear(void)
ml_delete((linenr_T)1, false);
}
deleted_lines_mark(1, line_count); // prepare for display
- ml_close(curbuf, true); // free memline_T
- buf_clear_file(curbuf);
}
/// buf_freeall() - free all things allocated for a buffer that are related to
@@ -2124,7 +2124,7 @@ void buflist_getfpos(void)
fpos = &buflist_findfmark(curbuf)->mark;
curwin->w_cursor.lnum = fpos->lnum;
- check_cursor_lnum();
+ check_cursor_lnum(curwin);
if (p_sol) {
curwin->w_cursor.col = 0;
diff --git a/src/nvim/change.c b/src/nvim/change.c
index 36f0fc70a1..067b48faee 100644
--- a/src/nvim/change.c
+++ b/src/nvim/change.c
@@ -101,28 +101,28 @@ void change_warning(buf_T *buf, int col)
}
}
-/// Call this function when something in the current buffer is changed.
+/// Call this function when something in a buffer is changed.
///
/// Most often called through changed_bytes() and changed_lines(), which also
/// mark the area of the display to be redrawn.
///
/// Careful: may trigger autocommands that reload the buffer.
-void changed(void)
+void changed(buf_T *buf)
{
- if (!curbuf->b_changed) {
+ if (!buf->b_changed) {
int save_msg_scroll = msg_scroll;
// Give a warning about changing a read-only file. This may also
// check-out the file, thus change "curbuf"!
- change_warning(curbuf, 0);
+ change_warning(buf, 0);
// Create a swap file if that is wanted.
// Don't do this for "nofile" and "nowrite" buffer types.
- if (curbuf->b_may_swap && !bt_dontwrite(curbuf)) {
+ if (buf->b_may_swap && !bt_dontwrite(buf)) {
bool save_need_wait_return = need_wait_return;
need_wait_return = false;
- ml_open_file(curbuf);
+ ml_open_file(buf);
// The ml_open_file() can cause an ATTENTION message.
// Wait two seconds, to make sure the user reads this unexpected
@@ -137,9 +137,9 @@ void changed(void)
need_wait_return = save_need_wait_return;
}
}
- changed_internal();
+ changed_internal(buf);
}
- buf_inc_changedtick(curbuf);
+ buf_inc_changedtick(buf);
// If a pattern is highlighted, the position may now be invalid.
highlight_match = false;
@@ -147,12 +147,12 @@ void changed(void)
/// Internal part of changed(), no user interaction.
/// Also used for recovery.
-void changed_internal(void)
+void changed_internal(buf_T *buf)
{
- curbuf->b_changed = true;
- curbuf->b_changed_invalid = true;
- ml_setflags(curbuf);
- redraw_buf_status_later(curbuf);
+ buf->b_changed = true;
+ buf->b_changed_invalid = true;
+ ml_setflags(buf);
+ redraw_buf_status_later(buf);
redraw_tabline = true;
need_maketitle = true; // set window title later
}
@@ -160,13 +160,15 @@ void changed_internal(void)
/// Common code for when a change was made.
/// See changed_lines() for the arguments.
/// Careful: may trigger autocommands that reload the buffer.
-static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume, linenr_T xtra)
+static void changed_common(buf_T *buf, linenr_T lnum, colnr_T col, linenr_T lnume, linenr_T xtra)
{
// mark the buffer as modified
- changed();
+ changed(buf);
- if (curwin->w_p_diff && diff_internal()) {
- curtab->tp_diff_update = true;
+ FOR_ALL_WINDOWS_IN_TAB(win, curtab) {
+ if (win->w_buffer == buf && win->w_p_diff && diff_internal()) {
+ curtab->tp_diff_update = true;
+ }
}
// set the '. mark
@@ -174,22 +176,25 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume, linenr_T
fmarkv_T view = INIT_FMARKV;
// Set the markview only if lnum is visible, as changes might be done
// outside of the current window view.
- if (lnum >= curwin->w_topline && lnum <= curwin->w_botline) {
- view = mark_view_make(curwin->w_topline, curwin->w_cursor);
+
+ if (curwin->w_buffer == buf) {
+ if (lnum >= curwin->w_topline && lnum <= curwin->w_botline) {
+ view = mark_view_make(curwin->w_topline, curwin->w_cursor);
+ }
}
- RESET_FMARK(&curbuf->b_last_change, ((pos_T) { lnum, col, 0 }), curbuf->handle, view);
+ RESET_FMARK(&buf->b_last_change, ((pos_T) { lnum, col, 0 }), buf->handle, view);
// Create a new entry if a new undo-able change was started or we
// don't have an entry yet.
- if (curbuf->b_new_change || curbuf->b_changelistlen == 0) {
+ if (buf->b_new_change || buf->b_changelistlen == 0) {
int add;
- if (curbuf->b_changelistlen == 0) {
+ if (buf->b_changelistlen == 0) {
add = true;
} else {
// Don't create a new entry when the line number is the same
// as the last one and the column is not too far away. Avoids
// creating many entries for typing "xxxxx".
- pos_T *p = &curbuf->b_changelist[curbuf->b_changelistlen - 1].mark;
+ pos_T *p = &buf->b_changelist[buf->b_changelistlen - 1].mark;
if (p->lnum != lnum) {
add = true;
} else {
@@ -204,17 +209,17 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume, linenr_T
// This is the first of a new sequence of undo-able changes
// and it's at some distance of the last change. Use a new
// position in the changelist.
- curbuf->b_new_change = false;
+ buf->b_new_change = false;
- if (curbuf->b_changelistlen == JUMPLISTSIZE) {
+ if (buf->b_changelistlen == JUMPLISTSIZE) {
// changelist is full: remove oldest entry
- curbuf->b_changelistlen = JUMPLISTSIZE - 1;
- memmove(curbuf->b_changelist, curbuf->b_changelist + 1,
- sizeof(curbuf->b_changelist[0]) * (JUMPLISTSIZE - 1));
+ buf->b_changelistlen = JUMPLISTSIZE - 1;
+ memmove(buf->b_changelist, buf->b_changelist + 1,
+ sizeof(buf->b_changelist[0]) * (JUMPLISTSIZE - 1));
FOR_ALL_TAB_WINDOWS(tp, wp) {
// Correct position in changelist for other windows on
// this buffer.
- if (wp->w_buffer == curbuf && wp->w_changelistidx > 0) {
+ if (wp->w_buffer == buf && wp->w_changelistidx > 0) {
wp->w_changelistidx--;
}
}
@@ -222,27 +227,29 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume, linenr_T
FOR_ALL_TAB_WINDOWS(tp, wp) {
// For other windows, if the position in the changelist is
// at the end it stays at the end.
- if (wp->w_buffer == curbuf
- && wp->w_changelistidx == curbuf->b_changelistlen) {
+ if (wp->w_buffer == buf
+ && wp->w_changelistidx == buf->b_changelistlen) {
wp->w_changelistidx++;
}
}
- curbuf->b_changelistlen++;
+ buf->b_changelistlen++;
}
}
- curbuf->b_changelist[curbuf->b_changelistlen - 1] =
- curbuf->b_last_change;
+ buf->b_changelist[buf->b_changelistlen - 1] =
+ buf->b_last_change;
// The current window is always after the last change, so that "g,"
// takes you back to it.
- curwin->w_changelistidx = curbuf->b_changelistlen;
+ if (curwin->w_buffer == buf) {
+ curwin->w_changelistidx = buf->b_changelistlen;
+ }
}
- if (VIsual_active) {
+ if (curwin->w_buffer == buf && VIsual_active) {
check_visual_pos();
}
FOR_ALL_TAB_WINDOWS(tp, wp) {
- if (wp->w_buffer == curbuf) {
+ if (wp->w_buffer == buf) {
// Mark this window to be redrawn later.
if (wp->w_redr_type < UPD_VALID) {
wp->w_redr_type = UPD_VALID;
@@ -295,7 +302,7 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume, linenr_T
if (wp->w_cursor.lnum > lnum) {
changed_line_abv_curs_win(wp);
} else if (wp->w_cursor.lnum == lnum && wp->w_cursor.col >= col) {
- changed_cline_bef_curs_win(wp);
+ changed_cline_bef_curs(wp);
}
if (wp->w_botline >= lnum) {
// Assume that botline doesn't change (inserted lines make
@@ -361,7 +368,7 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume, linenr_T
}
// when the cursor line is changed always trigger CursorMoved
- if (last_cursormoved_win == curwin
+ if (last_cursormoved_win == curwin && curwin->w_buffer == buf
&& lnum <= curwin->w_cursor.lnum
&& lnume + (xtra < 0 ? -xtra : xtra) > curwin->w_cursor.lnum) {
last_cursormoved.lnum = 0;
@@ -394,7 +401,7 @@ static void changedOneline(buf_T *buf, linenr_T lnum)
void changed_bytes(linenr_T lnum, colnr_T col)
{
changedOneline(curbuf, lnum);
- changed_common(lnum, col, lnum + 1, 0);
+ changed_common(curbuf, lnum, col, lnum + 1, 0);
// When text has been changed at the end of the line, possibly the start of
// the next line may have SpellCap that should be removed or it needs to be
// displayed. Schedule the next line for redrawing just in case.
@@ -438,14 +445,14 @@ void inserted_bytes(linenr_T lnum, colnr_T start_col, int old_col, int new_col)
/// Takes care of marking the buffer to be redrawn and sets the changed flag.
void appended_lines(linenr_T lnum, linenr_T count)
{
- changed_lines(lnum + 1, 0, lnum + 1, count, true);
+ changed_lines(curbuf, lnum + 1, 0, lnum + 1, count, true);
}
/// Like appended_lines(), but adjust marks first.
void appended_lines_mark(linenr_T lnum, int count)
{
mark_adjust(lnum + 1, (linenr_T)MAXLNUM, (linenr_T)count, 0L, kExtmarkUndo);
- changed_lines(lnum + 1, 0, lnum + 1, (linenr_T)count, true);
+ changed_lines(curbuf, lnum + 1, 0, lnum + 1, (linenr_T)count, true);
}
/// Deleted "count" lines at line "lnum" in the current buffer.
@@ -453,7 +460,7 @@ void appended_lines_mark(linenr_T lnum, int count)
/// Takes care of marking the buffer to be redrawn and sets the changed flag.
void deleted_lines(linenr_T lnum, linenr_T count)
{
- changed_lines(lnum, 0, lnum + count, -count, true);
+ changed_lines(curbuf, lnum, 0, lnum + count, -count, true);
}
/// Like deleted_lines(), but adjust marks first.
@@ -467,7 +474,7 @@ void deleted_lines_mark(linenr_T lnum, int count)
// if we deleted the entire buffer, we need to implicitly add a new empty line
extmark_adjust(curbuf, lnum, (linenr_T)(lnum + count - 1), MAXLNUM,
-(linenr_T)count + (made_empty ? 1 : 0), kExtmarkUndo);
- changed_lines(lnum, 0, lnum + (linenr_T)count, (linenr_T)(-count), true);
+ changed_lines(curbuf, lnum, 0, lnum + (linenr_T)count, (linenr_T)(-count), true);
}
/// Marks the area to be redrawn after a change.
@@ -477,7 +484,7 @@ void deleted_lines_mark(linenr_T lnum, int count)
/// @param lnum first line with change
/// @param lnume line below last changed line
/// @param xtra number of extra lines (negative when deleting)
-void changed_lines_buf(buf_T *buf, linenr_T lnum, linenr_T lnume, linenr_T xtra)
+void buf_redraw_changed_lines_later(buf_T *buf, linenr_T lnum, linenr_T lnume, linenr_T xtra)
{
if (buf->b_mod_set) {
// find the maximum area that must be redisplayed
@@ -504,7 +511,7 @@ void changed_lines_buf(buf_T *buf, linenr_T lnum, linenr_T lnume, linenr_T xtra)
}
}
-/// Changed lines for the current buffer.
+/// Changed lines for a buffer.
/// Must be called AFTER the change and after mark_adjust().
/// - mark the buffer changed by calling changed()
/// - mark the windows on this buffer to be redisplayed
@@ -522,11 +529,12 @@ void changed_lines_buf(buf_T *buf, linenr_T lnum, linenr_T lnume, linenr_T xtra)
/// @param do_buf_event some callers like undo/redo call changed_lines() and
/// then increment changedtick *again*. This flag allows these callers to send
/// the nvim_buf_lines_event events after they're done modifying changedtick.
-void changed_lines(linenr_T lnum, colnr_T col, linenr_T lnume, linenr_T xtra, bool do_buf_event)
+void changed_lines(buf_T *buf, linenr_T lnum, colnr_T col, linenr_T lnume, linenr_T xtra,
+ bool do_buf_event)
{
- changed_lines_buf(curbuf, lnum, lnume, xtra);
+ buf_redraw_changed_lines_later(buf, lnum, lnume, xtra);
- if (xtra == 0 && curwin->w_p_diff && !diff_internal()) {
+ if (xtra == 0 && curwin->w_p_diff && curwin->w_buffer == buf && !diff_internal()) {
// When the number of lines doesn't change then mark_adjust() isn't
// called and other diff buffers still need to be marked for
// displaying.
@@ -537,19 +545,19 @@ void changed_lines(linenr_T lnum, colnr_T col, linenr_T lnume, linenr_T xtra, bo
redraw_later(wp, UPD_VALID);
wlnum = diff_lnum_win(lnum, wp);
if (wlnum > 0) {
- changed_lines_buf(wp->w_buffer, wlnum,
- lnume - lnum + wlnum, 0L);
+ buf_redraw_changed_lines_later(wp->w_buffer, wlnum,
+ lnume - lnum + wlnum, 0L);
}
}
}
}
- changed_common(lnum, col, lnume, xtra);
+ changed_common(buf, lnum, col, lnume, xtra);
if (do_buf_event) {
int64_t num_added = (int64_t)(lnume + xtra - lnum);
int64_t num_removed = lnume - lnum;
- buf_updates_send_changes(curbuf, lnum, num_added, num_removed);
+ buf_updates_send_changes(buf, lnum, num_added, num_removed);
}
}
@@ -1119,7 +1127,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
*p_extra = NUL;
}
- u_clearline(); // cannot do "U" command when adding lines
+ u_clearline(curbuf); // cannot do "U" command when adding lines
did_si = false;
ai_col = 0;
@@ -1807,7 +1815,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
saved_line = NULL;
if (did_append) {
- changed_lines(curwin->w_cursor.lnum, curwin->w_cursor.col,
+ changed_lines(curbuf, curwin->w_cursor.lnum, curwin->w_cursor.col,
curwin->w_cursor.lnum + 1, 1L, true);
did_append = false;
@@ -1833,7 +1841,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
curwin->w_cursor.lnum = old_cursor.lnum + 1;
}
if (did_append) {
- changed_lines(curwin->w_cursor.lnum, 0, curwin->w_cursor.lnum, 1L, true);
+ changed_lines(curbuf, curwin->w_cursor.lnum, 0, curwin->w_cursor.lnum, 1L, true);
// bail out and just get the final length of the line we just manipulated
bcount_t extra = (bcount_t)strlen(ml_get(curwin->w_cursor.lnum));
extmark_splice(curbuf, (int)curwin->w_cursor.lnum - 1, 0,
@@ -1958,7 +1966,7 @@ void del_lines(long nlines, bool undo)
// Correct the cursor position before calling deleted_lines_mark(), it may
// trigger a callback to display the cursor.
curwin->w_cursor.col = 0;
- check_cursor_lnum();
+ check_cursor_lnum(curwin);
// adjust marks, mark the buffer as changed and prepare for displaying
deleted_lines_mark(first, n);
diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c
index f7a456f4c7..2dc903309e 100644
--- a/src/nvim/cursor.c
+++ b/src/nvim/cursor.c
@@ -324,18 +324,18 @@ void check_pos(buf_T *buf, pos_T *pos)
}
/// Make sure curwin->w_cursor.lnum is valid.
-void check_cursor_lnum(void)
+void check_cursor_lnum(win_T *win)
{
- if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
+ buf_T *buf = win->w_buffer;
+ if (win->w_cursor.lnum > buf->b_ml.ml_line_count) {
// If there is a closed fold at the end of the file, put the cursor in
// its first line. Otherwise in the last line.
- if (!hasFolding(curbuf->b_ml.ml_line_count,
- &curwin->w_cursor.lnum, NULL)) {
- curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ if (!hasFolding(buf->b_ml.ml_line_count, &win->w_cursor.lnum, NULL)) {
+ win->w_cursor.lnum = buf->b_ml.ml_line_count;
}
}
- if (curwin->w_cursor.lnum <= 0) {
- curwin->w_cursor.lnum = 1;
+ if (win->w_cursor.lnum <= 0) {
+ win->w_cursor.lnum = 1;
}
}
@@ -406,7 +406,7 @@ void check_cursor_col_win(win_T *win)
/// Make sure curwin->w_cursor in on a valid character
void check_cursor(void)
{
- check_cursor_lnum();
+ check_cursor_lnum(curwin);
check_cursor_col();
}
@@ -451,7 +451,7 @@ bool set_leftcol(colnr_T leftcol)
}
curwin->w_leftcol = leftcol;
- changed_cline_bef_curs();
+ changed_cline_bef_curs(curwin);
// TODO(hinidu): I think it should be colnr_T or int, but p_siso is long.
// Perhaps we can change p_siso to int.
int64_t lastcol = curwin->w_leftcol + curwin->w_width_inner - curwin_col_off() - 1;
@@ -481,7 +481,7 @@ bool set_leftcol(colnr_T leftcol)
retval = true;
if (coladvance(e + 1) == FAIL) { // there isn't another character
curwin->w_leftcol = s; // adjust w_leftcol instead
- changed_cline_bef_curs();
+ changed_cline_bef_curs(curwin);
}
}
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index d3bd9f7754..c5783ef00e 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -266,24 +266,25 @@ void diff_invalidate(buf_T *buf)
}
}
-/// Called by mark_adjust(): update line numbers in "curbuf".
+/// Called by mark_adjust(): update line numbers in "buf".
///
/// @param line1
/// @param line2
/// @param amount
/// @param amount_after
-void diff_mark_adjust(linenr_T line1, linenr_T line2, linenr_T amount, linenr_T amount_after)
+void diff_mark_adjust(buf_T *buf, linenr_T line1, linenr_T line2, linenr_T amount,
+ linenr_T amount_after)
{
- // Handle all tab pages that use the current buffer in a diff.
+ // Handle all tab pages that use "buf" in a diff.
FOR_ALL_TABS(tp) {
- int idx = diff_buf_idx_tp(curbuf, tp);
+ int idx = diff_buf_idx_tp(buf, tp);
if (idx != DB_COUNT) {
diff_mark_adjust_tp(tp, idx, line1, line2, amount, amount_after);
}
}
}
-/// Update line numbers in tab page "tp" for "curbuf" with index "idx".
+/// Update line numbers in tab page "tp" for the buffer with index "idx".
///
/// This attempts to update the changes as much as possible:
/// When inserting/deleting lines outside of existing change blocks, create a
@@ -2444,7 +2445,7 @@ void diff_set_topline(win_T *fromwin, win_T *towin)
}
// When w_topline changes need to recompute w_botline and cursor position
- invalidate_botline_win(towin);
+ invalidate_botline(towin);
changed_line_abv_curs_win(towin);
check_topfill(towin, false);
@@ -3144,7 +3145,7 @@ static void diffgetput(const int addr_count, const int idx_cur, const int idx_fr
}
}
extmark_adjust(curbuf, lnum, lnum + count - 1, (long)MAXLNUM, added, kExtmarkUndo);
- changed_lines(lnum, 0, lnum + count, added, true);
+ changed_lines(curbuf, lnum, 0, lnum + count, added, true);
if (did_free) {
// Diff is deleted, update folds in other windows.
diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c
index 9e25676d4e..30a5755297 100644
--- a/src/nvim/drawscreen.c
+++ b/src/nvim/drawscreen.c
@@ -329,7 +329,7 @@ void screen_resize(int width, int height)
maketitle();
changed_line_abv_curs();
- invalidate_botline();
+ invalidate_botline(curwin);
// We only redraw when it's needed:
// - While at the more prompt or executing an external command, don't
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 6a6f44f0c7..88ed1e6cb4 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -1708,7 +1708,7 @@ void change_indent(int type, int amount, int round, int replaced, int call_chang
curwin->w_cursor.col = (colnr_T)new_cursor_col;
}
curwin->w_set_curswant = true;
- changed_cline_bef_curs();
+ changed_cline_bef_curs(curwin);
// May have to adjust the start of the insert.
if (State & MODE_INSERT) {
diff --git a/src/nvim/eval/buffer.c b/src/nvim/eval/buffer.c
index 4dbfcd2938..b480d25367 100644
--- a/src/nvim/eval/buffer.c
+++ b/src/nvim/eval/buffer.c
@@ -301,7 +301,8 @@ void f_bufload(typval_T *argvars, typval_T *unused, EvalFuncData fptr)
buf_T *buf = get_buf_arg(&argvars[0]);
if (buf != NULL) {
- buffer_ensure_loaded(buf);
+ swap_exists_action = SEA_NONE;
+ buf_ensure_loaded(buf);
}
}
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index b4d07cc78a..494ebce370 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -321,7 +321,7 @@ void ex_align(exarg_T *eap)
}
(void)set_indent(new_indent, 0); // set indent
}
- changed_lines(eap->line1, 0, eap->line2 + 1, 0L, true);
+ changed_lines(curbuf, eap->line1, 0, eap->line2 + 1, 0L, true);
curwin->w_cursor = save_curpos;
beginline(BL_WHITE | BL_FIX);
}
@@ -702,7 +702,7 @@ void ex_sort(exarg_T *eap)
(int)count, 0, old_count,
lnum - eap->line2, 0, new_count, kExtmarkUndo);
- changed_lines(eap->line1, 0, eap->line2 + 1, -deleted, true);
+ changed_lines(curbuf, eap->line1, 0, eap->line2 + 1, -deleted, true);
}
curwin->w_cursor.lnum = eap->line1;
@@ -784,7 +784,7 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
mark_adjust_nofold(line1, line2, last_line - line2, 0L, kExtmarkNOOP);
disable_fold_update++;
- changed_lines(last_line - num_lines + 1, 0, last_line + 1, num_lines, false);
+ changed_lines(curbuf, last_line - num_lines + 1, 0, last_line + 1, num_lines, false);
disable_fold_update--;
int line_off = 0;
@@ -821,7 +821,7 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
-(last_line - dest - extra), 0L, kExtmarkNOOP);
disable_fold_update++;
- changed_lines(last_line - num_lines + 1, 0, last_line + 1, -extra, false);
+ changed_lines(curbuf, last_line - num_lines + 1, 0, last_line + 1, -extra, false);
disable_fold_update--;
// send update regarding the new lines that were added
@@ -859,9 +859,9 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
if (dest > last_line + 1) {
dest = last_line + 1;
}
- changed_lines(line1, 0, dest, 0L, false);
+ changed_lines(curbuf, line1, 0, dest, 0L, false);
} else {
- changed_lines(dest + 1, 0, line1 + num_lines, 0L, false);
+ changed_lines(curbuf, dest + 1, 0, line1 + num_lines, 0L, false);
}
// send nvim_buf_lines_event regarding lines that were deleted
@@ -1124,7 +1124,7 @@ static void do_filter(linenr_T line1, linenr_T line2, exarg_T *eap, char *cmd, b
curwin->w_cursor.lnum = line1;
curwin->w_cursor.col = 0;
changed_line_abv_curs();
- invalidate_botline();
+ invalidate_botline(curwin);
// When using temp files:
// 1. * Form temp file names
@@ -2088,7 +2088,7 @@ int getfile(int fnum, char *ffname_arg, char *sfname_arg, int setpm, linenr_T ln
if (lnum != 0) {
curwin->w_cursor.lnum = lnum;
}
- check_cursor_lnum();
+ check_cursor_lnum(curwin);
beginline(BL_SOL | BL_FIX);
retval = GETFILE_SAME_FILE; // it's in the same file
} else if (do_ecmd(fnum, ffname, sfname, NULL, lnum,
@@ -2652,7 +2652,7 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum
check_cursor();
} else if (newlnum > 0) { // line number from caller or old position
curwin->w_cursor.lnum = newlnum;
- check_cursor_lnum();
+ check_cursor_lnum(curwin);
if (solcol >= 0 && !p_sol) {
// 'sol' is off: Use last known column.
curwin->w_cursor.col = solcol;
@@ -2883,7 +2883,7 @@ void ex_append(exarg_T *eap)
curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
}
curwin->w_cursor.lnum = lnum;
- check_cursor_lnum();
+ check_cursor_lnum(curwin);
beginline(BL_SOL | BL_FIX);
need_wait_return = false; // don't use wait_return() now
@@ -2913,7 +2913,7 @@ void ex_change(exarg_T *eap)
}
// make sure the cursor is not beyond the end of the file now
- check_cursor_lnum();
+ check_cursor_lnum(curwin);
deleted_lines_mark(eap->line1, (eap->line2 - lnum));
// ":append" on the line above the deleted lines.
@@ -4200,7 +4200,7 @@ skip:
// the line number before the change (same as adding the number of
// deleted lines).
i = curbuf->b_ml.ml_line_count - old_line_count;
- changed_lines(first_line, 0, last_line - (linenr_T)i, (linenr_T)i, false);
+ changed_lines(curbuf, first_line, 0, last_line - (linenr_T)i, (linenr_T)i, false);
int64_t num_added = last_line - first_line;
int64_t num_removed = num_added - i;
@@ -4611,9 +4611,6 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i
linenr_T linenr_origbuf = 0; // last line added to original buffer
linenr_T next_linenr = 0; // next line to show for the match
- // Temporarily switch to preview buffer
- aco_save_T aco;
-
for (size_t matchidx = 0; matchidx < lines.subresults.size; matchidx++) {
SubResult match = lines.subresults.items[matchidx];
@@ -4621,6 +4618,9 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i
lpos_T p_start = { 0, match.start.col }; // match starts here in preview
lpos_T p_end = { 0, match.end.col }; // ... and ends here
+ // You Might Gonna Need It
+ buf_ensure_loaded(cmdpreview_buf);
+
if (match.pre_match == 0) {
next_linenr = match.start.lnum;
} else {
@@ -4656,14 +4656,11 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i
// Put "|lnum| line" into `str` and append it to the preview buffer.
snprintf(str, line_size, "|%*" PRIdLINENR "| %s", col_width - 3,
next_linenr, line);
- // Temporarily switch to preview buffer
- aucmd_prepbuf(&aco, cmdpreview_buf);
if (linenr_preview == 0) {
- ml_replace(1, str, true);
+ ml_replace_buf(cmdpreview_buf, 1, str, true);
} else {
- ml_append(linenr_preview, str, (colnr_T)line_size, false);
+ ml_append_buf(cmdpreview_buf, linenr_preview, str, (colnr_T)line_size, false);
}
- aucmd_restbuf(&aco);
linenr_preview += 1;
}
linenr_origbuf = match.end.lnum;
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 682b6f6481..aba50b2042 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -5881,7 +5881,7 @@ static void ex_copymove(exarg_T *eap)
} else {
ex_copy(eap->line1, eap->line2, n);
}
- u_clearline();
+ u_clearline(curbuf);
beginline(BL_SOL | BL_FIX);
ex_may_print(eap);
}
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index c401293ccc..08b010c153 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -492,7 +492,7 @@ static void may_do_incsearch_highlighting(int firstc, int count, incsearch_state
// first restore the old curwin values, so the screen is
// positioned in the same way as the actual search command
restore_viewstate(curwin, &s->old_viewstate);
- changed_cline_bef_curs();
+ changed_cline_bef_curs(curwin);
update_topline(curwin);
if (found != 0) {
@@ -1460,7 +1460,7 @@ static int may_do_command_line_next_incsearch(int firstc, int count, incsearch_s
set_search_match(&s->match_end);
curwin->w_cursor = s->match_start;
- changed_cline_bef_curs();
+ changed_cline_bef_curs(curwin);
update_topline(curwin);
validate_cursor();
highlight_match = true;
@@ -4480,7 +4480,7 @@ static int open_cmdwin(void)
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
curwin->w_cursor.col = ccline.cmdpos;
changed_line_abv_curs();
- invalidate_botline();
+ invalidate_botline(curwin);
if (ui_has(kUICmdline)) {
ccline.redraw_state = kCmdRedrawNone;
ui_call_cmdline_hide(ccline.level);
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 1cbfcff9f4..5d7ddb657a 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -1784,7 +1784,7 @@ failed:
curbuf->b_p_ro = true;
}
- u_clearline(); // cannot use "U" command after adding lines
+ u_clearline(curbuf); // cannot use "U" command after adding lines
// In Ex mode: cursor at last new line.
// Otherwise: cursor at first new line.
@@ -1793,7 +1793,7 @@ failed:
} else {
curwin->w_cursor.lnum = from + 1;
}
- check_cursor_lnum();
+ check_cursor_lnum(curwin);
beginline(BL_WHITE | BL_FIX); // on first non-blank
if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) {
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index 595136d590..a6cb0b568c 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.c
@@ -743,8 +743,7 @@ void deleteFold(win_T *const wp, const linenr_T start, const linenr_T end, const
}
if (last_lnum > 0) {
- // TODO(teto): pass the buffer
- changed_lines(first_lnum, (colnr_T)0, last_lnum, 0L, false);
+ changed_lines(wp->w_buffer, first_lnum, (colnr_T)0, last_lnum, 0L, false);
// send one nvim_buf_lines_event at the end
// last_lnum is the line *after* the last line of the outermost fold
@@ -1580,8 +1579,7 @@ static void foldCreateMarkers(win_T *wp, pos_T start, pos_T end)
// Update both changes here, to avoid all folds after the start are
// changed when the start marker is inserted and the end isn't.
- // TODO(teto): pass the buffer
- changed_lines(start.lnum, (colnr_T)0, end.lnum, 0L, false);
+ changed_lines(buf, start.lnum, (colnr_T)0, end.lnum, 0L, false);
// Note: foldAddMarker() may not actually change start and/or end if
// u_save() is unable to save the buffer line, but we send the
diff --git a/src/nvim/help.c b/src/nvim/help.c
index 1e21dbba4d..698eda8468 100644
--- a/src/nvim/help.c
+++ b/src/nvim/help.c
@@ -836,7 +836,7 @@ void fix_help_buffer(void)
linenr_T appended = lnum - lnum_start;
if (appended) {
mark_adjust(lnum_start + 1, (linenr_T)MAXLNUM, appended, 0L, kExtmarkUndo);
- changed_lines_buf(curbuf, lnum_start + 1, lnum_start + 1, appended);
+ buf_redraw_changed_lines_later(curbuf, lnum_start + 1, lnum_start + 1, appended);
}
break;
}
diff --git a/src/nvim/indent.c b/src/nvim/indent.c
index fb6228ae2d..c16a94f06c 100644
--- a/src/nvim/indent.c
+++ b/src/nvim/indent.c
@@ -1083,7 +1083,7 @@ void ex_retab(exarg_T *eap)
redraw_curbuf_later(UPD_NOT_VALID);
}
if (first_line != 0) {
- changed_lines(first_line, 0, last_line + 1, 0L, true);
+ changed_lines(curbuf, first_line, 0, last_line + 1, 0L, true);
}
curwin->w_p_list = save_list; // restore 'list'
@@ -1107,7 +1107,7 @@ void ex_retab(exarg_T *eap)
}
coladvance(curwin->w_curswant);
- u_clearline();
+ u_clearline(curbuf);
}
/// Get indent level from 'indentexpr'.
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
index fe15e21a29..d961d6664a 100644
--- a/src/nvim/insexpand.c
+++ b/src/nvim/insexpand.c
@@ -3446,7 +3446,7 @@ void ins_compl_delete(void)
// TODO(vim): is this sufficient for redrawing? Redrawing everything
// causes flicker, thus we can't do that.
- changed_cline_bef_curs();
+ changed_cline_bef_curs(curwin);
// clear v:completed_item
set_vim_var_dict(VV_COMPLETED_ITEM, tv_dict_alloc_lock(VAR_FIXED));
}
diff --git a/src/nvim/log.c b/src/nvim/log.c
index afe3d95e9a..84b6e9ece7 100644
--- a/src/nvim/log.c
+++ b/src/nvim/log.c
@@ -152,7 +152,17 @@ bool logmsg(int log_level, const char *context, const char *func_name, int line_
#ifdef EXITFREE
// Logging after we've already started freeing all our memory will only cause
// pain. We need access to VV_PROGPATH, homedir, etc.
- assert(!entered_free_all_mem);
+ if (entered_free_all_mem) {
+ fprintf(stderr, "FATAL: error in free_all_mem\n %s %s %d: ", context, func_name, line_num);
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ if (eol) {
+ fprintf(stderr, "\n");
+ }
+ abort();
+ }
#endif
log_lock();
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index 5c36493b82..2e08a6f591 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -1121,7 +1121,7 @@ void ex_changes(exarg_T *eap)
void mark_adjust(linenr_T line1, linenr_T line2, linenr_T amount, linenr_T amount_after,
ExtmarkOp op)
{
- mark_adjust_internal(line1, line2, amount, amount_after, true, op);
+ mark_adjust_buf(curbuf, line1, line2, amount, amount_after, true, true, op);
}
// mark_adjust_nofold() does the same as mark_adjust() but without adjusting
@@ -1132,13 +1132,13 @@ void mark_adjust(linenr_T line1, linenr_T line2, linenr_T amount, linenr_T amoun
void mark_adjust_nofold(linenr_T line1, linenr_T line2, linenr_T amount, linenr_T amount_after,
ExtmarkOp op)
{
- mark_adjust_internal(line1, line2, amount, amount_after, false, op);
+ mark_adjust_buf(curbuf, line1, line2, amount, amount_after, false, true, op);
}
-static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount,
- linenr_T amount_after, bool adjust_folds, ExtmarkOp op)
+void mark_adjust_buf(buf_T *buf, linenr_T line1, linenr_T line2, linenr_T amount,
+ linenr_T amount_after, bool adjust_folds, bool adj_cursor, ExtmarkOp op)
{
- int fnum = curbuf->b_fnum;
+ int fnum = buf->b_fnum;
linenr_T *lp;
static pos_T initpos = { 1, 0, 0 };
@@ -1149,7 +1149,7 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount
if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) {
// named marks, lower case and upper case
for (int i = 0; i < NMARKS; i++) {
- ONE_ADJUST(&(curbuf->b_namedm[i].mark.lnum));
+ ONE_ADJUST(&(buf->b_namedm[i].mark.lnum));
if (namedfm[i].fmark.fnum == fnum) {
ONE_ADJUST_NODEL(&(namedfm[i].fmark.mark.lnum));
}
@@ -1161,54 +1161,56 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount
}
// last Insert position
- ONE_ADJUST(&(curbuf->b_last_insert.mark.lnum));
+ ONE_ADJUST(&(buf->b_last_insert.mark.lnum));
// last change position
- ONE_ADJUST(&(curbuf->b_last_change.mark.lnum));
+ ONE_ADJUST(&(buf->b_last_change.mark.lnum));
// last cursor position, if it was set
- if (!equalpos(curbuf->b_last_cursor.mark, initpos)) {
- ONE_ADJUST(&(curbuf->b_last_cursor.mark.lnum));
+ if (!equalpos(buf->b_last_cursor.mark, initpos)) {
+ ONE_ADJUST(&(buf->b_last_cursor.mark.lnum));
}
// list of change positions
- for (int i = 0; i < curbuf->b_changelistlen; i++) {
- ONE_ADJUST_NODEL(&(curbuf->b_changelist[i].mark.lnum));
+ for (int i = 0; i < buf->b_changelistlen; i++) {
+ ONE_ADJUST_NODEL(&(buf->b_changelist[i].mark.lnum));
}
// Visual area
- ONE_ADJUST_NODEL(&(curbuf->b_visual.vi_start.lnum));
- ONE_ADJUST_NODEL(&(curbuf->b_visual.vi_end.lnum));
+ ONE_ADJUST_NODEL(&(buf->b_visual.vi_start.lnum));
+ ONE_ADJUST_NODEL(&(buf->b_visual.vi_end.lnum));
// quickfix marks
- if (!qf_mark_adjust(NULL, line1, line2, amount, amount_after)) {
- curbuf->b_has_qf_entry &= ~BUF_HAS_QF_ENTRY;
+ if (!qf_mark_adjust(buf, NULL, line1, line2, amount, amount_after)) {
+ buf->b_has_qf_entry &= ~BUF_HAS_QF_ENTRY;
}
// location lists
bool found_one = false;
FOR_ALL_TAB_WINDOWS(tab, win) {
- found_one |= qf_mark_adjust(win, line1, line2, amount, amount_after);
+ found_one |= qf_mark_adjust(buf, win, line1, line2, amount, amount_after);
}
if (!found_one) {
- curbuf->b_has_qf_entry &= ~BUF_HAS_LL_ENTRY;
+ buf->b_has_qf_entry &= ~BUF_HAS_LL_ENTRY;
}
- sign_mark_adjust(line1, line2, amount, amount_after);
+ sign_mark_adjust(buf, line1, line2, amount, amount_after);
}
if (op != kExtmarkNOOP) {
- extmark_adjust(curbuf, line1, line2, amount, amount_after, op);
+ extmark_adjust(buf, line1, line2, amount, amount_after, op);
}
- // previous context mark
- ONE_ADJUST(&(curwin->w_pcmark.lnum));
+ if (curwin->w_buffer == buf) {
+ // previous context mark
+ ONE_ADJUST(&(curwin->w_pcmark.lnum));
- // previous pcmark
- ONE_ADJUST(&(curwin->w_prev_pcmark.lnum));
+ // previous pcpmark
+ ONE_ADJUST(&(curwin->w_prev_pcmark.lnum));
- // saved cursor for formatting
- if (saved_cursor.lnum != 0) {
- ONE_ADJUST_NODEL(&(saved_cursor.lnum));
+ // saved cursor for formatting
+ if (saved_cursor.lnum != 0) {
+ ONE_ADJUST_NODEL(&(saved_cursor.lnum));
+ }
}
// Adjust items in all windows related to the current buffer.
@@ -1223,7 +1225,7 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount
}
}
- if (win->w_buffer == curbuf) {
+ if (win->w_buffer == buf) {
if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) {
// marks in the tag stack
for (int i = 0; i < win->w_tagstacklen; i++) {
@@ -1259,19 +1261,21 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount
win->w_topline += amount_after;
win->w_topfill = 0;
}
- if (win->w_cursor.lnum >= line1 && win->w_cursor.lnum <= line2) {
- if (amount == MAXLNUM) { // line with cursor is deleted
- if (line1 <= 1) {
- win->w_cursor.lnum = 1;
- } else {
- win->w_cursor.lnum = line1 - 1;
+ if (adj_cursor) {
+ if (win->w_cursor.lnum >= line1 && win->w_cursor.lnum <= line2) {
+ if (amount == MAXLNUM) { // line with cursor is deleted
+ if (line1 <= 1) {
+ win->w_cursor.lnum = 1;
+ } else {
+ win->w_cursor.lnum = line1 - 1;
+ }
+ win->w_cursor.col = 0;
+ } else { // keep cursor on the same line
+ win->w_cursor.lnum += amount;
}
- win->w_cursor.col = 0;
- } else { // keep cursor on the same line
- win->w_cursor.lnum += amount;
+ } else if (amount_after && win->w_cursor.lnum > line2) {
+ win->w_cursor.lnum += amount_after;
}
- } else if (amount_after && win->w_cursor.lnum > line2) {
- win->w_cursor.lnum += amount_after;
}
}
@@ -1282,7 +1286,7 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount
}
// adjust diffs
- diff_mark_adjust(line1, line2, amount, amount_after);
+ diff_mark_adjust(buf, line1, line2, amount, amount_after);
}
// This code is used often, needs to be fast.
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 1451a8404c..b100942594 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -348,9 +348,8 @@ int ml_open(buf_T *buf)
}
// Fill in root pointer block and write page 1.
- if ((hp = ml_new_ptr(mfp)) == NULL) {
- goto error;
- }
+ hp = ml_new_ptr(mfp);
+ assert(hp != NULL);
if (hp->bh_bnum != 1) {
iemsg(_("E298: Didn't get block nr 1?"));
goto error;
@@ -1170,7 +1169,7 @@ void ml_recover(bool checkext)
// Recovering an empty file results in two lines and the first line is
// empty. Don't set the modified flag then.
if (!(curbuf->b_ml.ml_line_count == 2 && *ml_get(1) == NUL)) {
- changed_internal();
+ changed_internal(curbuf);
buf_inc_changedtick(curbuf);
}
} else {
@@ -1180,7 +1179,7 @@ void ml_recover(bool checkext)
int i = strcmp(p, ml_get(idx + lnum));
xfree(p);
if (i != 0) {
- changed_internal();
+ changed_internal(curbuf);
buf_inc_changedtick(curbuf);
break;
}
@@ -2495,6 +2494,19 @@ int ml_delete(linenr_T lnum, bool message)
return ml_delete_int(curbuf, lnum, message);
}
+/// Delete line `lnum` in buffer
+///
+/// @note The caller of this function should probably also call changed_lines() after this.
+///
+/// @param message Show "--No lines in buffer--" message.
+///
+/// @return FAIL for failure, OK otherwise
+int ml_delete_buf(buf_T *buf, linenr_T lnum, bool message)
+{
+ ml_flush_line(buf);
+ return ml_delete_int(buf, lnum, message);
+}
+
static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
{
if (lnum < 1 || lnum > buf->b_ml.ml_line_count) {
diff --git a/src/nvim/move.c b/src/nvim/move.c
index 57c5b7d6cf..0077dc3102 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -547,13 +547,7 @@ void set_topline(win_T *wp, linenr_T lnum)
/// If the line length changed the number of screen lines might change,
/// requiring updating w_topline. That may also invalidate w_crow.
/// Need to take care of w_botline separately!
-void changed_cline_bef_curs(void)
-{
- curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL|VALID_CROW
- |VALID_CHEIGHT|VALID_TOPLINE);
-}
-
-void changed_cline_bef_curs_win(win_T *wp)
+void changed_cline_bef_curs(win_T *wp)
{
wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL|VALID_CROW
|VALID_CHEIGHT|VALID_TOPLINE);
@@ -595,13 +589,8 @@ void validate_botline(win_T *wp)
}
}
-// Mark curwin->w_botline as invalid (because of some change in the buffer).
-void invalidate_botline(void)
-{
- curwin->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP);
-}
-
-void invalidate_botline_win(win_T *wp)
+// Mark wp->w_botline as invalid (because of some change in the buffer).
+void invalidate_botline(win_T *wp)
{
wp->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP);
}
@@ -1276,7 +1265,7 @@ bool scrolldown(long line_count, int byfold)
}
}
curwin->w_botline--; // approximate w_botline
- invalidate_botline();
+ invalidate_botline(curwin);
}
curwin->w_wrow += done; // keep w_wrow updated
curwin->w_cline_row += done; // keep w_cline_row updated
@@ -2651,7 +2640,7 @@ void halfpage(bool flag, linenr_T Prenum)
} else {
curwin->w_cursor.lnum += n;
}
- check_cursor_lnum();
+ check_cursor_lnum(curwin);
}
} else {
// scroll the text down
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 1a220bc962..82b930d2ff 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -3922,7 +3922,7 @@ static void nv_gotofile(cmdarg_T *cap)
buf_hide(curbuf) ? ECMD_HIDE : 0, curwin) == OK
&& cap->nchar == 'F' && lnum >= 0) {
curwin->w_cursor.lnum = lnum;
- check_cursor_lnum();
+ check_cursor_lnum(curwin);
beginline(BL_SOL | BL_FIX);
}
xfree(ptr);
@@ -4771,7 +4771,7 @@ static void n_swapchar(cmdarg_T *cap)
if (u_savesub(curwin->w_cursor.lnum) == false) {
break;
}
- u_clearline();
+ u_clearline(curbuf);
}
} else {
break;
@@ -4782,7 +4782,7 @@ static void n_swapchar(cmdarg_T *cap)
check_cursor();
curwin->w_set_curswant = true;
if (did_change) {
- changed_lines(startpos.lnum, startpos.col, curwin->w_cursor.lnum + 1,
+ changed_lines(curbuf, startpos.lnum, startpos.col, curwin->w_cursor.lnum + 1,
0L, true);
curbuf->b_op_start = startpos;
curbuf->b_op_end = curwin->w_cursor;
@@ -5363,7 +5363,7 @@ static void nv_gi_cmd(cmdarg_T *cap)
{
if (curbuf->b_last_insert.mark.lnum != 0) {
curwin->w_cursor = curbuf->b_last_insert.mark;
- check_cursor_lnum();
+ check_cursor_lnum(curwin);
int i = (int)strlen(get_cursor_line_ptr());
if (curwin->w_cursor.col > (colnr_T)i) {
if (virtual_active()) {
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 0564e3dde2..8270641256 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -281,7 +281,7 @@ void op_shift(oparg_T *oap, int curs_top, int amount)
}
}
- changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L, true);
+ changed_lines(curbuf, oap->start.lnum, 0, oap->end.lnum + 1, 0L, true);
}
/// Shift the current line one shiftwidth left (if left != 0) or right
@@ -626,7 +626,7 @@ static void block_insert(oparg_T *oap, char *s, int b_insert, struct block_def *
State = oldstate;
- changed_lines(oap->start.lnum + 1, 0, oap->end.lnum + 1, 0L, true);
+ changed_lines(curbuf, oap->start.lnum + 1, 0, oap->end.lnum + 1, 0L, true);
}
/// Handle reindenting a block of lines.
@@ -690,7 +690,7 @@ void op_reindent(oparg_T *oap, Indenter how)
// highlighting was present, need to continue until the last line. When
// there is no change still need to remove the Visual highlighting.
if (last_changed != 0) {
- changed_lines(first_changed, 0,
+ changed_lines(curbuf, first_changed, 0,
oap->is_VIsual ? start_lnum + (linenr_T)oap->line_count :
last_changed + 1, 0L, true);
} else if (oap->is_VIsual) {
@@ -1593,7 +1593,7 @@ int op_delete(oparg_T *oap)
}
check_cursor_col();
- changed_lines(curwin->w_cursor.lnum, curwin->w_cursor.col,
+ changed_lines(curbuf, curwin->w_cursor.lnum, curwin->w_cursor.col,
oap->end.lnum + 1, 0L, true);
oap->line_count = 0; // no lines deleted
} else if (oap->motion_type == kMTLineWise) {
@@ -1628,12 +1628,12 @@ int op_delete(oparg_T *oap)
// leave cursor past last char in line
if (oap->line_count > 1) {
- u_clearline(); // "U" command not possible after "2cc"
+ u_clearline(curbuf); // "U" command not possible after "2cc"
}
} else {
del_lines(oap->line_count, true);
beginline(BL_WHITE | BL_FIX);
- u_clearline(); // "U" command not possible after "dd"
+ u_clearline(curbuf); // "U" command not possible after "dd"
}
} else {
if (virtual_op) {
@@ -2030,7 +2030,7 @@ static int op_replace(oparg_T *oap, int c)
curwin->w_cursor = oap->start;
check_cursor();
- changed_lines(oap->start.lnum, oap->start.col, oap->end.lnum + 1, 0L, true);
+ changed_lines(curbuf, oap->start.lnum, oap->start.col, oap->end.lnum + 1, 0L, true);
if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) {
// Set "'[" and "']" marks.
@@ -2064,7 +2064,7 @@ void op_tilde(oparg_T *oap)
did_change |= one_change;
}
if (did_change) {
- changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L, true);
+ changed_lines(curbuf, oap->start.lnum, 0, oap->end.lnum + 1, 0L, true);
}
} else { // not block mode
if (oap->motion_type == kMTLineWise) {
@@ -2092,7 +2092,7 @@ void op_tilde(oparg_T *oap)
}
}
if (did_change) {
- changed_lines(oap->start.lnum, oap->start.col, oap->end.lnum + 1,
+ changed_lines(curbuf, oap->start.lnum, oap->start.col, oap->end.lnum + 1,
0L, true);
}
}
@@ -2531,7 +2531,7 @@ int op_change(oparg_T *oap)
}
}
check_cursor();
- changed_lines(oap->start.lnum + 1, 0, oap->end.lnum + 1, 0L, true);
+ changed_lines(curbuf, oap->start.lnum + 1, 0, oap->end.lnum + 1, 0L, true);
xfree(ins_text);
}
}
@@ -3365,7 +3365,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
}
}
- changed_lines(lnum, 0, curbuf->b_op_start.lnum + (linenr_T)y_size
+ changed_lines(curbuf, lnum, 0, curbuf->b_op_start.lnum + (linenr_T)y_size
- nr_lines, nr_lines, true);
// Set '[ mark.
@@ -3481,8 +3481,8 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
// Place cursor on last putted char.
if (lnum == curwin->w_cursor.lnum) {
// make sure curwin->w_virtcol is updated
- changed_cline_bef_curs();
- invalidate_botline();
+ changed_cline_bef_curs(curwin);
+ invalidate_botline(curwin);
curwin->w_cursor.col += (colnr_T)(totlen - 1);
}
changed_bytes(lnum, col);
@@ -3620,10 +3620,10 @@ error:
// note changed text for displaying and folding
if (y_type == kMTCharWise) {
- changed_lines(curwin->w_cursor.lnum, col,
+ changed_lines(curbuf, curwin->w_cursor.lnum, col,
curwin->w_cursor.lnum + 1, nr_lines, true);
} else {
- changed_lines(curbuf->b_op_start.lnum, 0,
+ changed_lines(curbuf, curbuf->b_op_start.lnum, 0,
curbuf->b_op_start.lnum, nr_lines, true);
}
@@ -4159,7 +4159,7 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions
// Only report the change in the first line here, del_lines() will report
// the deleted line.
- changed_lines(curwin->w_cursor.lnum, currsize,
+ changed_lines(curbuf, curwin->w_cursor.lnum, currsize,
curwin->w_cursor.lnum + 1, 0L, true);
// Delete following lines. To do this we move the cursor there
@@ -4379,7 +4379,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd)
change_cnt = do_addsub(oap->op_type, &pos, 0, amount);
disable_fold_update--;
if (change_cnt) {
- changed_lines(pos.lnum, 0, pos.lnum + 1, 0L, true);
+ changed_lines(curbuf, pos.lnum, 0, pos.lnum + 1, 0L, true);
}
} else {
int length;
@@ -4437,7 +4437,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd)
disable_fold_update--;
if (change_cnt) {
- changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L, true);
+ changed_lines(curbuf, oap->start.lnum, 0, oap->end.lnum + 1, 0L, true);
}
if (!change_cnt && oap->is_VIsual) {
diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c
index f07c05c113..07e2e5eed1 100644
--- a/src/nvim/optionstr.c
+++ b/src/nvim/optionstr.c
@@ -406,6 +406,19 @@ void set_string_option_direct_in_win(win_T *wp, const char *name, int opt_idx, c
unblock_autocmds();
}
+/// Like set_string_option_direct(), but for a buffer-local option in "buf".
+/// Blocks autocommands to avoid the old curwin becoming invalid.
+void set_string_option_direct_in_buf(buf_T *buf, const char *name, int opt_idx, const char *val,
+ int opt_flags, int set_sid)
+{
+ buf_T *save_curbuf = curbuf;
+
+ block_autocmds();
+ curbuf = buf;
+ set_string_option_direct(name, opt_idx, val, opt_flags, set_sid);
+ curbuf = save_curbuf;
+ unblock_autocmds();
+}
/// Set a string option to a new value, handling the effects
///
/// @param[in] opt_idx Option to set.
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 2152e79536..70fcf3d276 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -3433,14 +3433,17 @@ static void qf_free(qf_list_T *qfl)
qfl->qf_changedtick = 0L;
}
-// qf_mark_adjust: adjust marks
-bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, linenr_T amount,
+/// Adjust error list entries for changed line numbers
+///
+/// Note: `buf` is the changed buffer, but `wp` is a potential location list
+/// into that buffer, or NULL to check the quickfix list.
+bool qf_mark_adjust(buf_T *buf, win_T *wp, linenr_T line1, linenr_T line2, linenr_T amount,
linenr_T amount_after)
{
qf_info_T *qi = &ql_info;
int buf_has_flag = wp == NULL ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
- if (!(curbuf->b_has_qf_entry & buf_has_flag)) {
+ if (!(buf->b_has_qf_entry & buf_has_flag)) {
return false;
}
if (wp != NULL) {
@@ -3457,7 +3460,7 @@ bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, linenr_T amount,
qf_list_T *qfl = qf_get_list(qi, idx);
if (!qf_list_empty(qfl)) {
FOR_ALL_QFL_ITEMS(qfl, qfp, i) {
- if (qfp->qf_fnum == curbuf->b_fnum) {
+ if (qfp->qf_fnum == buf->b_fnum) {
found_one = true;
if (qfp->qf_lnum >= line1 && qfp->qf_lnum <= line2) {
if (amount == MAXLNUM) {
diff --git a/src/nvim/sign.c b/src/nvim/sign.c
index 5e3882f629..1910e046e6 100644
--- a/src/nvim/sign.c
+++ b/src/nvim/sign.c
@@ -766,7 +766,8 @@ static linenr_T sign_adjust_one(const linenr_T se_lnum, linenr_T line1, linenr_T
}
/// Adjust placed signs for inserted/deleted lines.
-void sign_mark_adjust(linenr_T line1, linenr_T line2, linenr_T amount, linenr_T amount_after)
+void sign_mark_adjust(buf_T *buf, linenr_T line1, linenr_T line2, linenr_T amount,
+ linenr_T amount_after)
{
sign_entry_T *sign; // a sign in a b_signlist
sign_entry_T *next; // the next sign in a b_signlist
@@ -774,15 +775,15 @@ void sign_mark_adjust(linenr_T line1, linenr_T line2, linenr_T amount, linenr_T
sign_entry_T **lastp = NULL; // pointer to pointer to current sign
linenr_T new_lnum; // new line number to assign to sign
int is_fixed = 0;
- int signcol = win_signcol_configured(curwin, &is_fixed);
+ int signcol = curwin->w_buffer == buf ? win_signcol_configured(curwin, &is_fixed) : 0;
if (amount == MAXLNUM) { // deleting
- buf_signcols_del_check(curbuf, line1, line2);
+ buf_signcols_del_check(buf, line1, line2);
}
- lastp = &curbuf->b_signlist;
+ lastp = &buf->b_signlist;
- for (sign = curbuf->b_signlist; sign != NULL; sign = next) {
+ for (sign = buf->b_signlist; sign != NULL; sign = next) {
next = sign->se_next;
new_lnum = sign_adjust_one(sign->se_lnum, line1, line2, amount, amount_after);
@@ -799,7 +800,7 @@ void sign_mark_adjust(linenr_T line1, linenr_T line2, linenr_T amount, linenr_T
// If the new sign line number is past the last line in the buffer,
// then don't adjust the line number. Otherwise, it will always be past
// the last line and will not be visible.
- if (new_lnum <= curbuf->b_ml.ml_line_count) {
+ if (new_lnum <= buf->b_ml.ml_line_count) {
sign->se_lnum = new_lnum;
}
}
@@ -808,9 +809,9 @@ void sign_mark_adjust(linenr_T line1, linenr_T line2, linenr_T amount, linenr_T
lastp = &sign->se_next;
}
- new_lnum = sign_adjust_one(curbuf->b_signcols.sentinel, line1, line2, amount, amount_after);
+ new_lnum = sign_adjust_one(buf->b_signcols.sentinel, line1, line2, amount, amount_after);
if (new_lnum != 0) {
- curbuf->b_signcols.sentinel = new_lnum;
+ buf->b_signcols.sentinel = new_lnum;
}
}
@@ -1168,7 +1169,7 @@ static linenr_T sign_jump(int sign_id, char *sign_group, buf_T *buf)
// goto a sign ...
if (buf_jump_open_win(buf) != NULL) { // ... in a current window
curwin->w_cursor.lnum = lnum;
- check_cursor_lnum();
+ check_cursor_lnum(curwin);
beginline(BL_WHITE);
} else { // ... not currently in a window
if (buf->b_fname == NULL) {
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index 2d21451c9d..5e0ff072fb 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -1750,7 +1750,7 @@ static void refresh_screen(Terminal *term, buf_T *buf)
int change_start = row_to_linenr(term, term->invalid_start);
int change_end = change_start + changed;
- changed_lines(change_start, 0, change_end, added, true);
+ changed_lines(buf, change_start, 0, change_end, added, true);
term->invalid_start = INT_MAX;
term->invalid_end = -1;
}
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index 33fc5fac45..552120d4ae 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -250,15 +250,20 @@ int u_save_cursor(void)
/// Returns FAIL when lines could not be saved, OK otherwise.
int u_save(linenr_T top, linenr_T bot)
{
- if (top >= bot || bot > (curbuf->b_ml.ml_line_count + 1)) {
+ return u_save_buf(curbuf, top, bot);
+}
+
+int u_save_buf(buf_T *buf, linenr_T top, linenr_T bot)
+{
+ if (top >= bot || bot > (buf->b_ml.ml_line_count + 1)) {
return FAIL; // rely on caller to do error messages
}
if (top + 2 == bot) {
- u_saveline((linenr_T)(top + 1));
+ u_saveline(buf, (linenr_T)(top + 1));
}
- return u_savecommon(curbuf, top, bot, (linenr_T)0, false);
+ return u_savecommon(buf, top, bot, (linenr_T)0, false);
}
/// Save the line "lnum" (used by ":s" and "~" command).
@@ -2288,7 +2293,7 @@ static void u_undoredo(int undo, bool do_buf_event)
|| bot > curbuf->b_ml.ml_line_count + 1) {
unblock_autocmds();
iemsg(_("E438: u_undo: line numbers wrong"));
- changed(); // don't want UNCHANGED now
+ changed(curbuf); // don't want UNCHANGED now
return;
}
@@ -2373,7 +2378,7 @@ static void u_undoredo(int undo, bool do_buf_event)
}
}
- changed_lines(top + 1, 0, bot, newsize - oldsize, do_buf_event);
+ changed_lines(curbuf, top + 1, 0, bot, newsize - oldsize, do_buf_event);
// When text has been changed, possibly the start of the next line
// may have SpellCap that should be removed or it needs to be
// displayed. Schedule the next line for redrawing just in case.
@@ -2439,7 +2444,7 @@ static void u_undoredo(int undo, bool do_buf_event)
curbuf->b_ml.ml_flags |= ML_EMPTY;
}
if (old_flags & UH_CHANGED) {
- changed();
+ changed(curbuf);
} else {
unchanged(curbuf, false, true);
}
@@ -2980,34 +2985,34 @@ void u_clearall(buf_T *buf)
}
/// save the line "lnum" for the "U" command
-void u_saveline(linenr_T lnum)
+void u_saveline(buf_T *buf, linenr_T lnum)
{
- if (lnum == curbuf->b_u_line_lnum) { // line is already saved
+ if (lnum == buf->b_u_line_lnum) { // line is already saved
return;
}
- if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) { // should never happen
+ if (lnum < 1 || lnum > buf->b_ml.ml_line_count) { // should never happen
return;
}
- u_clearline();
- curbuf->b_u_line_lnum = lnum;
- if (curwin->w_cursor.lnum == lnum) {
- curbuf->b_u_line_colnr = curwin->w_cursor.col;
+ u_clearline(buf);
+ buf->b_u_line_lnum = lnum;
+ if (curwin->w_buffer == buf && curwin->w_cursor.lnum == lnum) {
+ buf->b_u_line_colnr = curwin->w_cursor.col;
} else {
- curbuf->b_u_line_colnr = 0;
+ buf->b_u_line_colnr = 0;
}
- curbuf->b_u_line_ptr = u_save_line(lnum);
+ buf->b_u_line_ptr = u_save_line_buf(buf, lnum);
}
/// clear the line saved for the "U" command
/// (this is used externally for crossing a line while in insert mode)
-void u_clearline(void)
+void u_clearline(buf_T *buf)
{
- if (curbuf->b_u_line_ptr == NULL) {
+ if (buf->b_u_line_ptr == NULL) {
return;
}
- XFREE_CLEAR(curbuf->b_u_line_ptr);
- curbuf->b_u_line_lnum = 0;
+ XFREE_CLEAR(buf->b_u_line_ptr);
+ buf->b_u_line_lnum = 0;
}
/// Implementation of the "U" command.
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 6ff9e07260..970027b2f8 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -562,7 +562,7 @@ wingotofile:
if (wp != NULL && nchar == 'F' && lnum >= 0) {
curwin->w_cursor.lnum = lnum;
- check_cursor_lnum();
+ check_cursor_lnum(curwin);
beginline(BL_SOL | BL_FIX);
}
xfree(ptr);
@@ -6493,7 +6493,7 @@ void win_fix_scroll(int resize)
wp->w_valid &= ~VALID_CROW;
}
- invalidate_botline_win(wp);
+ invalidate_botline(wp);
validate_botline(wp);
}
wp->w_prev_height = wp->w_height;
@@ -6666,7 +6666,7 @@ void scroll_to_fraction(win_T *wp, int prev_height)
}
redraw_later(wp, UPD_SOME_VALID);
- invalidate_botline_win(wp);
+ invalidate_botline(wp);
}
void win_set_inner_size(win_T *wp, bool valid_cursor)
@@ -6713,7 +6713,7 @@ void win_set_inner_size(win_T *wp, bool valid_cursor)
wp->w_lines_valid = 0;
if (valid_cursor) {
changed_line_abv_curs_win(wp);
- invalidate_botline_win(wp);
+ invalidate_botline(wp);
if (wp == curwin && *p_spk == 'c') {
curs_columns(wp, true); // validate w_wrow
}