aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/buffer.c5
-rw-r--r--src/nvim/api/private/helpers.c25
-rw-r--r--src/nvim/api/vim.c4
-rw-r--r--src/nvim/api/window.c5
-rw-r--r--src/nvim/buffer_defs.h4
-rw-r--r--src/nvim/eval.c21
-rw-r--r--src/nvim/ex_cmds2.c42
-rw-r--r--src/nvim/globals.h22
-rw-r--r--src/nvim/option.c58
-rw-r--r--src/nvim/option_defs.h7
10 files changed, 121 insertions, 72 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 6be981a18e..023f434f9d 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -581,7 +581,8 @@ Object nvim_buf_get_option(Buffer buffer, String name, Error *err)
/// @param name Option name
/// @param value Option value
/// @param[out] err Error details, if any
-void nvim_buf_set_option(Buffer buffer, String name, Object value, Error *err)
+void nvim_buf_set_option(uint64_t channel_id, Buffer buffer,
+ String name, Object value, Error *err)
FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -590,7 +591,7 @@ void nvim_buf_set_option(Buffer buffer, String name, Object value, Error *err)
return;
}
- set_option_to(buf, SREQ_BUF, name, value, err);
+ set_option_to(channel_id, buf, SREQ_BUF, name, value, err);
}
/// Gets the buffer number
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index 637e24575d..b922036893 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -324,7 +324,8 @@ Object get_option_from(void *from, int type, String name, Error *err)
/// @param type One of `SREQ_GLOBAL`, `SREQ_WIN` or `SREQ_BUF`
/// @param name The option name
/// @param[out] err Details of an error that may have occurred
-void set_option_to(void *to, int type, String name, Object value, Error *err)
+void set_option_to(uint64_t channel_id, void *to, int type,
+ String name, Object value, Error *err)
{
if (name.size == 0) {
api_set_error(err, kErrorTypeValidation, "Empty option name");
@@ -361,7 +362,8 @@ void set_option_to(void *to, int type, String name, Object value, Error *err)
}
}
- int opt_flags = (type == SREQ_GLOBAL) ? OPT_GLOBAL : OPT_LOCAL;
+ int numval = 0;
+ char *stringval = NULL;
if (flags & SOPT_BOOL) {
if (value.type != kObjectTypeBoolean) {
@@ -372,8 +374,7 @@ void set_option_to(void *to, int type, String name, Object value, Error *err)
return;
}
- bool val = value.data.boolean;
- set_option_value_for(name.data, val, NULL, opt_flags, type, to, err);
+ numval = value.data.boolean;
} else if (flags & SOPT_NUM) {
if (value.type != kObjectTypeInteger) {
api_set_error(err,
@@ -391,8 +392,7 @@ void set_option_to(void *to, int type, String name, Object value, Error *err)
return;
}
- int val = (int) value.data.integer;
- set_option_value_for(name.data, val, NULL, opt_flags, type, to, err);
+ numval = (int)value.data.integer;
} else {
if (value.type != kObjectTypeString) {
api_set_error(err,
@@ -402,9 +402,18 @@ void set_option_to(void *to, int type, String name, Object value, Error *err)
return;
}
- set_option_value_for(name.data, 0, value.data.string.data,
- opt_flags, type, to, err);
+ stringval = (char *)value.data.string.data;
}
+
+ const scid_T save_current_SID = current_SID;
+ current_SID = channel_id == LUA_INTERNAL_CALL ? SID_LUA : SID_API_CLIENT;
+ current_channel_id = channel_id;
+
+ const int opt_flags = (type == SREQ_GLOBAL) ? OPT_GLOBAL : OPT_LOCAL;
+ set_option_value_for(name.data, numval, stringval,
+ opt_flags, type, to, err);
+
+ current_SID = save_current_SID;
}
#define TYPVAL_ENCODE_ALLOW_SPECIALS false
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index fd9cf332d5..df4912a51e 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -683,10 +683,10 @@ Object nvim_get_option(String name, Error *err)
/// @param name Option name
/// @param value New option value
/// @param[out] err Error details, if any
-void nvim_set_option(String name, Object value, Error *err)
+void nvim_set_option(uint64_t channel_id, String name, Object value, Error *err)
FUNC_API_SINCE(1)
{
- set_option_to(NULL, SREQ_GLOBAL, name, value, err);
+ set_option_to(channel_id, NULL, SREQ_GLOBAL, name, value, err);
}
/// Writes a message to the Vim output buffer. Does not append "\n", the
diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c
index 9bc91ef8fb..abfa0dc20b 100644
--- a/src/nvim/api/window.c
+++ b/src/nvim/api/window.c
@@ -309,7 +309,8 @@ Object nvim_win_get_option(Window window, String name, Error *err)
/// @param name Option name
/// @param value Option value
/// @param[out] err Error details, if any
-void nvim_win_set_option(Window window, String name, Object value, Error *err)
+void nvim_win_set_option(uint64_t channel_id, Window window,
+ String name, Object value, Error *err)
FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -318,7 +319,7 @@ void nvim_win_set_option(Window window, String name, Object value, Error *err)
return;
}
- set_option_to(win, SREQ_WIN, name, value, err);
+ set_option_to(channel_id, win, SREQ_WIN, name, value, err);
}
/// Gets the window position in display cells. First position is zero.
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 8de4286216..53edae58a5 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -237,7 +237,7 @@ typedef struct {
char_u *wo_winhl;
# define w_p_winhl w_onebuf_opt.wo_winhl // 'winhighlight'
- int wo_scriptID[WV_COUNT]; /* SIDs for window-local options */
+ LastSet wo_scriptID[WV_COUNT]; // SIDs for window-local options
# define w_p_scriptID w_onebuf_opt.wo_scriptID
} winopt_T;
@@ -590,7 +590,7 @@ struct file_buffer {
*/
bool b_p_initialized; /* set when options initialized */
- int b_p_scriptID[BV_COUNT]; /* SIDs for buffer-local options */
+ LastSet b_p_scriptID[BV_COUNT]; // SIDs for buffer-local options
int b_p_ai; ///< 'autoindent'
int b_p_ai_nopaste; ///< b_p_ai saved for paste mode
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 45a1776c86..126e9e0da9 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -22066,12 +22066,27 @@ int store_session_globals(FILE *fd)
*/
void last_set_msg(scid_T scriptID)
{
- if (scriptID != 0) {
- char_u *p = home_replace_save(NULL, get_scriptname(scriptID));
+ const LastSet last_set = (LastSet){
+ .script_id = scriptID,
+ .channel_id = 0,
+ };
+ option_last_set_msg(last_set);
+}
+
+/// Displays where an option was last set.
+///
+/// Should only be invoked when 'verbose' is non-zero.
+void option_last_set_msg(LastSet last_set)
+{
+ if (last_set.script_id != 0) {
+ bool should_free;
+ char_u *p = get_scriptname(last_set, &should_free);
verbose_enter();
MSG_PUTS(_("\n\tLast set from "));
MSG_PUTS(p);
- xfree(p);
+ if (should_free) {
+ xfree(p);
+ }
verbose_leave();
}
}
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 821c050c50..96d2102156 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -3055,24 +3055,32 @@ void scriptnames_slash_adjust(void)
# endif
/// Get a pointer to a script name. Used for ":verbose set".
-char_u *get_scriptname(scid_T id)
-{
- if (id == SID_MODELINE) {
- return (char_u *)_("modeline");
- }
- if (id == SID_CMDARG) {
- return (char_u *)_("--cmd argument");
- }
- if (id == SID_CARG) {
- return (char_u *)_("-c argument");
- }
- if (id == SID_ENV) {
- return (char_u *)_("environment variable");
- }
- if (id == SID_ERROR) {
- return (char_u *)_("error handler");
+char_u *get_scriptname(LastSet last_set, bool *should_free)
+{
+ *should_free = false;
+
+ switch (last_set.script_id) {
+ case SID_MODELINE:
+ return (char_u *)_("modeline");
+ case SID_CMDARG:
+ return (char_u *)_("--cmd argument");
+ case SID_CARG:
+ return (char_u *)_("-c argument");
+ case SID_ENV:
+ return (char_u *)_("environment variable");
+ case SID_ERROR:
+ return (char_u *)_("error handler");
+ case SID_LUA:
+ return (char_u *)_("Lua");
+ case SID_API_CLIENT:
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("API client (channel id %" PRIu64 ")"),
+ last_set.channel_id);
+ return IObuff;
+ default:
+ *should_free = true;
+ return home_replace_save(NULL, SCRIPT_ITEM(last_set.script_id).sn_name);
}
- return SCRIPT_ITEM(id).sn_name;
}
# if defined(EXITFREE)
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 8a2769618e..ddc58c2425 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -390,16 +390,20 @@ EXTERN int may_garbage_collect INIT(= FALSE);
EXTERN int want_garbage_collect INIT(= FALSE);
EXTERN int garbage_collect_at_exit INIT(= FALSE);
-/* Special values for current_SID. */
-#define SID_MODELINE -1 /* when using a modeline */
-#define SID_CMDARG -2 /* for "--cmd" argument */
-#define SID_CARG -3 /* for "-c" argument */
-#define SID_ENV -4 /* for sourcing environment variable */
-#define SID_ERROR -5 /* option was reset because of an error */
-#define SID_NONE -6 /* don't set scriptID */
-
-/* ID of script being sourced or was sourced to define the current function. */
+// Special values for current_SID.
+#define SID_MODELINE -1 // when using a modeline
+#define SID_CMDARG -2 // for "--cmd" argument
+#define SID_CARG -3 // for "-c" argument
+#define SID_ENV -4 // for sourcing environment variable
+#define SID_ERROR -5 // option was reset because of an error
+#define SID_NONE -6 // don't set scriptID
+#define SID_LUA -7 // for Lua scripts/chunks
+#define SID_API_CLIENT -8 // for API clients
+
+// ID of script being sourced or was sourced to define the current function.
EXTERN scid_T current_SID INIT(= 0);
+// ID of the current channel making a client API call
+EXTERN uint64_t current_channel_id INIT(= 0);
EXTERN bool did_source_packages INIT(= false);
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 41e0fced2c..1da259e6b8 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -187,16 +187,16 @@ static long p_tw_nopaste;
static long p_wm_nopaste;
typedef struct vimoption {
- char *fullname; /* full option name */
- char *shortname; /* permissible abbreviation */
- uint32_t flags; /* see below */
- char_u *var; /* global option: pointer to variable;
- * window-local option: VAR_WIN;
- * buffer-local option: global value */
- idopt_T indir; /* global option: PV_NONE;
- * local option: indirect option index */
- char_u *def_val[2]; /* default values for variable (vi and vim) */
- scid_T scriptID; /* script in which the option was last set */
+ char *fullname; // full option name
+ char *shortname; // permissible abbreviation
+ uint32_t flags; // see below
+ char_u *var; // global option: pointer to variable;
+ // window-local option: VAR_WIN;
+ // buffer-local option: global value
+ idopt_T indir; // global option: PV_NONE;
+ // local option: indirect option index
+ char_u *def_val[2]; // default values for variable (vi and vim)
+ LastSet last_set; // script in which the option was last set
# define SCRIPTID_INIT , 0
} vimoption_T;
@@ -1345,15 +1345,16 @@ do_set (
if (opt_idx >= 0) {
showoneopt(&options[opt_idx], opt_flags);
if (p_verbose > 0) {
- /* Mention where the option was last set. */
- if (varp == options[opt_idx].var)
- last_set_msg(options[opt_idx].scriptID);
- else if ((int)options[opt_idx].indir & PV_WIN)
- last_set_msg(curwin->w_p_scriptID[
- (int)options[opt_idx].indir & PV_MASK]);
- else if ((int)options[opt_idx].indir & PV_BUF)
- last_set_msg(curbuf->b_p_scriptID[
- (int)options[opt_idx].indir & PV_MASK]);
+ // Mention where the option was last set.
+ if (varp == options[opt_idx].var) {
+ option_last_set_msg(options[opt_idx].last_set);
+ } else if ((int)options[opt_idx].indir & PV_WIN) {
+ option_last_set_msg(curwin->w_p_scriptID[
+ (int)options[opt_idx].indir & PV_MASK]);
+ } else if ((int)options[opt_idx].indir & PV_BUF) {
+ option_last_set_msg(curbuf->b_p_scriptID[
+ (int)options[opt_idx].indir & PV_MASK]);
+ }
}
} else {
errmsg = (char_u *)N_("E846: Key code not set");
@@ -3642,16 +3643,19 @@ static void set_option_scriptID_idx(int opt_idx, int opt_flags, int id)
{
int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
int indir = (int)options[opt_idx].indir;
+ const LastSet last_set = { id, current_channel_id };
- /* Remember where the option was set. For local options need to do that
- * in the buffer or window structure. */
- if (both || (opt_flags & OPT_GLOBAL) || (indir & (PV_BUF|PV_WIN)) == 0)
- options[opt_idx].scriptID = id;
+ // Remember where the option was set. For local options need to do that
+ // in the buffer or window structure.
+ if (both || (opt_flags & OPT_GLOBAL) || (indir & (PV_BUF|PV_WIN)) == 0) {
+ options[opt_idx].last_set = last_set;
+ }
if (both || (opt_flags & OPT_LOCAL)) {
- if (indir & PV_BUF)
- curbuf->b_p_scriptID[indir & PV_MASK] = id;
- else if (indir & PV_WIN)
- curwin->w_p_scriptID[indir & PV_MASK] = id;
+ if (indir & PV_BUF) {
+ curbuf->b_p_scriptID[indir & PV_MASK] = last_set;
+ } else if (indir & PV_WIN) {
+ curwin->w_p_scriptID[indir & PV_MASK] = last_set;
+ }
}
}
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index 1c841df96d..f7dfa65053 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -3,6 +3,7 @@
#include "nvim/types.h"
#include "nvim/macros.h" // For EXTERN
+#include "eval/typval.h" // For scid_T
// option_defs.h: definition of global variables for settable options
@@ -819,4 +820,10 @@ enum {
#define SB_MAX 100000 // Maximum 'scrollback' value.
+/// Stores an identifier of a script or channel that last set an option.
+typedef struct {
+ scid_T script_id; /// Script ID or one of SID_* special values.
+ uint64_t channel_id; /// Only used when script_id is SID_API_CLIENT.
+} LastSet;
+
#endif // NVIM_OPTION_DEFS_H