comparison src/option.c @ 17085:620e9011b685 v8.1.1542

patch 8.1.1542: an OptionSet autocommand does not get enough info commit https://github.com/vim/vim/commit/d7c968794710f338d491072171df48f96612cf72 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jun 15 17:12:48 2019 +0200 patch 8.1.1542: an OptionSet autocommand does not get enough info 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)
author Bram Moolenaar <Bram@vim.org>
date Sat, 15 Jun 2019 17:15:05 +0200
parents d726d8cce996
children 1c2d05cb4d1d
comparison
equal deleted inserted replaced
17084:06dcb09b3b07 17085:620e9011b685
4334 } 4334 }
4335 } 4335 }
4336 #endif 4336 #endif
4337 4337
4338 #if defined(FEAT_EVAL) 4338 #if defined(FEAT_EVAL)
4339 /*
4340 * Trigger the OptionSet autocommand.
4341 * "opt_idx" is the index of the option being set.
4342 * "opt_flags" can be OPT_LOCAL etc.
4343 * "oldval" the old value
4344 * "oldval_l" the old local value (only non-NULL if global and local value
4345 * are set)
4346 * "oldval_g" the old global value (only non-NULL if global and local value
4347 * are set)
4348 * "newval" the new value
4349 */
4339 static void 4350 static void
4340 trigger_optionsset_string( 4351 trigger_optionsset_string(
4341 int opt_idx, 4352 int opt_idx,
4342 int opt_flags, 4353 int opt_flags,
4343 char_u *oldval, 4354 char_u *oldval,
4344 char_u *newval) 4355 char_u *oldval_l,
4356 char_u *oldval_g,
4357 char_u *newval)
4345 { 4358 {
4346 // Don't do this recursively. 4359 // Don't do this recursively.
4347 if (oldval != NULL && newval != NULL 4360 if (oldval != NULL && newval != NULL
4348 && *get_vim_var_str(VV_OPTION_TYPE) == NUL) 4361 && *get_vim_var_str(VV_OPTION_TYPE) == NUL)
4349 { 4362 {
4352 sprintf((char *)buf_type, "%s", 4365 sprintf((char *)buf_type, "%s",
4353 (opt_flags & OPT_LOCAL) ? "local" : "global"); 4366 (opt_flags & OPT_LOCAL) ? "local" : "global");
4354 set_vim_var_string(VV_OPTION_OLD, oldval, -1); 4367 set_vim_var_string(VV_OPTION_OLD, oldval, -1);
4355 set_vim_var_string(VV_OPTION_NEW, newval, -1); 4368 set_vim_var_string(VV_OPTION_NEW, newval, -1);
4356 set_vim_var_string(VV_OPTION_TYPE, buf_type, -1); 4369 set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
4370 if (opt_flags & OPT_LOCAL)
4371 {
4372 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setlocal", -1);
4373 set_vim_var_string(VV_OPTION_OLDLOCAL, oldval, -1);
4374 }
4375 if (opt_flags & OPT_GLOBAL)
4376 {
4377 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setglobal", -1);
4378 set_vim_var_string(VV_OPTION_OLDGLOBAL, oldval, -1);
4379 }
4380 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
4381 {
4382 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"set", -1);
4383 set_vim_var_string(VV_OPTION_OLDLOCAL, oldval_l, -1);
4384 set_vim_var_string(VV_OPTION_OLDGLOBAL, oldval_g, -1);
4385 }
4386 if (opt_flags & OPT_MODELINE)
4387 {
4388 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"modeline", -1);
4389 set_vim_var_string(VV_OPTION_OLDLOCAL, oldval, -1);
4390 }
4357 apply_autocmds(EVENT_OPTIONSET, 4391 apply_autocmds(EVENT_OPTIONSET,
4358 (char_u *)options[opt_idx].fullname, NULL, FALSE, NULL); 4392 (char_u *)options[opt_idx].fullname, NULL, FALSE, NULL);
4359 reset_v_option_vars(); 4393 reset_v_option_vars();
4360 } 4394 }
4361 } 4395 }
4834 char_u *save_arg = NULL; 4868 char_u *save_arg = NULL;
4835 char_u *s = NULL; 4869 char_u *s = NULL;
4836 char_u *oldval = NULL; /* previous value if *varp */ 4870 char_u *oldval = NULL; /* previous value if *varp */
4837 char_u *newval; 4871 char_u *newval;
4838 char_u *origval = NULL; 4872 char_u *origval = NULL;
4873 char_u *origval_l = NULL;
4874 char_u *origval_g = NULL;
4839 #if defined(FEAT_EVAL) 4875 #if defined(FEAT_EVAL)
4840 char_u *saved_origval = NULL; 4876 char_u *saved_origval = NULL;
4877 char_u *saved_origval_l = NULL;
4878 char_u *saved_origval_g = NULL;
4841 char_u *saved_newval = NULL; 4879 char_u *saved_newval = NULL;
4842 #endif 4880 #endif
4843 unsigned newlen; 4881 unsigned newlen;
4844 int comma; 4882 int comma;
4845 int bs; 4883 int bs;
4855 4893
4856 /* The old value is kept until we are sure that the 4894 /* The old value is kept until we are sure that the
4857 * new value is valid. */ 4895 * new value is valid. */
4858 oldval = *(char_u **)varp; 4896 oldval = *(char_u **)varp;
4859 4897
4860 /* When setting the local value of a global 4898 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
4861 * option, the old value may be the global value. */ 4899 {
4900 origval_l = *(char_u **)get_varp_scope(
4901 &(options[opt_idx]), OPT_LOCAL);
4902 origval_g = *(char_u **)get_varp_scope(
4903 &(options[opt_idx]), OPT_GLOBAL);
4904
4905 // A global-local string option might have an empty
4906 // option as value to indicate that the global
4907 // value should be used.
4908 if (((int)options[opt_idx].indir & PV_BOTH)
4909 && origval_l == empty_option)
4910 origval_l = origval_g;
4911 }
4912
4913 // When setting the local value of a global
4914 // option, the old value may be the global value.
4862 if (((int)options[opt_idx].indir & PV_BOTH) 4915 if (((int)options[opt_idx].indir & PV_BOTH)
4863 && (opt_flags & OPT_LOCAL)) 4916 && (opt_flags & OPT_LOCAL))
4864 origval = *(char_u **)get_varp( 4917 origval = *(char_u **)get_varp(
4865 &options[opt_idx]); 4918 &options[opt_idx]);
4866 else 4919 else
4942 break; 4995 break;
4943 } 4996 }
4944 vim_free(oldval); 4997 vim_free(oldval);
4945 if (origval == oldval) 4998 if (origval == oldval)
4946 origval = *(char_u **)varp; 4999 origval = *(char_u **)varp;
5000 if (origval_l == oldval)
5001 origval_l = *(char_u **)varp;
5002 if (origval_g == oldval)
5003 origval_g = *(char_u **)varp;
4947 oldval = *(char_u **)varp; 5004 oldval = *(char_u **)varp;
4948 } 5005 }
4949 /* 5006 /*
4950 * Convert 'whichwrap' number to string, for 5007 * Convert 'whichwrap' number to string, for
4951 * backwards compatibility with Vim 3.0. 5008 * backwards compatibility with Vim 3.0.
5199 * did_set_string_option(), make a copy. */ 5256 * did_set_string_option(), make a copy. */
5200 saved_origval = vim_strsave(origval); 5257 saved_origval = vim_strsave(origval);
5201 /* newval (and varp) may become invalid if the 5258 /* newval (and varp) may become invalid if the
5202 * buffer is closed by autocommands. */ 5259 * buffer is closed by autocommands. */
5203 saved_newval = vim_strsave(newval); 5260 saved_newval = vim_strsave(newval);
5261 if (origval_l != NULL)
5262 saved_origval_l = vim_strsave(origval_l);
5263 if (origval_g != NULL)
5264 saved_origval_g = vim_strsave(origval_g);
5204 } 5265 }
5205 #endif 5266 #endif
5206 5267
5207 { 5268 {
5208 long_u *p = insecure_flag(opt_idx, opt_flags); 5269 long_u *p = insecure_flag(opt_idx, opt_flags);
5232 secure = secure_saved; 5293 secure = secure_saved;
5233 } 5294 }
5234 5295
5235 #if defined(FEAT_EVAL) 5296 #if defined(FEAT_EVAL)
5236 if (errmsg == NULL) 5297 if (errmsg == NULL)
5237 trigger_optionsset_string(opt_idx, opt_flags, 5298 trigger_optionsset_string(
5238 saved_origval, saved_newval); 5299 opt_idx, opt_flags, saved_origval,
5300 saved_origval_l, saved_origval_g,
5301 saved_newval);
5239 vim_free(saved_origval); 5302 vim_free(saved_origval);
5303 vim_free(saved_origval_l);
5304 vim_free(saved_origval_g);
5240 vim_free(saved_newval); 5305 vim_free(saved_newval);
5241 #endif 5306 #endif
5242 /* If error detected, print the error message. */ 5307 /* If error detected, print the error message. */
5243 if (errmsg != NULL) 5308 if (errmsg != NULL)
5244 goto skip; 5309 goto skip;
6068 int opt_flags) /* OPT_LOCAL and/or OPT_GLOBAL */ 6133 int opt_flags) /* OPT_LOCAL and/or OPT_GLOBAL */
6069 { 6134 {
6070 char_u *s; 6135 char_u *s;
6071 char_u **varp; 6136 char_u **varp;
6072 char_u *oldval; 6137 char_u *oldval;
6138 char_u *oldval_l = NULL;
6139 char_u *oldval_g = NULL;
6073 #if defined(FEAT_EVAL) 6140 #if defined(FEAT_EVAL)
6074 char_u *saved_oldval = NULL; 6141 char_u *saved_oldval = NULL;
6142 char_u *saved_oldval_l = NULL;
6143 char_u *saved_oldval_g = NULL;
6075 char_u *saved_newval = NULL; 6144 char_u *saved_newval = NULL;
6076 #endif 6145 #endif
6077 char *r = NULL; 6146 char *r = NULL;
6078 int value_checked = FALSE; 6147 int value_checked = FALSE;
6079 6148
6087 (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0 6156 (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
6088 ? (((int)options[opt_idx].indir & PV_BOTH) 6157 ? (((int)options[opt_idx].indir & PV_BOTH)
6089 ? OPT_GLOBAL : OPT_LOCAL) 6158 ? OPT_GLOBAL : OPT_LOCAL)
6090 : opt_flags); 6159 : opt_flags);
6091 oldval = *varp; 6160 oldval = *varp;
6161 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
6162 {
6163 oldval_l = *(char_u **)get_varp_scope(&(options[opt_idx]),
6164 OPT_LOCAL);
6165 oldval_g = *(char_u **)get_varp_scope(&(options[opt_idx]),
6166 OPT_GLOBAL);
6167 }
6092 *varp = s; 6168 *varp = s;
6093 6169
6094 #if defined(FEAT_EVAL) 6170 #if defined(FEAT_EVAL)
6095 if (!starting 6171 if (!starting
6096 # ifdef FEAT_CRYPT 6172 # ifdef FEAT_CRYPT
6097 && options[opt_idx].indir != PV_KEY 6173 && options[opt_idx].indir != PV_KEY
6098 # endif 6174 # endif
6099 ) 6175 )
6100 { 6176 {
6177 if (oldval_l != NULL)
6178 saved_oldval_l = vim_strsave(oldval_l);
6179 if (oldval_g != NULL)
6180 saved_oldval_g = vim_strsave(oldval_g);
6101 saved_oldval = vim_strsave(oldval); 6181 saved_oldval = vim_strsave(oldval);
6102 saved_newval = vim_strsave(s); 6182 saved_newval = vim_strsave(s);
6103 } 6183 }
6104 #endif 6184 #endif
6105 if ((r = did_set_string_option(opt_idx, varp, TRUE, oldval, NULL, 6185 if ((r = did_set_string_option(opt_idx, varp, TRUE, oldval, NULL,
6108 6188
6109 #if defined(FEAT_EVAL) 6189 #if defined(FEAT_EVAL)
6110 /* call autocommand after handling side effects */ 6190 /* call autocommand after handling side effects */
6111 if (r == NULL) 6191 if (r == NULL)
6112 trigger_optionsset_string(opt_idx, opt_flags, 6192 trigger_optionsset_string(opt_idx, opt_flags,
6113 saved_oldval, saved_newval); 6193 saved_oldval, saved_oldval_l,
6194 saved_oldval_g, saved_newval);
6114 vim_free(saved_oldval); 6195 vim_free(saved_oldval);
6196 vim_free(saved_oldval_l);
6197 vim_free(saved_oldval_g);
6115 vim_free(saved_newval); 6198 vim_free(saved_newval);
6116 #endif 6199 #endif
6117 } 6200 }
6118 return r; 6201 return r;
6119 } 6202 }
8440 char_u *varp, /* pointer to the option variable */ 8523 char_u *varp, /* pointer to the option variable */
8441 int value, /* new value */ 8524 int value, /* new value */
8442 int opt_flags) /* OPT_LOCAL and/or OPT_GLOBAL */ 8525 int opt_flags) /* OPT_LOCAL and/or OPT_GLOBAL */
8443 { 8526 {
8444 int old_value = *(int *)varp; 8527 int old_value = *(int *)varp;
8528 int old_global_value = 0;
8445 8529
8446 /* Disallow changing some options from secure mode */ 8530 /* Disallow changing some options from secure mode */
8447 if ((secure 8531 if ((secure
8448 #ifdef HAVE_SANDBOX 8532 #ifdef HAVE_SANDBOX
8449 || sandbox != 0 8533 || sandbox != 0
8450 #endif 8534 #endif
8451 ) && (options[opt_idx].flags & P_SECURE)) 8535 ) && (options[opt_idx].flags & P_SECURE))
8452 return e_secure; 8536 return e_secure;
8537
8538 // Save the global value before changing anything. This is needed as for
8539 // a global-only option setting the "local value" in fact sets the global
8540 // value (since there is only one value).
8541 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
8542 old_global_value = *(int *)get_varp_scope(&(options[opt_idx]),
8543 OPT_GLOBAL);
8453 8544
8454 *(int *)varp = value; /* set the new value */ 8545 *(int *)varp = value; /* set the new value */
8455 #ifdef FEAT_EVAL 8546 #ifdef FEAT_EVAL
8456 /* Remember where the option was set. */ 8547 /* Remember where the option was set. */
8457 set_option_sctx_idx(opt_idx, opt_flags, current_sctx); 8548 set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
8974 9065
8975 #if defined(FEAT_EVAL) 9066 #if defined(FEAT_EVAL)
8976 // Don't do this while starting up or recursively. 9067 // Don't do this while starting up or recursively.
8977 if (!starting && *get_vim_var_str(VV_OPTION_TYPE) == NUL) 9068 if (!starting && *get_vim_var_str(VV_OPTION_TYPE) == NUL)
8978 { 9069 {
8979 char_u buf_old[2], buf_new[2], buf_type[7]; 9070 char_u buf_old[2], buf_old_global[2], buf_new[2], buf_type[7];
8980 9071
8981 vim_snprintf((char *)buf_old, 2, "%d", old_value ? TRUE: FALSE); 9072 vim_snprintf((char *)buf_old, 2, "%d", old_value ? TRUE: FALSE);
9073 vim_snprintf((char *)buf_old_global, 2, "%d",
9074 old_global_value ? TRUE: FALSE);
8982 vim_snprintf((char *)buf_new, 2, "%d", value ? TRUE: FALSE); 9075 vim_snprintf((char *)buf_new, 2, "%d", value ? TRUE: FALSE);
8983 vim_snprintf((char *)buf_type, 7, "%s", (opt_flags & OPT_LOCAL) ? "local" : "global"); 9076 vim_snprintf((char *)buf_type, 7, "%s",
9077 (opt_flags & OPT_LOCAL) ? "local" : "global");
8984 set_vim_var_string(VV_OPTION_NEW, buf_new, -1); 9078 set_vim_var_string(VV_OPTION_NEW, buf_new, -1);
8985 set_vim_var_string(VV_OPTION_OLD, buf_old, -1); 9079 set_vim_var_string(VV_OPTION_OLD, buf_old, -1);
8986 set_vim_var_string(VV_OPTION_TYPE, buf_type, -1); 9080 set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
8987 apply_autocmds(EVENT_OPTIONSET, (char_u *) options[opt_idx].fullname, NULL, FALSE, NULL); 9081 if (opt_flags & OPT_LOCAL)
9082 {
9083 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setlocal", -1);
9084 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
9085 }
9086 if (opt_flags & OPT_GLOBAL)
9087 {
9088 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setglobal", -1);
9089 set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old, -1);
9090 }
9091 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
9092 {
9093 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"set", -1);
9094 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
9095 set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old_global, -1);
9096 }
9097 if (opt_flags & OPT_MODELINE)
9098 {
9099 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"modeline", -1);
9100 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
9101 }
9102 apply_autocmds(EVENT_OPTIONSET, (char_u *)options[opt_idx].fullname,
9103 NULL, FALSE, NULL);
8988 reset_v_option_vars(); 9104 reset_v_option_vars();
8989 } 9105 }
8990 #endif 9106 #endif
8991 9107
8992 comp_col(); /* in case 'ruler' or 'showcmd' changed */ 9108 comp_col(); /* in case 'ruler' or 'showcmd' changed */
9012 int opt_flags) /* OPT_LOCAL, OPT_GLOBAL and 9128 int opt_flags) /* OPT_LOCAL, OPT_GLOBAL and
9013 OPT_MODELINE */ 9129 OPT_MODELINE */
9014 { 9130 {
9015 char *errmsg = NULL; 9131 char *errmsg = NULL;
9016 long old_value = *(long *)varp; 9132 long old_value = *(long *)varp;
9017 long old_Rows = Rows; /* remember old Rows */ 9133 long old_global_value = 0; // only used when setting a local and
9018 long old_Columns = Columns; /* remember old Columns */ 9134 // global option
9135 long old_Rows = Rows; // remember old Rows
9136 long old_Columns = Columns; // remember old Columns
9019 long *pp = (long *)varp; 9137 long *pp = (long *)varp;
9020 9138
9021 /* Disallow changing some options from secure mode. */ 9139 /* Disallow changing some options from secure mode. */
9022 if ((secure 9140 if ((secure
9023 #ifdef HAVE_SANDBOX 9141 #ifdef HAVE_SANDBOX
9024 || sandbox != 0 9142 || sandbox != 0
9025 #endif 9143 #endif
9026 ) && (options[opt_idx].flags & P_SECURE)) 9144 ) && (options[opt_idx].flags & P_SECURE))
9027 return e_secure; 9145 return e_secure;
9146
9147 // Save the global value before changing anything. This is needed as for
9148 // a global-only option setting the "local value" infact sets the global
9149 // value (since there is only one value).
9150 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
9151 old_global_value = *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL);
9028 9152
9029 *pp = value; 9153 *pp = value;
9030 #ifdef FEAT_EVAL 9154 #ifdef FEAT_EVAL
9031 /* Remember where the option was set. */ 9155 /* Remember where the option was set. */
9032 set_option_sctx_idx(opt_idx, opt_flags, current_sctx); 9156 set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
9531 9655
9532 #if defined(FEAT_EVAL) 9656 #if defined(FEAT_EVAL)
9533 // Don't do this while starting up, failure or recursively. 9657 // Don't do this while starting up, failure or recursively.
9534 if (!starting && errmsg == NULL && *get_vim_var_str(VV_OPTION_TYPE) == NUL) 9658 if (!starting && errmsg == NULL && *get_vim_var_str(VV_OPTION_TYPE) == NUL)
9535 { 9659 {
9536 char_u buf_old[11], buf_new[11], buf_type[7]; 9660 char_u buf_old[11], buf_old_global[11], buf_new[11], buf_type[7];
9537
9538 vim_snprintf((char *)buf_old, 10, "%ld", old_value); 9661 vim_snprintf((char *)buf_old, 10, "%ld", old_value);
9662 vim_snprintf((char *)buf_old_global, 10, "%ld", old_global_value);
9539 vim_snprintf((char *)buf_new, 10, "%ld", value); 9663 vim_snprintf((char *)buf_new, 10, "%ld", value);
9540 vim_snprintf((char *)buf_type, 7, "%s", (opt_flags & OPT_LOCAL) ? "local" : "global"); 9664 vim_snprintf((char *)buf_type, 7, "%s", (opt_flags & OPT_LOCAL) ? "local" : "global");
9541 set_vim_var_string(VV_OPTION_NEW, buf_new, -1); 9665 set_vim_var_string(VV_OPTION_NEW, buf_new, -1);
9542 set_vim_var_string(VV_OPTION_OLD, buf_old, -1); 9666 set_vim_var_string(VV_OPTION_OLD, buf_old, -1);
9543 set_vim_var_string(VV_OPTION_TYPE, buf_type, -1); 9667 set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
9544 apply_autocmds(EVENT_OPTIONSET, (char_u *) options[opt_idx].fullname, NULL, FALSE, NULL); 9668 if (opt_flags & OPT_LOCAL)
9669 {
9670 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setlocal", -1);
9671 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
9672 }
9673 if (opt_flags & OPT_GLOBAL)
9674 {
9675 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setglobal", -1);
9676 set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old, -1);
9677 }
9678 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
9679 {
9680 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"set", -1);
9681 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
9682 set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old_global, -1);
9683 }
9684 if (opt_flags & OPT_MODELINE)
9685 {
9686 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"modeline", -1);
9687 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
9688 }
9689 apply_autocmds(EVENT_OPTIONSET, (char_u *)options[opt_idx].fullname,
9690 NULL, FALSE, NULL);
9545 reset_v_option_vars(); 9691 reset_v_option_vars();
9546 } 9692 }
9547 #endif 9693 #endif
9548 9694
9549 comp_col(); /* in case 'columns' or 'ls' changed */ 9695 comp_col(); /* in case 'columns' or 'ls' changed */