diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-06-15 17:12:48 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-06-15 17:12:48 +0200 |
commit | d7c968794710f338d491072171df48f96612cf72 (patch) | |
tree | d5edca7e09283ff5c345d8e113a10829a70412a2 /src/option.c | |
parent | bffc50494d52a3690cbbc5c7b34a835f9153184e (diff) | |
download | vim-git-d7c968794710f338d491072171df48f96612cf72.tar.gz |
patch 8.1.1542: an OptionSet autocommand does not get enough infov8.1.1542
Problem: An OptionSet autocommand does not get enough info.
Solution: Add v:option_command, v:option_oldlocal and v:option_oldglobal.
(Latrice Wilgus, closes #4118)
Diffstat (limited to 'src/option.c')
-rw-r--r-- | src/option.c | 176 |
1 files changed, 161 insertions, 15 deletions
diff --git a/src/option.c b/src/option.c index 2d22c4c97..12a0816f3 100644 --- a/src/option.c +++ b/src/option.c @@ -4336,12 +4336,25 @@ set_title_defaults(void) #endif #if defined(FEAT_EVAL) +/* + * Trigger the OptionSet autocommand. + * "opt_idx" is the index of the option being set. + * "opt_flags" can be OPT_LOCAL etc. + * "oldval" the old value + * "oldval_l" the old local value (only non-NULL if global and local value + * are set) + * "oldval_g" the old global value (only non-NULL if global and local value + * are set) + * "newval" the new value + */ static void trigger_optionsset_string( int opt_idx, int opt_flags, - char_u *oldval, - char_u *newval) + char_u *oldval, + char_u *oldval_l, + char_u *oldval_g, + char_u *newval) { // Don't do this recursively. if (oldval != NULL && newval != NULL @@ -4354,6 +4367,27 @@ trigger_optionsset_string( set_vim_var_string(VV_OPTION_OLD, oldval, -1); set_vim_var_string(VV_OPTION_NEW, newval, -1); set_vim_var_string(VV_OPTION_TYPE, buf_type, -1); + if (opt_flags & OPT_LOCAL) + { + set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setlocal", -1); + set_vim_var_string(VV_OPTION_OLDLOCAL, oldval, -1); + } + if (opt_flags & OPT_GLOBAL) + { + set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setglobal", -1); + set_vim_var_string(VV_OPTION_OLDGLOBAL, oldval, -1); + } + if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) + { + set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"set", -1); + set_vim_var_string(VV_OPTION_OLDLOCAL, oldval_l, -1); + set_vim_var_string(VV_OPTION_OLDGLOBAL, oldval_g, -1); + } + if (opt_flags & OPT_MODELINE) + { + set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"modeline", -1); + set_vim_var_string(VV_OPTION_OLDLOCAL, oldval, -1); + } apply_autocmds(EVENT_OPTIONSET, (char_u *)options[opt_idx].fullname, NULL, FALSE, NULL); reset_v_option_vars(); @@ -4836,8 +4870,12 @@ do_set( char_u *oldval = NULL; /* previous value if *varp */ char_u *newval; char_u *origval = NULL; + char_u *origval_l = NULL; + char_u *origval_g = NULL; #if defined(FEAT_EVAL) char_u *saved_origval = NULL; + char_u *saved_origval_l = NULL; + char_u *saved_origval_g = NULL; char_u *saved_newval = NULL; #endif unsigned newlen; @@ -4857,8 +4895,23 @@ do_set( * new value is valid. */ oldval = *(char_u **)varp; - /* When setting the local value of a global - * option, the old value may be the global value. */ + if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) + { + origval_l = *(char_u **)get_varp_scope( + &(options[opt_idx]), OPT_LOCAL); + origval_g = *(char_u **)get_varp_scope( + &(options[opt_idx]), OPT_GLOBAL); + + // A global-local string option might have an empty + // option as value to indicate that the global + // value should be used. + if (((int)options[opt_idx].indir & PV_BOTH) + && origval_l == empty_option) + origval_l = origval_g; + } + + // When setting the local value of a global + // option, the old value may be the global value. if (((int)options[opt_idx].indir & PV_BOTH) && (opt_flags & OPT_LOCAL)) origval = *(char_u **)get_varp( @@ -4944,6 +4997,10 @@ do_set( vim_free(oldval); if (origval == oldval) origval = *(char_u **)varp; + if (origval_l == oldval) + origval_l = *(char_u **)varp; + if (origval_g == oldval) + origval_g = *(char_u **)varp; oldval = *(char_u **)varp; } /* @@ -5201,6 +5258,10 @@ do_set( /* newval (and varp) may become invalid if the * buffer is closed by autocommands. */ saved_newval = vim_strsave(newval); + if (origval_l != NULL) + saved_origval_l = vim_strsave(origval_l); + if (origval_g != NULL) + saved_origval_g = vim_strsave(origval_g); } #endif @@ -5234,9 +5295,13 @@ do_set( #if defined(FEAT_EVAL) if (errmsg == NULL) - trigger_optionsset_string(opt_idx, opt_flags, - saved_origval, saved_newval); + trigger_optionsset_string( + opt_idx, opt_flags, saved_origval, + saved_origval_l, saved_origval_g, + saved_newval); vim_free(saved_origval); + vim_free(saved_origval_l); + vim_free(saved_origval_g); vim_free(saved_newval); #endif /* If error detected, print the error message. */ @@ -6070,8 +6135,12 @@ set_string_option( char_u *s; char_u **varp; char_u *oldval; + char_u *oldval_l = NULL; + char_u *oldval_g = NULL; #if defined(FEAT_EVAL) char_u *saved_oldval = NULL; + char_u *saved_oldval_l = NULL; + char_u *saved_oldval_g = NULL; char_u *saved_newval = NULL; #endif char *r = NULL; @@ -6089,6 +6158,13 @@ set_string_option( ? OPT_GLOBAL : OPT_LOCAL) : opt_flags); oldval = *varp; + if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) + { + oldval_l = *(char_u **)get_varp_scope(&(options[opt_idx]), + OPT_LOCAL); + oldval_g = *(char_u **)get_varp_scope(&(options[opt_idx]), + OPT_GLOBAL); + } *varp = s; #if defined(FEAT_EVAL) @@ -6098,6 +6174,10 @@ set_string_option( # endif ) { + if (oldval_l != NULL) + saved_oldval_l = vim_strsave(oldval_l); + if (oldval_g != NULL) + saved_oldval_g = vim_strsave(oldval_g); saved_oldval = vim_strsave(oldval); saved_newval = vim_strsave(s); } @@ -6110,8 +6190,11 @@ set_string_option( /* call autocommand after handling side effects */ if (r == NULL) trigger_optionsset_string(opt_idx, opt_flags, - saved_oldval, saved_newval); + saved_oldval, saved_oldval_l, + saved_oldval_g, saved_newval); vim_free(saved_oldval); + vim_free(saved_oldval_l); + vim_free(saved_oldval_g); vim_free(saved_newval); #endif } @@ -8442,6 +8525,7 @@ set_bool_option( int opt_flags) /* OPT_LOCAL and/or OPT_GLOBAL */ { int old_value = *(int *)varp; + int old_global_value = 0; /* Disallow changing some options from secure mode */ if ((secure @@ -8451,6 +8535,13 @@ set_bool_option( ) && (options[opt_idx].flags & P_SECURE)) return e_secure; + // Save the global value before changing anything. This is needed as for + // a global-only option setting the "local value" in fact sets the global + // value (since there is only one value). + if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) + old_global_value = *(int *)get_varp_scope(&(options[opt_idx]), + OPT_GLOBAL); + *(int *)varp = value; /* set the new value */ #ifdef FEAT_EVAL /* Remember where the option was set. */ @@ -8976,15 +9067,40 @@ set_bool_option( // Don't do this while starting up or recursively. if (!starting && *get_vim_var_str(VV_OPTION_TYPE) == NUL) { - char_u buf_old[2], buf_new[2], buf_type[7]; + char_u buf_old[2], buf_old_global[2], buf_new[2], buf_type[7]; vim_snprintf((char *)buf_old, 2, "%d", old_value ? TRUE: FALSE); + vim_snprintf((char *)buf_old_global, 2, "%d", + old_global_value ? TRUE: FALSE); vim_snprintf((char *)buf_new, 2, "%d", value ? TRUE: FALSE); - vim_snprintf((char *)buf_type, 7, "%s", (opt_flags & OPT_LOCAL) ? "local" : "global"); + vim_snprintf((char *)buf_type, 7, "%s", + (opt_flags & OPT_LOCAL) ? "local" : "global"); set_vim_var_string(VV_OPTION_NEW, buf_new, -1); set_vim_var_string(VV_OPTION_OLD, buf_old, -1); set_vim_var_string(VV_OPTION_TYPE, buf_type, -1); - apply_autocmds(EVENT_OPTIONSET, (char_u *) options[opt_idx].fullname, NULL, FALSE, NULL); + if (opt_flags & OPT_LOCAL) + { + set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setlocal", -1); + set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1); + } + if (opt_flags & OPT_GLOBAL) + { + set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setglobal", -1); + set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old, -1); + } + if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) + { + set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"set", -1); + set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1); + set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old_global, -1); + } + if (opt_flags & OPT_MODELINE) + { + set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"modeline", -1); + set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1); + } + apply_autocmds(EVENT_OPTIONSET, (char_u *)options[opt_idx].fullname, + NULL, FALSE, NULL); reset_v_option_vars(); } #endif @@ -9014,8 +9130,10 @@ set_num_option( { char *errmsg = NULL; long old_value = *(long *)varp; - long old_Rows = Rows; /* remember old Rows */ - long old_Columns = Columns; /* remember old Columns */ + long old_global_value = 0; // only used when setting a local and + // global option + long old_Rows = Rows; // remember old Rows + long old_Columns = Columns; // remember old Columns long *pp = (long *)varp; /* Disallow changing some options from secure mode. */ @@ -9026,6 +9144,12 @@ set_num_option( ) && (options[opt_idx].flags & P_SECURE)) return e_secure; + // Save the global value before changing anything. This is needed as for + // a global-only option setting the "local value" infact sets the global + // value (since there is only one value). + if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) + old_global_value = *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL); + *pp = value; #ifdef FEAT_EVAL /* Remember where the option was set. */ @@ -9533,15 +9657,37 @@ set_num_option( // Don't do this while starting up, failure or recursively. if (!starting && errmsg == NULL && *get_vim_var_str(VV_OPTION_TYPE) == NUL) { - char_u buf_old[11], buf_new[11], buf_type[7]; - + char_u buf_old[11], buf_old_global[11], buf_new[11], buf_type[7]; vim_snprintf((char *)buf_old, 10, "%ld", old_value); + vim_snprintf((char *)buf_old_global, 10, "%ld", old_global_value); vim_snprintf((char *)buf_new, 10, "%ld", value); vim_snprintf((char *)buf_type, 7, "%s", (opt_flags & OPT_LOCAL) ? "local" : "global"); set_vim_var_string(VV_OPTION_NEW, buf_new, -1); set_vim_var_string(VV_OPTION_OLD, buf_old, -1); set_vim_var_string(VV_OPTION_TYPE, buf_type, -1); - apply_autocmds(EVENT_OPTIONSET, (char_u *) options[opt_idx].fullname, NULL, FALSE, NULL); + if (opt_flags & OPT_LOCAL) + { + set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setlocal", -1); + set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1); + } + if (opt_flags & OPT_GLOBAL) + { + set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setglobal", -1); + set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old, -1); + } + if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) + { + set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"set", -1); + set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1); + set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old_global, -1); + } + if (opt_flags & OPT_MODELINE) + { + set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"modeline", -1); + set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1); + } + apply_autocmds(EVENT_OPTIONSET, (char_u *)options[opt_idx].fullname, + NULL, FALSE, NULL); reset_v_option_vars(); } #endif |