mirror of
https://github.com/neovim/neovim.git
synced 2025-09-22 19:18:34 +00:00
ui: use line-based rather than char-based updates in screen.c
Add ext_newgrid and ext_hlstate extensions. These use predefined highlights and line-segment based updates, for efficiency and simplicity.. The ext_hlstate extension in addition allows semantic identification of builtin and syntax highlights. Reimplement the old char-based updates in the remote UI layer, for compatibility. For the moment, this is still the default. The bulitin TUI uses the new line-based protocol. cmdline uses curwin cursor position when ext_cmdline is active.
This commit is contained in:
@@ -300,7 +300,8 @@ void update_screen(int type)
|
||||
type = CLEAR;
|
||||
} else if (type != CLEAR) {
|
||||
check_for_delay(false);
|
||||
if (screen_ins_lines(0, 0, msg_scrolled, (int)Rows, NULL) == FAIL) {
|
||||
if (screen_ins_lines(0, msg_scrolled, (int)Rows, 0, (int)Columns)
|
||||
== FAIL) {
|
||||
type = CLEAR;
|
||||
}
|
||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||
@@ -4314,13 +4315,14 @@ static void screen_line(int row, int coloff, int endcol,
|
||||
/* 2: occupies two display cells */
|
||||
# define CHAR_CELLS char_cells
|
||||
|
||||
int start_dirty = -1, end_dirty = 0;
|
||||
|
||||
/* Check for illegal row and col, just in case. */
|
||||
if (row >= Rows)
|
||||
row = Rows - 1;
|
||||
if (endcol > Columns)
|
||||
endcol = Columns;
|
||||
|
||||
|
||||
off_from = (unsigned)(current_ScreenLine - ScreenLines);
|
||||
off_to = LineOffset[row] + coloff;
|
||||
max_off_from = off_from + screen_Columns;
|
||||
@@ -4368,6 +4370,10 @@ static void screen_line(int row, int coloff, int endcol,
|
||||
|
||||
|
||||
if (redraw_this) {
|
||||
if (start_dirty == -1) {
|
||||
start_dirty = col;
|
||||
}
|
||||
end_dirty = col + char_cells;
|
||||
// When writing a single-width character over a double-width
|
||||
// character and at the end of the redrawn text, need to clear out
|
||||
// the right halve of the old character.
|
||||
@@ -4388,12 +4394,11 @@ static void screen_line(int row, int coloff, int endcol,
|
||||
}
|
||||
|
||||
ScreenAttrs[off_to] = ScreenAttrs[off_from];
|
||||
/* For simplicity set the attributes of second half of a
|
||||
* double-wide character equal to the first half. */
|
||||
if (char_cells == 2)
|
||||
// For simplicity set the attributes of second half of a
|
||||
// double-wide character equal to the first half.
|
||||
if (char_cells == 2) {
|
||||
ScreenAttrs[off_to + 1] = ScreenAttrs[off_from];
|
||||
|
||||
screen_char(off_to, row, col + coloff);
|
||||
}
|
||||
}
|
||||
|
||||
off_to += CHAR_CELLS;
|
||||
@@ -4405,23 +4410,29 @@ static void screen_line(int row, int coloff, int endcol,
|
||||
/* Clear the second half of a double-wide character of which the left
|
||||
* half was overwritten with a single-wide character. */
|
||||
schar_from_ascii(ScreenLines[off_to], ' ');
|
||||
screen_char(off_to, row, col + coloff);
|
||||
end_dirty++;
|
||||
}
|
||||
|
||||
int clear_end = -1;
|
||||
if (clear_width > 0 && !rlflag) {
|
||||
// blank out the rest of the line
|
||||
while (col < clear_width && ScreenLines[off_to][0] == ' '
|
||||
&& ScreenLines[off_to][1] == NUL
|
||||
&& ScreenAttrs[off_to] == bg_attr
|
||||
) {
|
||||
++off_to;
|
||||
++col;
|
||||
}
|
||||
if (col < clear_width) {
|
||||
screen_fill(row, row + 1, col + coloff, clear_width + coloff, ' ', ' ',
|
||||
bg_attr);
|
||||
off_to += clear_width - col;
|
||||
col = clear_width;
|
||||
// TODO(bfredl): we could cache winline widths
|
||||
while (col < clear_width) {
|
||||
if (ScreenLines[off_to][0] != ' ' || ScreenLines[off_to][1] != NUL
|
||||
|| ScreenAttrs[off_to] != bg_attr) {
|
||||
ScreenLines[off_to][0] = ' ';
|
||||
ScreenLines[off_to][1] = NUL;
|
||||
ScreenAttrs[off_to] = bg_attr;
|
||||
if (start_dirty == -1) {
|
||||
start_dirty = col;
|
||||
end_dirty = col;
|
||||
} else if (clear_end == -1) {
|
||||
end_dirty = endcol;
|
||||
}
|
||||
clear_end = col+1;
|
||||
}
|
||||
col++;
|
||||
off_to++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4436,11 +4447,25 @@ static void screen_line(int row, int coloff, int endcol,
|
||||
|| ScreenAttrs[off_to] != hl) {
|
||||
schar_copy(ScreenLines[off_to], sc);
|
||||
ScreenAttrs[off_to] = hl;
|
||||
screen_char(off_to, row, col + coloff);
|
||||
if (start_dirty == -1) {
|
||||
start_dirty = col;
|
||||
}
|
||||
end_dirty = col+1;
|
||||
}
|
||||
} else
|
||||
LineWraps[row] = FALSE;
|
||||
}
|
||||
|
||||
if (clear_end < end_dirty) {
|
||||
clear_end = end_dirty;
|
||||
}
|
||||
if (start_dirty == -1) {
|
||||
start_dirty = end_dirty;
|
||||
}
|
||||
if (clear_end > start_dirty) {
|
||||
ui_line(row, coloff+start_dirty, coloff+end_dirty, coloff+clear_end,
|
||||
bg_attr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4722,11 +4747,11 @@ win_redr_status_matches (
|
||||
/* Put the wildmenu just above the command line. If there is
|
||||
* no room, scroll the screen one line up. */
|
||||
if (cmdline_row == Rows - 1) {
|
||||
screen_del_lines(0, 0, 1, (int)Rows, NULL);
|
||||
++msg_scrolled;
|
||||
screen_del_lines(0, 1, (int)Rows, 0, (int)Columns);
|
||||
msg_scrolled++;
|
||||
} else {
|
||||
++cmdline_row;
|
||||
++row;
|
||||
cmdline_row++;
|
||||
row++;
|
||||
}
|
||||
wild_menu_showing = WM_SCROLLED;
|
||||
} else {
|
||||
@@ -5090,6 +5115,8 @@ win_redr_custom (
|
||||
/*
|
||||
* Draw each snippet with the specified highlighting.
|
||||
*/
|
||||
screen_puts_line_start(row);
|
||||
|
||||
curattr = attr;
|
||||
p = buf;
|
||||
for (n = 0; hltab[n].start != NULL; n++) {
|
||||
@@ -5110,6 +5137,8 @@ win_redr_custom (
|
||||
// Make sure to use an empty string instead of p, if p is beyond buf + len.
|
||||
screen_puts(p >= buf + len ? (char_u *)"" : p, row, col, curattr);
|
||||
|
||||
screen_puts_line_flush(false);
|
||||
|
||||
if (wp == NULL) {
|
||||
// Fill the tab_page_click_defs array for clicking in the tab pages line.
|
||||
col = 0;
|
||||
@@ -5207,7 +5236,6 @@ void screen_getbytes(int row, int col, char_u *bytes, int *attrp)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Put string '*text' on the screen at position 'row' and 'col', with
|
||||
* attributes 'attr', and update ScreenLines[] and ScreenAttrs[].
|
||||
@@ -5219,6 +5247,20 @@ void screen_puts(char_u *text, int row, int col, int attr)
|
||||
screen_puts_len(text, -1, row, col, attr);
|
||||
}
|
||||
|
||||
static int put_dirty_row = -1;
|
||||
static int put_dirty_first = -1;
|
||||
static int put_dirty_last = 0;
|
||||
|
||||
/// Start a group of screen_puts_len calls that builds a single screen line.
|
||||
///
|
||||
/// Must be matched with a screen_puts_line_flush call before moving to
|
||||
/// another line.
|
||||
void screen_puts_line_start(int row)
|
||||
{
|
||||
assert(put_dirty_row == -1);
|
||||
put_dirty_row = row;
|
||||
}
|
||||
|
||||
/*
|
||||
* Like screen_puts(), but output "text[len]". When "len" is -1 output up to
|
||||
* a NUL.
|
||||
@@ -5242,6 +5284,16 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr)
|
||||
int force_redraw_next = FALSE;
|
||||
int need_redraw;
|
||||
|
||||
bool do_flush = false;
|
||||
if (put_dirty_row == -1) {
|
||||
screen_puts_line_start(row);
|
||||
do_flush = true;
|
||||
} else {
|
||||
if (row != put_dirty_row) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
if (ScreenLines == NULL || row >= screen_Rows) /* safety check */
|
||||
return;
|
||||
off = LineOffset[row] + col;
|
||||
@@ -5252,9 +5304,12 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr)
|
||||
schar_from_ascii(ScreenLines[off - 1], ' ');
|
||||
ScreenAttrs[off - 1] = 0;
|
||||
// redraw the previous cell, make it empty
|
||||
screen_char(off - 1, row, col - 1);
|
||||
/* force the cell at "col" to be redrawn */
|
||||
force_redraw_next = TRUE;
|
||||
if (put_dirty_first == -1) {
|
||||
put_dirty_first = col-1;
|
||||
}
|
||||
put_dirty_last = col+1;
|
||||
// force the cell at "col" to be redrawn
|
||||
force_redraw_next = true;
|
||||
}
|
||||
|
||||
max_off = LineOffset[row] + screen_Columns;
|
||||
@@ -5333,8 +5388,12 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr)
|
||||
ScreenLines[off + 1][0] = 0;
|
||||
ScreenAttrs[off + 1] = attr;
|
||||
}
|
||||
screen_char(off, row, col);
|
||||
if (put_dirty_first == -1) {
|
||||
put_dirty_first = col;
|
||||
}
|
||||
put_dirty_last = col+mbyte_cells;
|
||||
}
|
||||
|
||||
off += mbyte_cells;
|
||||
col += mbyte_cells;
|
||||
ptr += mbyte_blen;
|
||||
@@ -5345,13 +5404,31 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr)
|
||||
}
|
||||
}
|
||||
|
||||
/* If we detected the next character needs to be redrawn, but the text
|
||||
* doesn't extend up to there, update the character here. */
|
||||
if (force_redraw_next && col < screen_Columns) {
|
||||
screen_char(off, row, col);
|
||||
if (do_flush) {
|
||||
screen_puts_line_flush(true);
|
||||
}
|
||||
}
|
||||
|
||||
/// End a group of screen_puts_len calls and send the screen buffer to the UI
|
||||
/// layer.
|
||||
///
|
||||
/// @param set_cursor Move the visible cursor to the end of the changed region.
|
||||
/// This is a workaround for not yet refactored code paths
|
||||
/// and shouldn't be used in new code.
|
||||
void screen_puts_line_flush(bool set_cursor)
|
||||
{
|
||||
assert(put_dirty_row != -1);
|
||||
if (put_dirty_first != -1) {
|
||||
if (set_cursor) {
|
||||
ui_cursor_goto(put_dirty_row, put_dirty_last);
|
||||
}
|
||||
ui_line(put_dirty_row, put_dirty_first, put_dirty_last, put_dirty_last, 0);
|
||||
put_dirty_first = -1;
|
||||
put_dirty_last = 0;
|
||||
}
|
||||
put_dirty_row = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare for 'hlsearch' highlighting.
|
||||
*/
|
||||
@@ -5641,32 +5718,6 @@ next_search_hl_pos(
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put character ScreenLines["off"] on the screen at position "row" and "col",
|
||||
* using the attributes from ScreenAttrs["off"].
|
||||
*/
|
||||
static void screen_char(unsigned off, int row, int col)
|
||||
{
|
||||
// Check for illegal values, just in case (could happen just after resizing).
|
||||
if (row >= screen_Rows || col >= screen_Columns) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Outputting the last character on the screen may scrollup the screen.
|
||||
// Don't to it! Mark the character invalid (update it when scrolled up)
|
||||
// FIXME: The premise here is not actually true (cf. deferred wrap).
|
||||
if (row == screen_Rows - 1 && col == screen_Columns - 1
|
||||
// account for first command-line character in rightleft mode
|
||||
&& !cmdmsg_rl) {
|
||||
ScreenAttrs[off] = (sattr_T)-1;
|
||||
return;
|
||||
}
|
||||
|
||||
ui_cursor_goto(row, col);
|
||||
ui_set_highlight(ScreenAttrs[off]);
|
||||
|
||||
ui_puts(ScreenLines[off]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill the screen from 'start_row' to 'end_row', from 'start_col' to 'end_col'
|
||||
@@ -5675,12 +5726,6 @@ static void screen_char(unsigned off, int row, int col)
|
||||
*/
|
||||
void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1, int c2, int attr)
|
||||
{
|
||||
int row;
|
||||
int col;
|
||||
int off;
|
||||
int end_off;
|
||||
int did_delete;
|
||||
int c;
|
||||
schar_T sc;
|
||||
|
||||
if (end_row > screen_Rows) /* safety check */
|
||||
@@ -5692,8 +5737,7 @@ void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1,
|
||||
|| start_col >= end_col) /* nothing to do */
|
||||
return;
|
||||
|
||||
/* it's a "normal" terminal when not in a GUI or cterm */
|
||||
for (row = start_row; row < end_row; ++row) {
|
||||
for (int row = start_row; row < end_row; row++) {
|
||||
if (has_mbyte) {
|
||||
// When drawing over the right halve of a double-wide char clear
|
||||
// out the left halve. When drawing over the left halve of a
|
||||
@@ -5706,71 +5750,52 @@ void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1,
|
||||
screen_puts_len((char_u *)" ", 1, row, end_col, 0);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Try to use delete-line termcap code, when no attributes or in a
|
||||
* "normal" terminal, where a bold/italic space is just a
|
||||
* space.
|
||||
*/
|
||||
did_delete = FALSE;
|
||||
if (c2 == ' '
|
||||
&& end_col == Columns
|
||||
&& attr == 0) {
|
||||
/*
|
||||
* check if we really need to clear something
|
||||
*/
|
||||
col = start_col;
|
||||
if (c1 != ' ') /* don't clear first char */
|
||||
++col;
|
||||
|
||||
off = LineOffset[row] + col;
|
||||
end_off = LineOffset[row] + end_col;
|
||||
|
||||
// skip blanks (used often, keep it fast!)
|
||||
while (off < end_off && ScreenLines[off][0] == ' '
|
||||
&& ScreenLines[off][1] == 0 && ScreenAttrs[off] == 0) {
|
||||
off++;
|
||||
}
|
||||
if (off < end_off) { // something to be cleared
|
||||
col = off - LineOffset[row];
|
||||
ui_clear_highlight();
|
||||
ui_cursor_goto(row, col); // clear rest of this screen line
|
||||
ui_call_eol_clear();
|
||||
col = end_col - col;
|
||||
while (col--) { // clear chars in ScreenLines
|
||||
schar_from_ascii(ScreenLines[off], ' ');
|
||||
ScreenAttrs[off] = 0;
|
||||
++off;
|
||||
}
|
||||
}
|
||||
did_delete = TRUE; /* the chars are cleared now */
|
||||
}
|
||||
|
||||
off = LineOffset[row] + start_col;
|
||||
c = c1;
|
||||
schar_from_char(sc, c);
|
||||
int dirty_first = INT_MAX;
|
||||
int dirty_last = 0;
|
||||
int col = start_col;
|
||||
schar_from_char(sc, c1);
|
||||
int lineoff = LineOffset[row];
|
||||
for (col = start_col; col < end_col; col++) {
|
||||
int off = lineoff + col;
|
||||
if (schar_cmp(ScreenLines[off], sc) || ScreenAttrs[off] != attr) {
|
||||
schar_copy(ScreenLines[off], sc);
|
||||
ScreenAttrs[off] = attr;
|
||||
if (!did_delete || c != ' ')
|
||||
screen_char(off, row, col);
|
||||
if (dirty_first == INT_MAX) {
|
||||
dirty_first = col;
|
||||
}
|
||||
dirty_last = col+1;
|
||||
}
|
||||
++off;
|
||||
if (col == start_col) {
|
||||
if (did_delete)
|
||||
break;
|
||||
c = c2;
|
||||
schar_from_char(sc, c);
|
||||
schar_from_char(sc, c2);
|
||||
}
|
||||
}
|
||||
if (end_col == Columns)
|
||||
LineWraps[row] = FALSE;
|
||||
if (row == Rows - 1) { /* overwritten the command line */
|
||||
redraw_cmdline = TRUE;
|
||||
if (c1 == ' ' && c2 == ' ')
|
||||
clear_cmdline = FALSE; /* command line has been cleared */
|
||||
if (start_col == 0)
|
||||
mode_displayed = FALSE; /* mode cleared or overwritten */
|
||||
if (dirty_last > dirty_first) {
|
||||
// TODO(bfredl): support a cleared suffix even with a batched line?
|
||||
if (put_dirty_row == row) {
|
||||
if (put_dirty_first == -1) {
|
||||
put_dirty_first = dirty_first;
|
||||
}
|
||||
put_dirty_last = MAX(put_dirty_last, dirty_last);
|
||||
} else {
|
||||
int last = c2 != ' ' ? dirty_last : dirty_first + (c1 != ' ');
|
||||
ui_line(row, dirty_first, last, dirty_last, attr);
|
||||
}
|
||||
}
|
||||
|
||||
if (end_col == Columns) {
|
||||
LineWraps[row] = false;
|
||||
}
|
||||
|
||||
// TODO(bfredl): The relevant caller should do this
|
||||
if (row == Rows - 1) { // overwritten the command line
|
||||
redraw_cmdline = true;
|
||||
if (c1 == ' ' && c2 == ' ') {
|
||||
clear_cmdline = false; // command line has been cleared
|
||||
}
|
||||
if (start_col == 0) {
|
||||
mode_displayed = false; // mode cleared or overwritten
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6027,15 +6052,13 @@ static void screenclear2(void)
|
||||
return;
|
||||
}
|
||||
|
||||
ui_clear_highlight(); // don't want highlighting here
|
||||
|
||||
/* blank out ScreenLines */
|
||||
for (i = 0; i < Rows; ++i) {
|
||||
lineclear(LineOffset[i], (int)Columns);
|
||||
LineWraps[i] = FALSE;
|
||||
}
|
||||
|
||||
ui_call_clear(); // clear the display
|
||||
ui_call_grid_clear(1); // clear the display
|
||||
clear_cmdline = false;
|
||||
mode_displayed = false;
|
||||
screen_cleared = true; // can use contents of ScreenLines now
|
||||
@@ -6064,18 +6087,16 @@ static void lineclear(unsigned off, int width)
|
||||
(void)memset(ScreenAttrs + off, 0, (size_t)width * sizeof(sattr_T));
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy part of a Screenline for vertically split window "wp".
|
||||
*/
|
||||
static void linecopy(int to, int from, win_T *wp)
|
||||
/// Copy part of a Screenline for vertically split window.
|
||||
static void linecopy(int to, int from, int col, int width)
|
||||
{
|
||||
const unsigned off_to = LineOffset[to] + wp->w_wincol;
|
||||
const unsigned off_from = LineOffset[from] + wp->w_wincol;
|
||||
unsigned off_to = LineOffset[to] + col;
|
||||
unsigned off_from = LineOffset[from] + col;
|
||||
|
||||
memmove(ScreenLines + off_to, ScreenLines + off_from,
|
||||
wp->w_width * sizeof(schar_T));
|
||||
width * sizeof(schar_T));
|
||||
memmove(ScreenAttrs + off_to, ScreenAttrs + off_from,
|
||||
wp->w_width * sizeof(ScreenAttrs[0]));
|
||||
width * sizeof(sattr_T));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -6153,15 +6174,16 @@ static int win_do_lines(win_T *wp, int row, int line_count,
|
||||
// otherwise it will stay there forever.
|
||||
clear_cmdline = TRUE;
|
||||
int retval;
|
||||
ui_set_scroll_region(wp, row);
|
||||
|
||||
if (del) {
|
||||
retval = screen_del_lines(wp->w_winrow + row, 0, line_count,
|
||||
wp->w_height - row, wp);
|
||||
retval = screen_del_lines(wp->w_winrow + row, line_count,
|
||||
wp->w_winrow + wp->w_height,
|
||||
wp->w_wincol, wp->w_width);
|
||||
} else {
|
||||
retval = screen_ins_lines(wp->w_winrow + row, 0, line_count,
|
||||
wp->w_height - row, wp);
|
||||
retval = screen_ins_lines(wp->w_winrow + row, line_count,
|
||||
wp->w_winrow + wp->w_height,
|
||||
wp->w_wincol, wp->w_width);
|
||||
}
|
||||
ui_reset_scroll_region();
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -6189,19 +6211,13 @@ static void win_rest_invalid(win_T *wp)
|
||||
*/
|
||||
|
||||
|
||||
// insert lines on the screen and update ScreenLines[]
|
||||
// 'end' is the line after the scrolled part. Normally it is Rows.
|
||||
// When scrolling region used 'off' is the offset from the top for the region.
|
||||
// 'row' and 'end' are relative to the start of the region.
|
||||
//
|
||||
// return FAIL for failure, OK for success.
|
||||
int screen_ins_lines (
|
||||
int off,
|
||||
int row,
|
||||
int line_count,
|
||||
int end,
|
||||
win_T *wp /* NULL or window to use width from */
|
||||
)
|
||||
/// insert lines on the screen and update ScreenLines[]
|
||||
/// 'end' is the line after the scrolled part. Normally it is Rows.
|
||||
/// When scrolling region used 'off' is the offset from the top for the region.
|
||||
/// 'row' and 'end' are relative to the start of the region.
|
||||
///
|
||||
/// @return FAIL for failure, OK for success.
|
||||
int screen_ins_lines(int row, int line_count, int end, int col, int width)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
@@ -6213,18 +6229,16 @@ int screen_ins_lines (
|
||||
|
||||
// Shift LineOffset[] line_count down to reflect the inserted lines.
|
||||
// Clear the inserted lines in ScreenLines[].
|
||||
row += off;
|
||||
end += off;
|
||||
for (i = 0; i < line_count; ++i) {
|
||||
if (wp != NULL && wp->w_width != Columns) {
|
||||
for (i = 0; i < line_count; i++) {
|
||||
if (width != Columns) {
|
||||
// need to copy part of a line
|
||||
j = end - 1 - i;
|
||||
while ((j -= line_count) >= row) {
|
||||
linecopy(j + line_count, j, wp);
|
||||
linecopy(j + line_count, j, col, width);
|
||||
}
|
||||
j += line_count;
|
||||
lineclear(LineOffset[j] + wp->w_wincol, wp->w_width);
|
||||
LineWraps[j] = FALSE;
|
||||
lineclear(LineOffset[j] + col, width);
|
||||
LineWraps[j] = false;
|
||||
} else {
|
||||
j = end - 1 - i;
|
||||
temp = LineOffset[j];
|
||||
@@ -6233,29 +6247,23 @@ int screen_ins_lines (
|
||||
LineWraps[j + line_count] = LineWraps[j];
|
||||
}
|
||||
LineOffset[j + line_count] = temp;
|
||||
LineWraps[j + line_count] = FALSE;
|
||||
LineWraps[j + line_count] = false;
|
||||
lineclear(temp, (int)Columns);
|
||||
}
|
||||
}
|
||||
|
||||
ui_call_scroll(-line_count);
|
||||
ui_call_grid_scroll(1, row, end, col, col+width, -line_count, 0);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// delete lines on the screen and update ScreenLines[]
|
||||
// 'end' is the line after the scrolled part. Normally it is Rows.
|
||||
// When scrolling region used 'off' is the offset from the top for the region.
|
||||
// 'row' and 'end' are relative to the start of the region.
|
||||
//
|
||||
// Return OK for success, FAIL if the lines are not deleted.
|
||||
int screen_del_lines (
|
||||
int off,
|
||||
int row,
|
||||
int line_count,
|
||||
int end,
|
||||
win_T *wp /* NULL or window to use width from */
|
||||
)
|
||||
/// delete lines on the screen and update ScreenLines[]
|
||||
/// 'end' is the line after the scrolled part. Normally it is Rows.
|
||||
/// When scrolling region used 'off' is the offset from the top for the region.
|
||||
/// 'row' and 'end' are relative to the start of the region.
|
||||
///
|
||||
/// Return OK for success, FAIL if the lines are not deleted.
|
||||
int screen_del_lines(int row, int line_count, int end, int col, int width)
|
||||
{
|
||||
int j;
|
||||
int i;
|
||||
@@ -6267,18 +6275,16 @@ int screen_del_lines (
|
||||
|
||||
// Now shift LineOffset[] line_count up to reflect the deleted lines.
|
||||
// Clear the inserted lines in ScreenLines[].
|
||||
row += off;
|
||||
end += off;
|
||||
for (i = 0; i < line_count; ++i) {
|
||||
if (wp != NULL && wp->w_width != Columns) {
|
||||
for (i = 0; i < line_count; i++) {
|
||||
if (width != Columns) {
|
||||
// need to copy part of a line
|
||||
j = row + i;
|
||||
while ((j += line_count) <= end - 1) {
|
||||
linecopy(j - line_count, j, wp);
|
||||
linecopy(j - line_count, j, col, width);
|
||||
}
|
||||
j -= line_count;
|
||||
lineclear(LineOffset[j] + wp->w_wincol, wp->w_width);
|
||||
LineWraps[j] = FALSE;
|
||||
lineclear(LineOffset[j] + col, width);
|
||||
LineWraps[j] = false;
|
||||
} else {
|
||||
// whole width, moving the line pointers is faster
|
||||
j = row + i;
|
||||
@@ -6288,16 +6294,17 @@ int screen_del_lines (
|
||||
LineWraps[j - line_count] = LineWraps[j];
|
||||
}
|
||||
LineOffset[j - line_count] = temp;
|
||||
LineWraps[j - line_count] = FALSE;
|
||||
LineWraps[j - line_count] = false;
|
||||
lineclear(temp, (int)Columns);
|
||||
}
|
||||
}
|
||||
|
||||
ui_call_scroll(line_count);
|
||||
ui_call_grid_scroll(1, row, end, col, col+width, line_count, 0);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* show the current mode and ruler
|
||||
*
|
||||
|
Reference in New Issue
Block a user