From c9b559a0308714ef8ad396eb340a4af580e44d74 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sun, 5 Nov 2017 11:33:31 +0100 Subject: multigrid: introduce grid abstraction --- src/nvim/globals.h | 8 +--- src/nvim/mbyte.h | 7 --- src/nvim/memory.c | 4 +- src/nvim/move.c | 5 ++- src/nvim/screen.c | 123 +++++++++++++++++++++++++++++------------------------ src/nvim/types.h | 18 ++++++++ 6 files changed, 94 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 04ff1320ce..097c71928c 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -128,12 +128,6 @@ typedef off_t off_T; # endif #endif -/* - * The characters and attributes cached for the screen. - */ -typedef char_u schar_T[(MAX_MCO+1) * 4 + 1]; -typedef int16_t sattr_T; - /// ScreenLines[] contains a copy of the whole screen, as it currently is /// displayed. It is a single block of screen cells, the size of the screen /// plus one line. The extra line used as a buffer while redrawing a window @@ -167,6 +161,8 @@ EXTERN char_u *LineWraps INIT(= NULL); /* line wraps to next line */ EXTERN int screen_Rows INIT(= 0); /* actual size of ScreenLines[] */ EXTERN int screen_Columns INIT(= 0); /* actual size of ScreenLines[] */ +EXTERN ScreenGrid default_grid INIT(= { 0 }); + /* * When vgetc() is called, it sets mod_mask to the set of modifiers that are * held down based on the MOD_MASK_* symbols that are read first. diff --git a/src/nvim/mbyte.h b/src/nvim/mbyte.h index 70073a8540..ed48705c6d 100644 --- a/src/nvim/mbyte.h +++ b/src/nvim/mbyte.h @@ -19,13 +19,6 @@ #define MB_BYTE2LEN(b) utf8len_tab[b] #define MB_BYTE2LEN_CHECK(b) (((b) < 0 || (b) > 255) ? 1 : utf8len_tab[b]) -/// Maximum value for 'maxcombine' -/// -/// At most that number of composing characters may be attached to the leading -/// character by various `utfc_*` functions. Note that some functions do not -/// have this limit. -enum { MAX_MCO = 6 }; - // max length of an unicode char #define MB_MAXCHAR 6 diff --git a/src/nvim/memory.c b/src/nvim/memory.c index 6b96a3b070..ce914b43f9 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -698,8 +698,8 @@ void free_all_mem(void) buf = bufref_valid(&bufref) ? nextbuf : firstbuf; } - /* screenlines (can't display anything now!) */ - free_screenlines(); + // free screenlines (can't display anything now!) + free_screengrid(&default_grid); clear_hl_tables(false); list_free_log(); diff --git a/src/nvim/move.c b/src/nvim/move.c index 3a29851ee6..bb44b458e8 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -149,9 +149,12 @@ void update_topline(void) bool check_botline = false; long save_so = p_so; + // need to have w_grid.Rows/Columns updated + win_grid_alloc(curwin, false); + // If there is no valid screen and when the window height is zero just use // the cursor line. - if (!screen_valid(true) || curwin->w_height == 0) { + if (!screen_valid(true) || curwin->w_grid.Rows == 0) { curwin->w_topline = curwin->w_cursor.lnum; curwin->w_botline = curwin->w_topline; curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP; diff --git a/src/nvim/screen.c b/src/nvim/screen.c index d095bdb7c8..fcb225084d 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -130,6 +130,10 @@ static foldinfo_T win_foldinfo; /* info for 'foldcolumn' */ static schar_T *current_ScreenLine; StlClickDefinition *tab_page_click_defs = NULL; + +int grid_Rows = 0; +int grid_Columns = 0; + long tab_page_click_defs_size = 0; // for line_putchar. Contains the state that needs to be remembered from @@ -5883,8 +5887,6 @@ int screen_valid(int doclear) */ void screenalloc(bool doclear) { - int new_row, old_row; - int len; static bool entered = false; // avoid recursiveness int retry_count = 0; @@ -5892,7 +5894,7 @@ retry: // Allocation of the screen buffers is done only when the size changes and // when Rows and Columns have been set and we have started doing full // screen stuff. - if ((ScreenLines != NULL + if ((default_grid.ScreenLines != NULL && Rows == screen_Rows && Columns == screen_Columns ) @@ -5938,13 +5940,7 @@ retry: if (aucmd_win != NULL) win_free_lsize(aucmd_win); - // Allocate space for an extra row as scratch space, so that a redrawn - // line can be compared with the previous screen line state. - size_t ncells = (size_t)((Rows+1) * Columns); - schar_T *new_ScreenLines = xmalloc(ncells * sizeof(*new_ScreenLines)); - sattr_T *new_ScreenAttrs = xmalloc(ncells * sizeof(*new_ScreenAttrs)); - unsigned *new_LineOffset = xmalloc((size_t)(Rows * sizeof(*new_LineOffset))); - char_u *new_LineWraps = xmalloc((size_t)(Rows * sizeof(*new_LineWraps))); + alloc_grid(&default_grid, Rows, Columns, !doclear); StlClickDefinition *new_tab_page_click_defs = xcalloc( (size_t)Columns, sizeof(*new_tab_page_click_defs)); @@ -5955,46 +5951,11 @@ retry: win_alloc_lines(aucmd_win); } - for (new_row = 0; new_row < Rows; new_row++) { - new_LineOffset[new_row] = new_row * Columns; - new_LineWraps[new_row] = false; - - // If the screen is not going to be cleared, copy as much as - // possible from the old screen to the new one and clear the rest - // (used when resizing the window at the "--more--" prompt or when - // executing an external command, for the GUI). - if (!doclear) { - for (int col = 0; col < Columns; col++) { - schar_from_ascii(new_ScreenLines[new_row * Columns + col], ' '); - } - memset(new_ScreenAttrs + new_row * Columns, - 0, (size_t)Columns * sizeof(*new_ScreenAttrs)); - old_row = new_row + (screen_Rows - Rows); - if (old_row >= 0 && ScreenLines != NULL) { - if (screen_Columns < Columns) { - len = screen_Columns; - } else { - len = Columns; - } - - memmove(new_ScreenLines + new_LineOffset[new_row], - ScreenLines + LineOffset[old_row], - (size_t)len * sizeof(schar_T)); - memmove(new_ScreenAttrs + new_LineOffset[new_row], - ScreenAttrs + LineOffset[old_row], - (size_t)len * sizeof(new_ScreenAttrs[0])); - } - } - } - // Use the last line of the screen for the current line. - current_ScreenLine = new_ScreenLines + Rows * Columns; + clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size); + xfree(tab_page_click_defs); - free_screenlines(); + set_screengrid(&default_grid); - ScreenLines = new_ScreenLines; - ScreenAttrs = new_ScreenAttrs; - LineOffset = new_LineOffset; - LineWraps = new_LineWraps; tab_page_click_defs = new_tab_page_click_defs; tab_page_click_defs_size = Columns; @@ -6023,14 +5984,66 @@ retry: } } -void free_screenlines(void) +void alloc_grid(ScreenGrid *grid, int Rows, int Columns, bool copy) { - xfree(ScreenLines); - xfree(ScreenAttrs); - xfree(LineOffset); - xfree(LineWraps); - clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size); - xfree(tab_page_click_defs); + int new_row, old_row; + ScreenGrid new = { 0 }; + + size_t ncells = (size_t)((Rows+1) * Columns); + new.ScreenLines = xmalloc(ncells * sizeof(schar_T)); + new.ScreenAttrs = xmalloc(ncells * sizeof(sattr_T)); + new.LineOffset = xmalloc((size_t)(Rows * sizeof(unsigned))); + new.LineWraps = xmalloc((size_t)(Rows * sizeof(char_u))); + + new.Rows = Rows; + new.Columns = Columns; + + for (new_row = 0; new_row < Rows; new_row++) { + new.LineOffset[new_row] = new_row * Columns; + new.LineWraps[new_row] = false; + if (copy) { + // If the screen is not going to be cleared, copy as much as + // possible from the old screen to the new one and clear the rest + // (used when resizing the window at the "--more--" prompt or when + // executing an external command, for the GUI). + memset(new.ScreenLines + new_row * Columns, + ' ', (size_t)Columns * sizeof(schar_T)); + memset(new.ScreenAttrs + new_row * Columns, + 0, (size_t)Columns * sizeof(sattr_T)); + old_row = new_row + (grid->Rows - Rows); + if (old_row >= 0 && grid->ScreenLines != NULL) { + int len = MIN(grid->Columns, Columns); + memmove(new.ScreenLines + new.LineOffset[new_row], + grid->ScreenLines + grid->LineOffset[old_row], + (size_t)len * sizeof(schar_T)); + memmove(new.ScreenAttrs + new.LineOffset[new_row], + grid->ScreenAttrs + grid->LineOffset[old_row], + (size_t)len * sizeof(sattr_T)); + } + } + } + free_screengrid(grid); + *grid = new; +} + + +void free_screengrid(ScreenGrid *grid) +{ + xfree(grid->ScreenLines); + xfree(grid->ScreenAttrs); + xfree(grid->LineOffset); + xfree(grid->LineWraps); +} + +void set_screengrid(ScreenGrid *grid) +{ + ScreenLines = grid->ScreenLines; + ScreenAttrs = grid->ScreenAttrs; + LineOffset = grid->LineOffset; + LineWraps = grid->LineWraps; + grid_Rows = grid->Rows; + grid_Columns = grid->Columns; + current_ScreenLine = ScreenLines + grid_Rows * grid_Columns; } /// Clear tab_page_click_defs table diff --git a/src/nvim/types.h b/src/nvim/types.h index 317bead3bb..84634b1cb7 100644 --- a/src/nvim/types.h +++ b/src/nvim/types.h @@ -15,4 +15,22 @@ typedef uint32_t u8char_T; typedef struct expand expand_T; +#define MAX_MCO 6 // maximum value for 'maxcombine' + + +// The characters and attributes cached for the screen. +typedef char_u schar_T[(MAX_MCO+1) * 4 + 1]; +typedef int16_t sattr_T; + +// TODO(bfredl): find me a good home +typedef struct { + schar_T *ScreenLines; + sattr_T *ScreenAttrs; + unsigned *LineOffset; + char_u *LineWraps; + + int Rows; + int Columns; +} ScreenGrid; + #endif // NVIM_TYPES_H -- cgit From f102f50ebeca98365b308463c25eb2caffffba51 Mon Sep 17 00:00:00 2001 From: Utkarsh Maheshwari Date: Sat, 19 May 2018 21:03:17 +0530 Subject: multigrid: Change screen_* functions to grid_* functions --- src/nvim/api/ui_events.in.h | 2 + src/nvim/buffer_defs.h | 2 + src/nvim/edit.c | 27 +- src/nvim/globals.h | 3 +- src/nvim/hardcopy.c | 4 +- src/nvim/message.c | 50 +-- src/nvim/normal.c | 9 +- src/nvim/popupmnu.c | 27 +- src/nvim/screen.c | 807 +++++++++++++++++++++++--------------------- src/nvim/types.h | 10 + src/nvim/ui.c | 34 +- src/nvim/ui.h | 2 + src/nvim/version.c | 4 +- src/nvim/window.c | 24 +- 14 files changed, 552 insertions(+), 453 deletions(-) (limited to 'src') diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h index 10331fd5c2..5c48cb4804 100644 --- a/src/nvim/api/ui_events.in.h +++ b/src/nvim/api/ui_events.in.h @@ -81,6 +81,8 @@ void grid_line(Integer grid, Integer row, Integer col_start, Array data) void grid_scroll(Integer grid, Integer top, Integer bot, Integer left, Integer right, Integer rows, Integer cols) FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL; +void grid_destroy(Integer grid) + FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; void popupmenu_show(Array items, Integer selected, Integer row, Integer col) FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index d270714611..01f3044332 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -1183,6 +1183,8 @@ struct window_S { int w_tagstackidx; /* idx just below active entry */ int w_tagstacklen; /* number of tags on stack */ + ScreenGrid w_grid; // the grid specific to the window + /* * w_fraction is the fractional row of the cursor within the window, from * 0 at the top row to FRACTION_MULT at the last row. diff --git a/src/nvim/edit.c b/src/nvim/edit.c index c04190eaba..14577d5abb 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -560,7 +560,7 @@ static int insert_check(VimState *state) if (curwin->w_wcol < s->mincol - curbuf->b_p_ts && curwin->w_wrow == curwin->w_winrow - + curwin->w_height - 1 - p_so + + curwin->w_grid.Rows - 1 - p_so && (curwin->w_cursor.lnum != curwin->w_topline || curwin->w_topfill > 0)) { if (curwin->w_topfill > 0) { @@ -1502,17 +1502,17 @@ void edit_putchar(int c, int highlight) } else { attr = 0; } - pc_row = curwin->w_winrow + curwin->w_wrow; - pc_col = curwin->w_wincol; + pc_row = curwin->w_wrow; + pc_col = 0; pc_status = PC_STATUS_UNSET; if (curwin->w_p_rl) { - pc_col += curwin->w_width - 1 - curwin->w_wcol; + pc_col += curwin->w_grid.Columns - 1 - curwin->w_wcol; if (has_mbyte) { int fix_col = mb_fix_col(pc_col, pc_row); if (fix_col != pc_col) { - screen_putchar(' ', pc_row, fix_col, attr); - --curwin->w_wcol; + grid_putchar(&curwin->w_grid, ' ', pc_row, fix_col, attr); + curwin->w_wcol--; pc_status = PC_STATUS_RIGHT; } } @@ -1524,10 +1524,10 @@ void edit_putchar(int c, int highlight) /* save the character to be able to put it back */ if (pc_status == PC_STATUS_UNSET) { - screen_getbytes(pc_row, pc_col, pc_bytes, &pc_attr); + grid_getbytes(&curwin->w_grid, pc_row, pc_col, pc_bytes, &pc_attr); pc_status = PC_STATUS_SET; } - screen_putchar(c, pc_row, pc_col, attr); + grid_putchar(&curwin->w_grid, c, pc_row, pc_col, attr); } } @@ -1543,7 +1543,8 @@ void edit_unputchar(void) if (pc_status == PC_STATUS_RIGHT || pc_status == PC_STATUS_LEFT) { redrawWinline(curwin, curwin->w_cursor.lnum, false); } else { - screen_puts(pc_bytes, pc_row - msg_scrolled, pc_col, pc_attr); + grid_puts(&curwin->w_grid, pc_bytes, pc_row - msg_scrolled, pc_col, + pc_attr); } } } @@ -1566,7 +1567,7 @@ void display_dollar(colnr_T col) char_u *p = get_cursor_line_ptr(); curwin->w_cursor.col -= utf_head_off(p, p + col); curs_columns(false); // Recompute w_wrow and w_wcol - if (curwin->w_wcol < curwin->w_width) { + if (curwin->w_wcol < curwin->w_grid.Columns) { edit_putchar('$', FALSE); dollar_vcol = curwin->w_virtcol; } @@ -5825,7 +5826,7 @@ static void check_auto_format( /* * Find out textwidth to be used for formatting: * if 'textwidth' option is set, use it - * else if 'wrapmargin' option is set, use curwin->w_width - 'wrapmargin' + * else if 'wrapmargin' option is set, use curwin->w_grid.Columns-'wrapmargin' * if invalid value, use 0. * Set default to window width (maximum 79) for "gq" operator. */ @@ -5840,7 +5841,7 @@ comp_textwidth ( if (textwidth == 0 && curbuf->b_p_wm) { /* The width is the window width minus 'wrapmargin' minus all the * things that add to the margin. */ - textwidth = curwin->w_width - curbuf->b_p_wm; + textwidth = curwin->w_grid.Columns - curbuf->b_p_wm; if (cmdwin_type != 0) textwidth -= 1; textwidth -= curwin->w_p_fdc; @@ -5855,7 +5856,7 @@ comp_textwidth ( if (textwidth < 0) textwidth = 0; if (ff && textwidth == 0) { - textwidth = curwin->w_width - 1; + textwidth = curwin->w_grid.Columns - 1; if (textwidth > 79) textwidth = 79; } diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 097c71928c..3462199476 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -161,7 +161,8 @@ EXTERN char_u *LineWraps INIT(= NULL); /* line wraps to next line */ EXTERN int screen_Rows INIT(= 0); /* actual size of ScreenLines[] */ EXTERN int screen_Columns INIT(= 0); /* actual size of ScreenLines[] */ -EXTERN ScreenGrid default_grid INIT(= { 0 }); +EXTERN ScreenGrid default_grid INIT(= { 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0, + 0, 0, 0 }); /* * When vgetc() is called, it sets mod_mask to the set of modifiers that are diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c index a8731d5bd7..f66592682b 100644 --- a/src/nvim/hardcopy.c +++ b/src/nvim/hardcopy.c @@ -582,8 +582,8 @@ static void prt_header(prt_settings_T *const psettings, const int pagenum, */ static void prt_message(char_u *s) { - screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0); - screen_puts(s, (int)Rows - 1, 0, HL_ATTR(HLF_R)); + grid_fill(&default_grid, (int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0); + grid_puts(&default_grid, s, (int)Rows - 1, 0, HL_ATTR(HLF_R)); ui_flush(); } diff --git a/src/nvim/message.c b/src/nvim/message.c index 6de81a8aaf..bb7c605428 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1547,7 +1547,7 @@ void msg_prt_line(char_u *s, int list) } /* - * Use screen_puts() to output one multi-byte character. + * Use grid_puts() to output one multi-byte character. * Return the pointer "s" advanced to the next character. */ static char_u *screen_puts_mbyte(char_u *s, int l, int attr) @@ -1563,7 +1563,7 @@ static char_u *screen_puts_mbyte(char_u *s, int l, int attr) return s; } - screen_puts_len(s, l, msg_row, msg_col, attr); + grid_puts_len(&default_grid, s, l, msg_row, msg_col, attr); if (cmdmsg_rl) { msg_col -= cw; if (msg_col == 0) { @@ -1888,17 +1888,17 @@ static void msg_scroll_up(void) { if (dy_flags & DY_MSGSEP) { if (msg_scrolled == 0) { - screen_fill(Rows-p_ch-1, Rows-p_ch, 0, (int)Columns, - fill_msgsep, fill_msgsep, HL_ATTR(HLF_MSGSEP)); + grid_fill(&default_grid, Rows-p_ch-1, Rows-p_ch, 0, (int)Columns, + fill_msgsep, fill_msgsep, HL_ATTR(HLF_MSGSEP)); } int nscroll = MIN(msg_scrollsize()+1, Rows); - screen_del_lines(Rows-nscroll, 1, Rows, 0, Columns); + grid_del_lines(&default_grid, Rows-nscroll, 1, Rows, 0, Columns); } else { - screen_del_lines(0, 1, (int)Rows, 0, Columns); + grid_del_lines(&default_grid, 0, 1, (int)Rows, 0, Columns); } // TODO(bfredl): when msgsep display is properly batched, this fill should be // eliminated. - screen_fill(Rows-1, Rows, 0, (int)Columns, ' ', ' ', 0); + grid_fill(&default_grid, Rows-1, Rows, 0, (int)Columns, ' ', ' ', 0); } /* @@ -2097,7 +2097,7 @@ static void t_puts(int *t_col, const char_u *t_s, const char_u *s, int attr) { // Output postponed text. msg_didout = true; // Remember that line is not empty. - screen_puts_len((char_u *)t_s, (int)(s - t_s), msg_row, msg_col, attr); + grid_puts_len(&default_grid, (char_u *)t_s, (int)(s - t_s), msg_row, msg_col, attr); msg_col += *t_col; *t_col = 0; /* If the string starts with a composing character don't increment the @@ -2313,8 +2313,9 @@ static int do_more_prompt(int typed_char) } if (toscroll == -1 - && screen_ins_lines(0, 1, (int)Rows, 0, (int)Columns) == OK) { - screen_fill(0, 1, 0, (int)Columns, ' ', ' ', 0); + && grid_ins_lines(&default_grid, 0, 1, (int)Rows, + 0, (int)Columns) == OK) { + grid_fill(&default_grid, 0, 1, 0, (int)Columns, ' ', ' ', 0); // display line at top (void)disp_sb_line(0, mp); } else { @@ -2333,7 +2334,7 @@ static int do_more_prompt(int typed_char) /* scroll up, display line at bottom */ msg_scroll_up(); inc_msg_scrolled(); - screen_fill((int)Rows - 2, (int)Rows - 1, 0, + grid_fill(&default_grid, (int)Rows - 2, (int)Rows - 1, 0, (int)Columns, ' ', ' ', 0); mp_last = disp_sb_line((int)Rows - 2, mp_last); --toscroll; @@ -2342,7 +2343,7 @@ static int do_more_prompt(int typed_char) if (toscroll <= 0) { /* displayed the requested text, more prompt again */ - screen_fill((int)Rows - 1, (int)Rows, 0, + grid_fill(&default_grid, (int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0); msg_moremsg(FALSE); continue; @@ -2356,7 +2357,7 @@ static int do_more_prompt(int typed_char) } /* clear the --more-- message */ - screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0); + grid_fill(&default_grid, (int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0); State = oldState; setmouse(); if (quit_more) { @@ -2452,8 +2453,8 @@ void mch_msg(char *str) */ static void msg_screen_putchar(int c, int attr) { - msg_didout = TRUE; /* remember that line is not empty */ - screen_putchar(c, msg_row, msg_col, attr); + msg_didout = true; // remember that line is not empty + grid_putchar(&default_grid, c, msg_row, msg_col, attr); if (cmdmsg_rl) { if (--msg_col == 0) { msg_col = Columns; @@ -2473,11 +2474,12 @@ void msg_moremsg(int full) char_u *s = (char_u *)_("-- More --"); attr = HL_ATTR(HLF_M); - screen_puts(s, (int)Rows - 1, 0, attr); - if (full) - screen_puts((char_u *) - _(" SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "), - (int)Rows - 1, vim_strsize(s), attr); + grid_puts(&default_grid, s, (int)Rows - 1, 0, attr); + if (full) { + grid_puts(&default_grid, (char_u *) + _(" SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "), + (int)Rows - 1, vim_strsize(s), attr); + } } /* @@ -2526,11 +2528,11 @@ void msg_clr_eos(void) void msg_clr_eos_force(void) { if (cmdmsg_rl) { - screen_fill(msg_row, msg_row + 1, 0, msg_col + 1, ' ', ' ', 0); - screen_fill(msg_row + 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0); + grid_fill(&default_grid, msg_row, msg_row + 1, 0, msg_col + 1, ' ', ' ', 0); + grid_fill(&default_grid, msg_row + 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0); } else { - screen_fill(msg_row, msg_row + 1, msg_col, (int)Columns, ' ', ' ', 0); - screen_fill(msg_row + 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0); + grid_fill(&default_grid, msg_row, msg_row + 1, msg_col, (int)Columns, ' ', ' ', 0); + grid_fill(&default_grid, msg_row + 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0); } } diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 38ee0936aa..4e6c3c4063 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -3466,10 +3466,10 @@ static void display_showcmd(void) int len; len = (int)STRLEN(showcmd_buf); - if (len == 0) + if (len == 0) { showcmd_is_clear = true; - else { - screen_puts(showcmd_buf, (int)Rows - 1, sc_col, 0); + } else { + grid_puts(&default_grid, showcmd_buf, (int)Rows - 1, sc_col, 0); showcmd_is_clear = false; } @@ -3477,7 +3477,8 @@ static void display_showcmd(void) * clear the rest of an old message by outputting up to SHOWCMD_COLS * spaces */ - screen_puts((char_u *)" " + len, (int)Rows - 1, sc_col + len, 0); + grid_puts(&default_grid, (char_u *)" " + len, (int)Rows - 1, + sc_col + len, 0); setcursor(); /* put cursor back where it belongs */ } diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index 68c8967b91..e9a0c7c6b4 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -351,10 +351,10 @@ void pum_redraw(void) // prepend a space if there is room if (curwin->w_p_rl) { if (pum_col < curwin->w_wincol + curwin->w_width - 1) { - screen_putchar(' ', row, pum_col + 1, attr); + grid_putchar(&default_grid, ' ', row, pum_col + 1, attr); } } else if (pum_col > 0) { - screen_putchar(' ', row, pum_col - 1, attr); + grid_putchar(&default_grid, ' ', row, pum_col - 1, attr); } // Display each entry, use two spaces for a Tab. @@ -416,12 +416,13 @@ void pum_redraw(void) size++; } } - screen_puts_len(rt, (int)STRLEN(rt), row, col - size + 1, attr); + grid_puts_len(&default_grid, rt, (int)STRLEN(rt), row, col - size + 1, + attr); xfree(rt_start); xfree(st); col -= width; } else { - screen_puts_len(st, (int)STRLEN(st), row, col, attr); + grid_puts_len(&default_grid, st, (int)STRLEN(st), row, col, attr); xfree(st); col += width; } @@ -432,10 +433,10 @@ void pum_redraw(void) // Display two spaces for a Tab. if (curwin->w_p_rl) { - screen_puts_len((char_u *)" ", 2, row, col - 1, attr); + grid_puts_len(&default_grid, (char_u *)" ", 2, row, col - 1, attr); col -= 2; } else { - screen_puts_len((char_u *)" ", 2, row, col, attr); + grid_puts_len(&default_grid, (char_u *)" ", 2, row, col, attr); col += 2; } totwidth += 2; @@ -466,11 +467,11 @@ void pum_redraw(void) } if (curwin->w_p_rl) { - screen_fill(row, row + 1, pum_col - pum_base_width - n + 1, + grid_fill(&default_grid, row, row + 1, pum_col - pum_base_width - n + 1, col + 1, ' ', ' ', attr); col = pum_col - pum_base_width - n + 1; } else { - screen_fill(row, row + 1, col, pum_col + pum_base_width + n, + grid_fill(&default_grid, row, row + 1, col, pum_col + pum_base_width + n, ' ', ' ', attr); col = pum_col + pum_base_width + n; } @@ -478,24 +479,24 @@ void pum_redraw(void) } if (curwin->w_p_rl) { - screen_fill(row, row + 1, pum_col - pum_width + 1, col + 1, ' ', ' ', + grid_fill(&default_grid, row, row + 1, pum_col - pum_width + 1, col + 1, ' ', ' ', attr); } else { - screen_fill(row, row + 1, col, pum_col + pum_width, ' ', ' ', attr); + grid_fill(&default_grid, row, row + 1, col, pum_col + pum_width, ' ', ' ', attr); } if (pum_scrollbar > 0) { if (curwin->w_p_rl) { - screen_putchar(' ', row, pum_col - pum_width, + grid_putchar(&default_grid, ' ', row, pum_col - pum_width, i >= thumb_pos && i < thumb_pos + thumb_heigth ? attr_thumb : attr_scroll); } else { - screen_putchar(' ', row, pum_col + pum_width, + grid_putchar(&default_grid, ' ', row, pum_col + pum_width, i >= thumb_pos && i < thumb_pos + thumb_heigth ? attr_thumb : attr_scroll); } } - screen_puts_line_flush(false); + grid_puts_line_flush(&default_grid, false); row++; } } diff --git a/src/nvim/screen.c b/src/nvim/screen.c index fcb225084d..3aaca394f5 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -118,22 +118,14 @@ #define MB_FILLER_CHAR '<' /* character used when a double-width character * doesn't fit. */ -#define W_ENDCOL(wp) (wp->w_wincol + wp->w_width) +#define W_ENDCOL(wp) (wp->w_width + wp->w_wincol) static match_T search_hl; /* used for 'hlsearch' highlight matching */ static foldinfo_T win_foldinfo; /* info for 'foldcolumn' */ -/* - * Buffer for one screen line (characters and attributes). - */ -static schar_T *current_ScreenLine; - StlClickDefinition *tab_page_click_defs = NULL; -int grid_Rows = 0; -int grid_Columns = 0; - long tab_page_click_defs_size = 0; // for line_putchar. Contains the state that needs to be remembered from @@ -145,6 +137,13 @@ typedef struct { } LineState; #define LINE_STATE(p) { p, 0, 0 } +/// The last handle that was assigned to a ScreenGrid. 1 is reserved for +/// the default_grid. +static int last_handle = 1; + +/// Whether to call "ui_call_grid_resize" in win_grid_alloc +static int send_grid_resize; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "screen.c.generated.h" #endif @@ -304,12 +303,12 @@ void update_screen(int type) wp->w_redr_status = true; } } - } else if (msg_scrolled > Rows - 5) { // clearing is faster + } else if (msg_scrolled > default_grid.Rows - 5) { // clearing is faster type = CLEAR; } else if (type != CLEAR) { check_for_delay(false); - if (screen_ins_lines(0, msg_scrolled, (int)Rows, 0, (int)Columns) - == FAIL) { + if (grid_ins_lines(&default_grid, 0, msg_scrolled, (int)Rows, + 0, (int)Columns) == FAIL) { type = CLEAR; } FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { @@ -434,6 +433,7 @@ void update_screen(int type) win_redr_status(wp, true); // any popup menu will be redrawn below } } + send_grid_resize = false; end_search_hl(); // May need to redraw the popup menu. if (pum_drawn()) { @@ -502,7 +502,7 @@ void update_single_line(win_T *wp, linenr_T lnum) int j; // Don't do anything if the screen structures are (not yet) valid. - if (!screen_valid(true) || updating_screen) { + if (wp->w_grid.ScreenLines == NULL || updating_screen) { return; } updating_screen = true; @@ -673,19 +673,21 @@ static void win_update(win_T *wp) type = wp->w_redr_type; + win_grid_alloc(wp, false); + if (type >= NOT_VALID) { wp->w_redr_status = true; wp->w_lines_valid = 0; } /* Window is zero-height: nothing to draw. */ - if (wp->w_height == 0) { + if (wp->w_grid.Rows == 0) { wp->w_redr_type = 0; return; } /* Window is zero-width: Only need to draw the separator. */ - if (wp->w_width == 0) { + if (wp->w_grid.Columns == 0) { /* draw the vertical separator right of this window */ draw_vsep_win(wp, 0); wp->w_redr_type = 0; @@ -876,19 +878,19 @@ static void win_update(win_T *wp) j = 0; for (ln = wp->w_topline; ln < wp->w_lines[0].wl_lnum; ++ln) { ++j; - if (j >= wp->w_height - 2) + if (j >= wp->w_grid.Rows - 2) break; (void)hasFoldingWin(wp, ln, NULL, &ln, true, NULL); } } else j = wp->w_lines[0].wl_lnum - wp->w_topline; - if (j < wp->w_height - 2) { /* not too far off */ + if (j < wp->w_grid.Rows - 2) { /* not too far off */ i = plines_m_win(wp, wp->w_topline, wp->w_lines[0].wl_lnum - 1); /* insert extra lines for previously invisible filler lines */ if (wp->w_lines[0].wl_lnum != wp->w_topline) i += diff_check_fill(wp, wp->w_lines[0].wl_lnum) - wp->w_old_topfill; - if (i < wp->w_height - 2) { // less than a screen off + if (i < wp->w_grid.Rows - 2) { // less than a screen off // Try to insert the correct number of lines. // If not the last window, delete the lines at the bottom. // win_ins_lines may fail when the terminal can't do it. @@ -901,8 +903,8 @@ static void win_update(win_T *wp) /* Move the entries that were scrolled, disable * the entries for the lines to be redrawn. */ - if ((wp->w_lines_valid += j) > wp->w_height) - wp->w_lines_valid = wp->w_height; + if ((wp->w_lines_valid += j) > wp->w_grid.Rows) + wp->w_lines_valid = wp->w_grid.Rows; for (idx = wp->w_lines_valid; idx - j >= 0; idx--) wp->w_lines[idx] = wp->w_lines[idx - j]; while (idx >= 0) @@ -951,7 +953,7 @@ static void win_update(win_T *wp) row -= wp->w_topfill; if (row > 0) { if (win_del_lines(wp, 0, row) == OK) { - bot_start = wp->w_height - row; + bot_start = wp->w_grid.Rows - row; } else { mid_start = 0; // redraw all lines } @@ -970,7 +972,7 @@ static void win_update(win_T *wp) /* stop at line that didn't fit, unless it is still * valid (no lines deleted) */ if (row > 0 && bot_start + row - + (int)wp->w_lines[j].wl_size > wp->w_height) { + + (int)wp->w_lines[j].wl_size > wp->w_grid.Rows) { wp->w_lines_valid = idx + 1; break; } @@ -994,18 +996,18 @@ static void win_update(win_T *wp) // When starting redraw in the first line, redraw all lines. if (mid_start == 0) { - mid_end = wp->w_height; + mid_end = wp->w_grid.Rows; } } else { /* Not VALID or INVERTED: redraw all lines. */ mid_start = 0; - mid_end = wp->w_height; + mid_end = wp->w_grid.Rows; } if (type == SOME_VALID) { /* SOME_VALID: redraw all lines. */ mid_start = 0; - mid_end = wp->w_height; + mid_end = wp->w_grid.Rows; type = NOT_VALID; } @@ -1150,7 +1152,7 @@ static void win_update(win_T *wp) ++lnum; } srow += mid_start; - mid_end = wp->w_height; + mid_end = wp->w_grid.Rows; for (; idx < wp->w_lines_valid; ++idx) { /* find end */ if (wp->w_lines[idx].wl_valid && wp->w_lines[idx].wl_lnum >= to + 1) { @@ -1191,7 +1193,7 @@ static void win_update(win_T *wp) for (;; ) { /* stop updating when reached the end of the window (check for _past_ * the end of the window is at the end of the loop) */ - if (row == wp->w_height) { + if (row == wp->w_grid.Rows) { didline = TRUE; break; } @@ -1290,7 +1292,7 @@ static void win_update(win_T *wp) new_rows += plines_win(wp, l, true); } j++; - if (new_rows > wp->w_height - row - 2) { + if (new_rows > wp->w_grid.Rows - row - 2) { /* it's getting too much, must redraw the rest */ new_rows = 9999; break; @@ -1302,20 +1304,20 @@ static void win_update(win_T *wp) * remaining text or scrolling fails, must redraw the * rest. If scrolling works, must redraw the text * below the scrolled text. */ - if (row - xtra_rows >= wp->w_height - 2) { + if (row - xtra_rows >= wp->w_grid.Rows - 2) { mod_bot = MAXLNUM; } else { if (win_del_lines(wp, row, -xtra_rows) == FAIL) { mod_bot = MAXLNUM; } else { - bot_start = wp->w_height + xtra_rows; + bot_start = wp->w_grid.Rows + xtra_rows; } } } else if (xtra_rows > 0) { /* May scroll text down. If there is not enough * remaining text of scrolling fails, must redraw the * rest. */ - if (row + xtra_rows >= wp->w_height - 2) { + if (row + xtra_rows >= wp->w_grid.Rows - 2) { mod_bot = MAXLNUM; } else { if (win_ins_lines(wp, row + old_rows, xtra_rows) == FAIL) { @@ -1344,7 +1346,7 @@ static void win_update(win_T *wp) wp->w_lines[j] = wp->w_lines[i]; /* stop at a line that won't fit */ if (x + (int)wp->w_lines[j].wl_size - > wp->w_height) { + > wp->w_grid.Rows) { wp->w_lines_valid = j + 1; break; } @@ -1357,8 +1359,8 @@ static void win_update(win_T *wp) /* move entries in w_lines[] downwards */ j -= i; wp->w_lines_valid += j; - if (wp->w_lines_valid > wp->w_height) - wp->w_lines_valid = wp->w_height; + if (wp->w_lines_valid > wp->w_grid.Rows) + wp->w_lines_valid = wp->w_grid.Rows; for (i = wp->w_lines_valid; i - j >= idx; --i) wp->w_lines[i] = wp->w_lines[i - j]; @@ -1392,12 +1394,12 @@ static void win_update(win_T *wp) && wp->w_lines[idx].wl_lnum == lnum && lnum > wp->w_topline && !(dy_flags & (DY_LASTLINE | DY_TRUNCATE)) - && srow + wp->w_lines[idx].wl_size > wp->w_height + && srow + wp->w_lines[idx].wl_size > wp->w_grid.Rows && diff_check_fill(wp, lnum) == 0 ) { /* This line is not going to fit. Don't draw anything here, * will draw "@ " lines below. */ - row = wp->w_height + 1; + row = wp->w_grid.Rows + 1; } else { prepare_search_hl(wp, lnum); /* Let the syntax stuff know we skipped a few lines. */ @@ -1408,7 +1410,7 @@ static void win_update(win_T *wp) /* * Display one line. */ - row = win_line(wp, lnum, srow, wp->w_height, mod_top == 0, false); + row = win_line(wp, lnum, srow, wp->w_grid.Rows, mod_top == 0, false); wp->w_lines[idx].wl_folded = FALSE; wp->w_lines[idx].wl_lastlnum = lnum; @@ -1422,7 +1424,7 @@ static void win_update(win_T *wp) // Past end of the window or end of the screen. Note that after // resizing wp->w_height may be end up too big. That's a problem // elsewhere, but prevent a crash here. - if (row > wp->w_height || row + wp->w_winrow >= Rows) { + if (row > wp->w_grid.Rows || row + wp->w_winrow >= Rows) { // we may need the size of that too long line later on if (dollar_vcol == -1) { wp->w_lines[idx].wl_size = plines_win(wp, lnum, true); @@ -1443,7 +1445,7 @@ static void win_update(win_T *wp) // This line does not need to be drawn, advance to the next one. row += wp->w_lines[idx++].wl_size; - if (row > wp->w_height) /* past end of screen */ + if (row > wp->w_grid.Rows) /* past end of screen */ break; lnum = wp->w_lines[idx - 1].wl_lastlnum + 1; did_update = DID_NONE; @@ -1483,31 +1485,28 @@ static void win_update(win_T *wp) * Don't overwrite it, it can be edited. */ wp->w_botline = lnum + 1; - } else if (diff_check_fill(wp, lnum) >= wp->w_height - srow) { + } else if (diff_check_fill(wp, lnum) >= wp->w_grid.Rows - srow) { /* Window ends in filler lines. */ wp->w_botline = lnum; - wp->w_filler_rows = wp->w_height - srow; + wp->w_filler_rows = wp->w_grid.Rows - srow; } else if (dy_flags & DY_TRUNCATE) { // 'display' has "truncate" - int scr_row = wp->w_winrow + wp->w_height - 1; + int scr_row = wp->w_grid.Rows - 1; // Last line isn't finished: Display "@@@" in the last screen line. - screen_puts_len((char_u *)"@@", 2, scr_row, wp->w_wincol, at_attr); + grid_puts_len(&wp->w_grid, (char_u *)"@@", 2, scr_row, 0, at_attr); - screen_fill(scr_row, scr_row + 1, - (int)wp->w_wincol + 2, (int)W_ENDCOL(wp), - '@', ' ', at_attr); + grid_fill(&wp->w_grid, scr_row, scr_row + 1, 2, (int)wp->w_grid.Columns, + '@', ' ', at_attr); set_empty_rows(wp, srow); wp->w_botline = lnum; } else if (dy_flags & DY_LASTLINE) { // 'display' has "lastline" // Last line isn't finished: Display "@@@" at the end. - screen_fill(wp->w_winrow + wp->w_height - 1, - wp->w_winrow + wp->w_height, - W_ENDCOL(wp) - 3, W_ENDCOL(wp), - '@', '@', at_attr); + grid_fill(&wp->w_grid, wp->w_height - 1, wp->w_height, + wp->w_grid.Columns - 3, wp->w_grid.Columns, '@', '@', at_attr); set_empty_rows(wp, srow); wp->w_botline = lnum; } else { - win_draw_end(wp, '@', ' ', srow, wp->w_height, HLF_AT); + win_draw_end(wp, '@', ' ', srow, wp->w_grid.Rows, HLF_AT); wp->w_botline = lnum; } } else { @@ -1522,8 +1521,8 @@ static void win_update(win_T *wp) i = '-'; else i = fill_diff; - if (row + j > wp->w_height) - j = wp->w_height - row; + if (row + j > wp->w_grid.Rows) + j = wp->w_grid.Rows - row; win_draw_end(wp, i, i, row, row + (int)j, HLF_DED); row += j; } @@ -1614,9 +1613,8 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h /* draw the fold column at the right */ if (n > wp->w_width) n = wp->w_width; - screen_fill(wp->w_winrow + row, wp->w_winrow + endrow, - W_ENDCOL(wp) - n, W_ENDCOL(wp), - ' ', ' ', win_hl_attr(wp, HLF_FC)); + grid_fill(&wp->w_grid, row, endrow, wp->w_grid.Columns - n, + wp->w_grid.Columns, ' ', ' ', win_hl_attr(wp, HLF_FC)); } if (signcolumn_on(wp)) { @@ -1626,27 +1624,24 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h if (nn > wp->w_width) { nn = wp->w_width; } - screen_fill(wp->w_winrow + row, wp->w_winrow + endrow, - W_ENDCOL(wp) - nn, W_ENDCOL(wp) - n, - ' ', ' ', win_hl_attr(wp, HLF_SC)); + grid_fill(&wp->w_grid, row, endrow, wp->w_grid.Columns - nn, + wp->w_grid.Columns - n, ' ', ' ', win_hl_attr(wp, HLF_SC)); n = nn; } - screen_fill(wp->w_winrow + row, wp->w_winrow + endrow, - wp->w_wincol, W_ENDCOL(wp) - 1 - FDC_OFF, - c2, c2, attr); - screen_fill(wp->w_winrow + row, wp->w_winrow + endrow, - W_ENDCOL(wp) - 1 - FDC_OFF, W_ENDCOL(wp) - FDC_OFF, - c1, c2, attr); + grid_fill(&wp->w_grid, row, endrow, 0, wp->w_grid.Columns - 1 - FDC_OFF, + c2, c2, attr); + grid_fill(&wp->w_grid, row, endrow, + wp->w_grid.Columns - 1 - FDC_OFF, wp->w_grid.Columns - FDC_OFF, + c1, c2, attr); } else { if (cmdwin_type != 0 && wp == curwin) { /* draw the cmdline character in the leftmost column */ n = 1; if (n > wp->w_width) n = wp->w_width; - screen_fill(wp->w_winrow + row, wp->w_winrow + endrow, - wp->w_wincol, wp->w_wincol + n, - cmdwin_type, ' ', win_hl_attr(wp, HLF_AT)); + grid_fill(&wp->w_grid, row, endrow, 0, n, cmdwin_type, ' ', + win_hl_attr(wp, HLF_AT)); } if (fdc > 0) { int nn = n + fdc; @@ -1654,9 +1649,8 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h /* draw the fold column at the left */ if (nn > wp->w_width) nn = wp->w_width; - screen_fill(wp->w_winrow + row, wp->w_winrow + endrow, - wp->w_wincol + n, wp->w_wincol + nn, - ' ', ' ', win_hl_attr(wp, HLF_FC)); + grid_fill(&wp->w_grid, row, endrow, n, nn, ' ', ' ', + win_hl_attr(wp, HLF_FC)); n = nn; } @@ -1667,15 +1661,12 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h if (nn > wp->w_width) { nn = wp->w_width; } - screen_fill(wp->w_winrow + row, wp->w_winrow + endrow, - wp->w_wincol + n, wp->w_wincol + nn, - ' ', ' ', win_hl_attr(wp, HLF_SC)); + grid_fill(&wp->w_grid, row, endrow, n, nn, ' ', ' ', + win_hl_attr(wp, HLF_SC)); n = nn; } - screen_fill(wp->w_winrow + row, wp->w_winrow + endrow, - wp->w_wincol + FDC_OFF, W_ENDCOL(wp), - c1, c2, attr); + grid_fill(&wp->w_grid, row, endrow, FDC_OFF, wp->w_grid.Columns, c1, c2, attr); } set_empty_rows(wp, row); } @@ -1768,8 +1759,9 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T int fdc; int col; int txtcol; - int off = (int)(current_ScreenLine - ScreenLines); + int off; int ri; + ScreenGrid *grid = &wp->w_grid; /* Build the fold line: * 1. Add the cmdwin_type for the command-line window @@ -1780,14 +1772,15 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T * 6. set highlighting for the Visual area an other text */ col = 0; + off = (int)(grid->Rows * grid->Columns); /* * 1. Add the cmdwin_type for the command-line window * Ignores 'rightleft', this window is never right-left. */ if (cmdwin_type != 0 && wp == curwin) { - schar_from_ascii(ScreenLines[off], cmdwin_type); - ScreenAttrs[off] = win_hl_attr(wp, HLF_AT); + schar_from_ascii(grid->ScreenLines[off], cmdwin_type); + grid->ScreenAttrs[off] = win_hl_attr(wp, HLF_AT); col++; } @@ -1803,7 +1796,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T win_hl_attr(wp, HLF_FC)); // reverse the fold column for (i = 0; i < fdc; i++) { - schar_from_ascii(ScreenLines[off + wp->w_width - i - 1 - col], buf[i]); + schar_from_ascii(grid->ScreenLines[off + wp->w_width - i - 1 - col], buf[i]); } } else { copy_text_attr(off + col, buf, fdc, win_hl_attr(wp, HLF_FC)); @@ -1813,10 +1806,10 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T # define RL_MEMSET(p, v, l) if (wp->w_p_rl) \ for (ri = 0; ri < l; ++ri) \ - ScreenAttrs[off + (wp->w_width - (p) - (l)) + ri] = v; \ + grid->ScreenAttrs[off + (wp->w_width - (p) - (l)) + ri] = v; \ else \ for (ri = 0; ri < l; ++ri) \ - ScreenAttrs[off + (p) + ri] = v + grid->ScreenAttrs[off + (p) + ri] = v /* Set all attributes of the 'number' or 'relativenumber' column and the * text */ @@ -1882,11 +1875,9 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T txtcol = col; /* remember where text starts */ - /* - * 5. move the text to current_ScreenLine. Fill up with "fill_fold". - * Right-left text is put in columns 0 - number-col, normal text is put - * in columns number-col - window-width. - */ + // 5. move the text to grid->ScreenLines[off]. Fill up with "fill_fold". + // Right-left text is put in columns 0 - number-col, normal text is put + // in columns number-col - window-width. int idx; if (wp->w_p_rl) { @@ -1903,7 +1894,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T // This is obvious wrong. If Vim ever fixes this, solve for "cells" again // in the correct condition. int maxcells = wp->w_width - col - (wp->w_p_rl ? col : 0); - int cells = line_putchar(&s, &ScreenLines[idx], maxcells, wp->w_p_rl); + int cells = line_putchar(&s, &grid->ScreenLines[idx], maxcells, wp->w_p_rl); if (cells == -1) { break; } @@ -1920,7 +1911,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T while (col < wp->w_width - (wp->w_p_rl ? txtcol : 0) ) { - schar_copy(ScreenLines[off+col++], sc); + schar_copy(grid->ScreenLines[off+col++], sc); } if (text != buf) @@ -1984,8 +1975,8 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T txtcol -= wp->w_leftcol; } if (txtcol >= 0 && txtcol < wp->w_width) { - ScreenAttrs[off + txtcol] = - hl_combine_attr(ScreenAttrs[off + txtcol], win_hl_attr(wp, HLF_MC)); + grid->ScreenAttrs[off + txtcol] = + hl_combine_attr(grid->ScreenAttrs[off + txtcol], win_hl_attr(wp, HLF_MC)); } txtcol = old_txtcol; j = wp->w_p_cc_cols[++i]; @@ -2000,12 +1991,12 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T else txtcol -= wp->w_leftcol; if (txtcol >= 0 && txtcol < wp->w_width) - ScreenAttrs[off + txtcol] = hl_combine_attr( - ScreenAttrs[off + txtcol], win_hl_attr(wp, HLF_CUC)); + grid->ScreenAttrs[off + txtcol] = hl_combine_attr( + grid->ScreenAttrs[off + txtcol], win_hl_attr(wp, HLF_CUC)); } - screen_line(row + wp->w_winrow, wp->w_wincol, wp->w_width, - wp->w_width, false, wp, wp->w_hl_attr_normal, false); + grid_move_line(grid, row, 0, grid->Columns, grid->Columns, false, wp, + wp->w_hl_attr_normal, false); /* * Update w_cline_height and w_cline_folded if the cursor line was @@ -2114,7 +2105,7 @@ win_line ( char_u *line; // current line char_u *ptr; // current position in "line" int row; // row in the window, excl w_winrow - int screen_row; // row on the screen, incl w_winrow + ScreenGrid *grid = &wp->w_grid; // grid specfic to the window char_u extra[18]; /* line number and 'fdc' must fit in here */ int n_extra = 0; /* number of extra chars */ @@ -2244,7 +2235,9 @@ win_line ( return startrow; row = startrow; - screen_row = row + wp->w_winrow; + + // allocate window grid if not already + win_grid_alloc(wp, true); if (!number_only) { // To speed up the loop below, set extra_check when there is linebreak, @@ -2681,11 +2674,11 @@ win_line ( cur = cur->next; } - off = (unsigned)(current_ScreenLine - ScreenLines); + off = (unsigned)(grid->Rows * grid->Columns); int col = 0; // Visual column on screen. if (wp->w_p_rl) { // Rightleft window: process the text in the normal direction, but put - // it in current_ScreenLine[] from right to left. Start at the + // it in grid->ScreenLines[off] from right to left. Start at the // rightmost column of the window. col = wp->w_width - 1; off += col; @@ -2906,14 +2899,14 @@ win_line ( && lnum == wp->w_cursor.lnum && vcol >= (long)wp->w_virtcol && filler_todo <= 0) || (number_only && draw_state > WL_NR)) { - screen_line(screen_row, wp->w_wincol, col, -wp->w_width, wp->w_p_rl, wp, - wp->w_hl_attr_normal, false); + grid_move_line(grid, row, 0, col, -grid->Columns, wp->w_p_rl, wp, + wp->w_hl_attr_normal, false); // Pretend we have finished updating the window. Except when // 'cursorcolumn' is set. if (wp->w_p_cuc) { row = wp->w_cline_row + wp->w_cline_height; } else { - row = wp->w_height; + row = wp->w_grid.Rows; } break; } @@ -3851,7 +3844,7 @@ win_line ( col += n; } else { // Add a blank character to highlight. - schar_from_ascii(ScreenLines[off], ' '); + schar_from_ascii(grid->ScreenLines[off], ' '); } if (area_attr == 0) { /* Use attributes from match with highest priority among @@ -3882,7 +3875,7 @@ win_line ( if (wp->w_p_cul && lnum == wp->w_cursor.lnum) { eol_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), eol_attr); } - ScreenAttrs[off] = eol_attr; + grid->ScreenAttrs[off] = eol_attr; if (wp->w_p_rl) { --col; --off; @@ -3976,14 +3969,14 @@ win_line ( } } if (*s.p != NUL) { - cells = line_putchar(&s, &ScreenLines[off], wp->w_width - col, + cells = line_putchar(&s, &grid->ScreenLines[off], wp->w_width - col, false); } } delay_virttext = false; if (cells == -1) { - schar_from_ascii(ScreenLines[off], ' '); + schar_from_ascii(grid->ScreenLines[off], ' '); cells = 1; } col += cells * col_stride; @@ -4025,13 +4018,13 @@ win_line ( // terminal buffers may need to highlight beyond the end of the // logical line while (col < wp->w_width) { - schar_from_ascii(ScreenLines[off], ' '); - ScreenAttrs[off++] = term_attrs[vcol++]; + schar_from_ascii(grid->ScreenLines[off], ' '); + grid->ScreenAttrs[off++] = term_attrs[vcol++]; col++; } } - screen_line(screen_row, wp->w_wincol, col, wp->w_width, wp->w_p_rl, wp, - wp->w_hl_attr_normal, false); + grid_move_line(grid, row, 0, col, grid->Columns, wp->w_p_rl, wp, + wp->w_hl_attr_normal, false); row++; /* @@ -4111,22 +4104,22 @@ win_line ( --col; } if (mb_utf8) { - schar_from_cc(ScreenLines[off], mb_c, u8cc); + schar_from_cc(grid->ScreenLines[off], mb_c, u8cc); } else { - schar_from_ascii(ScreenLines[off], c); + schar_from_ascii(grid->ScreenLines[off], c); } if (multi_attr) { - ScreenAttrs[off] = multi_attr; + grid->ScreenAttrs[off] = multi_attr; multi_attr = 0; } else - ScreenAttrs[off] = char_attr; + grid->ScreenAttrs[off] = char_attr; if (has_mbyte && (*mb_char2cells)(mb_c) > 1) { // Need to fill two screen columns. off++; col++; // UTF-8: Put a 0 in the second screen char. - ScreenLines[off][0] = 0; + grid->ScreenLines[off][0] = 0; if (draw_state > WL_NR && filler_todo <= 0) { vcol++; } @@ -4240,25 +4233,24 @@ win_line ( || (wp->w_p_list && lcs_eol != NUL && p_extra != at_end_str) || (n_extra != 0 && (c_extra != NUL || *p_extra != NUL))) ) { - bool wrap = wp->w_p_wrap // Wrapping enabled. - && filler_todo <= 0 // Not drawing diff filler lines. - && lcs_eol_one != -1 // Haven't printed the lcs_eol character. - && row != endrow - 1 // Not the last line being displayed. - && wp->w_width == Columns // Window spans the width of the screen. - && !wp->w_p_rl; // Not right-to-left. - screen_line(screen_row, wp->w_wincol, col - boguscols, - wp->w_width, wp->w_p_rl, wp, wp->w_hl_attr_normal, wrap); + bool wrap = wp->w_p_wrap // Wrapping enabled. + && filler_todo <= 0 // Not drawing diff filler lines. + && lcs_eol_one != -1 // Haven't printed the lcs_eol character. + && row != endrow - 1 // Not the last line being displayed. + && grid->Columns == Columns // Window spans the width of the screen. + && !wp->w_p_rl; // Not right-to-left. + grid_move_line(grid, row, 0, col - boguscols, grid->Columns, wp->w_p_rl, + wp, wp->w_hl_attr_normal, wrap); if (wrap) { // Force a redraw of the first column of the next line. - ScreenAttrs[LineOffset[screen_row + 1]] = -1; + grid->ScreenAttrs[grid->LineOffset[row + 1]] = -1; // Remember that the line wraps, used for modeless copy. - LineWraps[screen_row] = true; + grid->LineWraps[row] = true; } boguscols = 0; ++row; - ++screen_row; /* When not wrapping and finished diff lines, or when displayed * '$' and highlighting until last column, break here. */ @@ -4271,7 +4263,7 @@ win_line ( if (draw_state != WL_LINE && filler_todo <= 0 ) { - win_draw_end(wp, '@', ' ', row, wp->w_height, HLF_AT); + win_draw_end(wp, '@', ' ', row, wp->w_grid.Rows, HLF_AT); row = endrow; } @@ -4282,7 +4274,7 @@ win_line ( } col = 0; - off = (unsigned)(current_ScreenLine - ScreenLines); + off = (unsigned)(grid->Rows * grid->Columns); if (wp->w_p_rl) { col = wp->w_width - 1; /* col is not used if breaking! */ off += col; @@ -4325,32 +4317,32 @@ win_line ( * - the character is multi-byte and the next byte is different * - the character is two cells wide and the second cell differs. */ -static int char_needs_redraw(int off_from, int off_to, int cols) +static int grid_char_needs_redraw(ScreenGrid *grid, int off_from, int off_to, + int cols) { return (cols > 0 - && ((schar_cmp(ScreenLines[off_from], ScreenLines[off_to]) - || ScreenAttrs[off_from] != ScreenAttrs[off_to] + && ((schar_cmp(grid->ScreenLines[off_from], grid->ScreenLines[off_to]) + || grid->ScreenAttrs[off_from] != grid->ScreenAttrs[off_to] || (utf_off2cells(off_from, off_from + cols) > 1 - && schar_cmp(ScreenLines[off_from + 1], - ScreenLines[off_to + 1]))) + && schar_cmp(grid->ScreenLines[off_from + 1], + grid->ScreenLines[off_to + 1]))) || p_wd < 0)); } -/* - * Move one "cooked" screen line to the screen, but only the characters that - * have actually changed. Handle insert/delete character. - * "coloff" gives the first column on the screen for this line. - * "endcol" gives the columns where valid characters are. - * "clear_width" is the width of the window. It's > 0 if the rest of the line - * needs to be cleared, negative otherwise. - * "rlflag" is TRUE in a rightleft window: - * When TRUE and "clear_width" > 0, clear columns 0 to "endcol" - * When FALSE and "clear_width" > 0, clear columns "endcol" to "clear_width" - * If "wrap" is true, then hint to the UI that "row" contains a line - * which has wrapped into the next row. - */ -static void screen_line(int row, int coloff, int endcol, int clear_width, - int rlflag, win_T *wp, int bg_attr, bool wrap) +/// Move one "cooked" line to the window grid, but only the characters that +/// have actually changed. Handle insert/delete character. +/// "coloff" gives the first column on the grid for this line. +/// "endcol" gives the columns where valid characters are. +/// "clear_width" is the width of the window. It's > 0 if the rest of the line +/// needs to be cleared, negative otherwise. +/// "rlflag" is TRUE in a rightleft window: +/// When TRUE and "clear_width" > 0, clear columns 0 to "endcol" +/// When FALSE and "clear_width" > 0, clear columns "endcol" to "clear_width" +/// If "wrap" is true, then hint to the UI that "row" contains a line +/// which has wrapped into the next row. +static void grid_move_line(ScreenGrid *grid, int row, int coloff, int endcol, + int clear_width, int rlflag, win_T *wp, int bg_attr, + bool wrap) { unsigned off_from; unsigned off_to; @@ -4364,46 +4356,50 @@ static void screen_line(int row, int coloff, int endcol, int clear_width, // 2: occupies two display cells int start_dirty = -1, end_dirty = 0; + if (grid == NULL) { + grid = &default_grid; + } + /* Check for illegal row and col, just in case. */ - if (row >= Rows) - row = Rows - 1; - if (endcol > Columns) - endcol = Columns; + if (row >= grid->Rows) + row = grid->Rows - 1; + if (endcol > grid->Columns) + endcol = grid->Columns; - off_from = (unsigned)(current_ScreenLine - ScreenLines); - off_to = LineOffset[row] + coloff; - max_off_from = off_from + screen_Columns; - max_off_to = LineOffset[row] + screen_Columns; + off_from = (unsigned)(grid->Rows * grid->Columns); + off_to = grid->LineOffset[row] + coloff; + max_off_from = off_from + grid->Columns; + max_off_to = grid->LineOffset[row] + grid->Columns; if (rlflag) { /* Clear rest first, because it's left of the text. */ if (clear_width > 0) { - while (col <= endcol && ScreenLines[off_to][0] == ' ' - && ScreenLines[off_to][1] == NUL - && ScreenAttrs[off_to] == bg_attr + while (col <= endcol && grid->ScreenLines[off_to][0] == ' ' + && grid->ScreenLines[off_to][1] == NUL + && grid->ScreenAttrs[off_to] == bg_attr ) { ++off_to; ++col; } if (col <= endcol) { - screen_fill(row, row + 1, col + coloff, endcol + coloff + 1, ' ', ' ', - bg_attr); + grid_fill(grid, row, row + 1, col + coloff, endcol + coloff + 1, + ' ', ' ', bg_attr); } } col = endcol + 1; - off_to = LineOffset[row] + col + coloff; + off_to = grid->LineOffset[row] + col + coloff; off_from += col; endcol = (clear_width > 0 ? clear_width : -clear_width); } if (bg_attr) { for (int c = col; c < endcol; c++) { - ScreenAttrs[off_from+c] = hl_combine_attr(bg_attr, - ScreenAttrs[off_from+c]); + grid->ScreenAttrs[off_from+c] = + hl_combine_attr(bg_attr, grid->ScreenAttrs[off_from+c]); } } - redraw_next = char_needs_redraw(off_from, off_to, endcol - col); + redraw_next = grid_char_needs_redraw(grid, off_from, off_to, endcol - col); while (col < endcol) { char_cells = 1; @@ -4411,9 +4407,9 @@ static void screen_line(int row, int coloff, int endcol, int clear_width, char_cells = utf_off2cells(off_from, max_off_from); } redraw_this = redraw_next; - redraw_next = char_needs_redraw(off_from + char_cells, - off_to + char_cells, - endcol - col - char_cells); + redraw_next = grid_char_needs_redraw(grid, off_from + char_cells, + off_to + char_cells, + endcol - col - char_cells); if (redraw_this) { if (start_dirty == -1) { @@ -4434,16 +4430,16 @@ static void screen_line(int row, int coloff, int endcol, int clear_width, clear_next = true; } - schar_copy(ScreenLines[off_to], ScreenLines[off_from]); + schar_copy(grid->ScreenLines[off_to], grid->ScreenLines[off_from]); if (char_cells == 2) { - schar_copy(ScreenLines[off_to+1], ScreenLines[off_from+1]); + schar_copy(grid->ScreenLines[off_to+1], grid->ScreenLines[off_from+1]); } - ScreenAttrs[off_to] = ScreenAttrs[off_from]; + grid->ScreenAttrs[off_to] = grid->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) { - ScreenAttrs[off_to + 1] = ScreenAttrs[off_from]; + grid->ScreenAttrs[off_to + 1] = grid->ScreenAttrs[off_from]; } } @@ -4455,7 +4451,7 @@ static void screen_line(int row, int coloff, int endcol, int clear_width, if (clear_next) { /* 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], ' '); + schar_from_ascii(grid->ScreenLines[off_to], ' '); end_dirty++; } @@ -4464,11 +4460,11 @@ static void screen_line(int row, int coloff, int endcol, int clear_width, // blank out the rest of the line // 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 (grid->ScreenLines[off_to][0] != ' ' || grid->ScreenLines[off_to][1] != NUL + || grid->ScreenAttrs[off_to] != bg_attr) { + grid->ScreenLines[off_to][0] = ' '; + grid->ScreenLines[off_to][1] = NUL; + grid->ScreenAttrs[off_to] = bg_attr; if (start_dirty == -1) { start_dirty = col; end_dirty = col; @@ -4482,10 +4478,10 @@ static void screen_line(int row, int coloff, int endcol, int clear_width, } } - if (clear_width > 0 || wp->w_width != Columns) { + if (clear_width > 0 || wp->w_width != grid->Columns) { // If we cleared after the end of the line, it did not wrap. // For vsplit, line wrapping is not possible. - LineWraps[row] = false; + grid->LineWraps[row] = false; } if (clear_end < end_dirty) { @@ -4495,7 +4491,7 @@ static void screen_line(int row, int coloff, int endcol, int clear_width, start_dirty = end_dirty; } if (clear_end > start_dirty) { - ui_line(row, coloff+start_dirty, coloff+end_dirty, coloff+clear_end, + ui_line(grid, row, coloff+start_dirty, coloff+end_dirty, coloff+clear_end, bg_attr, wrap); } } @@ -4590,9 +4586,8 @@ static void draw_vsep_win(win_T *wp, int row) if (wp->w_vsep_width) { // draw the vertical separator right of this window c = fillchar_vsep(wp, &hl); - screen_fill(wp->w_winrow + row, wp->w_winrow + wp->w_height, - W_ENDCOL(wp), W_ENDCOL(wp) + 1, - c, ' ', hl); + grid_fill(&default_grid, wp->w_winrow + row, wp->w_winrow + wp->w_height, + W_ENDCOL(wp), W_ENDCOL(wp) + 1, c, ' ', hl); } } @@ -4677,7 +4672,7 @@ win_redr_status_matches ( if (matches == NULL) /* interrupted completion? */ return; - buf = xmalloc(has_mbyte ? Columns * MB_MAXBYTES + 1 : Columns + 1); + buf = xmalloc(has_mbyte ? default_grid.Columns * MB_MAXBYTES + 1 : default_grid.Columns + 1); if (match == -1) { /* don't show match but original text */ match = 0; @@ -4698,13 +4693,13 @@ win_redr_status_matches ( if (first_match > 0) clen += 2; /* jumping right, put match at the left */ - if ((long)clen > Columns) { + if ((long)clen > default_grid.Columns) { first_match = match; /* if showing the last match, we can add some on the left */ clen = 2; for (i = match; i < num_matches; ++i) { clen += status_match_len(xp, L_MATCH(i)) + 2; - if ((long)clen >= Columns) + if ((long)clen >= default_grid.Columns) break; } if (i == num_matches) @@ -4714,7 +4709,7 @@ win_redr_status_matches ( if (add_left) while (first_match > 0) { clen += status_match_len(xp, L_MATCH(first_match - 1)) + 2; - if ((long)clen >= Columns) + if ((long)clen >= default_grid.Columns) break; --first_match; } @@ -4731,7 +4726,7 @@ win_redr_status_matches ( clen = len; i = first_match; - while ((long)(clen + status_match_len(xp, L_MATCH(i)) + 2) < Columns) { + while ((long)(clen + status_match_len(xp, L_MATCH(i)) + 2) < default_grid.Columns) { if (i == match) { selstart = buf + len; selstart_col = clen; @@ -4782,8 +4777,8 @@ win_redr_status_matches ( if (msg_scrolled > 0) { /* 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, 1, (int)Rows, 0, (int)Columns); + if (cmdline_row == default_grid.Rows - 1) { + grid_del_lines(&default_grid, 0, 1, (int)Rows, 0, (int)Columns); msg_scrolled++; } else { cmdline_row++; @@ -4805,13 +4800,14 @@ win_redr_status_matches ( } } - screen_puts(buf, row, 0, attr); + grid_puts(&default_grid, buf, row, 0, attr); if (selstart != NULL && highlight) { *selend = NUL; - screen_puts(selstart, row, selstart_col, HL_ATTR(HLF_WM)); + grid_puts(&default_grid, selstart, row, selstart_col, HL_ATTR(HLF_WM)); } - screen_fill(row, row + 1, clen, (int)Columns, fillchar, fillchar, attr); + grid_fill(&default_grid, row, row + 1, clen, (int)default_grid.Columns, + fillchar, fillchar, attr); } win_redraw_last_status(topframe); @@ -4910,14 +4906,14 @@ static void win_redr_status(win_T *wp, int ignore_pum) } row = wp->w_winrow + wp->w_height; - screen_puts(p, row, wp->w_wincol, attr); - screen_fill(row, row + 1, len + wp->w_wincol, - this_ru_col + wp->w_wincol, fillchar, fillchar, attr); + grid_puts(&default_grid, p, row, wp->w_wincol, attr); + grid_fill(&default_grid, row, row + 1, len + wp->w_wincol, + this_ru_col + wp->w_wincol, fillchar, fillchar, attr); if (get_keymap_str(wp, (char_u *)"<%s>", NameBuff, MAXPATHL) && this_ru_col - len > (int)(STRLEN(NameBuff) + 1)) - screen_puts(NameBuff, row, (int)(this_ru_col - STRLEN(NameBuff) - - 1 + wp->w_wincol), attr); + grid_puts(&default_grid, NameBuff, row, + (int)(this_ru_col - STRLEN(NameBuff) - 1), attr); win_redr_ruler(wp, TRUE); } @@ -4931,8 +4927,8 @@ static void win_redr_status(win_T *wp, int ignore_pum) } else { fillchar = fillchar_vsep(wp, &attr); } - screen_putchar(fillchar, wp->w_winrow + wp->w_height, - W_ENDCOL(wp), attr); + grid_putchar(&default_grid, fillchar, wp->w_winrow + wp->w_height, + W_ENDCOL(wp), attr); } busy = FALSE; } @@ -5076,7 +5072,7 @@ win_redr_custom ( row = 0; fillchar = ' '; attr = HL_ATTR(HLF_TPF); - maxwidth = Columns; + maxwidth = default_grid.Columns; use_sandbox = was_set_insecurely((char_u *)"tabline", 0); } else { row = wp->w_winrow + wp->w_height; @@ -5095,12 +5091,12 @@ win_redr_custom ( if (*stl++ != '(') stl = p_ruf; } - col = ru_col - (Columns - wp->w_width); + col = ru_col - (default_grid.Columns - wp->w_width); if (col < (wp->w_width + 1) / 2) col = (wp->w_width + 1) / 2; maxwidth = wp->w_width - col; if (!wp->w_status_height) { - row = Rows - 1; + row = default_grid.Rows - 1; --maxwidth; /* writing in last column may cause scrolling */ fillchar = ' '; attr = 0; @@ -5116,7 +5112,7 @@ win_redr_custom ( *wp->w_p_stl == NUL ? 0 : OPT_LOCAL); } - col += wp->w_wincol; + col += wp->w_winrow; } if (maxwidth <= 0) @@ -5159,7 +5155,7 @@ win_redr_custom ( p = buf; for (n = 0; hltab[n].start != NULL; n++) { int len = (int)(hltab[n].start - p); - screen_puts_len(p, len, row, col, curattr); + grid_puts_len(&default_grid, p, len, row, col, curattr); col += vim_strnsize(p, len); p = hltab[n].start; @@ -5173,9 +5169,9 @@ win_redr_custom ( curattr = highlight_user[hltab[n].userhl - 1]; } // 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); + grid_puts(&default_grid, p >= buf + len ? (char_u *)"" : p, row, col, curattr); - screen_puts_line_flush(false); + grid_puts_line_flush(&default_grid, false); if (wp == NULL) { // Fill the tab_page_click_defs array for clicking in the tab pages line. @@ -5193,7 +5189,7 @@ win_redr_custom ( p = (char_u *) tabtab[n].start; cur_click_def = tabtab[n].def; } - while (col < Columns) { + while (col < default_grid.Columns) { tab_page_click_defs[col++] = cur_click_def; } } @@ -5247,42 +5243,42 @@ static void schar_copy(char_u *sc1, char_u *sc2) } -/* - * Output a single character directly to the screen and update ScreenLines. - */ -void screen_putchar(int c, int row, int col, int attr) +/// output a single character directly to the grid and update ScreenLines. +void grid_putchar(ScreenGrid *grid, int c, int row, int col, int attr) { char_u buf[MB_MAXBYTES + 1]; buf[utf_char2bytes(c, buf)] = NUL; - screen_puts(buf, row, col, attr); + grid_puts(grid, buf, row, col, attr); } -/* - * Get a single character directly from ScreenLines into "bytes[]". - * Also return its attribute in *attrp; - */ -void screen_getbytes(int row, int col, char_u *bytes, int *attrp) +/// get a single character directly from grid.ScreenLines into "bytes[]". +/// Also return its attribute in *attrp; +void grid_getbytes(ScreenGrid *grid, int row, int col, char_u *bytes, + int *attrp) { unsigned off; - /* safety check */ - if (ScreenLines != NULL && row < screen_Rows && col < screen_Columns) { - off = LineOffset[row] + col; - *attrp = ScreenAttrs[off]; - schar_copy(bytes, ScreenLines[off]); + if (grid == NULL) { + grid = &default_grid; + } + + // safety check + if (grid->ScreenLines != NULL && row < grid->Rows && col < grid->Columns) { + off = grid->LineOffset[row] + col; + *attrp = grid->ScreenAttrs[off]; + schar_copy(bytes, grid->ScreenLines[off]); } } -/* - * Put string '*text' on the screen at position 'row' and 'col', with - * attributes 'attr', and update ScreenLines[] and ScreenAttrs[]. - * Note: only outputs within one row, message is truncated at screen boundary! - * Note: if ScreenLines[], row and/or col is invalid, nothing is done. - */ -void screen_puts(char_u *text, int row, int col, int attr) + +/// put string '*text' on the window grid at position 'row' and 'col', with +/// attributes 'attr', and update ScreenLines[] and ScreenAttrs[]. +/// Note: only outputs within one row, message is truncated at grid boundary! +/// Note: if ScreenLines[], row and/or col is invalid, nothing is done. +void grid_puts(ScreenGrid *grid, char_u *text, int row, int col, int attr) { - screen_puts_len(text, -1, row, col, attr); + grid_puts_len(grid, text, -1, row, col, attr); } static int put_dirty_row = -1; @@ -5299,11 +5295,10 @@ void screen_puts_line_start(int row) put_dirty_row = row; } -/* - * Like screen_puts(), but output "text[len]". When "len" is -1 output up to - * a NUL. - */ -void screen_puts_len(char_u *text, int textlen, int row, int col, int attr) +/// like grid_puts(), but output "text[len]". When "len" is -1 output up to +/// a NUL. +void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, + int col, int attr) { unsigned off; char_u *ptr = text; @@ -5321,8 +5316,17 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr) int force_redraw_this; int force_redraw_next = FALSE; int need_redraw; - bool do_flush = false; + + if (grid == NULL) { + grid = &default_grid; + } + + // safety check + if (grid->ScreenLines == NULL || row >= grid->Rows || col >= grid->Columns) { + return; + } + if (put_dirty_row == -1) { screen_puts_line_start(row); do_flush = true; @@ -5331,16 +5335,13 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr) abort(); } } - - if (ScreenLines == NULL || row >= screen_Rows) /* safety check */ - return; - off = LineOffset[row] + col; + off = grid->LineOffset[row] + col; /* When drawing over the right halve of a double-wide char clear out the * left halve. Only needed in a terminal. */ - if (col > 0 && col < screen_Columns && mb_fix_col(col, row) != col) { - schar_from_ascii(ScreenLines[off - 1], ' '); - ScreenAttrs[off - 1] = 0; + if (col > 0 && col < grid->Columns && mb_fix_col(col, row) != col) { + schar_from_ascii(grid->ScreenLines[off - 1], ' '); + grid->ScreenAttrs[off - 1] = 0; // redraw the previous cell, make it empty if (put_dirty_first == -1) { put_dirty_first = col-1; @@ -5350,8 +5351,8 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr) force_redraw_next = true; } - max_off = LineOffset[row] + screen_Columns; - while (col < screen_Columns + max_off = grid->LineOffset[row] + grid->Columns; + while (col < grid->Columns && (len < 0 || (int)(ptr - text) < len) && *ptr != NUL) { c = *ptr; @@ -5384,7 +5385,7 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr) } else { prev_c = u8c; } - if (col + mbyte_cells > screen_Columns) { + if (col + mbyte_cells > grid->Columns) { // Only 1 cell left, but character requires 2 cells: // display a '>' in the last column to avoid wrapping. */ c = '>'; @@ -5398,9 +5399,9 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr) force_redraw_this = force_redraw_next; force_redraw_next = FALSE; - need_redraw = schar_cmp(ScreenLines[off], buf) - || (mbyte_cells == 2 && ScreenLines[off + 1][0] != 0) - || ScreenAttrs[off] != attr + need_redraw = schar_cmp(grid->ScreenLines[off], buf) + || (mbyte_cells == 2 && grid->ScreenLines[off + 1][0] != 0) + || grid->ScreenAttrs[off] != attr || exmode_active; if (need_redraw || force_redraw_this) { @@ -5420,11 +5421,11 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr) clear_next_cell = true; } - schar_copy(ScreenLines[off], buf); - ScreenAttrs[off] = attr; + schar_copy(grid->ScreenLines[off], buf); + grid->ScreenAttrs[off] = attr; if (mbyte_cells == 2) { - ScreenLines[off + 1][0] = 0; - ScreenAttrs[off + 1] = attr; + grid->ScreenLines[off + 1][0] = 0; + grid->ScreenAttrs[off + 1] = attr; } if (put_dirty_first == -1) { put_dirty_first = col; @@ -5443,25 +5444,26 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr) } if (do_flush) { - screen_puts_line_flush(true); + grid_puts_line_flush(grid, true); } } /// End a group of screen_puts_len calls and send the screen buffer to the UI /// layer. /// +/// @param grid The grid which contains the buffer. /// @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) +void grid_puts_line_flush(ScreenGrid *grid, 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_grid_cursor_goto(grid, put_dirty_row, put_dirty_last); } - ui_line(put_dirty_row, put_dirty_first, put_dirty_last, put_dirty_last, 0, - false); + ui_line(grid, put_dirty_row, put_dirty_first, put_dirty_last, + put_dirty_last, 0, false); put_dirty_first = -1; put_dirty_last = 0; } @@ -5764,20 +5766,23 @@ next_search_hl_pos( } -/* - * Fill the screen from 'start_row' to 'end_row', from 'start_col' to 'end_col' - * with character 'c1' in first column followed by 'c2' in the other columns. - * Use attributes 'attr'. - */ -void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1, int c2, int attr) +/// Fill the grid from 'start_row' to 'end_row', from 'start_col' to 'end_col' +/// with character 'c1' in first column followed by 'c2' in the other columns. +/// Use attributes 'attr'. +void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, + int end_col, int c1, int c2, int attr) { schar_T sc; - if (end_row > screen_Rows) /* safety check */ - end_row = screen_Rows; - if (end_col > screen_Columns) /* safety check */ - end_col = screen_Columns; - if (ScreenLines == NULL + if (grid == NULL) { + grid = &default_grid; + } + + if (end_row > grid->Rows) // safety check + end_row = grid->Rows; + if (end_col > grid->Columns) // safety check + end_col = grid->Columns; + if (grid->ScreenLines == NULL || start_row >= end_row || start_col >= end_col) /* nothing to do */ return; @@ -5789,10 +5794,10 @@ void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1, // double wide-char clear out the right halve. Only needed in a // terminal. if (start_col > 0 && mb_fix_col(start_col, row) != start_col) { - screen_puts_len((char_u *)" ", 1, row, start_col - 1, 0); + grid_puts_len(grid, (char_u *)" ", 1, row, start_col - 1, 0); } - if (end_col < screen_Columns && mb_fix_col(end_col, row) != end_col) { - screen_puts_len((char_u *)" ", 1, row, end_col, 0); + if (end_col < grid->Columns && mb_fix_col(end_col, row) != end_col) { + grid_puts_len(grid, (char_u *)" ", 1, row, end_col, 0); } } @@ -5800,12 +5805,13 @@ void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1, int dirty_last = 0; int col = start_col; schar_from_char(sc, c1); - int lineoff = LineOffset[row]; + int lineoff = grid->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 (schar_cmp(grid->ScreenLines[off], sc) + || grid->ScreenAttrs[off] != attr) { + schar_copy(grid->ScreenLines[off], sc); + grid->ScreenAttrs[off] = attr; if (dirty_first == INT_MAX) { dirty_first = col; } @@ -5824,16 +5830,16 @@ void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1, 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, false); + ui_line(grid, row, dirty_first, last, dirty_last, attr, false); } } if (end_col == Columns) { - LineWraps[row] = false; + grid->LineWraps[row] = false; } // TODO(bfredl): The relevant caller should do this - if (row == Rows - 1) { // overwritten the command line + if (row == default_grid.Rows - 1) { // overwritten the command line redraw_cmdline = true; if (start_col == 0 && end_col == Columns && c1 == ' ' && c2 == ' ' && attr == 0) { @@ -5872,7 +5878,34 @@ void check_for_delay(int check_msg_scroll) int screen_valid(int doclear) { screenalloc(doclear); /* allocate screen buffers if size changed */ - return ScreenLines != NULL; + return default_grid.ScreenLines != NULL; +} + +/// (re)allocate a window grid if size changed +/// If "doclear" is true, clear the screen if resized. +// TODO(utkarshme): Think of a better name, place +void win_grid_alloc(win_T *wp, int doclear) +{ + if (wp->w_grid.ScreenLines == NULL + || wp->w_grid.Rows != wp->w_height + || wp->w_grid.Columns != wp->w_width) { + grid_alloc(&wp->w_grid, wp->w_height, wp->w_width, doclear); + + // only assign a grid handle if not already + if (wp->w_grid.handle == 0) { + wp->w_grid.handle = ++last_handle; + } + + wp->w_grid.OffsetRow = wp->w_winrow; + wp->w_grid.OffsetColumn = wp->w_wincol; + + wp->w_grid.was_resized = true; + } + + if (send_grid_resize || wp->w_grid.was_resized) { + ui_call_grid_resize(wp->w_grid.handle, wp->w_grid.Columns, wp->w_grid.Rows); + wp->w_grid.was_resized = false; + } } /* @@ -5895,12 +5928,12 @@ retry: // when Rows and Columns have been set and we have started doing full // screen stuff. if ((default_grid.ScreenLines != NULL - && Rows == screen_Rows - && Columns == screen_Columns + && Rows == default_grid.Rows + && Columns == default_grid.Columns ) || Rows == 0 || Columns == 0 - || (!full_screen && ScreenLines == NULL)) { + || (!full_screen && default_grid.ScreenLines == NULL)) { return; } @@ -5940,7 +5973,7 @@ retry: if (aucmd_win != NULL) win_free_lsize(aucmd_win); - alloc_grid(&default_grid, Rows, Columns, !doclear); + grid_alloc(&default_grid, Rows, Columns, !doclear); StlClickDefinition *new_tab_page_click_defs = xcalloc( (size_t)Columns, sizeof(*new_tab_page_click_defs)); @@ -5957,12 +5990,16 @@ retry: set_screengrid(&default_grid); tab_page_click_defs = new_tab_page_click_defs; - tab_page_click_defs_size = Columns; + tab_page_click_defs_size = default_grid.Columns; /* It's important that screen_Rows and screen_Columns reflect the actual * size of ScreenLines[]. Set them before calling anything. */ - screen_Rows = Rows; - screen_Columns = Columns; + screen_Rows = default_grid.Rows; + screen_Columns = default_grid.Columns; + + default_grid.OffsetRow = 0; + default_grid.OffsetColumn = 0; + default_grid.handle = 1; must_redraw = CLEAR; /* need to clear the screen later */ if (doclear) @@ -5984,35 +6021,35 @@ retry: } } -void alloc_grid(ScreenGrid *grid, int Rows, int Columns, bool copy) +void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy) { int new_row, old_row; - ScreenGrid new = { 0 }; + ScreenGrid new = *grid; - size_t ncells = (size_t)((Rows+1) * Columns); + size_t ncells = (size_t)((rows+1) * columns); new.ScreenLines = xmalloc(ncells * sizeof(schar_T)); new.ScreenAttrs = xmalloc(ncells * sizeof(sattr_T)); - new.LineOffset = xmalloc((size_t)(Rows * sizeof(unsigned))); - new.LineWraps = xmalloc((size_t)(Rows * sizeof(char_u))); + new.LineOffset = xmalloc((size_t)(rows * sizeof(unsigned))); + new.LineWraps = xmalloc((size_t)(rows * sizeof(char_u))); - new.Rows = Rows; - new.Columns = Columns; + new.Rows = rows; + new.Columns = columns; - for (new_row = 0; new_row < Rows; new_row++) { - new.LineOffset[new_row] = new_row * Columns; + for (new_row = 0; new_row < new.Rows; new_row++) { + new.LineOffset[new_row] = new_row * new.Columns; new.LineWraps[new_row] = false; if (copy) { // If the screen is not going to be cleared, copy as much as // possible from the old screen to the new one and clear the rest // (used when resizing the window at the "--more--" prompt or when // executing an external command, for the GUI). - memset(new.ScreenLines + new_row * Columns, - ' ', (size_t)Columns * sizeof(schar_T)); - memset(new.ScreenAttrs + new_row * Columns, - 0, (size_t)Columns * sizeof(sattr_T)); - old_row = new_row + (grid->Rows - Rows); + memset(new.ScreenLines + new_row * new.Columns, + ' ', (size_t)new.Columns * sizeof(schar_T)); + memset(new.ScreenAttrs + new_row * new.Columns, + 0, (size_t)new.Columns * sizeof(sattr_T)); + old_row = new_row + (grid->Rows - new.Rows); if (old_row >= 0 && grid->ScreenLines != NULL) { - int len = MIN(grid->Columns, Columns); + int len = MIN(grid->Columns, new.Columns); memmove(new.ScreenLines + new.LineOffset[new_row], grid->ScreenLines + grid->LineOffset[old_row], (size_t)len * sizeof(schar_T)); @@ -6041,9 +6078,6 @@ void set_screengrid(ScreenGrid *grid) ScreenAttrs = grid->ScreenAttrs; LineOffset = grid->LineOffset; LineWraps = grid->LineWraps; - grid_Rows = grid->Rows; - grid_Columns = grid->Columns; - current_ScreenLine = ScreenLines + grid_Rows * grid_Columns; } /// Clear tab_page_click_defs table @@ -6078,10 +6112,10 @@ static void screenclear2(void) return; } - // blank out ScreenLines - for (i = 0; i < Rows; i++) { - lineclear(LineOffset[i], (int)Columns, true); - LineWraps[i] = false; + /* blank out ScreenLines */ + for (i = 0; i < default_grid.Rows; ++i) { + grid_clear_line(&default_grid, LineOffset[i], (int)default_grid.Columns, true); + LineWraps[i] = FALSE; } ui_call_grid_clear(1); // clear the display @@ -6102,27 +6136,26 @@ static void screenclear2(void) msg_didout = false; } -/* - * Clear one line in ScreenLines. - */ -static void lineclear(unsigned off, int width, bool valid) +/// clear a line in the grid starting at "off" until "width" characters +/// are cleared. +static void grid_clear_line(ScreenGrid *grid, unsigned off, int width, bool valid) { for (int col = 0; col < width; col++) { - schar_from_ascii(ScreenLines[off + col], ' '); + schar_from_ascii(grid->ScreenLines[off + col], ' '); } int fill = valid ? 0 : -1; - (void)memset(ScreenAttrs + off, fill, (size_t)width * sizeof(sattr_T)); + (void)memset(grid->ScreenAttrs + off, fill, (size_t)width * sizeof(sattr_T)); } /// Copy part of a Screenline for vertically split window. -static void linecopy(int to, int from, int col, int width) +static void linecopy(ScreenGrid *grid, int to, int from, int col, int width) { - unsigned off_to = LineOffset[to] + col; - unsigned off_from = LineOffset[from] + col; + unsigned off_to = grid->LineOffset[to] + col; + unsigned off_from = grid->LineOffset[from] + col; - memmove(ScreenLines + off_to, ScreenLines + off_from, + memmove(grid->ScreenLines + off_to, grid->ScreenLines + off_from, width * sizeof(schar_T)); - memmove(ScreenAttrs + off_to, ScreenAttrs + off_from, + memmove(grid->ScreenAttrs + off_to, grid->ScreenAttrs + off_from, width * sizeof(sattr_T)); } @@ -6141,8 +6174,7 @@ void setcursor(void) - ((utf_ptr2cells(get_cursor_pos_ptr()) == 2 && vim_isprintc(gchar_cursor())) ? 2 : 1); } - ui_cursor_goto(curwin->w_winrow + curwin->w_wrow, - curwin->w_wincol + left_offset); + ui_grid_cursor_goto(&curwin->w_grid, curwin->w_wrow, left_offset); } } @@ -6178,15 +6210,12 @@ static int win_do_lines(win_T *wp, int row, int line_count, int del) check_for_delay(false); clear_cmdline = true; int retval; - if (del) { - retval = screen_del_lines(wp->w_winrow + row, line_count, - wp->w_winrow + wp->w_height, - wp->w_wincol, wp->w_width); + retval = grid_del_lines(&wp->w_grid, row, line_count, + wp->w_height, 0, wp->w_width); } else { - retval = screen_ins_lines(wp->w_winrow + row, line_count, - wp->w_winrow + wp->w_height, - wp->w_wincol, wp->w_width); + retval = grid_ins_lines(&wp->w_grid, row, line_count, + wp->w_height, 0, wp->w_width); } return retval; } @@ -6208,12 +6237,17 @@ static int win_do_lines(win_T *wp, int row, int line_count, int del) /// '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 grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, + int col, int width) { int i; int j; unsigned temp; + if (grid == NULL) { + grid = &default_grid; + } + if (!screen_valid(TRUE) || line_count <= 0) { return FAIL; } @@ -6221,29 +6255,29 @@ int screen_ins_lines(int row, int line_count, int end, int col, int width) // Shift LineOffset[] line_count down to reflect the inserted lines. // Clear the inserted lines in ScreenLines[]. for (i = 0; i < line_count; i++) { - if (width != Columns) { + if (width != grid->Columns) { // need to copy part of a line j = end - 1 - i; while ((j -= line_count) >= row) { - linecopy(j + line_count, j, col, width); + linecopy(grid, j + line_count, j, col, width); } j += line_count; - lineclear(LineOffset[j] + col, width, false); - LineWraps[j] = false; + grid_clear_line(grid, grid->LineOffset[j] + col, width, false); + grid->LineWraps[j] = false; } else { j = end - 1 - i; - temp = LineOffset[j]; + temp = grid->LineOffset[j]; while ((j -= line_count) >= row) { - LineOffset[j + line_count] = LineOffset[j]; - LineWraps[j + line_count] = LineWraps[j]; + grid->LineOffset[j + line_count] = grid->LineOffset[j]; + grid->LineWraps[j + line_count] = grid->LineWraps[j]; } - LineOffset[j + line_count] = temp; - LineWraps[j + line_count] = false; - lineclear(temp, (int)Columns, false); + grid->LineOffset[j + line_count] = temp; + grid->LineWraps[j + line_count] = false; + grid_clear_line(grid, temp, (int)grid->Columns, false); } } - ui_call_grid_scroll(1, row, end, col, col+width, -line_count, 0); + ui_call_grid_scroll(grid->handle, row, end, col, col+width, -line_count, 0); return OK; } @@ -6254,12 +6288,17 @@ int screen_ins_lines(int row, int line_count, int end, int col, int width) /// '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 grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, + int col, int width) { int j; int i; unsigned temp; + if (grid == NULL) { + grid = &default_grid; + } + if (!screen_valid(TRUE) || line_count <= 0) { return FAIL; } @@ -6267,30 +6306,30 @@ int screen_del_lines(int row, int line_count, int end, int col, int width) // Now shift LineOffset[] line_count up to reflect the deleted lines. // Clear the inserted lines in ScreenLines[]. for (i = 0; i < line_count; i++) { - if (width != Columns) { + if (width != grid->Columns) { // need to copy part of a line j = row + i; while ((j += line_count) <= end - 1) { - linecopy(j - line_count, j, col, width); + linecopy(grid, j - line_count, j, col, width); } j -= line_count; - lineclear(LineOffset[j] + col, width, false); - LineWraps[j] = false; + grid_clear_line(grid, grid->LineOffset[j] + col, width, false); + grid->LineWraps[j] = false; } else { // whole width, moving the line pointers is faster j = row + i; - temp = LineOffset[j]; + temp = grid->LineOffset[j]; while ((j += line_count) <= end - 1) { - LineOffset[j - line_count] = LineOffset[j]; - LineWraps[j - line_count] = LineWraps[j]; + grid->LineOffset[j - line_count] = grid->LineOffset[j]; + grid->LineWraps[j - line_count] = grid->LineWraps[j]; } - LineOffset[j - line_count] = temp; - LineWraps[j - line_count] = false; - lineclear(temp, (int)Columns, false); + grid->LineOffset[j - line_count] = temp; + grid->LineWraps[j - line_count] = false; + grid_clear_line(grid, temp, (int)grid->Columns, false); } } - ui_call_grid_scroll(1, row, end, col, col+width, line_count, 0); + ui_call_grid_scroll(grid->handle, row, end, col, col+width, line_count, 0); return OK; } @@ -6337,7 +6376,7 @@ int showmode(void) /* if the cmdline is more than one line high, erase top lines */ need_clear = clear_cmdline; - if (clear_cmdline && cmdline_row < Rows - 1) + if (clear_cmdline && cmdline_row < default_grid.Rows - 1) msg_clr_cmdline(); /* will reset clear_cmdline */ /* Position on the last line in the window, column 0 */ @@ -6356,7 +6395,7 @@ int showmode(void) if (edit_submode != NULL && !shortmess(SHM_COMPLETIONMENU)) { /* These messages can get long, avoid a wrap in a narrow * window. Prefer showing edit_submode_extra. */ - length = (Rows - msg_row) * Columns - 3; + length = (default_grid.Rows - msg_row) * default_grid.Columns - 3; if (edit_submode_extra != NULL) length -= vim_strsize(edit_submode_extra); if (length > 0) { @@ -6479,7 +6518,7 @@ int showmode(void) static void msg_pos_mode(void) { msg_col = 0; - msg_row = Rows - 1; + msg_row = default_grid.Rows - 1; } /// Delete mode message. Used when ESC is typed which is expected to end @@ -6538,7 +6577,7 @@ static void draw_tabline(void) int use_sep_chars = (t_colors < 8 ); - if (ScreenLines == NULL) { + if (default_grid.ScreenLines == NULL) { return; } redraw_tabline = false; @@ -6553,7 +6592,7 @@ static void draw_tabline(void) // Init TabPageIdxs[] to zero: Clicking outside of tabs has no effect. - assert(Columns == tab_page_click_defs_size); + assert(default_grid.Columns == tab_page_click_defs_size); clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size); /* Use the 'tabline' option if it's set. */ @@ -6575,7 +6614,7 @@ static void draw_tabline(void) } if (tabcount > 0) { - tabwidth = (Columns - 1 + tabcount / 2) / tabcount; + tabwidth = (default_grid.Columns - 1 + tabcount / 2) / tabcount; } if (tabwidth < 6) { @@ -6586,7 +6625,7 @@ static void draw_tabline(void) tabcount = 0; FOR_ALL_TABS(tp) { - if (col >= Columns - 4) { + if (col >= default_grid.Columns - 4) { break; } @@ -6605,14 +6644,14 @@ static void draw_tabline(void) attr = win_hl_attr(cwp, HLF_TPS); } if (use_sep_chars && col > 0) { - screen_putchar('|', 0, col++, attr); + grid_putchar(&default_grid, '|', 0, col++, attr); } if (tp->tp_topframe != topframe) { attr = win_hl_attr(cwp, HLF_TP); } - screen_putchar(' ', 0, col++, attr); + grid_putchar(&default_grid, ' ', 0, col++, attr); modified = false; @@ -6627,15 +6666,17 @@ static void draw_tabline(void) if (wincount > 1) { vim_snprintf((char *)NameBuff, MAXPATHL, "%d", wincount); len = (int)STRLEN(NameBuff); - if (col + len >= Columns - 3) + if (col + len >= default_grid.Columns - 3) { break; - screen_puts_len(NameBuff, len, 0, col, + } + grid_puts_len(&default_grid, NameBuff, len, 0, col, hl_combine_attr(attr, win_hl_attr(cwp, HLF_T))); col += len; } - if (modified) - screen_puts_len((char_u *)"+", 1, 0, col++, attr); - screen_putchar(' ', 0, col++, attr); + if (modified) { + grid_puts_len(&default_grid, (char_u *)"+", 1, 0, col++, attr); + } + grid_putchar(&default_grid, ' ', 0, col++, attr); } room = scol - col + tabwidth - 1; @@ -6654,13 +6695,13 @@ static void draw_tabline(void) p += len - room; len = room; } - if (len > Columns - col - 1) - len = Columns - col - 1; + if (len > default_grid.Columns - col - 1) + len = default_grid.Columns - col - 1; - screen_puts_len(p, (int)STRLEN(p), 0, col, attr); + grid_puts_len(&default_grid, p, (int)STRLEN(p), 0, col, attr); col += len; } - screen_putchar(' ', 0, col++, attr); + grid_putchar(&default_grid, ' ', 0, col++, attr); // Store the tab page number in tab_page_click_defs[], so that // jump_to_mouse() knows where each one is. @@ -6678,12 +6719,12 @@ static void draw_tabline(void) c = '_'; else c = ' '; - screen_fill(0, 1, col, (int)Columns, c, c, attr_fill); + grid_fill(&default_grid, 0, 1, col, (int)default_grid.Columns, c, c, attr_fill); /* Put an "X" for closing the current tab if there are several. */ if (first_tabpage->tp_next != NULL) { - screen_putchar('X', 0, (int)Columns - 1, attr_nosel); - tab_page_click_defs[Columns - 1] = (StlClickDefinition) { + grid_putchar(&default_grid, 'X', 0, (int)default_grid.Columns - 1, attr_nosel); + tab_page_click_defs[default_grid.Columns - 1] = (StlClickDefinition) { .type = kStlClickTabClose, .tabnr = 999, .func = NULL, @@ -6879,10 +6920,10 @@ static void win_redr_ruler(win_T *wp, int always) off = wp->w_wincol; width = wp->w_width; } else { - row = Rows - 1; + row = default_grid.Rows - 1; fillchar = ' '; attr = 0; - width = Columns; + width = default_grid.Columns; off = 0; } @@ -6919,7 +6960,7 @@ static void win_redr_ruler(win_T *wp, int always) int o = i + vim_strsize(buffer + i + 1); if (wp->w_status_height == 0) /* can't use last char of screen */ ++o; - int this_ru_col = ru_col - (Columns - width); + int this_ru_col = ru_col - (default_grid.Columns - width); if (this_ru_col < 0) this_ru_col = 0; /* Never use more than half the window/screen width, leave the other @@ -6944,9 +6985,9 @@ static void win_redr_ruler(win_T *wp, int always) } } - screen_puts(buffer, row, this_ru_col + off, attr); + grid_puts(&default_grid, buffer, row, this_ru_col + off, attr); i = redraw_cmdline; - screen_fill(row, row + 1, + grid_fill(&default_grid, row, row + 1, this_ru_col + off + (int)STRLEN(buffer), off + width, fillchar, fillchar, attr); @@ -7032,6 +7073,8 @@ void screen_resize(int width, int height) width = Columns; ui_resize(width, height); + send_grid_resize = true; + /* The window layout used to be adjusted here, but it now happens in * screenalloc() (also invoked from screenclear()). That is because the * "busy" check above may skip this, but not screenalloc(). */ diff --git a/src/nvim/types.h b/src/nvim/types.h index 84634b1cb7..aa83bc04bf 100644 --- a/src/nvim/types.h +++ b/src/nvim/types.h @@ -23,14 +23,24 @@ typedef char_u schar_T[(MAX_MCO+1) * 4 + 1]; typedef int16_t sattr_T; // TODO(bfredl): find me a good home +typedef int GridHandle; typedef struct { + GridHandle handle; + schar_T *ScreenLines; sattr_T *ScreenAttrs; unsigned *LineOffset; char_u *LineWraps; + // the size of the allocated grid int Rows; int Columns; + + // offsets for the grid relative to the screen + int OffsetRow; + int OffsetColumn; + + int was_resized; } ScreenGrid; #endif // NVIM_TYPES_H diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 0c69e94e5d..a454afad24 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -57,6 +57,7 @@ static int busy = 0; static int mode_idx = SHAPE_IDX_N; static bool pending_mode_info_update = false; static bool pending_mode_update = false; +static GridHandle cursor_grid_handle = 1; #if MIN_LOG_LEVEL > DEBUG_LOG_LEVEL # define UI_LOG(funname, ...) @@ -315,12 +316,18 @@ void ui_set_ext_option(UI *ui, UIExtension ext, bool active) } } -void ui_line(int row, int startcol, int endcol, int clearcol, int clearattr, - bool wrap) +void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol, + int clearattr, bool wrap) { - size_t off = LineOffset[row]+(size_t)startcol; - UI_CALL(raw_line, 1, row, startcol, endcol, clearcol, clearattr, wrap, - (const schar_T *)ScreenLines+off, (const sattr_T *)ScreenAttrs+off); + size_t off = grid->LineOffset[row] + (size_t)startcol; + int row_off = ui_is_external(kUIMultigrid) ? 0 : grid->OffsetRow; + int col_off = ui_is_external(kUIMultigrid) ? 0 : grid->OffsetColumn; + + UI_CALL(raw_line, grid->handle, row_off + row, col_off + startcol, + col_off + endcol, col_off + clearcol, clearattr, wrap, + (const schar_T *)grid->ScreenLines + off, + (const sattr_T *)grid->ScreenAttrs + off); + if (p_wd) { // 'writedelay': flush & delay each time. int old_row = row, old_col = col; // If'writedelay is active, we set the cursor to highlight what was drawn @@ -334,11 +341,20 @@ void ui_line(int row, int startcol, int endcol, int clearcol, int clearattr, void ui_cursor_goto(int new_row, int new_col) { - if (new_row == row && new_col == col) { + ui_grid_cursor_goto(&default_grid, new_row, new_col); +} + +void ui_grid_cursor_goto(ScreenGrid *grid, int new_row, int new_col) +{ + int off_row = (ui_is_external(kUIMultigrid) ? 0 : grid->OffsetRow); + int off_col = (ui_is_external(kUIMultigrid) ? 0 : grid->OffsetColumn); + + if (new_row + off_row == row && new_col + off_col == col) { return; } - row = new_row; - col = new_col; + row = new_row + off_row; + col = new_col + off_col; + cursor_grid_handle = grid->handle; pending_cursor_update = true; } @@ -361,7 +377,7 @@ void ui_flush(void) { cmdline_ui_flush(); if (pending_cursor_update) { - ui_call_grid_cursor_goto(1, row, col); + ui_call_grid_cursor_goto(cursor_grid_handle, row, col); pending_cursor_update = false; } if (pending_mode_info_update) { diff --git a/src/nvim/ui.h b/src/nvim/ui.h index d89ad60ce7..16237214cb 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -16,6 +16,7 @@ typedef enum { kUIWildmenu, #define kUIGlobalCount (kUIWildmenu+1) kUILinegrid, + kUIMultigrid, kUIHlState, kUIExtCount, } UIExtension; @@ -26,6 +27,7 @@ EXTERN const char *ui_ext_names[] INIT(= { "ext_tabline", "ext_wildmenu", "ext_linegrid", + "ext_multigrid", "ext_hlstate", }); diff --git a/src/nvim/version.c b/src/nvim/version.c index 11dc813997..9b9053d7a9 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -2271,8 +2271,8 @@ static void do_intro_line(long row, char_u *mesg, int attr) } } assert(row <= INT_MAX && col <= INT_MAX); - screen_puts_len(p, l, (int)row, (int)col, - *p == '<' ? HL_ATTR(HLF_8) : attr); + grid_puts_len(&default_grid, p, l, (int)row, (int)col, + *p == '<' ? HL_ATTR(HLF_8) : attr); col += clen; } } diff --git a/src/nvim/window.c b/src/nvim/window.c index 8be79f0cff..4d2b238b7a 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -3958,6 +3958,8 @@ win_free ( xfree(wp->w_p_cc_cols); + win_free_grid(wp, false); + if (wp != aucmd_win) win_remove(wp, tp); if (autocmd_busy) { @@ -3970,6 +3972,20 @@ win_free ( unblock_autocmds(); } +void win_free_grid(win_T *wp, bool reinit) +{ + if (wp->w_grid.handle != 0 && ui_is_external(kUIMultigrid)) { + ui_call_grid_destroy(wp->w_grid.handle); + wp->w_grid.handle = 0; + } + free_screengrid(&wp->w_grid); + if (reinit) { + // if a float is turned into a split and back into a float, the grid + // data structure will be reused + memset(&wp->w_grid, 0, sizeof(wp->w_grid)); + } +} + /* * Append window "wp" in the window list after window "after". */ @@ -4247,6 +4263,7 @@ void win_setheight_win(int height, win_T *win) } frame_setheight(win->w_frame, height + win->w_status_height); + win_grid_alloc(win, false); /* recompute the window positions */ row = win_comp_pos(); @@ -4256,7 +4273,7 @@ void win_setheight_win(int height, win_T *win) * line, clear it. */ if (full_screen && msg_scrolled == 0 && row < cmdline_row) - screen_fill(row, cmdline_row, 0, (int)Columns, ' ', ' ', 0); + grid_fill(&default_grid, row, cmdline_row, 0, (int)Columns, ' ', ' ', 0); cmdline_row = row; msg_row = row; msg_col = 0; @@ -4443,6 +4460,7 @@ void win_setwidth_win(int width, win_T *wp) } frame_setwidth(wp->w_frame, width + wp->w_vsep_width); + win_grid_alloc(wp, false); /* recompute the window positions */ (void)win_comp_pos(); @@ -4706,7 +4724,7 @@ void win_drag_status_line(win_T *dragwin, int offset) fr = fr->fr_next; } row = win_comp_pos(); - screen_fill(row, cmdline_row, 0, (int)Columns, ' ', ' ', 0); + grid_fill(&default_grid, row, cmdline_row, 0, (int)Columns, ' ', ' ', 0); cmdline_row = row; p_ch = Rows - cmdline_row; if (p_ch < 1) @@ -5054,7 +5072,7 @@ void command_height(void) /* clear the lines added to cmdline */ if (full_screen) - screen_fill(cmdline_row, (int)Rows, 0, + grid_fill(&default_grid, cmdline_row, (int)Rows, 0, (int)Columns, ' ', ' ', 0); msg_row = cmdline_row; redraw_cmdline = TRUE; -- cgit From 01555de2da79eaf6e569e5e6ee7244dbf5f709e5 Mon Sep 17 00:00:00 2001 From: Utkarsh Maheshwari Date: Wed, 6 Jun 2018 02:59:11 +0530 Subject: multigrid: Allow UIs to set grid size different from window size --- src/nvim/api/ui.c | 19 +++++- src/nvim/charset.c | 24 +++---- src/nvim/cursor.c | 8 +-- src/nvim/eval.c | 4 +- src/nvim/ex_cmds.c | 6 +- src/nvim/ex_docmd.c | 6 +- src/nvim/getchar.c | 6 +- src/nvim/globals.h | 2 +- src/nvim/indent.c | 2 +- src/nvim/misc1.c | 12 ++-- src/nvim/move.c | 123 ++++++++++++++++++------------------ src/nvim/normal.c | 30 ++++----- src/nvim/screen.c | 175 +++++++++++++++++++++++++++++++--------------------- src/nvim/search.c | 2 +- src/nvim/types.h | 4 +- src/nvim/ui.c | 32 +++++++--- src/nvim/window.c | 6 +- 17 files changed, 268 insertions(+), 193 deletions(-) (limited to 'src') diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 01f8c9f71c..18befd498f 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -126,7 +126,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, } } - if (ui->ui_ext[kUIHlState]) { + if (ui->ui_ext[kUIHlState] || ui->ui_ext[kUIMultigrid]) { ui->ui_ext[kUILinegrid] = true; } @@ -245,6 +245,23 @@ static void ui_set_option(UI *ui, bool init, String name, Object value, name.data); } +/// Sets the inner "width" and "height" of the window grid identified by +/// "grid" handle. If the grid does not exist, set error. +void nvim_ui_try_resize_grid(uint64_t channel_id, Integer grid, Integer width, + Integer height, Error *error) + FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY +{ + if (!pmap_has(uint64_t)(connected_uis, channel_id)) { + api_set_error(error, kErrorTypeException, + "UI not attached to channel: %" PRId64, channel_id); + return; + } + + // TODO(utkarshme): Check if grid exists + + ui_grid_resize((GridHandle)grid, (int)width, (int)height); +} + /// Pushes data into UI.UIData, to be consumed later by remote_ui_flush(). static void push_call(UI *ui, const char *name, Array args) { diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 4e8bb3b0d7..874c996b1b 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1022,12 +1022,12 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he && vim_isbreak(c) && !vim_isbreak((int)s[1]) && wp->w_p_wrap - && (wp->w_width != 0)) { + && (wp->w_grid.Columns != 0)) { // Count all characters from first non-blank after a blank up to next // non-blank after a blank. numberextra = win_col_off(wp); col2 = col; - colmax = (colnr_T)(wp->w_width - numberextra - col_adj); + colmax = (colnr_T)(wp->w_grid.Columns - numberextra - col_adj); if (col >= colmax) { colmax += col_adj; @@ -1076,9 +1076,9 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he numberextra = numberwidth; col += numberextra + mb_added; - if (col >= (colnr_T)wp->w_width) { - col -= wp->w_width; - numberextra = wp->w_width - (numberextra - win_col_off2(wp)); + if (col >= (colnr_T)wp->w_grid.Columns) { + col -= wp->w_grid.Columns; + numberextra = wp->w_grid.Columns - (numberextra - win_col_off2(wp)); if (col >= numberextra && numberextra > 0) { col %= numberextra; } @@ -1097,16 +1097,16 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he numberwidth -= win_col_off2(wp); } - if (col == 0 || (col + size + sbrlen > (colnr_T)wp->w_width)) { + if (col == 0 || (col + size + sbrlen > (colnr_T)wp->w_grid.Columns)) { added = 0; if (*p_sbr != NUL) { - if (size + sbrlen + numberwidth > (colnr_T)wp->w_width) { + if (size + sbrlen + numberwidth > (colnr_T)wp->w_grid.Columns) { // Calculate effective window width. - int width = (colnr_T)wp->w_width - sbrlen - numberwidth; - int prev_width = col ? ((colnr_T)wp->w_width - (sbrlen + col)) : 0; + int width = (colnr_T)wp->w_grid.Columns - sbrlen - numberwidth; + int prev_width = col ? ((colnr_T)wp->w_grid.Columns - (sbrlen + col)) : 0; if (width == 0) { - width = (colnr_T)wp->w_width; + width = (colnr_T)wp->w_grid.Columns; } added += ((size - prev_width) / width) * vim_strsize(p_sbr); if ((size - prev_width) % width) { @@ -1175,11 +1175,11 @@ bool in_win_border(win_T *wp, colnr_T vcol) int width1; // width of first line (after line number) int width2; // width of further lines - if (wp->w_width == 0) { + if (wp->w_grid.Columns == 0) { // there is no border return false; } - width1 = wp->w_width - win_col_off(wp); + width1 = wp->w_grid.Columns - win_col_off(wp); if ((int)vcol < width1 - 1) { return false; diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c index 0fda941a51..8c80c1dfc0 100644 --- a/src/nvim/cursor.c +++ b/src/nvim/cursor.c @@ -120,11 +120,11 @@ static int coladvance2( --curwin->w_curswant; } } else { - int width = curwin->w_width - win_col_off(curwin); + int width = curwin->w_grid.Columns - win_col_off(curwin); if (finetune && curwin->w_p_wrap - && curwin->w_width != 0 + && curwin->w_grid.Columns != 0 && wcol >= (colnr_T)width) { csize = linetabsize(line); if (csize > 0) @@ -224,7 +224,7 @@ static int coladvance2( int b = (int)wcol - (int)col; /* The difference between wcol and col is used to set coladd. */ - if (b > 0 && b < (MAXCOL - 2 * curwin->w_width)) + if (b > 0 && b < (MAXCOL - 2 * curwin->w_grid.Columns)) pos->coladd = b; col += b; @@ -436,7 +436,7 @@ bool leftcol_changed(void) bool retval = false; changed_cline_bef_curs(); - lastcol = curwin->w_leftcol + curwin->w_width - curwin_col_off() - 1; + lastcol = curwin->w_leftcol + curwin->w_grid.Columns - curwin_col_off() - 1; validate_virtcol(); /* diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d67818aa81..6fe62f1a87 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -16774,10 +16774,10 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } - uint16_t term_width = MAX(0, curwin->w_width - win_col_off(curwin)); + uint16_t term_width = MAX(0, curwin->w_grid.Columns - win_col_off(curwin)); Channel *chan = channel_job_start(argv, on_stdout, on_stderr, on_exit, true, false, false, cwd, - term_width, curwin->w_height, + term_width, curwin->w_grid.Rows, xstrdup("xterm-256color"), &rettv->vval.v_number); if (rettv->vval.v_number <= 0) { diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 36c4e333cf..0d14c90110 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -257,7 +257,7 @@ void ex_align(exarg_T *eap) if (width <= 0) width = curbuf->b_p_tw; if (width == 0 && curbuf->b_p_wm > 0) - width = curwin->w_width - curbuf->b_p_wm; + width = curwin->w_grid.Columns - curbuf->b_p_wm; if (width <= 0) width = 80; } @@ -2870,11 +2870,11 @@ void ex_z(exarg_T *eap) // Vi compatible: ":z!" uses display height, without a count uses // 'scroll' if (eap->forceit) { - bigness = curwin->w_height; + bigness = curwin->w_grid.Rows; } else if (ONE_WINDOW) { bigness = curwin->w_p_scr * 2; } else { - bigness = curwin->w_height - 3; + bigness = curwin->w_grid.Rows - 3; } if (bigness < 1) { bigness = 1; diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 4ef332186e..4e5619ccc8 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -9196,7 +9196,7 @@ static int ses_winsizes(FILE *fd, int restore_size, win_T *tab_firstwin) && (fprintf(fd, "exe '%dresize ' . ((&lines * %" PRId64 " + %" PRId64 ") / %" PRId64 ")", - n, (int64_t)wp->w_height, + n, (int64_t)wp->w_grid.Rows, (int64_t)(Rows / 2), (int64_t)Rows) < 0 || put_eol(fd) == FAIL)) return FAIL; @@ -9459,8 +9459,8 @@ put_view( " * winheight(0) + %" PRId64 ") / %" PRId64 ")", (int64_t)wp->w_cursor.lnum, (int64_t)(wp->w_cursor.lnum - wp->w_topline), - (int64_t)(wp->w_height / 2), - (int64_t)wp->w_height) < 0 + (int64_t)(wp->w_grid.Rows / 2), + (int64_t)wp->w_grid.Rows) < 0 || put_eol(fd) == FAIL || put_line(fd, "if s:l < 1 | let s:l = 1 | endif") == FAIL || put_line(fd, "exe s:l") == FAIL diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 94702a9a3a..6a2ee12e46 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -2120,8 +2120,8 @@ static int vgetorpeek(int advance) ++col; } curwin->w_wrow = curwin->w_cline_row - + curwin->w_wcol / curwin->w_width; - curwin->w_wcol %= curwin->w_width; + + curwin->w_wcol / curwin->w_grid.Columns; + curwin->w_wcol %= curwin->w_grid.Columns; curwin->w_wcol += curwin_col_off(); col = 0; /* no correction needed */ } else { @@ -2130,7 +2130,7 @@ static int vgetorpeek(int advance) } } else if (curwin->w_p_wrap && curwin->w_wrow) { --curwin->w_wrow; - curwin->w_wcol = curwin->w_width - 1; + curwin->w_wcol = curwin->w_grid.Columns - 1; col = curwin->w_cursor.col - 1; } if (col > 0 && curwin->w_wcol > 0) { diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 3462199476..57d14d650c 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -162,7 +162,7 @@ EXTERN int screen_Rows INIT(= 0); /* actual size of ScreenLines[] */ EXTERN int screen_Columns INIT(= 0); /* actual size of ScreenLines[] */ EXTERN ScreenGrid default_grid INIT(= { 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0, - 0, 0, 0 }); + 0, 0 }); /* * When vgetc() is called, it sets mod_mask to the set of modifiers that are diff --git a/src/nvim/indent.c b/src/nvim/indent.c index 3cc64e0033..76b06190a5 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -464,7 +464,7 @@ int get_breakindent_win(win_T *wp, char_u *line) static varnumber_T prev_tick = 0; // Changedtick of cached value. int bri = 0; /* window width minus window margin space, i.e. what rests for text */ - const int eff_wwidth = wp->w_width + const int eff_wwidth = wp->w_grid.Columns - ((wp->w_p_nu || wp->w_p_rnu) && (vim_strchr(p_cpo, CPO_NUMCOL) == NULL) ? number_width(wp) + 1 : 0); diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index ffe2d11f08..fb5586dea2 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -1251,7 +1251,7 @@ int plines_win_nofill( return 1; } - if (wp->w_width == 0) { + if (wp->w_grid.Columns == 0) { return 1; } @@ -1261,8 +1261,8 @@ int plines_win_nofill( } const int lines = plines_win_nofold(wp, lnum); - if (winheight && lines > wp->w_height) { - return wp->w_height; + if (winheight && lines > wp->w_grid.Rows) { + return wp->w_grid.Rows; } return lines; } @@ -1292,7 +1292,7 @@ int plines_win_nofold(win_T *wp, linenr_T lnum) /* * Add column offset for 'number', 'relativenumber' and 'foldcolumn'. */ - width = wp->w_width - win_col_off(wp); + width = wp->w_grid.Columns - win_col_off(wp); if (width <= 0 || col > 32000) { return 32000; // bigger than the number of screen columns } @@ -1318,7 +1318,7 @@ int plines_win_col(win_T *wp, linenr_T lnum, long column) if (!wp->w_p_wrap) return lines + 1; - if (wp->w_width == 0) + if (wp->w_grid.Columns == 0) return lines + 1; char_u *line = ml_get_buf(wp->w_buffer, lnum, false); @@ -1340,7 +1340,7 @@ int plines_win_col(win_T *wp, linenr_T lnum, long column) } // Add column offset for 'number', 'relativenumber', 'foldcolumn', etc. - int width = wp->w_width - win_col_off(wp); + int width = wp->w_grid.Columns - win_col_off(wp); if (width <= 0) { return 9999; } diff --git a/src/nvim/move.c b/src/nvim/move.c index bb44b458e8..6e317b03a4 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -83,7 +83,7 @@ static void comp_botline(win_T *wp) redraw_for_cursorline(wp); wp->w_valid |= (VALID_CROW|VALID_CHEIGHT); } - if (done + n > wp->w_height) + if (done + n > wp->w_grid.Rows) break; done += n; lnum = last; @@ -203,7 +203,7 @@ void update_topline(void) check_topline = true; if (check_topline) { - int halfheight = curwin->w_height / 2 - 1; + int halfheight = curwin->w_grid.Rows / 2 - 1; if (halfheight < 2) halfheight = 2; long n; @@ -295,14 +295,14 @@ void update_topline(void) lnum >= curwin->w_botline - p_so; --lnum) { ++line_count; /* stop at end of file or when we know we are far off */ - if (lnum <= 0 || line_count > curwin->w_height + 1) + if (lnum <= 0 || line_count > curwin->w_grid.Rows + 1) break; (void)hasFolding(lnum, &lnum, NULL); } } else line_count = curwin->w_cursor.lnum - curwin->w_botline + 1 + p_so; - if (line_count <= curwin->w_height + 1) + if (line_count <= curwin->w_grid.Rows + 1) scroll_cursor_bot(scrolljump_value(), false); else scroll_cursor_halfway(false); @@ -349,7 +349,7 @@ void update_topline_win(win_T* win) */ static int scrolljump_value(void) { - long result = p_sj >= 0 ? p_sj : (curwin->w_height * -p_sj) / 100; + long result = p_sj >= 0 ? p_sj : (curwin->w_grid.Rows * -p_sj) / 100; assert(result <= INT_MAX); return (int)result; } @@ -525,6 +525,7 @@ int cursor_valid(void) */ void validate_cursor(void) { + win_grid_alloc(curwin, true); // we need to have w_grid.Rows/Columns updated check_cursor_moved(curwin); if ((curwin->w_valid & (VALID_WCOL|VALID_WROW)) != (VALID_WCOL|VALID_WROW)) curs_columns(true); @@ -663,14 +664,14 @@ void validate_cursor_col(void) colnr_T col = curwin->w_virtcol; colnr_T off = curwin_col_off(); col += off; - int width = curwin->w_width - off + curwin_col_off2(); + int width = curwin->w_grid.Columns - off + curwin_col_off2(); /* long line wrapping, adjust curwin->w_wrow */ if (curwin->w_p_wrap - && col >= (colnr_T)curwin->w_width + && col >= (colnr_T)curwin->w_grid.Columns && width > 0) /* use same formula as what is used in curs_columns() */ - col -= ((col - curwin->w_width) / width + 1) * width; + col -= ((col - curwin->w_grid.Columns) / width + 1) * width; if (col > (int)curwin->w_leftcol) col -= curwin->w_leftcol; else @@ -763,20 +764,20 @@ void curs_columns( */ curwin->w_wrow = curwin->w_cline_row; - int textwidth = curwin->w_width - extra; + int textwidth = curwin->w_grid.Columns - extra; if (textwidth <= 0) { /* No room for text, put cursor in last char of window. */ - curwin->w_wcol = curwin->w_width - 1; - curwin->w_wrow = curwin->w_height - 1; + curwin->w_wcol = curwin->w_grid.Columns - 1; + curwin->w_wrow = curwin->w_grid.Rows - 1; } else if (curwin->w_p_wrap - && curwin->w_width != 0 + && curwin->w_grid.Columns != 0 ) { width = textwidth + curwin_col_off2(); /* long line wrapping, adjust curwin->w_wrow */ - if (curwin->w_wcol >= curwin->w_width) { + if (curwin->w_wcol >= curwin->w_grid.Columns) { /* this same formula is used in validate_cursor_col() */ - n = (curwin->w_wcol - curwin->w_width) / width + 1; + n = (curwin->w_wcol - curwin->w_grid.Columns) / width + 1; curwin->w_wcol -= n * width; curwin->w_wrow += n; @@ -803,7 +804,7 @@ void curs_columns( assert(p_siso <= INT_MAX); int off_left = startcol - curwin->w_leftcol - (int)p_siso; int off_right = - endcol - curwin->w_leftcol - curwin->w_width + (int)p_siso + 1; + endcol - curwin->w_leftcol - curwin->w_grid.Columns + (int)p_siso + 1; if (off_left < 0 || off_right > 0) { int diff = (off_left < 0) ? -off_left: off_right; @@ -846,17 +847,17 @@ void curs_columns( prev_skipcol = curwin->w_skipcol; int p_lines = 0; - if ((curwin->w_wrow >= curwin->w_height + if ((curwin->w_wrow >= curwin->w_grid.Rows || ((prev_skipcol > 0 - || curwin->w_wrow + p_so >= curwin->w_height) + || curwin->w_wrow + p_so >= curwin->w_grid.Rows) && (p_lines = plines_win_nofill (curwin, curwin->w_cursor.lnum, false)) - - 1 >= curwin->w_height)) - && curwin->w_height != 0 + - 1 >= curwin->w_grid.Rows)) + && curwin->w_grid.Rows != 0 && curwin->w_cursor.lnum == curwin->w_topline && width > 0 - && curwin->w_width != 0 + && curwin->w_grid.Columns != 0 ) { /* Cursor past end of screen. Happens with a single line that does * not fit on screen. Find a skipcol to show the text around the @@ -878,19 +879,19 @@ void curs_columns( } else n = p_lines; - if ((colnr_T)n >= curwin->w_height + curwin->w_skipcol / width) + if ((colnr_T)n >= curwin->w_grid.Rows + curwin->w_skipcol / width) extra += 2; if (extra == 3 || p_lines < p_so * 2) { /* not enough room for 'scrolloff', put cursor in the middle */ n = curwin->w_virtcol / width; - if (n > curwin->w_height / 2) - n -= curwin->w_height / 2; + if (n > curwin->w_grid.Rows / 2) + n -= curwin->w_grid.Rows / 2; else n = 0; /* don't skip more than necessary */ - if (n > p_lines - curwin->w_height + 1) - n = p_lines - curwin->w_height + 1; + if (n > p_lines - curwin->w_grid.Rows + 1) + n = p_lines - curwin->w_grid.Rows + 1; curwin->w_skipcol = n * width; } else if (extra == 1) { /* less then 'scrolloff' lines above, decrease skipcol */ @@ -904,7 +905,7 @@ void curs_columns( } } else if (extra == 2) { /* less then 'scrolloff' lines below, increase skipcol */ - endcol = (n - curwin->w_height + 1) * width; + endcol = (n - curwin->w_grid.Rows + 1) * width; while (endcol > curwin->w_virtcol) endcol -= width; if (endcol > curwin->w_skipcol) @@ -912,9 +913,9 @@ void curs_columns( } curwin->w_wrow -= curwin->w_skipcol / width; - if (curwin->w_wrow >= curwin->w_height) { + if (curwin->w_wrow >= curwin->w_grid.Rows) { /* small window, make sure cursor is in it */ - extra = curwin->w_wrow - curwin->w_height + 1; + extra = curwin->w_wrow - curwin->w_grid.Rows + 1; curwin->w_skipcol += extra * width; curwin->w_wrow -= extra; } @@ -956,7 +957,7 @@ scrolldown ( validate_cursor(); /* w_wrow needs to be valid */ while (line_count-- > 0) { if (curwin->w_topfill < diff_check(curwin, curwin->w_topline) - && curwin->w_topfill < curwin->w_height - 1) { + && curwin->w_topfill < curwin->w_grid.Rows - 1) { ++curwin->w_topfill; ++done; } else { @@ -991,15 +992,15 @@ scrolldown ( */ int wrow = curwin->w_wrow; if (curwin->w_p_wrap - && curwin->w_width != 0 + && curwin->w_grid.Columns != 0 ) { validate_virtcol(); validate_cheight(); wrow += curwin->w_cline_height - 1 - - curwin->w_virtcol / curwin->w_width; + curwin->w_virtcol / curwin->w_grid.Columns; } bool moved = false; - while (wrow >= curwin->w_height && curwin->w_cursor.lnum > 1) { + while (wrow >= curwin->w_grid.Rows && curwin->w_cursor.lnum > 1) { linenr_T first; if (hasFolding(curwin->w_cursor.lnum, &first, NULL)) { --wrow; @@ -1084,12 +1085,12 @@ check_topfill ( { if (wp->w_topfill > 0) { int n = plines_win_nofill(wp, wp->w_topline, true); - if (wp->w_topfill + n > wp->w_height) { + if (wp->w_topfill + n > wp->w_grid.Rows) { if (down && wp->w_topline > 1) { --wp->w_topline; wp->w_topfill = 0; } else { - wp->w_topfill = wp->w_height - n; + wp->w_topfill = wp->w_grid.Rows - n; if (wp->w_topfill < 0) wp->w_topfill = 0; } @@ -1104,12 +1105,12 @@ check_topfill ( static void max_topfill(void) { int n = plines_nofill(curwin->w_topline); - if (n >= curwin->w_height) + if (n >= curwin->w_grid.Rows) curwin->w_topfill = 0; else { curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline); - if (curwin->w_topfill + n > curwin->w_height) - curwin->w_topfill = curwin->w_height - n; + if (curwin->w_topfill + n > curwin->w_grid.Rows) + curwin->w_topfill = curwin->w_grid.Rows - n; } } @@ -1140,14 +1141,14 @@ void scrolldown_clamp(void) else end_row += plines_nofill(curwin->w_topline - 1); if (curwin->w_p_wrap - && curwin->w_width != 0 + && curwin->w_grid.Columns != 0 ) { validate_cheight(); validate_virtcol(); end_row += curwin->w_cline_height - 1 - - curwin->w_virtcol / curwin->w_width; + curwin->w_virtcol / curwin->w_grid.Columns; } - if (end_row < curwin->w_height - p_so) { + if (end_row < curwin->w_grid.Rows - p_so) { if (can_fill) { ++curwin->w_topfill; check_topfill(curwin, true); @@ -1182,10 +1183,10 @@ void scrollup_clamp(void) int start_row = curwin->w_wrow - plines_nofill(curwin->w_topline) - curwin->w_topfill; if (curwin->w_p_wrap - && curwin->w_width != 0 + && curwin->w_grid.Columns != 0 ) { validate_virtcol(); - start_row -= curwin->w_virtcol / curwin->w_width; + start_row -= curwin->w_virtcol / curwin->w_grid.Columns; } if (start_row >= p_so) { if (curwin->w_topfill > 0) @@ -1339,7 +1340,7 @@ void scroll_cursor_top(int min_scroll, int always) else used += plines(bot); } - if (used > curwin->w_height) + if (used > curwin->w_grid.Rows) break; if (top < curwin->w_topline) scrolled += i; @@ -1362,7 +1363,7 @@ void scroll_cursor_top(int min_scroll, int always) * This makes sure we get the same position when using "k" and "j" * in a small window. */ - if (used > curwin->w_height) { + if (used > curwin->w_grid.Rows) { scroll_cursor_halfway(false); } else { /* @@ -1399,7 +1400,7 @@ void set_empty_rows(win_T *wp, int used) if (used == 0) wp->w_empty_rows = 0; /* single line that doesn't fit */ else { - wp->w_empty_rows = wp->w_height - used; + wp->w_empty_rows = wp->w_grid.Rows - used; if (wp->w_botline <= wp->w_buffer->b_ml.ml_line_count) { wp->w_filler_rows = diff_check_fill(wp, wp->w_botline); if (wp->w_empty_rows > wp->w_filler_rows) @@ -1442,7 +1443,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) curwin->w_topline = loff.lnum) { loff.lnum = curwin->w_topline; topline_back(&loff); - if (loff.height == MAXCOL || used + loff.height > curwin->w_height) + if (loff.height == MAXCOL || used + loff.height > curwin->w_grid.Rows) break; used += loff.height; curwin->w_topfill = loff.fill; @@ -1504,7 +1505,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) used = MAXCOL; else used += loff.height; - if (used > curwin->w_height) + if (used > curwin->w_grid.Rows) break; if (loff.lnum >= curwin->w_botline && (loff.lnum > curwin->w_botline @@ -1522,7 +1523,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) /* Add one line below */ botline_forw(&boff); used += boff.height; - if (used > curwin->w_height) + if (used > curwin->w_grid.Rows) break; if (extra < ( mouse_dragging > 0 ? mouse_dragging - 1 : @@ -1548,7 +1549,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) if (scrolled <= 0) line_count = 0; /* more than a screenfull, don't scroll but redraw */ - else if (used > curwin->w_height) + else if (used > curwin->w_grid.Rows) line_count = used; /* scroll minimal number of lines */ else { @@ -1569,7 +1570,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) * Scroll up if the cursor is off the bottom of the screen a bit. * Otherwise put it at 1/2 of the screen. */ - if (line_count >= curwin->w_height && line_count > min_scroll) + if (line_count >= curwin->w_grid.Rows && line_count > min_scroll) scroll_cursor_halfway(false); else scrollup(line_count, true); @@ -1611,7 +1612,7 @@ void scroll_cursor_halfway(int atend) if (boff.lnum < curbuf->b_ml.ml_line_count) { botline_forw(&boff); used += boff.height; - if (used > curwin->w_height) + if (used > curwin->w_grid.Rows) break; below += boff.height; } else { @@ -1627,7 +1628,7 @@ void scroll_cursor_halfway(int atend) used = MAXCOL; else used += loff.height; - if (used > curwin->w_height) + if (used > curwin->w_grid.Rows) break; above += loff.height; topline = loff.lnum; @@ -1637,7 +1638,7 @@ void scroll_cursor_halfway(int atend) if (!hasFolding(topline, &curwin->w_topline, NULL)) curwin->w_topline = topline; curwin->w_topfill = topfill; - if (old_topline > curwin->w_topline + curwin->w_height) + if (old_topline > curwin->w_topline + curwin->w_grid.Rows) curwin->w_botfill = false; check_topfill(curwin, false); curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP); @@ -1665,7 +1666,7 @@ void cursor_correct(void) } if (curwin->w_topline == 1) { above_wanted = 0; - int max_off = curwin->w_height / 2; + int max_off = curwin->w_grid.Rows / 2; if (below_wanted > max_off) below_wanted = max_off; } @@ -1674,7 +1675,7 @@ void cursor_correct(void) && mouse_dragging == 0 ) { below_wanted = 0; - int max_off = (curwin->w_height - 1) / 2; + int max_off = (curwin->w_grid.Rows - 1) / 2; if (above_wanted > max_off) above_wanted = max_off; } @@ -1847,7 +1848,7 @@ int onepage(Direction dir, long count) /* Find the line just above the new topline to get the right line * at the bottom of the window. */ n = 0; - while (n <= curwin->w_height && loff.lnum >= 1) { + while (n <= curwin->w_grid.Rows && loff.lnum >= 1) { topline_back(&loff); if (loff.height == MAXCOL) n = MAXCOL; @@ -1938,7 +1939,7 @@ int onepage(Direction dir, long count) */ static void get_scroll_overlap(lineoff_T *lp, int dir) { - int min_height = curwin->w_height - 2; + int min_height = curwin->w_grid.Rows - 2; if (lp->fill > 0) lp->height = 1; @@ -1993,11 +1994,11 @@ void halfpage(bool flag, linenr_T Prenum) int i; if (Prenum) - curwin->w_p_scr = (Prenum > curwin->w_height) ? - curwin->w_height : Prenum; + curwin->w_p_scr = (Prenum > curwin->w_grid.Rows) ? + curwin->w_grid.Rows : Prenum; assert(curwin->w_p_scr <= INT_MAX); - int n = curwin->w_p_scr <= curwin->w_height ? (int)curwin->w_p_scr - : curwin->w_height; + int n = curwin->w_p_scr <= curwin->w_grid.Rows ? (int)curwin->w_p_scr + : curwin->w_grid.Rows; update_topline(); validate_botline(); diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 4e6c3c4063..28c577034c 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -3906,14 +3906,14 @@ static bool nv_screengo(oparg_T *oap, int dir, long dist) col_off1 = curwin_col_off(); col_off2 = col_off1 - curwin_col_off2(); - width1 = curwin->w_width - col_off1; - width2 = curwin->w_width - col_off2; + width1 = curwin->w_grid.Columns - col_off1; + width2 = curwin->w_grid.Columns - col_off2; if (width2 == 0) { width2 = 1; // Avoid divide by zero. } - if (curwin->w_width != 0) { + if (curwin->w_grid.Columns != 0) { /* * Instead of sticking at the last character of the buffer line we * try to stick in the last column of the screen. @@ -4256,7 +4256,7 @@ dozet: /* "zH" - scroll screen right half-page */ case 'H': - cap->count1 *= curwin->w_width / 2; + cap->count1 *= curwin->w_grid.Columns / 2; FALLTHROUGH; /* "zh" - scroll screen to the right */ @@ -4272,7 +4272,7 @@ dozet: break; /* "zL" - scroll screen left half-page */ - case 'L': cap->count1 *= curwin->w_width / 2; + case 'L': cap->count1 *= curwin->w_grid.Columns / 2; FALLTHROUGH; /* "zl" - scroll screen to the left */ @@ -4308,7 +4308,7 @@ dozet: col = 0; /* like the cursor is in col 0 */ else getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col); - n = curwin->w_width - curwin_col_off(); + n = curwin->w_grid.Columns - curwin_col_off(); if (col + l_p_siso < n) col = 0; else @@ -5018,7 +5018,7 @@ static void nv_scroll(cmdarg_T *cap) used -= diff_check_fill(curwin, curwin->w_topline) - curwin->w_topfill; validate_botline(); /* make sure w_empty_rows is valid */ - half = (curwin->w_height - curwin->w_empty_rows + 1) / 2; + half = (curwin->w_grid.Rows - curwin->w_empty_rows + 1) / 2; for (n = 0; curwin->w_topline + n < curbuf->b_ml.ml_line_count; ++n) { /* Count half he number of filler lines to be "below this * line" and half to be "above the next line". */ @@ -5033,7 +5033,7 @@ static void nv_scroll(cmdarg_T *cap) if (hasFolding(curwin->w_topline + n, NULL, &lnum)) n = lnum - curwin->w_topline; } - if (n > 0 && used > curwin->w_height) + if (n > 0 && used > curwin->w_grid.Rows) --n; } else { /* (cap->cmdchar == 'H') */ n = cap->count1 - 1; @@ -6748,9 +6748,9 @@ static void nv_g_cmd(cmdarg_T *cap) oap->motion_type = kMTCharWise; oap->inclusive = false; if (curwin->w_p_wrap - && curwin->w_width != 0 + && curwin->w_grid.Columns != 0 ) { - int width1 = curwin->w_width - curwin_col_off(); + int width1 = curwin->w_grid.Columns - curwin_col_off(); int width2 = width1 + curwin_col_off2(); validate_virtcol(); @@ -6763,7 +6763,7 @@ static void nv_g_cmd(cmdarg_T *cap) * 'relativenumber' is on and lines are wrapping the middle can be more * to the left. */ if (cap->nchar == 'm') - i += (curwin->w_width - curwin_col_off() + i += (curwin->w_grid.Columns - curwin_col_off() + ((curwin->w_p_wrap && i > 0) ? curwin_col_off2() : 0)) / 2; coladvance((colnr_T)i); @@ -6809,11 +6809,11 @@ static void nv_g_cmd(cmdarg_T *cap) oap->motion_type = kMTCharWise; oap->inclusive = true; if (curwin->w_p_wrap - && curwin->w_width != 0 + && curwin->w_grid.Columns != 0 ) { curwin->w_curswant = MAXCOL; /* so we stay at the end */ if (cap->count1 == 1) { - int width1 = curwin->w_width - col_off; + int width1 = curwin->w_grid.Columns - col_off; int width2 = width1 + curwin_col_off2(); validate_virtcol(); @@ -6839,7 +6839,7 @@ static void nv_g_cmd(cmdarg_T *cap) } else if (nv_screengo(oap, FORWARD, cap->count1 - 1) == false) clearopbeep(oap); } else { - i = curwin->w_leftcol + curwin->w_width - col_off - 1; + i = curwin->w_leftcol + curwin->w_grid.Columns - col_off - 1; coladvance((colnr_T)i); /* Make sure we stick in this column. */ @@ -7954,7 +7954,7 @@ static void get_op_vcol( colnr_T end; if (VIsual_mode != Ctrl_V - || (!initial && oap->end.col < curwin->w_width)) { + || (!initial && oap->end.col < curwin->w_grid.Columns)) { return; } diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 3aaca394f5..f247aa707d 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -118,7 +118,11 @@ #define MB_FILLER_CHAR '<' /* character used when a double-width character * doesn't fit. */ + #define W_ENDCOL(wp) (wp->w_width + wp->w_wincol) +#define W_ENDROW(wp) (wp->w_height + wp->w_winrow) + +#define DEFAULT_GRID_HANDLE 1 static match_T search_hl; /* used for 'hlsearch' highlight matching */ @@ -137,10 +141,6 @@ typedef struct { } LineState; #define LINE_STATE(p) { p, 0, 0 } -/// The last handle that was assigned to a ScreenGrid. 1 is reserved for -/// the default_grid. -static int last_handle = 1; - /// Whether to call "ui_call_grid_resize" in win_grid_alloc static int send_grid_resize; @@ -295,11 +295,11 @@ void update_screen(int type) redraw_tabline = true; } FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if (wp->w_winrow + wp->w_height > valid) { + if (W_ENDROW(wp) > valid) { wp->w_redr_type = NOT_VALID; wp->w_lines_valid = 0; } - if (wp->w_winrow + wp->w_height + wp->w_status_height > valid) { + if (W_ENDROW(wp) + wp->w_status_height > valid) { wp->w_redr_status = true; } } @@ -313,7 +313,7 @@ void update_screen(int type) } FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { if (wp->w_winrow < msg_scrolled) { - if (wp->w_winrow + wp->w_height > msg_scrolled + if (W_ENDROW(wp) > msg_scrolled && wp->w_redr_type < REDRAW_TOP && wp->w_lines_valid > 0 && wp->w_topline == wp->w_lines[0].wl_lnum) { @@ -321,7 +321,7 @@ void update_screen(int type) wp->w_redr_type = REDRAW_TOP; } else { wp->w_redr_type = NOT_VALID; - if (wp->w_winrow + wp->w_height + wp->w_status_height + if (W_ENDROW(wp) + wp->w_status_height <= msg_scrolled) { wp->w_redr_status = TRUE; } @@ -705,8 +705,8 @@ static void win_update(win_T *wp) if (buf->terminal) { terminal_resize(buf->terminal, - (uint16_t)(MAX(0, wp->w_width - win_col_off(wp))), - (uint16_t)wp->w_height); + (uint16_t)(MAX(0, wp->w_grid.Columns - win_col_off(wp))), + (uint16_t)wp->w_grid.Rows); } } else if (buf->b_mod_set && buf->b_mod_xlines != 0 @@ -1440,7 +1440,7 @@ static void win_update(win_T *wp) if (wp->w_p_rnu) { // 'relativenumber' set: The text doesn't need to be drawn, but // the number column nearly always does. - (void)win_line(wp, lnum, srow, wp->w_height, true, true); + (void)win_line(wp, lnum, srow, wp->w_grid.Rows, true, true); } // This line does not need to be drawn, advance to the next one. @@ -1501,7 +1501,7 @@ static void win_update(win_T *wp) wp->w_botline = lnum; } else if (dy_flags & DY_LASTLINE) { // 'display' has "lastline" // Last line isn't finished: Display "@@@" at the end. - grid_fill(&wp->w_grid, wp->w_height - 1, wp->w_height, + grid_fill(&wp->w_grid, wp->w_grid.Rows - 1, wp->w_grid.Rows, wp->w_grid.Columns - 3, wp->w_grid.Columns, '@', '@', at_attr); set_empty_rows(wp, srow); wp->w_botline = lnum; @@ -1531,7 +1531,7 @@ static void win_update(win_T *wp) // make sure the rest of the screen is blank // write the 'fill_eob' character to rows that aren't part of the file. - win_draw_end(wp, fill_eob, ' ', row, wp->w_height, HLF_EOB); + win_draw_end(wp, fill_eob, ' ', row, wp->w_grid.Rows, HLF_EOB); } if (wp->w_redr_type >= REDRAW_TOP) { @@ -1611,8 +1611,8 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h if (n > 0) { /* draw the fold column at the right */ - if (n > wp->w_width) - n = wp->w_width; + if (n > wp->w_grid.Columns) + n = wp->w_grid.Columns; grid_fill(&wp->w_grid, row, endrow, wp->w_grid.Columns - n, wp->w_grid.Columns, ' ', ' ', win_hl_attr(wp, HLF_FC)); } @@ -1621,8 +1621,8 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h int nn = n + win_signcol_width(wp); /* draw the sign column left of the fold column */ - if (nn > wp->w_width) { - nn = wp->w_width; + if (nn > wp->w_grid.Columns) { + nn = wp->w_grid.Columns; } grid_fill(&wp->w_grid, row, endrow, wp->w_grid.Columns - nn, wp->w_grid.Columns - n, ' ', ' ', win_hl_attr(wp, HLF_SC)); @@ -1638,8 +1638,8 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h if (cmdwin_type != 0 && wp == curwin) { /* draw the cmdline character in the leftmost column */ n = 1; - if (n > wp->w_width) - n = wp->w_width; + if (n > wp->w_grid.Columns) + n = wp->w_grid.Columns; grid_fill(&wp->w_grid, row, endrow, 0, n, cmdwin_type, ' ', win_hl_attr(wp, HLF_AT)); } @@ -1647,8 +1647,8 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h int nn = n + fdc; /* draw the fold column at the left */ - if (nn > wp->w_width) - nn = wp->w_width; + if (nn > wp->w_grid.Columns) + nn = wp->w_grid.Columns; grid_fill(&wp->w_grid, row, endrow, n, nn, ' ', ' ', win_hl_attr(wp, HLF_FC)); n = nn; @@ -1658,8 +1658,8 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h int nn = n + win_signcol_width(wp); /* draw the sign column after the fold column */ - if (nn > wp->w_width) { - nn = wp->w_width; + if (nn > wp->w_grid.Columns) { + nn = wp->w_grid.Columns; } grid_fill(&wp->w_grid, row, endrow, n, nn, ' ', ' ', win_hl_attr(wp, HLF_SC)); @@ -1688,7 +1688,7 @@ static int compute_foldcolumn(win_T *wp, int col) { int fdc = wp->w_p_fdc; int wmw = wp == curwin && p_wmw == 0 ? 1 : p_wmw; - int wwidth = wp->w_width; + int wwidth = wp->w_grid.Columns; if (fdc > wwidth - (col + wmw)) { fdc = wwidth - (col + wmw); @@ -2680,7 +2680,7 @@ win_line ( // Rightleft window: process the text in the normal direction, but put // it in grid->ScreenLines[off] from right to left. Start at the // rightmost column of the window. - col = wp->w_width - 1; + col = grid->Columns - 1; off += col; } @@ -2858,7 +2858,7 @@ win_line ( if (wp->w_p_rl) n_extra = col + 1; else - n_extra = wp->w_width - col; + n_extra = grid->Columns - col; char_attr = win_hl_attr(wp, HLF_DED); } if (*p_sbr != NUL && need_showbreak) { @@ -3129,7 +3129,7 @@ win_line ( * last column. */ if (( wp->w_p_rl ? (col <= 0) : - (col >= wp->w_width - 1)) + (col >= grid->Columns - 1)) && (*mb_char2cells)(mb_c) == 2) { c = '>'; mb_c = c; @@ -3271,7 +3271,7 @@ win_line ( * next line. */ if (( wp->w_p_rl ? (col <= 0) : - (col >= wp->w_width - 1)) + (col >= grid->Columns - 1)) && (*mb_char2cells)(mb_c) == 2) { c = '>'; mb_c = c; @@ -3445,7 +3445,7 @@ win_line ( char_u *p = ptr - (mb_off + 1); // TODO: is passing p for start of the line OK? n_extra = win_lbr_chartabsize(wp, line, p, (colnr_T)vcol, NULL) - 1; - if (c == TAB && n_extra + col > wp->w_width) { + if (c == TAB && n_extra + col > grid->Columns) { n_extra = (int)wp->w_buffer->b_p_ts - vcol % (int)wp->w_buffer->b_p_ts - 1; } @@ -3604,7 +3604,7 @@ win_line ( && VIsual_mode != Ctrl_V && ( wp->w_p_rl ? (col >= 0) : - (col < wp->w_width)) + (col < grid->Columns)) && !(noinvcur && lnum == wp->w_cursor.lnum && (colnr_T)vcol == wp->w_virtcol))) @@ -3676,7 +3676,7 @@ win_line ( && vcol < tocol && ( wp->w_p_rl ? (col >= 0) : - (col < wp->w_width))) { + (col < grid->Columns))) { c = ' '; ptr--; // put it back at the NUL } @@ -3746,7 +3746,7 @@ win_line ( && conceal_cursor_line(wp) && (int)wp->w_virtcol <= vcol + n_skip) { if (wp->w_p_rl) { - wp->w_wcol = wp->w_width - col + boguscols - 1; + wp->w_wcol = grid->Columns - col + boguscols - 1; } else { wp->w_wcol = col - boguscols; } @@ -3834,7 +3834,7 @@ win_line ( if (col < 0) n = 1; } else { - if (col >= wp->w_width) + if (col >= grid->Columns) n = -1; } if (n != 0) { @@ -3907,7 +3907,7 @@ win_line ( if (((wp->w_p_cuc && (int)wp->w_virtcol >= VCOL_HLC - eol_hl_off && (int)wp->w_virtcol < - wp->w_width * (row - startrow + 1) + v + grid->Columns * (row - startrow + 1) + v && lnum != wp->w_cursor.lnum) || draw_color_col || line_attr_lowprio || line_attr || diff_hlf != (hlf_T)0 || do_virttext)) { @@ -3955,7 +3955,7 @@ win_line ( int col_stride = wp->w_p_rl ? -1 : 1; - while (wp->w_p_rl ? col >= 0 : col < wp->w_width) { + while (wp->w_p_rl ? col >= 0 : col < grid->Columns) { int cells = -1; if (do_virttext && !delay_virttext) { if (*s.p == NUL) { @@ -3969,7 +3969,7 @@ win_line ( } } if (*s.p != NUL) { - cells = line_putchar(&s, &grid->ScreenLines[off], wp->w_width - col, + cells = line_putchar(&s, &grid->ScreenLines[off], grid->Columns - col, false); } } @@ -3998,9 +3998,9 @@ win_line ( attr = hl_combine_attr(attr, line_attr); - ScreenAttrs[off] = attr; + grid->ScreenAttrs[off] = attr; if (cells == 2) { - ScreenAttrs[off+1] = attr; + grid->ScreenAttrs[off+1] = attr; } off += cells * col_stride; @@ -4017,7 +4017,7 @@ win_line ( if (wp->w_buffer->terminal) { // terminal buffers may need to highlight beyond the end of the // logical line - while (col < wp->w_width) { + while (col < grid->Columns) { schar_from_ascii(grid->ScreenLines[off], ' '); grid->ScreenAttrs[off++] = term_attrs[vcol++]; col++; @@ -4047,7 +4047,7 @@ win_line ( && filler_todo <= 0 && ( wp->w_p_rl ? col == 0 : - col == wp->w_width - 1) + col == grid->Columns - 1) && (*ptr != NUL || (wp->w_p_list && lcs_eol_one > 0) || (n_extra && (c_extra != NUL || *p_extra != NUL)))) { @@ -4227,7 +4227,7 @@ win_line ( */ if (( wp->w_p_rl ? (col < 0) : - (col >= wp->w_width)) + (col >= grid->Columns)) && (*ptr != NUL || filler_todo > 0 || (wp->w_p_list && lcs_eol != NUL && p_extra != at_end_str) @@ -4276,7 +4276,7 @@ win_line ( col = 0; off = (unsigned)(grid->Rows * grid->Columns); if (wp->w_p_rl) { - col = wp->w_width - 1; /* col is not used if breaking! */ + col = grid->Columns - 1; /* col is not used if breaking! */ off += col; } @@ -4586,7 +4586,7 @@ static void draw_vsep_win(win_T *wp, int row) if (wp->w_vsep_width) { // draw the vertical separator right of this window c = fillchar_vsep(wp, &hl); - grid_fill(&default_grid, wp->w_winrow + row, wp->w_winrow + wp->w_height, + grid_fill(&default_grid, wp->w_winrow + row, W_ENDROW(wp), W_ENDCOL(wp), W_ENDCOL(wp) + 1, c, ' ', hl); } } @@ -4905,7 +4905,7 @@ static void win_redr_status(win_T *wp, int ignore_pum) } } - row = wp->w_winrow + wp->w_height; + row = W_ENDROW(wp); grid_puts(&default_grid, p, row, wp->w_wincol, attr); grid_fill(&default_grid, row, row + 1, len + wp->w_wincol, this_ru_col + wp->w_wincol, fillchar, fillchar, attr); @@ -4927,8 +4927,7 @@ static void win_redr_status(win_T *wp, int ignore_pum) } else { fillchar = fillchar_vsep(wp, &attr); } - grid_putchar(&default_grid, fillchar, wp->w_winrow + wp->w_height, - W_ENDCOL(wp), attr); + grid_putchar(&default_grid, fillchar, W_ENDROW(wp), W_ENDCOL(wp), attr); } busy = FALSE; } @@ -5075,7 +5074,7 @@ win_redr_custom ( maxwidth = default_grid.Columns; use_sandbox = was_set_insecurely((char_u *)"tabline", 0); } else { - row = wp->w_winrow + wp->w_height; + row = W_ENDROW(wp); fillchar = fillchar_status(&attr, wp); maxwidth = wp->w_width; @@ -5834,7 +5833,7 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, } } - if (end_col == Columns) { + if (end_col == grid->Columns) { grid->LineWraps[row] = false; } @@ -5886,25 +5885,51 @@ int screen_valid(int doclear) // TODO(utkarshme): Think of a better name, place void win_grid_alloc(win_T *wp, int doclear) { - if (wp->w_grid.ScreenLines == NULL - || wp->w_grid.Rows != wp->w_height - || wp->w_grid.Columns != wp->w_width) { - grid_alloc(&wp->w_grid, wp->w_height, wp->w_width, doclear); + ScreenGrid *grid = &wp->w_grid; + int rows = grid->internal_rows; + int columns = grid->internal_columns; + int was_resized = 0; - // only assign a grid handle if not already - if (wp->w_grid.handle == 0) { - wp->w_grid.handle = ++last_handle; - } + if (rows == 0) { + rows = wp->w_height; + } + if (columns == 0) { + columns = wp->w_width; + } + + if (grid->ScreenLines == NULL + || grid->Rows != rows + || grid->Columns != columns) { + grid_alloc(grid, rows, columns, doclear); + win_free_lsize(wp); + win_alloc_lines(wp); + was_resized = true; + } + + grid->OffsetRow = wp->w_winrow; + grid->OffsetColumn = wp->w_wincol; - wp->w_grid.OffsetRow = wp->w_winrow; - wp->w_grid.OffsetColumn = wp->w_wincol; + grid_assign_handle(grid); - wp->w_grid.was_resized = true; + // send grid resize event if: + // - a grid was just resized + // - screen_resize was called and all grid sizes must be sent + // - the UI wants multigrid event (necessary) + if ((send_grid_resize || was_resized) + && ui_is_external(kUIMultigrid)) { + ui_call_grid_resize(grid->handle, grid->Columns, grid->Rows); + was_resized = false; } +} + +/// assign a handle to the grid. The grid need not be allocated. +void grid_assign_handle(ScreenGrid *grid) +{ + static int last_grid_handle = DEFAULT_GRID_HANDLE; - if (send_grid_resize || wp->w_grid.was_resized) { - ui_call_grid_resize(wp->w_grid.handle, wp->w_grid.Columns, wp->w_grid.Rows); - wp->w_grid.was_resized = false; + // only assign a grid handle if not already + if (grid->handle == 0) { + grid->handle = ++last_grid_handle; } } @@ -5999,7 +6024,7 @@ retry: default_grid.OffsetRow = 0; default_grid.OffsetColumn = 0; - default_grid.handle = 1; + default_grid.handle = DEFAULT_GRID_HANDLE; must_redraw = CLEAR; /* need to clear the screen later */ if (doclear) @@ -6170,7 +6195,7 @@ void setcursor(void) if (curwin->w_p_rl) { // With 'rightleft' set and the cursor on a double-wide character, // position it on the leftmost column. - left_offset = curwin->w_width - curwin->w_wcol + left_offset = curwin->w_grid.Columns - curwin->w_wcol - ((utf_ptr2cells(get_cursor_pos_ptr()) == 2 && vim_isprintc(gchar_cursor())) ? 2 : 1); } @@ -6212,10 +6237,10 @@ static int win_do_lines(win_T *wp, int row, int line_count, int del) int retval; if (del) { retval = grid_del_lines(&wp->w_grid, row, line_count, - wp->w_height, 0, wp->w_width); + wp->w_grid.Rows, 0, wp->w_grid.Columns); } else { retval = grid_ins_lines(&wp->w_grid, row, line_count, - wp->w_height, 0, wp->w_width); + wp->w_grid.Rows, 0, wp->w_grid.Columns); } return retval; } @@ -6232,9 +6257,11 @@ static int win_do_lines(win_T *wp, int row, int line_count, int del) /// insert lines on the screen and update ScreenLines[] +/// 'line_count' is the number of lines to be inserted. /// '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. +/// 'col' is the column from with we start inserting. +// +/// 'row', 'col' and 'end' are relative to the start of the region. /// /// @return FAIL for failure, OK for success. int grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, @@ -6915,7 +6942,7 @@ static void win_redr_ruler(win_T *wp, int always) int off; if (wp->w_status_height) { - row = wp->w_winrow + wp->w_height; + row = W_ENDROW(wp); fillchar = fillchar_status(&attr, wp); off = wp->w_wincol; width = wp->w_width; @@ -7168,3 +7195,13 @@ void win_new_shellsize(void) shell_new_columns(); // update window sizes } } + +win_T * get_win_by_grid_handle(GridHandle handle) +{ + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + if (wp->w_grid.handle == handle) { + return wp; + } + } + return NULL; +} diff --git a/src/nvim/search.c b/src/nvim/search.c index f31ec7170b..e6243ad5ba 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -2167,7 +2167,7 @@ showmatch( getvcol(curwin, lpos, NULL, &vcol, NULL); } if (curwin->w_p_wrap || (vcol >= curwin->w_leftcol - && vcol < curwin->w_leftcol + curwin->w_width)) { + && vcol < curwin->w_leftcol + curwin->w_grid.Columns)) { mpos = *lpos; /* save the pos, update_screen() may change it */ save_cursor = curwin->w_cursor; save_so = p_so; diff --git a/src/nvim/types.h b/src/nvim/types.h index aa83bc04bf..aa4332fad1 100644 --- a/src/nvim/types.h +++ b/src/nvim/types.h @@ -40,7 +40,9 @@ typedef struct { int OffsetRow; int OffsetColumn; - int was_resized; + // the size expected to be allocated to the internal grid + int internal_rows; + int internal_columns; } ScreenGrid; #endif // NVIM_TYPES_H diff --git a/src/nvim/ui.c b/src/nvim/ui.c index a454afad24..968c3b7b16 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -57,7 +57,7 @@ static int busy = 0; static int mode_idx = SHAPE_IDX_N; static bool pending_mode_info_update = false; static bool pending_mode_update = false; -static GridHandle cursor_grid_handle = 1; +static GridHandle cursor_grid_handle = DEFAULT_GRID_HANDLE; #if MIN_LOG_LEVEL > DEBUG_LOG_LEVEL # define UI_LOG(funname, ...) @@ -197,13 +197,6 @@ void ui_refresh(void) row = col = 0; pending_cursor_update = true; - ui_default_colors_set(); - - int save_p_lz = p_lz; - p_lz = false; // convince redrawing() to return true ... - screen_resize(width, height); - p_lz = save_p_lz; - for (UIExtension i = 0; (int)i < kUIExtCount; i++) { ui_ext[i] = ext_widgets[i]; if (i < kUIGlobalCount) { @@ -211,6 +204,14 @@ void ui_refresh(void) BOOLEAN_OBJ(ext_widgets[i])); } } + + ui_default_colors_set(); + + int save_p_lz = p_lz; + p_lz = false; // convince redrawing() to return true ... + screen_resize(width, height); + p_lz = save_p_lz; + ui_mode_info_set(); pending_mode_update = true; ui_cursor_shape(); @@ -437,3 +438,18 @@ Array ui_array(void) } return all_uis; } + +void ui_grid_resize(GridHandle grid_handle, int width, int height) +{ + win_T *wp = get_win_by_grid_handle(grid_handle); + + if (wp == NULL) { + //TODO(utkarshme): error out + abort(); + return; + } + + wp->w_grid.internal_rows = (int)height; + wp->w_grid.internal_columns = (int)width; + redraw_win_later(wp, SOME_VALID); +} diff --git a/src/nvim/window.c b/src/nvim/window.c index 4d2b238b7a..5153bfadda 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -3860,6 +3860,8 @@ static win_T *win_alloc(win_T *after, int hidden) new_wp->handle = ++last_win_id; handle_register_window(new_wp); + grid_assign_handle(&new_wp->w_grid); + // Init w: variables. new_wp->w_vars = tv_dict_alloc(); init_var_dict(new_wp->w_vars, &new_wp->w_winvar, VAR_SCOPE); @@ -4087,8 +4089,8 @@ static void frame_remove(frame_T *frp) void win_alloc_lines(win_T *wp) { wp->w_lines_valid = 0; - assert(Rows >= 0); - wp->w_lines = xcalloc(Rows, sizeof(wline_T)); + assert(wp->w_grid.Rows >= 0); + wp->w_lines = xcalloc(wp->w_grid.Rows + 1, sizeof(wline_T)); } /* -- cgit From d5754eae020d672b4f6c62b636a56e0d6d56b4dc Mon Sep 17 00:00:00 2001 From: Utkarsh Maheshwari Date: Fri, 15 Jun 2018 02:41:59 +0530 Subject: multigrid: Add win_position event Throttle win_position events --- src/nvim/api/ui_events.in.h | 3 +++ src/nvim/buffer_defs.h | 1 + src/nvim/ui.c | 1 + src/nvim/window.c | 30 ++++++++++++++++++++++++++++++ 4 files changed, 35 insertions(+) (limited to 'src') diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h index 5c48cb4804..8870f39721 100644 --- a/src/nvim/api/ui_events.in.h +++ b/src/nvim/api/ui_events.in.h @@ -83,6 +83,9 @@ void grid_scroll(Integer grid, Integer top, Integer bot, FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL; void grid_destroy(Integer grid) FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; +void win_position(Integer win, Integer grid, Integer startrow, + Integer startcol, Integer width, Integer height) + FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY; void popupmenu_show(Array items, Integer selected, Integer row, Integer col) FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 01f3044332..ce83c4561d 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -1184,6 +1184,7 @@ struct window_S { int w_tagstacklen; /* number of tags on stack */ ScreenGrid w_grid; // the grid specific to the window + bool w_pos_changed; // true if window position changed /* * w_fraction is the fractional row of the cursor within the window, from diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 968c3b7b16..24557c5d0b 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -377,6 +377,7 @@ int ui_current_col(void) void ui_flush(void) { cmdline_ui_flush(); + win_ui_flush(); if (pending_cursor_update) { ui_call_grid_cursor_goto(cursor_grid_handle, row, col); pending_cursor_update = false; diff --git a/src/nvim/window.c b/src/nvim/window.c index 5153bfadda..ba44d7334f 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -997,6 +997,9 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) p_wh = i; } + // Send the window positions to the UI + oldwin->w_pos_changed = true; + return OK; } @@ -1341,6 +1344,9 @@ static void win_rotate(int upwards, int count) (void)win_comp_pos(); } + wp1->w_pos_changed = true; + wp2->w_pos_changed = true; + redraw_all_later(NOT_VALID); } @@ -1423,6 +1429,9 @@ void win_move_after(win_T *win1, win_T *win2) redraw_later(NOT_VALID); } win_enter(win1, false); + + win1->w_pos_changed = true; + win2->w_pos_changed = true; } /* @@ -2059,6 +2068,7 @@ int win_close(win_T *win, bool free_buf) if (help_window) restore_snapshot(SNAP_HELP_IDX, close_curwin); + curwin->w_pos_changed = true; redraw_all_later(NOT_VALID); return OK; } @@ -4221,6 +4231,7 @@ static void frame_comp_pos(frame_T *topfrp, int *row, int *col) wp->w_wincol = *col; redraw_win_later(wp, NOT_VALID); wp->w_redr_status = TRUE; + wp->w_pos_changed = true; } *row += wp->w_height + wp->w_status_height; *col += wp->w_width + wp->w_vsep_width; @@ -4886,6 +4897,8 @@ void win_new_height(win_T *wp, int height) if (!exiting) { scroll_to_fraction(wp, prev_height); } + + wp->w_pos_changed = true; } void scroll_to_fraction(win_T *wp, int prev_height) @@ -5016,6 +5029,7 @@ void win_new_width(win_T *wp, int width) 0); } } + wp->w_pos_changed = true; } void win_comp_scroll(win_T *wp) @@ -6051,3 +6065,19 @@ void win_findbuf(typval_T *argvars, list_T *list) } } } + +void win_ui_flush(void) +{ + if (!ui_is_external(kUIMultigrid)) { + return; + } + + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + if(wp->w_pos_changed && wp->w_grid.ScreenLines != NULL) { + ui_call_win_position(wp->handle, wp->w_grid.handle, wp->w_winrow, + wp->w_wincol, wp->w_width, wp->w_height); + wp->w_pos_changed = false; + } + } + +} -- cgit From 0432e1586ef0f9dd5e473cee07787ed5bb880570 Mon Sep 17 00:00:00 2001 From: Utkarsh Maheshwari Date: Tue, 19 Jun 2018 11:45:10 +0530 Subject: multigrid: Put everything on default_grid if not ext_multigrid --- src/nvim/api/ui.c | 4 +-- src/nvim/globals.h | 2 ++ src/nvim/screen.c | 96 ++++++++++++++++++++++++++++++++++++++++-------------- src/nvim/ui.c | 11 ++++--- 4 files changed, 82 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 18befd498f..4f56371633 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -257,9 +257,7 @@ void nvim_ui_try_resize_grid(uint64_t channel_id, Integer grid, Integer width, return; } - // TODO(utkarshme): Check if grid exists - - ui_grid_resize((GridHandle)grid, (int)width, (int)height); + ui_grid_resize((GridHandle)grid, (int)width, (int)height, error); } /// Pushes data into UI.UIData, to be consumed later by remote_ui_flush(). diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 57d14d650c..7e17136528 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -164,6 +164,8 @@ EXTERN int screen_Columns INIT(= 0); /* actual size of ScreenLines[] */ EXTERN ScreenGrid default_grid INIT(= { 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0 }); +#define DEFAULT_GRID_HANDLE 1 /* handle for the default_grid */ + /* * When vgetc() is called, it sets mod_mask to the set of modifiers that are * held down based on the MOD_MASK_* symbols that are read first. diff --git a/src/nvim/screen.c b/src/nvim/screen.c index f247aa707d..c248977df5 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -118,11 +118,11 @@ #define MB_FILLER_CHAR '<' /* character used when a double-width character * doesn't fit. */ +#define W_ENDCOL(wp) (wp->w_wincol + wp->w_width) +#define W_ENDROW(wp) (wp->w_winrow + wp->w_height) -#define W_ENDCOL(wp) (wp->w_width + wp->w_wincol) -#define W_ENDROW(wp) (wp->w_height + wp->w_winrow) - -#define DEFAULT_GRID_HANDLE 1 +// Get the offset for the current line buffer when redrawing a line for a grid +#define GRID_TMPLINE(grid) ((grid)->Rows * (grid)->Columns) static match_T search_hl; /* used for 'hlsearch' highlight matching */ @@ -1772,7 +1772,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T * 6. set highlighting for the Visual area an other text */ col = 0; - off = (int)(grid->Rows * grid->Columns); + off = (int)GRID_TMPLINE(grid); /* * 1. Add the cmdwin_type for the command-line window @@ -2674,7 +2674,7 @@ win_line ( cur = cur->next; } - off = (unsigned)(grid->Rows * grid->Columns); + off = (unsigned)GRID_TMPLINE(grid); int col = 0; // Visual column on screen. if (wp->w_p_rl) { // Rightleft window: process the text in the normal direction, but put @@ -4274,7 +4274,7 @@ win_line ( } col = 0; - off = (unsigned)(grid->Rows * grid->Columns); + off = (unsigned)GRID_TMPLINE(grid); if (wp->w_p_rl) { col = grid->Columns - 1; /* col is not used if breaking! */ off += col; @@ -4366,7 +4366,20 @@ static void grid_move_line(ScreenGrid *grid, int row, int coloff, int endcol, if (endcol > grid->Columns) endcol = grid->Columns; - off_from = (unsigned)(grid->Rows * grid->Columns); + // If UI is not externalized, merge the contents of global and window grids + if (!ui_is_external(kUIMultigrid) && grid != &default_grid) { + row += grid->OffsetRow; + coloff += grid->OffsetColumn; + memcpy(default_grid.ScreenLines + GRID_TMPLINE(&default_grid), + grid->ScreenLines + GRID_TMPLINE(grid), + sizeof(schar_T) * grid->Columns); + memcpy(default_grid.ScreenAttrs + GRID_TMPLINE(&default_grid), + grid->ScreenAttrs + GRID_TMPLINE(grid), + sizeof(sattr_T) * grid->Columns); + grid = &default_grid; + } + + off_from = (unsigned)GRID_TMPLINE(grid); off_to = grid->LineOffset[row] + coloff; max_off_from = off_from + grid->Columns; max_off_to = grid->LineOffset[row] + grid->Columns; @@ -4460,21 +4473,22 @@ static void grid_move_line(ScreenGrid *grid, int row, int coloff, int endcol, // blank out the rest of the line // TODO(bfredl): we could cache winline widths while (col < clear_width) { - if (grid->ScreenLines[off_to][0] != ' ' || grid->ScreenLines[off_to][1] != NUL - || grid->ScreenAttrs[off_to] != bg_attr) { - grid->ScreenLines[off_to][0] = ' '; - grid->ScreenLines[off_to][1] = NUL; - grid->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; + if (grid->ScreenLines[off_to][0] != ' ' + || grid->ScreenLines[off_to][1] != NUL + || grid->ScreenAttrs[off_to] != bg_attr) { + grid->ScreenLines[off_to][0] = ' '; + grid->ScreenLines[off_to][1] = NUL; + grid->ScreenAttrs[off_to] = bg_attr; + if (start_dirty == -1) { + start_dirty = col; + end_dirty = col; + } else if (clear_end == -1) { + end_dirty = endcol; } - col++; - off_to++; + clear_end = col+1; + } + col++; + off_to++; } } @@ -5111,7 +5125,7 @@ win_redr_custom ( *wp->w_p_stl == NUL ? 0 : OPT_LOCAL); } - col += wp->w_winrow; + col += wp->w_wincol; } if (maxwidth <= 0) @@ -5258,7 +5272,9 @@ void grid_getbytes(ScreenGrid *grid, int row, int col, char_u *bytes, { unsigned off; - if (grid == NULL) { + if (!ui_is_external(kUIMultigrid)) { + row += grid->OffsetRow; + col += grid->OffsetColumn; grid = &default_grid; } @@ -5321,6 +5337,13 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, grid = &default_grid; } + // If UI is not externalized, keep working on the default grid + if (!ui_is_external(kUIMultigrid) && grid != &default_grid) { + row += grid->OffsetRow; + col += grid->OffsetColumn; + grid = &default_grid; + } + // safety check if (grid->ScreenLines == NULL || row >= grid->Rows || col >= grid->Columns) { return; @@ -5777,6 +5800,15 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, grid = &default_grid; } + // if grids are not externalized, keep working on the default_grid + if (!ui_is_external(kUIMultigrid) && grid != &default_grid) { + start_row += grid->OffsetRow; + end_row += grid->OffsetRow; + start_col += grid->OffsetColumn; + end_col += grid->OffsetColumn; + grid = &default_grid; + } + if (end_row > grid->Rows) // safety check end_row = grid->Rows; if (end_col > grid->Columns) // safety check @@ -6275,6 +6307,14 @@ int grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, grid = &default_grid; } + // If UI is not externalized, keep working on default grid + if (!ui_is_external(kUIMultigrid) && grid != &default_grid) { + row += grid->OffsetRow; + end += grid->OffsetRow; + col += grid->OffsetColumn; + grid = &default_grid; + } + if (!screen_valid(TRUE) || line_count <= 0) { return FAIL; } @@ -6326,6 +6366,14 @@ int grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, grid = &default_grid; } + // If UI is not externalized, keep working on default grid + if (!ui_is_external(kUIMultigrid) && grid != &default_grid) { + row += grid->OffsetRow; + end += grid->OffsetRow; + col += grid->OffsetColumn; + grid = &default_grid; + } + if (!screen_valid(TRUE) || line_count <= 0) { return FAIL; } diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 24557c5d0b..74814bf0ae 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -440,13 +440,16 @@ Array ui_array(void) return all_uis; } -void ui_grid_resize(GridHandle grid_handle, int width, int height) +void ui_grid_resize(GridHandle grid_handle, int width, int height, Error *error) { - win_T *wp = get_win_by_grid_handle(grid_handle); + if (grid_handle == DEFAULT_GRID_HANDLE) { + screen_resize(width, height); + return; + } + win_T *wp = get_win_by_grid_handle(grid_handle); if (wp == NULL) { - //TODO(utkarshme): error out - abort(); + api_set_error(error, kErrorTypeValidation, "No window with the given handle"); return; } -- cgit From 911b731378954dd0fa0448cc02b95d576cdfc3c5 Mon Sep 17 00:00:00 2001 From: Utkarsh Maheshwari Date: Fri, 17 Aug 2018 17:40:04 +0530 Subject: multigrid: Get rid of global ScreenLines and set_screengrid --- src/nvim/api/vim.c | 10 +++++----- src/nvim/edit.c | 2 +- src/nvim/eval.c | 14 +++++++------- src/nvim/globals.h | 17 ++++++----------- src/nvim/highlight.c | 6 +++--- src/nvim/mbyte.c | 11 ++++++----- src/nvim/mouse.c | 5 +++-- src/nvim/screen.c | 37 ++++++++++++------------------------- 8 files changed, 43 insertions(+), 59 deletions(-) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index ecfff1ea8f..82a61b43bd 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1920,13 +1920,13 @@ Object nvim_get_proc(Integer pid, Error *err) Array nvim__inspect_cell(Integer row, Integer col, Error *err) { Array ret = ARRAY_DICT_INIT; - if (row < 0 || row >= screen_Rows - || col < 0 || col >= screen_Columns) { + if (row < 0 || row >= default_grid.Rows + || col < 0 || col >= default_grid.Columns) { return ret; } - size_t off = LineOffset[(size_t)row] + (size_t)col; - ADD(ret, STRING_OBJ(cstr_to_string((char *)ScreenLines[off]))); - int attr = ScreenAttrs[off]; + size_t off = default_grid.LineOffset[(size_t)row] + (size_t)col; + ADD(ret, STRING_OBJ(cstr_to_string((char *)default_grid.ScreenLines[off]))); + int attr = default_grid.ScreenAttrs[off]; ADD(ret, DICTIONARY_OBJ(hl_get_attr_by_id(attr, true, err))); // will not work first time if (!highlight_use_hlstate()) { diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 14577d5abb..0cc64f6965 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -1494,7 +1494,7 @@ void edit_putchar(int c, int highlight) { int attr; - if (ScreenLines != NULL) { + if (default_grid.ScreenLines != NULL) { update_topline(); /* just in case w_topline isn't valid */ validate_cursor(); if (highlight) { diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 6fe62f1a87..957a8c4ef1 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -14023,11 +14023,11 @@ static void f_screenattr(typval_T *argvars, typval_T *rettv, FunPtr fptr) const int row = (int)tv_get_number_chk(&argvars[0], NULL) - 1; const int col = (int)tv_get_number_chk(&argvars[1], NULL) - 1; - if (row < 0 || row >= screen_Rows - || col < 0 || col >= screen_Columns) { + if (row < 0 || row >= default_grid.Rows + || col < 0 || col >= default_grid.Columns) { c = -1; } else { - c = ScreenAttrs[LineOffset[row] + col]; + c = default_grid.ScreenAttrs[default_grid.LineOffset[row] + col]; } rettv->vval.v_number = c; } @@ -14042,12 +14042,12 @@ static void f_screenchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) const int row = tv_get_number_chk(&argvars[0], NULL) - 1; const int col = tv_get_number_chk(&argvars[1], NULL) - 1; - if (row < 0 || row >= screen_Rows - || col < 0 || col >= screen_Columns) { + if (row < 0 || row >= default_grid.Rows + || col < 0 || col >= default_grid.Columns) { c = -1; } else { - off = LineOffset[row] + col; - c = utf_ptr2char(ScreenLines[off]); + off = default_grid.LineOffset[row] + col; + c = utf_ptr2char(default_grid.ScreenLines[off]); } rettv->vval.v_number = c; } diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 7e17136528..317ae8f41a 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -91,9 +91,10 @@ EXTERN struct nvim_stats_s { /* * Number of Rows and Columns in the screen. * Must be long to be able to use them as options in option.c. - * Note: Use screen_Rows and screen_Columns to access items in ScreenLines[]. - * They may have different values when the screen wasn't (re)allocated yet - * after setting Rows or Columns (e.g., when starting up). + * Note: Use default_grid.Rows and default_grid.Columns to access items in + * default_grid.ScreenLines[]. They may have different values when the screen + * wasn't (re)allocated yet after setting Rows or Columns (e.g., when starting + * up). */ #define DFLT_COLS 80 // default value for 'columns' #define DFLT_ROWS 24 // default value for 'lines' @@ -150,17 +151,11 @@ typedef off_t off_T; /// to the next line. It can only be true if a window occupies the entire screen /// width. /// +/// These, with other related attributes, are stored in a "ScreenGrid" +/// datastructure. /// /// Note: before the screen is initialized and when out of memory these can be /// NULL. -EXTERN schar_T *ScreenLines INIT(= NULL); -EXTERN sattr_T *ScreenAttrs INIT(= NULL); -EXTERN unsigned *LineOffset INIT(= NULL); -EXTERN char_u *LineWraps INIT(= NULL); /* line wraps to next line */ - -EXTERN int screen_Rows INIT(= 0); /* actual size of ScreenLines[] */ -EXTERN int screen_Columns INIT(= 0); /* actual size of ScreenLines[] */ - EXTERN ScreenGrid default_grid INIT(= { 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0 }); diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c index 5a9727f46e..cbc230b65a 100644 --- a/src/nvim/highlight.c +++ b/src/nvim/highlight.c @@ -213,11 +213,11 @@ void clear_hl_tables(bool reinit) highlight_attr_set_all(); highlight_changed(); redraw_all_later(NOT_VALID); - if (ScreenAttrs) { + if (default_grid.ScreenAttrs) { // the meaning of 0 doesn't change anyway // but the rest must be retransmitted - memset(ScreenAttrs, 0, - sizeof(*ScreenAttrs) * (size_t)(screen_Rows * screen_Columns)); + memset(default_grid.ScreenAttrs, 0, sizeof(*default_grid.ScreenAttrs) + * (size_t)(default_grid.Rows * default_grid.Columns)); } } else { kv_destroy(attr_entries); diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index 0ee8e2bd85..c0c36717e2 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -560,7 +560,8 @@ size_t mb_string2cells(const char_u *str) /// We make sure that the offset used is less than "max_off". int utf_off2cells(unsigned off, unsigned max_off) { - return (off + 1 < max_off && ScreenLines[off + 1][0] == 0) ? 2 : 1; + return (off + 1 < max_off + && default_grid.ScreenLines[off + 1][0] == 0) ? 2 : 1; } /// Convert a UTF-8 byte sequence to a wide character @@ -1829,8 +1830,8 @@ const char *mb_unescape(const char **const pp) */ bool mb_lefthalve(int row, int col) { - return utf_off2cells(LineOffset[row] + col, - LineOffset[row] + screen_Columns) > 1; + return utf_off2cells(default_grid.LineOffset[row] + col, + default_grid.LineOffset[row] + screen_Columns) > 1; } /* @@ -1841,8 +1842,8 @@ int mb_fix_col(int col, int row) { col = check_col(col); row = check_row(row); - if (ScreenLines != NULL && col > 0 - && ScreenLines[LineOffset[row] + col][0] == 0) { + if (default_grid.ScreenLines != NULL && col > 0 + && default_grid.ScreenLines[default_grid.LineOffset[row] + col][0] == 0) { return col - 1; } return col; diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 3c792326a4..bd19f54b3d 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -110,8 +110,9 @@ retnomove: // Remember the character under the mouse, it might be a '-' or '+' in the // fold column. NB: only works for ASCII chars! if (row >= 0 && row < Rows && col >= 0 && col <= Columns - && ScreenLines != NULL) { - mouse_char = ScreenLines[LineOffset[row] + (unsigned)col][0]; + && default_grid.ScreenLines != NULL) { + mouse_char = default_grid.ScreenLines[default_grid.LineOffset[row] + + (unsigned)col][0]; } else { mouse_char = ' '; } diff --git a/src/nvim/screen.c b/src/nvim/screen.c index c248977df5..f00fe5d338 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2021,8 +2021,8 @@ static void copy_text_attr(int off, char_u *buf, int len, int attr) int i; for (i = 0; i < len; i++) { - schar_from_ascii(ScreenLines[off + i], buf[i]); - ScreenAttrs[off + i] = attr; + schar_from_ascii(default_grid.ScreenLines[off + i], buf[i]); + default_grid.ScreenAttrs[off + i] = attr; } } @@ -5967,13 +5967,14 @@ void grid_assign_handle(ScreenGrid *grid) /* * Resize the shell to Rows and Columns. - * Allocate ScreenLines[] and associated items. + * Allocate default_grid.ScreenLines[] and associated items. * * There may be some time between setting Rows and Columns and (re)allocating - * ScreenLines[]. This happens when starting up and when (manually) changing - * the shell size. Always use screen_Rows and screen_Columns to access items - * in ScreenLines[]. Use Rows and Columns for positioning text etc. where the - * final size of the shell is needed. + * default_grid.ScreenLines[]. This happens when starting up and when + * (manually) changing the shell size. Always use default_grid.Rows and + * default_grid.Columns to access items in default_grid.ScreenLines[]. Use Rows + * and Columns for positioning text etc. where the final size of the shell is + * needed. */ void screenalloc(bool doclear) { @@ -6044,16 +6045,9 @@ retry: clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size); xfree(tab_page_click_defs); - set_screengrid(&default_grid); - tab_page_click_defs = new_tab_page_click_defs; tab_page_click_defs_size = default_grid.Columns; - /* It's important that screen_Rows and screen_Columns reflect the actual - * size of ScreenLines[]. Set them before calling anything. */ - screen_Rows = default_grid.Rows; - screen_Columns = default_grid.Columns; - default_grid.OffsetRow = 0; default_grid.OffsetColumn = 0; default_grid.handle = DEFAULT_GRID_HANDLE; @@ -6129,14 +6123,6 @@ void free_screengrid(ScreenGrid *grid) xfree(grid->LineWraps); } -void set_screengrid(ScreenGrid *grid) -{ - ScreenLines = grid->ScreenLines; - ScreenAttrs = grid->ScreenAttrs; - LineOffset = grid->LineOffset; - LineWraps = grid->LineWraps; -} - /// Clear tab_page_click_defs table /// /// @param[out] tpcd Table to clear. @@ -6165,14 +6151,15 @@ static void screenclear2(void) { int i; - if (starting == NO_SCREEN || ScreenLines == NULL) { + if (starting == NO_SCREEN || default_grid.ScreenLines == NULL) { return; } /* blank out ScreenLines */ for (i = 0; i < default_grid.Rows; ++i) { - grid_clear_line(&default_grid, LineOffset[i], (int)default_grid.Columns, true); - LineWraps[i] = FALSE; + grid_clear_line(&default_grid, default_grid.LineOffset[i], + (int)default_grid.Columns, true); + default_grid.LineWraps[i] = FALSE; } ui_call_grid_clear(1); // clear the display -- cgit From 0bab611a96bff90fb9fab99ca3fdd6bad77fe1be Mon Sep 17 00:00:00 2001 From: Utkarsh Maheshwari Date: Fri, 17 Aug 2018 18:41:52 +0530 Subject: multigrid: Add ScreenGrid as a param to multibyte functions --- src/nvim/edit.c | 4 ++-- src/nvim/mbyte.c | 32 ++++++++++++++++---------------- src/nvim/screen.c | 24 ++++++++++++------------ 3 files changed, 30 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 0cc64f6965..3558bdea06 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -1508,7 +1508,7 @@ void edit_putchar(int c, int highlight) if (curwin->w_p_rl) { pc_col += curwin->w_grid.Columns - 1 - curwin->w_wcol; if (has_mbyte) { - int fix_col = mb_fix_col(pc_col, pc_row); + int fix_col = mb_fix_col(&curwin->w_grid, pc_col, pc_row); if (fix_col != pc_col) { grid_putchar(&curwin->w_grid, ' ', pc_row, fix_col, attr); @@ -1518,7 +1518,7 @@ void edit_putchar(int c, int highlight) } } else { pc_col += curwin->w_wcol; - if (mb_lefthalve(pc_row, pc_col)) + if (mb_lefthalve(&curwin->w_grid, pc_row, pc_col)) pc_status = PC_STATUS_LEFT; } diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index c0c36717e2..775e5b24fc 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -558,10 +558,10 @@ size_t mb_string2cells(const char_u *str) /// Return number of display cells for char at ScreenLines[off]. /// We make sure that the offset used is less than "max_off". -int utf_off2cells(unsigned off, unsigned max_off) +int utf_off2cells(ScreenGrid *grid, unsigned off, unsigned max_off) { return (off + 1 < max_off - && default_grid.ScreenLines[off + 1][0] == 0) ? 2 : 1; + && grid->ScreenLines[off + 1][0] == 0) ? 2 : 1; } /// Convert a UTF-8 byte sequence to a wide character @@ -1828,22 +1828,22 @@ const char *mb_unescape(const char **const pp) * of a double-width character. * Caller must make sure "row" and "col" are not invalid! */ -bool mb_lefthalve(int row, int col) +bool mb_lefthalve(ScreenGrid *grid, int row, int col) { - return utf_off2cells(default_grid.LineOffset[row] + col, - default_grid.LineOffset[row] + screen_Columns) > 1; + return utf_off2cells(grid, grid->LineOffset[row] + col, + grid->LineOffset[row] + grid->Columns) > 1; } /* * Correct a position on the screen, if it's the right half of a double-wide * char move it to the left half. Returns the corrected column. */ -int mb_fix_col(int col, int row) +int mb_fix_col(ScreenGrid *grid, int col, int row) { - col = check_col(col); - row = check_row(row); - if (default_grid.ScreenLines != NULL && col > 0 - && default_grid.ScreenLines[default_grid.LineOffset[row] + col][0] == 0) { + col = check_col(grid, col); + row = check_row(grid, row); + if (grid->ScreenLines != NULL && col > 0 + && grid->ScreenLines[grid->LineOffset[row] + col][0] == 0) { return col - 1; } return col; @@ -2527,21 +2527,21 @@ char_u * string_convert_ext(const vimconv_T *const vcp, char_u *ptr, } // Check bounds for column number -static int check_col(int col) +static int check_col(ScreenGrid *grid, int col) { if (col < 0) return 0; - if (col >= screen_Columns) - return screen_Columns - 1; + if (col >= grid->Columns) + return grid->Columns - 1; return col; } // Check bounds for row number -static int check_row(int row) +static int check_row(ScreenGrid *grid, int row) { if (row < 0) return 0; - if (row >= screen_Rows) - return screen_Rows - 1; + if (row >= grid->Rows) + return grid->Rows - 1; return row; } diff --git a/src/nvim/screen.c b/src/nvim/screen.c index f00fe5d338..23853ba13a 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -4323,7 +4323,7 @@ static int grid_char_needs_redraw(ScreenGrid *grid, int off_from, int off_to, return (cols > 0 && ((schar_cmp(grid->ScreenLines[off_from], grid->ScreenLines[off_to]) || grid->ScreenAttrs[off_from] != grid->ScreenAttrs[off_to] - || (utf_off2cells(off_from, off_from + cols) > 1 + || (utf_off2cells(grid, off_from, off_from + cols) > 1 && schar_cmp(grid->ScreenLines[off_from + 1], grid->ScreenLines[off_to + 1]))) || p_wd < 0)); @@ -4417,7 +4417,7 @@ static void grid_move_line(ScreenGrid *grid, int row, int coloff, int endcol, while (col < endcol) { char_cells = 1; if (col + 1 < endcol) { - char_cells = utf_off2cells(off_from, max_off_from); + char_cells = utf_off2cells(grid, off_from, max_off_from); } redraw_this = redraw_next; redraw_next = grid_char_needs_redraw(grid, off_from + char_cells, @@ -4436,10 +4436,10 @@ static void grid_move_line(ScreenGrid *grid, int row, int coloff, int endcol, // char over the left halve of an existing one if (col + char_cells == endcol && ((char_cells == 1 - && utf_off2cells(off_to, max_off_to) > 1) + && utf_off2cells(grid, off_to, max_off_to) > 1) || (char_cells == 2 - && utf_off2cells(off_to, max_off_to) == 1 - && utf_off2cells(off_to + 1, max_off_to) > 1))) { + && utf_off2cells(grid, off_to, max_off_to) == 1 + && utf_off2cells(grid, off_to + 1, max_off_to) > 1))) { clear_next = true; } @@ -5361,7 +5361,7 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, /* When drawing over the right halve of a double-wide char clear out the * left halve. Only needed in a terminal. */ - if (col > 0 && col < grid->Columns && mb_fix_col(col, row) != col) { + if (col > 0 && col < grid->Columns && mb_fix_col(grid, col, row) != col) { schar_from_ascii(grid->ScreenLines[off - 1], ' '); grid->ScreenAttrs[off - 1] = 0; // redraw the previous cell, make it empty @@ -5436,10 +5436,10 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, clear_next_cell = false; } else if ((len < 0 ? ptr[mbyte_blen] == NUL : ptr + mbyte_blen >= text + len) - && ((mbyte_cells == 1 && utf_off2cells(off, max_off) > 1) + && ((mbyte_cells == 1 && utf_off2cells(grid, off, max_off) > 1) || (mbyte_cells == 2 - && utf_off2cells(off, max_off) == 1 - && utf_off2cells(off + 1, max_off) > 1))) { + && utf_off2cells(grid, off, max_off) == 1 + && utf_off2cells(grid, off + 1, max_off) > 1))) { clear_next_cell = true; } @@ -5824,10 +5824,10 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, // out the left halve. When drawing over the left halve of a // double wide-char clear out the right halve. Only needed in a // terminal. - if (start_col > 0 && mb_fix_col(start_col, row) != start_col) { + if (start_col > 0 && mb_fix_col(grid, start_col, row) != start_col) { grid_puts_len(grid, (char_u *)" ", 1, row, start_col - 1, 0); } - if (end_col < grid->Columns && mb_fix_col(end_col, row) != end_col) { + if (end_col < grid->Columns && mb_fix_col(grid, end_col, row) != end_col) { grid_puts_len(grid, (char_u *)" ", 1, row, end_col, 0); } } @@ -7076,7 +7076,7 @@ int number_width(win_T *wp) if (wp->w_p_rnu && !wp->w_p_nu) /* cursor line shows "0" */ - lnum = wp->w_height; + lnum = wp->w_grid.Rows; else /* cursor line shows absolute line number */ lnum = wp->w_buffer->b_ml.ml_line_count; -- cgit From 4f1dcf7c28c941cfe3c8516728b6543ad2854645 Mon Sep 17 00:00:00 2001 From: Utkarsh Maheshwari Date: Sat, 18 Aug 2018 15:39:22 +0530 Subject: multigrid: Clean whole grid when it was just resized --- src/nvim/globals.h | 2 +- src/nvim/screen.c | 20 +++++++++++++------- src/nvim/types.h | 2 ++ 3 files changed, 16 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 317ae8f41a..1a3cf6886d 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -157,7 +157,7 @@ typedef off_t off_T; /// Note: before the screen is initialized and when out of memory these can be /// NULL. EXTERN ScreenGrid default_grid INIT(= { 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0, - 0, 0 }); + 0, 0, 0 }); #define DEFAULT_GRID_HANDLE 1 /* handle for the default_grid */ diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 23853ba13a..dca11fd49e 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -1573,6 +1573,8 @@ static void win_update(win_T *wp) } } + wp->w_grid.was_resized = false; + /* restore got_int, unless CTRL-C was hit while redrawing */ if (!got_int) got_int = save_got_int; @@ -5832,8 +5834,12 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, } } - int dirty_first = INT_MAX; - int dirty_last = 0; + // if grid was resized (in ext_multigrid mode), the UI has no redraw updates + // for the newly resized grid. It is better mark everything as dirty and + // send all the updates. + int dirty_first = grid->was_resized ? start_col : INT_MAX; + int dirty_last = grid->was_resized ? grid->Columns : 0; + int col = start_col; schar_from_char(sc, c1); int lineoff = grid->LineOffset[row]; @@ -5846,7 +5852,9 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, if (dirty_first == INT_MAX) { dirty_first = col; } - dirty_last = col+1; + if (!grid->was_resized) { + dirty_last = col+1; + } } if (col == start_col) { schar_from_char(sc, c2); @@ -5920,7 +5928,6 @@ void win_grid_alloc(win_T *wp, int doclear) ScreenGrid *grid = &wp->w_grid; int rows = grid->internal_rows; int columns = grid->internal_columns; - int was_resized = 0; if (rows == 0) { rows = wp->w_height; @@ -5935,7 +5942,7 @@ void win_grid_alloc(win_T *wp, int doclear) grid_alloc(grid, rows, columns, doclear); win_free_lsize(wp); win_alloc_lines(wp); - was_resized = true; + grid->was_resized = true; } grid->OffsetRow = wp->w_winrow; @@ -5947,10 +5954,9 @@ void win_grid_alloc(win_T *wp, int doclear) // - a grid was just resized // - screen_resize was called and all grid sizes must be sent // - the UI wants multigrid event (necessary) - if ((send_grid_resize || was_resized) + if ((send_grid_resize || grid->was_resized) && ui_is_external(kUIMultigrid)) { ui_call_grid_resize(grid->handle, grid->Columns, grid->Rows); - was_resized = false; } } diff --git a/src/nvim/types.h b/src/nvim/types.h index aa4332fad1..6d39caab50 100644 --- a/src/nvim/types.h +++ b/src/nvim/types.h @@ -43,6 +43,8 @@ typedef struct { // the size expected to be allocated to the internal grid int internal_rows; int internal_columns; + + int was_resized; } ScreenGrid; #endif // NVIM_TYPES_H -- cgit From 1a896bc93f9c54cc8b973feba1963fd6b60a22b7 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sat, 25 Aug 2018 13:23:54 +0200 Subject: multigrid: avoid allocation when not ext_multigrid. Move grid specific functions from mbyte.c to screen.c --- src/nvim/edit.c | 4 +- src/nvim/mbyte.c | 46 ---------- src/nvim/memory.c | 2 +- src/nvim/screen.c | 256 +++++++++++++++++++++++++++++++++++------------------- src/nvim/window.c | 4 +- 5 files changed, 172 insertions(+), 140 deletions(-) (limited to 'src') diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 3558bdea06..768d37bd01 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -1508,7 +1508,7 @@ void edit_putchar(int c, int highlight) if (curwin->w_p_rl) { pc_col += curwin->w_grid.Columns - 1 - curwin->w_wcol; if (has_mbyte) { - int fix_col = mb_fix_col(&curwin->w_grid, pc_col, pc_row); + int fix_col = grid_fix_col(&curwin->w_grid, pc_col, pc_row); if (fix_col != pc_col) { grid_putchar(&curwin->w_grid, ' ', pc_row, fix_col, attr); @@ -1518,7 +1518,7 @@ void edit_putchar(int c, int highlight) } } else { pc_col += curwin->w_wcol; - if (mb_lefthalve(&curwin->w_grid, pc_row, pc_col)) + if (grid_lefthalve(&curwin->w_grid, pc_row, pc_col)) pc_status = PC_STATUS_LEFT; } diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index 775e5b24fc..73748154e7 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -1823,32 +1823,6 @@ const char *mb_unescape(const char **const pp) return NULL; } -/* - * Return true if the character at "row"/"col" on the screen is the left side - * of a double-width character. - * Caller must make sure "row" and "col" are not invalid! - */ -bool mb_lefthalve(ScreenGrid *grid, int row, int col) -{ - return utf_off2cells(grid, grid->LineOffset[row] + col, - grid->LineOffset[row] + grid->Columns) > 1; -} - -/* - * Correct a position on the screen, if it's the right half of a double-wide - * char move it to the left half. Returns the corrected column. - */ -int mb_fix_col(ScreenGrid *grid, int col, int row) -{ - col = check_col(grid, col); - row = check_row(grid, row); - if (grid->ScreenLines != NULL && col > 0 - && grid->ScreenLines[grid->LineOffset[row] + col][0] == 0) { - return col - 1; - } - return col; -} - /* * Skip the Vim specific head of a 'encoding' name. @@ -2525,23 +2499,3 @@ char_u * string_convert_ext(const vimconv_T *const vcp, char_u *ptr, return retval; } - -// Check bounds for column number -static int check_col(ScreenGrid *grid, int col) -{ - if (col < 0) - return 0; - if (col >= grid->Columns) - return grid->Columns - 1; - return col; -} - -// Check bounds for row number -static int check_row(ScreenGrid *grid, int row) -{ - if (row < 0) - return 0; - if (row >= grid->Rows) - return grid->Rows - 1; - return row; -} diff --git a/src/nvim/memory.c b/src/nvim/memory.c index ce914b43f9..d38079ca72 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -699,7 +699,7 @@ void free_all_mem(void) } // free screenlines (can't display anything now!) - free_screengrid(&default_grid); + screen_free_all_mem(); clear_hl_tables(false); list_free_log(); diff --git a/src/nvim/screen.c b/src/nvim/screen.c index dca11fd49e..063363755a 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -121,8 +121,12 @@ #define W_ENDCOL(wp) (wp->w_wincol + wp->w_width) #define W_ENDROW(wp) (wp->w_winrow + wp->w_height) -// Get the offset for the current line buffer when redrawing a line for a grid -#define GRID_TMPLINE(grid) ((grid)->Rows * (grid)->Columns) + +// temporary buffer for rendering a single screenline, so it can be +// comparared with previous contents to calulate smallest delta. +static size_t linebuf_size = 0; +static schar_T *linebuf_char = NULL; +static sattr_T *linebuf_attr = NULL; static match_T search_hl; /* used for 'hlsearch' highlight matching */ @@ -502,7 +506,7 @@ void update_single_line(win_T *wp, linenr_T lnum) int j; // Don't do anything if the screen structures are (not yet) valid. - if (wp->w_grid.ScreenLines == NULL || updating_screen) { + if (linebuf_char == NULL || updating_screen) { return; } updating_screen = true; @@ -516,6 +520,8 @@ void update_single_line(win_T *wp, linenr_T lnum) start_search_hl(); prepare_search_hl(wp, lnum); update_window_hl(wp, false); + // allocate window grid if not already + win_grid_alloc(wp, false); win_line(wp, lnum, row, row + wp->w_lines[j].wl_size, false, false); end_search_hl(); break; @@ -1774,15 +1780,15 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T * 6. set highlighting for the Visual area an other text */ col = 0; - off = (int)GRID_TMPLINE(grid); + off = 0; /* * 1. Add the cmdwin_type for the command-line window * Ignores 'rightleft', this window is never right-left. */ if (cmdwin_type != 0 && wp == curwin) { - schar_from_ascii(grid->ScreenLines[off], cmdwin_type); - grid->ScreenAttrs[off] = win_hl_attr(wp, HLF_AT); + schar_from_ascii(linebuf_char[off], cmdwin_type); + linebuf_attr[off] = win_hl_attr(wp, HLF_AT); col++; } @@ -1798,7 +1804,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T win_hl_attr(wp, HLF_FC)); // reverse the fold column for (i = 0; i < fdc; i++) { - schar_from_ascii(grid->ScreenLines[off + wp->w_width - i - 1 - col], buf[i]); + schar_from_ascii(linebuf_char[off + wp->w_width - i - 1 - col], buf[i]); } } else { copy_text_attr(off + col, buf, fdc, win_hl_attr(wp, HLF_FC)); @@ -1808,10 +1814,10 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T # define RL_MEMSET(p, v, l) if (wp->w_p_rl) \ for (ri = 0; ri < l; ++ri) \ - grid->ScreenAttrs[off + (wp->w_width - (p) - (l)) + ri] = v; \ + linebuf_attr[off + (wp->w_width - (p) - (l)) + ri] = v; \ else \ for (ri = 0; ri < l; ++ri) \ - grid->ScreenAttrs[off + (p) + ri] = v + linebuf_attr[off + (p) + ri] = v /* Set all attributes of the 'number' or 'relativenumber' column and the * text */ @@ -1877,7 +1883,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T txtcol = col; /* remember where text starts */ - // 5. move the text to grid->ScreenLines[off]. Fill up with "fill_fold". + // 5. move the text to linebuf_char[off]. Fill up with "fill_fold". // Right-left text is put in columns 0 - number-col, normal text is put // in columns number-col - window-width. int idx; @@ -1895,8 +1901,8 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T // if(col + cells > wp->w_width - (wp->w_p_rl ? col : 0)) { break; } // This is obvious wrong. If Vim ever fixes this, solve for "cells" again // in the correct condition. - int maxcells = wp->w_width - col - (wp->w_p_rl ? col : 0); - int cells = line_putchar(&s, &grid->ScreenLines[idx], maxcells, wp->w_p_rl); + int maxcells = grid->Columns - col - (wp->w_p_rl ? col : 0); + int cells = line_putchar(&s, &linebuf_char[idx], maxcells, wp->w_p_rl); if (cells == -1) { break; } @@ -1913,7 +1919,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T while (col < wp->w_width - (wp->w_p_rl ? txtcol : 0) ) { - schar_copy(grid->ScreenLines[off+col++], sc); + schar_copy(linebuf_char[off+col++], sc); } if (text != buf) @@ -1977,8 +1983,8 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T txtcol -= wp->w_leftcol; } if (txtcol >= 0 && txtcol < wp->w_width) { - grid->ScreenAttrs[off + txtcol] = - hl_combine_attr(grid->ScreenAttrs[off + txtcol], win_hl_attr(wp, HLF_MC)); + linebuf_attr[off + txtcol] = + hl_combine_attr(linebuf_attr[off + txtcol], win_hl_attr(wp, HLF_MC)); } txtcol = old_txtcol; j = wp->w_p_cc_cols[++i]; @@ -1992,13 +1998,14 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T txtcol -= wp->w_skipcol; else txtcol -= wp->w_leftcol; - if (txtcol >= 0 && txtcol < wp->w_width) - grid->ScreenAttrs[off + txtcol] = hl_combine_attr( - grid->ScreenAttrs[off + txtcol], win_hl_attr(wp, HLF_CUC)); + if (txtcol >= 0 && txtcol < wp->w_width) { + linebuf_attr[off + txtcol] = hl_combine_attr( + linebuf_attr[off + txtcol], win_hl_attr(wp, HLF_CUC)); + } } - grid_move_line(grid, row, 0, grid->Columns, grid->Columns, false, wp, - wp->w_hl_attr_normal, false); + grid_put_linebuf(grid, row, 0, grid->Columns, grid->Columns, false, wp, + wp->w_hl_attr_normal, false); /* * Update w_cline_height and w_cline_folded if the cursor line was @@ -2023,8 +2030,8 @@ static void copy_text_attr(int off, char_u *buf, int len, int attr) int i; for (i = 0; i < len; i++) { - schar_from_ascii(default_grid.ScreenLines[off + i], buf[i]); - default_grid.ScreenAttrs[off + i] = attr; + schar_from_ascii(linebuf_char[off + i], buf[i]); + linebuf_attr[off + i] = attr; } } @@ -2099,7 +2106,6 @@ win_line ( bool number_only // only update the number column ) { - unsigned off; // offset in ScreenLines/ScreenAttrs int c = 0; // init for GCC long vcol = 0; // virtual column (for tabs) long vcol_sbr = -1; // virtual column after showbreak @@ -2238,9 +2244,6 @@ win_line ( row = startrow; - // allocate window grid if not already - win_grid_alloc(wp, true); - if (!number_only) { // To speed up the loop below, set extra_check when there is linebreak, // trailing white space and/or syntax processing to be done. @@ -2676,11 +2679,11 @@ win_line ( cur = cur->next; } - off = (unsigned)GRID_TMPLINE(grid); + unsigned off = 0; // Offset relative start of line int col = 0; // Visual column on screen. if (wp->w_p_rl) { // Rightleft window: process the text in the normal direction, but put - // it in grid->ScreenLines[off] from right to left. Start at the + // it in linebuf_char[off] from right to left. Start at the // rightmost column of the window. col = grid->Columns - 1; off += col; @@ -2901,8 +2904,8 @@ win_line ( && lnum == wp->w_cursor.lnum && vcol >= (long)wp->w_virtcol && filler_todo <= 0) || (number_only && draw_state > WL_NR)) { - grid_move_line(grid, row, 0, col, -grid->Columns, wp->w_p_rl, wp, - wp->w_hl_attr_normal, false); + grid_put_linebuf(grid, row, 0, col, -grid->Columns, wp->w_p_rl, wp, + wp->w_hl_attr_normal, false); // Pretend we have finished updating the window. Except when // 'cursorcolumn' is set. if (wp->w_p_cuc) { @@ -3846,7 +3849,7 @@ win_line ( col += n; } else { // Add a blank character to highlight. - schar_from_ascii(grid->ScreenLines[off], ' '); + schar_from_ascii(linebuf_char[off], ' '); } if (area_attr == 0) { /* Use attributes from match with highest priority among @@ -3877,7 +3880,7 @@ win_line ( if (wp->w_p_cul && lnum == wp->w_cursor.lnum) { eol_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), eol_attr); } - grid->ScreenAttrs[off] = eol_attr; + linebuf_attr[off] = eol_attr; if (wp->w_p_rl) { --col; --off; @@ -3971,14 +3974,14 @@ win_line ( } } if (*s.p != NUL) { - cells = line_putchar(&s, &grid->ScreenLines[off], grid->Columns - col, + cells = line_putchar(&s, &linebuf_char[off], grid->Columns - col, false); } } delay_virttext = false; if (cells == -1) { - schar_from_ascii(grid->ScreenLines[off], ' '); + schar_from_ascii(linebuf_char[off], ' '); cells = 1; } col += cells * col_stride; @@ -4000,9 +4003,9 @@ win_line ( attr = hl_combine_attr(attr, line_attr); - grid->ScreenAttrs[off] = attr; + linebuf_attr[off] = attr; if (cells == 2) { - grid->ScreenAttrs[off+1] = attr; + linebuf_attr[off+1] = attr; } off += cells * col_stride; @@ -4020,12 +4023,12 @@ win_line ( // terminal buffers may need to highlight beyond the end of the // logical line while (col < grid->Columns) { - schar_from_ascii(grid->ScreenLines[off], ' '); - grid->ScreenAttrs[off++] = term_attrs[vcol++]; + schar_from_ascii(linebuf_char[off], ' '); + linebuf_attr[off++] = term_attrs[vcol++]; col++; } } - grid_move_line(grid, row, 0, col, grid->Columns, wp->w_p_rl, wp, + grid_put_linebuf(grid, row, 0, col, grid->Columns, wp->w_p_rl, wp, wp->w_hl_attr_normal, false); row++; @@ -4106,22 +4109,23 @@ win_line ( --col; } if (mb_utf8) { - schar_from_cc(grid->ScreenLines[off], mb_c, u8cc); + schar_from_cc(linebuf_char[off], mb_c, u8cc); } else { - schar_from_ascii(grid->ScreenLines[off], c); + schar_from_ascii(linebuf_char[off], c); } if (multi_attr) { - grid->ScreenAttrs[off] = multi_attr; + linebuf_attr[off] = multi_attr; multi_attr = 0; - } else - grid->ScreenAttrs[off] = char_attr; + } else { + linebuf_attr[off] = char_attr; + } if (has_mbyte && (*mb_char2cells)(mb_c) > 1) { // Need to fill two screen columns. off++; col++; // UTF-8: Put a 0 in the second screen char. - grid->ScreenLines[off][0] = 0; + linebuf_char[off][0] = 0; if (draw_state > WL_NR && filler_todo <= 0) { vcol++; } @@ -4241,8 +4245,8 @@ win_line ( && row != endrow - 1 // Not the last line being displayed. && grid->Columns == Columns // Window spans the width of the screen. && !wp->w_p_rl; // Not right-to-left. - grid_move_line(grid, row, 0, col - boguscols, grid->Columns, wp->w_p_rl, - wp, wp->w_hl_attr_normal, wrap); + grid_put_linebuf(grid, row, 0, col - boguscols, grid->Columns, wp->w_p_rl, + wp, wp->w_hl_attr_normal, wrap); if (wrap) { // Force a redraw of the first column of the next line. grid->ScreenAttrs[grid->LineOffset[row + 1]] = -1; @@ -4276,7 +4280,7 @@ win_line ( } col = 0; - off = (unsigned)GRID_TMPLINE(grid); + off = 0; if (wp->w_p_rl) { col = grid->Columns - 1; /* col is not used if breaking! */ off += col; @@ -4323,15 +4327,15 @@ static int grid_char_needs_redraw(ScreenGrid *grid, int off_from, int off_to, int cols) { return (cols > 0 - && ((schar_cmp(grid->ScreenLines[off_from], grid->ScreenLines[off_to]) - || grid->ScreenAttrs[off_from] != grid->ScreenAttrs[off_to] - || (utf_off2cells(grid, off_from, off_from + cols) > 1 - && schar_cmp(grid->ScreenLines[off_from + 1], + && ((schar_cmp(linebuf_char[off_from], grid->ScreenLines[off_to]) + || linebuf_attr[off_from] != grid->ScreenAttrs[off_to] + || (line_off2cells(linebuf_char, off_from, off_from + cols) > 1 + && schar_cmp(linebuf_char[off_from + 1], grid->ScreenLines[off_to + 1]))) || p_wd < 0)); } -/// Move one "cooked" line to the window grid, but only the characters that +/// Move one buffered line to the window grid, but only the characters that /// have actually changed. Handle insert/delete character. /// "coloff" gives the first column on the grid for this line. /// "endcol" gives the columns where valid characters are. @@ -4342,9 +4346,9 @@ static int grid_char_needs_redraw(ScreenGrid *grid, int off_from, int off_to, /// When FALSE and "clear_width" > 0, clear columns "endcol" to "clear_width" /// If "wrap" is true, then hint to the UI that "row" contains a line /// which has wrapped into the next row. -static void grid_move_line(ScreenGrid *grid, int row, int coloff, int endcol, - int clear_width, int rlflag, win_T *wp, int bg_attr, - bool wrap) +static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, + int clear_width, int rlflag, win_T *wp, + int bg_attr, bool wrap) { unsigned off_from; unsigned off_to; @@ -4372,18 +4376,12 @@ static void grid_move_line(ScreenGrid *grid, int row, int coloff, int endcol, if (!ui_is_external(kUIMultigrid) && grid != &default_grid) { row += grid->OffsetRow; coloff += grid->OffsetColumn; - memcpy(default_grid.ScreenLines + GRID_TMPLINE(&default_grid), - grid->ScreenLines + GRID_TMPLINE(grid), - sizeof(schar_T) * grid->Columns); - memcpy(default_grid.ScreenAttrs + GRID_TMPLINE(&default_grid), - grid->ScreenAttrs + GRID_TMPLINE(grid), - sizeof(sattr_T) * grid->Columns); grid = &default_grid; } - off_from = (unsigned)GRID_TMPLINE(grid); + off_from = 0; off_to = grid->LineOffset[row] + coloff; - max_off_from = off_from + grid->Columns; + max_off_from = linebuf_size; max_off_to = grid->LineOffset[row] + grid->Columns; if (rlflag) { @@ -4409,8 +4407,8 @@ static void grid_move_line(ScreenGrid *grid, int row, int coloff, int endcol, if (bg_attr) { for (int c = col; c < endcol; c++) { - grid->ScreenAttrs[off_from+c] = - hl_combine_attr(bg_attr, grid->ScreenAttrs[off_from+c]); + linebuf_attr[off_from+c] = + hl_combine_attr(bg_attr, linebuf_attr[off_from+c]); } } @@ -4419,7 +4417,7 @@ static void grid_move_line(ScreenGrid *grid, int row, int coloff, int endcol, while (col < endcol) { char_cells = 1; if (col + 1 < endcol) { - char_cells = utf_off2cells(grid, off_from, max_off_from); + char_cells = line_off2cells(linebuf_char, off_from, max_off_from); } redraw_this = redraw_next; redraw_next = grid_char_needs_redraw(grid, off_from + char_cells, @@ -4438,23 +4436,23 @@ static void grid_move_line(ScreenGrid *grid, int row, int coloff, int endcol, // char over the left halve of an existing one if (col + char_cells == endcol && ((char_cells == 1 - && utf_off2cells(grid, off_to, max_off_to) > 1) + && grid_off2cells(grid, off_to, max_off_to) > 1) || (char_cells == 2 - && utf_off2cells(grid, off_to, max_off_to) == 1 - && utf_off2cells(grid, off_to + 1, max_off_to) > 1))) { + && grid_off2cells(grid, off_to, max_off_to) == 1 + && grid_off2cells(grid, off_to + 1, max_off_to) > 1))) { clear_next = true; } - schar_copy(grid->ScreenLines[off_to], grid->ScreenLines[off_from]); + schar_copy(grid->ScreenLines[off_to], linebuf_char[off_from]); if (char_cells == 2) { - schar_copy(grid->ScreenLines[off_to+1], grid->ScreenLines[off_from+1]); + schar_copy(grid->ScreenLines[off_to+1], linebuf_char[off_from+1]); } - grid->ScreenAttrs[off_to] = grid->ScreenAttrs[off_from]; + grid->ScreenAttrs[off_to] = linebuf_attr[off_from]; // For simplicity set the attributes of second half of a // double-wide character equal to the first half. if (char_cells == 2) { - grid->ScreenAttrs[off_to + 1] = grid->ScreenAttrs[off_from]; + grid->ScreenAttrs[off_to + 1] = linebuf_attr[off_from]; } } @@ -5257,6 +5255,52 @@ static void schar_copy(char_u *sc1, char_u *sc2) STRLCPY(sc1, sc2, sizeof(schar_T)); } +static int line_off2cells(schar_T *line, size_t off, size_t max_off) +{ + return (off + 1 < max_off && line[off + 1][0] == 0) ? 2 : 1; +} + +/// Return number of display cells for char at ScreenLines[off]. +/// We make sure that the offset used is less than "max_off". +static int grid_off2cells(ScreenGrid *grid, size_t off, size_t max_off) +{ + return line_off2cells(grid->ScreenLines, off, max_off); +} + +/// Return true if the character at "row"/"col" on the screen is the left side +/// of a double-width character. +/// +/// Caller must make sure "row" and "col" are not invalid! +bool grid_lefthalve(ScreenGrid *grid, int row, int col) +{ + if (!ui_is_external(kUIMultigrid)) { + row += grid->OffsetRow; + col += grid->OffsetColumn; + grid = &default_grid; + } + + return grid_off2cells(grid, grid->LineOffset[row] + col, + grid->LineOffset[row] + grid->Columns) > 1; +} + +/// Correct a position on the screen, if it's the right half of a double-wide +/// char move it to the left half. Returns the corrected column. +int grid_fix_col(ScreenGrid *grid, int col, int row) +{ + int coloff = 0; + if (!ui_is_external(kUIMultigrid)) { + row += grid->OffsetRow; + coloff = grid->OffsetColumn; + grid = &default_grid; + } + + col += coloff; + if (grid->ScreenLines != NULL && col > 0 + && grid->ScreenLines[grid->LineOffset[row] + col][0] == 0) { + return col - 1 - coloff; + } + return col - coloff; +} /// output a single character directly to the grid and update ScreenLines. void grid_putchar(ScreenGrid *grid, int c, int row, int col, int attr) @@ -5363,7 +5407,7 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, /* When drawing over the right halve of a double-wide char clear out the * left halve. Only needed in a terminal. */ - if (col > 0 && col < grid->Columns && mb_fix_col(grid, col, row) != col) { + if (col > 0 && col < grid->Columns && grid_fix_col(grid, col, row) != col) { schar_from_ascii(grid->ScreenLines[off - 1], ' '); grid->ScreenAttrs[off - 1] = 0; // redraw the previous cell, make it empty @@ -5438,10 +5482,11 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, clear_next_cell = false; } else if ((len < 0 ? ptr[mbyte_blen] == NUL : ptr + mbyte_blen >= text + len) - && ((mbyte_cells == 1 && utf_off2cells(grid, off, max_off) > 1) + && ((mbyte_cells == 1 + && grid_off2cells(grid, off, max_off) > 1) || (mbyte_cells == 2 - && utf_off2cells(grid, off, max_off) == 1 - && utf_off2cells(grid, off + 1, max_off) > 1))) { + && grid_off2cells(grid, off, max_off) == 1 + && grid_off2cells(grid, off + 1, max_off) > 1))) { clear_next_cell = true; } @@ -5826,10 +5871,11 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, // out the left halve. When drawing over the left halve of a // double wide-char clear out the right halve. Only needed in a // terminal. - if (start_col > 0 && mb_fix_col(grid, start_col, row) != start_col) { + if (start_col > 0 && grid_fix_col(grid, start_col, row) != start_col) { grid_puts_len(grid, (char_u *)" ", 1, row, start_col - 1, 0); } - if (end_col < grid->Columns && mb_fix_col(grid, end_col, row) != end_col) { + if (end_col < grid->Columns + && grid_fix_col(grid, end_col, row) != end_col) { grid_puts_len(grid, (char_u *)" ", 1, row, end_col, 0); } } @@ -5936,20 +5982,30 @@ void win_grid_alloc(win_T *wp, int doclear) columns = wp->w_width; } - if (grid->ScreenLines == NULL + // TODO(bfredl): floating windows should force this to true + bool want_allocation = ui_is_external(kUIMultigrid); + bool has_allocation = (grid->ScreenLines != NULL); + + if ((has_allocation != want_allocation) || grid->Rows != rows || grid->Columns != columns) { - grid_alloc(grid, rows, columns, doclear); - win_free_lsize(wp); - win_alloc_lines(wp); + if (want_allocation) { + grid_alloc(grid, rows, columns, !doclear); + win_free_lsize(wp); + win_alloc_lines(wp); + } else { + // Single grid mode, all rendering will be redirected to default_grid. + // Only keep track of the size and offset of the window. + grid_free(grid); + grid->Rows = rows; + grid->Columns = columns; + } grid->was_resized = true; } grid->OffsetRow = wp->w_winrow; grid->OffsetColumn = wp->w_wincol; - grid_assign_handle(grid); - // send grid resize event if: // - a grid was just resized // - screen_resize was called and all grid sizes must be sent @@ -6116,17 +6172,39 @@ void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy) } } } - free_screengrid(grid); + grid_free(grid); *grid = new; -} + // Share a single scratch buffer for all grids, by + // ensuring it is as wide as the widest grid. + if (linebuf_size < (size_t)columns) { + xfree(linebuf_char); + xfree(linebuf_attr); + linebuf_char = xmalloc(columns * sizeof(schar_T)); + linebuf_attr = xmalloc(columns * sizeof(sattr_T)); + linebuf_size = columns; + } +} -void free_screengrid(ScreenGrid *grid) +void grid_free(ScreenGrid *grid) { xfree(grid->ScreenLines); xfree(grid->ScreenAttrs); xfree(grid->LineOffset); xfree(grid->LineWraps); + + grid->ScreenLines = NULL; + grid->ScreenAttrs = NULL; + grid->LineOffset = NULL; + grid->LineWraps = NULL; +} + +/// Doesn't allow reinit, so must only be called by free_all_mem! +void screen_free_all_mem(void) +{ + grid_free(&default_grid); + xfree(linebuf_char); + xfree(linebuf_attr); } /// Clear tab_page_click_defs table diff --git a/src/nvim/window.c b/src/nvim/window.c index ba44d7334f..3d11076a40 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -3990,7 +3990,7 @@ void win_free_grid(win_T *wp, bool reinit) ui_call_grid_destroy(wp->w_grid.handle); wp->w_grid.handle = 0; } - free_screengrid(&wp->w_grid); + grid_free(&wp->w_grid); if (reinit) { // if a float is turned into a split and back into a float, the grid // data structure will be reused @@ -4100,7 +4100,7 @@ void win_alloc_lines(win_T *wp) { wp->w_lines_valid = 0; assert(wp->w_grid.Rows >= 0); - wp->w_lines = xcalloc(wp->w_grid.Rows + 1, sizeof(wline_T)); + wp->w_lines = xcalloc(MAX(wp->w_grid.Rows + 1, Rows), sizeof(wline_T)); } /* -- cgit From 882dd63dc735a7826f6ee0888a404f13f6c7cb80 Mon Sep 17 00:00:00 2001 From: Utkarsh Maheshwari Date: Wed, 5 Sep 2018 00:04:40 +0530 Subject: multigrid: Fix grid allocation misses - Clear whole grid in one go. - Fix wrongly sent "copy" flag. - Add clear function comment. --- src/nvim/screen.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 063363755a..f58dff675e 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -679,7 +679,7 @@ static void win_update(win_T *wp) type = wp->w_redr_type; - win_grid_alloc(wp, false); + win_grid_alloc(wp, true); if (type >= NOT_VALID) { wp->w_redr_status = true; @@ -5966,9 +5966,11 @@ int screen_valid(int doclear) return default_grid.ScreenLines != NULL; } -/// (re)allocate a window grid if size changed -/// If "doclear" is true, clear the screen if resized. -// TODO(utkarshme): Think of a better name, place +/// (Re)allocates a window grid if size changed while in ext_multigrid mode. +/// Updates size, offsets and handle for the grid regardless. +/// +/// If "doclear" is true, don't try to copy from the old grid rather clear the +/// resized grid. void win_grid_alloc(win_T *wp, int doclear) { ScreenGrid *grid = &wp->w_grid; @@ -6151,15 +6153,14 @@ void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy) for (new_row = 0; new_row < new.Rows; new_row++) { new.LineOffset[new_row] = new_row * new.Columns; new.LineWraps[new_row] = false; + + grid_clear_line(&new, 0, columns); + if (copy) { // If the screen is not going to be cleared, copy as much as // possible from the old screen to the new one and clear the rest // (used when resizing the window at the "--more--" prompt or when // executing an external command, for the GUI). - memset(new.ScreenLines + new_row * new.Columns, - ' ', (size_t)new.Columns * sizeof(schar_T)); - memset(new.ScreenAttrs + new_row * new.Columns, - 0, (size_t)new.Columns * sizeof(sattr_T)); old_row = new_row + (grid->Rows - new.Rows); if (old_row >= 0 && grid->ScreenLines != NULL) { int len = MIN(grid->Columns, new.Columns); -- cgit From 16c3337122955c1e18c5ff69dcb14b61c43c4ac0 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sat, 8 Sep 2018 10:35:09 +0200 Subject: multigrid: use grid-based coordinates for ext_popupmenu --- src/nvim/api/ui_events.in.h | 3 ++- src/nvim/popupmnu.c | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h index 8870f39721..308d5aaf02 100644 --- a/src/nvim/api/ui_events.in.h +++ b/src/nvim/api/ui_events.in.h @@ -87,7 +87,8 @@ void win_position(Integer win, Integer grid, Integer startrow, Integer startcol, Integer width, Integer height) FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY; -void popupmenu_show(Array items, Integer selected, Integer row, Integer col) +void popupmenu_show(Array items, Integer selected, + Integer row, Integer col, Integer grid) FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; void popupmenu_hide(void) FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index e9a0c7c6b4..670c794b68 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -68,12 +68,12 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed) int kind_width; int extra_width; int i; - int row; int context_lines; - int col; int above_row; int below_row; int redo_count = 0; + int row; + int col; if (!pum_is_visible) { // To keep the code simple, we only allow changing the @@ -90,13 +90,20 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed) below_row = cmdline_row; // anchor position: the start of the completed word - row = curwin->w_wrow + curwin->w_winrow; + row = curwin->w_wrow; if (curwin->w_p_rl) { - col = curwin->w_wincol + curwin->w_width - curwin->w_wcol - 1; + col = curwin->w_width - curwin->w_wcol - 1; } else { col = curwin->w_wincol + curwin->w_wcol; } + int grid = (int)curwin->w_grid.handle; + if (!ui_is_external(kUIMultigrid)) { + grid = (int)default_grid.handle; + row += curwin->w_winrow; + col += curwin->w_wincol; + } + if (pum_external) { if (array_changed) { Array arr = ARRAY_DICT_INIT; @@ -108,7 +115,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed) ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_info))); ADD(arr, ARRAY_OBJ(item)); } - ui_call_popupmenu_show(arr, selected, row, col); + ui_call_popupmenu_show(arr, selected, row, col, grid); } else { ui_call_popupmenu_select(selected); } -- cgit From 62be9f39ef9cd8592ac0048ba2840aa65cbc1849 Mon Sep 17 00:00:00 2001 From: Utkarsh Maheshwari Date: Tue, 4 Sep 2018 02:45:29 +0530 Subject: multigrid: Fix sending window grid handle in ext_newline mode --- src/nvim/screen.c | 8 +++----- src/nvim/ui.c | 14 ++++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/nvim/screen.c b/src/nvim/screen.c index f58dff675e..945879cd21 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -1579,8 +1579,6 @@ static void win_update(win_T *wp) } } - wp->w_grid.was_resized = false; - /* restore got_int, unless CTRL-C was hit while redrawing */ if (!got_int) got_int = save_got_int; @@ -5976,6 +5974,7 @@ void win_grid_alloc(win_T *wp, int doclear) ScreenGrid *grid = &wp->w_grid; int rows = grid->internal_rows; int columns = grid->internal_columns; + int was_resized = false; if (rows == 0) { rows = wp->w_height; @@ -6002,7 +6001,7 @@ void win_grid_alloc(win_T *wp, int doclear) grid->Rows = rows; grid->Columns = columns; } - grid->was_resized = true; + was_resized = true; } grid->OffsetRow = wp->w_winrow; @@ -6012,8 +6011,7 @@ void win_grid_alloc(win_T *wp, int doclear) // - a grid was just resized // - screen_resize was called and all grid sizes must be sent // - the UI wants multigrid event (necessary) - if ((send_grid_resize || grid->was_resized) - && ui_is_external(kUIMultigrid)) { + if ((send_grid_resize || was_resized) && ui_is_external(kUIMultigrid)) { ui_call_grid_resize(grid->handle, grid->Columns, grid->Rows); } } diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 74814bf0ae..89c0069e58 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -347,15 +347,17 @@ void ui_cursor_goto(int new_row, int new_col) void ui_grid_cursor_goto(ScreenGrid *grid, int new_row, int new_col) { - int off_row = (ui_is_external(kUIMultigrid) ? 0 : grid->OffsetRow); - int off_col = (ui_is_external(kUIMultigrid) ? 0 : grid->OffsetColumn); + new_row += ui_is_external(kUIMultigrid) ? 0 : grid->OffsetRow; + new_col += ui_is_external(kUIMultigrid) ? 0 : grid->OffsetColumn; + int handle = ui_is_external(kUIMultigrid) ? grid->handle : DEFAULT_GRID_HANDLE; - if (new_row + off_row == row && new_col + off_col == col) { + if (new_row == row && new_col == col && handle == cursor_grid_handle) { return; } - row = new_row + off_row; - col = new_col + off_col; - cursor_grid_handle = grid->handle; + + row = new_row; + col = new_col; + cursor_grid_handle = handle; pending_cursor_update = true; } -- cgit From f241930472a58aae69932aa43408a4a974f02278 Mon Sep 17 00:00:00 2001 From: Utkarsh Maheshwari Date: Thu, 13 Sep 2018 14:17:13 +0530 Subject: multigrid: Fix rebase errors in screen.c --- src/nvim/screen.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 945879cd21..d4127b0b02 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -1427,10 +1427,7 @@ static void win_update(win_T *wp) wp->w_lines[idx].wl_lnum = lnum; wp->w_lines[idx].wl_valid = true; - // Past end of the window or end of the screen. Note that after - // resizing wp->w_height may be end up too big. That's a problem - // elsewhere, but prevent a crash here. - if (row > wp->w_grid.Rows || row + wp->w_winrow >= Rows) { + if (row > wp->w_grid.Rows) { // past end of grid // we may need the size of that too long line later on if (dollar_vcol == -1) { wp->w_lines[idx].wl_size = plines_win(wp, lnum, true); @@ -2909,7 +2906,7 @@ win_line ( if (wp->w_p_cuc) { row = wp->w_cline_row + wp->w_cline_height; } else { - row = wp->w_grid.Rows; + row = grid->Rows; } break; } @@ -4246,11 +4243,21 @@ win_line ( grid_put_linebuf(grid, row, 0, col - boguscols, grid->Columns, wp->w_p_rl, wp, wp->w_hl_attr_normal, wrap); if (wrap) { + ScreenGrid *current_grid = grid; + int current_row = row; + + // if we're not in ext_multigrid mode, grid has not been allocated; keep + // working on the default_grid. + if (!ui_is_external(kUIMultigrid)) { + current_row += grid->OffsetRow; + current_grid = &default_grid; + } + // Force a redraw of the first column of the next line. - grid->ScreenAttrs[grid->LineOffset[row + 1]] = -1; + current_grid->ScreenAttrs[current_grid->LineOffset[current_row+1]] = -1; // Remember that the line wraps, used for modeless copy. - grid->LineWraps[row] = true; + current_grid->LineWraps[current_row] = true; } boguscols = 0; -- cgit From 8b47b56fc6216968cc8841503417586a5aba5b31 Mon Sep 17 00:00:00 2001 From: Utkarsh Maheshwari Date: Fri, 14 Sep 2018 20:10:06 +0530 Subject: multigrid: Draw fold for the entire width of window grid --- src/nvim/screen.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/nvim/screen.c b/src/nvim/screen.c index d4127b0b02..4d0ca0ebcb 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -1764,7 +1764,6 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T int txtcol; int off; int ri; - ScreenGrid *grid = &wp->w_grid; /* Build the fold line: * 1. Add the cmdwin_type for the command-line window @@ -1795,11 +1794,11 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T if (wp->w_p_rl) { int i; - copy_text_attr(off + wp->w_width - fdc - col, buf, fdc, + copy_text_attr(off + wp->w_grid.Columns - fdc - col, buf, fdc, win_hl_attr(wp, HLF_FC)); // reverse the fold column for (i = 0; i < fdc; i++) { - schar_from_ascii(linebuf_char[off + wp->w_width - i - 1 - col], buf[i]); + schar_from_ascii(linebuf_char[off + wp->w_grid.Columns - i - 1 - col], buf[i]); } } else { copy_text_attr(off + col, buf, fdc, win_hl_attr(wp, HLF_FC)); @@ -1809,18 +1808,18 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T # define RL_MEMSET(p, v, l) if (wp->w_p_rl) \ for (ri = 0; ri < l; ++ri) \ - linebuf_attr[off + (wp->w_width - (p) - (l)) + ri] = v; \ + linebuf_attr[off + (wp->w_grid.Columns - (p) - (l)) + ri] = v; \ else \ for (ri = 0; ri < l; ++ri) \ linebuf_attr[off + (p) + ri] = v /* Set all attributes of the 'number' or 'relativenumber' column and the * text */ - RL_MEMSET(col, win_hl_attr(wp, HLF_FL), wp->w_width - col); + RL_MEMSET(col, win_hl_attr(wp, HLF_FL), wp->w_grid.Columns - col); // If signs are being displayed, add spaces. if (signcolumn_on(wp)) { - len = wp->w_width - col; + len = wp->w_grid.Columns - col; if (len > 0) { int len_max = win_signcol_width(wp); if (len > len_max) { @@ -1836,7 +1835,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T * 3. Add the 'number' or 'relativenumber' column */ if (wp->w_p_nu || wp->w_p_rnu) { - len = wp->w_width - col; + len = wp->w_grid.Columns - col; if (len > 0) { int w = number_width(wp); long num; @@ -1862,7 +1861,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T snprintf((char *)buf, FOLD_TEXT_LEN, fmt, w, num); if (wp->w_p_rl) { // the line number isn't reversed - copy_text_attr(off + wp->w_width - len - col, buf, len, + copy_text_attr(off + wp->w_grid.Columns - len - col, buf, len, win_hl_attr(wp, HLF_FL)); } else { copy_text_attr(off + col, buf, len, win_hl_attr(wp, HLF_FL)); @@ -1896,7 +1895,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T // if(col + cells > wp->w_width - (wp->w_p_rl ? col : 0)) { break; } // This is obvious wrong. If Vim ever fixes this, solve for "cells" again // in the correct condition. - int maxcells = grid->Columns - col - (wp->w_p_rl ? col : 0); + int maxcells = wp->w_grid.Columns - col - (wp->w_p_rl ? col : 0); int cells = line_putchar(&s, &linebuf_char[idx], maxcells, wp->w_p_rl); if (cells == -1) { break; @@ -1911,7 +1910,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T schar_T sc; schar_from_char(sc, fill_fold); - while (col < wp->w_width + while (col < wp->w_grid.Columns - (wp->w_p_rl ? txtcol : 0) ) { schar_copy(linebuf_char[off+col++], sc); @@ -1947,19 +1946,19 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T FALSE))))))) { if (VIsual_mode == Ctrl_V) { /* Visual block mode: highlight the chars part of the block */ - if (wp->w_old_cursor_fcol + txtcol < (colnr_T)wp->w_width) { + if (wp->w_old_cursor_fcol + txtcol < (colnr_T)wp->w_grid.Columns) { if (wp->w_old_cursor_lcol != MAXCOL && wp->w_old_cursor_lcol + txtcol - < (colnr_T)wp->w_width) + < (colnr_T)wp->w_grid.Columns) len = wp->w_old_cursor_lcol; else - len = wp->w_width - txtcol; + len = wp->w_grid.Columns - txtcol; RL_MEMSET(wp->w_old_cursor_fcol + txtcol, win_hl_attr(wp, HLF_V), len - (int)wp->w_old_cursor_fcol); } } else { // Set all attributes of the text - RL_MEMSET(txtcol, win_hl_attr(wp, HLF_V), wp->w_width - txtcol); + RL_MEMSET(txtcol, win_hl_attr(wp, HLF_V), wp->w_grid.Columns - txtcol); } } } @@ -1977,7 +1976,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T } else { txtcol -= wp->w_leftcol; } - if (txtcol >= 0 && txtcol < wp->w_width) { + if (txtcol >= 0 && txtcol < wp->w_grid.Columns) { linebuf_attr[off + txtcol] = hl_combine_attr(linebuf_attr[off + txtcol], win_hl_attr(wp, HLF_MC)); } @@ -1993,14 +1992,14 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T txtcol -= wp->w_skipcol; else txtcol -= wp->w_leftcol; - if (txtcol >= 0 && txtcol < wp->w_width) { + if (txtcol >= 0 && txtcol < wp->w_grid.Columns) { linebuf_attr[off + txtcol] = hl_combine_attr( linebuf_attr[off + txtcol], win_hl_attr(wp, HLF_CUC)); } } - grid_put_linebuf(grid, row, 0, grid->Columns, grid->Columns, false, wp, - wp->w_hl_attr_normal, false); + grid_put_linebuf(&wp->w_grid, row, 0, wp->w_grid.Columns, wp->w_grid.Columns, + false, wp, wp->w_hl_attr_normal, false); /* * Update w_cline_height and w_cline_folded if the cursor line was -- cgit From ba6f9f60addb569aa223f6e245df78741eab5adf Mon Sep 17 00:00:00 2001 From: Utkarsh Maheshwari Date: Fri, 21 Sep 2018 18:14:32 +0530 Subject: multigrid: Fix lint errors --- src/nvim/api/ui.c | 4 +- src/nvim/charset.c | 3 +- src/nvim/cursor.c | 5 +- src/nvim/edit.c | 13 ++- src/nvim/ex_cmds.c | 6 +- src/nvim/ex_docmd.c | 8 +- src/nvim/getchar.c | 2 +- src/nvim/globals.h | 2 +- src/nvim/hardcopy.c | 3 +- src/nvim/indent.c | 2 +- src/nvim/message.c | 42 ++++---- src/nvim/misc1.c | 3 +- src/nvim/mouse.c | 2 +- src/nvim/move.c | 150 +++++++++++++++++------------ src/nvim/normal.c | 33 +++---- src/nvim/popupmnu.c | 28 +++--- src/nvim/screen.c | 270 +++++++++++++++++++++++++++------------------------- src/nvim/search.c | 7 +- src/nvim/ui.c | 6 +- src/nvim/window.c | 16 ++-- 20 files changed, 328 insertions(+), 277 deletions(-) (limited to 'src') diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 4f56371633..48a4708dbf 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -248,8 +248,8 @@ static void ui_set_option(UI *ui, bool init, String name, Object value, /// Sets the inner "width" and "height" of the window grid identified by /// "grid" handle. If the grid does not exist, set error. void nvim_ui_try_resize_grid(uint64_t channel_id, Integer grid, Integer width, - Integer height, Error *error) - FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY + Integer height, Error *error) + FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY { if (!pmap_has(uint64_t)(connected_uis, channel_id)) { api_set_error(error, kErrorTypeException, diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 874c996b1b..c220c4e347 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1104,7 +1104,8 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he if (size + sbrlen + numberwidth > (colnr_T)wp->w_grid.Columns) { // Calculate effective window width. int width = (colnr_T)wp->w_grid.Columns - sbrlen - numberwidth; - int prev_width = col ? ((colnr_T)wp->w_grid.Columns - (sbrlen + col)) : 0; + int prev_width = col ? ((colnr_T)wp->w_grid.Columns - (sbrlen + col)) + : 0; if (width == 0) { width = (colnr_T)wp->w_grid.Columns; } diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c index 8c80c1dfc0..ee1bc6cf31 100644 --- a/src/nvim/cursor.c +++ b/src/nvim/cursor.c @@ -223,9 +223,10 @@ static int coladvance2( } else { int b = (int)wcol - (int)col; - /* The difference between wcol and col is used to set coladd. */ - if (b > 0 && b < (MAXCOL - 2 * curwin->w_grid.Columns)) + // The difference between wcol and col is used to set coladd. + if (b > 0 && b < (MAXCOL - 2 * curwin->w_grid.Columns)) { pos->coladd = b; + } col += b; } diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 768d37bd01..4399e118f0 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -1495,7 +1495,7 @@ void edit_putchar(int c, int highlight) int attr; if (default_grid.ScreenLines != NULL) { - update_topline(); /* just in case w_topline isn't valid */ + update_topline(); // just in case w_topline isn't valid validate_cursor(); if (highlight) { attr = HL_ATTR(HLF_8); @@ -1518,8 +1518,9 @@ void edit_putchar(int c, int highlight) } } else { pc_col += curwin->w_wcol; - if (grid_lefthalve(&curwin->w_grid, pc_row, pc_col)) + if (grid_lefthalve(&curwin->w_grid, pc_row, pc_col)) { pc_status = PC_STATUS_LEFT; + } } /* save the character to be able to put it back */ @@ -1568,7 +1569,7 @@ void display_dollar(colnr_T col) curwin->w_cursor.col -= utf_head_off(p, p + col); curs_columns(false); // Recompute w_wrow and w_wcol if (curwin->w_wcol < curwin->w_grid.Columns) { - edit_putchar('$', FALSE); + edit_putchar('$', false); dollar_vcol = curwin->w_virtcol; } curwin->w_cursor.col = save_col; @@ -5842,8 +5843,9 @@ comp_textwidth ( /* The width is the window width minus 'wrapmargin' minus all the * things that add to the margin. */ textwidth = curwin->w_grid.Columns - curbuf->b_p_wm; - if (cmdwin_type != 0) + if (cmdwin_type != 0) { textwidth -= 1; + } textwidth -= curwin->w_p_fdc; if (signcolumn_on(curwin)) { @@ -5857,8 +5859,9 @@ comp_textwidth ( textwidth = 0; if (ff && textwidth == 0) { textwidth = curwin->w_grid.Columns - 1; - if (textwidth > 79) + if (textwidth > 79) { textwidth = 79; + } } return textwidth; } diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 0d14c90110..0067445b38 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -256,10 +256,12 @@ void ex_align(exarg_T *eap) */ if (width <= 0) width = curbuf->b_p_tw; - if (width == 0 && curbuf->b_p_wm > 0) + if (width == 0 && curbuf->b_p_wm > 0) { width = curwin->w_grid.Columns - curbuf->b_p_wm; - if (width <= 0) + } + if (width <= 0) { width = 80; + } } if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL) diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 4e5619ccc8..8bc6193d08 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -9194,10 +9194,10 @@ static int ses_winsizes(FILE *fd, int restore_size, win_T *tab_firstwin) /* restore height when not full height */ if (wp->w_height + wp->w_status_height < topframe->fr_height && (fprintf(fd, - "exe '%dresize ' . ((&lines * %" PRId64 - " + %" PRId64 ") / %" PRId64 ")", - n, (int64_t)wp->w_grid.Rows, - (int64_t)(Rows / 2), (int64_t)Rows) < 0 + "exe '%dresize ' . ((&lines * %" PRId64 + " + %" PRId64 ") / %" PRId64 ")", + n, (int64_t)wp->w_grid.Rows, + (int64_t)(Rows / 2), (int64_t)Rows) < 0 || put_eol(fd) == FAIL)) return FAIL; diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 6a2ee12e46..53e9846c2d 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -2129,7 +2129,7 @@ static int vgetorpeek(int advance) col = curwin->w_cursor.col - 1; } } else if (curwin->w_p_wrap && curwin->w_wrow) { - --curwin->w_wrow; + curwin->w_wrow--; curwin->w_wcol = curwin->w_grid.Columns - 1; col = curwin->w_cursor.col - 1; } diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 1a3cf6886d..7f18262c3f 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -159,7 +159,7 @@ typedef off_t off_T; EXTERN ScreenGrid default_grid INIT(= { 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0 }); -#define DEFAULT_GRID_HANDLE 1 /* handle for the default_grid */ +#define DEFAULT_GRID_HANDLE 1 // handle for the default_grid /* * When vgetc() is called, it sets mod_mask to the set of modifiers that are diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c index f66592682b..983dbb7bbe 100644 --- a/src/nvim/hardcopy.c +++ b/src/nvim/hardcopy.c @@ -582,7 +582,8 @@ static void prt_header(prt_settings_T *const psettings, const int pagenum, */ static void prt_message(char_u *s) { - grid_fill(&default_grid, (int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0); + grid_fill(&default_grid, (int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', + 0); grid_puts(&default_grid, s, (int)Rows - 1, 0, HL_ATTR(HLF_R)); ui_flush(); } diff --git a/src/nvim/indent.c b/src/nvim/indent.c index 76b06190a5..0b7ebd498a 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -463,7 +463,7 @@ int get_breakindent_win(win_T *wp, char_u *line) static char_u *prev_line = NULL; // cached pointer to line. static varnumber_T prev_tick = 0; // Changedtick of cached value. int bri = 0; - /* window width minus window margin space, i.e. what rests for text */ + // window width minus window margin space, i.e. what rests for text const int eff_wwidth = wp->w_grid.Columns - ((wp->w_p_nu || wp->w_p_rnu) && (vim_strchr(p_cpo, CPO_NUMCOL) == NULL) diff --git a/src/nvim/message.c b/src/nvim/message.c index bb7c605428..27382cb951 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1546,10 +1546,8 @@ void msg_prt_line(char_u *s, int list) msg_clr_eos(); } -/* - * Use grid_puts() to output one multi-byte character. - * Return the pointer "s" advanced to the next character. - */ +// Use grid_puts() to output one multi-byte character. +// Return the pointer "s" advanced to the next character. static char_u *screen_puts_mbyte(char_u *s, int l, int attr) { int cw; @@ -2097,7 +2095,8 @@ static void t_puts(int *t_col, const char_u *t_s, const char_u *s, int attr) { // Output postponed text. msg_didout = true; // Remember that line is not empty. - grid_puts_len(&default_grid, (char_u *)t_s, (int)(s - t_s), msg_row, msg_col, attr); + grid_puts_len(&default_grid, (char_u *)t_s, (int)(s - t_s), msg_row, msg_col, + attr); msg_col += *t_col; *t_col = 0; /* If the string starts with a composing character don't increment the @@ -2314,7 +2313,7 @@ static int do_more_prompt(int typed_char) if (toscroll == -1 && grid_ins_lines(&default_grid, 0, 1, (int)Rows, - 0, (int)Columns) == OK) { + 0, (int)Columns) == OK) { grid_fill(&default_grid, 0, 1, 0, (int)Columns, ' ', ' ', 0); // display line at top (void)disp_sb_line(0, mp); @@ -2335,17 +2334,17 @@ static int do_more_prompt(int typed_char) msg_scroll_up(); inc_msg_scrolled(); grid_fill(&default_grid, (int)Rows - 2, (int)Rows - 1, 0, - (int)Columns, ' ', ' ', 0); + (int)Columns, ' ', ' ', 0); mp_last = disp_sb_line((int)Rows - 2, mp_last); --toscroll; } } if (toscroll <= 0) { - /* displayed the requested text, more prompt again */ + // displayed the requested text, more prompt again grid_fill(&default_grid, (int)Rows - 1, (int)Rows, 0, - (int)Columns, ' ', ' ', 0); - msg_moremsg(FALSE); + (int)Columns, ' ', ' ', 0); + msg_moremsg(false); continue; } @@ -2356,8 +2355,9 @@ static int do_more_prompt(int typed_char) break; } - /* clear the --more-- message */ - grid_fill(&default_grid, (int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0); + // clear the --more-- message + grid_fill(&default_grid, (int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', + 0); State = oldState; setmouse(); if (quit_more) { @@ -2477,8 +2477,8 @@ void msg_moremsg(int full) grid_puts(&default_grid, s, (int)Rows - 1, 0, attr); if (full) { grid_puts(&default_grid, (char_u *) - _(" SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "), - (int)Rows - 1, vim_strsize(s), attr); + _(" SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "), + (int)Rows - 1, vim_strsize(s), attr); } } @@ -2527,13 +2527,13 @@ void msg_clr_eos(void) */ void msg_clr_eos_force(void) { - if (cmdmsg_rl) { - grid_fill(&default_grid, msg_row, msg_row + 1, 0, msg_col + 1, ' ', ' ', 0); - grid_fill(&default_grid, msg_row + 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0); - } else { - grid_fill(&default_grid, msg_row, msg_row + 1, msg_col, (int)Columns, ' ', ' ', 0); - grid_fill(&default_grid, msg_row + 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0); - } + int msg_startcol = (cmdmsg_rl) ? 0 : msg_col; + int msg_endcol = (cmdmsg_rl) ? msg_col + 1 : (int)Columns; + + grid_fill(&default_grid, msg_row, msg_row + 1, msg_startcol, msg_endcol, ' ', + ' ', 0); + grid_fill(&default_grid, msg_row + 1, (int)Rows, 0, (int)Columns, ' ', ' ', + 0); } /* diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index fb5586dea2..5f76458275 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -1318,8 +1318,9 @@ int plines_win_col(win_T *wp, linenr_T lnum, long column) if (!wp->w_p_wrap) return lines + 1; - if (wp->w_grid.Columns == 0) + if (wp->w_grid.Columns == 0) { return lines + 1; + } char_u *line = ml_get_buf(wp->w_buffer, lnum, false); char_u *s = line; diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index bd19f54b3d..fe5918eae4 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -112,7 +112,7 @@ retnomove: if (row >= 0 && row < Rows && col >= 0 && col <= Columns && default_grid.ScreenLines != NULL) { mouse_char = default_grid.ScreenLines[default_grid.LineOffset[row] - + (unsigned)col][0]; + + (unsigned)col][0]; } else { mouse_char = ' '; } diff --git a/src/nvim/move.c b/src/nvim/move.c index 6e317b03a4..4267b4bb61 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -83,8 +83,9 @@ static void comp_botline(win_T *wp) redraw_for_cursorline(wp); wp->w_valid |= (VALID_CROW|VALID_CHEIGHT); } - if (done + n > wp->w_grid.Rows) + if (done + n > wp->w_grid.Rows) { break; + } done += n; lnum = last; } @@ -204,8 +205,9 @@ void update_topline(void) if (check_topline) { int halfheight = curwin->w_grid.Rows / 2 - 1; - if (halfheight < 2) + if (halfheight < 2) { halfheight = 2; + } long n; if (hasAnyFolding(curwin)) { /* Count the number of logical lines between the cursor and @@ -292,20 +294,22 @@ void update_topline(void) * botline - p_so (approximation of how much will be * scrolled). */ for (linenr_T lnum = curwin->w_cursor.lnum; - lnum >= curwin->w_botline - p_so; --lnum) { - ++line_count; - /* stop at end of file or when we know we are far off */ - if (lnum <= 0 || line_count > curwin->w_grid.Rows + 1) + lnum >= curwin->w_botline - p_so; lnum--) { + line_count++; + // stop at end of file or when we know we are far off + if (lnum <= 0 || line_count > curwin->w_grid.Rows + 1) { break; + } (void)hasFolding(lnum, &lnum, NULL); } } else line_count = curwin->w_cursor.lnum - curwin->w_botline + 1 + p_so; - if (line_count <= curwin->w_grid.Rows + 1) + if (line_count <= curwin->w_grid.Rows + 1) { scroll_cursor_bot(scrolljump_value(), false); - else + } else { scroll_cursor_halfway(false); + } } } } @@ -666,16 +670,17 @@ void validate_cursor_col(void) col += off; int width = curwin->w_grid.Columns - off + curwin_col_off2(); - /* long line wrapping, adjust curwin->w_wrow */ - if (curwin->w_p_wrap - && col >= (colnr_T)curwin->w_grid.Columns - && width > 0) - /* use same formula as what is used in curs_columns() */ + // long line wrapping, adjust curwin->w_wrow + if (curwin->w_p_wrap && col >= (colnr_T)curwin->w_grid.Columns + && width > 0) { + // use same formula as what is used in curs_columns() col -= ((col - curwin->w_grid.Columns) / width + 1) * width; - if (col > (int)curwin->w_leftcol) + } + if (col > (int)curwin->w_leftcol) { col -= curwin->w_leftcol; - else + } else { col = 0; + } curwin->w_wcol = col; curwin->w_valid |= VALID_WCOL; @@ -766,7 +771,7 @@ void curs_columns( int textwidth = curwin->w_grid.Columns - extra; if (textwidth <= 0) { - /* No room for text, put cursor in last char of window. */ + // No room for text, put cursor in last char of window. curwin->w_wcol = curwin->w_grid.Columns - 1; curwin->w_wrow = curwin->w_grid.Rows - 1; } else if (curwin->w_p_wrap @@ -774,9 +779,9 @@ void curs_columns( ) { width = textwidth + curwin_col_off2(); - /* long line wrapping, adjust curwin->w_wrow */ + // long line wrapping, adjust curwin->w_wrow if (curwin->w_wcol >= curwin->w_grid.Columns) { - /* this same formula is used in validate_cursor_col() */ + // this same formula is used in validate_cursor_col() n = (curwin->w_wcol - curwin->w_grid.Columns) / width + 1; curwin->w_wcol -= n * width; curwin->w_wrow += n; @@ -851,9 +856,8 @@ void curs_columns( || ((prev_skipcol > 0 || curwin->w_wrow + p_so >= curwin->w_grid.Rows) && (p_lines = - plines_win_nofill - (curwin, curwin->w_cursor.lnum, false)) - - 1 >= curwin->w_grid.Rows)) + plines_win_nofill(curwin, curwin->w_cursor.lnum, false)) - 1 + >= curwin->w_grid.Rows)) && curwin->w_grid.Rows != 0 && curwin->w_cursor.lnum == curwin->w_topline && width > 0 @@ -879,19 +883,22 @@ void curs_columns( } else n = p_lines; - if ((colnr_T)n >= curwin->w_grid.Rows + curwin->w_skipcol / width) + if ((colnr_T)n >= curwin->w_grid.Rows + curwin->w_skipcol / width) { extra += 2; + } if (extra == 3 || p_lines < p_so * 2) { - /* not enough room for 'scrolloff', put cursor in the middle */ + // not enough room for 'scrolloff', put cursor in the middle n = curwin->w_virtcol / width; - if (n > curwin->w_grid.Rows / 2) + if (n > curwin->w_grid.Rows / 2) { n -= curwin->w_grid.Rows / 2; - else + } else { n = 0; - /* don't skip more than necessary */ - if (n > p_lines - curwin->w_grid.Rows + 1) + } + // don't skip more than necessary + if (n > p_lines - curwin->w_grid.Rows + 1) { n = p_lines - curwin->w_grid.Rows + 1; + } curwin->w_skipcol = n * width; } else if (extra == 1) { /* less then 'scrolloff' lines above, decrease skipcol */ @@ -904,17 +911,19 @@ void curs_columns( curwin->w_skipcol -= extra * width; } } else if (extra == 2) { - /* less then 'scrolloff' lines below, increase skipcol */ + // less then 'scrolloff' lines below, increase skipcol endcol = (n - curwin->w_grid.Rows + 1) * width; - while (endcol > curwin->w_virtcol) + while (endcol > curwin->w_virtcol) { endcol -= width; - if (endcol > curwin->w_skipcol) + } + if (endcol > curwin->w_skipcol) { curwin->w_skipcol = endcol; + } } curwin->w_wrow -= curwin->w_skipcol / width; if (curwin->w_wrow >= curwin->w_grid.Rows) { - /* small window, make sure cursor is in it */ + // small window, make sure cursor is in it extra = curwin->w_wrow - curwin->w_grid.Rows + 1; curwin->w_skipcol += extra * width; curwin->w_wrow -= extra; @@ -958,8 +967,8 @@ scrolldown ( while (line_count-- > 0) { if (curwin->w_topfill < diff_check(curwin, curwin->w_topline) && curwin->w_topfill < curwin->w_grid.Rows - 1) { - ++curwin->w_topfill; - ++done; + curwin->w_topfill++; + done++; } else { if (curwin->w_topline == 1) break; @@ -1091,8 +1100,9 @@ check_topfill ( wp->w_topfill = 0; } else { wp->w_topfill = wp->w_grid.Rows - n; - if (wp->w_topfill < 0) + if (wp->w_topfill < 0) { wp->w_topfill = 0; + } } } } @@ -1105,12 +1115,13 @@ check_topfill ( static void max_topfill(void) { int n = plines_nofill(curwin->w_topline); - if (n >= curwin->w_grid.Rows) + if (n >= curwin->w_grid.Rows) { curwin->w_topfill = 0; - else { + } else { curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline); - if (curwin->w_topfill + n > curwin->w_grid.Rows) + if (curwin->w_topfill + n > curwin->w_grid.Rows) { curwin->w_topfill = curwin->w_grid.Rows - n; + } } } @@ -1340,10 +1351,12 @@ void scroll_cursor_top(int min_scroll, int always) else used += plines(bot); } - if (used > curwin->w_grid.Rows) + if (used > curwin->w_grid.Rows) { break; - if (top < curwin->w_topline) + } + if (top < curwin->w_topline) { scrolled += i; + } /* * If scrolling is needed, scroll at least 'sj' lines. @@ -1397,9 +1410,9 @@ void scroll_cursor_top(int min_scroll, int always) void set_empty_rows(win_T *wp, int used) { wp->w_filler_rows = 0; - if (used == 0) - wp->w_empty_rows = 0; /* single line that doesn't fit */ - else { + if (used == 0) { + wp->w_empty_rows = 0; // single line that doesn't fit + } else { wp->w_empty_rows = wp->w_grid.Rows - used; if (wp->w_botline <= wp->w_buffer->b_ml.ml_line_count) { wp->w_filler_rows = diff_check_fill(wp, wp->w_botline); @@ -1443,8 +1456,9 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) curwin->w_topline = loff.lnum) { loff.lnum = curwin->w_topline; topline_back(&loff); - if (loff.height == MAXCOL || used + loff.height > curwin->w_grid.Rows) + if (loff.height == MAXCOL || used + loff.height > curwin->w_grid.Rows) { break; + } used += loff.height; curwin->w_topfill = loff.fill; } @@ -1501,12 +1515,14 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) /* Add one line above */ topline_back(&loff); - if (loff.height == MAXCOL) + if (loff.height == MAXCOL) { used = MAXCOL; - else + } else { used += loff.height; - if (used > curwin->w_grid.Rows) + } + if (used > curwin->w_grid.Rows) { break; + } if (loff.lnum >= curwin->w_botline && (loff.lnum > curwin->w_botline || loff.fill <= fill_below_window) @@ -1523,8 +1539,9 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) /* Add one line below */ botline_forw(&boff); used += boff.height; - if (used > curwin->w_grid.Rows) + if (used > curwin->w_grid.Rows) { break; + } if (extra < ( mouse_dragging > 0 ? mouse_dragging - 1 : p_so) || scrolled < min_scroll) { @@ -1545,14 +1562,14 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) } linenr_T line_count; - /* curwin->w_empty_rows is larger, no need to scroll */ - if (scrolled <= 0) + // curwin->w_empty_rows is larger, no need to scroll + if (scrolled <= 0) { line_count = 0; - /* more than a screenfull, don't scroll but redraw */ - else if (used > curwin->w_grid.Rows) + // more than a screenfull, don't scroll but redraw + } else if (used > curwin->w_grid.Rows) { line_count = used; - /* scroll minimal number of lines */ - else { + // scroll minimal number of lines + } else { line_count = 0; boff.fill = curwin->w_topfill; boff.lnum = curwin->w_topline - 1; @@ -1570,10 +1587,11 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) * Scroll up if the cursor is off the bottom of the screen a bit. * Otherwise put it at 1/2 of the screen. */ - if (line_count >= curwin->w_grid.Rows && line_count > min_scroll) + if (line_count >= curwin->w_grid.Rows && line_count > min_scroll) { scroll_cursor_halfway(false); - else + } else { scrollup(line_count, true); + } /* * If topline didn't change we need to restore w_botline and w_empty_rows @@ -1612,8 +1630,9 @@ void scroll_cursor_halfway(int atend) if (boff.lnum < curbuf->b_ml.ml_line_count) { botline_forw(&boff); used += boff.height; - if (used > curwin->w_grid.Rows) + if (used > curwin->w_grid.Rows) { break; + } below += boff.height; } else { ++below; /* count a "~" line */ @@ -1628,8 +1647,9 @@ void scroll_cursor_halfway(int atend) used = MAXCOL; else used += loff.height; - if (used > curwin->w_grid.Rows) + if (used > curwin->w_grid.Rows) { break; + } above += loff.height; topline = loff.lnum; topfill = loff.fill; @@ -1638,8 +1658,9 @@ void scroll_cursor_halfway(int atend) if (!hasFolding(topline, &curwin->w_topline, NULL)) curwin->w_topline = topline; curwin->w_topfill = topfill; - if (old_topline > curwin->w_topline + curwin->w_grid.Rows) + if (old_topline > curwin->w_topline + curwin->w_grid.Rows) { curwin->w_botfill = false; + } check_topfill(curwin, false); curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP); curwin->w_valid |= VALID_TOPLINE; @@ -1667,8 +1688,9 @@ void cursor_correct(void) if (curwin->w_topline == 1) { above_wanted = 0; int max_off = curwin->w_grid.Rows / 2; - if (below_wanted > max_off) + if (below_wanted > max_off) { below_wanted = max_off; + } } validate_botline(); if (curwin->w_botline == curbuf->b_ml.ml_line_count + 1 @@ -1676,8 +1698,9 @@ void cursor_correct(void) ) { below_wanted = 0; int max_off = (curwin->w_grid.Rows - 1) / 2; - if (above_wanted > max_off) + if (above_wanted > max_off) { above_wanted = max_off; + } } /* @@ -1993,9 +2016,10 @@ void halfpage(bool flag, linenr_T Prenum) long scrolled = 0; int i; - if (Prenum) - curwin->w_p_scr = (Prenum > curwin->w_grid.Rows) ? - curwin->w_grid.Rows : Prenum; + if (Prenum) { + curwin->w_p_scr = (Prenum > curwin->w_grid.Rows) ? curwin->w_grid.Rows + : Prenum; + } assert(curwin->w_p_scr <= INT_MAX); int n = curwin->w_p_scr <= curwin->w_grid.Rows ? (int)curwin->w_p_scr : curwin->w_grid.Rows; diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 28c577034c..a050c95224 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -3478,7 +3478,7 @@ static void display_showcmd(void) * spaces */ grid_puts(&default_grid, (char_u *)" " + len, (int)Rows - 1, - sc_col + len, 0); + sc_col + len, 0); setcursor(); /* put cursor back where it belongs */ } @@ -3914,10 +3914,8 @@ static bool nv_screengo(oparg_T *oap, int dir, long dist) } if (curwin->w_grid.Columns != 0) { - /* - * Instead of sticking at the last character of the buffer line we - * try to stick in the last column of the screen. - */ + // Instead of sticking at the last character of the buffer line we + // try to stick in the last column of the screen. if (curwin->w_curswant == MAXCOL) { atend = true; validate_virtcol(); @@ -4271,7 +4269,7 @@ dozet: } break; - /* "zL" - scroll screen left half-page */ + // "zL" - scroll screen left half-page case 'L': cap->count1 *= curwin->w_grid.Columns / 2; FALLTHROUGH; @@ -4309,10 +4307,11 @@ dozet: else getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col); n = curwin->w_grid.Columns - curwin_col_off(); - if (col + l_p_siso < n) + if (col + l_p_siso < n) { col = 0; - else + } else { col = col + l_p_siso - n + 1; + } if (curwin->w_leftcol != col) { curwin->w_leftcol = col; redraw_later(NOT_VALID); @@ -5017,11 +5016,11 @@ static void nv_scroll(cmdarg_T *cap) /* Don't count filler lines above the window. */ used -= diff_check_fill(curwin, curwin->w_topline) - curwin->w_topfill; - validate_botline(); /* make sure w_empty_rows is valid */ + validate_botline(); // make sure w_empty_rows is valid half = (curwin->w_grid.Rows - curwin->w_empty_rows + 1) / 2; - for (n = 0; curwin->w_topline + n < curbuf->b_ml.ml_line_count; ++n) { - /* Count half he number of filler lines to be "below this - * line" and half to be "above the next line". */ + for (n = 0; curwin->w_topline + n < curbuf->b_ml.ml_line_count; n++) { + // Count half he number of filler lines to be "below this + // line" and half to be "above the next line". if (n > 0 && used + diff_check_fill(curwin, curwin->w_topline + n) / 2 >= half) { --n; @@ -5033,9 +5032,10 @@ static void nv_scroll(cmdarg_T *cap) if (hasFolding(curwin->w_topline + n, NULL, &lnum)) n = lnum - curwin->w_topline; } - if (n > 0 && used > curwin->w_grid.Rows) - --n; - } else { /* (cap->cmdchar == 'H') */ + if (n > 0 && used > curwin->w_grid.Rows) { + n--; + } + } else { // (cap->cmdchar == 'H') n = cap->count1 - 1; if (hasAnyFolding(curwin)) { /* Count a fold for one screen line. */ @@ -6762,10 +6762,11 @@ static void nv_g_cmd(cmdarg_T *cap) /* Go to the middle of the screen line. When 'number' or * 'relativenumber' is on and lines are wrapping the middle can be more * to the left. */ - if (cap->nchar == 'm') + if (cap->nchar == 'm') { i += (curwin->w_grid.Columns - curwin_col_off() + ((curwin->w_p_wrap && i > 0) ? curwin_col_off2() : 0)) / 2; + } coladvance((colnr_T)i); if (flag) { do diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index 670c794b68..b5c74b5255 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -423,8 +423,8 @@ void pum_redraw(void) size++; } } - grid_puts_len(&default_grid, rt, (int)STRLEN(rt), row, col - size + 1, - attr); + grid_puts_len(&default_grid, rt, (int)STRLEN(rt), row, + col - size + 1, attr); xfree(rt_start); xfree(st); col -= width; @@ -440,7 +440,8 @@ void pum_redraw(void) // Display two spaces for a Tab. if (curwin->w_p_rl) { - grid_puts_len(&default_grid, (char_u *)" ", 2, row, col - 1, attr); + grid_puts_len(&default_grid, (char_u *)" ", 2, row, col - 1, + attr); col -= 2; } else { grid_puts_len(&default_grid, (char_u *)" ", 2, row, col, attr); @@ -475,32 +476,33 @@ void pum_redraw(void) if (curwin->w_p_rl) { grid_fill(&default_grid, row, row + 1, pum_col - pum_base_width - n + 1, - col + 1, ' ', ' ', attr); + col + 1, ' ', ' ', attr); col = pum_col - pum_base_width - n + 1; } else { - grid_fill(&default_grid, row, row + 1, col, pum_col + pum_base_width + n, - ' ', ' ', attr); + grid_fill(&default_grid, row, row + 1, col, + pum_col + pum_base_width + n, ' ', ' ', attr); col = pum_col + pum_base_width + n; } totwidth = pum_base_width + n; } if (curwin->w_p_rl) { - grid_fill(&default_grid, row, row + 1, pum_col - pum_width + 1, col + 1, ' ', ' ', - attr); + grid_fill(&default_grid, row, row + 1, pum_col - pum_width + 1, col + 1, + ' ', ' ', attr); } else { - grid_fill(&default_grid, row, row + 1, col, pum_col + pum_width, ' ', ' ', attr); + grid_fill(&default_grid, row, row + 1, col, pum_col + pum_width, ' ', ' ', + attr); } if (pum_scrollbar > 0) { if (curwin->w_p_rl) { grid_putchar(&default_grid, ' ', row, pum_col - pum_width, - i >= thumb_pos && i < thumb_pos + thumb_heigth - ? attr_thumb : attr_scroll); + i >= thumb_pos && i < thumb_pos + thumb_heigth + ? attr_thumb : attr_scroll); } else { grid_putchar(&default_grid, ' ', row, pum_col + pum_width, - i >= thumb_pos && i < thumb_pos + thumb_heigth - ? attr_thumb : attr_scroll); + i >= thumb_pos && i < thumb_pos + thumb_heigth + ? attr_thumb : attr_scroll); } } grid_puts_line_flush(&default_grid, false); diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 4d0ca0ebcb..17006c2954 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -686,15 +686,15 @@ static void win_update(win_T *wp) wp->w_lines_valid = 0; } - /* Window is zero-height: nothing to draw. */ + // Window is zero-height: nothing to draw. if (wp->w_grid.Rows == 0) { wp->w_redr_type = 0; return; } - /* Window is zero-width: Only need to draw the separator. */ + // Window is zero-width: Only need to draw the separator. if (wp->w_grid.Columns == 0) { - /* draw the vertical separator right of this window */ + // draw the vertical separator right of this window draw_vsep_win(wp, 0); wp->w_redr_type = 0; return; @@ -882,15 +882,16 @@ static void win_update(win_T *wp) /* count the number of lines we are off, counting a sequence * of folded lines as one */ j = 0; - for (ln = wp->w_topline; ln < wp->w_lines[0].wl_lnum; ++ln) { - ++j; - if (j >= wp->w_grid.Rows - 2) + for (ln = wp->w_topline; ln < wp->w_lines[0].wl_lnum; ln++) { + j++; + if (j >= wp->w_grid.Rows - 2) { break; + } (void)hasFoldingWin(wp, ln, NULL, &ln, true, NULL); } } else j = wp->w_lines[0].wl_lnum - wp->w_topline; - if (j < wp->w_grid.Rows - 2) { /* not too far off */ + if (j < wp->w_grid.Rows - 2) { // not too far off i = plines_m_win(wp, wp->w_topline, wp->w_lines[0].wl_lnum - 1); /* insert extra lines for previously invisible filler lines */ if (wp->w_lines[0].wl_lnum != wp->w_topline) @@ -909,12 +910,15 @@ static void win_update(win_T *wp) /* Move the entries that were scrolled, disable * the entries for the lines to be redrawn. */ - if ((wp->w_lines_valid += j) > wp->w_grid.Rows) + if ((wp->w_lines_valid += j) > wp->w_grid.Rows) { wp->w_lines_valid = wp->w_grid.Rows; - for (idx = wp->w_lines_valid; idx - j >= 0; idx--) + } + for (idx = wp->w_lines_valid; idx - j >= 0; idx--) { wp->w_lines[idx] = wp->w_lines[idx - j]; - while (idx >= 0) - wp->w_lines[idx--].wl_valid = FALSE; + } + while (idx >= 0) { + wp->w_lines[idx--].wl_valid = false; + } } } else mid_start = 0; /* redraw all lines */ @@ -1159,7 +1163,7 @@ static void win_update(win_T *wp) } srow += mid_start; mid_end = wp->w_grid.Rows; - for (; idx < wp->w_lines_valid; ++idx) { /* find end */ + for (; idx < wp->w_lines_valid; idx++) { // find end if (wp->w_lines[idx].wl_valid && wp->w_lines[idx].wl_lnum >= to + 1) { /* Only update until first row of this line */ @@ -1200,7 +1204,7 @@ static void win_update(win_T *wp) /* stop updating when reached the end of the window (check for _past_ * the end of the window is at the end of the loop) */ if (row == wp->w_grid.Rows) { - didline = TRUE; + didline = true; break; } @@ -1299,7 +1303,7 @@ static void win_update(win_T *wp) } j++; if (new_rows > wp->w_grid.Rows - row - 2) { - /* it's getting too much, must redraw the rest */ + // it's getting too much, must redraw the rest new_rows = 9999; break; } @@ -1365,10 +1369,12 @@ static void win_update(win_T *wp) /* move entries in w_lines[] downwards */ j -= i; wp->w_lines_valid += j; - if (wp->w_lines_valid > wp->w_grid.Rows) + if (wp->w_lines_valid > wp->w_grid.Rows) { wp->w_lines_valid = wp->w_grid.Rows; - for (i = wp->w_lines_valid; i - j >= idx; --i) + } + for (i = wp->w_lines_valid; i - j >= idx; i--) { wp->w_lines[i] = wp->w_lines[i - j]; + } /* The w_lines[] entries for inserted lines are * now invalid, but wl_size may be used above. @@ -1448,8 +1454,9 @@ static void win_update(win_T *wp) // This line does not need to be drawn, advance to the next one. row += wp->w_lines[idx++].wl_size; - if (row > wp->w_grid.Rows) /* past end of screen */ + if (row > wp->w_grid.Rows) { // past end of screen break; + } lnum = wp->w_lines[idx - 1].wl_lastlnum + 1; did_update = DID_NONE; } @@ -1489,7 +1496,7 @@ static void win_update(win_T *wp) */ wp->w_botline = lnum + 1; } else if (diff_check_fill(wp, lnum) >= wp->w_grid.Rows - srow) { - /* Window ends in filler lines. */ + // Window ends in filler lines. wp->w_botline = lnum; wp->w_filler_rows = wp->w_grid.Rows - srow; } else if (dy_flags & DY_TRUNCATE) { // 'display' has "truncate" @@ -1524,8 +1531,9 @@ static void win_update(win_T *wp) i = '-'; else i = fill_diff; - if (row + j > wp->w_grid.Rows) + if (row + j > wp->w_grid.Rows) { j = wp->w_grid.Rows - row; + } win_draw_end(wp, i, i, row, row + (int)j, HLF_DED); row += j; } @@ -1613,9 +1621,10 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h n = fdc; if (n > 0) { - /* draw the fold column at the right */ - if (n > wp->w_grid.Columns) + // draw the fold column at the right + if (n > wp->w_grid.Columns) { n = wp->w_grid.Columns; + } grid_fill(&wp->w_grid, row, endrow, wp->w_grid.Columns - n, wp->w_grid.Columns, ' ', ' ', win_hl_attr(wp, HLF_FC)); } @@ -1623,7 +1632,7 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h if (signcolumn_on(wp)) { int nn = n + win_signcol_width(wp); - /* draw the sign column left of the fold column */ + // draw the sign column left of the fold column if (nn > wp->w_grid.Columns) { nn = wp->w_grid.Columns; } @@ -1641,17 +1650,19 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h if (cmdwin_type != 0 && wp == curwin) { /* draw the cmdline character in the leftmost column */ n = 1; - if (n > wp->w_grid.Columns) + if (n > wp->w_grid.Columns) { n = wp->w_grid.Columns; + } grid_fill(&wp->w_grid, row, endrow, 0, n, cmdwin_type, ' ', win_hl_attr(wp, HLF_AT)); } if (fdc > 0) { int nn = n + fdc; - /* draw the fold column at the left */ - if (nn > wp->w_grid.Columns) + // draw the fold column at the left + if (nn > wp->w_grid.Columns) { nn = wp->w_grid.Columns; + } grid_fill(&wp->w_grid, row, endrow, n, nn, ' ', ' ', win_hl_attr(wp, HLF_FC)); n = nn; @@ -1660,7 +1671,7 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h if (signcolumn_on(wp)) { int nn = n + win_signcol_width(wp); - /* draw the sign column after the fold column */ + // draw the sign column after the fold column if (nn > wp->w_grid.Columns) { nn = wp->w_grid.Columns; } @@ -1669,7 +1680,8 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h n = nn; } - grid_fill(&wp->w_grid, row, endrow, FDC_OFF, wp->w_grid.Columns, c1, c2, attr); + grid_fill(&wp->w_grid, row, endrow, FDC_OFF, wp->w_grid.Columns, c1, c2, + attr); } set_empty_rows(wp, row); } @@ -1798,7 +1810,8 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T win_hl_attr(wp, HLF_FC)); // reverse the fold column for (i = 0; i < fdc; i++) { - schar_from_ascii(linebuf_char[off + wp->w_grid.Columns - i - 1 - col], buf[i]); + schar_from_ascii(linebuf_char[off + wp->w_grid.Columns - i - 1 - col], + buf[i]); } } else { copy_text_attr(off + col, buf, fdc, win_hl_attr(wp, HLF_FC)); @@ -1806,12 +1819,15 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T col += fdc; } -# define RL_MEMSET(p, v, l) if (wp->w_p_rl) \ - for (ri = 0; ri < l; ++ri) \ +# define RL_MEMSET(p, v, l) if (wp->w_p_rl) { \ + for (ri = 0; ri < l; ri++) { \ linebuf_attr[off + (wp->w_grid.Columns - (p) - (l)) + ri] = v; \ - else \ - for (ri = 0; ri < l; ++ri) \ - linebuf_attr[off + (p) + ri] = v + } \ + } else { \ + for (ri = 0; ri < l; ri++) { \ + linebuf_attr[off + (p) + ri] = v; \ + } \ + } /* Set all attributes of the 'number' or 'relativenumber' column and the * text */ @@ -1945,14 +1961,15 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T >= (colnr_T)STRLEN(ml_get_buf(wp->w_buffer, lnume, FALSE))))))) { if (VIsual_mode == Ctrl_V) { - /* Visual block mode: highlight the chars part of the block */ + // Visual block mode: highlight the chars part of the block if (wp->w_old_cursor_fcol + txtcol < (colnr_T)wp->w_grid.Columns) { if (wp->w_old_cursor_lcol != MAXCOL && wp->w_old_cursor_lcol + txtcol - < (colnr_T)wp->w_grid.Columns) + < (colnr_T)wp->w_grid.Columns) { len = wp->w_old_cursor_lcol; - else + } else { len = wp->w_grid.Columns - txtcol; + } RL_MEMSET(wp->w_old_cursor_fcol + txtcol, win_hl_attr(wp, HLF_V), len - (int)wp->w_old_cursor_fcol); } @@ -2854,10 +2871,11 @@ win_line ( c_extra = '-'; else c_extra = fill_diff; - if (wp->w_p_rl) + if (wp->w_p_rl) { n_extra = col + 1; - else + } else { n_extra = grid->Columns - col; + } char_attr = win_hl_attr(wp, HLF_DED); } if (*p_sbr != NUL && need_showbreak) { @@ -3126,9 +3144,8 @@ win_line ( /* If a double-width char doesn't fit display a '>' in the * last column. */ - if (( - wp->w_p_rl ? (col <= 0) : - (col >= grid->Columns - 1)) + if ((wp->w_p_rl ? (col <= 0) : + (col >= grid->Columns - 1)) && (*mb_char2cells)(mb_c) == 2) { c = '>'; mb_c = c; @@ -3268,9 +3285,8 @@ win_line ( /* If a double-width char doesn't fit display a '>' in the * last column; the character is displayed at the start of the * next line. */ - if (( - wp->w_p_rl ? (col <= 0) : - (col >= grid->Columns - 1)) + if ((wp->w_p_rl ? (col <= 0) : + (col >= grid->Columns - 1)) && (*mb_char2cells)(mb_c) == 2) { c = '>'; mb_c = c; @@ -3601,9 +3617,7 @@ win_line ( || ((fromcol >= 0 || fromcol_prev >= 0) && tocol > vcol && VIsual_mode != Ctrl_V - && ( - wp->w_p_rl ? (col >= 0) : - (col < grid->Columns)) + && (wp->w_p_rl ? (col >= 0) : (col < grid->Columns)) && !(noinvcur && lnum == wp->w_cursor.lnum && (colnr_T)vcol == wp->w_virtcol))) @@ -3668,14 +3682,11 @@ win_line ( saved_attr2 = char_attr; // save current attr mb_utf8 = false; // don't draw as UTF-8 } else if (VIsual_active - && (VIsual_mode == Ctrl_V - || VIsual_mode == 'v') + && (VIsual_mode == Ctrl_V || VIsual_mode == 'v') && virtual_active() && tocol != MAXCOL && vcol < tocol - && ( - wp->w_p_rl ? (col >= 0) : - (col < grid->Columns))) { + && (wp->w_p_rl ? (col >= 0) : (col < grid->Columns))) { c = ' '; ptr--; // put it back at the NUL } @@ -3833,8 +3844,9 @@ win_line ( if (col < 0) n = 1; } else { - if (col >= grid->Columns) + if (col >= grid->Columns) { n = -1; + } } if (n != 0) { /* At the window boundary, highlight the last character @@ -4023,7 +4035,7 @@ win_line ( } } grid_put_linebuf(grid, row, 0, col, grid->Columns, wp->w_p_rl, wp, - wp->w_hl_attr_normal, false); + wp->w_hl_attr_normal, false); row++; /* @@ -4044,9 +4056,7 @@ win_line ( if (lcs_ext && !wp->w_p_wrap && filler_todo <= 0 - && ( - wp->w_p_rl ? col == 0 : - col == grid->Columns - 1) + && (wp->w_p_rl ? col == 0 : col == grid->Columns - 1) && (*ptr != NUL || (wp->w_p_list && lcs_eol_one > 0) || (n_extra && (c_extra != NUL || *p_extra != NUL)))) { @@ -4225,9 +4235,7 @@ win_line ( * At end of screen line and there is more to come: Display the line * so far. If there is no more to display it is caught above. */ - if (( - wp->w_p_rl ? (col < 0) : - (col >= grid->Columns)) + if ((wp->w_p_rl ? (col < 0) : (col >= grid->Columns)) && (*ptr != NUL || filler_todo > 0 || (wp->w_p_list && lcs_eol != NUL && p_extra != at_end_str) @@ -4260,7 +4268,7 @@ win_line ( } boguscols = 0; - ++row; + row++; /* When not wrapping and finished diff lines, or when displayed * '$' and highlighting until last column, break here. */ @@ -4286,7 +4294,7 @@ win_line ( col = 0; off = 0; if (wp->w_p_rl) { - col = grid->Columns - 1; /* col is not used if breaking! */ + col = grid->Columns - 1; // col is not used if breaking! off += col; } @@ -4366,15 +4374,13 @@ static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, // 2: occupies two display cells int start_dirty = -1, end_dirty = 0; - if (grid == NULL) { - grid = &default_grid; - } - - /* Check for illegal row and col, just in case. */ - if (row >= grid->Rows) + // Check for illegal row and col, just in case + if (row >= grid->Rows) { row = grid->Rows - 1; - if (endcol > grid->Columns) + } + if (endcol > grid->Columns) { endcol = grid->Columns; + } // If UI is not externalized, merge the contents of global and window grids if (!ui_is_external(kUIMultigrid) && grid != &default_grid) { @@ -4690,7 +4696,8 @@ win_redr_status_matches ( if (matches == NULL) /* interrupted completion? */ return; - buf = xmalloc(has_mbyte ? default_grid.Columns * MB_MAXBYTES + 1 : default_grid.Columns + 1); + buf = xmalloc(has_mbyte ? default_grid.Columns * MB_MAXBYTES + 1 + : default_grid.Columns + 1); if (match == -1) { /* don't show match but original text */ match = 0; @@ -4710,15 +4717,16 @@ win_redr_status_matches ( clen += status_match_len(xp, L_MATCH(i)) + 2; if (first_match > 0) clen += 2; - /* jumping right, put match at the left */ + // jumping right, put match at the left if ((long)clen > default_grid.Columns) { first_match = match; /* if showing the last match, we can add some on the left */ clen = 2; for (i = match; i < num_matches; ++i) { clen += status_match_len(xp, L_MATCH(i)) + 2; - if ((long)clen >= default_grid.Columns) + if ((long)clen >= default_grid.Columns) { break; + } } if (i == num_matches) add_left = TRUE; @@ -4727,9 +4735,10 @@ win_redr_status_matches ( if (add_left) while (first_match > 0) { clen += status_match_len(xp, L_MATCH(first_match - 1)) + 2; - if ((long)clen >= default_grid.Columns) + if ((long)clen >= default_grid.Columns) { break; - --first_match; + } + first_match--; } fillchar = fillchar_status(&attr, curwin); @@ -4744,7 +4753,8 @@ win_redr_status_matches ( clen = len; i = first_match; - while ((long)(clen + status_match_len(xp, L_MATCH(i)) + 2) < default_grid.Columns) { + while ((long)(clen + status_match_len(xp, L_MATCH(i)) + 2) + < default_grid.Columns) { if (i == match) { selstart = buf + len; selstart_col = clen; @@ -5109,12 +5119,13 @@ win_redr_custom ( stl = p_ruf; } col = ru_col - (default_grid.Columns - wp->w_width); - if (col < (wp->w_width + 1) / 2) + if (col < (wp->w_width + 1) / 2) { col = (wp->w_width + 1) / 2; + } maxwidth = wp->w_width - col; if (!wp->w_status_height) { row = default_grid.Rows - 1; - --maxwidth; /* writing in last column may cause scrolling */ + maxwidth--; // writing in last column may cause scrolling fillchar = ' '; attr = 0; } @@ -5186,7 +5197,8 @@ win_redr_custom ( curattr = highlight_user[hltab[n].userhl - 1]; } // Make sure to use an empty string instead of p, if p is beyond buf + len. - grid_puts(&default_grid, p >= buf + len ? (char_u *)"" : p, row, col, curattr); + grid_puts(&default_grid, p >= buf + len ? (char_u *)"" : p, row, col, + curattr); grid_puts_line_flush(&default_grid, false); @@ -5318,7 +5330,7 @@ void grid_putchar(ScreenGrid *grid, int c, int row, int col, int attr) /// get a single character directly from grid.ScreenLines into "bytes[]". /// Also return its attribute in *attrp; void grid_getbytes(ScreenGrid *grid, int row, int col, char_u *bytes, - int *attrp) + int *attrp) { unsigned off; @@ -5383,10 +5395,6 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, int need_redraw; bool do_flush = false; - if (grid == NULL) { - grid = &default_grid; - } - // If UI is not externalized, keep working on the default grid if (!ui_is_external(kUIMultigrid) && grid != &default_grid) { row += grid->OffsetRow; @@ -5536,7 +5544,7 @@ void grid_puts_line_flush(ScreenGrid *grid, bool set_cursor) ui_grid_cursor_goto(grid, put_dirty_row, put_dirty_last); } ui_line(grid, put_dirty_row, put_dirty_first, put_dirty_last, - put_dirty_last, 0, false); + put_dirty_last, 0, false); put_dirty_first = -1; put_dirty_last = 0; } @@ -5843,14 +5851,10 @@ next_search_hl_pos( /// with character 'c1' in first column followed by 'c2' in the other columns. /// Use attributes 'attr'. void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, - int end_col, int c1, int c2, int attr) + int end_col, int c1, int c2, int attr) { schar_T sc; - if (grid == NULL) { - grid = &default_grid; - } - // if grids are not externalized, keep working on the default_grid if (!ui_is_external(kUIMultigrid) && grid != &default_grid) { start_row += grid->OffsetRow; @@ -5860,14 +5864,20 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, grid = &default_grid; } - if (end_row > grid->Rows) // safety check + // safety check + if (end_row > grid->Rows) { end_row = grid->Rows; - if (end_col > grid->Columns) // safety check + } + if (end_col > grid->Columns) { end_col = grid->Columns; + } + + // nothing to do if (grid->ScreenLines == NULL || start_row >= end_row - || start_col >= end_col) /* nothing to do */ + || start_col >= end_col) { return; + } for (int row = start_row; row < end_row; row++) { if (has_mbyte) { @@ -5966,7 +5976,7 @@ void check_for_delay(int check_msg_scroll) */ int screen_valid(int doclear) { - screenalloc(doclear); /* allocate screen buffers if size changed */ + screenalloc(doclear); // allocate screen buffers if size changed return default_grid.ScreenLines != NULL; } @@ -6244,11 +6254,11 @@ static void screenclear2(void) return; } - /* blank out ScreenLines */ - for (i = 0; i < default_grid.Rows; ++i) { + // blank out ScreenLines + for (i = 0; i < default_grid.Rows; i++) { grid_clear_line(&default_grid, default_grid.LineOffset[i], (int)default_grid.Columns, true); - default_grid.LineWraps[i] = FALSE; + default_grid.LineWraps[i] = false; } ui_call_grid_clear(1); // clear the display @@ -6334,7 +6344,7 @@ static int win_do_lines(win_T *wp, int row, int line_count, int del) } // No lines are being moved, just draw over the entire area - if (row + line_count >= wp->w_height) { + if (row + line_count >= wp->w_grid.Rows) { return OK; } @@ -6372,17 +6382,13 @@ static int win_do_lines(win_T *wp, int row, int line_count, int del) /// 'row', 'col' and 'end' are relative to the start of the region. /// /// @return FAIL for failure, OK for success. -int grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, - int col, int width) +int grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col, + int width) { int i; int j; unsigned temp; - if (grid == NULL) { - grid = &default_grid; - } - // If UI is not externalized, keep working on default grid if (!ui_is_external(kUIMultigrid) && grid != &default_grid) { row += grid->OffsetRow; @@ -6431,17 +6437,13 @@ int grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, /// 'row' and 'end' are relative to the start of the region. /// /// Return OK for success, FAIL if the lines are not deleted. -int grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, - int col, int width) +int grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col, + int width) { int j; int i; unsigned temp; - if (grid == NULL) { - grid = &default_grid; - } - // If UI is not externalized, keep working on default grid if (!ui_is_external(kUIMultigrid) && grid != &default_grid) { row += grid->OffsetRow; @@ -6527,8 +6529,9 @@ int showmode(void) /* if the cmdline is more than one line high, erase top lines */ need_clear = clear_cmdline; - if (clear_cmdline && cmdline_row < default_grid.Rows - 1) - msg_clr_cmdline(); /* will reset clear_cmdline */ + if (clear_cmdline && cmdline_row < default_grid.Rows - 1) { + msg_clr_cmdline(); // will reset clear_cmdline + } /* Position on the last line in the window, column 0 */ msg_pos_mode(); @@ -6547,8 +6550,9 @@ int showmode(void) /* These messages can get long, avoid a wrap in a narrow * window. Prefer showing edit_submode_extra. */ length = (default_grid.Rows - msg_row) * default_grid.Columns - 3; - if (edit_submode_extra != NULL) + if (edit_submode_extra != NULL) { length -= vim_strsize(edit_submode_extra); + } if (length > 0) { if (edit_submode_pre != NULL) length -= vim_strsize(edit_submode_pre); @@ -6821,7 +6825,7 @@ static void draw_tabline(void) break; } grid_puts_len(&default_grid, NameBuff, len, 0, col, - hl_combine_attr(attr, win_hl_attr(cwp, HLF_T))); + hl_combine_attr(attr, win_hl_attr(cwp, HLF_T))); col += len; } if (modified) { @@ -6846,8 +6850,9 @@ static void draw_tabline(void) p += len - room; len = room; } - if (len > default_grid.Columns - col - 1) + if (len > default_grid.Columns - col - 1) { len = default_grid.Columns - col - 1; + } grid_puts_len(&default_grid, p, (int)STRLEN(p), 0, col, attr); col += len; @@ -6870,11 +6875,13 @@ static void draw_tabline(void) c = '_'; else c = ' '; - grid_fill(&default_grid, 0, 1, col, (int)default_grid.Columns, c, c, attr_fill); + grid_fill(&default_grid, 0, 1, col, (int)default_grid.Columns, c, c, + attr_fill); /* Put an "X" for closing the current tab if there are several. */ if (first_tabpage->tp_next != NULL) { - grid_putchar(&default_grid, 'X', 0, (int)default_grid.Columns - 1, attr_nosel); + grid_putchar(&default_grid, 'X', 0, (int)default_grid.Columns - 1, + attr_nosel); tab_page_click_defs[default_grid.Columns - 1] = (StlClickDefinition) { .type = kStlClickTabClose, .tabnr = 999, @@ -7109,15 +7116,18 @@ static void win_redr_ruler(win_T *wp, int always) int i = (int)STRLEN(buffer); get_rel_pos(wp, buffer + i + 1, RULER_BUF_LEN - i - 1); int o = i + vim_strsize(buffer + i + 1); - if (wp->w_status_height == 0) /* can't use last char of screen */ - ++o; + if (wp->w_status_height == 0) { // can't use last char of screen + o++; + } int this_ru_col = ru_col - (default_grid.Columns - width); - if (this_ru_col < 0) + if (this_ru_col < 0) { this_ru_col = 0; - /* Never use more than half the window/screen width, leave the other - * half for the filename. */ - if (this_ru_col < (width + 1) / 2) + } + // Never use more than half the window/screen width, leave the other half + // for the filename. + if (this_ru_col < (width + 1) / 2) { this_ru_col = (width + 1) / 2; + } if (this_ru_col + o < width) { // Need at least 3 chars left for get_rel_pos() + NUL. while (this_ru_col + o < width && RULER_BUF_LEN > i + 4) { @@ -7139,10 +7149,9 @@ static void win_redr_ruler(win_T *wp, int always) grid_puts(&default_grid, buffer, row, this_ru_col + off, attr); i = redraw_cmdline; grid_fill(&default_grid, row, row + 1, - this_ru_col + off + (int)STRLEN(buffer), - off + width, - fillchar, fillchar, attr); - /* don't redraw the cmdline because of showing the ruler */ + this_ru_col + off + (int)STRLEN(buffer), off + width, fillchar, + fillchar, attr); + // don't redraw the cmdline because of showing the ruler redraw_cmdline = i; wp->w_ru_cursor = wp->w_cursor; wp->w_ru_virtcol = wp->w_virtcol; @@ -7163,12 +7172,13 @@ int number_width(win_T *wp) int n; linenr_T lnum; - if (wp->w_p_rnu && !wp->w_p_nu) - /* cursor line shows "0" */ + if (wp->w_p_rnu && !wp->w_p_nu) { + // cursor line shows "0" lnum = wp->w_grid.Rows; - else - /* cursor line shows absolute line number */ + } else { + // cursor line shows absolute line number lnum = wp->w_buffer->b_ml.ml_line_count; + } if (lnum == wp->w_nrwidth_line_count) return wp->w_nrwidth_width; diff --git a/src/nvim/search.c b/src/nvim/search.c index e6243ad5ba..cf0f1ea287 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -2166,9 +2166,10 @@ showmatch( if (!curwin->w_p_wrap) { getvcol(curwin, lpos, NULL, &vcol, NULL); } - if (curwin->w_p_wrap || (vcol >= curwin->w_leftcol - && vcol < curwin->w_leftcol + curwin->w_grid.Columns)) { - mpos = *lpos; /* save the pos, update_screen() may change it */ + if (curwin->w_p_wrap + || (vcol >= curwin->w_leftcol + && vcol < curwin->w_leftcol + curwin->w_grid.Columns)) { + mpos = *lpos; // save the pos, update_screen() may change it save_cursor = curwin->w_cursor; save_so = p_so; save_siso = p_siso; diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 89c0069e58..da6a1d0f2a 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -349,7 +349,8 @@ void ui_grid_cursor_goto(ScreenGrid *grid, int new_row, int new_col) { new_row += ui_is_external(kUIMultigrid) ? 0 : grid->OffsetRow; new_col += ui_is_external(kUIMultigrid) ? 0 : grid->OffsetColumn; - int handle = ui_is_external(kUIMultigrid) ? grid->handle : DEFAULT_GRID_HANDLE; + int handle = ui_is_external(kUIMultigrid) ? grid->handle + : DEFAULT_GRID_HANDLE; if (new_row == row && new_col == col && handle == cursor_grid_handle) { return; @@ -451,7 +452,8 @@ void ui_grid_resize(GridHandle grid_handle, int width, int height, Error *error) win_T *wp = get_win_by_grid_handle(grid_handle); if (wp == NULL) { - api_set_error(error, kErrorTypeValidation, "No window with the given handle"); + api_set_error(error, kErrorTypeValidation, + "No window with the given handle"); return; } diff --git a/src/nvim/window.c b/src/nvim/window.c index 3d11076a40..30ee4c6303 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -4230,7 +4230,7 @@ static void frame_comp_pos(frame_T *topfrp, int *row, int *col) wp->w_winrow = *row; wp->w_wincol = *col; redraw_win_later(wp, NOT_VALID); - wp->w_redr_status = TRUE; + wp->w_redr_status = true; wp->w_pos_changed = true; } *row += wp->w_height + wp->w_status_height; @@ -4285,8 +4285,9 @@ void win_setheight_win(int height, win_T *win) * If there is extra space created between the last window and the command * line, clear it. */ - if (full_screen && msg_scrolled == 0 && row < cmdline_row) + if (full_screen && msg_scrolled == 0 && row < cmdline_row) { grid_fill(&default_grid, row, cmdline_row, 0, (int)Columns, ' ', ' ', 0); + } cmdline_row = row; msg_row = row; msg_col = 0; @@ -5086,10 +5087,11 @@ void command_height(void) /* Recompute window positions. */ (void)win_comp_pos(); - /* clear the lines added to cmdline */ - if (full_screen) - grid_fill(&default_grid, cmdline_row, (int)Rows, 0, - (int)Columns, ' ', ' ', 0); + // clear the lines added to cmdline + if (full_screen) { + grid_fill(&default_grid, cmdline_row, (int)Rows, 0, (int)Columns, ' ', + ' ', 0); + } msg_row = cmdline_row; redraw_cmdline = TRUE; return; @@ -6073,7 +6075,7 @@ void win_ui_flush(void) } FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if(wp->w_pos_changed && wp->w_grid.ScreenLines != NULL) { + if (wp->w_pos_changed && wp->w_grid.ScreenLines != NULL) { ui_call_win_position(wp->handle, wp->w_grid.handle, wp->w_winrow, wp->w_wincol, wp->w_width, wp->w_height); wp->w_pos_changed = false; -- cgit From f77f09ea6e0e540a636990df84d09166a757482f Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sat, 22 Sep 2018 14:50:58 +0200 Subject: multigrid: don't clear window grids on resize Instead define that the shared top-left part of the grid is preserved. --- src/nvim/move.c | 2 +- src/nvim/screen.c | 24 +++++++++++------------- 2 files changed, 12 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/nvim/move.c b/src/nvim/move.c index 4267b4bb61..ebbcd1b853 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -529,7 +529,7 @@ int cursor_valid(void) */ void validate_cursor(void) { - win_grid_alloc(curwin, true); // we need to have w_grid.Rows/Columns updated + win_grid_alloc(curwin, false); // we need to have w_grid.Rows/Columns updated check_cursor_moved(curwin); if ((curwin->w_valid & (VALID_WCOL|VALID_WROW)) != (VALID_WCOL|VALID_WROW)) curs_columns(true); diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 17006c2954..953aea0094 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -679,7 +679,7 @@ static void win_update(win_T *wp) type = wp->w_redr_type; - win_grid_alloc(wp, true); + win_grid_alloc(wp, false); if (type >= NOT_VALID) { wp->w_redr_status = true; @@ -5897,8 +5897,8 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, // if grid was resized (in ext_multigrid mode), the UI has no redraw updates // for the newly resized grid. It is better mark everything as dirty and // send all the updates. - int dirty_first = grid->was_resized ? start_col : INT_MAX; - int dirty_last = grid->was_resized ? grid->Columns : 0; + int dirty_first = INT_MAX; + int dirty_last = 0; int col = start_col; schar_from_char(sc, c1); @@ -5912,9 +5912,7 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, if (dirty_first == INT_MAX) { dirty_first = col; } - if (!grid->was_resized) { - dirty_last = col+1; - } + dirty_last = col+1; } if (col == start_col) { schar_from_char(sc, c2); @@ -6152,7 +6150,7 @@ retry: void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy) { - int new_row, old_row; + int new_row; ScreenGrid new = *grid; size_t ncells = (size_t)((rows+1) * columns); @@ -6168,21 +6166,20 @@ void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy) new.LineOffset[new_row] = new_row * new.Columns; new.LineWraps[new_row] = false; - grid_clear_line(&new, 0, columns); + grid_clear_line(&new, new.LineOffset[new_row], columns, true); if (copy) { // If the screen is not going to be cleared, copy as much as // possible from the old screen to the new one and clear the rest // (used when resizing the window at the "--more--" prompt or when // executing an external command, for the GUI). - old_row = new_row + (grid->Rows - new.Rows); - if (old_row >= 0 && grid->ScreenLines != NULL) { + if (new_row < grid->Rows && grid->ScreenLines != NULL) { int len = MIN(grid->Columns, new.Columns); memmove(new.ScreenLines + new.LineOffset[new_row], - grid->ScreenLines + grid->LineOffset[old_row], + grid->ScreenLines + grid->LineOffset[new_row], (size_t)len * sizeof(schar_T)); memmove(new.ScreenAttrs + new.LineOffset[new_row], - grid->ScreenAttrs + grid->LineOffset[old_row], + grid->ScreenAttrs + grid->LineOffset[new_row], (size_t)len * sizeof(sattr_T)); } } @@ -6281,7 +6278,8 @@ static void screenclear2(void) /// clear a line in the grid starting at "off" until "width" characters /// are cleared. -static void grid_clear_line(ScreenGrid *grid, unsigned off, int width, bool valid) +static void grid_clear_line(ScreenGrid *grid, unsigned off, int width, + bool valid) { for (int col = 0; col < width; col++) { schar_from_ascii(grid->ScreenLines[off + col], ' '); -- cgit From c3e2e40e028b66495a866785afaf1a6d7e5b3a3b Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Thu, 18 Oct 2018 19:06:21 +0200 Subject: multigrid: send win_hide events when changing tabpage --- src/nvim/api/ui_events.in.h | 4 +++- src/nvim/window.c | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h index 308d5aaf02..48e43061c6 100644 --- a/src/nvim/api/ui_events.in.h +++ b/src/nvim/api/ui_events.in.h @@ -85,7 +85,9 @@ void grid_destroy(Integer grid) FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; void win_position(Integer win, Integer grid, Integer startrow, Integer startcol, Integer width, Integer height) - FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY; + FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; +void win_hide(Integer win, Integer grid) + FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; void popupmenu_show(Array items, Integer selected, Integer row, Integer col, Integer grid) diff --git a/src/nvim/window.c b/src/nvim/window.c index 30ee4c6303..5fa33e618c 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -3118,6 +3118,10 @@ int win_new_tabpage(int after, char_u *filename) redraw_all_later(NOT_VALID); + if (ui_is_external(kUIMultigrid)) { + tabpage_check_windows(tp); + } + apply_autocmds(EVENT_WINNEW, NULL, NULL, false, curbuf); apply_autocmds(EVENT_WINENTER, NULL, NULL, false, curbuf); apply_autocmds(EVENT_TABNEW, filename, filename, false, curbuf); @@ -3309,11 +3313,16 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, int trigger_enter_au int old_off = tp->tp_firstwin->w_winrow; win_T *next_prevwin = tp->tp_prevwin; + tabpage_T *old_curtab = curtab; curtab = tp; firstwin = tp->tp_firstwin; lastwin = tp->tp_lastwin; topframe = tp->tp_topframe; + if (old_curtab != curtab && ui_is_external(kUIMultigrid)) { + tabpage_check_windows(old_curtab); + } + /* We would like doing the TabEnter event first, but we don't have a * valid current window yet, which may break some commands. * This triggers autocommands, thus may make "tp" invalid. */ @@ -3349,6 +3358,20 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, int trigger_enter_au must_redraw = NOT_VALID; } +/// called when changing current tabpage from old_curtab to curtab +static void tabpage_check_windows(tabpage_T *old_curtab) +{ + win_T *next_wp; + for (win_T *wp = old_curtab->tp_firstwin; wp; wp = next_wp) { + next_wp = wp->w_next; + wp->w_pos_changed = true; + } + + for (win_T *wp = firstwin; wp; wp = wp->w_next) { + wp->w_pos_changed = true; + } +} + /* * Go to tab page "n". For ":tab N" and "Ngt". * When "n" is 9999 go to the last tab page. @@ -6074,10 +6097,14 @@ void win_ui_flush(void) return; } - FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + FOR_ALL_TAB_WINDOWS(tp, wp) { if (wp->w_pos_changed && wp->w_grid.ScreenLines != NULL) { - ui_call_win_position(wp->handle, wp->w_grid.handle, wp->w_winrow, - wp->w_wincol, wp->w_width, wp->w_height); + if (tp == curtab) { + ui_call_win_position(wp->handle, wp->w_grid.handle, wp->w_winrow, + wp->w_wincol, wp->w_width, wp->w_height); + } else { + ui_call_win_hide(wp->handle, wp->w_grid.handle); + } wp->w_pos_changed = false; } } -- cgit From f6f8f0ee762aed40586429362b83e5c7d0ca0686 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Fri, 19 Oct 2018 10:42:34 +0200 Subject: multigrid: add msg_scroll_start and msg_scroll_reset events --- src/nvim/api/ui_events.in.h | 5 +++++ src/nvim/message.c | 3 +++ src/nvim/screen.c | 1 + 3 files changed, 9 insertions(+) (limited to 'src') diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h index 48e43061c6..90f1d1b2a9 100644 --- a/src/nvim/api/ui_events.in.h +++ b/src/nvim/api/ui_events.in.h @@ -83,11 +83,16 @@ void grid_scroll(Integer grid, Integer top, Integer bot, FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL; void grid_destroy(Integer grid) FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; + void win_position(Integer win, Integer grid, Integer startrow, Integer startcol, Integer width, Integer height) FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; void win_hide(Integer win, Integer grid) FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; +void win_scroll_over_start(void) + FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; +void win_scroll_over_reset(void) + FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; void popupmenu_show(Array items, Integer selected, Integer row, Integer col, Integer grid) diff --git a/src/nvim/message.c b/src/nvim/message.c index 27382cb951..37e40c3cc1 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1884,6 +1884,9 @@ int msg_scrollsize(void) */ static void msg_scroll_up(void) { + if (msg_scrolled == 0) { + ui_call_win_scroll_over_start(); + } if (dy_flags & DY_MSGSEP) { if (msg_scrolled == 0) { grid_fill(&default_grid, Rows-p_ch-1, Rows-p_ch, 0, (int)Columns, diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 953aea0094..c088367c69 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -292,6 +292,7 @@ void update_screen(int type) * if the screen was scrolled up when displaying a message, scroll it down */ if (msg_scrolled) { + ui_call_win_scroll_over_reset(); clear_cmdline = true; if (dy_flags & DY_MSGSEP) { int valid = MAX(Rows - msg_scrollsize(), 0); -- cgit From db14d78e4f90a0dab64beb569efe0a7d314db4a7 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sun, 11 Nov 2018 10:33:02 +0100 Subject: multigrid: rename event to win_pos, make grid first --- src/nvim/api/ui_events.in.h | 6 +++--- src/nvim/window.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h index 90f1d1b2a9..28beebb9e4 100644 --- a/src/nvim/api/ui_events.in.h +++ b/src/nvim/api/ui_events.in.h @@ -84,10 +84,10 @@ void grid_scroll(Integer grid, Integer top, Integer bot, void grid_destroy(Integer grid) FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; -void win_position(Integer win, Integer grid, Integer startrow, - Integer startcol, Integer width, Integer height) +void win_pos(Integer grid, Integer win, Integer startrow, + Integer startcol, Integer width, Integer height) FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; -void win_hide(Integer win, Integer grid) +void win_hide(Integer grid) FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; void win_scroll_over_start(void) FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; diff --git a/src/nvim/window.c b/src/nvim/window.c index 5fa33e618c..39fc1897ae 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -6100,10 +6100,10 @@ void win_ui_flush(void) FOR_ALL_TAB_WINDOWS(tp, wp) { if (wp->w_pos_changed && wp->w_grid.ScreenLines != NULL) { if (tp == curtab) { - ui_call_win_position(wp->handle, wp->w_grid.handle, wp->w_winrow, - wp->w_wincol, wp->w_width, wp->w_height); + ui_call_win_pos(wp->w_grid.handle, wp->handle, wp->w_winrow, + wp->w_wincol, wp->w_width, wp->w_height); } else { - ui_call_win_hide(wp->handle, wp->w_grid.handle); + ui_call_win_hide(wp->w_grid.handle); } wp->w_pos_changed = false; } -- cgit From 47c053cc39c9b3aa78eb4f64ec98c574506729ae Mon Sep 17 00:00:00 2001 From: Utkarsh Maheshwari Date: Thu, 28 Jun 2018 15:35:19 +0530 Subject: multigrid: Add multigrid documentation --- src/nvim/api/ui.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 48a4708dbf..c374bede99 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -245,8 +245,15 @@ static void ui_set_option(UI *ui, bool init, String name, Object value, name.data); } -/// Sets the inner "width" and "height" of the window grid identified by -/// "grid" handle. If the grid does not exist, set error. +/// Tell nvim to resize a grid. Nvim sends grid_resize event with the +/// requested grid size is within size limits and with maximum allowed size +/// otherwise. +/// +/// On invalid grid handle, fails with error. +/// +/// @param grid The handle of the grid to be changed. +/// @param width The new requested width. +/// @param height The new requested height. void nvim_ui_try_resize_grid(uint64_t channel_id, Integer grid, Integer width, Integer height, Error *error) FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY -- cgit From 820c81e638768994f4e51fdb87eadf31664048ff Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sun, 23 Dec 2018 14:12:56 +0100 Subject: multigrid: various cleanup (types, unused parameters) Handle the rare case of full highlight table properly --- src/nvim/edit.c | 2 +- src/nvim/highlight.c | 10 ++-------- src/nvim/mbyte.c | 8 -------- src/nvim/move.c | 4 ++-- src/nvim/screen.c | 33 ++++++++++++++++++++++++++++----- src/nvim/window.c | 2 -- 6 files changed, 33 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 4399e118f0..eb81ee9320 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -1494,7 +1494,7 @@ void edit_putchar(int c, int highlight) { int attr; - if (default_grid.ScreenLines != NULL) { + if (curwin->w_grid.ScreenLines != NULL || default_grid.ScreenLines != NULL) { update_topline(); // just in case w_topline isn't valid validate_cursor(); if (highlight) { diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c index cbc230b65a..41d60fa3ea 100644 --- a/src/nvim/highlight.c +++ b/src/nvim/highlight.c @@ -98,7 +98,7 @@ static int get_attr_entry(HlEntry entry) return id; } -/// When a UI connects, we need to send it the table of higlights used so far. +/// When a UI connects, we need to send it the table of highlights used so far. void ui_send_all_hls(UI *ui) { for (size_t i = 1; i < kv_size(attr_entries); i++) { @@ -212,13 +212,7 @@ void clear_hl_tables(bool reinit) map_clear(int, int)(combine_attr_entries); highlight_attr_set_all(); highlight_changed(); - redraw_all_later(NOT_VALID); - if (default_grid.ScreenAttrs) { - // the meaning of 0 doesn't change anyway - // but the rest must be retransmitted - memset(default_grid.ScreenAttrs, 0, sizeof(*default_grid.ScreenAttrs) - * (size_t)(default_grid.Rows * default_grid.Columns)); - } + screen_invalidate_highlights(); } else { kv_destroy(attr_entries); map_free(HlEntry, int)(attr_entry_ids); diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index 73748154e7..ead6b4405d 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -556,14 +556,6 @@ size_t mb_string2cells(const char_u *str) return clen; } -/// Return number of display cells for char at ScreenLines[off]. -/// We make sure that the offset used is less than "max_off". -int utf_off2cells(ScreenGrid *grid, unsigned off, unsigned max_off) -{ - return (off + 1 < max_off - && grid->ScreenLines[off + 1][0] == 0) ? 2 : 1; -} - /// Convert a UTF-8 byte sequence to a wide character /// /// If the sequence is illegal or truncated by a NUL then the first byte is diff --git a/src/nvim/move.c b/src/nvim/move.c index ebbcd1b853..b8225cc64c 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -151,7 +151,7 @@ void update_topline(void) long save_so = p_so; // need to have w_grid.Rows/Columns updated - win_grid_alloc(curwin, false); + win_grid_alloc(curwin); // If there is no valid screen and when the window height is zero just use // the cursor line. @@ -529,7 +529,7 @@ int cursor_valid(void) */ void validate_cursor(void) { - win_grid_alloc(curwin, false); // we need to have w_grid.Rows/Columns updated + win_grid_alloc(curwin); // we need to have w_grid.Rows/Columns updated check_cursor_moved(curwin); if ((curwin->w_valid & (VALID_WCOL|VALID_WROW)) != (VALID_WCOL|VALID_WROW)) curs_columns(true); diff --git a/src/nvim/screen.c b/src/nvim/screen.c index c088367c69..079ed049e4 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -146,7 +146,10 @@ typedef struct { #define LINE_STATE(p) { p, 0, 0 } /// Whether to call "ui_call_grid_resize" in win_grid_alloc -static int send_grid_resize; +static bool send_grid_resize = false; + +/// Highlight ids are no longer valid. Force retransmission +static bool highlights_invalid = false; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "screen.c.generated.h" @@ -184,6 +187,12 @@ void redraw_all_later(int type) } } +void screen_invalidate_highlights(void) +{ + redraw_all_later(NOT_VALID); + highlights_invalid = true; +} + /* * Mark all windows that are editing the current buffer to be updated later. */ @@ -353,6 +362,8 @@ void update_screen(int type) type = NOT_VALID; // must_redraw may be set indirectly, avoid another redraw later must_redraw = 0; + } else if (highlights_invalid) { + grid_invalidate(&default_grid); } if (clear_cmdline) /* going to clear cmdline (done below) */ @@ -439,6 +450,7 @@ void update_screen(int type) } } send_grid_resize = false; + highlights_invalid = false; end_search_hl(); // May need to redraw the popup menu. if (pum_drawn()) { @@ -522,7 +534,7 @@ void update_single_line(win_T *wp, linenr_T lnum) prepare_search_hl(wp, lnum); update_window_hl(wp, false); // allocate window grid if not already - win_grid_alloc(wp, false); + win_grid_alloc(wp); win_line(wp, lnum, row, row + wp->w_lines[j].wl_size, false, false); end_search_hl(); break; @@ -680,7 +692,7 @@ static void win_update(win_T *wp) type = wp->w_redr_type; - win_grid_alloc(wp, false); + win_grid_alloc(wp); if (type >= NOT_VALID) { wp->w_redr_status = true; @@ -5984,7 +5996,7 @@ int screen_valid(int doclear) /// /// If "doclear" is true, don't try to copy from the old grid rather clear the /// resized grid. -void win_grid_alloc(win_T *wp, int doclear) +void win_grid_alloc(win_T *wp) { ScreenGrid *grid = &wp->w_grid; int rows = grid->internal_rows; @@ -6002,11 +6014,15 @@ void win_grid_alloc(win_T *wp, int doclear) bool want_allocation = ui_is_external(kUIMultigrid); bool has_allocation = (grid->ScreenLines != NULL); + if (want_allocation && has_allocation && highlights_invalid) { + grid_invalidate(grid); + } + if ((has_allocation != want_allocation) || grid->Rows != rows || grid->Columns != columns) { if (want_allocation) { - grid_alloc(grid, rows, columns, !doclear); + grid_alloc(grid, rows, columns, true); win_free_lsize(wp); win_alloc_lines(wp); } else { @@ -6289,6 +6305,13 @@ static void grid_clear_line(ScreenGrid *grid, unsigned off, int width, (void)memset(grid->ScreenAttrs + off, fill, (size_t)width * sizeof(sattr_T)); } +static void grid_invalidate(ScreenGrid *grid) +{ + (void)memset(grid->ScreenAttrs, -1, + grid->Rows * grid->Columns * sizeof(sattr_T)); +} + + /// Copy part of a Screenline for vertically split window. static void linecopy(ScreenGrid *grid, int to, int from, int col, int width) { diff --git a/src/nvim/window.c b/src/nvim/window.c index 39fc1897ae..7e381e7069 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -4299,7 +4299,6 @@ void win_setheight_win(int height, win_T *win) } frame_setheight(win->w_frame, height + win->w_status_height); - win_grid_alloc(win, false); /* recompute the window positions */ row = win_comp_pos(); @@ -4497,7 +4496,6 @@ void win_setwidth_win(int width, win_T *wp) } frame_setwidth(wp->w_frame, width + wp->w_vsep_width); - win_grid_alloc(wp, false); /* recompute the window positions */ (void)win_comp_pos(); -- cgit From 1cec5542a83baf04848e37475b9b0b7f50e47284 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sun, 23 Dec 2018 14:35:23 +0100 Subject: multigrid: reorganize types and global varaibles --- src/nvim/api/private/defs.h | 3 +-- src/nvim/api/ui.c | 2 +- src/nvim/buffer_defs.h | 2 ++ src/nvim/globals.h | 32 ------------------------ src/nvim/grid_defs.h | 59 +++++++++++++++++++++++++++++++++++++++++++++ src/nvim/screen.c | 2 +- src/nvim/screen.h | 13 ++++++++++ src/nvim/types.h | 35 +++------------------------ src/nvim/ui.c | 4 +-- 9 files changed, 82 insertions(+), 70 deletions(-) create mode 100644 src/nvim/grid_defs.h (limited to 'src') diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h index 390b7e8363..feca140547 100644 --- a/src/nvim/api/private/defs.h +++ b/src/nvim/api/private/defs.h @@ -6,6 +6,7 @@ #include #include "nvim/func_attr.h" +#include "nvim/types.h" #define ARRAY_DICT_INIT {.size = 0, .capacity = 0, .items = NULL} #define STRING_INIT {.data = NULL, .size = 0} @@ -20,8 +21,6 @@ # define DictionaryOf(...) Dictionary #endif -typedef int handle_T; - // Basic types typedef enum { kErrorTypeNone = -1, diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index c374bede99..4c55a56242 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -264,7 +264,7 @@ void nvim_ui_try_resize_grid(uint64_t channel_id, Integer grid, Integer width, return; } - ui_grid_resize((GridHandle)grid, (int)width, (int)height, error); + ui_grid_resize((handle_T)grid, (int)width, (int)height, error); } /// Pushes data into UI.UIData, to be consumed later by remote_ui_flush(). diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index ce83c4561d..05688790c2 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -18,6 +18,8 @@ typedef struct { // for garray_T #include "nvim/garray.h" +// for ScreenGrid +#include "nvim/grid_defs.h" // for HLF_COUNT #include "nvim/highlight_defs.h" // for pos_T, lpos_T and linenr_T diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 7f18262c3f..3447d9eb23 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -129,38 +129,6 @@ typedef off_t off_T; # endif #endif -/// ScreenLines[] contains a copy of the whole screen, as it currently is -/// displayed. It is a single block of screen cells, the size of the screen -/// plus one line. The extra line used as a buffer while redrawing a window -/// line, so it can be compared with the previous state of that line. This way -/// we can avoid sending bigger updates than neccessary to the Ul layer. -/// -/// Screen cells are stored as NUL-terminated UTF-8 strings, and a cell can -/// contain up to MAX_MCO composing characters after the base character. -/// The composing characters are to be drawn on top of the original character. -/// The content after the NUL is not defined (so comparison must be done a -/// single cell at a time). Double-width characters are stored in the left cell, -/// and the right cell should only contain the empty string. When a part of the -/// screen is cleared, the cells should be filled with a single whitespace char. -/// -/// ScreenAttrs[] contains the highlighting attribute for each cell. -/// LineOffset[n] is the offset from ScreenLines[] and ScreenAttrs[] for the -/// start of line 'n'. These offsets are in general not linear, as full screen -/// scrolling is implemented by rotating the offsets in the LineOffset array. -/// LineWraps[] is an array of boolean flags indicating if the screen line wraps -/// to the next line. It can only be true if a window occupies the entire screen -/// width. -/// -/// These, with other related attributes, are stored in a "ScreenGrid" -/// datastructure. -/// -/// Note: before the screen is initialized and when out of memory these can be -/// NULL. -EXTERN ScreenGrid default_grid INIT(= { 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0, - 0, 0, 0 }); - -#define DEFAULT_GRID_HANDLE 1 // handle for the default_grid - /* * When vgetc() is called, it sets mod_mask to the set of modifiers that are * held down based on the MOD_MASK_* symbols that are read first. diff --git a/src/nvim/grid_defs.h b/src/nvim/grid_defs.h new file mode 100644 index 0000000000..964a71de62 --- /dev/null +++ b/src/nvim/grid_defs.h @@ -0,0 +1,59 @@ +#ifndef NVIM_GRID_DEFS_H +#define NVIM_GRID_DEFS_H + +#include + +#include "nvim/types.h" + +#define MAX_MCO 6 // maximum value for 'maxcombine' + +// The characters and attributes drawn on grids. +typedef char_u schar_T[(MAX_MCO+1) * 4 + 1]; +typedef int16_t sattr_T; + +/// ScreenGrid represents a resizable rectuangular grid displayed by UI clients. +/// +/// ScreenLines contains the UTF-8 text that is currently displayed on the grid. +/// It is stored as a single block of cells. When redrawing a part of the grid, +/// the new state can be compared with the existing state of the grid. This way +/// we can avoid sending bigger updates than neccessary to the Ul layer. +/// +/// Screen cells are stored as NUL-terminated UTF-8 strings, and a cell can +/// contain up to MAX_MCO composing characters after the base character. +/// The composing characters are to be drawn on top of the original character. +/// The content after the NUL is not defined (so comparison must be done a +/// single cell at a time). Double-width characters are stored in the left cell, +/// and the right cell should only contain the empty string. When a part of the +/// screen is cleared, the cells should be filled with a single whitespace char. +/// +/// ScreenAttrs[] contains the highlighting attribute for each cell. +/// LineOffset[n] is the offset from ScreenLines[] and ScreenAttrs[] for the +/// start of line 'n'. These offsets are in general not linear, as full screen +/// scrolling is implemented by rotating the offsets in the LineOffset array. +/// LineWraps[] is an array of boolean flags indicating if the screen line wraps +/// to the next line. It can only be true if a window occupies the entire screen +/// width. +typedef struct { + handle_T handle; + + schar_T *ScreenLines; + sattr_T *ScreenAttrs; + unsigned *LineOffset; + char_u *LineWraps; + + // the size of the allocated grid + int Rows; + int Columns; + + // offsets for the grid relative to the global screen + int OffsetRow; + int OffsetColumn; + + // the size expected to be allocated to the internal grid + int internal_rows; + int internal_columns; + + int was_resized; +} ScreenGrid; + +#endif // NVIM_GRID_DEFS_H diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 079ed049e4..42c78e5a6a 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -7352,7 +7352,7 @@ void win_new_shellsize(void) } } -win_T * get_win_by_grid_handle(GridHandle handle) +win_T *get_win_by_grid_handle(handle_T handle) { FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { if (wp->w_grid.handle == handle) { diff --git a/src/nvim/screen.h b/src/nvim/screen.h index 17515d4253..109541ef07 100644 --- a/src/nvim/screen.h +++ b/src/nvim/screen.h @@ -5,6 +5,7 @@ #include "nvim/types.h" #include "nvim/buffer_defs.h" +#include "nvim/grid_defs.h" #include "nvim/pos.h" /* @@ -20,6 +21,18 @@ #define NOT_VALID 40 /* buffer needs complete redraw */ #define CLEAR 50 /* screen messed up, clear it */ +/// By default, all widows are draw on a single rectangular grid, represented by +/// this ScreenGrid instance. In multigrid mode each window will have its own +/// grid, then this is only used for global screen elements that hasn't been +/// externalized. +/// +/// Note: before the screen is initialized and when out of memory these can be +/// NULL. +EXTERN ScreenGrid default_grid INIT(= { 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0, + 0, 0, 0 }); + +#define DEFAULT_GRID_HANDLE 1 // handle for the default_grid + /// Status line click definition typedef struct { enum { diff --git a/src/nvim/types.h b/src/nvim/types.h index 6d39caab50..f803b45e27 100644 --- a/src/nvim/types.h +++ b/src/nvim/types.h @@ -13,38 +13,9 @@ typedef unsigned char char_u; // Can hold one decoded UTF-8 character. typedef uint32_t u8char_T; -typedef struct expand expand_T; - -#define MAX_MCO 6 // maximum value for 'maxcombine' - - -// The characters and attributes cached for the screen. -typedef char_u schar_T[(MAX_MCO+1) * 4 + 1]; -typedef int16_t sattr_T; - -// TODO(bfredl): find me a good home -typedef int GridHandle; -typedef struct { - GridHandle handle; +// Opaque handle used by API clients to refer to various objects in vim +typedef int handle_T; - schar_T *ScreenLines; - sattr_T *ScreenAttrs; - unsigned *LineOffset; - char_u *LineWraps; - - // the size of the allocated grid - int Rows; - int Columns; - - // offsets for the grid relative to the screen - int OffsetRow; - int OffsetColumn; - - // the size expected to be allocated to the internal grid - int internal_rows; - int internal_columns; - - int was_resized; -} ScreenGrid; +typedef struct expand expand_T; #endif // NVIM_TYPES_H diff --git a/src/nvim/ui.c b/src/nvim/ui.c index da6a1d0f2a..302aa555af 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -57,7 +57,7 @@ static int busy = 0; static int mode_idx = SHAPE_IDX_N; static bool pending_mode_info_update = false; static bool pending_mode_update = false; -static GridHandle cursor_grid_handle = DEFAULT_GRID_HANDLE; +static handle_T cursor_grid_handle = DEFAULT_GRID_HANDLE; #if MIN_LOG_LEVEL > DEBUG_LOG_LEVEL # define UI_LOG(funname, ...) @@ -443,7 +443,7 @@ Array ui_array(void) return all_uis; } -void ui_grid_resize(GridHandle grid_handle, int width, int height, Error *error) +void ui_grid_resize(handle_T grid_handle, int width, int height, Error *error) { if (grid_handle == DEFAULT_GRID_HANDLE) { screen_resize(width, height); -- cgit From dc4430933648c908bdabcd4ed6c782efffbec4f2 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sun, 23 Dec 2018 15:06:28 +0100 Subject: multigrid: rename to grid.row_offset and grid.requested_rows --- src/nvim/grid_defs.h | 12 +++++------ src/nvim/screen.c | 57 ++++++++++++++++++++++++++-------------------------- src/nvim/ui.c | 12 +++++------ 3 files changed, 41 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/nvim/grid_defs.h b/src/nvim/grid_defs.h index 964a71de62..006a07bfb4 100644 --- a/src/nvim/grid_defs.h +++ b/src/nvim/grid_defs.h @@ -41,17 +41,17 @@ typedef struct { unsigned *LineOffset; char_u *LineWraps; - // the size of the allocated grid + // the size of the allocated grid. int Rows; int Columns; // offsets for the grid relative to the global screen - int OffsetRow; - int OffsetColumn; + int row_offset; + int col_offset; - // the size expected to be allocated to the internal grid - int internal_rows; - int internal_columns; + // grid size requested by the UI. Used for window grids only. + int requested_rows; + int requested_cols; int was_resized; } ScreenGrid; diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 42c78e5a6a..8fcb189b9c 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -4269,7 +4269,7 @@ win_line ( // if we're not in ext_multigrid mode, grid has not been allocated; keep // working on the default_grid. if (!ui_is_external(kUIMultigrid)) { - current_row += grid->OffsetRow; + current_row += grid->row_offset; current_grid = &default_grid; } @@ -4397,8 +4397,8 @@ static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, // If UI is not externalized, merge the contents of global and window grids if (!ui_is_external(kUIMultigrid) && grid != &default_grid) { - row += grid->OffsetRow; - coloff += grid->OffsetColumn; + row += grid->row_offset; + coloff += grid->col_offset; grid = &default_grid; } @@ -5303,8 +5303,8 @@ static int grid_off2cells(ScreenGrid *grid, size_t off, size_t max_off) bool grid_lefthalve(ScreenGrid *grid, int row, int col) { if (!ui_is_external(kUIMultigrid)) { - row += grid->OffsetRow; - col += grid->OffsetColumn; + row += grid->row_offset; + col += grid->col_offset; grid = &default_grid; } @@ -5318,8 +5318,8 @@ int grid_fix_col(ScreenGrid *grid, int col, int row) { int coloff = 0; if (!ui_is_external(kUIMultigrid)) { - row += grid->OffsetRow; - coloff = grid->OffsetColumn; + row += grid->row_offset; + coloff = grid->col_offset; grid = &default_grid; } @@ -5348,8 +5348,8 @@ void grid_getbytes(ScreenGrid *grid, int row, int col, char_u *bytes, unsigned off; if (!ui_is_external(kUIMultigrid)) { - row += grid->OffsetRow; - col += grid->OffsetColumn; + row += grid->row_offset; + col += grid->col_offset; grid = &default_grid; } @@ -5410,8 +5410,8 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, // If UI is not externalized, keep working on the default grid if (!ui_is_external(kUIMultigrid) && grid != &default_grid) { - row += grid->OffsetRow; - col += grid->OffsetColumn; + row += grid->row_offset; + col += grid->col_offset; grid = &default_grid; } @@ -5870,10 +5870,10 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, // if grids are not externalized, keep working on the default_grid if (!ui_is_external(kUIMultigrid) && grid != &default_grid) { - start_row += grid->OffsetRow; - end_row += grid->OffsetRow; - start_col += grid->OffsetColumn; - end_col += grid->OffsetColumn; + start_row += grid->row_offset; + end_row += grid->row_offset; + start_col += grid->col_offset; + end_col += grid->col_offset; grid = &default_grid; } @@ -5999,13 +5999,13 @@ int screen_valid(int doclear) void win_grid_alloc(win_T *wp) { ScreenGrid *grid = &wp->w_grid; - int rows = grid->internal_rows; - int columns = grid->internal_columns; - int was_resized = false; + int rows = grid->requested_rows; if (rows == 0) { rows = wp->w_height; } + + int columns = grid->requested_cols; if (columns == 0) { columns = wp->w_width; } @@ -6018,6 +6018,7 @@ void win_grid_alloc(win_T *wp) grid_invalidate(grid); } + int was_resized = false; if ((has_allocation != want_allocation) || grid->Rows != rows || grid->Columns != columns) { @@ -6035,8 +6036,8 @@ void win_grid_alloc(win_T *wp) was_resized = true; } - grid->OffsetRow = wp->w_winrow; - grid->OffsetColumn = wp->w_wincol; + grid->row_offset = wp->w_winrow; + grid->col_offset = wp->w_wincol; // send grid resize event if: // - a grid was just resized @@ -6141,8 +6142,8 @@ retry: tab_page_click_defs = new_tab_page_click_defs; tab_page_click_defs_size = default_grid.Columns; - default_grid.OffsetRow = 0; - default_grid.OffsetColumn = 0; + default_grid.row_offset = 0; + default_grid.col_offset = 0; default_grid.handle = DEFAULT_GRID_HANDLE; must_redraw = CLEAR; /* need to clear the screen later */ @@ -6413,9 +6414,9 @@ int grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col, // If UI is not externalized, keep working on default grid if (!ui_is_external(kUIMultigrid) && grid != &default_grid) { - row += grid->OffsetRow; - end += grid->OffsetRow; - col += grid->OffsetColumn; + row += grid->row_offset; + end += grid->row_offset; + col += grid->col_offset; grid = &default_grid; } @@ -6468,9 +6469,9 @@ int grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col, // If UI is not externalized, keep working on default grid if (!ui_is_external(kUIMultigrid) && grid != &default_grid) { - row += grid->OffsetRow; - end += grid->OffsetRow; - col += grid->OffsetColumn; + row += grid->row_offset; + end += grid->row_offset; + col += grid->col_offset; grid = &default_grid; } diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 302aa555af..fd134e626f 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -321,8 +321,8 @@ void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol, int clearattr, bool wrap) { size_t off = grid->LineOffset[row] + (size_t)startcol; - int row_off = ui_is_external(kUIMultigrid) ? 0 : grid->OffsetRow; - int col_off = ui_is_external(kUIMultigrid) ? 0 : grid->OffsetColumn; + int row_off = ui_is_external(kUIMultigrid) ? 0 : grid->row_offset; + int col_off = ui_is_external(kUIMultigrid) ? 0 : grid->col_offset; UI_CALL(raw_line, grid->handle, row_off + row, col_off + startcol, col_off + endcol, col_off + clearcol, clearattr, wrap, @@ -347,8 +347,8 @@ void ui_cursor_goto(int new_row, int new_col) void ui_grid_cursor_goto(ScreenGrid *grid, int new_row, int new_col) { - new_row += ui_is_external(kUIMultigrid) ? 0 : grid->OffsetRow; - new_col += ui_is_external(kUIMultigrid) ? 0 : grid->OffsetColumn; + new_row += ui_is_external(kUIMultigrid) ? 0 : grid->row_offset; + new_col += ui_is_external(kUIMultigrid) ? 0 : grid->col_offset; int handle = ui_is_external(kUIMultigrid) ? grid->handle : DEFAULT_GRID_HANDLE; @@ -457,7 +457,7 @@ void ui_grid_resize(handle_T grid_handle, int width, int height, Error *error) return; } - wp->w_grid.internal_rows = (int)height; - wp->w_grid.internal_columns = (int)width; + wp->w_grid.requested_rows = (int)height; + wp->w_grid.requested_cols = (int)width; redraw_win_later(wp, SOME_VALID); } -- cgit From c778c2e107d7c9453b22e45bf8ec595956ea1538 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Mon, 31 Dec 2018 12:54:57 +0100 Subject: multigrid: API version bump --- src/nvim/api/ui.c | 2 +- src/nvim/api/ui_events.in.h | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 4c55a56242..7ba5251c60 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -256,7 +256,7 @@ static void ui_set_option(UI *ui, bool init, String name, Object value, /// @param height The new requested height. void nvim_ui_try_resize_grid(uint64_t channel_id, Integer grid, Integer width, Integer height, Error *error) - FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY + FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY { if (!pmap_has(uint64_t)(connected_uis, channel_id)) { api_set_error(error, kErrorTypeException, diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h index 28beebb9e4..59a7780651 100644 --- a/src/nvim/api/ui_events.in.h +++ b/src/nvim/api/ui_events.in.h @@ -82,17 +82,17 @@ void grid_scroll(Integer grid, Integer top, Integer bot, Integer left, Integer right, Integer rows, Integer cols) FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL; void grid_destroy(Integer grid) - FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; + FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY; void win_pos(Integer grid, Integer win, Integer startrow, Integer startcol, Integer width, Integer height) - FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; + FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY; void win_hide(Integer grid) - FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; + FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY; void win_scroll_over_start(void) - FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; + FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY; void win_scroll_over_reset(void) - FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; + FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY; void popupmenu_show(Array items, Integer selected, Integer row, Integer col, Integer grid) -- cgit From c72d9ce0a602ba53b99145f64f0d43327a4e3eb3 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Mon, 31 Dec 2018 13:29:58 +0100 Subject: multigrid: rename grid->ScreenLines and other grid arrays --- src/nvim/api/vim.c | 6 +- src/nvim/edit.c | 2 +- src/nvim/eval.c | 6 +- src/nvim/globals.h | 9 +- src/nvim/grid_defs.h | 22 ++-- src/nvim/mouse.c | 6 +- src/nvim/screen.c | 294 +++++++++++++++++++++++++-------------------------- src/nvim/ui.c | 6 +- src/nvim/window.c | 2 +- 9 files changed, 171 insertions(+), 182 deletions(-) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 82a61b43bd..2a724a85ec 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1924,9 +1924,9 @@ Array nvim__inspect_cell(Integer row, Integer col, Error *err) || col < 0 || col >= default_grid.Columns) { return ret; } - size_t off = default_grid.LineOffset[(size_t)row] + (size_t)col; - ADD(ret, STRING_OBJ(cstr_to_string((char *)default_grid.ScreenLines[off]))); - int attr = default_grid.ScreenAttrs[off]; + size_t off = default_grid.line_offset[(size_t)row] + (size_t)col; + ADD(ret, STRING_OBJ(cstr_to_string((char *)default_grid.chars[off]))); + int attr = default_grid.attrs[off]; ADD(ret, DICTIONARY_OBJ(hl_get_attr_by_id(attr, true, err))); // will not work first time if (!highlight_use_hlstate()) { diff --git a/src/nvim/edit.c b/src/nvim/edit.c index eb81ee9320..41a2be6ad4 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -1494,7 +1494,7 @@ void edit_putchar(int c, int highlight) { int attr; - if (curwin->w_grid.ScreenLines != NULL || default_grid.ScreenLines != NULL) { + if (curwin->w_grid.chars != NULL || default_grid.chars != NULL) { update_topline(); // just in case w_topline isn't valid validate_cursor(); if (highlight) { diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 957a8c4ef1..3a231ab8f1 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -14027,7 +14027,7 @@ static void f_screenattr(typval_T *argvars, typval_T *rettv, FunPtr fptr) || col < 0 || col >= default_grid.Columns) { c = -1; } else { - c = default_grid.ScreenAttrs[default_grid.LineOffset[row] + col]; + c = default_grid.attrs[default_grid.line_offset[row] + col]; } rettv->vval.v_number = c; } @@ -14046,8 +14046,8 @@ static void f_screenchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) || col < 0 || col >= default_grid.Columns) { c = -1; } else { - off = default_grid.LineOffset[row] + col; - c = utf_ptr2char(default_grid.ScreenLines[off]); + off = default_grid.line_offset[row] + col; + c = utf_ptr2char(default_grid.chars[off]); } rettv->vval.v_number = c; } diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 3447d9eb23..f2bd6408e8 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -92,7 +92,7 @@ EXTERN struct nvim_stats_s { * Number of Rows and Columns in the screen. * Must be long to be able to use them as options in option.c. * Note: Use default_grid.Rows and default_grid.Columns to access items in - * default_grid.ScreenLines[]. They may have different values when the screen + * default_grid.chars[]. They may have different values when the screen * wasn't (re)allocated yet after setting Rows or Columns (e.g., when starting * up). */ @@ -190,11 +190,8 @@ EXTERN int compl_cont_status INIT(= 0); # define CONT_LOCAL 32 /* for ctrl_x_mode 0, ^X^P/^X^N do a local * expansion, (eg use complete=.) */ -/* - * Functions for putting characters in the command line, - * while keeping ScreenLines[] updated. - */ -EXTERN int cmdmsg_rl INIT(= FALSE); /* cmdline is drawn right to left */ +// state for putting characters in the message area +EXTERN int cmdmsg_rl INIT(= false); // cmdline is drawn right to left EXTERN int msg_col; EXTERN int msg_row; EXTERN int msg_scrolled; /* Number of screen lines that windows have diff --git a/src/nvim/grid_defs.h b/src/nvim/grid_defs.h index 006a07bfb4..37d85ead0c 100644 --- a/src/nvim/grid_defs.h +++ b/src/nvim/grid_defs.h @@ -13,7 +13,7 @@ typedef int16_t sattr_T; /// ScreenGrid represents a resizable rectuangular grid displayed by UI clients. /// -/// ScreenLines contains the UTF-8 text that is currently displayed on the grid. +/// chars[] contains the UTF-8 text that is currently displayed on the grid. /// It is stored as a single block of cells. When redrawing a part of the grid, /// the new state can be compared with the existing state of the grid. This way /// we can avoid sending bigger updates than neccessary to the Ul layer. @@ -26,20 +26,20 @@ typedef int16_t sattr_T; /// and the right cell should only contain the empty string. When a part of the /// screen is cleared, the cells should be filled with a single whitespace char. /// -/// ScreenAttrs[] contains the highlighting attribute for each cell. -/// LineOffset[n] is the offset from ScreenLines[] and ScreenAttrs[] for the +/// attrs[] contains the highlighting attribute for each cell. +/// line_offset[n] is the offset from chars[] and attrs[] for the /// start of line 'n'. These offsets are in general not linear, as full screen -/// scrolling is implemented by rotating the offsets in the LineOffset array. -/// LineWraps[] is an array of boolean flags indicating if the screen line wraps -/// to the next line. It can only be true if a window occupies the entire screen -/// width. +/// scrolling is implemented by rotating the offsets in the line_offset array. +/// line_wraps[] is an array of boolean flags indicating if the screen line +/// wraps to the next line. It can only be true if a window occupies the entire +/// screen width. typedef struct { handle_T handle; - schar_T *ScreenLines; - sattr_T *ScreenAttrs; - unsigned *LineOffset; - char_u *LineWraps; + schar_T *chars; + sattr_T *attrs; + unsigned *line_offset; + char_u *line_wraps; // the size of the allocated grid. int Rows; diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index fe5918eae4..3790886194 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -110,9 +110,9 @@ retnomove: // Remember the character under the mouse, it might be a '-' or '+' in the // fold column. NB: only works for ASCII chars! if (row >= 0 && row < Rows && col >= 0 && col <= Columns - && default_grid.ScreenLines != NULL) { - mouse_char = default_grid.ScreenLines[default_grid.LineOffset[row] - + (unsigned)col][0]; + && default_grid.chars != NULL) { + mouse_char = default_grid.chars[default_grid.line_offset[row] + + (unsigned)col][0]; } else { mouse_char = ' '; } diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 8fcb189b9c..770e00a80e 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -7,8 +7,7 @@ // by remembering what is already on the screen, and only updating the parts // that changed. // -// The screen_*() functions write to the screen and handle updating -// ScreenLines[]. +// The grid_*() functions write to the screen and handle updating grid->lines[]. // // update_screen() is the function that updates all windows and status lines. // It is called from the main loop when must_redraw is non-zero. It may be @@ -253,12 +252,12 @@ void update_curbuf(int type) update_screen(type); } -/* - * update_screen() - * - * Based on the current value of curwin->w_topline, transfer a screenfull - * of stuff from Filemem to ScreenLines[], and update curwin->w_botline. - */ +/// Redraw the parts of the screen that is marked for redraw. +/// +/// Most code shouldn't call this directly, rather use redraw_later() and +/// and redraw_all_later() to mark parts of the screen as needing a redraw. +/// +/// @param type set to a NOT_VALID to force redraw of entire screen void update_screen(int type) { static int did_intro = FALSE; @@ -2046,7 +2045,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T } -/// Copy "buf[len]" to ScreenLines["off"] and set attributes to "attr". +/// Copy "buf[len]" to linebuf_char["off"] and set attributes to "attr". /// /// Only works for ASCII text! static void copy_text_attr(int off, char_u *buf, int len, int attr) @@ -3529,8 +3528,7 @@ win_line ( */ if (!vim_isprintc(c)) { // when getting a character from the file, we may have to - // turn it into something else on the way to putting it - // into "ScreenLines". + // turn it into something else on the way to putting it on the screen. if (c == TAB && (!wp->w_p_list || lcs_tab1)) { int tab_len = 0; long vcol_adjusted = vcol; // removed showbreak length @@ -4274,10 +4272,10 @@ win_line ( } // Force a redraw of the first column of the next line. - current_grid->ScreenAttrs[current_grid->LineOffset[current_row+1]] = -1; + current_grid->attrs[current_grid->line_offset[current_row+1]] = -1; // Remember that the line wraps, used for modeless copy. - current_grid->LineWraps[current_row] = true; + current_grid->line_wraps[current_row] = true; } boguscols = 0; @@ -4352,11 +4350,11 @@ static int grid_char_needs_redraw(ScreenGrid *grid, int off_from, int off_to, int cols) { return (cols > 0 - && ((schar_cmp(linebuf_char[off_from], grid->ScreenLines[off_to]) - || linebuf_attr[off_from] != grid->ScreenAttrs[off_to] + && ((schar_cmp(linebuf_char[off_from], grid->chars[off_to]) + || linebuf_attr[off_from] != grid->attrs[off_to] || (line_off2cells(linebuf_char, off_from, off_from + cols) > 1 && schar_cmp(linebuf_char[off_from + 1], - grid->ScreenLines[off_to + 1]))) + grid->chars[off_to + 1]))) || p_wd < 0)); } @@ -4403,16 +4401,16 @@ static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, } off_from = 0; - off_to = grid->LineOffset[row] + coloff; + off_to = grid->line_offset[row] + coloff; max_off_from = linebuf_size; - max_off_to = grid->LineOffset[row] + grid->Columns; + max_off_to = grid->line_offset[row] + grid->Columns; if (rlflag) { /* Clear rest first, because it's left of the text. */ if (clear_width > 0) { - while (col <= endcol && grid->ScreenLines[off_to][0] == ' ' - && grid->ScreenLines[off_to][1] == NUL - && grid->ScreenAttrs[off_to] == bg_attr + while (col <= endcol && grid->chars[off_to][0] == ' ' + && grid->chars[off_to][1] == NUL + && grid->attrs[off_to] == bg_attr ) { ++off_to; ++col; @@ -4423,7 +4421,7 @@ static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, } } col = endcol + 1; - off_to = grid->LineOffset[row] + col + coloff; + off_to = grid->line_offset[row] + col + coloff; off_from += col; endcol = (clear_width > 0 ? clear_width : -clear_width); } @@ -4466,16 +4464,16 @@ static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, clear_next = true; } - schar_copy(grid->ScreenLines[off_to], linebuf_char[off_from]); + schar_copy(grid->chars[off_to], linebuf_char[off_from]); if (char_cells == 2) { - schar_copy(grid->ScreenLines[off_to+1], linebuf_char[off_from+1]); + schar_copy(grid->chars[off_to+1], linebuf_char[off_from+1]); } - grid->ScreenAttrs[off_to] = linebuf_attr[off_from]; + grid->attrs[off_to] = linebuf_attr[off_from]; // For simplicity set the attributes of second half of a // double-wide character equal to the first half. if (char_cells == 2) { - grid->ScreenAttrs[off_to + 1] = linebuf_attr[off_from]; + grid->attrs[off_to + 1] = linebuf_attr[off_from]; } } @@ -4487,7 +4485,7 @@ static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, if (clear_next) { /* Clear the second half of a double-wide character of which the left * half was overwritten with a single-wide character. */ - schar_from_ascii(grid->ScreenLines[off_to], ' '); + schar_from_ascii(grid->chars[off_to], ' '); end_dirty++; } @@ -4496,12 +4494,12 @@ static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, // blank out the rest of the line // TODO(bfredl): we could cache winline widths while (col < clear_width) { - if (grid->ScreenLines[off_to][0] != ' ' - || grid->ScreenLines[off_to][1] != NUL - || grid->ScreenAttrs[off_to] != bg_attr) { - grid->ScreenLines[off_to][0] = ' '; - grid->ScreenLines[off_to][1] = NUL; - grid->ScreenAttrs[off_to] = bg_attr; + if (grid->chars[off_to][0] != ' ' + || grid->chars[off_to][1] != NUL + || grid->attrs[off_to] != bg_attr) { + grid->chars[off_to][0] = ' '; + grid->chars[off_to][1] = NUL; + grid->attrs[off_to] = bg_attr; if (start_dirty == -1) { start_dirty = col; end_dirty = col; @@ -4518,7 +4516,7 @@ static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, if (clear_width > 0 || wp->w_width != grid->Columns) { // If we cleared after the end of the line, it did not wrap. // For vsplit, line wrapping is not possible. - grid->LineWraps[row] = false; + grid->line_wraps[row] = false; } if (clear_end < end_dirty) { @@ -5289,11 +5287,11 @@ static int line_off2cells(schar_T *line, size_t off, size_t max_off) return (off + 1 < max_off && line[off + 1][0] == 0) ? 2 : 1; } -/// Return number of display cells for char at ScreenLines[off]. +/// Return number of display cells for char at grid->chars[off]. /// We make sure that the offset used is less than "max_off". static int grid_off2cells(ScreenGrid *grid, size_t off, size_t max_off) { - return line_off2cells(grid->ScreenLines, off, max_off); + return line_off2cells(grid->chars, off, max_off); } /// Return true if the character at "row"/"col" on the screen is the left side @@ -5308,8 +5306,8 @@ bool grid_lefthalve(ScreenGrid *grid, int row, int col) grid = &default_grid; } - return grid_off2cells(grid, grid->LineOffset[row] + col, - grid->LineOffset[row] + grid->Columns) > 1; + return grid_off2cells(grid, grid->line_offset[row] + col, + grid->line_offset[row] + grid->Columns) > 1; } /// Correct a position on the screen, if it's the right half of a double-wide @@ -5324,14 +5322,14 @@ int grid_fix_col(ScreenGrid *grid, int col, int row) } col += coloff; - if (grid->ScreenLines != NULL && col > 0 - && grid->ScreenLines[grid->LineOffset[row] + col][0] == 0) { + if (grid->chars != NULL && col > 0 + && grid->chars[grid->line_offset[row] + col][0] == 0) { return col - 1 - coloff; } return col - coloff; } -/// output a single character directly to the grid and update ScreenLines. +/// output a single character directly to the grid void grid_putchar(ScreenGrid *grid, int c, int row, int col, int attr) { char_u buf[MB_MAXBYTES + 1]; @@ -5340,7 +5338,7 @@ void grid_putchar(ScreenGrid *grid, int c, int row, int col, int attr) grid_puts(grid, buf, row, col, attr); } -/// get a single character directly from grid.ScreenLines into "bytes[]". +/// get a single character directly from grid.chars into "bytes[]". /// Also return its attribute in *attrp; void grid_getbytes(ScreenGrid *grid, int row, int col, char_u *bytes, int *attrp) @@ -5354,18 +5352,18 @@ void grid_getbytes(ScreenGrid *grid, int row, int col, char_u *bytes, } // safety check - if (grid->ScreenLines != NULL && row < grid->Rows && col < grid->Columns) { - off = grid->LineOffset[row] + col; - *attrp = grid->ScreenAttrs[off]; - schar_copy(bytes, grid->ScreenLines[off]); + if (grid->chars != NULL && row < grid->Rows && col < grid->Columns) { + off = grid->line_offset[row] + col; + *attrp = grid->attrs[off]; + schar_copy(bytes, grid->chars[off]); } } /// put string '*text' on the window grid at position 'row' and 'col', with -/// attributes 'attr', and update ScreenLines[] and ScreenAttrs[]. +/// attributes 'attr', and update chars[] and attrs[]. /// Note: only outputs within one row, message is truncated at grid boundary! -/// Note: if ScreenLines[], row and/or col is invalid, nothing is done. +/// Note: if grid, row and/or col is invalid, nothing is done. void grid_puts(ScreenGrid *grid, char_u *text, int row, int col, int attr) { grid_puts_len(grid, text, -1, row, col, attr); @@ -5416,7 +5414,7 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, } // safety check - if (grid->ScreenLines == NULL || row >= grid->Rows || col >= grid->Columns) { + if (grid->chars == NULL || row >= grid->Rows || col >= grid->Columns) { return; } @@ -5428,13 +5426,13 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, abort(); } } - off = grid->LineOffset[row] + col; + off = grid->line_offset[row] + col; /* When drawing over the right halve of a double-wide char clear out the * left halve. Only needed in a terminal. */ if (col > 0 && col < grid->Columns && grid_fix_col(grid, col, row) != col) { - schar_from_ascii(grid->ScreenLines[off - 1], ' '); - grid->ScreenAttrs[off - 1] = 0; + schar_from_ascii(grid->chars[off - 1], ' '); + grid->attrs[off - 1] = 0; // redraw the previous cell, make it empty if (put_dirty_first == -1) { put_dirty_first = col-1; @@ -5444,7 +5442,7 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, force_redraw_next = true; } - max_off = grid->LineOffset[row] + grid->Columns; + max_off = grid->line_offset[row] + grid->Columns; while (col < grid->Columns && (len < 0 || (int)(ptr - text) < len) && *ptr != NUL) { @@ -5492,9 +5490,9 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, force_redraw_this = force_redraw_next; force_redraw_next = FALSE; - need_redraw = schar_cmp(grid->ScreenLines[off], buf) - || (mbyte_cells == 2 && grid->ScreenLines[off + 1][0] != 0) - || grid->ScreenAttrs[off] != attr + need_redraw = schar_cmp(grid->chars[off], buf) + || (mbyte_cells == 2 && grid->chars[off + 1][0] != 0) + || grid->attrs[off] != attr || exmode_active; if (need_redraw || force_redraw_this) { @@ -5515,11 +5513,11 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, clear_next_cell = true; } - schar_copy(grid->ScreenLines[off], buf); - grid->ScreenAttrs[off] = attr; + schar_copy(grid->chars[off], buf); + grid->attrs[off] = attr; if (mbyte_cells == 2) { - grid->ScreenLines[off + 1][0] = 0; - grid->ScreenAttrs[off + 1] = attr; + grid->chars[off + 1][0] = 0; + grid->attrs[off + 1] = attr; } if (put_dirty_first == -1) { put_dirty_first = col; @@ -5886,9 +5884,7 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, } // nothing to do - if (grid->ScreenLines == NULL - || start_row >= end_row - || start_col >= end_col) { + if (grid->chars == NULL || start_row >= end_row || start_col >= end_col) { return; } @@ -5915,13 +5911,13 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int col = start_col; schar_from_char(sc, c1); - int lineoff = grid->LineOffset[row]; + int lineoff = grid->line_offset[row]; for (col = start_col; col < end_col; col++) { int off = lineoff + col; - if (schar_cmp(grid->ScreenLines[off], sc) - || grid->ScreenAttrs[off] != attr) { - schar_copy(grid->ScreenLines[off], sc); - grid->ScreenAttrs[off] = attr; + if (schar_cmp(grid->chars[off], sc) + || grid->attrs[off] != attr) { + schar_copy(grid->chars[off], sc); + grid->attrs[off] = attr; if (dirty_first == INT_MAX) { dirty_first = col; } @@ -5945,7 +5941,7 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, } if (end_col == grid->Columns) { - grid->LineWraps[row] = false; + grid->line_wraps[row] = false; } // TODO(bfredl): The relevant caller should do this @@ -5988,7 +5984,7 @@ void check_for_delay(int check_msg_scroll) int screen_valid(int doclear) { screenalloc(doclear); // allocate screen buffers if size changed - return default_grid.ScreenLines != NULL; + return default_grid.chars != NULL; } /// (Re)allocates a window grid if size changed while in ext_multigrid mode. @@ -6012,7 +6008,7 @@ void win_grid_alloc(win_T *wp) // TODO(bfredl): floating windows should force this to true bool want_allocation = ui_is_external(kUIMultigrid); - bool has_allocation = (grid->ScreenLines != NULL); + bool has_allocation = (grid->chars != NULL); if (want_allocation && has_allocation && highlights_invalid) { grid_invalidate(grid); @@ -6059,17 +6055,16 @@ void grid_assign_handle(ScreenGrid *grid) } } -/* - * Resize the shell to Rows and Columns. - * Allocate default_grid.ScreenLines[] and associated items. - * - * There may be some time between setting Rows and Columns and (re)allocating - * default_grid.ScreenLines[]. This happens when starting up and when - * (manually) changing the shell size. Always use default_grid.Rows and - * default_grid.Columns to access items in default_grid.ScreenLines[]. Use Rows - * and Columns for positioning text etc. where the final size of the shell is - * needed. - */ +/// Resize the screen to Rows and Columns. +/// +/// Allocate default_grid.chars[] and other grid arrays. +/// +/// There may be some time between setting Rows and Columns and (re)allocating +/// default_grid arrays. This happens when starting up and when +/// (manually) changing the shell size. Always use default_grid.Rows and +/// default_grid.Columns to access items in default_grid.chars[]. Use Rows +/// and Columns for positioning text etc. where the final size of the shell is +/// needed. void screenalloc(bool doclear) { static bool entered = false; // avoid recursiveness @@ -6079,13 +6074,13 @@ retry: // Allocation of the screen buffers is done only when the size changes and // when Rows and Columns have been set and we have started doing full // screen stuff. - if ((default_grid.ScreenLines != NULL + if ((default_grid.chars != NULL && Rows == default_grid.Rows && Columns == default_grid.Columns ) || Rows == 0 || Columns == 0 - || (!full_screen && default_grid.ScreenLines == NULL)) { + || (!full_screen && default_grid.chars == NULL)) { return; } @@ -6108,17 +6103,15 @@ retry: comp_col(); /* recompute columns for shown command and ruler */ - /* - * We're changing the size of the screen. - * - Allocate new arrays for ScreenLines and ScreenAttrs. - * - Move lines from the old arrays into the new arrays, clear extra - * lines (unless the screen is going to be cleared). - * - Free the old arrays. - * - * If anything fails, make ScreenLines NULL, so we don't do anything! - * Continuing with the old ScreenLines may result in a crash, because the - * size is wrong. - */ + // We're changing the size of the screen. + // - Allocate new arrays for default_grid + // - Move lines from the old arrays into the new arrays, clear extra + // lines (unless the screen is going to be cleared). + // - Free the old arrays. + // + // If anything fails, make grid arrays NULL, so we don't do anything! + // Continuing with the old arrays may result in a crash, because the + // size is wrong. FOR_ALL_TAB_WINDOWS(tp, wp) { win_free_lsize(wp); } @@ -6172,32 +6165,32 @@ void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy) ScreenGrid new = *grid; size_t ncells = (size_t)((rows+1) * columns); - new.ScreenLines = xmalloc(ncells * sizeof(schar_T)); - new.ScreenAttrs = xmalloc(ncells * sizeof(sattr_T)); - new.LineOffset = xmalloc((size_t)(rows * sizeof(unsigned))); - new.LineWraps = xmalloc((size_t)(rows * sizeof(char_u))); + new.chars = xmalloc(ncells * sizeof(schar_T)); + new.attrs = xmalloc(ncells * sizeof(sattr_T)); + new.line_offset = xmalloc((size_t)(rows * sizeof(unsigned))); + new.line_wraps = xmalloc((size_t)(rows * sizeof(char_u))); new.Rows = rows; new.Columns = columns; for (new_row = 0; new_row < new.Rows; new_row++) { - new.LineOffset[new_row] = new_row * new.Columns; - new.LineWraps[new_row] = false; + new.line_offset[new_row] = new_row * new.Columns; + new.line_wraps[new_row] = false; - grid_clear_line(&new, new.LineOffset[new_row], columns, true); + grid_clear_line(&new, new.line_offset[new_row], columns, true); if (copy) { // If the screen is not going to be cleared, copy as much as // possible from the old screen to the new one and clear the rest // (used when resizing the window at the "--more--" prompt or when // executing an external command, for the GUI). - if (new_row < grid->Rows && grid->ScreenLines != NULL) { + if (new_row < grid->Rows && grid->chars != NULL) { int len = MIN(grid->Columns, new.Columns); - memmove(new.ScreenLines + new.LineOffset[new_row], - grid->ScreenLines + grid->LineOffset[new_row], + memmove(new.chars + new.line_offset[new_row], + grid->chars + grid->line_offset[new_row], (size_t)len * sizeof(schar_T)); - memmove(new.ScreenAttrs + new.LineOffset[new_row], - grid->ScreenAttrs + grid->LineOffset[new_row], + memmove(new.attrs + new.line_offset[new_row], + grid->attrs + grid->line_offset[new_row], (size_t)len * sizeof(sattr_T)); } } @@ -6218,15 +6211,15 @@ void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy) void grid_free(ScreenGrid *grid) { - xfree(grid->ScreenLines); - xfree(grid->ScreenAttrs); - xfree(grid->LineOffset); - xfree(grid->LineWraps); - - grid->ScreenLines = NULL; - grid->ScreenAttrs = NULL; - grid->LineOffset = NULL; - grid->LineWraps = NULL; + xfree(grid->chars); + xfree(grid->attrs); + xfree(grid->line_offset); + xfree(grid->line_wraps); + + grid->chars = NULL; + grid->attrs = NULL; + grid->line_offset = NULL; + grid->line_wraps = NULL; } /// Doesn't allow reinit, so must only be called by free_all_mem! @@ -6265,15 +6258,15 @@ static void screenclear2(void) { int i; - if (starting == NO_SCREEN || default_grid.ScreenLines == NULL) { + if (starting == NO_SCREEN || default_grid.chars == NULL) { return; } - // blank out ScreenLines + // blank out the default grid for (i = 0; i < default_grid.Rows; i++) { - grid_clear_line(&default_grid, default_grid.LineOffset[i], + grid_clear_line(&default_grid, default_grid.line_offset[i], (int)default_grid.Columns, true); - default_grid.LineWraps[i] = false; + default_grid.line_wraps[i] = false; } ui_call_grid_clear(1); // clear the display @@ -6300,28 +6293,27 @@ static void grid_clear_line(ScreenGrid *grid, unsigned off, int width, bool valid) { for (int col = 0; col < width; col++) { - schar_from_ascii(grid->ScreenLines[off + col], ' '); + schar_from_ascii(grid->chars[off + col], ' '); } int fill = valid ? 0 : -1; - (void)memset(grid->ScreenAttrs + off, fill, (size_t)width * sizeof(sattr_T)); + (void)memset(grid->attrs + off, fill, (size_t)width * sizeof(sattr_T)); } static void grid_invalidate(ScreenGrid *grid) { - (void)memset(grid->ScreenAttrs, -1, - grid->Rows * grid->Columns * sizeof(sattr_T)); + (void)memset(grid->attrs, -1, grid->Rows * grid->Columns * sizeof(sattr_T)); } -/// Copy part of a Screenline for vertically split window. +/// Copy part of a grid line for vertically split window. static void linecopy(ScreenGrid *grid, int to, int from, int col, int width) { - unsigned off_to = grid->LineOffset[to] + col; - unsigned off_from = grid->LineOffset[from] + col; + unsigned off_to = grid->line_offset[to] + col; + unsigned off_from = grid->line_offset[from] + col; - memmove(grid->ScreenLines + off_to, grid->ScreenLines + off_from, + memmove(grid->chars + off_to, grid->chars + off_from, width * sizeof(schar_T)); - memmove(grid->ScreenAttrs + off_to, grid->ScreenAttrs + off_from, + memmove(grid->attrs + off_to, grid->attrs + off_from, width * sizeof(sattr_T)); } @@ -6397,7 +6389,7 @@ static int win_do_lines(win_T *wp, int row, int line_count, int del) */ -/// insert lines on the screen and update ScreenLines[] +/// insert lines on the screen and move the existing lines down /// 'line_count' is the number of lines to be inserted. /// 'end' is the line after the scrolled part. Normally it is Rows. /// 'col' is the column from with we start inserting. @@ -6424,8 +6416,8 @@ int grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col, return FAIL; } - // Shift LineOffset[] line_count down to reflect the inserted lines. - // Clear the inserted lines in ScreenLines[]. + // Shift line_offset[] line_count down to reflect the inserted lines. + // Clear the inserted lines. for (i = 0; i < line_count; i++) { if (width != grid->Columns) { // need to copy part of a line @@ -6434,17 +6426,17 @@ int grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col, linecopy(grid, j + line_count, j, col, width); } j += line_count; - grid_clear_line(grid, grid->LineOffset[j] + col, width, false); - grid->LineWraps[j] = false; + grid_clear_line(grid, grid->line_offset[j] + col, width, false); + grid->line_wraps[j] = false; } else { j = end - 1 - i; - temp = grid->LineOffset[j]; + temp = grid->line_offset[j]; while ((j -= line_count) >= row) { - grid->LineOffset[j + line_count] = grid->LineOffset[j]; - grid->LineWraps[j + line_count] = grid->LineWraps[j]; + grid->line_offset[j + line_count] = grid->line_offset[j]; + grid->line_wraps[j + line_count] = grid->line_wraps[j]; } - grid->LineOffset[j + line_count] = temp; - grid->LineWraps[j + line_count] = false; + grid->line_offset[j + line_count] = temp; + grid->line_wraps[j + line_count] = false; grid_clear_line(grid, temp, (int)grid->Columns, false); } } @@ -6454,7 +6446,7 @@ int grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col, return OK; } -/// delete lines on the screen and update ScreenLines[] +/// delete lines on the screen and move lines up. /// '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. @@ -6479,8 +6471,8 @@ int grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col, return FAIL; } - // Now shift LineOffset[] line_count up to reflect the deleted lines. - // Clear the inserted lines in ScreenLines[]. + // Now shift line_offset[] line_count up to reflect the deleted lines. + // Clear the inserted lines. for (i = 0; i < line_count; i++) { if (width != grid->Columns) { // need to copy part of a line @@ -6489,18 +6481,18 @@ int grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col, linecopy(grid, j - line_count, j, col, width); } j -= line_count; - grid_clear_line(grid, grid->LineOffset[j] + col, width, false); - grid->LineWraps[j] = false; + grid_clear_line(grid, grid->line_offset[j] + col, width, false); + grid->line_wraps[j] = false; } else { // whole width, moving the line pointers is faster j = row + i; - temp = grid->LineOffset[j]; + temp = grid->line_offset[j]; while ((j += line_count) <= end - 1) { - grid->LineOffset[j - line_count] = grid->LineOffset[j]; - grid->LineWraps[j - line_count] = grid->LineWraps[j]; + grid->line_offset[j - line_count] = grid->line_offset[j]; + grid->line_wraps[j - line_count] = grid->line_wraps[j]; } - grid->LineOffset[j - line_count] = temp; - grid->LineWraps[j - line_count] = false; + grid->line_offset[j - line_count] = temp; + grid->line_wraps[j - line_count] = false; grid_clear_line(grid, temp, (int)grid->Columns, false); } } @@ -6755,7 +6747,7 @@ static void draw_tabline(void) int use_sep_chars = (t_colors < 8 ); - if (default_grid.ScreenLines == NULL) { + if (default_grid.chars == NULL) { return; } redraw_tabline = false; @@ -7280,7 +7272,7 @@ void screen_resize(int width, int height) * - in Ex mode, don't redraw anything. * - Otherwise, redraw right now, and position the cursor. * Always need to call update_screen() or screenalloc(), to make - * sure Rows/Columns and the size of ScreenLines[] is correct! + * sure Rows/Columns and the size of the screen is correct! */ if (State == ASKMORE || State == EXTERNCMD || State == CONFIRM || exmode_active) { diff --git a/src/nvim/ui.c b/src/nvim/ui.c index fd134e626f..dc81c18b0b 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -320,14 +320,14 @@ void ui_set_ext_option(UI *ui, UIExtension ext, bool active) void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol, int clearattr, bool wrap) { - size_t off = grid->LineOffset[row] + (size_t)startcol; + size_t off = grid->line_offset[row] + (size_t)startcol; int row_off = ui_is_external(kUIMultigrid) ? 0 : grid->row_offset; int col_off = ui_is_external(kUIMultigrid) ? 0 : grid->col_offset; UI_CALL(raw_line, grid->handle, row_off + row, col_off + startcol, col_off + endcol, col_off + clearcol, clearattr, wrap, - (const schar_T *)grid->ScreenLines + off, - (const sattr_T *)grid->ScreenAttrs + off); + (const schar_T *)grid->chars + off, + (const sattr_T *)grid->attrs + off); if (p_wd) { // 'writedelay': flush & delay each time. int old_row = row, old_col = col; diff --git a/src/nvim/window.c b/src/nvim/window.c index 7e381e7069..1b7318dd8c 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -6096,7 +6096,7 @@ void win_ui_flush(void) } FOR_ALL_TAB_WINDOWS(tp, wp) { - if (wp->w_pos_changed && wp->w_grid.ScreenLines != NULL) { + if (wp->w_pos_changed && wp->w_grid.chars != NULL) { if (tp == curtab) { ui_call_win_pos(wp->w_grid.handle, wp->handle, wp->w_winrow, wp->w_wincol, wp->w_width, wp->w_height); -- cgit