aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluukvbaal <31730729+luukvbaal@users.noreply.github.com>2022-11-08 00:21:22 +0100
committerGitHub <noreply@github.com>2022-11-08 07:21:22 +0800
commit8147d3df284a075f89746f9d5e948b5220c45f0b (patch)
treeb132435018203f9a41dee15af9afcba0634c4526
parent050b0e30b9d8a073a3b421a6cebd878226249ab6 (diff)
downloadrneovim-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.c3
-rw-r--r--src/nvim/buffer.c24
-rw-r--r--src/nvim/hardcopy.c4
-rw-r--r--src/nvim/screen.c9
-rw-r--r--src/nvim/statusline.c66
-rw-r--r--test/functional/lua/ffi_spec.lua14
-rw-r--r--test/unit/buffer_spec.lua3
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,