diff options
author | luukvbaal <31730729+luukvbaal@users.noreply.github.com> | 2022-11-08 00:21:22 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-08 07:21:22 +0800 |
commit | 8147d3df284a075f89746f9d5e948b5220c45f0b (patch) | |
tree | b132435018203f9a41dee15af9afcba0634c4526 | |
parent | 050b0e30b9d8a073a3b421a6cebd878226249ab6 (diff) | |
download | rneovim-8147d3df284a075f89746f9d5e948b5220c45f0b.tar.gz rneovim-8147d3df284a075f89746f9d5e948b5220c45f0b.tar.bz2 rneovim-8147d3df284a075f89746f9d5e948b5220c45f0b.zip |
vim-patch:9.0.0844: handling 'statusline' errors is spread out (#20992)
Problem: Handling 'statusline' errors is spread out.
Solution: Pass the option name to the lower levels so the option can be
reset there when an error is encountered. (Luuk van Baal,
closes vim/vim#11467)
https://github.com/vim/vim/commit/7b224fdf4a29f115567d4fc8629c1cef92d8444a
-rw-r--r-- | src/nvim/api/vim.c | 3 | ||||
-rw-r--r-- | src/nvim/buffer.c | 24 | ||||
-rw-r--r-- | src/nvim/hardcopy.c | 4 | ||||
-rw-r--r-- | src/nvim/screen.c | 9 | ||||
-rw-r--r-- | src/nvim/statusline.c | 66 | ||||
-rw-r--r-- | test/functional/lua/ffi_spec.lua | 14 | ||||
-rw-r--r-- | test/unit/buffer_spec.lua | 3 |
7 files changed, 51 insertions, 72 deletions
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index beb48b8d7d..d3f8c768a0 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2223,7 +2223,8 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * buf, sizeof(buf), str.data, - false, + NULL, + 0, fillchar, maxwidth, hltab_ptr, diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 2c87677925..fa0b2a83c8 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3203,17 +3203,9 @@ void maketitle(void) if (*p_titlestring != NUL) { if (stl_syntax & STL_IN_TITLE) { - int use_sandbox = false; - const int called_emsg_before = called_emsg; - - use_sandbox = was_set_insecurely(curwin, "titlestring", 0); - build_stl_str_hl(curwin, buf, sizeof(buf), - p_titlestring, use_sandbox, - 0, maxlen, NULL, NULL); + build_stl_str_hl(curwin, buf, sizeof(buf), p_titlestring, + "titlestring", 0, 0, maxlen, NULL, NULL); title_str = buf; - if (called_emsg > called_emsg_before) { - set_string_option_direct("titlestring", -1, "", OPT_FREE, SID_ERROR); - } } else { title_str = p_titlestring; } @@ -3317,16 +3309,8 @@ void maketitle(void) icon_str = buf; if (*p_iconstring != NUL) { if (stl_syntax & STL_IN_ICON) { - int use_sandbox = false; - const int called_emsg_before = called_emsg; - - use_sandbox = was_set_insecurely(curwin, "iconstring", 0); - build_stl_str_hl(curwin, icon_str, sizeof(buf), - p_iconstring, use_sandbox, - 0, 0, NULL, NULL); - if (called_emsg > called_emsg_before) { - set_string_option_direct("iconstring", -1, "", OPT_FREE, SID_ERROR); - } + build_stl_str_hl(curwin, icon_str, sizeof(buf), p_iconstring, + "iconstring", 0, 0, 0, NULL, NULL); } else { icon_str = p_iconstring; } diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c index 50af6dafe7..6c32e5355f 100644 --- a/src/nvim/hardcopy.c +++ b/src/nvim/hardcopy.c @@ -522,7 +522,6 @@ static void prt_header(prt_settings_T *const psettings, const int pagenum, const if (*p_header != NUL) { linenr_T tmp_lnum, tmp_topline, tmp_botline; - int use_sandbox = false; // Need to (temporarily) set current line number and first/last line // number on the 'window'. Since we don't know how long the page is, @@ -536,9 +535,8 @@ static void prt_header(prt_settings_T *const psettings, const int pagenum, const curwin->w_botline = lnum + 63; printer_page_num = pagenum; - use_sandbox = was_set_insecurely(curwin, "printheader", 0); build_stl_str_hl(curwin, (char *)tbuf, (size_t)width + IOSIZE, - (char *)p_header, use_sandbox, + (char *)p_header, "printheader", 0, ' ', width, NULL, NULL); // Reset line numbers diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 377927ba4d..39b3291404 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -999,16 +999,7 @@ void draw_tabline(void) // Use the 'tabline' option if it's set. if (*p_tal != NUL) { - int saved_did_emsg = did_emsg; - - // Check for an error. If there is one we would loop in redrawing the - // screen. Avoid that by making 'tabline' empty. - did_emsg = false; win_redr_custom(NULL, false, false); - if (did_emsg) { - set_string_option_direct("tabline", -1, "", OPT_FREE, SID_ERROR); - } - did_emsg |= saved_did_emsg; } else { FOR_ALL_TABS(tp) { tabcount++; diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index 71f9bde2e9..2c3f7e8375 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -214,11 +214,7 @@ void win_redr_ruler(win_T *wp, bool always) } if (*p_ruf && p_ch > 0 && !ui_has(kUIMessages)) { - const int called_emsg_before = called_emsg; win_redr_custom(wp, false, true); - if (called_emsg > called_emsg_before) { - set_string_option_direct("rulerformat", -1, "", OPT_FREE, SID_ERROR); - } return; } @@ -389,7 +385,6 @@ int fillchar_status(int *attr, win_T *wp) void redraw_custom_statusline(win_T *wp) { static bool entered = false; - int saved_did_emsg = did_emsg; // When called recursively return. This can happen when the statusline // contains an expression that triggers a redraw. @@ -398,17 +393,7 @@ void redraw_custom_statusline(win_T *wp) } entered = true; - did_emsg = false; win_redr_custom(wp, false, false); - if (did_emsg) { - // When there is an error disable the statusline, otherwise the - // display is messed up with errors and a redraw triggers the problem - // again and again. - set_string_option_direct("statusline", -1, "", - OPT_FREE | (*wp->w_p_stl != NUL - ? OPT_LOCAL : OPT_GLOBAL), SID_ERROR); - } - did_emsg |= saved_did_emsg; entered = false; } @@ -429,9 +414,10 @@ void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) char buf[MAXPATHL]; char *stl; char *p; + char *opt_name; + int opt_scope = 0; stl_hlrec_t *hltab; StlClickRecord *tabtab; - int use_sandbox = false; win_T *ewp; int p_crb_save; bool is_stl_global = global_stl_height() > 0; @@ -454,9 +440,11 @@ void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) fillchar = ' '; attr = HL_ATTR(HLF_TPF); maxwidth = Columns; - use_sandbox = was_set_insecurely(wp, "tabline", 0); + opt_name = "tabline"; } else if (draw_winbar) { + opt_name = "winbar"; stl = ((*wp->w_p_wbr != NUL) ? wp->w_p_wbr : p_wbr); + opt_scope = ((*wp->w_p_wbr != NUL) ? OPT_LOCAL : 0); row = -1; // row zero is first row of text col = 0; grid = &wp->w_grid; @@ -469,7 +457,6 @@ void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) fillchar = wp->w_p_fcs_chars.wbr; attr = (wp == curwin) ? win_hl_attr(wp, HLF_WBR) : win_hl_attr(wp, HLF_WBRNC); maxwidth = wp->w_width_inner; - use_sandbox = was_set_insecurely(wp, "winbar", 0); stl_clear_click_defs(wp->w_winbar_click_defs, (long)wp->w_winbar_click_defs_size); wp->w_winbar_click_defs = stl_alloc_click_defs(wp->w_winbar_click_defs, maxwidth, &wp->w_winbar_click_defs_size); @@ -483,6 +470,7 @@ void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) if (draw_ruler) { stl = p_ruf; + opt_name = "rulerformat"; // advance past any leading group spec - implicit in ru_col if (*stl == '%') { if (*++stl == '-') { @@ -509,15 +497,10 @@ void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) fillchar = ' '; attr = HL_ATTR(HLF_MSG); } - - use_sandbox = was_set_insecurely(wp, "rulerformat", 0); } else { - if (*wp->w_p_stl != NUL) { - stl = wp->w_p_stl; - } else { - stl = p_stl; - } - use_sandbox = was_set_insecurely(wp, "statusline", *wp->w_p_stl == NUL ? 0 : OPT_LOCAL); + opt_name = "statusline"; + stl = ((*wp->w_p_stl != NUL) ? wp->w_p_stl : p_stl); + opt_scope = ((*wp->w_p_stl != NUL) ? OPT_LOCAL : 0); } col += is_stl_global ? 0 : wp->w_wincol; @@ -536,9 +519,8 @@ void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) // Make a copy, because the statusline may include a function call that // might change the option value and free the memory. stl = xstrdup(stl); - width = - build_stl_str_hl(ewp, buf, sizeof(buf), stl, use_sandbox, - fillchar, maxwidth, &hltab, &tabtab); + width = build_stl_str_hl(ewp, buf, sizeof(buf), stl, opt_name, + opt_scope, fillchar, maxwidth, &hltab, &tabtab); xfree(stl); ewp->w_p_crb = p_crb_save; @@ -611,15 +593,16 @@ theend: /// Note: This should not be NameBuff /// @param outlen The length of the output buffer /// @param fmt The statusline format string -/// @param use_sandbox Use a sandboxed environment when evaluating fmt +/// @param opt_name The option name corresponding to "fmt" +/// @param opt_scope The scope corresponding to "opt_name" /// @param fillchar Character to use when filling empty space in the statusline /// @param maxwidth The maximum width to make the statusline /// @param hltab HL attributes (can be NULL) /// @param tabtab Tab clicks definition (can be NULL). /// /// @return The final width of the statusline -int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_sandbox, int fillchar, - int maxwidth, stl_hlrec_t **hltab, StlClickRecord **tabtab) +int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_name, int opt_scope, + int fillchar, int maxwidth, stl_hlrec_t **hltab, StlClickRecord **tabtab) { static size_t stl_items_len = 20; // Initial value, grows as needed. static stl_item_t *stl_items = NULL; @@ -634,6 +617,10 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san char *usefmt = fmt; const int save_must_redraw = must_redraw; const int save_redr_type = curwin->w_redr_type; + // TODO(Bram): find out why using called_emsg_before makes tests fail, does it + // matter? + // const int called_emsg_before = called_emsg; + const int did_emsg_before = did_emsg; if (stl_items == NULL) { stl_items = xmalloc(sizeof(stl_item_t) * stl_items_len); @@ -647,6 +634,11 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san stl_separator_locations = xmalloc(sizeof(int) * stl_items_len); } + // if "fmt" was set insecurely it needs to be evaluated in the sandbox + // "opt_name" will be NULL when caller is nvim_eval_statusline() + const int use_sandbox = opt_name ? was_set_insecurely(wp, opt_name, opt_scope) + : false; + // When the format starts with "%!" then evaluate it as an expression and // use the result as the actual format string. if (fmt[0] == '%' && fmt[1] == '!') { @@ -1769,5 +1761,15 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san curwin->w_redr_type = save_redr_type; } + // 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 + // empty. + // TODO(Bram): find out why using called_emsg_before makes tests fail, does it + // matter? + // if (called_emsg > called_emsg_before) + if (opt_name && did_emsg > did_emsg_before) { + set_string_option_direct(opt_name, -1, "", OPT_FREE | opt_scope, SID_ERROR); + } + return width; } diff --git a/test/functional/lua/ffi_spec.lua b/test/functional/lua/ffi_spec.lua index 80c01a2b8c..3969a7a478 100644 --- a/test/functional/lua/ffi_spec.lua +++ b/test/functional/lua/ffi_spec.lua @@ -35,11 +35,12 @@ describe('ffi.cdef', function() int build_stl_str_hl( win_T *wp, - char_u *out, + char *out, size_t outlen, - char_u *fmt, - int use_sandbox, - char_u fillchar, + char *fmt, + char *opt_name, + int opt_scope, + int fillchar, int maxwidth, stl_hlrec_t **hltab, StlClickRecord **tabtab @@ -48,9 +49,10 @@ describe('ffi.cdef', function() return ffi.C.build_stl_str_hl( ffi.C.find_window_by_handle(0, ffi.new('Error')), - ffi.new('char_u[1024]'), + ffi.new('char[1024]'), 1024, - ffi.cast('char_u*', 'StatusLineOfLength20'), + ffi.cast('char*', 'StatusLineOfLength20'), + nil, 0, 0, 0, diff --git a/test/unit/buffer_spec.lua b/test/unit/buffer_spec.lua index 5dccc2f5a2..2611e7ca7c 100644 --- a/test/unit/buffer_spec.lua +++ b/test/unit/buffer_spec.lua @@ -233,7 +233,8 @@ describe('buffer functions', function() output_buffer, buffer_byte_size, to_cstr(pat), - false, + NULL, + 0, fillchar, maximum_cell_count, NULL, |