diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/buffer.c | 5 | ||||
-rw-r--r-- | src/nvim/api/private/helpers.c | 25 | ||||
-rw-r--r-- | src/nvim/api/vim.c | 4 | ||||
-rw-r--r-- | src/nvim/api/window.c | 5 | ||||
-rw-r--r-- | src/nvim/buffer_defs.h | 4 | ||||
-rw-r--r-- | src/nvim/eval.c | 21 | ||||
-rw-r--r-- | src/nvim/ex_cmds2.c | 42 | ||||
-rw-r--r-- | src/nvim/globals.h | 22 | ||||
-rw-r--r-- | src/nvim/option.c | 58 | ||||
-rw-r--r-- | src/nvim/option_defs.h | 7 |
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 |