diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/drawscreen.c | 145 | ||||
-rw-r--r-- | src/nvim/fileio.c | 7 | ||||
-rw-r--r-- | src/nvim/main.c | 28 | ||||
-rw-r--r-- | src/nvim/message.c | 4 | ||||
-rw-r--r-- | src/nvim/version.c | 1 |
5 files changed, 79 insertions, 106 deletions
diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index d2c2d7238b..7ad4193058 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -97,7 +97,7 @@ typedef enum { static bool redraw_popupmenu = false; static bool msg_grid_invalid = false; -static bool resizing = false; +static bool resizing_autocmd = false; static char *provider_err = NULL; @@ -115,7 +115,7 @@ void conceal_check_cursor_line(void) } } -/// Resize the screen to Rows and Columns. +/// Resize default_grid to Rows and Columns. /// /// Allocate default_grid.chars[] and other grid arrays. /// @@ -125,19 +125,18 @@ void conceal_check_cursor_line(void) /// default_grid.Columns to access items in default_grid.chars[]. Use Rows /// and Columns for positioning text etc. where the final size of the screen is /// needed. -void screenalloc(void) +bool default_grid_alloc(void) { + static bool resizing = false; + // It's possible that we produce an out-of-memory message below, which // will cause this function to be called again. To break the loop, just // return here. if (resizing) { - return; + return false; } resizing = true; - int retry_count = 0; - -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. @@ -148,24 +147,9 @@ retry: || Columns == 0 || (!full_screen && default_grid.chars == NULL)) { resizing = false; - return; - } - - // Note that the window sizes are updated before reallocating the arrays, - // thus we must not redraw here! - RedrawingDisabled++; - - // win_new_screensize will recompute floats position, but tell the - // compositor to not redraw them yet - ui_comp_set_screen_valid(false); - if (msg_grid.chars) { - msg_grid_invalid = true; + return false; } - win_new_screensize(); // fit the windows in the new sized screen - - comp_col(); // recompute columns for shown command and ruler - // 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 @@ -193,26 +177,13 @@ retry: default_grid.col_offset = 0; default_grid.handle = DEFAULT_GRID_HANDLE; - must_redraw = UPD_CLEAR; // need to clear the screen later - - RedrawingDisabled--; - - // Do not apply autocommands more than 3 times to avoid an endless loop - // in case applying autocommands always changes Rows or Columns. - if (starting == 0 && ++retry_count <= 3) { - apply_autocmds(EVENT_VIMRESIZED, NULL, NULL, false, curbuf); - // In rare cases, autocommands may have altered Rows or Columns, - // jump back to check if we need to allocate the screen again. - goto retry; - } - resizing = false; + return true; } void screenclear(void) { check_for_delay(false); - screenalloc(); // allocate screen buffers if size changed int i; @@ -281,13 +252,6 @@ void screen_resize(int width, int height) return; } - // curwin->w_buffer can be NULL when we are closing a window and the - // buffer has already been closed and removing a scrollbar causes a resize - // event. Don't resize then, it will happen after entering another buffer. - if (curwin->w_buffer == NULL) { - return; - } - resizing_screen = true; Rows = height; @@ -301,16 +265,54 @@ void screen_resize(int width, int height) width = Columns; p_lines = Rows; p_columns = Columns; - ui_call_grid_resize(1, width, height); - /// The window layout used to be adjusted here, but it now happens in - /// screenalloc() (also invoked from screenclear()). That is because the - /// recursize "resizing_screen" check above may skip this, but not screenalloc(). + // was invoked recursively from a VimResized autocmd, handled as a loop below + if (resizing_autocmd) { + return; + } + + int retry_count = 0; + resizing_autocmd = true; + + bool retry_resize = true; + while (retry_resize) { + retry_resize = default_grid_alloc(); - if (State != MODE_ASKMORE && State != MODE_EXTERNCMD && State != MODE_CONFIRM) { - screenclear(); + // Do not apply autocommands more than 3 times to avoid an endless loop + // in case applying autocommands always changes Rows or Columns. + if (++retry_count > 3) { + break; + } + + if (retry_resize) { + // In rare cases, autocommands may have altered Rows or Columns, + // retry to check if we need to allocate the screen again. + apply_autocmds(EVENT_VIMRESIZED, NULL, NULL, false, curbuf); + } + } + + resizing_autocmd = false; + + ui_call_grid_resize(1, width, height); + + // win_new_screensize will recompute floats position, but tell the + // compositor to not redraw them yet + ui_comp_set_screen_valid(false); + if (msg_grid.chars) { + msg_grid_invalid = true; } + // Note that the window sizes are updated before reallocating the arrays, + // thus we must not redraw here! + RedrawingDisabled++; + + win_new_screensize(); // fit the windows in the new sized screen + + comp_col(); // recompute columns for shown command and ruler + + RedrawingDisabled--; + redraw_all_later(UPD_CLEAR); + if (starting != NO_SCREEN) { maketitle(); @@ -320,14 +322,11 @@ void screen_resize(int width, int height) // We only redraw when it's needed: // - While at the more prompt or executing an external command, don't // redraw, but position the cursor. - // - While editing the command line, only redraw that. + // - While editing the command line, only redraw that. TODO: lies // - 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 the screen is correct! if (State == MODE_ASKMORE || State == MODE_EXTERNCMD || State == MODE_CONFIRM || exmode_active) { - screenalloc(); if (msg_grid.chars) { msg_grid_validate(); } @@ -378,7 +377,7 @@ int update_screen(void) // Don't do anything if the screen structures are (not yet) valid. // A VimResized autocmd can invoke redrawing in the middle of a resize, // which would bypass the checks in screen_resize for popupmenu etc. - if (!default_grid.chars || resizing) { + if (resizing_autocmd || !default_grid.chars) { return FAIL; } @@ -387,34 +386,25 @@ int update_screen(void) diff_redraw(true); } - int type = 0; - - if (must_redraw) { - if (type < must_redraw) { // use maximal type - type = must_redraw; - } - - // must_redraw is reset here, so that when we run into some weird - // reason to redraw while busy redrawing (e.g., asynchronous - // scrolling), or update_topline() in win_update() will cause a - // scroll, or a decoration provider requires a redraw, the screen - // will be redrawn later or in win_update(). - must_redraw = 0; - } - // Postpone the redrawing when it's not needed and when being called // recursively. if (!redrawing() || updating_screen) { - must_redraw = type; - if (type > UPD_INVERTED_ALL) { - curwin->w_lines_valid = 0; // don't use w_lines[].wl_size now - } return FAIL; } + + int type = must_redraw; + + // must_redraw is reset here, so that when we run into some weird + // reason to redraw while busy redrawing (e.g., asynchronous + // scrolling), or update_topline() in win_update() will cause a + // scroll, or a decoration provider requires a redraw, the screen + // will be redrawn later or in win_update(). + must_redraw = 0; + updating_screen = 1; - display_tick++; // let syntax code know we're in a next round of - // display updating + display_tick++; // let syntax code know we're in a next round of + // display updating // Tricky: vim code can reset msg_scrolled behind our back, so need // separate bookkeeping for now. @@ -525,7 +515,8 @@ int update_screen(void) } if (type == UPD_CLEAR) { // first clear screen - screenclear(); // will reset clear_cmdline + screenclear(); // will reset clear_cmdline + // and set UPD_NOT_VALID for each window cmdline_screen_cleared(); // clear external cmdline state type = UPD_NOT_VALID; // must_redraw may be set indirectly, avoid another redraw later diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 76317298dc..b31b8336aa 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -1721,13 +1721,6 @@ failed: appended_lines_mark(from, linecnt); } - // If we were reading from the same terminal as where messages go, - // the screen will have been messed up. - // Switch on raw mode now and clear the screen. - if (read_stdin) { - screenclear(); - } - if (got_int) { if (!(flags & READ_DUMMY)) { filemess(curbuf, sfname, _(e_interr), 0); diff --git a/src/nvim/main.c b/src/nvim/main.c index 1119cee6ad..ddb3fbdd65 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -314,7 +314,7 @@ int main(int argc, char **argv) assert(p_ch >= 0 && Rows >= p_ch && Rows - p_ch <= INT_MAX); cmdline_row = (int)(Rows - p_ch); msg_row = cmdline_row; - screenalloc(); // allocate screen buffers + default_grid_alloc(); // allocate screen buffers set_init_2(headless_mode); TIME_MSG("inits 2"); @@ -346,13 +346,14 @@ int main(int argc, char **argv) ui_builtin_start(); } TIME_MSG("done waiting for UI"); - - // prepare screen now, so external UIs can display messages - starting = NO_BUFFERS; - screenclear(); - TIME_MSG("init screen for UI"); } + // prepare screen now + starting = NO_BUFFERS; + screenclear(); + win_new_screensize(); + TIME_MSG("clear screen"); + if (ui_client_channel_id) { ui_client_init(ui_client_channel_id); ui_client_execute(ui_client_channel_id); @@ -361,8 +362,8 @@ int main(int argc, char **argv) // Default mappings (incl. menus) Error err = ERROR_INIT; - Object o = nlua_exec(STATIC_CSTR_AS_STRING("return vim._init_default_mappings()"), - (Array)ARRAY_DICT_INIT, &err); + Object o = NLUA_EXEC_STATIC("return vim._init_default_mappings()", + (Array)ARRAY_DICT_INIT, &err); assert(!ERROR_SET(&err)); api_clear_error(&err); assert(o.type == kObjectTypeNil); @@ -432,10 +433,8 @@ int main(int argc, char **argv) p_ut = 1; } - // // Read in registers, history etc, from the ShaDa file. // This is where v:oldfiles gets filled. - // if (*p_shada != NUL) { shada_read_everything(NULL, false, true); TIME_MSG("reading ShaDa"); @@ -474,14 +473,7 @@ int main(int argc, char **argv) setmouse(); // may start using the mouse - if (exmode_active || use_remote_ui || use_builtin_ui) { - // Don't clear the screen when starting in Ex mode, or when a UI might have - // displayed messages. - redraw_later(curwin, UPD_VALID); - } else { - screenclear(); // clear screen - TIME_MSG("clearing screen"); - } + redraw_later(curwin, UPD_VALID); no_wait_return = true; diff --git a/src/nvim/message.c b/src/nvim/message.c index 060d969f4b..d6835e04eb 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1159,10 +1159,6 @@ void wait_return(int redraw) c = CAR; // no need for a return in ex mode got_int = false; } else { - // Make sure the hit-return prompt is on screen when 'guioptions' was - // just changed. - screenalloc(); - State = MODE_HITRETURN; setmouse(); cmdline_row = msg_row; diff --git a/src/nvim/version.c b/src/nvim/version.c index 5888d4614e..d4d406482d 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -2324,6 +2324,7 @@ static void do_intro_line(long row, char *mesg, int attr) /// @param eap void ex_intro(exarg_T *eap) { + // TODO(bfredl): use msg_grid instead! screenclear(); intro_message(true); wait_return(true); |