diff options
author | bfredl <bjorn.linse@gmail.com> | 2023-08-21 14:52:17 +0200 |
---|---|---|
committer | bfredl <bjorn.linse@gmail.com> | 2023-08-26 12:02:05 +0200 |
commit | 008154954791001efcc46c28146e21403f3a698b (patch) | |
tree | 306721ca60456ba9562c16b9d41cf5ec8d5a360c | |
parent | 1635c9e75e21e07c4331cf983e14a11c7e09b119 (diff) | |
download | rneovim-008154954791001efcc46c28146e21403f3a698b.tar.gz rneovim-008154954791001efcc46c28146e21403f3a698b.tar.bz2 rneovim-008154954791001efcc46c28146e21403f3a698b.zip |
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.
33 files changed, 737 insertions, 548 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 } diff --git a/test/functional/api/buffer_spec.lua b/test/functional/api/buffer_spec.lua index 512a1a08a6..4784c0a9dd 100644 --- a/test/functional/api/buffer_spec.lua +++ b/test/functional/api/buffer_spec.lua @@ -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)) diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 7edf1d9cde..2de1990b14 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -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) diff --git a/test/functional/ui/diff_spec.lua b/test/functional/ui/diff_spec.lua index 0f551e3044..92b7235885 100644 --- a/test/functional/ui/diff_spec.lua +++ b/test/functional/ui/diff_spec.lua @@ -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() diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua index c2bcac2449..85795e7e17 100644 --- a/test/functional/ui/float_spec.lua +++ b/test/functional/ui/float_spec.lua @@ -1445,16 +1445,16 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {5:âââââââââââ}| {5:â}{1: halloj! }{5:â}| {5:â}{1: BORDAA }{5:â}| {5:âââââââââââ}| ]], float_pos={ - [5] = { { id = 1002 }, "NW", 1, 2, 5, true } + [4] = { { id = 1001 }, "NW", 1, 2, 5, true } }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1488,16 +1488,16 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {5:âââââââââââ}| {5:â}{1: halloj! }{5:â}| {5:â}{1: BORDAA }{5:â}| {5:âââââââââââ}| ]], float_pos={ - [5] = { { id = 1002 }, "NW", 1, 2, 5, true } + [4] = { { id = 1001 }, "NW", 1, 2, 5, true } }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1531,16 +1531,16 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {5:âââââââââââŽ}| {5:â}{1: halloj! }{5:â}| {5:â}{1: BORDAA }{5:â}| {5:â°ââââââââââŻ}| ]], float_pos={ - [5] = { { id = 1002 }, "NW", 1, 2, 5, true } + [4] = { { id = 1001 }, "NW", 1, 2, 5, true } }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1574,16 +1574,16 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {5: }| {5: }{1: halloj! }{5: }| {5: }{1: BORDAA }{5: }| {5: }| ]], float_pos={ - [5] = { { id = 1002 }, "NW", 1, 2, 5, true } + [4] = { { id = 1001 }, "NW", 1, 2, 5, true } }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1618,16 +1618,16 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {5:x}{7:ĂĽĂĽĂĽĂĽĂĽĂĽĂĽĂĽĂĽ}{5:\}| {17:nĚĚ}{1: halloj! }{17:nĚĚ}| {17:nĚĚ}{1: BORDAA }{17:nĚĚ}| {5:\}{7:ĂĽĂĽĂĽĂĽĂĽĂĽĂĽĂĽĂĽ}{5:x}| ]], float_pos={ - [5] = { { id = 1002 }, "NW", 1, 2, 5, true } + [4] = { { id = 1001 }, "NW", 1, 2, 5, true } }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1661,14 +1661,14 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1: halloj! }| {1: BORDAA }| ]], float_pos={ - [5] = { { id = 1002 }, "NW", 1, 2, 5, true } + [4] = { { id = 1001 }, "NW", 1, 2, 5, true } }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1702,14 +1702,14 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {5:<}{1: halloj! }{5:>}| {5:<}{1: BORDAA }{5:>}| ]], float_pos={ - [5] = { { id = 1002 }, "NW", 1, 2, 5, true } + [4] = { { id = 1001 }, "NW", 1, 2, 5, true } }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1743,16 +1743,16 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {5:_________}| {1: halloj! }| {1: BORDAA }| {5:---------}| ]], float_pos={ - [5] = { { id = 1002 }, "NW", 1, 2, 5, true } + [4] = { { id = 1001 }, "NW", 1, 2, 5, true } }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1794,15 +1794,15 @@ describe('float window', function() ^ | ## grid 3 | - ## grid 5 + ## grid 4 {1: halloj! }{25: }| {1: BORDAA }{26: }| {25: }{26: }| ]], float_pos={ - [5] = { { id = 1002 }, "NW", 1, 2, 5, true } + [4] = { { id = 1001 }, "NW", 1, 2, 5, true } }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 6, curline = 5, curcol = 0, linecount = 6, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1880,16 +1880,16 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {5:â}{11:Left}{5:ââââââ}| {5:â}{1: halloj! }{5:â}| {5:â}{1: BORDAA }{5:â}| {5:âââââââââââ}| ]], float_pos={ - [5] = { { id = 1002 }, "NW", 1, 2, 5, true } + [4] = { { id = 1001 }, "NW", 1, 2, 5, true } }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1923,16 +1923,16 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {5:ââ}{11:Center}{5:âââ}| {5:â}{1: halloj! }{5:â}| {5:â}{1: BORDAA }{5:â}| {5:âââââââââââ}| ]], float_pos={ - [5] = { { id = 1002 }, "NW", 1, 2, 5, true } + [4] = { { id = 1001 }, "NW", 1, 2, 5, true } }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1966,16 +1966,16 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {5:âââââ}{11:Right}{5:â}| {5:â}{1: halloj! }{5:â}| {5:â}{1: BORDAA }{5:â}| {5:âââââââââââ}| ]], float_pos={ - [5] = { { id = 1002 }, "NW", 1, 2, 5, true } + [4] = { { id = 1001 }, "NW", 1, 2, 5, true } }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2009,16 +2009,16 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {5:ââââââ}đŚBB{5:â}| {5:â}{1: halloj! }{5:â}| {5:â}{1: BORDAA }{5:â}| {5:âââââââââââ}| ]], float_pos={ - [5] = { { id = 1002 }, "NW", 1, 2, 5, true } + [4] = { { id = 1001 }, "NW", 1, 2, 5, true } }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2117,17 +2117,17 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {5:âââââââââââ}| {5:â}{1:aaa aab }{5:â}| {5:â}{1:abb acc }{5:â}| {5:â}{1:^ }{5:â}| {5:âââââââââââ}| ]], float_pos={ - [5] = { { id = 1002 }, "NW", 1, 0, 5, true }; + [4] = { { id = 1001 }, "NW", 1, 0, 5, true }; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 2, curcol = 0, linecount = 3, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 2, curcol = 0, linecount = 3, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2170,23 +2170,23 @@ describe('float window', function() {0:~ }| ## grid 3 {3:-- }{8:match 1 of 4} | - ## grid 5 + ## grid 4 {5:âââââââââââ}| {5:â}{1:aaa aab }{5:â}| {5:â}{1:abb acc }{5:â}| {5:â}{1:acc^ }{5:â}| {5:âââââââââââ}| - ## grid 6 + ## grid 5 {1: aaa }| {1: aab }| {1: abb }| {13: acc }| ]], float_pos={ - [5] = { { id = 1002 }, "NW", 1, 0, 5, true, 50 }; - [6] = { { id = -1 }, "NW", 5, 4, 0, false, 100 }; + [4] = { { id = 1001 }, "NW", 1, 0, 5, true, 50 }; + [5] = { { id = -1 }, "NW", 4, 4, 0, false, 100 }; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount=1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 2, curcol = 3, linecount=3, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 2, curcol = 3, linecount=3, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2229,17 +2229,17 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {5:âââââââââââ}| {5:â}{1:aaa aab }{5:â}| {5:â}{1:abb acc }{5:â}| {5:â}{1:ac^c }{5:â}| {5:âââââââââââ}| ]], float_pos={ - [5] = { { id = 1002 }, "NW", 1, 0, 5, true }; + [4] = { { id = 1001 }, "NW", 1, 0, 5, true }; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 2, curcol = 2, linecount = 3, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 2, curcol = 2, linecount = 3, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2287,22 +2287,22 @@ describe('float window', function() {0:~ }| ## grid 3 :popup Test | - ## grid 5 + ## grid 4 {5:âââââââââââ}| {5:â}{1:aaa aab }{5:â}| {5:â}{1:abb acc }{5:â}| {5:â}{1:ac^c }{5:â}| {5:âââââââââââ}| - ## grid 6 + ## grid 5 {1: foo }| {1: bar }| {1: baz }| ]], float_pos={ - [5] = { { id = 1002 }, "NW", 1, 0, 5, true }; - [6] = { { id = -1 }, "NW", 5, 4, 2, false, 250 }; + [4] = { { id = 1001 }, "NW", 1, 0, 5, true }; + [5] = { { id = -1 }, "NW", 4, 4, 2, false, 250 }; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 2, curcol = 2, linecount = 3, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 2, curcol = 2, linecount = 3, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2347,15 +2347,15 @@ describe('float window', function() {0:~ }| ## grid 3 1,1 All | - ## grid 5 + ## grid 4 {1:^aaa aab }| {1:abb acc }| {2:~ }| ]], float_pos={ - [5] = {{id = 1002}, "NW", 1, 0, 5, true, 50}; + [4] = {{id = 1001}, "NW", 1, 0, 5, true, 50}; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2389,15 +2389,15 @@ describe('float window', function() {0:~ }| ## grid 3 1,5 All | - ## grid 5 + ## grid 4 {1:aaa ^aab }| {1:abb acc }| {2:~ }| ]], float_pos={ - [5] = {{id = 1002}, "NW", 1, 0, 5, true, 50}; + [4] = {{id = 1001}, "NW", 1, 0, 5, true, 50}; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 0, curcol = 4, linecount = 2, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 0, curcol = 4, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2596,10 +2596,10 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:x}| ]], float_pos={ - [5] = {{id = 1002}, "NW", 2, 0, 4, false} + [4] = {{id = 1001}, "NW", 2, 0, 4, false} }} else screen:expect([[ @@ -2633,10 +2633,10 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:x}| ]], float_pos={ - [5] = {{id = 1002}, "NW", 2, 0, 15, false} + [4] = {{id = 1001}, "NW", 2, 0, 15, false} }} else screen:expect([[ @@ -3132,13 +3132,13 @@ describe('float window', function() {0:~ }| {0:~ }| {0:~ }| - ## grid 6 + ## grid 5 {5:âââââââââââ}| {5:â}{1: halloj! }{5:â}| {5:â}{1: BORDAA }{5:â}| {5:âââââââââââ}| ]], float_pos={ - [6] = {{id = 1003}, "NW", 4, 1, 14, true} + [5] = {{id = 1002}, "NW", 4, 1, 14, true} }} else screen:expect([[ @@ -3189,13 +3189,13 @@ describe('float window', function() {0:~ }| {0:~ }| {0:~ }| - ## grid 6 + ## grid 5 {5:âââââââââââ}| {5:â}{1: halloj! }{5:â}| {5:â}{1: BORDAA }{5:â}| {5:âââââââââââ}| ]], float_pos={ - [6] = {{id = 1003}, "NE", 4, 0, 14, true} + [5] = {{id = 1002}, "NE", 4, 0, 14, true} }} else screen:expect([[ @@ -3246,13 +3246,13 @@ describe('float window', function() {0:~ }| {0:~ }| {0:~ }| - ## grid 6 + ## grid 5 {5:âââââââââââ}| {5:â}{1: halloj! }{5:â}| {5:â}{1: BORDAA }{5:â}| {5:âââââââââââ}| ]], float_pos={ - [6] = {{id = 1003}, "SE", 4, 1, 14, true} + [5] = {{id = 1002}, "SE", 4, 1, 14, true} }} else screen:expect([[ @@ -3303,13 +3303,13 @@ describe('float window', function() {0:~ }| {0:~ }| {0:~ }| - ## grid 6 + ## grid 5 {5:âââââââââââ}| {5:â}{1: halloj! }{5:â}| {5:â}{1: BORDAA }{5:â}| {5:âââââââââââ}| ]], float_pos={ - [6] = {{id = 1003}, "SW", 4, 0, 14, true} + [5] = {{id = 1002}, "SW", 4, 0, 14, true} }} else screen:expect([[ @@ -3379,12 +3379,10 @@ describe('float window', function() | ## grid 3 | - ## grid 5 + ## grid 4 {1:some info! }| ]], float_pos={ - [5] = { { - id = 1002 - }, "NW", 2, 3, 2, true } + [4] = { { id = 1001 }, "NW", 2, 3, 2, true } }} else screen:expect{grid=[[ @@ -3414,12 +3412,10 @@ describe('float window', function() | ## grid 3 | - ## grid 5 + ## grid 4 {1:some info! }| ]], float_pos={ - [5] = { { - id = 1002 - }, "NW", 2, 2, 2, true } + [4] = { { id = 1001 }, "NW", 2, 2, 2, true }, }} else screen:expect{grid=[[ @@ -3448,12 +3444,10 @@ describe('float window', function() more text | ## grid 3 | - ## grid 5 + ## grid 4 {1:some info! }| ]], float_pos={ - [5] = { { - id = 1002 - }, "NW", 2, 1, 32, true } + [4] = { { id = 1001 }, "NW", 2, 1, 32, true } }} else -- note: appears misaligned due to cursor @@ -3492,12 +3486,10 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:some info! }| ]], float_pos={ - [5] = { { - id = 1002 - }, "NW", 2, 2, 7, true } + [4] = { { id = 1001 }, "NW", 2, 2, 7, true } }} else screen:expect{grid=[[ @@ -3540,12 +3532,10 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:some info! }| ]], float_pos={ - [5] = { { - id = 1002 - }, "SW", 2, 1, 7, true } + [4] = { { id = 1001 }, "SW", 2, 1, 7, true } }} else screen:expect{grid=[[ @@ -3567,15 +3557,15 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----]{5:â}[6:--------------------]| - [2:----]{5:â}[6:--------------------]| - [2:----]{5:â}[6:--------------------]| - [2:----]{5:â}[6:--------------------]| - [2:----]{5:â}[6:--------------------]| - [2:----]{5:â}[6:--------------------]| - [2:----]{5:â}[6:--------------------]| - [2:----]{5:â}[6:--------------------]| - [2:----]{5:â}[6:--------------------]| + [2:----]{5:â}[5:--------------------]| + [2:----]{5:â}[5:--------------------]| + [2:----]{5:â}[5:--------------------]| + [2:----]{5:â}[5:--------------------]| + [2:----]{5:â}[5:--------------------]| + [2:----]{5:â}[5:--------------------]| + [2:----]{5:â}[5:--------------------]| + [2:----]{5:â}[5:--------------------]| + [2:----]{5:â}[5:--------------------]| [3:-------------------------]| ## grid 2 exam| @@ -3589,9 +3579,9 @@ describe('float window', function() the | ## grid 3 | - ## grid 5 + ## grid 4 {1:some info! }| - ## grid 6 + ## grid 5 ^ | {0:~ }| {0:~ }| @@ -3602,9 +3592,7 @@ describe('float window', function() {0:~ }| {0:~ }| ]], float_pos={ - [5] = { { - id = 1002 - }, "SW", 2, 8, 0, true } + [4] = { { id = 1001 }, "SW", 2, 8, 0, true } }} else screen:expect{grid=[[ @@ -3648,12 +3636,10 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:some info! }| ]], float_pos={ - [5] = { { - id = 1002 - }, "NW", 2, 2, 5, true } + [4] = { { id = 1001 }, "NW", 2, 2, 5, true } }} else screen:expect{grid=[[ @@ -3696,12 +3682,10 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:some info! }| ]], float_pos={ - [5] = { { - id = 1002 - }, "NW", 2, 3, 7, true } + [4] = { { id = 1001 }, "NW", 2, 3, 7, true } }} else screen:expect{grid=[[ @@ -3744,12 +3728,10 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:some info! }| ]], float_pos={ - [5] = { { - id = 1002 - }, "NW", 2, 2, 0, true } + [4] = { { id = 1001 }, "NW", 2, 2, 0, true } }} else screen:expect{grid=[[ @@ -3815,10 +3797,10 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:some floaty text }| ]], float_pos={ - [5] = {{id = 1002}, "NW", 1, 3, 1, true} + [4] = {{id = 1001}, "NW", 1, 3, 1, true} }} else screen:expect([[ @@ -3874,7 +3856,7 @@ describe('float window', function() meths.buf_set_lines(buf, 0, -1, true, {'such', 'very', 'float'}) local win = meths.open_win(buf, false, {relative='editor', width=15, height=4, row=2, col=10}) local expected_pos = { - [5]={{id=1002}, 'NW', 1, 2, 10, true}, + [4]={{id=1001}, 'NW', 1, 2, 10, true}, } if multigrid then screen:expect{grid=[[ @@ -3895,7 +3877,7 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:such }| {1:very }| {1:float }| @@ -3929,7 +3911,7 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:such }| {1:very }| {1:float }| @@ -3959,7 +3941,7 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:such }| {1:very }| {1:float }| @@ -3986,7 +3968,7 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:such }| {1:very }| {1:float }| @@ -4011,7 +3993,7 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:such }| {1:very }| {1:^float }| @@ -4045,7 +4027,7 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:such }| {1:very }| {1:^float }| @@ -4084,7 +4066,7 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:^such }| {1:very }| {1:float }| @@ -4121,7 +4103,7 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:^such }| {1:very }| {1:float }| @@ -4158,7 +4140,7 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:^such }| {1:very }| {1:float }| @@ -4195,7 +4177,7 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:^such }| {1:very }| {1:float }| @@ -4232,7 +4214,7 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:^such }| {1:very }| {1:float }| @@ -4269,7 +4251,7 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:^such }| {1:very }| {1:float }| @@ -4306,7 +4288,7 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:^such }| {1:very }| {1:float }| @@ -4343,7 +4325,7 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:^such }| {1:very }| {1:float }| @@ -4371,7 +4353,7 @@ describe('float window', function() | ## grid 3 | - ## grid 5 + ## grid 4 {1:^such }| {1:very }| {1:float }| @@ -4403,7 +4385,7 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:^such }| {1:very }| {1:float }| @@ -5063,12 +5045,12 @@ describe('float window', function() {13:aa }| {1:word }| {1:longtext }| - ## grid 6 + ## grid 5 {15:some info }| {15:about item }| ]], float_pos={ [4] = {{id = -1}, "NW", 2, 1, 0, false, 100}, - [6] = {{id = 1002}, "NW", 2, 1, 12, true, 50}, + [5] = {{id = 1001}, "NW", 2, 1, 12, true, 50}, }} else screen:expect([[ @@ -5104,11 +5086,11 @@ describe('float window', function() {0:~ }| ## grid 3 {3:-- INSERT --} | - ## grid 6 + ## grid 5 {15:some info }| {15:about item }| ]], float_pos={ - [6] = {{id = 1002}, "NW", 2, 1, 12, true}, + [5] = {{id = 1001}, "NW", 2, 1, 12, true}, }} else screen:expect([[ @@ -5256,14 +5238,14 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 here | float | ]], float_pos={ - [5] = {{id = 1002}, "NW", 1, 2, 5, true, 50}; + [4] = {{id = 1001}, "NW", 1, 2, 5, true, 50}; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -7580,18 +7562,18 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:foo }| {1:bar }| {1:baz }| ]], float_pos={ - [5] = {{id = 1002}, "NW", 1, 2, 5, true, 50}; + [4] = {{id = 1001}, "NW", 1, 2, 5, true, 50}; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; }} - meths.input_mouse('left', 'press', '', 5, 0, 0) + meths.input_mouse('left', 'press', '', 4, 0, 0) screen:expect{grid=[[ ## grid 1 [2:----------------------------------------]| @@ -7610,18 +7592,18 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:^foo }| {1:bar }| {1:baz }| ]], float_pos={ - [5] = {{id = 1002}, "NW", 1, 2, 5, true, 50}; + [4] = {{id = 1001}, "NW", 1, 2, 5, true, 50}; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; }} - meths.input_mouse('left', 'drag', '', 5, 1, 2) + meths.input_mouse('left', 'drag', '', 4, 1, 2) screen:expect{grid=[[ ## grid 1 [2:----------------------------------------]| @@ -7640,15 +7622,15 @@ describe('float window', function() {0:~ }| ## grid 3 {3:-- VISUAL --} | - ## grid 5 + ## grid 4 {27:foo}{1: }| {27:ba}{1:^r }| {1:baz }| ]], float_pos={ - [5] = {{id = 1002}, "NW", 1, 2, 5, true, 50}; + [4] = {{id = 1001}, "NW", 1, 2, 5, true, 50}; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 1, curcol = 2, linecount = 3, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 1, curcol = 2, linecount = 3, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -7708,20 +7690,20 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {5:ââââââââââââââââââââââ}| {5:â}{1:foo }{5:â}| {5:â}{1:bar }{5:â}| {5:â}{1:baz }{5:â}| {5:ââââââââââââââââââââââ}| ]], float_pos={ - [5] = {{id = 1002}, "NW", 1, 0, 5, true, 50}; + [4] = {{id = 1001}, "NW", 1, 0, 5, true, 50}; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; }} - meths.input_mouse('left', 'press', '', 5, 1, 1) + meths.input_mouse('left', 'press', '', 4, 1, 1) screen:expect{grid=[[ ## grid 1 [2:----------------------------------------]| @@ -7740,20 +7722,20 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {5:ââââââââââââââââââââââ}| {5:â}{1:^foo }{5:â}| {5:â}{1:bar }{5:â}| {5:â}{1:baz }{5:â}| {5:ââââââââââââââââââââââ}| ]], float_pos={ - [5] = {{id = 1002}, "NW", 1, 0, 5, true, 50}; + [4] = {{id = 1001}, "NW", 1, 0, 5, true, 50}; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; }} - meths.input_mouse('left', 'drag', '', 5, 2, 3) + meths.input_mouse('left', 'drag', '', 4, 2, 3) screen:expect{grid=[[ ## grid 1 [2:----------------------------------------]| @@ -7772,17 +7754,17 @@ describe('float window', function() {0:~ }| ## grid 3 {3:-- VISUAL --} | - ## grid 5 + ## grid 4 {5:ââââââââââââââââââââââ}| {5:â}{27:foo}{1: }{5:â}| {5:â}{27:ba}{1:^r }{5:â}| {5:â}{1:baz }{5:â}| {5:ââââââââââââââââââââââ}| ]], float_pos={ - [5] = {{id = 1002}, "NW", 1, 0, 5, true, 50}; + [4] = {{id = 1001}, "NW", 1, 0, 5, true, 50}; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 1, curcol = 2, linecount = 3, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 1, curcol = 2, linecount = 3, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -7843,19 +7825,19 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {3:floaty bar }| {1:foo }| {1:bar }| {1:baz }| ]], float_pos={ - [5] = {{id = 1002}, "NW", 1, 1, 5, true, 50}; + [4] = {{id = 1001}, "NW", 1, 1, 5, true, 50}; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; }} - meths.input_mouse('left', 'press', '', 5, 1, 0) + meths.input_mouse('left', 'press', '', 4, 1, 0) screen:expect{grid=[[ ## grid 1 [2:----------------------------------------]| @@ -7874,19 +7856,19 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {3:floaty bar }| {1:^foo }| {1:bar }| {1:baz }| ]], float_pos={ - [5] = {{id = 1002}, "NW", 1, 1, 5, true, 50}; + [4] = {{id = 1001}, "NW", 1, 1, 5, true, 50}; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; }} - meths.input_mouse('left', 'drag', '', 5, 2, 2) + meths.input_mouse('left', 'drag', '', 4, 2, 2) screen:expect{grid=[[ ## grid 1 [2:----------------------------------------]| @@ -7905,16 +7887,16 @@ describe('float window', function() {0:~ }| ## grid 3 {3:-- VISUAL --} | - ## grid 5 + ## grid 4 {3:floaty bar }| {27:foo}{1: }| {27:ba}{1:^r }| {1:baz }| ]], float_pos={ - [5] = {{id = 1002}, "NW", 1, 1, 5, true, 50}; + [4] = {{id = 1001}, "NW", 1, 1, 5, true, 50}; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 1, curcol = 2, linecount = 3, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 1, curcol = 2, linecount = 3, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -7959,11 +7941,11 @@ describe('float window', function() if multigrid then screen:expect([[ ## grid 1 - [2:-------------------]{5:â}[5:--------------------]| - [2:-------------------]{5:â}[5:--------------------]| - [2:-------------------]{5:â}[5:--------------------]| - [2:-------------------]{5:â}[5:--------------------]| - [2:-------------------]{5:â}[5:--------------------]| + [2:-------------------]{5:â}[4:--------------------]| + [2:-------------------]{5:â}[4:--------------------]| + [2:-------------------]{5:â}[4:--------------------]| + [2:-------------------]{5:â}[4:--------------------]| + [2:-------------------]{5:â}[4:--------------------]| {5:[No Name] }{4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -7974,7 +7956,7 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 ^foo | bar | baz | @@ -7982,14 +7964,14 @@ describe('float window', function() {0:~ }| ]]) - meths.input_mouse('left', 'press', '', 5, 2, 2) + meths.input_mouse('left', 'press', '', 4, 2, 2) screen:expect([[ ## grid 1 - [2:-------------------]{5:â}[5:--------------------]| - [2:-------------------]{5:â}[5:--------------------]| - [2:-------------------]{5:â}[5:--------------------]| - [2:-------------------]{5:â}[5:--------------------]| - [2:-------------------]{5:â}[5:--------------------]| + [2:-------------------]{5:â}[4:--------------------]| + [2:-------------------]{5:â}[4:--------------------]| + [2:-------------------]{5:â}[4:--------------------]| + [2:-------------------]{5:â}[4:--------------------]| + [2:-------------------]{5:â}[4:--------------------]| {5:[No Name] }{4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -8000,7 +7982,7 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 foo | bar | ba^z | @@ -8008,14 +7990,14 @@ describe('float window', function() {0:~ }| ]]) - meths.input_mouse('left', 'drag', '', 5, 1, 1) + meths.input_mouse('left', 'drag', '', 4, 1, 1) screen:expect([[ ## grid 1 - [2:-------------------]{5:â}[5:--------------------]| - [2:-------------------]{5:â}[5:--------------------]| - [2:-------------------]{5:â}[5:--------------------]| - [2:-------------------]{5:â}[5:--------------------]| - [2:-------------------]{5:â}[5:--------------------]| + [2:-------------------]{5:â}[4:--------------------]| + [2:-------------------]{5:â}[4:--------------------]| + [2:-------------------]{5:â}[4:--------------------]| + [2:-------------------]{5:â}[4:--------------------]| + [2:-------------------]{5:â}[4:--------------------]| {5:[No Name] }{4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -8026,7 +8008,7 @@ describe('float window', function() {0:~ }| ## grid 3 {3:-- VISUAL --} | - ## grid 5 + ## grid 4 foo | b^a{27:r} | {27:baz} | @@ -8125,11 +8107,11 @@ describe('float window', function() laborum^. | ## grid 3 | - ## grid 5 + ## grid 4 {1:test }| {1: }| {1:popup text }| - ]], float_pos={[5] = {{id = 1002}, "NW", 1, 2, 5, true}}} + ]], float_pos={[4] = {{id = 1001}, "NW", 1, 2, 5, true}}} else screen:expect([[ Ut enim ad minim veniam, quis nostrud | @@ -8168,11 +8150,11 @@ describe('float window', function() laborum^. | ## grid 3 | - ## grid 5 + ## grid 4 {9:test }| {9: }| {9:popup text }| - ]], float_pos={[5] = {{id = 1002}, "NW", 1, 2, 5, true}}, unchanged=true} + ]], float_pos={[4] = {{id = 1001}, "NW", 1, 2, 5, true}}, unchanged=true} else screen:expect([[ Ut enim ad minim veniam, quis nostrud | @@ -8212,12 +8194,12 @@ describe('float window', function() laborum^. | ## grid 3 | - ## grid 5 + ## grid 4 {13:test }| {13: }| {13:popup text }| ]], float_pos={ - [5] = {{id = 1002}, "NW", 1, 2, 5, true, 50}; + [4] = {{id = 1001}, "NW", 1, 2, 5, true, 50}; }} else screen:expect([[ @@ -8264,11 +8246,11 @@ describe('float window', function() laborum^. | ## grid 3 | - ## grid 5 + ## grid 4 {9:test }| {9: }| {10:popup text}{9: }| - ]], float_pos={[5] = {{id = 1002}, "NW", 1, 2, 5, true}}} + ]], float_pos={[4] = {{id = 1001}, "NW", 1, 2, 5, true}}} else screen:expect([[ Ut enim ad minim veniam, quis nostrud | @@ -8307,11 +8289,11 @@ describe('float window', function() laborum^. | ## grid 3 | - ## grid 5 + ## grid 4 {9:test }| {9: }| {11:popup text}{9: }| - ]], float_pos={[5] = {{id = 1002}, "NW", 1, 2, 5, true}}, unchanged=true} + ]], float_pos={[4] = {{id = 1001}, "NW", 1, 2, 5, true}}, unchanged=true} else screen:expect([[ Ut enim ad minim veniam, quis nostrud | @@ -8328,7 +8310,7 @@ describe('float window', function() -- Test scrolling by mouse if multigrid then - meths.input_mouse('wheel', 'down', '', 5, 2, 2) + meths.input_mouse('wheel', 'down', '', 4, 2, 2) screen:expect{grid=[[ ## grid 1 [2:--------------------------------------------------]| @@ -8351,11 +8333,11 @@ describe('float window', function() laborum^. | ## grid 3 | - ## grid 5 + ## grid 4 {11:popup text}{9: }| {12:~ }| {12:~ }| - ]], float_pos={[5] = {{id = 1002}, "NW", 1, 2, 5, true}}} + ]], float_pos={[4] = {{id = 1001}, "NW", 1, 2, 5, true}}} else meths.input_mouse('wheel', 'down', '', 0, 4, 7) screen:expect([[ @@ -8398,11 +8380,11 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {1:ĺŁ }| {1:ĺŁ }| {1: }| - ]], float_pos={ [5] = { { id = 1002 }, "NW", 1, 0, 11, true } }} + ]], float_pos={ [4] = { { id = 1001 }, "NW", 1, 0, 11, true } }} else screen:expect([[ # TODO: ćľ {1:ĺŁ }俥ćŻçĺçĄŽć§ | @@ -8480,14 +8462,12 @@ describe('float window', function() {3:~ }| ## grid 3 | - ## grid 6 + ## grid 5 {5: x x x xx}| {5: x x x x}| {5: }| ]], float_pos={ - [6] = { { - id = 1003 - }, "NW", 1, 0, 11, true } + [5] = { { id = 1002 }, "NW", 1, 0, 11, true } }} else screen:expect([[ @@ -8521,14 +8501,12 @@ describe('float window', function() {3:~ }| ## grid 3 | - ## grid 6 + ## grid 5 {5: x x x xx}| {5: x x x x}| {5: }| ]], float_pos={ - [6] = { { - id = 1003 - }, "NW", 1, 0, 12, true } + [5] = { { id = 1002 }, "NW", 1, 0, 12, true } }} else screen:expect([[ @@ -8590,11 +8568,11 @@ describe('float window', function() {1:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {2:^long }| {2:longer }| {2:longest}| - ## grid 6 + ## grid 5 {2:---------}| {2:- -}| {2:- -}| @@ -8604,11 +8582,11 @@ describe('float window', function() [1] = {foreground = Screen.colors.Blue1, bold = true}; [2] = {background = Screen.colors.LightMagenta}; }, float_pos={ + [4] = { { + id = 1001 + }, "NW", 1, 1, 1, true }, [5] = { { id = 1002 - }, "NW", 1, 1, 1, true }, - [6] = { { - id = 1003 }, "NW", 1, 0, 0, true } }} else @@ -8658,11 +8636,11 @@ describe('float window', function() {1:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {2:^l}| {2:o}| {2:n}| - ## grid 6 + ## grid 5 {2:---}| {2:- -}| {2:- -}| @@ -8672,12 +8650,8 @@ describe('float window', function() [1] = {foreground = Screen.colors.Blue1, bold = true}; [2] = {background = Screen.colors.LightMagenta}; }, float_pos={ - [5] = { { - id = 1002 - }, "NW", 1, 1, 1, true }, - [6] = { { - id = 1003 - }, "NW", 1, 0, 0, true } + [4] = { { id = 1001 }, "NW", 1, 1, 1, true }, + [5] = { { id = 1002 }, "NW", 1, 0, 0, true } }} else screen:expect([[ @@ -9088,7 +9062,7 @@ describe('float window', function() {0:~ }| {0:~ }| ## grid 3 - ## grid 5 + ## grid 4 {5:ââââââââââââââââââââââââââââââââââââââââââ}| {5:â}{1: }{5:â}| {5:â}{1: }{5:â}| @@ -9096,10 +9070,10 @@ describe('float window', function() {5:â}{1: }{5:â}| {5:ââââââââââââââââââââââââââââââââââââââââââ}| ]], float_pos={ - [5] = {{id = 1002}, "SW", 1, 9, 0, true, 50}; + [4] = {{id = 1001}, "SW", 1, 9, 0, true, 50}; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -9144,16 +9118,16 @@ describe('float window', function() {0:~ }| {0:~ }| ## grid 3 - ## grid 5 + ## grid 4 {5:ââââââââââââââââââââââââââââââââââââââââââ}| {5:â}{1: }{5:â}| {5:â}{1: }{5:â}| {5:ââââââââââââââââââââââââââââââââââââââââââ}| ]], float_pos={ - [5] = {{id = 1002}, "SW", 1, 9, 0, true, 50}; + [4] = {{id = 1001}, "SW", 1, 9, 0, true, 50}; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -9240,7 +9214,7 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {5:ââââââââââââââââââââââââââââââââââââââââââ}| {5:â}{1: }{5:â}| {5:â}{1: }{5:â}| @@ -9248,10 +9222,10 @@ describe('float window', function() {5:â}{1: }{5:â}| {5:ââââââââââââââââââââââââââââââââââââââââââ}| ]], float_pos={ - [5] = {{id = 1002}, "SW", 1, 8, 0, true, 50}; + [4] = {{id = 1001}, "SW", 1, 8, 0, true, 50}; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -9300,7 +9274,7 @@ describe('float window', function() ## grid 3 | {8:Press ENTER or type command to continue}^ | - ## grid 5 + ## grid 4 {5:ââââââââââââââââââââââââââââââââââââââââââ}| {5:â}{1: }{5:â}| {5:â}{1: }{5:â}| @@ -9308,10 +9282,10 @@ describe('float window', function() {5:â}{1: }{5:â}| {5:ââââââââââââââââââââââââââââââââââââââââââ}| ]], float_pos={ - [5] = {{id = 1002}, "SW", 1, 8, 0, true, 50}; + [4] = {{id = 1001}, "SW", 1, 8, 0, true, 50}; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -9351,16 +9325,16 @@ describe('float window', function() {0:~ }| ## grid 3 | - ## grid 5 + ## grid 4 {5:ââââââââââââââââââââââââââââââââââââââââââ}| {5:â}{1: }{5:â}| {5:â}{1: }{5:â}| {5:ââââââââââââââââââââââââââââââââââââââââââ}| ]], float_pos={ - [5] = {{id = 1002}, "SW", 1, 8, 0, true, 50}; + [4] = {{id = 1001}, "SW", 1, 8, 0, true, 50}; }, win_viewport={ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ |