mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
refactor(change): do API changes to buffer without curbuf switch
Most of the messy things when changing a non-current buffer is not about the buffer, it is about windows. In particular, it is about `curwin`. When editing a non-current buffer which is displayed in some other window in the current tabpage, one such window will be "borrowed" as the curwin. But this means if two or more non-current windows displayed the buffers, one of them will be treated differenty. this is not desirable. In particular, with nvim_buf_set_text, cursor _column_ position was only corrected for one single window. Two new tests are added: the test with just one non-current window passes, but the one with two didn't. Two corresponding such tests were also added for nvim_buf_set_lines. This already worked correctly on master, but make sure this is well-tested for future refactors. Also, nvim_create_buf no longer invokes autocmds just because you happened to use `scratch=true`. No option value was changed, therefore OptionSet must not be fired.
This commit is contained in:
parent
1635c9e75e
commit
0081549547
@ -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);
|
||||
mark_adjust_buf(buf, (linenr_T)start, (linenr_T)(end - 1), MAXLNUM, (linenr_T)extra,
|
||||
true, true, kExtmarkNOOP);
|
||||
|
||||
extmark_splice(curbuf, (int)start - 1, 0, (int)(end - start), 0,
|
||||
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++;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
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.
|
||||
// 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);
|
||||
|
||||
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:
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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'.
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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()) {
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -76,6 +76,38 @@ describe('api/buf', function()
|
||||
eq({4, 2}, curwin('get_cursor'))
|
||||
end)
|
||||
|
||||
it('cursor position is maintained in non-current window', function()
|
||||
meths.buf_set_lines(0, 0, -1, 1, {"line1", "line2", "line3", "line4"})
|
||||
meths.win_set_cursor(0, {3, 2})
|
||||
local win = meths.get_current_win()
|
||||
local buf = meths.get_current_buf()
|
||||
|
||||
command('new')
|
||||
|
||||
meths.buf_set_lines(buf, 1, 2, 1, {"line5", "line6"})
|
||||
eq({"line1", "line5", "line6", "line3", "line4"}, meths.buf_get_lines(buf, 0, -1, true))
|
||||
eq({4, 2}, meths.win_get_cursor(win))
|
||||
end)
|
||||
|
||||
it('cursor position is maintained in TWO non-current windows', function()
|
||||
meths.buf_set_lines(0, 0, -1, 1, {"line1", "line2", "line3", "line4"})
|
||||
meths.win_set_cursor(0, {3, 2})
|
||||
local win = meths.get_current_win()
|
||||
local buf = meths.get_current_buf()
|
||||
|
||||
command('split')
|
||||
meths.win_set_cursor(0, {4, 2})
|
||||
local win2 = meths.get_current_win()
|
||||
|
||||
-- set current window to third one with another buffer
|
||||
command("new")
|
||||
|
||||
meths.buf_set_lines(buf, 1, 2, 1, {"line5", "line6"})
|
||||
eq({"line1", "line5", "line6", "line3", "line4"}, meths.buf_get_lines(buf, 0, -1, true))
|
||||
eq({4, 2}, meths.win_get_cursor(win))
|
||||
eq({5, 2}, meths.win_get_cursor(win2))
|
||||
end)
|
||||
|
||||
it('line_count has defined behaviour for unloaded buffers', function()
|
||||
-- we'll need to know our bufnr for when it gets unloaded
|
||||
local bufnr = curbuf('get_number')
|
||||
@ -484,6 +516,50 @@ describe('api/buf', function()
|
||||
eq({1, 9}, curwin('get_cursor'))
|
||||
end)
|
||||
|
||||
it('updates the cursor position in non-current window', function()
|
||||
insert([[
|
||||
hello world!]])
|
||||
|
||||
-- position the cursor on `!`
|
||||
meths.win_set_cursor(0, {1, 11})
|
||||
|
||||
local win = meths.get_current_win()
|
||||
local buf = meths.get_current_buf()
|
||||
|
||||
command("new")
|
||||
|
||||
-- replace 'world' with 'foo'
|
||||
meths.buf_set_text(buf, 0, 6, 0, 11, {'foo'})
|
||||
eq({'hello foo!'}, meths.buf_get_lines(buf, 0, -1, true))
|
||||
-- cursor should be moved left by two columns (replacement is shorter by 2 chars)
|
||||
eq({1, 9}, meths.win_get_cursor(win))
|
||||
end)
|
||||
|
||||
it('updates the cursor position in TWO non-current windows', function()
|
||||
insert([[
|
||||
hello world!]])
|
||||
|
||||
-- position the cursor on `!`
|
||||
meths.win_set_cursor(0, {1, 11})
|
||||
local win = meths.get_current_win()
|
||||
local buf = meths.get_current_buf()
|
||||
|
||||
command("split")
|
||||
local win2 = meths.get_current_win()
|
||||
-- position the cursor on `w`
|
||||
meths.win_set_cursor(0, {1, 6})
|
||||
|
||||
command("new")
|
||||
|
||||
-- replace 'hello' with 'foo'
|
||||
meths.buf_set_text(buf, 0, 0, 0, 5, {'foo'})
|
||||
eq({'foo world!'}, meths.buf_get_lines(buf, 0, -1, true))
|
||||
|
||||
-- both cursors should be moved left by two columns (replacement is shorter by 2 chars)
|
||||
eq({1, 9}, meths.win_get_cursor(win))
|
||||
eq({1, 4}, meths.win_get_cursor(win2))
|
||||
end)
|
||||
|
||||
it('can handle NULs', function()
|
||||
set_text(0, 0, 0, 0, {'ab\0cd'})
|
||||
eq('ab\0cd', curbuf_depr('get_line', 0))
|
||||
|
@ -28,7 +28,6 @@ local write_file = helpers.write_file
|
||||
local exec_lua = helpers.exec_lua
|
||||
local exc_exec = helpers.exc_exec
|
||||
local insert = helpers.insert
|
||||
local expect_exit = helpers.expect_exit
|
||||
local skip = helpers.skip
|
||||
|
||||
local pcall_err = helpers.pcall_err
|
||||
@ -2832,7 +2831,9 @@ describe('API', function()
|
||||
|
||||
it('does not cause heap-use-after-free on exit while setting options', function()
|
||||
command('au OptionSet * q')
|
||||
expect_exit(command, 'silent! call nvim_create_buf(0, 1)')
|
||||
command('silent! call nvim_create_buf(0, 1)')
|
||||
-- nowadays this works because we don't execute any spurious autocmds at all #24824
|
||||
assert_alive()
|
||||
end)
|
||||
end)
|
||||
|
||||
|
@ -1251,6 +1251,98 @@ AAAB]]
|
||||
]]}
|
||||
end)
|
||||
end)
|
||||
|
||||
it('redraws with a change to non-current buffer', function()
|
||||
write_file(fname, "aaa\nbbb\nccc\n\nxx", false)
|
||||
write_file(fname_2, "aaa\nbbb\nccc\n\nyy", false)
|
||||
reread()
|
||||
local buf = meths.get_current_buf()
|
||||
command('botright new')
|
||||
screen:expect{grid=[[
|
||||
{1: }aaa │{1: }aaa |
|
||||
{1: }bbb │{1: }bbb |
|
||||
{1: }ccc │{1: }ccc |
|
||||
{1: } │{1: } |
|
||||
{1: }{8:xx}{9: }│{1: }{8:yy}{9: }|
|
||||
{6:~ }│{6:~ }|
|
||||
{3:<onal-diff-screen-1 <l-diff-screen-1.2 }|
|
||||
^ |
|
||||
{6:~ }|
|
||||
{6:~ }|
|
||||
{6:~ }|
|
||||
{6:~ }|
|
||||
{6:~ }|
|
||||
{6:~ }|
|
||||
{7:[No Name] }|
|
||||
:e |
|
||||
]]}
|
||||
|
||||
meths.buf_set_lines(buf, 1, 2, true, {'BBB'})
|
||||
screen:expect{grid=[[
|
||||
{1: }aaa │{1: }aaa |
|
||||
{1: }{8:BBB}{9: }│{1: }{8:bbb}{9: }|
|
||||
{1: }ccc │{1: }ccc |
|
||||
{1: } │{1: } |
|
||||
{1: }{8:xx}{9: }│{1: }{8:yy}{9: }|
|
||||
{6:~ }│{6:~ }|
|
||||
{3:<-diff-screen-1 [+] <l-diff-screen-1.2 }|
|
||||
^ |
|
||||
{6:~ }|
|
||||
{6:~ }|
|
||||
{6:~ }|
|
||||
{6:~ }|
|
||||
{6:~ }|
|
||||
{6:~ }|
|
||||
{7:[No Name] }|
|
||||
:e |
|
||||
]]}
|
||||
end)
|
||||
|
||||
it('redraws with a change current buffer in another window', function()
|
||||
write_file(fname, "aaa\nbbb\nccc\n\nxx", false)
|
||||
write_file(fname_2, "aaa\nbbb\nccc\n\nyy", false)
|
||||
reread()
|
||||
local buf = meths.get_current_buf()
|
||||
command('botright split | diffoff')
|
||||
screen:expect{grid=[[
|
||||
{1: }aaa │{1: }aaa |
|
||||
{1: }bbb │{1: }bbb |
|
||||
{1: }ccc │{1: }ccc |
|
||||
{1: } │{1: } |
|
||||
{1: }{8:xx}{9: }│{1: }{8:yy}{9: }|
|
||||
{6:~ }│{6:~ }|
|
||||
{3:<onal-diff-screen-1 <l-diff-screen-1.2 }|
|
||||
^aaa |
|
||||
bbb |
|
||||
ccc |
|
||||
|
|
||||
xx |
|
||||
{6:~ }|
|
||||
{6:~ }|
|
||||
{7:Xtest-functional-diff-screen-1 }|
|
||||
:e |
|
||||
]]}
|
||||
|
||||
meths.buf_set_lines(buf, 1, 2, true, {'BBB'})
|
||||
screen:expect{grid=[[
|
||||
{1: }aaa │{1: }aaa |
|
||||
{1: }{8:BBB}{9: }│{1: }{8:bbb}{9: }|
|
||||
{1: }ccc │{1: }ccc |
|
||||
{1: } │{1: } |
|
||||
{1: }{8:xx}{9: }│{1: }{8:yy}{9: }|
|
||||
{6:~ }│{6:~ }|
|
||||
{3:<-diff-screen-1 [+] <l-diff-screen-1.2 }|
|
||||
^aaa |
|
||||
BBB |
|
||||
ccc |
|
||||
|
|
||||
xx |
|
||||
{6:~ }|
|
||||
{6:~ }|
|
||||
{7:Xtest-functional-diff-screen-1 [+] }|
|
||||
:e |
|
||||
]]}
|
||||
end)
|
||||
end)
|
||||
|
||||
it('win_update redraws lines properly', function()
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user