diff src/option.c @ 26618:b531c26f728b v8.2.3838

patch 8.2.3838: cannot use script-local function for setting *func options Commit: https://github.com/vim/vim/commit/db1a410b610b2c1941311acc57dcc4afec20720e Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Fri Dec 17 16:21:20 2021 +0000 patch 8.2.3838: cannot use script-local function for setting *func options Problem: Cannot use script-local function for setting *func options. Solution: Use the script context. (Yegappan Lakshmanan, closes https://github.com/vim/vim/issues/9362)
author Bram Moolenaar <Bram@vim.org>
date Fri, 17 Dec 2021 17:30:04 +0100
parents 6fed1f1bc282
children 9c9b8d95b05f
line wrap: on
line diff
--- a/src/option.c
+++ b/src/option.c
@@ -7199,17 +7199,39 @@ option_set_callback_func(char_u *optval 
 	return OK;
     }
 
-    if (STRNCMP(optval, "s:", 2) == 0 && !SCRIPT_ID_VALID(current_sctx.sc_sid))
-	return FAIL;
-
     if (*optval == '{' || (in_vim9script() && *optval == '(')
 	    || (STRNCMP(optval, "function(", 9) == 0)
 	    || (STRNCMP(optval, "funcref(", 8) == 0))
 	// Lambda expression or a funcref
 	tv = eval_expr(optval, NULL);
     else
+    {
 	// treat everything else as a function name string
-	tv = alloc_string_tv(vim_strsave(optval));
+
+	// Function name starting with "s:" are supported only in a vimscript
+	// context.
+	if (STRNCMP(optval, "s:", 2) == 0)
+	{
+	    char	sid_buf[25];
+	    char_u	*funcname;
+
+	    if (!SCRIPT_ID_VALID(current_sctx.sc_sid))
+	    {
+		emsg(_(e_using_sid_not_in_script_context));
+		return FAIL;
+	    }
+	    // Expand s: prefix into <SNR>nr_<name>
+	    sprintf(sid_buf, "<SNR>%ld_", (long)current_sctx.sc_sid);
+	    funcname = alloc(STRLEN(sid_buf) + STRLEN(optval + 2) + 1);
+	    if (funcname == NULL)
+		return FAIL;
+	    STRCPY(funcname, sid_buf);
+	    STRCAT(funcname, optval + 2);
+	    tv = alloc_string_tv(funcname);
+	}
+	else
+	    tv = alloc_string_tv(vim_strsave(optval));
+    }
     if (tv == NULL)
 	return FAIL;