mirror of
https://github.com/neovim/neovim.git
synced 2025-09-28 14:08:32 +00:00
vim-patch:9.0.0245: mechanism to prevent recursive screen updating is incomplete (#27448)
Problem: Mechanism to prevent recursive screen updating is incomplete.
Solution: Add "redraw_not_allowed" and set it in build_stl_str_hl().
(issue vim/vim#10952)
471c0fa3ee
Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
@@ -322,7 +322,7 @@ static void changed_common(buf_T *buf, linenr_T lnum, colnr_T col, linenr_T lnum
|
|||||||
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
||||||
if (wp->w_buffer == buf) {
|
if (wp->w_buffer == buf) {
|
||||||
// Mark this window to be redrawn later.
|
// Mark this window to be redrawn later.
|
||||||
if (wp->w_redr_type < UPD_VALID) {
|
if (!redraw_not_allowed && wp->w_redr_type < UPD_VALID) {
|
||||||
wp->w_redr_type = UPD_VALID;
|
wp->w_redr_type = UPD_VALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,9 +390,7 @@ static void changed_common(buf_T *buf, linenr_T lnum, colnr_T col, linenr_T lnum
|
|||||||
|
|
||||||
// Call update_screen() later, which checks out what needs to be redrawn,
|
// Call update_screen() later, which checks out what needs to be redrawn,
|
||||||
// since it notices b_mod_set and then uses b_mod_*.
|
// since it notices b_mod_set and then uses b_mod_*.
|
||||||
if (must_redraw < UPD_VALID) {
|
set_must_redraw(UPD_VALID);
|
||||||
must_redraw = UPD_VALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
// when the cursor line is changed always trigger CursorMoved
|
// when the cursor line is changed always trigger CursorMoved
|
||||||
if (last_cursormoved_win == curwin && curwin->w_buffer == buf
|
if (last_cursormoved_win == curwin && curwin->w_buffer == buf
|
||||||
|
@@ -2647,7 +2647,7 @@ void redraw_later(win_T *wp, int type)
|
|||||||
{
|
{
|
||||||
// curwin may have been set to NULL when exiting
|
// curwin may have been set to NULL when exiting
|
||||||
assert(wp != NULL || exiting);
|
assert(wp != NULL || exiting);
|
||||||
if (!exiting && wp->w_redr_type < type) {
|
if (!exiting && !redraw_not_allowed && wp->w_redr_type < type) {
|
||||||
wp->w_redr_type = type;
|
wp->w_redr_type = type;
|
||||||
if (type >= UPD_NOT_VALID) {
|
if (type >= UPD_NOT_VALID) {
|
||||||
wp->w_lines_valid = 0;
|
wp->w_lines_valid = 0;
|
||||||
@@ -2665,7 +2665,14 @@ void redraw_all_later(int type)
|
|||||||
redraw_later(wp, type);
|
redraw_later(wp, type);
|
||||||
}
|
}
|
||||||
// This may be needed when switching tabs.
|
// This may be needed when switching tabs.
|
||||||
if (must_redraw < type) {
|
set_must_redraw(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set "must_redraw" to "type" unless it already has a higher value
|
||||||
|
/// or it is currently not allowed.
|
||||||
|
void set_must_redraw(int type)
|
||||||
|
{
|
||||||
|
if (!redraw_not_allowed && must_redraw < type) {
|
||||||
must_redraw = type;
|
must_redraw = type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2730,9 +2737,7 @@ void redraw_buf_status_later(buf_T *buf)
|
|||||||
|| (wp == curwin && global_stl_height())
|
|| (wp == curwin && global_stl_height())
|
||||||
|| wp->w_winbar_height)) {
|
|| wp->w_winbar_height)) {
|
||||||
wp->w_redr_status = true;
|
wp->w_redr_status = true;
|
||||||
if (must_redraw < UPD_VALID) {
|
set_must_redraw(UPD_VALID);
|
||||||
must_redraw = UPD_VALID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,10 @@ enum {
|
|||||||
/// ('lines' and 'rows') must not be changed.
|
/// ('lines' and 'rows') must not be changed.
|
||||||
EXTERN bool updating_screen INIT( = false);
|
EXTERN bool updating_screen INIT( = false);
|
||||||
|
|
||||||
|
/// While computing a statusline and the like we do not want any w_redr_type or
|
||||||
|
/// must_redraw to be set.
|
||||||
|
EXTERN bool redraw_not_allowed INIT( = false);
|
||||||
|
|
||||||
EXTERN match_T screen_search_hl INIT( = { 0 }); ///< used for 'hlsearch' highlight matching
|
EXTERN match_T screen_search_hl INIT( = { 0 }); ///< used for 'hlsearch' highlight matching
|
||||||
|
|
||||||
#define W_ENDCOL(wp) ((wp)->w_wincol + (wp)->w_width)
|
#define W_ENDCOL(wp) ((wp)->w_wincol + (wp)->w_width)
|
||||||
|
@@ -902,9 +902,7 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear
|
|||||||
// not get printed in the middle of it.
|
// not get printed in the middle of it.
|
||||||
msg_check();
|
msg_check();
|
||||||
if (p_ch == 0 && !ui_has(kUIMessages)) {
|
if (p_ch == 0 && !ui_has(kUIMessages)) {
|
||||||
if (must_redraw < UPD_VALID) {
|
set_must_redraw(UPD_VALID);
|
||||||
must_redraw = UPD_VALID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
msg_scroll = s->save_msg_scroll;
|
msg_scroll = s->save_msg_scroll;
|
||||||
redir_off = false;
|
redir_off = false;
|
||||||
|
@@ -2419,9 +2419,7 @@ static void inc_msg_scrolled(void)
|
|||||||
xfree(tofree);
|
xfree(tofree);
|
||||||
}
|
}
|
||||||
msg_scrolled++;
|
msg_scrolled++;
|
||||||
if (must_redraw < UPD_VALID) {
|
set_must_redraw(UPD_VALID);
|
||||||
must_redraw = UPD_VALID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static msgchunk_T *last_msgchunk = NULL; // last displayed text
|
static msgchunk_T *last_msgchunk = NULL; // last displayed text
|
||||||
@@ -3067,9 +3065,7 @@ void msg_ext_clear_later(void)
|
|||||||
{
|
{
|
||||||
if (msg_ext_is_visible()) {
|
if (msg_ext_is_visible()) {
|
||||||
msg_ext_need_clear = true;
|
msg_ext_need_clear = true;
|
||||||
if (must_redraw < UPD_VALID) {
|
set_must_redraw(UPD_VALID);
|
||||||
must_redraw = UPD_VALID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -935,14 +935,20 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
|
|||||||
char buf_tmp[TMPLEN];
|
char buf_tmp[TMPLEN];
|
||||||
char win_tmp[TMPLEN];
|
char win_tmp[TMPLEN];
|
||||||
char *usefmt = fmt;
|
char *usefmt = fmt;
|
||||||
const int save_must_redraw = must_redraw;
|
const bool save_redraw_not_allowed = redraw_not_allowed;
|
||||||
const int save_redr_type = curwin->w_redr_type;
|
|
||||||
const bool save_KeyTyped = KeyTyped;
|
const bool save_KeyTyped = KeyTyped;
|
||||||
// TODO(Bram): find out why using called_emsg_before makes tests fail, does it
|
// TODO(Bram): find out why using called_emsg_before makes tests fail, does it
|
||||||
// matter?
|
// matter?
|
||||||
// const int called_emsg_before = called_emsg;
|
// const int called_emsg_before = called_emsg;
|
||||||
const int did_emsg_before = did_emsg;
|
const int did_emsg_before = did_emsg;
|
||||||
|
|
||||||
|
// When inside update_screen() we do not want redrawing a statusline,
|
||||||
|
// ruler, title, etc. to trigger another redraw, it may cause an endless
|
||||||
|
// loop.
|
||||||
|
if (updating_screen) {
|
||||||
|
redraw_not_allowed = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (stl_items == NULL) {
|
if (stl_items == NULL) {
|
||||||
stl_items = xmalloc(sizeof(stl_item_t) * stl_items_len);
|
stl_items = xmalloc(sizeof(stl_item_t) * stl_items_len);
|
||||||
stl_groupitems = xmalloc(sizeof(int) * stl_items_len);
|
stl_groupitems = xmalloc(sizeof(int) * stl_items_len);
|
||||||
@@ -1938,16 +1944,16 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
|
|||||||
stl_items[curitem].type = Empty;
|
stl_items[curitem].type = Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (num >= 0 || (!itemisflag && str && *str)) {
|
||||||
|
prevchar_isflag = false; // Item not NULL, but not a flag
|
||||||
|
}
|
||||||
|
|
||||||
// Only free the string buffer if we allocated it.
|
// Only free the string buffer if we allocated it.
|
||||||
// Note: This is not needed if `str` is pointing at `tmp`
|
// Note: This is not needed if `str` is pointing at `tmp`
|
||||||
if (opt == STL_VIM_EXPR) {
|
if (opt == STL_VIM_EXPR) {
|
||||||
XFREE_CLEAR(str);
|
XFREE_CLEAR(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num >= 0 || (!itemisflag && str && *str)) {
|
|
||||||
prevchar_isflag = false; // Item not NULL, but not a flag
|
|
||||||
}
|
|
||||||
|
|
||||||
// Item processed, move to the next
|
// Item processed, move to the next
|
||||||
curitem++;
|
curitem++;
|
||||||
}
|
}
|
||||||
@@ -2172,12 +2178,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
|
|||||||
cur_tab_rec->def.func = NULL;
|
cur_tab_rec->def.func = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When inside update_screen we do not want redrawing a statusline, ruler,
|
redraw_not_allowed = save_redraw_not_allowed;
|
||||||
// title, etc. to trigger another redraw, it may cause an endless loop.
|
|
||||||
if (updating_screen) {
|
|
||||||
must_redraw = save_must_redraw;
|
|
||||||
curwin->w_redr_type = save_redr_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for an error. If there is one the display will be messed up and
|
// Check for an error. If there is one the display will be messed up and
|
||||||
// might loop redrawing. Avoid that by making the corresponding option
|
// might loop redrawing. Avoid that by making the corresponding option
|
||||||
|
@@ -184,7 +184,7 @@ void win_config_float(win_T *wp, WinConfig fconfig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
win_set_inner_size(wp, true);
|
win_set_inner_size(wp, true);
|
||||||
must_redraw = MAX(must_redraw, UPD_VALID);
|
set_must_redraw(UPD_VALID);
|
||||||
|
|
||||||
wp->w_pos_changed = true;
|
wp->w_pos_changed = true;
|
||||||
if (change_external || change_border) {
|
if (change_external || change_border) {
|
||||||
|
Reference in New Issue
Block a user