1 /* vi:set ts=8 sts=4 sw=4 noet: 2 * 3 * VIM - Vi IMproved by Bram Moolenaar 4 * 5 * Do ":help uganda" in Vim to read copying and usage conditions. 6 * Do ":help credits" in Vim to see a list of people who contributed. 7 * See README.txt for an overview of the Vim source code. 8 */ 9 10 /* 11 * Code to handle user-settable options. This is all pretty much table- 12 * driven. Checklist for adding a new option: 13 * - Put it in the options array below (copy an existing entry). 14 * - For a global option: Add a variable for it in option.h. 15 * - For a buffer or window local option: 16 * - Add a PV_XX entry to the enum below. 17 * - Add a variable to the window or buffer struct in structs.h. 18 * - For a window option, add some code to copy_winopt(). 19 * - For a buffer option, add some code to buf_copy_options(). 20 * - For a buffer string option, add code to check_buf_options(). 21 * - If it's a numeric option, add any necessary bounds checks to do_set(). 22 * - If it's a list of flags, add some code in do_set(), search for WW_ALL. 23 * - When adding an option with expansion (P_EXPAND), but with a different 24 * default for Vi and Vim (no P_VI_DEF), add some code at VIMEXP. 25 * - Add documentation! One line in doc/quickref.txt, full description in 26 * options.txt, and any other related places. 27 * - Add an entry in runtime/optwin.vim. 28 * When making changes: 29 * - Adjust the help for the option in doc/option.txt. 30 * - When an entry has the P_VIM flag, or is lacking the P_VI_DEF flag, add a 31 * comment at the help for the 'compatible' option. 32 */ 33 34 #define IN_OPTION_C 35 #include "vim.h" 36 #include "optiondefs.h" 37 38 static void set_options_default(int opt_flags); 39 static void set_string_default_esc(char *name, char_u *val, int escape); 40 static char_u *find_dup_item(char_u *origval, char_u *newval, long_u flags); 41 static char_u *option_expand(int opt_idx, char_u *val); 42 static void didset_options(void); 43 static void didset_options2(void); 44 #if defined(FEAT_EVAL) || defined(PROTO) 45 static long_u *insecure_flag(int opt_idx, int opt_flags); 46 #else 47 # define insecure_flag(opt_idx, opt_flags) (&options[opt_idx].flags) 48 #endif 49 static char *set_bool_option(int opt_idx, char_u *varp, int value, int opt_flags); 50 static char *set_num_option(int opt_idx, char_u *varp, long value, char *errbuf, size_t errbuflen, int opt_flags); 51 static int find_key_option(char_u *arg_arg, int has_lt); 52 static void showoptions(int all, int opt_flags); 53 static int optval_default(struct vimoption *, char_u *varp, int compatible); 54 static void showoneopt(struct vimoption *, int opt_flags); 55 static int put_setstring(FILE *fd, char *cmd, char *name, char_u **valuep, long_u flags); 56 static int put_setnum(FILE *fd, char *cmd, char *name, long *valuep); 57 static int put_setbool(FILE *fd, char *cmd, char *name, int value); 58 static int istermoption(struct vimoption *p); 59 static char_u *get_varp_scope(struct vimoption *p, int opt_flags); 60 static char_u *get_varp(struct vimoption *); 61 static void check_win_options(win_T *win); 62 static void option_value2string(struct vimoption *, int opt_flags); 63 static void check_winopt(winopt_T *wop); 64 static int wc_use_keyname(char_u *varp, long *wcp); 65 static void paste_option_changed(void); 66 static void compatible_set(void); 67 68 /* 69 * Initialize the options, first part. 70 * 71 * Called only once from main(), just after creating the first buffer. 72 * If "clean_arg" is TRUE Vim was started with --clean. 73 */ 74 void 75 set_init_1(int clean_arg) 76 { 77 char_u *p; 78 int opt_idx; 79 long_u n; 80 81 #ifdef FEAT_LANGMAP 82 langmap_init(); 83 #endif 84 85 // Be Vi compatible by default 86 p_cp = TRUE; 87 88 // Use POSIX compatibility when $VIM_POSIX is set. 89 if (mch_getenv((char_u *)"VIM_POSIX") != NULL) 90 { 91 set_string_default("cpo", (char_u *)CPO_ALL); 92 set_string_default("shm", (char_u *)SHM_POSIX); 93 } 94 95 /* 96 * Find default value for 'shell' option. 97 * Don't use it if it is empty. 98 */ 99 if (((p = mch_getenv((char_u *)"SHELL")) != NULL && *p != NUL) 100 #if defined(MSWIN) 101 || ((p = mch_getenv((char_u *)"COMSPEC")) != NULL && *p != NUL) 102 || ((p = (char_u *)default_shell()) != NULL && *p != NUL) 103 #endif 104 ) 105 #if defined(MSWIN) 106 { 107 // For MS-Windows put the path in quotes instead of escaping spaces. 108 char_u *cmd; 109 size_t len; 110 111 if (vim_strchr(p, ' ') != NULL) 112 { 113 len = STRLEN(p) + 3; // two quotes and a trailing NUL 114 cmd = alloc(len); 115 if (cmd != NULL) 116 { 117 vim_snprintf((char *)cmd, len, "\"%s\"", p); 118 set_string_default("sh", cmd); 119 vim_free(cmd); 120 } 121 } 122 else 123 set_string_default("sh", p); 124 } 125 #else 126 set_string_default_esc("sh", p, TRUE); 127 #endif 128 129 #ifdef FEAT_WILDIGN 130 /* 131 * Set the default for 'backupskip' to include environment variables for 132 * temp files. 133 */ 134 { 135 # ifdef UNIX 136 static char *(names[4]) = {"", "TMPDIR", "TEMP", "TMP"}; 137 # else 138 static char *(names[3]) = {"TMPDIR", "TEMP", "TMP"}; 139 # endif 140 int len; 141 garray_T ga; 142 int mustfree; 143 char_u *item; 144 145 opt_idx = findoption((char_u *)"backupskip"); 146 147 ga_init2(&ga, 1, 100); 148 for (n = 0; n < (long)ARRAY_LENGTH(names); ++n) 149 { 150 mustfree = FALSE; 151 # ifdef UNIX 152 if (*names[n] == NUL) 153 # ifdef MACOS_X 154 p = (char_u *)"/private/tmp"; 155 # else 156 p = (char_u *)"/tmp"; 157 # endif 158 else 159 # endif 160 p = vim_getenv((char_u *)names[n], &mustfree); 161 if (p != NULL && *p != NUL) 162 { 163 // First time count the NUL, otherwise count the ','. 164 len = (int)STRLEN(p) + 3; 165 item = alloc(len); 166 STRCPY(item, p); 167 add_pathsep(item); 168 STRCAT(item, "*"); 169 if (find_dup_item(ga.ga_data, item, options[opt_idx].flags) 170 == NULL 171 && ga_grow(&ga, len) == OK) 172 { 173 if (ga.ga_len > 0) 174 STRCAT(ga.ga_data, ","); 175 STRCAT(ga.ga_data, item); 176 ga.ga_len += len; 177 } 178 vim_free(item); 179 } 180 if (mustfree) 181 vim_free(p); 182 } 183 if (ga.ga_data != NULL) 184 { 185 set_string_default("bsk", ga.ga_data); 186 vim_free(ga.ga_data); 187 } 188 } 189 #endif 190 191 /* 192 * 'maxmemtot' and 'maxmem' may have to be adjusted for available memory 193 */ 194 opt_idx = findoption((char_u *)"maxmemtot"); 195 if (opt_idx >= 0) 196 { 197 #if !defined(HAVE_AVAIL_MEM) && !defined(HAVE_TOTAL_MEM) 198 if (options[opt_idx].def_val[VI_DEFAULT] == (char_u *)0L) 199 #endif 200 { 201 #ifdef HAVE_AVAIL_MEM 202 // Use amount of memory available at this moment. 203 n = (mch_avail_mem(FALSE) >> 1); 204 #else 205 # ifdef HAVE_TOTAL_MEM 206 // Use amount of memory available to Vim. 207 n = (mch_total_mem(FALSE) >> 1); 208 # else 209 n = (0x7fffffff >> 11); 210 # endif 211 #endif 212 options[opt_idx].def_val[VI_DEFAULT] = (char_u *)n; 213 opt_idx = findoption((char_u *)"maxmem"); 214 if (opt_idx >= 0) 215 { 216 #if !defined(HAVE_AVAIL_MEM) && !defined(HAVE_TOTAL_MEM) 217 if ((long)(long_i)options[opt_idx].def_val[VI_DEFAULT] > (long)n 218 || (long)(long_i)options[opt_idx].def_val[VI_DEFAULT] == 0L) 219 #endif 220 options[opt_idx].def_val[VI_DEFAULT] = (char_u *)n; 221 } 222 } 223 } 224 225 #ifdef FEAT_SEARCHPATH 226 { 227 char_u *cdpath; 228 char_u *buf; 229 int i; 230 int j; 231 int mustfree = FALSE; 232 233 // Initialize the 'cdpath' option's default value. 234 cdpath = vim_getenv((char_u *)"CDPATH", &mustfree); 235 if (cdpath != NULL) 236 { 237 buf = alloc((STRLEN(cdpath) << 1) + 2); 238 if (buf != NULL) 239 { 240 buf[0] = ','; // start with ",", current dir first 241 j = 1; 242 for (i = 0; cdpath[i] != NUL; ++i) 243 { 244 if (vim_ispathlistsep(cdpath[i])) 245 buf[j++] = ','; 246 else 247 { 248 if (cdpath[i] == ' ' || cdpath[i] == ',') 249 buf[j++] = '\\'; 250 buf[j++] = cdpath[i]; 251 } 252 } 253 buf[j] = NUL; 254 opt_idx = findoption((char_u *)"cdpath"); 255 if (opt_idx >= 0) 256 { 257 options[opt_idx].def_val[VI_DEFAULT] = buf; 258 options[opt_idx].flags |= P_DEF_ALLOCED; 259 } 260 else 261 vim_free(buf); // cannot happen 262 } 263 if (mustfree) 264 vim_free(cdpath); 265 } 266 } 267 #endif 268 269 #if defined(FEAT_POSTSCRIPT) && (defined(MSWIN) || defined(VMS) || defined(EBCDIC) || defined(MAC) || defined(hpux)) 270 // Set print encoding on platforms that don't default to latin1 271 set_string_default("penc", 272 # if defined(MSWIN) 273 (char_u *)"cp1252" 274 # else 275 # ifdef VMS 276 (char_u *)"dec-mcs" 277 # else 278 # ifdef EBCDIC 279 (char_u *)"ebcdic-uk" 280 # else 281 # ifdef MAC 282 (char_u *)"mac-roman" 283 # else // HPUX 284 (char_u *)"hp-roman8" 285 # endif 286 # endif 287 # endif 288 # endif 289 ); 290 #endif 291 292 #ifdef FEAT_POSTSCRIPT 293 // 'printexpr' must be allocated to be able to evaluate it. 294 set_string_default("pexpr", 295 # if defined(MSWIN) 296 (char_u *)"system('copy' . ' ' . v:fname_in . (&printdevice == '' ? ' LPT1:' : (' \"' . &printdevice . '\"'))) . delete(v:fname_in)" 297 # else 298 # ifdef VMS 299 (char_u *)"system('print/delete' . (&printdevice == '' ? '' : ' /queue=' . &printdevice) . ' ' . v:fname_in)" 300 301 # else 302 (char_u *)"system('lpr' . (&printdevice == '' ? '' : ' -P' . &printdevice) . ' ' . v:fname_in) . delete(v:fname_in) + v:shell_error" 303 # endif 304 # endif 305 ); 306 #endif 307 308 /* 309 * Set all the options (except the terminal options) to their default 310 * value. Also set the global value for local options. 311 */ 312 set_options_default(0); 313 314 #ifdef CLEAN_RUNTIMEPATH 315 if (clean_arg) 316 { 317 opt_idx = findoption((char_u *)"runtimepath"); 318 if (opt_idx >= 0) 319 { 320 options[opt_idx].def_val[VI_DEFAULT] = (char_u *)CLEAN_RUNTIMEPATH; 321 p_rtp = (char_u *)CLEAN_RUNTIMEPATH; 322 } 323 opt_idx = findoption((char_u *)"packpath"); 324 if (opt_idx >= 0) 325 { 326 options[opt_idx].def_val[VI_DEFAULT] = (char_u *)CLEAN_RUNTIMEPATH; 327 p_pp = (char_u *)CLEAN_RUNTIMEPATH; 328 } 329 } 330 #endif 331 332 #ifdef FEAT_GUI 333 if (found_reverse_arg) 334 set_option_value((char_u *)"bg", 0L, (char_u *)"dark", 0); 335 #endif 336 337 curbuf->b_p_initialized = TRUE; 338 curbuf->b_p_ar = -1; // no local 'autoread' value 339 curbuf->b_p_ul = NO_LOCAL_UNDOLEVEL; 340 check_buf_options(curbuf); 341 check_win_options(curwin); 342 check_options(); 343 344 // Must be before option_expand(), because that one needs vim_isIDc() 345 didset_options(); 346 347 #ifdef FEAT_SPELL 348 // Use the current chartab for the generic chartab. This is not in 349 // didset_options() because it only depends on 'encoding'. 350 init_spell_chartab(); 351 #endif 352 353 /* 354 * Expand environment variables and things like "~" for the defaults. 355 * If option_expand() returns non-NULL the variable is expanded. This can 356 * only happen for non-indirect options. 357 * Also set the default to the expanded value, so ":set" does not list 358 * them. 359 * Don't set the P_ALLOCED flag, because we don't want to free the 360 * default. 361 */ 362 for (opt_idx = 0; !istermoption_idx(opt_idx); opt_idx++) 363 { 364 if ((options[opt_idx].flags & P_GETTEXT) 365 && options[opt_idx].var != NULL) 366 p = (char_u *)_(*(char **)options[opt_idx].var); 367 else 368 p = option_expand(opt_idx, NULL); 369 if (p != NULL && (p = vim_strsave(p)) != NULL) 370 { 371 *(char_u **)options[opt_idx].var = p; 372 // VIMEXP 373 // Defaults for all expanded options are currently the same for Vi 374 // and Vim. When this changes, add some code here! Also need to 375 // split P_DEF_ALLOCED in two. 376 if (options[opt_idx].flags & P_DEF_ALLOCED) 377 vim_free(options[opt_idx].def_val[VI_DEFAULT]); 378 options[opt_idx].def_val[VI_DEFAULT] = p; 379 options[opt_idx].flags |= P_DEF_ALLOCED; 380 } 381 } 382 383 save_file_ff(curbuf); // Buffer is unchanged 384 385 #if defined(FEAT_ARABIC) 386 // Detect use of mlterm. 387 // Mlterm is a terminal emulator akin to xterm that has some special 388 // abilities (bidi namely). 389 // NOTE: mlterm's author is being asked to 'set' a variable 390 // instead of an environment variable due to inheritance. 391 if (mch_getenv((char_u *)"MLTERM") != NULL) 392 set_option_value((char_u *)"tbidi", 1L, NULL, 0); 393 #endif 394 395 didset_options2(); 396 397 # if defined(MSWIN) && defined(FEAT_GETTEXT) 398 /* 399 * If $LANG isn't set, try to get a good value for it. This makes the 400 * right language be used automatically. Don't do this for English. 401 */ 402 if (mch_getenv((char_u *)"LANG") == NULL) 403 { 404 char buf[20]; 405 406 // Could use LOCALE_SISO639LANGNAME, but it's not in Win95. 407 // LOCALE_SABBREVLANGNAME gives us three letters, like "enu", we use 408 // only the first two. 409 n = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SABBREVLANGNAME, 410 (LPTSTR)buf, 20); 411 if (n >= 2 && STRNICMP(buf, "en", 2) != 0) 412 { 413 // There are a few exceptions (probably more) 414 if (STRNICMP(buf, "cht", 3) == 0 || STRNICMP(buf, "zht", 3) == 0) 415 STRCPY(buf, "zh_TW"); 416 else if (STRNICMP(buf, "chs", 3) == 0 417 || STRNICMP(buf, "zhc", 3) == 0) 418 STRCPY(buf, "zh_CN"); 419 else if (STRNICMP(buf, "jp", 2) == 0) 420 STRCPY(buf, "ja"); 421 else 422 buf[2] = NUL; // truncate to two-letter code 423 vim_setenv((char_u *)"LANG", (char_u *)buf); 424 } 425 } 426 # else 427 # ifdef MACOS_CONVERT 428 // Moved to os_mac_conv.c to avoid dependency problems. 429 mac_lang_init(); 430 # endif 431 # endif 432 433 # ifdef MSWIN 434 // MS-Windows has builtin support for conversion to and from Unicode, using 435 // "utf-8" for 'encoding' should work best for most users. 436 p = vim_strsave((char_u *)ENC_DFLT); 437 # else 438 // enc_locale() will try to find the encoding of the current locale. 439 // This works best for properly configured systems, old and new. 440 p = enc_locale(); 441 # endif 442 if (p != NULL) 443 { 444 char_u *save_enc; 445 446 // Try setting 'encoding' and check if the value is valid. 447 // If not, go back to the default encoding. 448 save_enc = p_enc; 449 p_enc = p; 450 if (STRCMP(p_enc, "gb18030") == 0) 451 { 452 // We don't support "gb18030", but "cp936" is a good substitute 453 // for practical purposes, thus use that. It's not an alias to 454 // still support conversion between gb18030 and utf-8. 455 p_enc = vim_strsave((char_u *)"cp936"); 456 vim_free(p); 457 } 458 if (mb_init() == NULL) 459 { 460 opt_idx = findoption((char_u *)"encoding"); 461 if (opt_idx >= 0) 462 { 463 options[opt_idx].def_val[VI_DEFAULT] = p_enc; 464 options[opt_idx].flags |= P_DEF_ALLOCED; 465 } 466 467 #if defined(MSWIN) || defined(MACOS_X) || defined(VMS) 468 if (STRCMP(p_enc, "latin1") == 0 || enc_utf8) 469 { 470 // Adjust the default for 'isprint' and 'iskeyword' to match 471 // latin1. Also set the defaults for when 'nocompatible' is 472 // set. 473 set_string_option_direct((char_u *)"isp", -1, 474 ISP_LATIN1, OPT_FREE, SID_NONE); 475 set_string_option_direct((char_u *)"isk", -1, 476 ISK_LATIN1, OPT_FREE, SID_NONE); 477 opt_idx = findoption((char_u *)"isp"); 478 if (opt_idx >= 0) 479 options[opt_idx].def_val[VIM_DEFAULT] = ISP_LATIN1; 480 opt_idx = findoption((char_u *)"isk"); 481 if (opt_idx >= 0) 482 options[opt_idx].def_val[VIM_DEFAULT] = ISK_LATIN1; 483 (void)init_chartab(); 484 } 485 #endif 486 487 #if defined(MSWIN) && (!defined(FEAT_GUI) || defined(VIMDLL)) 488 // Win32 console: When GetACP() returns a different value from 489 // GetConsoleCP() set 'termencoding'. 490 if ( 491 # ifdef VIMDLL 492 (!gui.in_use && !gui.starting) && 493 # endif 494 GetACP() != GetConsoleCP()) 495 { 496 char buf[50]; 497 498 // Win32 console: In ConPTY, GetConsoleCP() returns zero. 499 // Use an alternative value. 500 if (GetConsoleCP() == 0) 501 sprintf(buf, "cp%ld", (long)GetACP()); 502 else 503 sprintf(buf, "cp%ld", (long)GetConsoleCP()); 504 p_tenc = vim_strsave((char_u *)buf); 505 if (p_tenc != NULL) 506 { 507 opt_idx = findoption((char_u *)"termencoding"); 508 if (opt_idx >= 0) 509 { 510 options[opt_idx].def_val[VI_DEFAULT] = p_tenc; 511 options[opt_idx].flags |= P_DEF_ALLOCED; 512 } 513 convert_setup(&input_conv, p_tenc, p_enc); 514 convert_setup(&output_conv, p_enc, p_tenc); 515 } 516 else 517 p_tenc = empty_option; 518 } 519 #endif 520 #if defined(MSWIN) 521 // $HOME may have characters in active code page. 522 init_homedir(); 523 #endif 524 } 525 else 526 { 527 vim_free(p_enc); 528 p_enc = save_enc; 529 } 530 } 531 532 #ifdef FEAT_MULTI_LANG 533 // Set the default for 'helplang'. 534 set_helplang_default(get_mess_lang()); 535 #endif 536 } 537 538 static char_u *fencs_utf8_default = (char_u *)"ucs-bom,utf-8,default,latin1"; 539 540 /* 541 * Set the "fileencodings" option to the default value for when 'encoding' is 542 * utf-8. 543 */ 544 void 545 set_fencs_unicode() 546 { 547 set_string_option_direct((char_u *)"fencs", -1, fencs_utf8_default, 548 OPT_FREE, 0); 549 } 550 551 /* 552 * Set an option to its default value. 553 * This does not take care of side effects! 554 */ 555 static void 556 set_option_default( 557 int opt_idx, 558 int opt_flags, // OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL 559 int compatible) // use Vi default value 560 { 561 char_u *varp; // pointer to variable for current option 562 int dvi; // index in def_val[] 563 long_u flags; 564 long_u *flagsp; 565 int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0; 566 567 varp = get_varp_scope(&(options[opt_idx]), both ? OPT_LOCAL : opt_flags); 568 flags = options[opt_idx].flags; 569 if (varp != NULL) // skip hidden option, nothing to do for it 570 { 571 dvi = ((flags & P_VI_DEF) || compatible) ? VI_DEFAULT : VIM_DEFAULT; 572 if (flags & P_STRING) 573 { 574 // 'fencs' default value depends on 'encoding' 575 if (options[opt_idx].var == (char_u *)&p_fencs && enc_utf8) 576 set_fencs_unicode(); 577 // Use set_string_option_direct() for local options to handle 578 // freeing and allocating the value. 579 else if (options[opt_idx].indir != PV_NONE) 580 set_string_option_direct(NULL, opt_idx, 581 options[opt_idx].def_val[dvi], opt_flags, 0); 582 else 583 { 584 if ((opt_flags & OPT_FREE) && (flags & P_ALLOCED)) 585 free_string_option(*(char_u **)(varp)); 586 *(char_u **)varp = options[opt_idx].def_val[dvi]; 587 options[opt_idx].flags &= ~P_ALLOCED; 588 } 589 } 590 else if (flags & P_NUM) 591 { 592 if (options[opt_idx].indir == PV_SCROLL) 593 win_comp_scroll(curwin); 594 else 595 { 596 long def_val = (long)(long_i)options[opt_idx].def_val[dvi]; 597 598 if ((long *)varp == &curwin->w_p_so 599 || (long *)varp == &curwin->w_p_siso) 600 // 'scrolloff' and 'sidescrolloff' local values have a 601 // different default value than the global default. 602 *(long *)varp = -1; 603 else 604 *(long *)varp = def_val; 605 // May also set global value for local option. 606 if (both) 607 *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = 608 def_val; 609 } 610 } 611 else // P_BOOL 612 { 613 // the cast to long is required for Manx C, long_i is needed for 614 // MSVC 615 *(int *)varp = (int)(long)(long_i)options[opt_idx].def_val[dvi]; 616 #ifdef UNIX 617 // 'modeline' defaults to off for root 618 if (options[opt_idx].indir == PV_ML && getuid() == ROOT_UID) 619 *(int *)varp = FALSE; 620 #endif 621 // May also set global value for local option. 622 if (both) 623 *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = 624 *(int *)varp; 625 } 626 627 // The default value is not insecure. 628 flagsp = insecure_flag(opt_idx, opt_flags); 629 *flagsp = *flagsp & ~P_INSECURE; 630 } 631 632 #ifdef FEAT_EVAL 633 set_option_sctx_idx(opt_idx, opt_flags, current_sctx); 634 #endif 635 } 636 637 /* 638 * Set all options (except terminal options) to their default value. 639 * When "opt_flags" is non-zero skip 'encoding'. 640 */ 641 static void 642 set_options_default( 643 int opt_flags) // OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL 644 { 645 int i; 646 win_T *wp; 647 tabpage_T *tp; 648 649 for (i = 0; !istermoption_idx(i); i++) 650 if (!(options[i].flags & P_NODEFAULT) 651 && (opt_flags == 0 652 || (options[i].var != (char_u *)&p_enc 653 # if defined(FEAT_CRYPT) 654 && options[i].var != (char_u *)&p_cm 655 && options[i].var != (char_u *)&p_key 656 # endif 657 ))) 658 set_option_default(i, opt_flags, p_cp); 659 660 // The 'scroll' option must be computed for all windows. 661 FOR_ALL_TAB_WINDOWS(tp, wp) 662 win_comp_scroll(wp); 663 #ifdef FEAT_CINDENT 664 parse_cino(curbuf); 665 #endif 666 } 667 668 /* 669 * Set the Vi-default value of a string option. 670 * Used for 'sh', 'backupskip' and 'term'. 671 * When "escape" is TRUE escape spaces with a backslash. 672 */ 673 static void 674 set_string_default_esc(char *name, char_u *val, int escape) 675 { 676 char_u *p; 677 int opt_idx; 678 679 if (escape && vim_strchr(val, ' ') != NULL) 680 p = vim_strsave_escaped(val, (char_u *)" "); 681 else 682 p = vim_strsave(val); 683 if (p != NULL) // we don't want a NULL 684 { 685 opt_idx = findoption((char_u *)name); 686 if (opt_idx >= 0) 687 { 688 if (options[opt_idx].flags & P_DEF_ALLOCED) 689 vim_free(options[opt_idx].def_val[VI_DEFAULT]); 690 options[opt_idx].def_val[VI_DEFAULT] = p; 691 options[opt_idx].flags |= P_DEF_ALLOCED; 692 } 693 } 694 } 695 696 void 697 set_string_default(char *name, char_u *val) 698 { 699 set_string_default_esc(name, val, FALSE); 700 } 701 702 /* 703 * For an option value that contains comma separated items, find "newval" in 704 * "origval". Return NULL if not found. 705 */ 706 static char_u * 707 find_dup_item(char_u *origval, char_u *newval, long_u flags) 708 { 709 int bs = 0; 710 size_t newlen; 711 char_u *s; 712 713 if (origval == NULL) 714 return NULL; 715 716 newlen = STRLEN(newval); 717 for (s = origval; *s != NUL; ++s) 718 { 719 if ((!(flags & P_COMMA) 720 || s == origval 721 || (s[-1] == ',' && !(bs & 1))) 722 && STRNCMP(s, newval, newlen) == 0 723 && (!(flags & P_COMMA) 724 || s[newlen] == ',' 725 || s[newlen] == NUL)) 726 return s; 727 // Count backslashes. Only a comma with an even number of backslashes 728 // or a single backslash preceded by a comma before it is recognized as 729 // a separator. 730 if ((s > origval + 1 731 && s[-1] == '\\' 732 && s[-2] != ',') 733 || (s == origval + 1 734 && s[-1] == '\\')) 735 ++bs; 736 else 737 bs = 0; 738 } 739 return NULL; 740 } 741 742 /* 743 * Set the Vi-default value of a number option. 744 * Used for 'lines' and 'columns'. 745 */ 746 void 747 set_number_default(char *name, long val) 748 { 749 int opt_idx; 750 751 opt_idx = findoption((char_u *)name); 752 if (opt_idx >= 0) 753 options[opt_idx].def_val[VI_DEFAULT] = (char_u *)(long_i)val; 754 } 755 756 /* 757 * Set all window-local and buffer-local options to the Vim default. 758 * local-global options will use the global value. 759 * When "do_buffer" is FALSE don't set buffer-local options. 760 */ 761 void 762 set_local_options_default(win_T *wp, int do_buffer) 763 { 764 win_T *save_curwin = curwin; 765 int i; 766 767 curwin = wp; 768 curbuf = curwin->w_buffer; 769 block_autocmds(); 770 771 for (i = 0; !istermoption_idx(i); i++) 772 { 773 struct vimoption *p = &(options[i]); 774 char_u *varp = get_varp_scope(p, OPT_LOCAL); 775 776 if (p->indir != PV_NONE 777 && (do_buffer || (p->indir & PV_BUF) == 0) 778 && !(options[i].flags & P_NODEFAULT) 779 && !optval_default(p, varp, FALSE)) 780 set_option_default(i, OPT_FREE|OPT_LOCAL, FALSE); 781 } 782 783 unblock_autocmds(); 784 curwin = save_curwin; 785 curbuf = curwin->w_buffer; 786 } 787 788 #if defined(EXITFREE) || defined(PROTO) 789 /* 790 * Free all options. 791 */ 792 void 793 free_all_options(void) 794 { 795 int i; 796 797 for (i = 0; !istermoption_idx(i); i++) 798 { 799 if (options[i].indir == PV_NONE) 800 { 801 // global option: free value and default value. 802 if ((options[i].flags & P_ALLOCED) && options[i].var != NULL) 803 free_string_option(*(char_u **)options[i].var); 804 if (options[i].flags & P_DEF_ALLOCED) 805 free_string_option(options[i].def_val[VI_DEFAULT]); 806 } 807 else if (options[i].var != VAR_WIN 808 && (options[i].flags & P_STRING)) 809 // buffer-local option: free global value 810 clear_string_option((char_u **)options[i].var); 811 } 812 } 813 #endif 814 815 816 /* 817 * Initialize the options, part two: After getting Rows and Columns and 818 * setting 'term'. 819 */ 820 void 821 set_init_2(void) 822 { 823 int idx; 824 825 /* 826 * 'scroll' defaults to half the window height. The stored default is zero, 827 * which results in the actual value computed from the window height. 828 */ 829 idx = findoption((char_u *)"scroll"); 830 if (idx >= 0 && !(options[idx].flags & P_WAS_SET)) 831 set_option_default(idx, OPT_LOCAL, p_cp); 832 comp_col(); 833 834 /* 835 * 'window' is only for backwards compatibility with Vi. 836 * Default is Rows - 1. 837 */ 838 if (!option_was_set((char_u *)"window")) 839 p_window = Rows - 1; 840 set_number_default("window", Rows - 1); 841 842 // For DOS console the default is always black. 843 #if !((defined(MSWIN)) && !defined(FEAT_GUI)) 844 /* 845 * If 'background' wasn't set by the user, try guessing the value, 846 * depending on the terminal name. Only need to check for terminals 847 * with a dark background, that can handle color. 848 */ 849 idx = findoption((char_u *)"bg"); 850 if (idx >= 0 && !(options[idx].flags & P_WAS_SET) 851 && *term_bg_default() == 'd') 852 { 853 set_string_option_direct(NULL, idx, (char_u *)"dark", OPT_FREE, 0); 854 // don't mark it as set, when starting the GUI it may be 855 // changed again 856 options[idx].flags &= ~P_WAS_SET; 857 } 858 #endif 859 860 #ifdef CURSOR_SHAPE 861 parse_shape_opt(SHAPE_CURSOR); // set cursor shapes from 'guicursor' 862 #endif 863 #ifdef FEAT_MOUSESHAPE 864 parse_shape_opt(SHAPE_MOUSE); // set mouse shapes from 'mouseshape' 865 #endif 866 #ifdef FEAT_PRINTER 867 (void)parse_printoptions(); // parse 'printoptions' default value 868 #endif 869 } 870 871 /* 872 * Initialize the options, part three: After reading the .vimrc 873 */ 874 void 875 set_init_3(void) 876 { 877 #if defined(UNIX) || defined(MSWIN) 878 /* 879 * Set 'shellpipe' and 'shellredir', depending on the 'shell' option. 880 * This is done after other initializations, where 'shell' might have been 881 * set, but only if they have not been set before. 882 */ 883 char_u *p; 884 int idx_srr; 885 int do_srr; 886 # ifdef FEAT_QUICKFIX 887 int idx_sp; 888 int do_sp; 889 # endif 890 891 idx_srr = findoption((char_u *)"srr"); 892 if (idx_srr < 0) 893 do_srr = FALSE; 894 else 895 do_srr = !(options[idx_srr].flags & P_WAS_SET); 896 # ifdef FEAT_QUICKFIX 897 idx_sp = findoption((char_u *)"sp"); 898 if (idx_sp < 0) 899 do_sp = FALSE; 900 else 901 do_sp = !(options[idx_sp].flags & P_WAS_SET); 902 # endif 903 p = get_isolated_shell_name(); 904 if (p != NULL) 905 { 906 /* 907 * Default for p_sp is "| tee", for p_srr is ">". 908 * For known shells it is changed here to include stderr. 909 */ 910 if ( fnamecmp(p, "csh") == 0 911 || fnamecmp(p, "tcsh") == 0 912 # if defined(MSWIN) // also check with .exe extension 913 || fnamecmp(p, "csh.exe") == 0 914 || fnamecmp(p, "tcsh.exe") == 0 915 # endif 916 ) 917 { 918 # if defined(FEAT_QUICKFIX) 919 if (do_sp) 920 { 921 # ifdef MSWIN 922 p_sp = (char_u *)">&"; 923 # else 924 p_sp = (char_u *)"|& tee"; 925 # endif 926 options[idx_sp].def_val[VI_DEFAULT] = p_sp; 927 } 928 # endif 929 if (do_srr) 930 { 931 p_srr = (char_u *)">&"; 932 options[idx_srr].def_val[VI_DEFAULT] = p_srr; 933 } 934 } 935 # ifdef MSWIN 936 // Windows PowerShell output is UTF-16 with BOM so re-encode to the 937 // current codepage. 938 else if ( fnamecmp(p, "powershell") == 0 939 || fnamecmp(p, "powershell.exe") == 0 940 ) 941 { 942 # if defined(FEAT_QUICKFIX) 943 if (do_sp) 944 { 945 p_sp = (char_u *)"2>&1 | Out-File -Encoding default"; 946 options[idx_sp].def_val[VI_DEFAULT] = p_sp; 947 } 948 # endif 949 if (do_srr) 950 { 951 p_srr = (char_u *)"2>&1 | Out-File -Encoding default"; 952 options[idx_srr].def_val[VI_DEFAULT] = p_srr; 953 } 954 } 955 #endif 956 else 957 // Always use POSIX shell style redirection if we reach this 958 if ( fnamecmp(p, "sh") == 0 959 || fnamecmp(p, "ksh") == 0 960 || fnamecmp(p, "mksh") == 0 961 || fnamecmp(p, "pdksh") == 0 962 || fnamecmp(p, "zsh") == 0 963 || fnamecmp(p, "zsh-beta") == 0 964 || fnamecmp(p, "bash") == 0 965 || fnamecmp(p, "fish") == 0 966 || fnamecmp(p, "ash") == 0 967 || fnamecmp(p, "dash") == 0 968 || fnamecmp(p, "pwsh") == 0 969 # ifdef MSWIN 970 || fnamecmp(p, "cmd") == 0 971 || fnamecmp(p, "sh.exe") == 0 972 || fnamecmp(p, "ksh.exe") == 0 973 || fnamecmp(p, "mksh.exe") == 0 974 || fnamecmp(p, "pdksh.exe") == 0 975 || fnamecmp(p, "zsh.exe") == 0 976 || fnamecmp(p, "zsh-beta.exe") == 0 977 || fnamecmp(p, "bash.exe") == 0 978 || fnamecmp(p, "cmd.exe") == 0 979 || fnamecmp(p, "dash.exe") == 0 980 || fnamecmp(p, "pwsh.exe") == 0 981 # endif 982 ) 983 { 984 # if defined(FEAT_QUICKFIX) 985 if (do_sp) 986 { 987 # ifdef MSWIN 988 p_sp = (char_u *)">%s 2>&1"; 989 # else 990 if (fnamecmp(p, "pwsh") == 0) 991 p_sp = (char_u *)">%s 2>&1"; 992 else 993 p_sp = (char_u *)"2>&1| tee"; 994 # endif 995 options[idx_sp].def_val[VI_DEFAULT] = p_sp; 996 } 997 # endif 998 if (do_srr) 999 { 1000 p_srr = (char_u *)">%s 2>&1"; 1001 options[idx_srr].def_val[VI_DEFAULT] = p_srr; 1002 } 1003 } 1004 vim_free(p); 1005 } 1006 #endif 1007 1008 #if defined(MSWIN) 1009 /* 1010 * Set 'shellcmdflag', 'shellxquote', and 'shellquote' depending on the 1011 * 'shell' option. 1012 * This is done after other initializations, where 'shell' might have been 1013 * set, but only if they have not been set before. 1014 * Default values depend on shell (cmd.exe is default shell): 1015 * 1016 * p_shcf p_sxq 1017 * cmd.exe - "/c" "(" 1018 * powershell.exe - "-Command" "\"" 1019 * pwsh.exe - "-c" "\"" 1020 * "sh" like shells - "-c" "\"" 1021 * 1022 * For Win32 p_sxq is set instead of p_shq to include shell redirection. 1023 */ 1024 if (strstr((char *)gettail(p_sh), "powershell") != NULL) 1025 { 1026 int idx_opt; 1027 1028 idx_opt = findoption((char_u *)"shcf"); 1029 if (idx_opt >= 0 && !(options[idx_opt].flags & P_WAS_SET)) 1030 { 1031 p_shcf = (char_u*)"-Command"; 1032 options[idx_opt].def_val[VI_DEFAULT] = p_shcf; 1033 } 1034 1035 idx_opt = findoption((char_u *)"sxq"); 1036 if (idx_opt >= 0 && !(options[idx_opt].flags & P_WAS_SET)) 1037 { 1038 p_sxq = (char_u*)"\""; 1039 options[idx_opt].def_val[VI_DEFAULT] = p_sxq; 1040 } 1041 } 1042 else if (strstr((char *)gettail(p_sh), "sh") != NULL) 1043 { 1044 int idx3; 1045 1046 idx3 = findoption((char_u *)"shcf"); 1047 if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET)) 1048 { 1049 p_shcf = (char_u *)"-c"; 1050 options[idx3].def_val[VI_DEFAULT] = p_shcf; 1051 } 1052 1053 // Somehow Win32 requires the quotes around the redirection too 1054 idx3 = findoption((char_u *)"sxq"); 1055 if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET)) 1056 { 1057 p_sxq = (char_u *)"\""; 1058 options[idx3].def_val[VI_DEFAULT] = p_sxq; 1059 } 1060 } 1061 else if (strstr((char *)gettail(p_sh), "cmd.exe") != NULL) 1062 { 1063 int idx3; 1064 1065 /* 1066 * cmd.exe on Windows will strip the first and last double quote given 1067 * on the command line, e.g. most of the time things like: 1068 * cmd /c "my path/to/echo" "my args to echo" 1069 * become: 1070 * my path/to/echo" "my args to echo 1071 * when executed. 1072 * 1073 * To avoid this, set shellxquote to surround the command in 1074 * parenthesis. This appears to make most commands work, without 1075 * breaking commands that worked previously, such as 1076 * '"path with spaces/cmd" "a&b"'. 1077 */ 1078 idx3 = findoption((char_u *)"sxq"); 1079 if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET)) 1080 { 1081 p_sxq = (char_u *)"("; 1082 options[idx3].def_val[VI_DEFAULT] = p_sxq; 1083 } 1084 1085 idx3 = findoption((char_u *)"shcf"); 1086 if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET)) 1087 { 1088 p_shcf = (char_u *)"/c"; 1089 options[idx3].def_val[VI_DEFAULT] = p_shcf; 1090 } 1091 } 1092 #endif 1093 1094 if (BUFEMPTY()) 1095 { 1096 int idx_ffs = findoption((char_u *)"ffs"); 1097 1098 // Apply the first entry of 'fileformats' to the initial buffer. 1099 if (idx_ffs >= 0 && (options[idx_ffs].flags & P_WAS_SET)) 1100 set_fileformat(default_fileformat(), OPT_LOCAL); 1101 } 1102 1103 #ifdef FEAT_TITLE 1104 set_title_defaults(); 1105 #endif 1106 } 1107 1108 #if defined(FEAT_MULTI_LANG) || defined(PROTO) 1109 /* 1110 * When 'helplang' is still at its default value, set it to "lang". 1111 * Only the first two characters of "lang" are used. 1112 */ 1113 void 1114 set_helplang_default(char_u *lang) 1115 { 1116 int idx; 1117 1118 if (lang == NULL || STRLEN(lang) < 2) // safety check 1119 return; 1120 idx = findoption((char_u *)"hlg"); 1121 if (idx >= 0 && !(options[idx].flags & P_WAS_SET)) 1122 { 1123 if (options[idx].flags & P_ALLOCED) 1124 free_string_option(p_hlg); 1125 p_hlg = vim_strsave(lang); 1126 if (p_hlg == NULL) 1127 p_hlg = empty_option; 1128 else 1129 { 1130 // zh_CN becomes "cn", zh_TW becomes "tw" 1131 if (STRNICMP(p_hlg, "zh_", 3) == 0 && STRLEN(p_hlg) >= 5) 1132 { 1133 p_hlg[0] = TOLOWER_ASC(p_hlg[3]); 1134 p_hlg[1] = TOLOWER_ASC(p_hlg[4]); 1135 } 1136 // any C like setting, such as C.UTF-8, becomes "en" 1137 else if (STRLEN(p_hlg) >= 1 && *p_hlg == 'C') 1138 { 1139 p_hlg[0] = 'e'; 1140 p_hlg[1] = 'n'; 1141 } 1142 p_hlg[2] = NUL; 1143 } 1144 options[idx].flags |= P_ALLOCED; 1145 } 1146 } 1147 #endif 1148 1149 #ifdef FEAT_TITLE 1150 /* 1151 * 'title' and 'icon' only default to true if they have not been set or reset 1152 * in .vimrc and we can read the old value. 1153 * When 'title' and 'icon' have been reset in .vimrc, we won't even check if 1154 * they can be reset. This reduces startup time when using X on a remote 1155 * machine. 1156 */ 1157 void 1158 set_title_defaults(void) 1159 { 1160 int idx1; 1161 long val; 1162 1163 /* 1164 * If GUI is (going to be) used, we can always set the window title and 1165 * icon name. Saves a bit of time, because the X11 display server does 1166 * not need to be contacted. 1167 */ 1168 idx1 = findoption((char_u *)"title"); 1169 if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) 1170 { 1171 #ifdef FEAT_GUI 1172 if (gui.starting || gui.in_use) 1173 val = TRUE; 1174 else 1175 #endif 1176 val = mch_can_restore_title(); 1177 options[idx1].def_val[VI_DEFAULT] = (char_u *)(long_i)val; 1178 p_title = val; 1179 } 1180 idx1 = findoption((char_u *)"icon"); 1181 if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) 1182 { 1183 #ifdef FEAT_GUI 1184 if (gui.starting || gui.in_use) 1185 val = TRUE; 1186 else 1187 #endif 1188 val = mch_can_restore_icon(); 1189 options[idx1].def_val[VI_DEFAULT] = (char_u *)(long_i)val; 1190 p_icon = val; 1191 } 1192 } 1193 #endif 1194 1195 void 1196 ex_set(exarg_T *eap) 1197 { 1198 int flags = 0; 1199 1200 if (eap->cmdidx == CMD_setlocal) 1201 flags = OPT_LOCAL; 1202 else if (eap->cmdidx == CMD_setglobal) 1203 flags = OPT_GLOBAL; 1204 #if defined(FEAT_EVAL) && defined(FEAT_BROWSE) 1205 if ((cmdmod.cmod_flags & CMOD_BROWSE) && flags == 0) 1206 ex_options(eap); 1207 else 1208 #endif 1209 { 1210 if (eap->forceit) 1211 flags |= OPT_ONECOLUMN; 1212 (void)do_set(eap->arg, flags); 1213 } 1214 } 1215 1216 /* 1217 * Parse 'arg' for option settings. 1218 * 1219 * 'arg' may be IObuff, but only when no errors can be present and option 1220 * does not need to be expanded with option_expand(). 1221 * "opt_flags": 1222 * 0 for ":set" 1223 * OPT_GLOBAL for ":setglobal" 1224 * OPT_LOCAL for ":setlocal" and a modeline 1225 * OPT_MODELINE for a modeline 1226 * OPT_WINONLY to only set window-local options 1227 * OPT_NOWIN to skip setting window-local options 1228 * 1229 * returns FAIL if an error is detected, OK otherwise 1230 */ 1231 int 1232 do_set( 1233 char_u *arg_start, // option string (may be written to!) 1234 int opt_flags) 1235 { 1236 char_u *arg = arg_start; 1237 int opt_idx; 1238 char *errmsg; 1239 char errbuf[80]; 1240 char_u *startarg; 1241 int prefix; // 1: nothing, 0: "no", 2: "inv" in front of name 1242 int nextchar; // next non-white char after option name 1243 int afterchar; // character just after option name 1244 int len; 1245 int i; 1246 varnumber_T value; 1247 int key; 1248 long_u flags; // flags for current option 1249 char_u *varp = NULL; // pointer to variable for current option 1250 int did_show = FALSE; // already showed one value 1251 int adding; // "opt+=arg" 1252 int prepending; // "opt^=arg" 1253 int removing; // "opt-=arg" 1254 int cp_val = 0; 1255 char_u key_name[2]; 1256 1257 if (*arg == NUL) 1258 { 1259 showoptions(0, opt_flags); 1260 did_show = TRUE; 1261 goto theend; 1262 } 1263 1264 while (*arg != NUL) // loop to process all options 1265 { 1266 errmsg = NULL; 1267 startarg = arg; // remember for error message 1268 1269 if (STRNCMP(arg, "all", 3) == 0 && !isalpha(arg[3]) 1270 && !(opt_flags & OPT_MODELINE)) 1271 { 1272 /* 1273 * ":set all" show all options. 1274 * ":set all&" set all options to their default value. 1275 */ 1276 arg += 3; 1277 if (*arg == '&') 1278 { 1279 ++arg; 1280 // Only for :set command set global value of local options. 1281 set_options_default(OPT_FREE | opt_flags); 1282 didset_options(); 1283 didset_options2(); 1284 redraw_all_later(CLEAR); 1285 } 1286 else 1287 { 1288 showoptions(1, opt_flags); 1289 did_show = TRUE; 1290 } 1291 } 1292 else if (STRNCMP(arg, "termcap", 7) == 0 && !(opt_flags & OPT_MODELINE)) 1293 { 1294 showoptions(2, opt_flags); 1295 show_termcodes(); 1296 did_show = TRUE; 1297 arg += 7; 1298 } 1299 else 1300 { 1301 prefix = 1; 1302 if (STRNCMP(arg, "no", 2) == 0 && STRNCMP(arg, "novice", 6) != 0) 1303 { 1304 prefix = 0; 1305 arg += 2; 1306 } 1307 else if (STRNCMP(arg, "inv", 3) == 0) 1308 { 1309 prefix = 2; 1310 arg += 3; 1311 } 1312 1313 // find end of name 1314 key = 0; 1315 if (*arg == '<') 1316 { 1317 opt_idx = -1; 1318 // look out for <t_>;> 1319 if (arg[1] == 't' && arg[2] == '_' && arg[3] && arg[4]) 1320 len = 5; 1321 else 1322 { 1323 len = 1; 1324 while (arg[len] != NUL && arg[len] != '>') 1325 ++len; 1326 } 1327 if (arg[len] != '>') 1328 { 1329 errmsg = e_invarg; 1330 goto skip; 1331 } 1332 arg[len] = NUL; // put NUL after name 1333 if (arg[1] == 't' && arg[2] == '_') // could be term code 1334 opt_idx = findoption(arg + 1); 1335 arg[len++] = '>'; // restore '>' 1336 if (opt_idx == -1) 1337 key = find_key_option(arg + 1, TRUE); 1338 } 1339 else 1340 { 1341 len = 0; 1342 /* 1343 * The two characters after "t_" may not be alphanumeric. 1344 */ 1345 if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3]) 1346 len = 4; 1347 else 1348 while (ASCII_ISALNUM(arg[len]) || arg[len] == '_') 1349 ++len; 1350 nextchar = arg[len]; 1351 arg[len] = NUL; // put NUL after name 1352 opt_idx = findoption(arg); 1353 arg[len] = nextchar; // restore nextchar 1354 if (opt_idx == -1) 1355 key = find_key_option(arg, FALSE); 1356 } 1357 1358 // remember character after option name 1359 afterchar = arg[len]; 1360 1361 if (in_vim9script()) 1362 { 1363 char_u *p = skipwhite(arg + len); 1364 1365 // disallow white space before =val, +=val, -=val, ^=val 1366 if (p > arg + len && (p[0] == '=' 1367 || (vim_strchr((char_u *)"+-^", p[0]) != NULL 1368 && p[1] == '='))) 1369 { 1370 errmsg = e_no_white_space_allowed_between_option_and; 1371 arg = p; 1372 startarg = p; 1373 goto skip; 1374 } 1375 } 1376 else 1377 // skip white space, allow ":set ai ?", ":set hlsearch !" 1378 while (VIM_ISWHITE(arg[len])) 1379 ++len; 1380 1381 adding = FALSE; 1382 prepending = FALSE; 1383 removing = FALSE; 1384 if (arg[len] != NUL && arg[len + 1] == '=') 1385 { 1386 if (arg[len] == '+') 1387 { 1388 adding = TRUE; // "+=" 1389 ++len; 1390 } 1391 else if (arg[len] == '^') 1392 { 1393 prepending = TRUE; // "^=" 1394 ++len; 1395 } 1396 else if (arg[len] == '-') 1397 { 1398 removing = TRUE; // "-=" 1399 ++len; 1400 } 1401 } 1402 nextchar = arg[len]; 1403 1404 if (opt_idx == -1 && key == 0) // found a mismatch: skip 1405 { 1406 if (in_vim9script() && arg > arg_start 1407 && vim_strchr((char_u *)"!&<", *arg) != NULL) 1408 errmsg = e_no_white_space_allowed_between_option_and; 1409 else 1410 errmsg = N_("E518: Unknown option"); 1411 goto skip; 1412 } 1413 1414 if (opt_idx >= 0) 1415 { 1416 if (options[opt_idx].var == NULL) // hidden option: skip 1417 { 1418 // Only give an error message when requesting the value of 1419 // a hidden option, ignore setting it. 1420 if (vim_strchr((char_u *)"=:!&<", nextchar) == NULL 1421 && (!(options[opt_idx].flags & P_BOOL) 1422 || nextchar == '?')) 1423 errmsg = N_("E519: Option not supported"); 1424 goto skip; 1425 } 1426 1427 flags = options[opt_idx].flags; 1428 varp = get_varp_scope(&(options[opt_idx]), opt_flags); 1429 } 1430 else 1431 { 1432 flags = P_STRING; 1433 if (key < 0) 1434 { 1435 key_name[0] = KEY2TERMCAP0(key); 1436 key_name[1] = KEY2TERMCAP1(key); 1437 } 1438 else 1439 { 1440 key_name[0] = KS_KEY; 1441 key_name[1] = (key & 0xff); 1442 } 1443 } 1444 1445 // Skip all options that are not window-local (used when showing 1446 // an already loaded buffer in a window). 1447 if ((opt_flags & OPT_WINONLY) 1448 && (opt_idx < 0 || options[opt_idx].var != VAR_WIN)) 1449 goto skip; 1450 1451 // Skip all options that are window-local (used for :vimgrep). 1452 if ((opt_flags & OPT_NOWIN) && opt_idx >= 0 1453 && options[opt_idx].var == VAR_WIN) 1454 goto skip; 1455 1456 // Disallow changing some options from modelines. 1457 if (opt_flags & OPT_MODELINE) 1458 { 1459 if (flags & (P_SECURE | P_NO_ML)) 1460 { 1461 errmsg = N_("E520: Not allowed in a modeline"); 1462 goto skip; 1463 } 1464 if ((flags & P_MLE) && !p_mle) 1465 { 1466 errmsg = N_("E992: Not allowed in a modeline when 'modelineexpr' is off"); 1467 goto skip; 1468 } 1469 #ifdef FEAT_DIFF 1470 // In diff mode some options are overruled. This avoids that 1471 // 'foldmethod' becomes "marker" instead of "diff" and that 1472 // "wrap" gets set. 1473 if (curwin->w_p_diff 1474 && opt_idx >= 0 // shut up coverity warning 1475 && ( 1476 #ifdef FEAT_FOLDING 1477 options[opt_idx].indir == PV_FDM || 1478 #endif 1479 options[opt_idx].indir == PV_WRAP)) 1480 goto skip; 1481 #endif 1482 } 1483 1484 #ifdef HAVE_SANDBOX 1485 // Disallow changing some options in the sandbox 1486 if (sandbox != 0 && (flags & P_SECURE)) 1487 { 1488 errmsg = e_not_allowed_in_sandbox; 1489 goto skip; 1490 } 1491 #endif 1492 1493 if (vim_strchr((char_u *)"?=:!&<", nextchar) != NULL) 1494 { 1495 arg += len; 1496 cp_val = p_cp; 1497 if (nextchar == '&' && arg[1] == 'v' && arg[2] == 'i') 1498 { 1499 if (arg[3] == 'm') // "opt&vim": set to Vim default 1500 { 1501 cp_val = FALSE; 1502 arg += 3; 1503 } 1504 else // "opt&vi": set to Vi default 1505 { 1506 cp_val = TRUE; 1507 arg += 2; 1508 } 1509 } 1510 if (vim_strchr((char_u *)"?!&<", nextchar) != NULL 1511 && arg[1] != NUL && !VIM_ISWHITE(arg[1])) 1512 { 1513 errmsg = e_trailing; 1514 goto skip; 1515 } 1516 } 1517 1518 /* 1519 * allow '=' and ':' for historical reasons (MSDOS command.com 1520 * allows only one '=' character per "set" command line. grrr. (jw) 1521 */ 1522 if (nextchar == '?' 1523 || (prefix == 1 1524 && vim_strchr((char_u *)"=:&<", nextchar) == NULL 1525 && !(flags & P_BOOL))) 1526 { 1527 /* 1528 * print value 1529 */ 1530 if (did_show) 1531 msg_putchar('\n'); // cursor below last one 1532 else 1533 { 1534 gotocmdline(TRUE); // cursor at status line 1535 did_show = TRUE; // remember that we did a line 1536 } 1537 if (opt_idx >= 0) 1538 { 1539 showoneopt(&options[opt_idx], opt_flags); 1540 #ifdef FEAT_EVAL 1541 if (p_verbose > 0) 1542 { 1543 // Mention where the option was last set. 1544 if (varp == options[opt_idx].var) 1545 last_set_msg(options[opt_idx].script_ctx); 1546 else if ((int)options[opt_idx].indir & PV_WIN) 1547 last_set_msg(curwin->w_p_script_ctx[ 1548 (int)options[opt_idx].indir & PV_MASK]); 1549 else if ((int)options[opt_idx].indir & PV_BUF) 1550 last_set_msg(curbuf->b_p_script_ctx[ 1551 (int)options[opt_idx].indir & PV_MASK]); 1552 } 1553 #endif 1554 } 1555 else 1556 { 1557 char_u *p; 1558 1559 p = find_termcode(key_name); 1560 if (p == NULL) 1561 { 1562 errmsg = N_("E846: Key code not set"); 1563 goto skip; 1564 } 1565 else 1566 (void)show_one_termcode(key_name, p, TRUE); 1567 } 1568 if (nextchar != '?' 1569 && nextchar != NUL && !VIM_ISWHITE(afterchar)) 1570 errmsg = e_trailing; 1571 } 1572 else 1573 { 1574 int value_is_replaced = !prepending && !adding && !removing; 1575 int value_checked = FALSE; 1576 1577 if (flags & P_BOOL) // boolean 1578 { 1579 if (nextchar == '=' || nextchar == ':') 1580 { 1581 errmsg = e_invarg; 1582 goto skip; 1583 } 1584 1585 /* 1586 * ":set opt!": invert 1587 * ":set opt&": reset to default value 1588 * ":set opt<": reset to global value 1589 */ 1590 if (nextchar == '!') 1591 value = *(int *)(varp) ^ 1; 1592 else if (nextchar == '&') 1593 value = (int)(long)(long_i)options[opt_idx].def_val[ 1594 ((flags & P_VI_DEF) || cp_val) 1595 ? VI_DEFAULT : VIM_DEFAULT]; 1596 else if (nextchar == '<') 1597 { 1598 // For 'autoread' -1 means to use global value. 1599 if ((int *)varp == &curbuf->b_p_ar 1600 && opt_flags == OPT_LOCAL) 1601 value = -1; 1602 else 1603 value = *(int *)get_varp_scope(&(options[opt_idx]), 1604 OPT_GLOBAL); 1605 } 1606 else 1607 { 1608 /* 1609 * ":set invopt": invert 1610 * ":set opt" or ":set noopt": set or reset 1611 */ 1612 if (nextchar != NUL && !VIM_ISWHITE(afterchar)) 1613 { 1614 errmsg = e_trailing; 1615 goto skip; 1616 } 1617 if (prefix == 2) // inv 1618 value = *(int *)(varp) ^ 1; 1619 else 1620 value = prefix; 1621 } 1622 1623 errmsg = set_bool_option(opt_idx, varp, (int)value, 1624 opt_flags); 1625 } 1626 else // numeric or string 1627 { 1628 if (vim_strchr((char_u *)"=:&<", nextchar) == NULL 1629 || prefix != 1) 1630 { 1631 errmsg = e_invarg; 1632 goto skip; 1633 } 1634 1635 if (flags & P_NUM) // numeric 1636 { 1637 /* 1638 * Different ways to set a number option: 1639 * & set to default value 1640 * < set to global value 1641 * <xx> accept special key codes for 'wildchar' 1642 * c accept any non-digit for 'wildchar' 1643 * [-]0-9 set number 1644 * other error 1645 */ 1646 ++arg; 1647 if (nextchar == '&') 1648 value = (long)(long_i)options[opt_idx].def_val[ 1649 ((flags & P_VI_DEF) || cp_val) 1650 ? VI_DEFAULT : VIM_DEFAULT]; 1651 else if (nextchar == '<') 1652 { 1653 // For 'undolevels' NO_LOCAL_UNDOLEVEL means to 1654 // use the global value. 1655 if ((long *)varp == &curbuf->b_p_ul 1656 && opt_flags == OPT_LOCAL) 1657 value = NO_LOCAL_UNDOLEVEL; 1658 else 1659 value = *(long *)get_varp_scope( 1660 &(options[opt_idx]), OPT_GLOBAL); 1661 } 1662 else if (((long *)varp == &p_wc 1663 || (long *)varp == &p_wcm) 1664 && (*arg == '<' 1665 || *arg == '^' 1666 || (*arg != NUL 1667 && (!arg[1] || VIM_ISWHITE(arg[1])) 1668 && !VIM_ISDIGIT(*arg)))) 1669 { 1670 value = string_to_key(arg, FALSE); 1671 if (value == 0 && (long *)varp != &p_wcm) 1672 { 1673 errmsg = e_invarg; 1674 goto skip; 1675 } 1676 } 1677 else if (*arg == '-' || VIM_ISDIGIT(*arg)) 1678 { 1679 // Allow negative (for 'undolevels'), octal and 1680 // hex numbers. 1681 vim_str2nr(arg, NULL, &i, STR2NR_ALL, 1682 &value, NULL, 0, TRUE); 1683 if (i == 0 || (arg[i] != NUL 1684 && !VIM_ISWHITE(arg[i]))) 1685 { 1686 errmsg = N_("E521: Number required after ="); 1687 goto skip; 1688 } 1689 } 1690 else 1691 { 1692 errmsg = N_("E521: Number required after ="); 1693 goto skip; 1694 } 1695 1696 if (adding) 1697 value = *(long *)varp + value; 1698 if (prepending) 1699 value = *(long *)varp * value; 1700 if (removing) 1701 value = *(long *)varp - value; 1702 errmsg = set_num_option(opt_idx, varp, value, 1703 errbuf, sizeof(errbuf), opt_flags); 1704 } 1705 else if (opt_idx >= 0) // string 1706 { 1707 char_u *save_arg = NULL; 1708 char_u *s = NULL; 1709 char_u *oldval = NULL; // previous value if *varp 1710 char_u *newval; 1711 char_u *origval = NULL; 1712 char_u *origval_l = NULL; 1713 char_u *origval_g = NULL; 1714 #if defined(FEAT_EVAL) 1715 char_u *saved_origval = NULL; 1716 char_u *saved_origval_l = NULL; 1717 char_u *saved_origval_g = NULL; 1718 char_u *saved_newval = NULL; 1719 #endif 1720 unsigned newlen; 1721 int comma; 1722 int new_value_alloced; // new string option 1723 // was allocated 1724 1725 // When using ":set opt=val" for a global option 1726 // with a local value the local value will be 1727 // reset, use the global value here. 1728 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0 1729 && ((int)options[opt_idx].indir & PV_BOTH)) 1730 varp = options[opt_idx].var; 1731 1732 // The old value is kept until we are sure that the 1733 // new value is valid. 1734 oldval = *(char_u **)varp; 1735 1736 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) 1737 { 1738 origval_l = *(char_u **)get_varp_scope( 1739 &(options[opt_idx]), OPT_LOCAL); 1740 origval_g = *(char_u **)get_varp_scope( 1741 &(options[opt_idx]), OPT_GLOBAL); 1742 1743 // A global-local string option might have an empty 1744 // option as value to indicate that the global 1745 // value should be used. 1746 if (((int)options[opt_idx].indir & PV_BOTH) 1747 && origval_l == empty_option) 1748 origval_l = origval_g; 1749 } 1750 1751 // When setting the local value of a global 1752 // option, the old value may be the global value. 1753 if (((int)options[opt_idx].indir & PV_BOTH) 1754 && (opt_flags & OPT_LOCAL)) 1755 origval = *(char_u **)get_varp( 1756 &options[opt_idx]); 1757 else 1758 origval = oldval; 1759 1760 if (nextchar == '&') // set to default val 1761 { 1762 newval = options[opt_idx].def_val[ 1763 ((flags & P_VI_DEF) || cp_val) 1764 ? VI_DEFAULT : VIM_DEFAULT]; 1765 if ((char_u **)varp == &p_bg) 1766 { 1767 // guess the value of 'background' 1768 #ifdef FEAT_GUI 1769 if (gui.in_use) 1770 newval = gui_bg_default(); 1771 else 1772 #endif 1773 newval = term_bg_default(); 1774 } 1775 else if ((char_u **)varp == &p_fencs && enc_utf8) 1776 newval = fencs_utf8_default; 1777 1778 // expand environment variables and ~ (since the 1779 // default value was already expanded, only 1780 // required when an environment variable was set 1781 // later 1782 if (newval == NULL) 1783 newval = empty_option; 1784 else 1785 { 1786 s = option_expand(opt_idx, newval); 1787 if (s == NULL) 1788 s = newval; 1789 newval = vim_strsave(s); 1790 } 1791 new_value_alloced = TRUE; 1792 } 1793 else if (nextchar == '<') // set to global val 1794 { 1795 newval = vim_strsave(*(char_u **)get_varp_scope( 1796 &(options[opt_idx]), OPT_GLOBAL)); 1797 new_value_alloced = TRUE; 1798 } 1799 else 1800 { 1801 ++arg; // jump to after the '=' or ':' 1802 1803 /* 1804 * Set 'keywordprg' to ":help" if an empty 1805 * value was passed to :set by the user. 1806 * Misuse errbuf[] for the resulting string. 1807 */ 1808 if (varp == (char_u *)&p_kp 1809 && (*arg == NUL || *arg == ' ')) 1810 { 1811 STRCPY(errbuf, ":help"); 1812 save_arg = arg; 1813 arg = (char_u *)errbuf; 1814 } 1815 /* 1816 * Convert 'backspace' number to string, for 1817 * adding, prepending and removing string. 1818 */ 1819 else if (varp == (char_u *)&p_bs 1820 && VIM_ISDIGIT(**(char_u **)varp)) 1821 { 1822 i = getdigits((char_u **)varp); 1823 switch (i) 1824 { 1825 case 0: 1826 *(char_u **)varp = empty_option; 1827 break; 1828 case 1: 1829 *(char_u **)varp = vim_strsave( 1830 (char_u *)"indent,eol"); 1831 break; 1832 case 2: 1833 *(char_u **)varp = vim_strsave( 1834 (char_u *)"indent,eol,start"); 1835 break; 1836 case 3: 1837 *(char_u **)varp = vim_strsave( 1838 (char_u *)"indent,eol,nostop"); 1839 break; 1840 } 1841 vim_free(oldval); 1842 if (origval == oldval) 1843 origval = *(char_u **)varp; 1844 if (origval_l == oldval) 1845 origval_l = *(char_u **)varp; 1846 if (origval_g == oldval) 1847 origval_g = *(char_u **)varp; 1848 oldval = *(char_u **)varp; 1849 } 1850 /* 1851 * Convert 'whichwrap' number to string, for 1852 * backwards compatibility with Vim 3.0. 1853 * Misuse errbuf[] for the resulting string. 1854 */ 1855 else if (varp == (char_u *)&p_ww 1856 && VIM_ISDIGIT(*arg)) 1857 { 1858 *errbuf = NUL; 1859 i = getdigits(&arg); 1860 if (i & 1) 1861 STRCAT(errbuf, "b,"); 1862 if (i & 2) 1863 STRCAT(errbuf, "s,"); 1864 if (i & 4) 1865 STRCAT(errbuf, "h,l,"); 1866 if (i & 8) 1867 STRCAT(errbuf, "<,>,"); 1868 if (i & 16) 1869 STRCAT(errbuf, "[,],"); 1870 if (*errbuf != NUL) // remove trailing , 1871 errbuf[STRLEN(errbuf) - 1] = NUL; 1872 save_arg = arg; 1873 arg = (char_u *)errbuf; 1874 } 1875 /* 1876 * Remove '>' before 'dir' and 'bdir', for 1877 * backwards compatibility with version 3.0 1878 */ 1879 else if ( *arg == '>' 1880 && (varp == (char_u *)&p_dir 1881 || varp == (char_u *)&p_bdir)) 1882 { 1883 ++arg; 1884 } 1885 1886 /* 1887 * Copy the new string into allocated memory. 1888 * Can't use set_string_option_direct(), because 1889 * we need to remove the backslashes. 1890 */ 1891 // get a bit too much 1892 newlen = (unsigned)STRLEN(arg) + 1; 1893 if (adding || prepending || removing) 1894 newlen += (unsigned)STRLEN(origval) + 1; 1895 newval = alloc(newlen); 1896 if (newval == NULL) // out of mem, don't change 1897 break; 1898 s = newval; 1899 1900 /* 1901 * Copy the string, skip over escaped chars. 1902 * For MS-DOS and WIN32 backslashes before normal 1903 * file name characters are not removed, and keep 1904 * backslash at start, for "\\machine\path", but 1905 * do remove it for "\\\\machine\\path". 1906 * The reverse is found in ExpandOldSetting(). 1907 */ 1908 while (*arg && !VIM_ISWHITE(*arg)) 1909 { 1910 if (*arg == '\\' && arg[1] != NUL 1911 #ifdef BACKSLASH_IN_FILENAME 1912 && !((flags & P_EXPAND) 1913 && vim_isfilec(arg[1]) 1914 && !VIM_ISWHITE(arg[1]) 1915 && (arg[1] != '\\' 1916 || (s == newval 1917 && arg[2] != '\\'))) 1918 #endif 1919 ) 1920 ++arg; // remove backslash 1921 if (has_mbyte 1922 && (i = (*mb_ptr2len)(arg)) > 1) 1923 { 1924 // copy multibyte char 1925 mch_memmove(s, arg, (size_t)i); 1926 arg += i; 1927 s += i; 1928 } 1929 else 1930 *s++ = *arg++; 1931 } 1932 *s = NUL; 1933 1934 /* 1935 * Expand environment variables and ~. 1936 * Don't do it when adding without inserting a 1937 * comma. 1938 */ 1939 if (!(adding || prepending || removing) 1940 || (flags & P_COMMA)) 1941 { 1942 s = option_expand(opt_idx, newval); 1943 if (s != NULL) 1944 { 1945 vim_free(newval); 1946 newlen = (unsigned)STRLEN(s) + 1; 1947 if (adding || prepending || removing) 1948 newlen += (unsigned)STRLEN(origval) + 1; 1949 newval = alloc(newlen); 1950 if (newval == NULL) 1951 break; 1952 STRCPY(newval, s); 1953 } 1954 } 1955 1956 // locate newval[] in origval[] when removing it 1957 // and when adding to avoid duplicates 1958 i = 0; // init for GCC 1959 if (removing || (flags & P_NODUP)) 1960 { 1961 i = (int)STRLEN(newval); 1962 s = find_dup_item(origval, newval, flags); 1963 1964 // do not add if already there 1965 if ((adding || prepending) && s != NULL) 1966 { 1967 prepending = FALSE; 1968 adding = FALSE; 1969 STRCPY(newval, origval); 1970 } 1971 1972 // if no duplicate, move pointer to end of 1973 // original value 1974 if (s == NULL) 1975 s = origval + (int)STRLEN(origval); 1976 } 1977 1978 // concatenate the two strings; add a ',' if 1979 // needed 1980 if (adding || prepending) 1981 { 1982 comma = ((flags & P_COMMA) && *origval != NUL 1983 && *newval != NUL); 1984 if (adding) 1985 { 1986 i = (int)STRLEN(origval); 1987 // strip a trailing comma, would get 2 1988 if (comma && i > 1 1989 && (flags & P_ONECOMMA) == P_ONECOMMA 1990 && origval[i - 1] == ',' 1991 && origval[i - 2] != '\\') 1992 i--; 1993 mch_memmove(newval + i + comma, newval, 1994 STRLEN(newval) + 1); 1995 mch_memmove(newval, origval, (size_t)i); 1996 } 1997 else 1998 { 1999 i = (int)STRLEN(newval); 2000 STRMOVE(newval + i + comma, origval); 2001 } 2002 if (comma) 2003 newval[i] = ','; 2004 } 2005 2006 // Remove newval[] from origval[]. (Note: "i" has 2007 // been set above and is used here). 2008 if (removing) 2009 { 2010 STRCPY(newval, origval); 2011 if (*s) 2012 { 2013 // may need to remove a comma 2014 if (flags & P_COMMA) 2015 { 2016 if (s == origval) 2017 { 2018 // include comma after string 2019 if (s[i] == ',') 2020 ++i; 2021 } 2022 else 2023 { 2024 // include comma before string 2025 --s; 2026 ++i; 2027 } 2028 } 2029 STRMOVE(newval + (s - origval), s + i); 2030 } 2031 } 2032 2033 if (flags & P_FLAGLIST) 2034 { 2035 // Remove flags that appear twice. 2036 for (s = newval; *s;) 2037 { 2038 // if options have P_FLAGLIST and 2039 // P_ONECOMMA such as 'whichwrap' 2040 if (flags & P_ONECOMMA) 2041 { 2042 if (*s != ',' && *(s + 1) == ',' 2043 && vim_strchr(s + 2, *s) != NULL) 2044 { 2045 // Remove the duplicated value and 2046 // the next comma. 2047 STRMOVE(s, s + 2); 2048 continue; 2049 } 2050 } 2051 else 2052 { 2053 if ((!(flags & P_COMMA) || *s != ',') 2054 && vim_strchr(s + 1, *s) != NULL) 2055 { 2056 STRMOVE(s, s + 1); 2057 continue; 2058 } 2059 } 2060 ++s; 2061 } 2062 } 2063 2064 if (save_arg != NULL) // number for 'whichwrap' 2065 arg = save_arg; 2066 new_value_alloced = TRUE; 2067 } 2068 2069 /* 2070 * Set the new value. 2071 */ 2072 *(char_u **)(varp) = newval; 2073 2074 #if defined(FEAT_EVAL) 2075 if (!starting 2076 # ifdef FEAT_CRYPT 2077 && options[opt_idx].indir != PV_KEY 2078 # endif 2079 && origval != NULL && newval != NULL) 2080 { 2081 // origval may be freed by 2082 // did_set_string_option(), make a copy. 2083 saved_origval = vim_strsave(origval); 2084 // newval (and varp) may become invalid if the 2085 // buffer is closed by autocommands. 2086 saved_newval = vim_strsave(newval); 2087 if (origval_l != NULL) 2088 saved_origval_l = vim_strsave(origval_l); 2089 if (origval_g != NULL) 2090 saved_origval_g = vim_strsave(origval_g); 2091 } 2092 #endif 2093 2094 { 2095 long_u *p = insecure_flag(opt_idx, opt_flags); 2096 int secure_saved = secure; 2097 2098 // When an option is set in the sandbox, from a 2099 // modeline or in secure mode, then deal with side 2100 // effects in secure mode. Also when the value was 2101 // set with the P_INSECURE flag and is not 2102 // completely replaced. 2103 if ((opt_flags & OPT_MODELINE) 2104 #ifdef HAVE_SANDBOX 2105 || sandbox != 0 2106 #endif 2107 || (!value_is_replaced && (*p & P_INSECURE))) 2108 secure = 1; 2109 2110 // Handle side effects, and set the global value 2111 // for ":set" on local options. Note: when setting 2112 // 'syntax' or 'filetype' autocommands may be 2113 // triggered that can cause havoc. 2114 errmsg = did_set_string_option( 2115 opt_idx, (char_u **)varp, 2116 new_value_alloced, oldval, errbuf, 2117 opt_flags, &value_checked); 2118 2119 secure = secure_saved; 2120 } 2121 2122 #if defined(FEAT_EVAL) 2123 if (errmsg == NULL) 2124 trigger_optionsset_string( 2125 opt_idx, opt_flags, saved_origval, 2126 saved_origval_l, saved_origval_g, 2127 saved_newval); 2128 vim_free(saved_origval); 2129 vim_free(saved_origval_l); 2130 vim_free(saved_origval_g); 2131 vim_free(saved_newval); 2132 #endif 2133 // If error detected, print the error message. 2134 if (errmsg != NULL) 2135 goto skip; 2136 } 2137 else // key code option 2138 { 2139 char_u *p; 2140 2141 if (nextchar == '&') 2142 { 2143 if (add_termcap_entry(key_name, TRUE) == FAIL) 2144 errmsg = N_("E522: Not found in termcap"); 2145 } 2146 else 2147 { 2148 ++arg; // jump to after the '=' or ':' 2149 for (p = arg; *p && !VIM_ISWHITE(*p); ++p) 2150 if (*p == '\\' && p[1] != NUL) 2151 ++p; 2152 nextchar = *p; 2153 *p = NUL; 2154 add_termcode(key_name, arg, FALSE); 2155 *p = nextchar; 2156 } 2157 if (full_screen) 2158 ttest(FALSE); 2159 redraw_all_later(CLEAR); 2160 } 2161 } 2162 2163 if (opt_idx >= 0) 2164 did_set_option( 2165 opt_idx, opt_flags, value_is_replaced, value_checked); 2166 } 2167 2168 skip: 2169 /* 2170 * Advance to next argument. 2171 * - skip until a blank found, taking care of backslashes 2172 * - skip blanks 2173 * - skip one "=val" argument (for hidden options ":set gfn =xx") 2174 */ 2175 for (i = 0; i < 2 ; ++i) 2176 { 2177 while (*arg != NUL && !VIM_ISWHITE(*arg)) 2178 if (*arg++ == '\\' && *arg != NUL) 2179 ++arg; 2180 arg = skipwhite(arg); 2181 if (*arg != '=') 2182 break; 2183 } 2184 } 2185 2186 if (errmsg != NULL) 2187 { 2188 vim_strncpy(IObuff, (char_u *)_(errmsg), IOSIZE - 1); 2189 i = (int)STRLEN(IObuff) + 2; 2190 if (i + (arg - startarg) < IOSIZE) 2191 { 2192 // append the argument with the error 2193 STRCAT(IObuff, ": "); 2194 mch_memmove(IObuff + i, startarg, (arg - startarg)); 2195 IObuff[i + (arg - startarg)] = NUL; 2196 } 2197 // make sure all characters are printable 2198 trans_characters(IObuff, IOSIZE); 2199 2200 ++no_wait_return; // wait_return done later 2201 emsg((char *)IObuff); // show error highlighted 2202 --no_wait_return; 2203 2204 return FAIL; 2205 } 2206 2207 arg = skipwhite(arg); 2208 } 2209 2210 theend: 2211 if (silent_mode && did_show) 2212 { 2213 // After displaying option values in silent mode. 2214 silent_mode = FALSE; 2215 info_message = TRUE; // use mch_msg(), not mch_errmsg() 2216 msg_putchar('\n'); 2217 cursor_on(); // msg_start() switches it off 2218 out_flush(); 2219 silent_mode = TRUE; 2220 info_message = FALSE; // use mch_msg(), not mch_errmsg() 2221 } 2222 2223 return OK; 2224 } 2225 2226 /* 2227 * Call this when an option has been given a new value through a user command. 2228 * Sets the P_WAS_SET flag and takes care of the P_INSECURE flag. 2229 */ 2230 void 2231 did_set_option( 2232 int opt_idx, 2233 int opt_flags, // possibly with OPT_MODELINE 2234 int new_value, // value was replaced completely 2235 int value_checked) // value was checked to be safe, no need to set the 2236 // P_INSECURE flag. 2237 { 2238 long_u *p; 2239 2240 options[opt_idx].flags |= P_WAS_SET; 2241 2242 // When an option is set in the sandbox, from a modeline or in secure mode 2243 // set the P_INSECURE flag. Otherwise, if a new value is stored reset the 2244 // flag. 2245 p = insecure_flag(opt_idx, opt_flags); 2246 if (!value_checked && (secure 2247 #ifdef HAVE_SANDBOX 2248 || sandbox != 0 2249 #endif 2250 || (opt_flags & OPT_MODELINE))) 2251 *p = *p | P_INSECURE; 2252 else if (new_value) 2253 *p = *p & ~P_INSECURE; 2254 } 2255 2256 /* 2257 * Convert a key name or string into a key value. 2258 * Used for 'wildchar' and 'cedit' options. 2259 * When "multi_byte" is TRUE allow for multi-byte characters. 2260 */ 2261 int 2262 string_to_key(char_u *arg, int multi_byte) 2263 { 2264 if (*arg == '<') 2265 return find_key_option(arg + 1, TRUE); 2266 if (*arg == '^') 2267 return Ctrl_chr(arg[1]); 2268 if (multi_byte) 2269 return PTR2CHAR(arg); 2270 return *arg; 2271 } 2272 2273 #ifdef FEAT_TITLE 2274 /* 2275 * When changing 'title', 'titlestring', 'icon' or 'iconstring', call 2276 * maketitle() to create and display it. 2277 * When switching the title or icon off, call mch_restore_title() to get 2278 * the old value back. 2279 */ 2280 void 2281 did_set_title(void) 2282 { 2283 if (starting != NO_SCREEN 2284 #ifdef FEAT_GUI 2285 && !gui.starting 2286 #endif 2287 ) 2288 maketitle(); 2289 } 2290 #endif 2291 2292 /* 2293 * set_options_bin - called when 'bin' changes value. 2294 */ 2295 void 2296 set_options_bin( 2297 int oldval, 2298 int newval, 2299 int opt_flags) // OPT_LOCAL and/or OPT_GLOBAL 2300 { 2301 /* 2302 * The option values that are changed when 'bin' changes are 2303 * copied when 'bin is set and restored when 'bin' is reset. 2304 */ 2305 if (newval) 2306 { 2307 if (!oldval) // switched on 2308 { 2309 if (!(opt_flags & OPT_GLOBAL)) 2310 { 2311 curbuf->b_p_tw_nobin = curbuf->b_p_tw; 2312 curbuf->b_p_wm_nobin = curbuf->b_p_wm; 2313 curbuf->b_p_ml_nobin = curbuf->b_p_ml; 2314 curbuf->b_p_et_nobin = curbuf->b_p_et; 2315 } 2316 if (!(opt_flags & OPT_LOCAL)) 2317 { 2318 p_tw_nobin = p_tw; 2319 p_wm_nobin = p_wm; 2320 p_ml_nobin = p_ml; 2321 p_et_nobin = p_et; 2322 } 2323 } 2324 2325 if (!(opt_flags & OPT_GLOBAL)) 2326 { 2327 curbuf->b_p_tw = 0; // no automatic line wrap 2328 curbuf->b_p_wm = 0; // no automatic line wrap 2329 curbuf->b_p_ml = 0; // no modelines 2330 curbuf->b_p_et = 0; // no expandtab 2331 } 2332 if (!(opt_flags & OPT_LOCAL)) 2333 { 2334 p_tw = 0; 2335 p_wm = 0; 2336 p_ml = FALSE; 2337 p_et = FALSE; 2338 p_bin = TRUE; // needed when called for the "-b" argument 2339 } 2340 } 2341 else if (oldval) // switched off 2342 { 2343 if (!(opt_flags & OPT_GLOBAL)) 2344 { 2345 curbuf->b_p_tw = curbuf->b_p_tw_nobin; 2346 curbuf->b_p_wm = curbuf->b_p_wm_nobin; 2347 curbuf->b_p_ml = curbuf->b_p_ml_nobin; 2348 curbuf->b_p_et = curbuf->b_p_et_nobin; 2349 } 2350 if (!(opt_flags & OPT_LOCAL)) 2351 { 2352 p_tw = p_tw_nobin; 2353 p_wm = p_wm_nobin; 2354 p_ml = p_ml_nobin; 2355 p_et = p_et_nobin; 2356 } 2357 } 2358 } 2359 2360 /* 2361 * Expand environment variables for some string options. 2362 * These string options cannot be indirect! 2363 * If "val" is NULL expand the current value of the option. 2364 * Return pointer to NameBuff, or NULL when not expanded. 2365 */ 2366 static char_u * 2367 option_expand(int opt_idx, char_u *val) 2368 { 2369 // if option doesn't need expansion nothing to do 2370 if (!(options[opt_idx].flags & P_EXPAND) || options[opt_idx].var == NULL) 2371 return NULL; 2372 2373 // If val is longer than MAXPATHL no meaningful expansion can be done, 2374 // expand_env() would truncate the string. 2375 if (val != NULL && STRLEN(val) > MAXPATHL) 2376 return NULL; 2377 2378 if (val == NULL) 2379 val = *(char_u **)options[opt_idx].var; 2380 2381 /* 2382 * Expanding this with NameBuff, expand_env() must not be passed IObuff. 2383 * Escape spaces when expanding 'tags', they are used to separate file 2384 * names. 2385 * For 'spellsuggest' expand after "file:". 2386 */ 2387 expand_env_esc(val, NameBuff, MAXPATHL, 2388 (char_u **)options[opt_idx].var == &p_tags, FALSE, 2389 #ifdef FEAT_SPELL 2390 (char_u **)options[opt_idx].var == &p_sps ? (char_u *)"file:" : 2391 #endif 2392 NULL); 2393 if (STRCMP(NameBuff, val) == 0) // they are the same 2394 return NULL; 2395 2396 return NameBuff; 2397 } 2398 2399 /* 2400 * After setting various option values: recompute variables that depend on 2401 * option values. 2402 */ 2403 static void 2404 didset_options(void) 2405 { 2406 // initialize the table for 'iskeyword' et.al. 2407 (void)init_chartab(); 2408 2409 didset_string_options(); 2410 2411 #ifdef FEAT_SPELL 2412 (void)spell_check_msm(); 2413 (void)spell_check_sps(); 2414 (void)compile_cap_prog(curwin->w_s); 2415 (void)did_set_spell_option(TRUE); 2416 #endif 2417 #ifdef FEAT_CMDWIN 2418 // set cedit_key 2419 (void)check_cedit(); 2420 #endif 2421 #ifdef FEAT_LINEBREAK 2422 // initialize the table for 'breakat'. 2423 fill_breakat_flags(); 2424 #endif 2425 after_copy_winopt(curwin); 2426 } 2427 2428 /* 2429 * More side effects of setting options. 2430 */ 2431 static void 2432 didset_options2(void) 2433 { 2434 // Initialize the highlight_attr[] table. 2435 (void)highlight_changed(); 2436 2437 // Parse default for 'wildmode' 2438 check_opt_wim(); 2439 2440 // Parse default for 'listchars'. 2441 (void)set_chars_option(curwin, &curwin->w_p_lcs); 2442 2443 // Parse default for 'fillchars'. 2444 (void)set_chars_option(curwin, &p_fcs); 2445 2446 #ifdef FEAT_CLIPBOARD 2447 // Parse default for 'clipboard' 2448 (void)check_clipboard_option(); 2449 #endif 2450 #ifdef FEAT_VARTABS 2451 vim_free(curbuf->b_p_vsts_array); 2452 (void)tabstop_set(curbuf->b_p_vsts, &curbuf->b_p_vsts_array); 2453 vim_free(curbuf->b_p_vts_array); 2454 (void)tabstop_set(curbuf->b_p_vts, &curbuf->b_p_vts_array); 2455 #endif 2456 } 2457 2458 /* 2459 * Check for string options that are NULL (normally only termcap options). 2460 */ 2461 void 2462 check_options(void) 2463 { 2464 int opt_idx; 2465 2466 for (opt_idx = 0; options[opt_idx].fullname != NULL; opt_idx++) 2467 if ((options[opt_idx].flags & P_STRING) && options[opt_idx].var != NULL) 2468 check_string_option((char_u **)get_varp(&(options[opt_idx]))); 2469 } 2470 2471 /* 2472 * Return the option index found by a pointer into term_strings[]. 2473 * Return -1 if not found. 2474 */ 2475 int 2476 get_term_opt_idx(char_u **p) 2477 { 2478 int opt_idx; 2479 2480 for (opt_idx = 1; options[opt_idx].fullname != NULL; opt_idx++) 2481 if (options[opt_idx].var == (char_u *)p) 2482 return opt_idx; 2483 return -1; // cannot happen: didn't find it! 2484 } 2485 2486 /* 2487 * Mark a terminal option as allocated, found by a pointer into term_strings[]. 2488 * Return the option index or -1 if not found. 2489 */ 2490 int 2491 set_term_option_alloced(char_u **p) 2492 { 2493 int opt_idx = get_term_opt_idx(p); 2494 2495 if (opt_idx >= 0) 2496 options[opt_idx].flags |= P_ALLOCED; 2497 return opt_idx; 2498 } 2499 2500 #if defined(FEAT_EVAL) || defined(PROTO) 2501 /* 2502 * Return TRUE when option "opt" was set from a modeline or in secure mode. 2503 * Return FALSE when it wasn't. 2504 * Return -1 for an unknown option. 2505 */ 2506 int 2507 was_set_insecurely(char_u *opt, int opt_flags) 2508 { 2509 int idx = findoption(opt); 2510 long_u *flagp; 2511 2512 if (idx >= 0) 2513 { 2514 flagp = insecure_flag(idx, opt_flags); 2515 return (*flagp & P_INSECURE) != 0; 2516 } 2517 internal_error("was_set_insecurely()"); 2518 return -1; 2519 } 2520 2521 /* 2522 * Get a pointer to the flags used for the P_INSECURE flag of option 2523 * "opt_idx". For some local options a local flags field is used. 2524 * NOTE: Caller must make sure that "curwin" is set to the window from which 2525 * the option is used. 2526 */ 2527 static long_u * 2528 insecure_flag(int opt_idx, int opt_flags) 2529 { 2530 if (opt_flags & OPT_LOCAL) 2531 switch ((int)options[opt_idx].indir) 2532 { 2533 #ifdef FEAT_STL_OPT 2534 case PV_STL: return &curwin->w_p_stl_flags; 2535 #endif 2536 #ifdef FEAT_EVAL 2537 # ifdef FEAT_FOLDING 2538 case PV_FDE: return &curwin->w_p_fde_flags; 2539 case PV_FDT: return &curwin->w_p_fdt_flags; 2540 # endif 2541 # ifdef FEAT_BEVAL 2542 case PV_BEXPR: return &curbuf->b_p_bexpr_flags; 2543 # endif 2544 # if defined(FEAT_CINDENT) 2545 case PV_INDE: return &curbuf->b_p_inde_flags; 2546 # endif 2547 case PV_FEX: return &curbuf->b_p_fex_flags; 2548 # ifdef FEAT_FIND_ID 2549 case PV_INEX: return &curbuf->b_p_inex_flags; 2550 # endif 2551 #endif 2552 } 2553 2554 // Nothing special, return global flags field. 2555 return &options[opt_idx].flags; 2556 } 2557 #endif 2558 2559 #if defined(FEAT_TITLE) || defined(PROTO) 2560 /* 2561 * Redraw the window title and/or tab page text later. 2562 */ 2563 void redraw_titles(void) 2564 { 2565 need_maketitle = TRUE; 2566 redraw_tabline = TRUE; 2567 } 2568 #endif 2569 2570 /* 2571 * Return TRUE if "val" is a valid name: only consists of alphanumeric ASCII 2572 * characters or characters in "allowed". 2573 */ 2574 int 2575 valid_name(char_u *val, char *allowed) 2576 { 2577 char_u *s; 2578 2579 for (s = val; *s != NUL; ++s) 2580 if (!ASCII_ISALNUM(*s) && vim_strchr((char_u *)allowed, *s) == NULL) 2581 return FALSE; 2582 return TRUE; 2583 } 2584 2585 #if defined(FEAT_EVAL) || defined(PROTO) 2586 /* 2587 * Set the script_ctx for an option, taking care of setting the buffer- or 2588 * window-local value. 2589 */ 2590 void 2591 set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx) 2592 { 2593 int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0; 2594 int indir = (int)options[opt_idx].indir; 2595 sctx_T new_script_ctx = script_ctx; 2596 2597 // Modeline already has the line number set. 2598 if (!(opt_flags & OPT_MODELINE)) 2599 new_script_ctx.sc_lnum += SOURCING_LNUM; 2600 2601 // Remember where the option was set. For local options need to do that 2602 // in the buffer or window structure. 2603 if (both || (opt_flags & OPT_GLOBAL) || (indir & (PV_BUF|PV_WIN)) == 0) 2604 options[opt_idx].script_ctx = new_script_ctx; 2605 if (both || (opt_flags & OPT_LOCAL)) 2606 { 2607 if (indir & PV_BUF) 2608 curbuf->b_p_script_ctx[indir & PV_MASK] = new_script_ctx; 2609 else if (indir & PV_WIN) 2610 curwin->w_p_script_ctx[indir & PV_MASK] = new_script_ctx; 2611 } 2612 } 2613 2614 /* 2615 * Set the script_ctx for a termcap option. 2616 * "name" must be the two character code, e.g. "RV". 2617 * When "name" is NULL use "opt_idx". 2618 */ 2619 void 2620 set_term_option_sctx_idx(char *name, int opt_idx) 2621 { 2622 char_u buf[5]; 2623 int idx; 2624 2625 if (name == NULL) 2626 idx = opt_idx; 2627 else 2628 { 2629 buf[0] = 't'; 2630 buf[1] = '_'; 2631 buf[2] = name[0]; 2632 buf[3] = name[1]; 2633 buf[4] = 0; 2634 idx = findoption(buf); 2635 } 2636 if (idx >= 0) 2637 set_option_sctx_idx(idx, OPT_GLOBAL, current_sctx); 2638 } 2639 #endif 2640 2641 #if defined(FEAT_EVAL) 2642 /* 2643 * Apply the OptionSet autocommand. 2644 */ 2645 static void 2646 apply_optionset_autocmd( 2647 int opt_idx, 2648 long opt_flags, 2649 long oldval, 2650 long oldval_g, 2651 long newval, 2652 char *errmsg) 2653 { 2654 char_u buf_old[12], buf_old_global[12], buf_new[12], buf_type[12]; 2655 2656 // Don't do this while starting up, failure or recursively. 2657 if (starting || errmsg != NULL || *get_vim_var_str(VV_OPTION_TYPE) != NUL) 2658 return; 2659 2660 vim_snprintf((char *)buf_old, sizeof(buf_old), "%ld", oldval); 2661 vim_snprintf((char *)buf_old_global, sizeof(buf_old_global), "%ld", 2662 oldval_g); 2663 vim_snprintf((char *)buf_new, sizeof(buf_new), "%ld", newval); 2664 vim_snprintf((char *)buf_type, sizeof(buf_type), "%s", 2665 (opt_flags & OPT_LOCAL) ? "local" : "global"); 2666 set_vim_var_string(VV_OPTION_NEW, buf_new, -1); 2667 set_vim_var_string(VV_OPTION_OLD, buf_old, -1); 2668 set_vim_var_string(VV_OPTION_TYPE, buf_type, -1); 2669 if (opt_flags & OPT_LOCAL) 2670 { 2671 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setlocal", -1); 2672 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1); 2673 } 2674 if (opt_flags & OPT_GLOBAL) 2675 { 2676 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setglobal", -1); 2677 set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old, -1); 2678 } 2679 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) 2680 { 2681 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"set", -1); 2682 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1); 2683 set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old_global, -1); 2684 } 2685 if (opt_flags & OPT_MODELINE) 2686 { 2687 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"modeline", -1); 2688 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1); 2689 } 2690 apply_autocmds(EVENT_OPTIONSET, (char_u *)options[opt_idx].fullname, 2691 NULL, FALSE, NULL); 2692 reset_v_option_vars(); 2693 } 2694 #endif 2695 2696 /* 2697 * Set the value of a boolean option, and take care of side effects. 2698 * Returns NULL for success, or an error message for an error. 2699 */ 2700 static char * 2701 set_bool_option( 2702 int opt_idx, // index in options[] table 2703 char_u *varp, // pointer to the option variable 2704 int value, // new value 2705 int opt_flags) // OPT_LOCAL and/or OPT_GLOBAL 2706 { 2707 int old_value = *(int *)varp; 2708 #if defined(FEAT_EVAL) 2709 int old_global_value = 0; 2710 #endif 2711 2712 // Disallow changing some options from secure mode 2713 if ((secure 2714 #ifdef HAVE_SANDBOX 2715 || sandbox != 0 2716 #endif 2717 ) && (options[opt_idx].flags & P_SECURE)) 2718 return e_secure; 2719 2720 #if defined(FEAT_EVAL) 2721 // Save the global value before changing anything. This is needed as for 2722 // a global-only option setting the "local value" in fact sets the global 2723 // value (since there is only one value). 2724 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) 2725 old_global_value = *(int *)get_varp_scope(&(options[opt_idx]), 2726 OPT_GLOBAL); 2727 #endif 2728 2729 *(int *)varp = value; // set the new value 2730 #ifdef FEAT_EVAL 2731 // Remember where the option was set. 2732 set_option_sctx_idx(opt_idx, opt_flags, current_sctx); 2733 #endif 2734 2735 #ifdef FEAT_GUI 2736 need_mouse_correct = TRUE; 2737 #endif 2738 2739 // May set global value for local option. 2740 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) 2741 *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = value; 2742 2743 /* 2744 * Handle side effects of changing a bool option. 2745 */ 2746 2747 // 'compatible' 2748 if ((int *)varp == &p_cp) 2749 compatible_set(); 2750 2751 #ifdef FEAT_LANGMAP 2752 if ((int *)varp == &p_lrm) 2753 // 'langremap' -> !'langnoremap' 2754 p_lnr = !p_lrm; 2755 else if ((int *)varp == &p_lnr) 2756 // 'langnoremap' -> !'langremap' 2757 p_lrm = !p_lnr; 2758 #endif 2759 2760 #ifdef FEAT_SYN_HL 2761 else if ((int *)varp == &curwin->w_p_cul && !value && old_value) 2762 reset_cursorline(); 2763 #endif 2764 2765 #ifdef FEAT_PERSISTENT_UNDO 2766 // 'undofile' 2767 else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf) 2768 { 2769 // Only take action when the option was set. When reset we do not 2770 // delete the undo file, the option may be set again without making 2771 // any changes in between. 2772 if (curbuf->b_p_udf || p_udf) 2773 { 2774 char_u hash[UNDO_HASH_SIZE]; 2775 buf_T *save_curbuf = curbuf; 2776 2777 FOR_ALL_BUFFERS(curbuf) 2778 { 2779 // When 'undofile' is set globally: for every buffer, otherwise 2780 // only for the current buffer: Try to read in the undofile, 2781 // if one exists, the buffer wasn't changed and the buffer was 2782 // loaded 2783 if ((curbuf == save_curbuf 2784 || (opt_flags & OPT_GLOBAL) || opt_flags == 0) 2785 && !curbufIsChanged() && curbuf->b_ml.ml_mfp != NULL) 2786 { 2787 #ifdef FEAT_CRYPT 2788 if (crypt_get_method_nr(curbuf) == CRYPT_M_SOD) 2789 continue; 2790 #endif 2791 u_compute_hash(hash); 2792 u_read_undo(NULL, hash, curbuf->b_fname); 2793 } 2794 } 2795 curbuf = save_curbuf; 2796 } 2797 } 2798 #endif 2799 2800 else if ((int *)varp == &curbuf->b_p_ro) 2801 { 2802 // when 'readonly' is reset globally, also reset readonlymode 2803 if (!curbuf->b_p_ro && (opt_flags & OPT_LOCAL) == 0) 2804 readonlymode = FALSE; 2805 2806 // when 'readonly' is set may give W10 again 2807 if (curbuf->b_p_ro) 2808 curbuf->b_did_warn = FALSE; 2809 2810 #ifdef FEAT_TITLE 2811 redraw_titles(); 2812 #endif 2813 } 2814 2815 #ifdef FEAT_GUI 2816 else if ((int *)varp == &p_mh) 2817 { 2818 if (!p_mh) 2819 gui_mch_mousehide(FALSE); 2820 } 2821 #endif 2822 2823 // when 'modifiable' is changed, redraw the window title 2824 else if ((int *)varp == &curbuf->b_p_ma) 2825 { 2826 # ifdef FEAT_TERMINAL 2827 // Cannot set 'modifiable' when in Terminal mode. 2828 if (curbuf->b_p_ma && (term_in_normal_mode() || (bt_terminal(curbuf) 2829 && curbuf->b_term != NULL && !term_is_finished(curbuf)))) 2830 { 2831 curbuf->b_p_ma = FALSE; 2832 return N_("E946: Cannot make a terminal with running job modifiable"); 2833 } 2834 # endif 2835 # ifdef FEAT_TITLE 2836 redraw_titles(); 2837 # endif 2838 } 2839 #ifdef FEAT_TITLE 2840 // when 'endofline' is changed, redraw the window title 2841 else if ((int *)varp == &curbuf->b_p_eol) 2842 { 2843 redraw_titles(); 2844 } 2845 // when 'fixeol' is changed, redraw the window title 2846 else if ((int *)varp == &curbuf->b_p_fixeol) 2847 { 2848 redraw_titles(); 2849 } 2850 // when 'bomb' is changed, redraw the window title and tab page text 2851 else if ((int *)varp == &curbuf->b_p_bomb) 2852 { 2853 redraw_titles(); 2854 } 2855 #endif 2856 2857 // when 'bin' is set also set some other options 2858 else if ((int *)varp == &curbuf->b_p_bin) 2859 { 2860 set_options_bin(old_value, curbuf->b_p_bin, opt_flags); 2861 #ifdef FEAT_TITLE 2862 redraw_titles(); 2863 #endif 2864 } 2865 2866 // when 'buflisted' changes, trigger autocommands 2867 else if ((int *)varp == &curbuf->b_p_bl && old_value != curbuf->b_p_bl) 2868 { 2869 apply_autocmds(curbuf->b_p_bl ? EVENT_BUFADD : EVENT_BUFDELETE, 2870 NULL, NULL, TRUE, curbuf); 2871 } 2872 2873 // when 'swf' is set, create swapfile, when reset remove swapfile 2874 else if ((int *)varp == &curbuf->b_p_swf) 2875 { 2876 if (curbuf->b_p_swf && p_uc) 2877 ml_open_file(curbuf); // create the swap file 2878 else 2879 // no need to reset curbuf->b_may_swap, ml_open_file() will check 2880 // buf->b_p_swf 2881 mf_close_file(curbuf, TRUE); // remove the swap file 2882 } 2883 2884 // when 'terse' is set change 'shortmess' 2885 else if ((int *)varp == &p_terse) 2886 { 2887 char_u *p; 2888 2889 p = vim_strchr(p_shm, SHM_SEARCH); 2890 2891 // insert 's' in p_shm 2892 if (p_terse && p == NULL) 2893 { 2894 STRCPY(IObuff, p_shm); 2895 STRCAT(IObuff, "s"); 2896 set_string_option_direct((char_u *)"shm", -1, IObuff, OPT_FREE, 0); 2897 } 2898 // remove 's' from p_shm 2899 else if (!p_terse && p != NULL) 2900 STRMOVE(p, p + 1); 2901 } 2902 2903 // when 'paste' is set or reset also change other options 2904 else if ((int *)varp == &p_paste) 2905 { 2906 paste_option_changed(); 2907 } 2908 2909 // when 'insertmode' is set from an autocommand need to do work here 2910 else if ((int *)varp == &p_im) 2911 { 2912 if (p_im) 2913 { 2914 if ((State & INSERT) == 0) 2915 need_start_insertmode = TRUE; 2916 stop_insert_mode = FALSE; 2917 } 2918 // only reset if it was set previously 2919 else if (old_value) 2920 { 2921 need_start_insertmode = FALSE; 2922 stop_insert_mode = TRUE; 2923 if (restart_edit != 0 && mode_displayed) 2924 clear_cmdline = TRUE; // remove "(insert)" 2925 restart_edit = 0; 2926 } 2927 } 2928 2929 // when 'ignorecase' is set or reset and 'hlsearch' is set, redraw 2930 else if ((int *)varp == &p_ic && p_hls) 2931 { 2932 redraw_all_later(SOME_VALID); 2933 } 2934 2935 #ifdef FEAT_SEARCH_EXTRA 2936 // when 'hlsearch' is set or reset: reset no_hlsearch 2937 else if ((int *)varp == &p_hls) 2938 { 2939 set_no_hlsearch(FALSE); 2940 } 2941 #endif 2942 2943 // when 'scrollbind' is set: snapshot the current position to avoid a jump 2944 // at the end of normal_cmd() 2945 else if ((int *)varp == &curwin->w_p_scb) 2946 { 2947 if (curwin->w_p_scb) 2948 { 2949 do_check_scrollbind(FALSE); 2950 curwin->w_scbind_pos = curwin->w_topline; 2951 } 2952 } 2953 2954 #if defined(FEAT_QUICKFIX) 2955 // There can be only one window with 'previewwindow' set. 2956 else if ((int *)varp == &curwin->w_p_pvw) 2957 { 2958 if (curwin->w_p_pvw) 2959 { 2960 win_T *win; 2961 2962 FOR_ALL_WINDOWS(win) 2963 if (win->w_p_pvw && win != curwin) 2964 { 2965 curwin->w_p_pvw = FALSE; 2966 return N_("E590: A preview window already exists"); 2967 } 2968 } 2969 } 2970 #endif 2971 2972 // when 'textmode' is set or reset also change 'fileformat' 2973 else if ((int *)varp == &curbuf->b_p_tx) 2974 { 2975 set_fileformat(curbuf->b_p_tx ? EOL_DOS : EOL_UNIX, opt_flags); 2976 } 2977 2978 // when 'textauto' is set or reset also change 'fileformats' 2979 else if ((int *)varp == &p_ta) 2980 { 2981 set_string_option_direct((char_u *)"ffs", -1, 2982 p_ta ? (char_u *)DFLT_FFS_VIM : (char_u *)"", 2983 OPT_FREE | opt_flags, 0); 2984 } 2985 2986 /* 2987 * When 'lisp' option changes include/exclude '-' in 2988 * keyword characters. 2989 */ 2990 #ifdef FEAT_LISP 2991 else if (varp == (char_u *)&(curbuf->b_p_lisp)) 2992 { 2993 (void)buf_init_chartab(curbuf, FALSE); // ignore errors 2994 } 2995 #endif 2996 2997 #ifdef FEAT_TITLE 2998 // when 'title' changed, may need to change the title; same for 'icon' 2999 else if ((int *)varp == &p_title || (int *)varp == &p_icon) 3000 { 3001 did_set_title(); 3002 } 3003 #endif 3004 3005 else if ((int *)varp == &curbuf->b_changed) 3006 { 3007 if (!value) 3008 save_file_ff(curbuf); // Buffer is unchanged 3009 #ifdef FEAT_TITLE 3010 redraw_titles(); 3011 #endif 3012 modified_was_set = value; 3013 } 3014 3015 #ifdef BACKSLASH_IN_FILENAME 3016 else if ((int *)varp == &p_ssl) 3017 { 3018 if (p_ssl) 3019 { 3020 psepc = '/'; 3021 psepcN = '\\'; 3022 pseps[0] = '/'; 3023 } 3024 else 3025 { 3026 psepc = '\\'; 3027 psepcN = '/'; 3028 pseps[0] = '\\'; 3029 } 3030 3031 // need to adjust the file name arguments and buffer names. 3032 buflist_slash_adjust(); 3033 alist_slash_adjust(); 3034 # ifdef FEAT_EVAL 3035 scriptnames_slash_adjust(); 3036 # endif 3037 } 3038 #endif 3039 3040 // If 'wrap' is set, set w_leftcol to zero. 3041 else if ((int *)varp == &curwin->w_p_wrap) 3042 { 3043 if (curwin->w_p_wrap) 3044 curwin->w_leftcol = 0; 3045 } 3046 3047 else if ((int *)varp == &p_ea) 3048 { 3049 if (p_ea && !old_value) 3050 win_equal(curwin, FALSE, 0); 3051 } 3052 3053 else if ((int *)varp == &p_wiv) 3054 { 3055 /* 3056 * When 'weirdinvert' changed, set/reset 't_xs'. 3057 * Then set 'weirdinvert' according to value of 't_xs'. 3058 */ 3059 if (p_wiv && !old_value) 3060 T_XS = (char_u *)"y"; 3061 else if (!p_wiv && old_value) 3062 T_XS = empty_option; 3063 p_wiv = (*T_XS != NUL); 3064 } 3065 3066 #ifdef FEAT_BEVAL_GUI 3067 else if ((int *)varp == &p_beval) 3068 { 3069 if (!balloonEvalForTerm) 3070 { 3071 if (p_beval && !old_value) 3072 gui_mch_enable_beval_area(balloonEval); 3073 else if (!p_beval && old_value) 3074 gui_mch_disable_beval_area(balloonEval); 3075 } 3076 } 3077 #endif 3078 #ifdef FEAT_BEVAL_TERM 3079 else if ((int *)varp == &p_bevalterm) 3080 { 3081 mch_bevalterm_changed(); 3082 } 3083 #endif 3084 3085 #ifdef FEAT_AUTOCHDIR 3086 else if ((int *)varp == &p_acd) 3087 { 3088 // Change directories when the 'acd' option is set now. 3089 DO_AUTOCHDIR; 3090 } 3091 #endif 3092 3093 #ifdef FEAT_DIFF 3094 // 'diff' 3095 else if ((int *)varp == &curwin->w_p_diff) 3096 { 3097 // May add or remove the buffer from the list of diff buffers. 3098 diff_buf_adjust(curwin); 3099 # ifdef FEAT_FOLDING 3100 if (foldmethodIsDiff(curwin)) 3101 foldUpdateAll(curwin); 3102 # endif 3103 } 3104 #endif 3105 3106 #ifdef HAVE_INPUT_METHOD 3107 // 'imdisable' 3108 else if ((int *)varp == &p_imdisable) 3109 { 3110 // Only de-activate it here, it will be enabled when changing mode. 3111 if (p_imdisable) 3112 im_set_active(FALSE); 3113 else if (State & INSERT) 3114 // When the option is set from an autocommand, it may need to take 3115 // effect right away. 3116 im_set_active(curbuf->b_p_iminsert == B_IMODE_IM); 3117 } 3118 #endif 3119 3120 #ifdef FEAT_SPELL 3121 // 'spell' 3122 else if ((int *)varp == &curwin->w_p_spell) 3123 { 3124 if (curwin->w_p_spell) 3125 { 3126 char *errmsg = did_set_spelllang(curwin); 3127 3128 if (errmsg != NULL) 3129 emsg(_(errmsg)); 3130 } 3131 } 3132 #endif 3133 3134 #ifdef FEAT_ARABIC 3135 if ((int *)varp == &curwin->w_p_arab) 3136 { 3137 if (curwin->w_p_arab) 3138 { 3139 /* 3140 * 'arabic' is set, handle various sub-settings. 3141 */ 3142 if (!p_tbidi) 3143 { 3144 // set rightleft mode 3145 if (!curwin->w_p_rl) 3146 { 3147 curwin->w_p_rl = TRUE; 3148 changed_window_setting(); 3149 } 3150 3151 // Enable Arabic shaping (major part of what Arabic requires) 3152 if (!p_arshape) 3153 { 3154 p_arshape = TRUE; 3155 redraw_later_clear(); 3156 } 3157 } 3158 3159 // Arabic requires a utf-8 encoding, inform the user if its not 3160 // set. 3161 if (STRCMP(p_enc, "utf-8") != 0) 3162 { 3163 static char *w_arabic = N_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'"); 3164 3165 msg_source(HL_ATTR(HLF_W)); 3166 msg_attr(_(w_arabic), HL_ATTR(HLF_W)); 3167 #ifdef FEAT_EVAL 3168 set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_arabic), -1); 3169 #endif 3170 } 3171 3172 // set 'delcombine' 3173 p_deco = TRUE; 3174 3175 # ifdef FEAT_KEYMAP 3176 // Force-set the necessary keymap for arabic 3177 set_option_value((char_u *)"keymap", 0L, (char_u *)"arabic", 3178 OPT_LOCAL); 3179 # endif 3180 } 3181 else 3182 { 3183 /* 3184 * 'arabic' is reset, handle various sub-settings. 3185 */ 3186 if (!p_tbidi) 3187 { 3188 // reset rightleft mode 3189 if (curwin->w_p_rl) 3190 { 3191 curwin->w_p_rl = FALSE; 3192 changed_window_setting(); 3193 } 3194 3195 // 'arabicshape' isn't reset, it is a global option and 3196 // another window may still need it "on". 3197 } 3198 3199 // 'delcombine' isn't reset, it is a global option and another 3200 // window may still want it "on". 3201 3202 # ifdef FEAT_KEYMAP 3203 // Revert to the default keymap 3204 curbuf->b_p_iminsert = B_IMODE_NONE; 3205 curbuf->b_p_imsearch = B_IMODE_USE_INSERT; 3206 # endif 3207 } 3208 } 3209 3210 #endif 3211 3212 #if defined(FEAT_SIGNS) && defined(FEAT_GUI) 3213 else if (((int *)varp == &curwin->w_p_nu 3214 || (int *)varp == &curwin->w_p_rnu) 3215 && gui.in_use 3216 && (*curwin->w_p_scl == 'n' && *(curwin->w_p_scl + 1) == 'u') 3217 && curbuf->b_signlist != NULL) 3218 { 3219 // If the 'number' or 'relativenumber' options are modified and 3220 // 'signcolumn' is set to 'number', then clear the screen for a full 3221 // refresh. Otherwise the sign icons are not displayed properly in the 3222 // number column. If the 'number' option is set and only the 3223 // 'relativenumber' option is toggled, then don't refresh the screen 3224 // (optimization). 3225 if (!(curwin->w_p_nu && ((int *)varp == &curwin->w_p_rnu))) 3226 redraw_all_later(CLEAR); 3227 } 3228 #endif 3229 3230 #ifdef FEAT_TERMGUICOLORS 3231 // 'termguicolors' 3232 else if ((int *)varp == &p_tgc) 3233 { 3234 # ifdef FEAT_VTP 3235 // Do not turn on 'tgc' when 24-bit colors are not supported. 3236 if ( 3237 # ifdef VIMDLL 3238 !gui.in_use && !gui.starting && 3239 # endif 3240 !has_vtp_working()) 3241 { 3242 p_tgc = 0; 3243 return N_("E954: 24-bit colors are not supported on this environment"); 3244 } 3245 if (is_term_win32()) 3246 swap_tcap(); 3247 # endif 3248 # ifdef FEAT_GUI 3249 if (!gui.in_use && !gui.starting) 3250 # endif 3251 highlight_gui_started(); 3252 # ifdef FEAT_VTP 3253 // reset t_Co 3254 if (is_term_win32()) 3255 { 3256 control_console_color_rgb(); 3257 set_termname(T_NAME); 3258 init_highlight(TRUE, FALSE); 3259 } 3260 # endif 3261 } 3262 #endif 3263 3264 /* 3265 * End of handling side effects for bool options. 3266 */ 3267 3268 // after handling side effects, call autocommand 3269 3270 options[opt_idx].flags |= P_WAS_SET; 3271 3272 #if defined(FEAT_EVAL) 3273 apply_optionset_autocmd(opt_idx, opt_flags, 3274 (long)(old_value ? TRUE : FALSE), 3275 (long)(old_global_value ? TRUE : FALSE), 3276 (long)(value ? TRUE : FALSE), NULL); 3277 #endif 3278 3279 comp_col(); // in case 'ruler' or 'showcmd' changed 3280 if (curwin->w_curswant != MAXCOL 3281 && (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0) 3282 curwin->w_set_curswant = TRUE; 3283 3284 if ((opt_flags & OPT_NO_REDRAW) == 0) 3285 check_redraw(options[opt_idx].flags); 3286 3287 return NULL; 3288 } 3289 3290 /* 3291 * Set the value of a number option, and take care of side effects. 3292 * Returns NULL for success, or an error message for an error. 3293 */ 3294 static char * 3295 set_num_option( 3296 int opt_idx, // index in options[] table 3297 char_u *varp, // pointer to the option variable 3298 long value, // new value 3299 char *errbuf, // buffer for error messages 3300 size_t errbuflen, // length of "errbuf" 3301 int opt_flags) // OPT_LOCAL, OPT_GLOBAL, 3302 // OPT_MODELINE, etc. 3303 { 3304 char *errmsg = NULL; 3305 long old_value = *(long *)varp; 3306 #if defined(FEAT_EVAL) 3307 long old_global_value = 0; // only used when setting a local and 3308 // global option 3309 #endif 3310 long old_Rows = Rows; // remember old Rows 3311 long old_Columns = Columns; // remember old Columns 3312 long *pp = (long *)varp; 3313 3314 // Disallow changing some options from secure mode. 3315 if ((secure 3316 #ifdef HAVE_SANDBOX 3317 || sandbox != 0 3318 #endif 3319 ) && (options[opt_idx].flags & P_SECURE)) 3320 return e_secure; 3321 3322 #if defined(FEAT_EVAL) 3323 // Save the global value before changing anything. This is needed as for 3324 // a global-only option setting the "local value" in fact sets the global 3325 // value (since there is only one value). 3326 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) 3327 old_global_value = *(long *)get_varp_scope(&(options[opt_idx]), 3328 OPT_GLOBAL); 3329 #endif 3330 3331 *pp = value; 3332 #ifdef FEAT_EVAL 3333 // Remember where the option was set. 3334 set_option_sctx_idx(opt_idx, opt_flags, current_sctx); 3335 #endif 3336 #ifdef FEAT_GUI 3337 need_mouse_correct = TRUE; 3338 #endif 3339 3340 if (curbuf->b_p_sw < 0) 3341 { 3342 errmsg = e_positive; 3343 #ifdef FEAT_VARTABS 3344 // Use the first 'vartabstop' value, or 'tabstop' if vts isn't in use. 3345 curbuf->b_p_sw = tabstop_count(curbuf->b_p_vts_array) > 0 3346 ? tabstop_first(curbuf->b_p_vts_array) 3347 : curbuf->b_p_ts; 3348 #else 3349 curbuf->b_p_sw = curbuf->b_p_ts; 3350 #endif 3351 } 3352 3353 /* 3354 * Number options that need some action when changed 3355 */ 3356 if (pp == &p_wh || pp == &p_hh) 3357 { 3358 // 'winheight' and 'helpheight' 3359 if (p_wh < 1) 3360 { 3361 errmsg = e_positive; 3362 p_wh = 1; 3363 } 3364 if (p_wmh > p_wh) 3365 { 3366 errmsg = e_winheight; 3367 p_wh = p_wmh; 3368 } 3369 if (p_hh < 0) 3370 { 3371 errmsg = e_positive; 3372 p_hh = 0; 3373 } 3374 3375 // Change window height NOW 3376 if (!ONE_WINDOW) 3377 { 3378 if (pp == &p_wh && curwin->w_height < p_wh) 3379 win_setheight((int)p_wh); 3380 if (pp == &p_hh && curbuf->b_help && curwin->w_height < p_hh) 3381 win_setheight((int)p_hh); 3382 } 3383 } 3384 else if (pp == &p_wmh) 3385 { 3386 // 'winminheight' 3387 if (p_wmh < 0) 3388 { 3389 errmsg = e_positive; 3390 p_wmh = 0; 3391 } 3392 if (p_wmh > p_wh) 3393 { 3394 errmsg = e_winheight; 3395 p_wmh = p_wh; 3396 } 3397 win_setminheight(); 3398 } 3399 else if (pp == &p_wiw) 3400 { 3401 // 'winwidth' 3402 if (p_wiw < 1) 3403 { 3404 errmsg = e_positive; 3405 p_wiw = 1; 3406 } 3407 if (p_wmw > p_wiw) 3408 { 3409 errmsg = e_winwidth; 3410 p_wiw = p_wmw; 3411 } 3412 3413 // Change window width NOW 3414 if (!ONE_WINDOW && curwin->w_width < p_wiw) 3415 win_setwidth((int)p_wiw); 3416 } 3417 else if (pp == &p_wmw) 3418 { 3419 // 'winminwidth' 3420 if (p_wmw < 0) 3421 { 3422 errmsg = e_positive; 3423 p_wmw = 0; 3424 } 3425 if (p_wmw > p_wiw) 3426 { 3427 errmsg = e_winwidth; 3428 p_wmw = p_wiw; 3429 } 3430 win_setminwidth(); 3431 } 3432 3433 // (re)set last window status line 3434 else if (pp == &p_ls) 3435 { 3436 last_status(FALSE); 3437 } 3438 3439 // (re)set tab page line 3440 else if (pp == &p_stal) 3441 { 3442 shell_new_rows(); // recompute window positions and heights 3443 } 3444 3445 #ifdef FEAT_GUI 3446 else if (pp == &p_linespace) 3447 { 3448 // Recompute gui.char_height and resize the Vim window to keep the 3449 // same number of lines. 3450 if (gui.in_use && gui_mch_adjust_charheight() == OK) 3451 gui_set_shellsize(FALSE, FALSE, RESIZE_VERT); 3452 } 3453 #endif 3454 3455 #ifdef FEAT_FOLDING 3456 // 'foldlevel' 3457 else if (pp == &curwin->w_p_fdl) 3458 { 3459 if (curwin->w_p_fdl < 0) 3460 curwin->w_p_fdl = 0; 3461 newFoldLevel(); 3462 } 3463 3464 // 'foldminlines' 3465 else if (pp == &curwin->w_p_fml) 3466 { 3467 foldUpdateAll(curwin); 3468 } 3469 3470 // 'foldnestmax' 3471 else if (pp == &curwin->w_p_fdn) 3472 { 3473 if (foldmethodIsSyntax(curwin) || foldmethodIsIndent(curwin)) 3474 foldUpdateAll(curwin); 3475 } 3476 3477 // 'foldcolumn' 3478 else if (pp == &curwin->w_p_fdc) 3479 { 3480 if (curwin->w_p_fdc < 0) 3481 { 3482 errmsg = e_positive; 3483 curwin->w_p_fdc = 0; 3484 } 3485 else if (curwin->w_p_fdc > 12) 3486 { 3487 errmsg = e_invarg; 3488 curwin->w_p_fdc = 12; 3489 } 3490 } 3491 #endif // FEAT_FOLDING 3492 3493 #if defined(FEAT_FOLDING) || defined(FEAT_CINDENT) 3494 // 'shiftwidth' or 'tabstop' 3495 else if (pp == &curbuf->b_p_sw || pp == &curbuf->b_p_ts) 3496 { 3497 # ifdef FEAT_FOLDING 3498 if (foldmethodIsIndent(curwin)) 3499 foldUpdateAll(curwin); 3500 # endif 3501 # ifdef FEAT_CINDENT 3502 // When 'shiftwidth' changes, or it's zero and 'tabstop' changes: 3503 // parse 'cinoptions'. 3504 if (pp == &curbuf->b_p_sw || curbuf->b_p_sw == 0) 3505 parse_cino(curbuf); 3506 # endif 3507 } 3508 #endif 3509 3510 // 'maxcombine' 3511 else if (pp == &p_mco) 3512 { 3513 if (p_mco > MAX_MCO) 3514 p_mco = MAX_MCO; 3515 else if (p_mco < 0) 3516 p_mco = 0; 3517 screenclear(); // will re-allocate the screen 3518 } 3519 3520 else if (pp == &curbuf->b_p_iminsert) 3521 { 3522 if (curbuf->b_p_iminsert < 0 || curbuf->b_p_iminsert > B_IMODE_LAST) 3523 { 3524 errmsg = e_invarg; 3525 curbuf->b_p_iminsert = B_IMODE_NONE; 3526 } 3527 p_iminsert = curbuf->b_p_iminsert; 3528 if (termcap_active) // don't do this in the alternate screen 3529 showmode(); 3530 #if defined(FEAT_KEYMAP) 3531 // Show/unshow value of 'keymap' in status lines. 3532 status_redraw_curbuf(); 3533 #endif 3534 } 3535 3536 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) 3537 // 'imstyle' 3538 else if (pp == &p_imst) 3539 { 3540 if (p_imst != IM_ON_THE_SPOT && p_imst != IM_OVER_THE_SPOT) 3541 errmsg = e_invarg; 3542 } 3543 #endif 3544 3545 else if (pp == &p_window) 3546 { 3547 if (p_window < 1) 3548 p_window = 1; 3549 else if (p_window >= Rows) 3550 p_window = Rows - 1; 3551 } 3552 3553 else if (pp == &curbuf->b_p_imsearch) 3554 { 3555 if (curbuf->b_p_imsearch < -1 || curbuf->b_p_imsearch > B_IMODE_LAST) 3556 { 3557 errmsg = e_invarg; 3558 curbuf->b_p_imsearch = B_IMODE_NONE; 3559 } 3560 p_imsearch = curbuf->b_p_imsearch; 3561 } 3562 3563 #ifdef FEAT_TITLE 3564 // if 'titlelen' has changed, redraw the title 3565 else if (pp == &p_titlelen) 3566 { 3567 if (p_titlelen < 0) 3568 { 3569 errmsg = e_positive; 3570 p_titlelen = 85; 3571 } 3572 if (starting != NO_SCREEN && old_value != p_titlelen) 3573 need_maketitle = TRUE; 3574 } 3575 #endif 3576 3577 // if p_ch changed value, change the command line height 3578 else if (pp == &p_ch) 3579 { 3580 if (p_ch < 1) 3581 { 3582 errmsg = e_positive; 3583 p_ch = 1; 3584 } 3585 if (p_ch > Rows - min_rows() + 1) 3586 p_ch = Rows - min_rows() + 1; 3587 3588 // Only compute the new window layout when startup has been 3589 // completed. Otherwise the frame sizes may be wrong. 3590 if (p_ch != old_value && full_screen 3591 #ifdef FEAT_GUI 3592 && !gui.starting 3593 #endif 3594 ) 3595 command_height(); 3596 } 3597 3598 // when 'updatecount' changes from zero to non-zero, open swap files 3599 else if (pp == &p_uc) 3600 { 3601 if (p_uc < 0) 3602 { 3603 errmsg = e_positive; 3604 p_uc = 100; 3605 } 3606 if (p_uc && !old_value) 3607 ml_open_files(); 3608 } 3609 #ifdef FEAT_CONCEAL 3610 else if (pp == &curwin->w_p_cole) 3611 { 3612 if (curwin->w_p_cole < 0) 3613 { 3614 errmsg = e_positive; 3615 curwin->w_p_cole = 0; 3616 } 3617 else if (curwin->w_p_cole > 3) 3618 { 3619 errmsg = e_invarg; 3620 curwin->w_p_cole = 3; 3621 } 3622 } 3623 #endif 3624 #ifdef MZSCHEME_GUI_THREADS 3625 else if (pp == &p_mzq) 3626 mzvim_reset_timer(); 3627 #endif 3628 3629 #if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) 3630 // 'pyxversion' 3631 else if (pp == &p_pyx) 3632 { 3633 if (p_pyx != 0 && p_pyx != 2 && p_pyx != 3) 3634 errmsg = e_invarg; 3635 } 3636 #endif 3637 3638 // sync undo before 'undolevels' changes 3639 else if (pp == &p_ul) 3640 { 3641 // use the old value, otherwise u_sync() may not work properly 3642 p_ul = old_value; 3643 u_sync(TRUE); 3644 p_ul = value; 3645 } 3646 else if (pp == &curbuf->b_p_ul) 3647 { 3648 // use the old value, otherwise u_sync() may not work properly 3649 curbuf->b_p_ul = old_value; 3650 u_sync(TRUE); 3651 curbuf->b_p_ul = value; 3652 } 3653 3654 #ifdef FEAT_LINEBREAK 3655 // 'numberwidth' must be positive 3656 else if (pp == &curwin->w_p_nuw) 3657 { 3658 if (curwin->w_p_nuw < 1) 3659 { 3660 errmsg = e_positive; 3661 curwin->w_p_nuw = 1; 3662 } 3663 if (curwin->w_p_nuw > 20) 3664 { 3665 errmsg = e_invarg; 3666 curwin->w_p_nuw = 20; 3667 } 3668 curwin->w_nrwidth_line_count = 0; // trigger a redraw 3669 } 3670 #endif 3671 3672 else if (pp == &curbuf->b_p_tw) 3673 { 3674 if (curbuf->b_p_tw < 0) 3675 { 3676 errmsg = e_positive; 3677 curbuf->b_p_tw = 0; 3678 } 3679 #ifdef FEAT_SYN_HL 3680 { 3681 win_T *wp; 3682 tabpage_T *tp; 3683 3684 FOR_ALL_TAB_WINDOWS(tp, wp) 3685 check_colorcolumn(wp); 3686 } 3687 #endif 3688 } 3689 3690 /* 3691 * Check the bounds for numeric options here 3692 */ 3693 if (Rows < min_rows() && full_screen) 3694 { 3695 if (errbuf != NULL) 3696 { 3697 vim_snprintf((char *)errbuf, errbuflen, 3698 _("E593: Need at least %d lines"), min_rows()); 3699 errmsg = errbuf; 3700 } 3701 Rows = min_rows(); 3702 } 3703 if (Columns < MIN_COLUMNS && full_screen) 3704 { 3705 if (errbuf != NULL) 3706 { 3707 vim_snprintf((char *)errbuf, errbuflen, 3708 _("E594: Need at least %d columns"), MIN_COLUMNS); 3709 errmsg = errbuf; 3710 } 3711 Columns = MIN_COLUMNS; 3712 } 3713 limit_screen_size(); 3714 3715 /* 3716 * If the screen (shell) height has been changed, assume it is the 3717 * physical screenheight. 3718 */ 3719 if (old_Rows != Rows || old_Columns != Columns) 3720 { 3721 // Changing the screen size is not allowed while updating the screen. 3722 if (updating_screen) 3723 *pp = old_value; 3724 else if (full_screen 3725 #ifdef FEAT_GUI 3726 && !gui.starting 3727 #endif 3728 ) 3729 set_shellsize((int)Columns, (int)Rows, TRUE); 3730 else 3731 { 3732 // Postpone the resizing; check the size and cmdline position for 3733 // messages. 3734 check_shellsize(); 3735 if (cmdline_row > Rows - p_ch && Rows > p_ch) 3736 cmdline_row = Rows - p_ch; 3737 } 3738 if (p_window >= Rows || !option_was_set((char_u *)"window")) 3739 p_window = Rows - 1; 3740 } 3741 3742 if (curbuf->b_p_ts <= 0) 3743 { 3744 errmsg = e_positive; 3745 curbuf->b_p_ts = 8; 3746 } 3747 if (p_tm < 0) 3748 { 3749 errmsg = e_positive; 3750 p_tm = 0; 3751 } 3752 if ((curwin->w_p_scr <= 0 3753 || (curwin->w_p_scr > curwin->w_height 3754 && curwin->w_height > 0)) 3755 && full_screen) 3756 { 3757 if (pp == &(curwin->w_p_scr)) 3758 { 3759 if (curwin->w_p_scr != 0) 3760 errmsg = e_invalid_scroll_size; 3761 win_comp_scroll(curwin); 3762 } 3763 // If 'scroll' became invalid because of a side effect silently adjust 3764 // it. 3765 else if (curwin->w_p_scr <= 0) 3766 curwin->w_p_scr = 1; 3767 else // curwin->w_p_scr > curwin->w_height 3768 curwin->w_p_scr = curwin->w_height; 3769 } 3770 if (p_hi < 0) 3771 { 3772 errmsg = e_positive; 3773 p_hi = 0; 3774 } 3775 else if (p_hi > 10000) 3776 { 3777 errmsg = e_invarg; 3778 p_hi = 10000; 3779 } 3780 if (p_re < 0 || p_re > 2) 3781 { 3782 errmsg = e_invarg; 3783 p_re = 0; 3784 } 3785 if (p_report < 0) 3786 { 3787 errmsg = e_positive; 3788 p_report = 1; 3789 } 3790 if ((p_sj < -100 || p_sj >= Rows) && full_screen) 3791 { 3792 if (Rows != old_Rows) // Rows changed, just adjust p_sj 3793 p_sj = Rows / 2; 3794 else 3795 { 3796 errmsg = e_invalid_scroll_size; 3797 p_sj = 1; 3798 } 3799 } 3800 if (p_so < 0 && full_screen) 3801 { 3802 errmsg = e_positive; 3803 p_so = 0; 3804 } 3805 if (p_siso < 0 && full_screen) 3806 { 3807 errmsg = e_positive; 3808 p_siso = 0; 3809 } 3810 #ifdef FEAT_CMDWIN 3811 if (p_cwh < 1) 3812 { 3813 errmsg = e_positive; 3814 p_cwh = 1; 3815 } 3816 #endif 3817 if (p_ut < 0) 3818 { 3819 errmsg = e_positive; 3820 p_ut = 2000; 3821 } 3822 if (p_ss < 0) 3823 { 3824 errmsg = e_positive; 3825 p_ss = 0; 3826 } 3827 3828 // May set global value for local option. 3829 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) 3830 *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = *pp; 3831 3832 options[opt_idx].flags |= P_WAS_SET; 3833 3834 #if defined(FEAT_EVAL) 3835 apply_optionset_autocmd(opt_idx, opt_flags, old_value, old_global_value, 3836 value, errmsg); 3837 #endif 3838 3839 comp_col(); // in case 'columns' or 'ls' changed 3840 if (curwin->w_curswant != MAXCOL 3841 && (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0) 3842 curwin->w_set_curswant = TRUE; 3843 if ((opt_flags & OPT_NO_REDRAW) == 0) 3844 check_redraw(options[opt_idx].flags); 3845 3846 return errmsg; 3847 } 3848 3849 /* 3850 * Called after an option changed: check if something needs to be redrawn. 3851 */ 3852 void 3853 check_redraw(long_u flags) 3854 { 3855 // Careful: P_RCLR and P_RALL are a combination of other P_ flags 3856 int doclear = (flags & P_RCLR) == P_RCLR; 3857 int all = ((flags & P_RALL) == P_RALL || doclear); 3858 3859 if ((flags & P_RSTAT) || all) // mark all status lines dirty 3860 status_redraw_all(); 3861 3862 if ((flags & P_RBUF) || (flags & P_RWIN) || all) 3863 changed_window_setting(); 3864 if (flags & P_RBUF) 3865 redraw_curbuf_later(NOT_VALID); 3866 if (flags & P_RWINONLY) 3867 redraw_later(NOT_VALID); 3868 if (doclear) 3869 redraw_all_later(CLEAR); 3870 else if (all) 3871 redraw_all_later(NOT_VALID); 3872 } 3873 3874 /* 3875 * Find index for option 'arg'. 3876 * Return -1 if not found. 3877 */ 3878 int 3879 findoption(char_u *arg) 3880 { 3881 int opt_idx; 3882 char *s, *p; 3883 static short quick_tab[27] = {0, 0}; // quick access table 3884 int is_term_opt; 3885 3886 /* 3887 * For first call: Initialize the quick-access table. 3888 * It contains the index for the first option that starts with a certain 3889 * letter. There are 26 letters, plus the first "t_" option. 3890 */ 3891 if (quick_tab[1] == 0) 3892 { 3893 p = options[0].fullname; 3894 for (opt_idx = 1; (s = options[opt_idx].fullname) != NULL; opt_idx++) 3895 { 3896 if (s[0] != p[0]) 3897 { 3898 if (s[0] == 't' && s[1] == '_') 3899 quick_tab[26] = opt_idx; 3900 else 3901 quick_tab[CharOrdLow(s[0])] = opt_idx; 3902 } 3903 p = s; 3904 } 3905 } 3906 3907 /* 3908 * Check for name starting with an illegal character. 3909 */ 3910 #ifdef EBCDIC 3911 if (!islower(arg[0])) 3912 #else 3913 if (arg[0] < 'a' || arg[0] > 'z') 3914 #endif 3915 return -1; 3916 3917 is_term_opt = (arg[0] == 't' && arg[1] == '_'); 3918 if (is_term_opt) 3919 opt_idx = quick_tab[26]; 3920 else 3921 opt_idx = quick_tab[CharOrdLow(arg[0])]; 3922 for ( ; (s = options[opt_idx].fullname) != NULL; opt_idx++) 3923 { 3924 if (STRCMP(arg, s) == 0) // match full name 3925 break; 3926 } 3927 if (s == NULL && !is_term_opt) 3928 { 3929 opt_idx = quick_tab[CharOrdLow(arg[0])]; 3930 for ( ; options[opt_idx].fullname != NULL; opt_idx++) 3931 { 3932 s = options[opt_idx].shortname; 3933 if (s != NULL && STRCMP(arg, s) == 0) // match short name 3934 break; 3935 s = NULL; 3936 } 3937 } 3938 if (s == NULL) 3939 opt_idx = -1; 3940 return opt_idx; 3941 } 3942 3943 #if defined(FEAT_EVAL) || defined(FEAT_TCL) || defined(FEAT_MZSCHEME) 3944 /* 3945 * Get the value for an option. 3946 * 3947 * Returns: 3948 * Number option: gov_number, *numval gets value. 3949 * Toggle option: gov_bool, *numval gets value. 3950 * String option: gov_string, *stringval gets allocated string. 3951 * Hidden Number option: gov_hidden_number. 3952 * Hidden Toggle option: gov_hidden_bool. 3953 * Hidden String option: gov_hidden_string. 3954 * Unknown option: gov_unknown. 3955 */ 3956 getoption_T 3957 get_option_value( 3958 char_u *name, 3959 long *numval, 3960 char_u **stringval, // NULL when only checking existence 3961 int opt_flags) 3962 { 3963 int opt_idx; 3964 char_u *varp; 3965 3966 opt_idx = findoption(name); 3967 if (opt_idx < 0) // option not in the table 3968 { 3969 int key; 3970 3971 if (STRLEN(name) == 4 && name[0] == 't' && name[1] == '_' 3972 && (key = find_key_option(name, FALSE)) != 0) 3973 { 3974 char_u key_name[2]; 3975 char_u *p; 3976 3977 // check for a terminal option 3978 if (key < 0) 3979 { 3980 key_name[0] = KEY2TERMCAP0(key); 3981 key_name[1] = KEY2TERMCAP1(key); 3982 } 3983 else 3984 { 3985 key_name[0] = KS_KEY; 3986 key_name[1] = (key & 0xff); 3987 } 3988 p = find_termcode(key_name); 3989 if (p != NULL) 3990 { 3991 if (stringval != NULL) 3992 *stringval = vim_strsave(p); 3993 return gov_string; 3994 } 3995 } 3996 return gov_unknown; 3997 } 3998 3999 varp = get_varp_scope(&(options[opt_idx]), opt_flags); 4000 4001 if (options[opt_idx].flags & P_STRING) 4002 { 4003 if (varp == NULL) // hidden option 4004 return gov_hidden_string; 4005 if (stringval != NULL) 4006 { 4007 #ifdef FEAT_CRYPT 4008 // never return the value of the crypt key 4009 if ((char_u **)varp == &curbuf->b_p_key 4010 && **(char_u **)(varp) != NUL) 4011 *stringval = vim_strsave((char_u *)"*****"); 4012 else 4013 #endif 4014 *stringval = vim_strsave(*(char_u **)(varp)); 4015 } 4016 return gov_string; 4017 } 4018 4019 if (varp == NULL) // hidden option 4020 return (options[opt_idx].flags & P_NUM) 4021 ? gov_hidden_number : gov_hidden_bool; 4022 if (options[opt_idx].flags & P_NUM) 4023 *numval = *(long *)varp; 4024 else 4025 { 4026 // Special case: 'modified' is b_changed, but we also want to consider 4027 // it set when 'ff' or 'fenc' changed. 4028 if ((int *)varp == &curbuf->b_changed) 4029 *numval = curbufIsChanged(); 4030 else 4031 *numval = (long) *(int *)varp; 4032 } 4033 return (options[opt_idx].flags & P_NUM) ? gov_number : gov_bool; 4034 } 4035 #endif 4036 4037 #if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) || defined(PROTO) 4038 /* 4039 * Returns the option attributes and its value. Unlike the above function it 4040 * will return either global value or local value of the option depending on 4041 * what was requested, but it will never return global value if it was 4042 * requested to return local one and vice versa. Neither it will return 4043 * buffer-local value if it was requested to return window-local one. 4044 * 4045 * Pretends that option is absent if it is not present in the requested scope 4046 * (i.e. has no global, window-local or buffer-local value depending on 4047 * opt_type). Uses 4048 * 4049 * Returned flags: 4050 * 0 hidden or unknown option, also option that does not have requested 4051 * type (see SREQ_* in vim.h) 4052 * see SOPT_* in vim.h for other flags 4053 * 4054 * Possible opt_type values: see SREQ_* in vim.h 4055 */ 4056 int 4057 get_option_value_strict( 4058 char_u *name, 4059 long *numval, 4060 char_u **stringval, // NULL when only obtaining attributes 4061 int opt_type, 4062 void *from) 4063 { 4064 int opt_idx; 4065 char_u *varp = NULL; 4066 struct vimoption *p; 4067 int r = 0; 4068 4069 opt_idx = findoption(name); 4070 if (opt_idx < 0) 4071 return 0; 4072 4073 p = &(options[opt_idx]); 4074 4075 // Hidden option 4076 if (p->var == NULL) 4077 return 0; 4078 4079 if (p->flags & P_BOOL) 4080 r |= SOPT_BOOL; 4081 else if (p->flags & P_NUM) 4082 r |= SOPT_NUM; 4083 else if (p->flags & P_STRING) 4084 r |= SOPT_STRING; 4085 4086 if (p->indir == PV_NONE) 4087 { 4088 if (opt_type == SREQ_GLOBAL) 4089 r |= SOPT_GLOBAL; 4090 else 4091 return 0; // Did not request global-only option 4092 } 4093 else 4094 { 4095 if (p->indir & PV_BOTH) 4096 r |= SOPT_GLOBAL; 4097 else if (opt_type == SREQ_GLOBAL) 4098 return 0; // Requested global option 4099 4100 if (p->indir & PV_WIN) 4101 { 4102 if (opt_type == SREQ_BUF) 4103 return 0; // Did not request window-local option 4104 else 4105 r |= SOPT_WIN; 4106 } 4107 else if (p->indir & PV_BUF) 4108 { 4109 if (opt_type == SREQ_WIN) 4110 return 0; // Did not request buffer-local option 4111 else 4112 r |= SOPT_BUF; 4113 } 4114 } 4115 4116 if (stringval == NULL) 4117 return r; 4118 4119 if (opt_type == SREQ_GLOBAL) 4120 varp = p->var; 4121 else 4122 { 4123 if (opt_type == SREQ_BUF) 4124 { 4125 // Special case: 'modified' is b_changed, but we also want to 4126 // consider it set when 'ff' or 'fenc' changed. 4127 if (p->indir == PV_MOD) 4128 { 4129 *numval = bufIsChanged((buf_T *)from); 4130 varp = NULL; 4131 } 4132 #ifdef FEAT_CRYPT 4133 else if (p->indir == PV_KEY) 4134 { 4135 // never return the value of the crypt key 4136 *stringval = NULL; 4137 varp = NULL; 4138 } 4139 #endif 4140 else 4141 { 4142 buf_T *save_curbuf = curbuf; 4143 4144 // only getting a pointer, no need to use aucmd_prepbuf() 4145 curbuf = (buf_T *)from; 4146 curwin->w_buffer = curbuf; 4147 varp = get_varp(p); 4148 curbuf = save_curbuf; 4149 curwin->w_buffer = curbuf; 4150 } 4151 } 4152 else if (opt_type == SREQ_WIN) 4153 { 4154 win_T *save_curwin = curwin; 4155 4156 curwin = (win_T *)from; 4157 curbuf = curwin->w_buffer; 4158 varp = get_varp(p); 4159 curwin = save_curwin; 4160 curbuf = curwin->w_buffer; 4161 } 4162 if (varp == p->var) 4163 return (r | SOPT_UNSET); 4164 } 4165 4166 if (varp != NULL) 4167 { 4168 if (p->flags & P_STRING) 4169 *stringval = vim_strsave(*(char_u **)(varp)); 4170 else if (p->flags & P_NUM) 4171 *numval = *(long *) varp; 4172 else 4173 *numval = *(int *)varp; 4174 } 4175 4176 return r; 4177 } 4178 4179 /* 4180 * Iterate over options. First argument is a pointer to a pointer to a 4181 * structure inside options[] array, second is option type like in the above 4182 * function. 4183 * 4184 * If first argument points to NULL it is assumed that iteration just started 4185 * and caller needs the very first value. 4186 * If first argument points to the end marker function returns NULL and sets 4187 * first argument to NULL. 4188 * 4189 * Returns full option name for current option on each call. 4190 */ 4191 char_u * 4192 option_iter_next(void **option, int opt_type) 4193 { 4194 struct vimoption *ret = NULL; 4195 do 4196 { 4197 if (*option == NULL) 4198 *option = (void *) options; 4199 else if (((struct vimoption *) (*option))->fullname == NULL) 4200 { 4201 *option = NULL; 4202 return NULL; 4203 } 4204 else 4205 *option = (void *) (((struct vimoption *) (*option)) + 1); 4206 4207 ret = ((struct vimoption *) (*option)); 4208 4209 // Hidden option 4210 if (ret->var == NULL) 4211 { 4212 ret = NULL; 4213 continue; 4214 } 4215 4216 switch (opt_type) 4217 { 4218 case SREQ_GLOBAL: 4219 if (!(ret->indir == PV_NONE || ret->indir & PV_BOTH)) 4220 ret = NULL; 4221 break; 4222 case SREQ_BUF: 4223 if (!(ret->indir & PV_BUF)) 4224 ret = NULL; 4225 break; 4226 case SREQ_WIN: 4227 if (!(ret->indir & PV_WIN)) 4228 ret = NULL; 4229 break; 4230 default: 4231 internal_error("option_iter_next()"); 4232 return NULL; 4233 } 4234 } 4235 while (ret == NULL); 4236 4237 return (char_u *)ret->fullname; 4238 } 4239 #endif 4240 4241 /* 4242 * Return the flags for the option at 'opt_idx'. 4243 */ 4244 long_u 4245 get_option_flags(int opt_idx) 4246 { 4247 return options[opt_idx].flags; 4248 } 4249 4250 /* 4251 * Set a flag for the option at 'opt_idx'. 4252 */ 4253 void 4254 set_option_flag(int opt_idx, long_u flag) 4255 { 4256 options[opt_idx].flags |= flag; 4257 } 4258 4259 /* 4260 * Clear a flag for the option at 'opt_idx'. 4261 */ 4262 void 4263 clear_option_flag(int opt_idx, long_u flag) 4264 { 4265 options[opt_idx].flags &= ~flag; 4266 } 4267 4268 /* 4269 * Returns TRUE if the option at 'opt_idx' is a global option 4270 */ 4271 int 4272 is_global_option(int opt_idx) 4273 { 4274 return options[opt_idx].indir == PV_NONE; 4275 } 4276 4277 /* 4278 * Returns TRUE if the option at 'opt_idx' is a global option which also has a 4279 * local value. 4280 */ 4281 int 4282 is_global_local_option(int opt_idx) 4283 { 4284 return options[opt_idx].indir & PV_BOTH; 4285 } 4286 4287 /* 4288 * Returns TRUE if the option at 'opt_idx' is a window-local option 4289 */ 4290 int 4291 is_window_local_option(int opt_idx) 4292 { 4293 return options[opt_idx].var == VAR_WIN; 4294 } 4295 4296 /* 4297 * Returns TRUE if the option at 'opt_idx' is a hidden option 4298 */ 4299 int 4300 is_hidden_option(int opt_idx) 4301 { 4302 return options[opt_idx].var == NULL; 4303 } 4304 4305 #if defined(FEAT_CRYPT) || defined(PROTO) 4306 /* 4307 * Returns TRUE if the option at 'opt_idx' is a crypt key option 4308 */ 4309 int 4310 is_crypt_key_option(int opt_idx) 4311 { 4312 return options[opt_idx].indir == PV_KEY; 4313 } 4314 #endif 4315 4316 /* 4317 * Set the value of option "name". 4318 * Use "string" for string options, use "number" for other options. 4319 * 4320 * Returns NULL on success or error message on error. 4321 */ 4322 char * 4323 set_option_value( 4324 char_u *name, 4325 long number, 4326 char_u *string, 4327 int opt_flags) // OPT_LOCAL or 0 (both) 4328 { 4329 int opt_idx; 4330 char_u *varp; 4331 long_u flags; 4332 4333 opt_idx = findoption(name); 4334 if (opt_idx < 0) 4335 { 4336 int key; 4337 4338 if (STRLEN(name) == 4 && name[0] == 't' && name[1] == '_' 4339 && (key = find_key_option(name, FALSE)) != 0) 4340 { 4341 char_u key_name[2]; 4342 4343 if (key < 0) 4344 { 4345 key_name[0] = KEY2TERMCAP0(key); 4346 key_name[1] = KEY2TERMCAP1(key); 4347 } 4348 else 4349 { 4350 key_name[0] = KS_KEY; 4351 key_name[1] = (key & 0xff); 4352 } 4353 add_termcode(key_name, string, FALSE); 4354 if (full_screen) 4355 ttest(FALSE); 4356 redraw_all_later(CLEAR); 4357 return NULL; 4358 } 4359 4360 semsg(_("E355: Unknown option: %s"), name); 4361 } 4362 else 4363 { 4364 flags = options[opt_idx].flags; 4365 #ifdef HAVE_SANDBOX 4366 // Disallow changing some options in the sandbox 4367 if (sandbox > 0 && (flags & P_SECURE)) 4368 { 4369 emsg(_(e_not_allowed_in_sandbox)); 4370 return NULL; 4371 } 4372 #endif 4373 if (flags & P_STRING) 4374 return set_string_option(opt_idx, string, opt_flags); 4375 else 4376 { 4377 varp = get_varp_scope(&(options[opt_idx]), opt_flags); 4378 if (varp != NULL) // hidden option is not changed 4379 { 4380 if (number == 0 && string != NULL) 4381 { 4382 int idx; 4383 4384 // Either we are given a string or we are setting option 4385 // to zero. 4386 for (idx = 0; string[idx] == '0'; ++idx) 4387 ; 4388 if (string[idx] != NUL || idx == 0) 4389 { 4390 // There's another character after zeros or the string 4391 // is empty. In both cases, we are trying to set a 4392 // num option using a string. 4393 semsg(_("E521: Number required: &%s = '%s'"), 4394 name, string); 4395 return NULL; // do nothing as we hit an error 4396 4397 } 4398 } 4399 if (flags & P_NUM) 4400 return set_num_option(opt_idx, varp, number, 4401 NULL, 0, opt_flags); 4402 else 4403 return set_bool_option(opt_idx, varp, (int)number, 4404 opt_flags); 4405 } 4406 } 4407 } 4408 return NULL; 4409 } 4410 4411 /* 4412 * Get the terminal code for a terminal option. 4413 * Returns NULL when not found. 4414 */ 4415 char_u * 4416 get_term_code(char_u *tname) 4417 { 4418 int opt_idx; 4419 char_u *varp; 4420 4421 if (tname[0] != 't' || tname[1] != '_' || 4422 tname[2] == NUL || tname[3] == NUL) 4423 return NULL; 4424 if ((opt_idx = findoption(tname)) >= 0) 4425 { 4426 varp = get_varp(&(options[opt_idx])); 4427 if (varp != NULL) 4428 varp = *(char_u **)(varp); 4429 return varp; 4430 } 4431 return find_termcode(tname + 2); 4432 } 4433 4434 char_u * 4435 get_highlight_default(void) 4436 { 4437 int i; 4438 4439 i = findoption((char_u *)"hl"); 4440 if (i >= 0) 4441 return options[i].def_val[VI_DEFAULT]; 4442 return (char_u *)NULL; 4443 } 4444 4445 char_u * 4446 get_encoding_default(void) 4447 { 4448 int i; 4449 4450 i = findoption((char_u *)"enc"); 4451 if (i >= 0) 4452 return options[i].def_val[VI_DEFAULT]; 4453 return (char_u *)NULL; 4454 } 4455 4456 /* 4457 * Translate a string like "t_xx", "<t_xx>" or "<S-Tab>" to a key number. 4458 * When "has_lt" is true there is a '<' before "*arg_arg". 4459 * Returns 0 when the key is not recognized. 4460 */ 4461 static int 4462 find_key_option(char_u *arg_arg, int has_lt) 4463 { 4464 int key = 0; 4465 int modifiers; 4466 char_u *arg = arg_arg; 4467 4468 /* 4469 * Don't use get_special_key_code() for t_xx, we don't want it to call 4470 * add_termcap_entry(). 4471 */ 4472 if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3]) 4473 key = TERMCAP2KEY(arg[2], arg[3]); 4474 else if (has_lt) 4475 { 4476 --arg; // put arg at the '<' 4477 modifiers = 0; 4478 key = find_special_key(&arg, &modifiers, 4479 FSK_KEYCODE | FSK_KEEP_X_KEY | FSK_SIMPLIFY, NULL); 4480 if (modifiers) // can't handle modifiers here 4481 key = 0; 4482 } 4483 return key; 4484 } 4485 4486 /* 4487 * if 'all' == 0: show changed options 4488 * if 'all' == 1: show all normal options 4489 * if 'all' == 2: show all terminal options 4490 */ 4491 static void 4492 showoptions( 4493 int all, 4494 int opt_flags) // OPT_LOCAL and/or OPT_GLOBAL 4495 { 4496 struct vimoption *p; 4497 int col; 4498 int isterm; 4499 char_u *varp; 4500 struct vimoption **items; 4501 int item_count; 4502 int run; 4503 int row, rows; 4504 int cols; 4505 int i; 4506 int len; 4507 4508 #define INC 20 4509 #define GAP 3 4510 4511 items = ALLOC_MULT(struct vimoption *, OPTION_COUNT); 4512 if (items == NULL) 4513 return; 4514 4515 // Highlight title 4516 if (all == 2) 4517 msg_puts_title(_("\n--- Terminal codes ---")); 4518 else if (opt_flags & OPT_GLOBAL) 4519 msg_puts_title(_("\n--- Global option values ---")); 4520 else if (opt_flags & OPT_LOCAL) 4521 msg_puts_title(_("\n--- Local option values ---")); 4522 else 4523 msg_puts_title(_("\n--- Options ---")); 4524 4525 /* 4526 * Do the loop two times: 4527 * 1. display the short items 4528 * 2. display the long items (only strings and numbers) 4529 * When "opt_flags" has OPT_ONECOLUMN do everything in run 2. 4530 */ 4531 for (run = 1; run <= 2 && !got_int; ++run) 4532 { 4533 /* 4534 * collect the items in items[] 4535 */ 4536 item_count = 0; 4537 for (p = &options[0]; p->fullname != NULL; p++) 4538 { 4539 // apply :filter /pat/ 4540 if (message_filtered((char_u *)p->fullname)) 4541 continue; 4542 4543 varp = NULL; 4544 isterm = istermoption(p); 4545 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) != 0) 4546 { 4547 if (p->indir != PV_NONE && !isterm) 4548 varp = get_varp_scope(p, opt_flags); 4549 } 4550 else 4551 varp = get_varp(p); 4552 if (varp != NULL 4553 && ((all == 2 && isterm) 4554 || (all == 1 && !isterm) 4555 || (all == 0 && !optval_default(p, varp, p_cp)))) 4556 { 4557 if (opt_flags & OPT_ONECOLUMN) 4558 len = Columns; 4559 else if (p->flags & P_BOOL) 4560 len = 1; // a toggle option fits always 4561 else 4562 { 4563 option_value2string(p, opt_flags); 4564 len = (int)STRLEN(p->fullname) + vim_strsize(NameBuff) + 1; 4565 } 4566 if ((len <= INC - GAP && run == 1) || 4567 (len > INC - GAP && run == 2)) 4568 items[item_count++] = p; 4569 } 4570 } 4571 4572 /* 4573 * display the items 4574 */ 4575 if (run == 1) 4576 { 4577 cols = (Columns + GAP - 3) / INC; 4578 if (cols == 0) 4579 cols = 1; 4580 rows = (item_count + cols - 1) / cols; 4581 } 4582 else // run == 2 4583 rows = item_count; 4584 for (row = 0; row < rows && !got_int; ++row) 4585 { 4586 msg_putchar('\n'); // go to next line 4587 if (got_int) // 'q' typed in more 4588 break; 4589 col = 0; 4590 for (i = row; i < item_count; i += rows) 4591 { 4592 msg_col = col; // make columns 4593 showoneopt(items[i], opt_flags); 4594 col += INC; 4595 } 4596 out_flush(); 4597 ui_breakcheck(); 4598 } 4599 } 4600 vim_free(items); 4601 } 4602 4603 /* 4604 * Return TRUE if option "p" has its default value. 4605 */ 4606 static int 4607 optval_default(struct vimoption *p, char_u *varp, int compatible) 4608 { 4609 int dvi; 4610 4611 if (varp == NULL) 4612 return TRUE; // hidden option is always at default 4613 dvi = ((p->flags & P_VI_DEF) || compatible) ? VI_DEFAULT : VIM_DEFAULT; 4614 if (p->flags & P_NUM) 4615 return (*(long *)varp == (long)(long_i)p->def_val[dvi]); 4616 if (p->flags & P_BOOL) 4617 // the cast to long is required for Manx C, long_i is 4618 // needed for MSVC 4619 return (*(int *)varp == (int)(long)(long_i)p->def_val[dvi]); 4620 // P_STRING 4621 return (STRCMP(*(char_u **)varp, p->def_val[dvi]) == 0); 4622 } 4623 4624 /* 4625 * showoneopt: show the value of one option 4626 * must not be called with a hidden option! 4627 */ 4628 static void 4629 showoneopt( 4630 struct vimoption *p, 4631 int opt_flags) // OPT_LOCAL or OPT_GLOBAL 4632 { 4633 char_u *varp; 4634 int save_silent = silent_mode; 4635 4636 silent_mode = FALSE; 4637 info_message = TRUE; // use mch_msg(), not mch_errmsg() 4638 4639 varp = get_varp_scope(p, opt_flags); 4640 4641 // for 'modified' we also need to check if 'ff' or 'fenc' changed. 4642 if ((p->flags & P_BOOL) && ((int *)varp == &curbuf->b_changed 4643 ? !curbufIsChanged() : !*(int *)varp)) 4644 msg_puts("no"); 4645 else if ((p->flags & P_BOOL) && *(int *)varp < 0) 4646 msg_puts("--"); 4647 else 4648 msg_puts(" "); 4649 msg_puts(p->fullname); 4650 if (!(p->flags & P_BOOL)) 4651 { 4652 msg_putchar('='); 4653 // put value string in NameBuff 4654 option_value2string(p, opt_flags); 4655 msg_outtrans(NameBuff); 4656 } 4657 4658 silent_mode = save_silent; 4659 info_message = FALSE; 4660 } 4661 4662 /* 4663 * Write modified options as ":set" commands to a file. 4664 * 4665 * There are three values for "opt_flags": 4666 * OPT_GLOBAL: Write global option values and fresh values of 4667 * buffer-local options (used for start of a session 4668 * file). 4669 * OPT_GLOBAL + OPT_LOCAL: Idem, add fresh values of window-local options for 4670 * curwin (used for a vimrc file). 4671 * OPT_LOCAL: Write buffer-local option values for curbuf, fresh 4672 * and local values for window-local options of 4673 * curwin. Local values are also written when at the 4674 * default value, because a modeline or autocommand 4675 * may have set them when doing ":edit file" and the 4676 * user has set them back at the default or fresh 4677 * value. 4678 * When "local_only" is TRUE, don't write fresh 4679 * values, only local values (for ":mkview"). 4680 * (fresh value = value used for a new buffer or window for a local option). 4681 * 4682 * Return FAIL on error, OK otherwise. 4683 */ 4684 int 4685 makeset(FILE *fd, int opt_flags, int local_only) 4686 { 4687 struct vimoption *p; 4688 char_u *varp; // currently used value 4689 char_u *varp_fresh; // local value 4690 char_u *varp_local = NULL; // fresh value 4691 char *cmd; 4692 int round; 4693 int pri; 4694 4695 /* 4696 * The options that don't have a default (terminal name, columns, lines) 4697 * are never written. Terminal options are also not written. 4698 * Do the loop over "options[]" twice: once for options with the 4699 * P_PRI_MKRC flag and once without. 4700 */ 4701 for (pri = 1; pri >= 0; --pri) 4702 { 4703 for (p = &options[0]; !istermoption(p); p++) 4704 if (!(p->flags & P_NO_MKRC) 4705 && !istermoption(p) 4706 && ((pri == 1) == ((p->flags & P_PRI_MKRC) != 0))) 4707 { 4708 // skip global option when only doing locals 4709 if (p->indir == PV_NONE && !(opt_flags & OPT_GLOBAL)) 4710 continue; 4711 4712 // Do not store options like 'bufhidden' and 'syntax' in a vimrc 4713 // file, they are always buffer-specific. 4714 if ((opt_flags & OPT_GLOBAL) && (p->flags & P_NOGLOB)) 4715 continue; 4716 4717 // Global values are only written when not at the default value. 4718 varp = get_varp_scope(p, opt_flags); 4719 if ((opt_flags & OPT_GLOBAL) && optval_default(p, varp, p_cp)) 4720 continue; 4721 4722 if ((opt_flags & OPT_SKIPRTP) && (p->var == (char_u *)&p_rtp 4723 || p->var == (char_u *)&p_pp)) 4724 continue; 4725 4726 round = 2; 4727 if (p->indir != PV_NONE) 4728 { 4729 if (p->var == VAR_WIN) 4730 { 4731 // skip window-local option when only doing globals 4732 if (!(opt_flags & OPT_LOCAL)) 4733 continue; 4734 // When fresh value of window-local option is not at the 4735 // default, need to write it too. 4736 if (!(opt_flags & OPT_GLOBAL) && !local_only) 4737 { 4738 varp_fresh = get_varp_scope(p, OPT_GLOBAL); 4739 if (!optval_default(p, varp_fresh, p_cp)) 4740 { 4741 round = 1; 4742 varp_local = varp; 4743 varp = varp_fresh; 4744 } 4745 } 4746 } 4747 } 4748 4749 // Round 1: fresh value for window-local options. 4750 // Round 2: other values 4751 for ( ; round <= 2; varp = varp_local, ++round) 4752 { 4753 if (round == 1 || (opt_flags & OPT_GLOBAL)) 4754 cmd = "set"; 4755 else 4756 cmd = "setlocal"; 4757 4758 if (p->flags & P_BOOL) 4759 { 4760 if (put_setbool(fd, cmd, p->fullname, *(int *)varp) == FAIL) 4761 return FAIL; 4762 } 4763 else if (p->flags & P_NUM) 4764 { 4765 if (put_setnum(fd, cmd, p->fullname, (long *)varp) == FAIL) 4766 return FAIL; 4767 } 4768 else // P_STRING 4769 { 4770 int do_endif = FALSE; 4771 4772 // Don't set 'syntax' and 'filetype' again if the value is 4773 // already right, avoids reloading the syntax file. 4774 if ( 4775 #if defined(FEAT_SYN_HL) 4776 p->indir == PV_SYN || 4777 #endif 4778 p->indir == PV_FT) 4779 { 4780 if (fprintf(fd, "if &%s != '%s'", p->fullname, 4781 *(char_u **)(varp)) < 0 4782 || put_eol(fd) < 0) 4783 return FAIL; 4784 do_endif = TRUE; 4785 } 4786 if (put_setstring(fd, cmd, p->fullname, (char_u **)varp, 4787 p->flags) == FAIL) 4788 return FAIL; 4789 if (do_endif) 4790 { 4791 if (put_line(fd, "endif") == FAIL) 4792 return FAIL; 4793 } 4794 } 4795 } 4796 } 4797 } 4798 return OK; 4799 } 4800 4801 #if defined(FEAT_FOLDING) || defined(PROTO) 4802 /* 4803 * Generate set commands for the local fold options only. Used when 4804 * 'sessionoptions' or 'viewoptions' contains "folds" but not "options". 4805 */ 4806 int 4807 makefoldset(FILE *fd) 4808 { 4809 if (put_setstring(fd, "setlocal", "fdm", &curwin->w_p_fdm, 0) == FAIL 4810 # ifdef FEAT_EVAL 4811 || put_setstring(fd, "setlocal", "fde", &curwin->w_p_fde, 0) 4812 == FAIL 4813 # endif 4814 || put_setstring(fd, "setlocal", "fmr", &curwin->w_p_fmr, 0) 4815 == FAIL 4816 || put_setstring(fd, "setlocal", "fdi", &curwin->w_p_fdi, 0) 4817 == FAIL 4818 || put_setnum(fd, "setlocal", "fdl", &curwin->w_p_fdl) == FAIL 4819 || put_setnum(fd, "setlocal", "fml", &curwin->w_p_fml) == FAIL 4820 || put_setnum(fd, "setlocal", "fdn", &curwin->w_p_fdn) == FAIL 4821 || put_setbool(fd, "setlocal", "fen", curwin->w_p_fen) == FAIL 4822 ) 4823 return FAIL; 4824 4825 return OK; 4826 } 4827 #endif 4828 4829 static int 4830 put_setstring( 4831 FILE *fd, 4832 char *cmd, 4833 char *name, 4834 char_u **valuep, 4835 long_u flags) 4836 { 4837 char_u *s; 4838 char_u *buf = NULL; 4839 char_u *part = NULL; 4840 char_u *p; 4841 4842 if (fprintf(fd, "%s %s=", cmd, name) < 0) 4843 return FAIL; 4844 if (*valuep != NULL) 4845 { 4846 // Output 'pastetoggle' as key names. For other 4847 // options some characters have to be escaped with 4848 // CTRL-V or backslash 4849 if (valuep == &p_pt) 4850 { 4851 s = *valuep; 4852 while (*s != NUL) 4853 if (put_escstr(fd, str2special(&s, FALSE), 2) == FAIL) 4854 return FAIL; 4855 } 4856 // expand the option value, replace $HOME by ~ 4857 else if ((flags & P_EXPAND) != 0) 4858 { 4859 int size = (int)STRLEN(*valuep) + 1; 4860 4861 // replace home directory in the whole option value into "buf" 4862 buf = alloc(size); 4863 if (buf == NULL) 4864 goto fail; 4865 home_replace(NULL, *valuep, buf, size, FALSE); 4866 4867 // If the option value is longer than MAXPATHL, we need to append 4868 // each comma separated part of the option separately, so that it 4869 // can be expanded when read back. 4870 if (size >= MAXPATHL && (flags & P_COMMA) != 0 4871 && vim_strchr(*valuep, ',') != NULL) 4872 { 4873 part = alloc(size); 4874 if (part == NULL) 4875 goto fail; 4876 4877 // write line break to clear the option, e.g. ':set rtp=' 4878 if (put_eol(fd) == FAIL) 4879 goto fail; 4880 4881 p = buf; 4882 while (*p != NUL) 4883 { 4884 // for each comma separated option part, append value to 4885 // the option, :set rtp+=value 4886 if (fprintf(fd, "%s %s+=", cmd, name) < 0) 4887 goto fail; 4888 (void)copy_option_part(&p, part, size, ","); 4889 if (put_escstr(fd, part, 2) == FAIL || put_eol(fd) == FAIL) 4890 goto fail; 4891 } 4892 vim_free(buf); 4893 vim_free(part); 4894 return OK; 4895 } 4896 if (put_escstr(fd, buf, 2) == FAIL) 4897 { 4898 vim_free(buf); 4899 return FAIL; 4900 } 4901 vim_free(buf); 4902 } 4903 else if (put_escstr(fd, *valuep, 2) == FAIL) 4904 return FAIL; 4905 } 4906 if (put_eol(fd) < 0) 4907 return FAIL; 4908 return OK; 4909 fail: 4910 vim_free(buf); 4911 vim_free(part); 4912 return FAIL; 4913 } 4914 4915 static int 4916 put_setnum( 4917 FILE *fd, 4918 char *cmd, 4919 char *name, 4920 long *valuep) 4921 { 4922 long wc; 4923 4924 if (fprintf(fd, "%s %s=", cmd, name) < 0) 4925 return FAIL; 4926 if (wc_use_keyname((char_u *)valuep, &wc)) 4927 { 4928 // print 'wildchar' and 'wildcharm' as a key name 4929 if (fputs((char *)get_special_key_name((int)wc, 0), fd) < 0) 4930 return FAIL; 4931 } 4932 else if (fprintf(fd, "%ld", *valuep) < 0) 4933 return FAIL; 4934 if (put_eol(fd) < 0) 4935 return FAIL; 4936 return OK; 4937 } 4938 4939 static int 4940 put_setbool( 4941 FILE *fd, 4942 char *cmd, 4943 char *name, 4944 int value) 4945 { 4946 if (value < 0) // global/local option using global value 4947 return OK; 4948 if (fprintf(fd, "%s %s%s", cmd, value ? "" : "no", name) < 0 4949 || put_eol(fd) < 0) 4950 return FAIL; 4951 return OK; 4952 } 4953 4954 /* 4955 * Clear all the terminal options. 4956 * If the option has been allocated, free the memory. 4957 * Terminal options are never hidden or indirect. 4958 */ 4959 void 4960 clear_termoptions(void) 4961 { 4962 /* 4963 * Reset a few things before clearing the old options. This may cause 4964 * outputting a few things that the terminal doesn't understand, but the 4965 * screen will be cleared later, so this is OK. 4966 */ 4967 mch_setmouse(FALSE); // switch mouse off 4968 #ifdef FEAT_TITLE 4969 mch_restore_title(SAVE_RESTORE_BOTH); // restore window titles 4970 #endif 4971 #if defined(FEAT_XCLIPBOARD) && defined(FEAT_GUI) 4972 // When starting the GUI close the display opened for the clipboard. 4973 // After restoring the title, because that will need the display. 4974 if (gui.starting) 4975 clear_xterm_clip(); 4976 #endif 4977 stoptermcap(); // stop termcap mode 4978 4979 free_termoptions(); 4980 } 4981 4982 void 4983 free_termoptions(void) 4984 { 4985 struct vimoption *p; 4986 4987 for (p = options; p->fullname != NULL; p++) 4988 if (istermoption(p)) 4989 { 4990 if (p->flags & P_ALLOCED) 4991 free_string_option(*(char_u **)(p->var)); 4992 if (p->flags & P_DEF_ALLOCED) 4993 free_string_option(p->def_val[VI_DEFAULT]); 4994 *(char_u **)(p->var) = empty_option; 4995 p->def_val[VI_DEFAULT] = empty_option; 4996 p->flags &= ~(P_ALLOCED|P_DEF_ALLOCED); 4997 #ifdef FEAT_EVAL 4998 // remember where the option was cleared 4999 set_option_sctx_idx((int)(p - options), OPT_GLOBAL, current_sctx); 5000 #endif 5001 } 5002 clear_termcodes(); 5003 } 5004 5005 /* 5006 * Free the string for one term option, if it was allocated. 5007 * Set the string to empty_option and clear allocated flag. 5008 * "var" points to the option value. 5009 */ 5010 void 5011 free_one_termoption(char_u *var) 5012 { 5013 struct vimoption *p; 5014 5015 for (p = &options[0]; p->fullname != NULL; p++) 5016 if (p->var == var) 5017 { 5018 if (p->flags & P_ALLOCED) 5019 free_string_option(*(char_u **)(p->var)); 5020 *(char_u **)(p->var) = empty_option; 5021 p->flags &= ~P_ALLOCED; 5022 break; 5023 } 5024 } 5025 5026 /* 5027 * Set the terminal option defaults to the current value. 5028 * Used after setting the terminal name. 5029 */ 5030 void 5031 set_term_defaults(void) 5032 { 5033 struct vimoption *p; 5034 5035 for (p = &options[0]; p->fullname != NULL; p++) 5036 { 5037 if (istermoption(p) && p->def_val[VI_DEFAULT] != *(char_u **)(p->var)) 5038 { 5039 if (p->flags & P_DEF_ALLOCED) 5040 { 5041 free_string_option(p->def_val[VI_DEFAULT]); 5042 p->flags &= ~P_DEF_ALLOCED; 5043 } 5044 p->def_val[VI_DEFAULT] = *(char_u **)(p->var); 5045 if (p->flags & P_ALLOCED) 5046 { 5047 p->flags |= P_DEF_ALLOCED; 5048 p->flags &= ~P_ALLOCED; // don't free the value now 5049 } 5050 } 5051 } 5052 } 5053 5054 /* 5055 * return TRUE if 'p' starts with 't_' 5056 */ 5057 static int 5058 istermoption(struct vimoption *p) 5059 { 5060 return (p->fullname[0] == 't' && p->fullname[1] == '_'); 5061 } 5062 5063 /* 5064 * Returns TRUE if the option at 'opt_idx' starts with 't_' 5065 */ 5066 int 5067 istermoption_idx(int opt_idx) 5068 { 5069 return istermoption(&options[opt_idx]); 5070 } 5071 5072 #if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) || defined(PROTO) 5073 /* 5074 * Unset local option value, similar to ":set opt<". 5075 */ 5076 void 5077 unset_global_local_option(char_u *name, void *from) 5078 { 5079 struct vimoption *p; 5080 int opt_idx; 5081 buf_T *buf = (buf_T *)from; 5082 5083 opt_idx = findoption(name); 5084 if (opt_idx < 0) 5085 return; 5086 p = &(options[opt_idx]); 5087 5088 switch ((int)p->indir) 5089 { 5090 // global option with local value: use local value if it's been set 5091 case PV_EP: 5092 clear_string_option(&buf->b_p_ep); 5093 break; 5094 case PV_KP: 5095 clear_string_option(&buf->b_p_kp); 5096 break; 5097 case PV_PATH: 5098 clear_string_option(&buf->b_p_path); 5099 break; 5100 case PV_AR: 5101 buf->b_p_ar = -1; 5102 break; 5103 case PV_BKC: 5104 clear_string_option(&buf->b_p_bkc); 5105 buf->b_bkc_flags = 0; 5106 break; 5107 case PV_TAGS: 5108 clear_string_option(&buf->b_p_tags); 5109 break; 5110 case PV_TC: 5111 clear_string_option(&buf->b_p_tc); 5112 buf->b_tc_flags = 0; 5113 break; 5114 case PV_SISO: 5115 curwin->w_p_siso = -1; 5116 break; 5117 case PV_SO: 5118 curwin->w_p_so = -1; 5119 break; 5120 #ifdef FEAT_FIND_ID 5121 case PV_DEF: 5122 clear_string_option(&buf->b_p_def); 5123 break; 5124 case PV_INC: 5125 clear_string_option(&buf->b_p_inc); 5126 break; 5127 #endif 5128 case PV_DICT: 5129 clear_string_option(&buf->b_p_dict); 5130 break; 5131 case PV_TSR: 5132 clear_string_option(&buf->b_p_tsr); 5133 break; 5134 case PV_FP: 5135 clear_string_option(&buf->b_p_fp); 5136 break; 5137 #ifdef FEAT_QUICKFIX 5138 case PV_EFM: 5139 clear_string_option(&buf->b_p_efm); 5140 break; 5141 case PV_GP: 5142 clear_string_option(&buf->b_p_gp); 5143 break; 5144 case PV_MP: 5145 clear_string_option(&buf->b_p_mp); 5146 break; 5147 #endif 5148 #if defined(FEAT_BEVAL) && defined(FEAT_EVAL) 5149 case PV_BEXPR: 5150 clear_string_option(&buf->b_p_bexpr); 5151 break; 5152 #endif 5153 #if defined(FEAT_CRYPT) 5154 case PV_CM: 5155 clear_string_option(&buf->b_p_cm); 5156 break; 5157 #endif 5158 #ifdef FEAT_LINEBREAK 5159 case PV_SBR: 5160 clear_string_option(&((win_T *)from)->w_p_sbr); 5161 break; 5162 #endif 5163 #ifdef FEAT_STL_OPT 5164 case PV_STL: 5165 clear_string_option(&((win_T *)from)->w_p_stl); 5166 break; 5167 #endif 5168 case PV_UL: 5169 buf->b_p_ul = NO_LOCAL_UNDOLEVEL; 5170 break; 5171 #ifdef FEAT_LISP 5172 case PV_LW: 5173 clear_string_option(&buf->b_p_lw); 5174 break; 5175 #endif 5176 case PV_MENC: 5177 clear_string_option(&buf->b_p_menc); 5178 break; 5179 case PV_LCS: 5180 clear_string_option(&((win_T *)from)->w_p_lcs); 5181 set_chars_option((win_T *)from, &((win_T *)from)->w_p_lcs); 5182 redraw_later(NOT_VALID); 5183 break; 5184 case PV_VE: 5185 clear_string_option(&((win_T *)from)->w_p_ve); 5186 ((win_T *)from)->w_ve_flags = 0; 5187 break; 5188 } 5189 } 5190 #endif 5191 5192 /* 5193 * Get pointer to option variable, depending on local or global scope. 5194 */ 5195 static char_u * 5196 get_varp_scope(struct vimoption *p, int opt_flags) 5197 { 5198 if ((opt_flags & OPT_GLOBAL) && p->indir != PV_NONE) 5199 { 5200 if (p->var == VAR_WIN) 5201 return (char_u *)GLOBAL_WO(get_varp(p)); 5202 return p->var; 5203 } 5204 if ((opt_flags & OPT_LOCAL) && ((int)p->indir & PV_BOTH)) 5205 { 5206 switch ((int)p->indir) 5207 { 5208 case PV_FP: return (char_u *)&(curbuf->b_p_fp); 5209 #ifdef FEAT_QUICKFIX 5210 case PV_EFM: return (char_u *)&(curbuf->b_p_efm); 5211 case PV_GP: return (char_u *)&(curbuf->b_p_gp); 5212 case PV_MP: return (char_u *)&(curbuf->b_p_mp); 5213 #endif 5214 case PV_EP: return (char_u *)&(curbuf->b_p_ep); 5215 case PV_KP: return (char_u *)&(curbuf->b_p_kp); 5216 case PV_PATH: return (char_u *)&(curbuf->b_p_path); 5217 case PV_AR: return (char_u *)&(curbuf->b_p_ar); 5218 case PV_TAGS: return (char_u *)&(curbuf->b_p_tags); 5219 case PV_TC: return (char_u *)&(curbuf->b_p_tc); 5220 case PV_SISO: return (char_u *)&(curwin->w_p_siso); 5221 case PV_SO: return (char_u *)&(curwin->w_p_so); 5222 #ifdef FEAT_FIND_ID 5223 case PV_DEF: return (char_u *)&(curbuf->b_p_def); 5224 case PV_INC: return (char_u *)&(curbuf->b_p_inc); 5225 #endif 5226 case PV_DICT: return (char_u *)&(curbuf->b_p_dict); 5227 case PV_TSR: return (char_u *)&(curbuf->b_p_tsr); 5228 #if defined(FEAT_BEVAL) && defined(FEAT_EVAL) 5229 case PV_BEXPR: return (char_u *)&(curbuf->b_p_bexpr); 5230 #endif 5231 #if defined(FEAT_CRYPT) 5232 case PV_CM: return (char_u *)&(curbuf->b_p_cm); 5233 #endif 5234 #ifdef FEAT_LINEBREAK 5235 case PV_SBR: return (char_u *)&(curwin->w_p_sbr); 5236 #endif 5237 #ifdef FEAT_STL_OPT 5238 case PV_STL: return (char_u *)&(curwin->w_p_stl); 5239 #endif 5240 case PV_UL: return (char_u *)&(curbuf->b_p_ul); 5241 #ifdef FEAT_LISP 5242 case PV_LW: return (char_u *)&(curbuf->b_p_lw); 5243 #endif 5244 case PV_BKC: return (char_u *)&(curbuf->b_p_bkc); 5245 case PV_MENC: return (char_u *)&(curbuf->b_p_menc); 5246 case PV_LCS: return (char_u *)&(curwin->w_p_lcs); 5247 case PV_VE: return (char_u *)&(curwin->w_p_ve); 5248 5249 } 5250 return NULL; // "cannot happen" 5251 } 5252 return get_varp(p); 5253 } 5254 5255 /* 5256 * Get pointer to option variable at 'opt_idx', depending on local or global 5257 * scope. 5258 */ 5259 char_u * 5260 get_option_varp_scope(int opt_idx, int opt_flags) 5261 { 5262 return get_varp_scope(&(options[opt_idx]), opt_flags); 5263 } 5264 5265 /* 5266 * Get pointer to option variable. 5267 */ 5268 static char_u * 5269 get_varp(struct vimoption *p) 5270 { 5271 // hidden option, always return NULL 5272 if (p->var == NULL) 5273 return NULL; 5274 5275 switch ((int)p->indir) 5276 { 5277 case PV_NONE: return p->var; 5278 5279 // global option with local value: use local value if it's been set 5280 case PV_EP: return *curbuf->b_p_ep != NUL 5281 ? (char_u *)&curbuf->b_p_ep : p->var; 5282 case PV_KP: return *curbuf->b_p_kp != NUL 5283 ? (char_u *)&curbuf->b_p_kp : p->var; 5284 case PV_PATH: return *curbuf->b_p_path != NUL 5285 ? (char_u *)&(curbuf->b_p_path) : p->var; 5286 case PV_AR: return curbuf->b_p_ar >= 0 5287 ? (char_u *)&(curbuf->b_p_ar) : p->var; 5288 case PV_TAGS: return *curbuf->b_p_tags != NUL 5289 ? (char_u *)&(curbuf->b_p_tags) : p->var; 5290 case PV_TC: return *curbuf->b_p_tc != NUL 5291 ? (char_u *)&(curbuf->b_p_tc) : p->var; 5292 case PV_BKC: return *curbuf->b_p_bkc != NUL 5293 ? (char_u *)&(curbuf->b_p_bkc) : p->var; 5294 case PV_SISO: return curwin->w_p_siso >= 0 5295 ? (char_u *)&(curwin->w_p_siso) : p->var; 5296 case PV_SO: return curwin->w_p_so >= 0 5297 ? (char_u *)&(curwin->w_p_so) : p->var; 5298 #ifdef FEAT_FIND_ID 5299 case PV_DEF: return *curbuf->b_p_def != NUL 5300 ? (char_u *)&(curbuf->b_p_def) : p->var; 5301 case PV_INC: return *curbuf->b_p_inc != NUL 5302 ? (char_u *)&(curbuf->b_p_inc) : p->var; 5303 #endif 5304 case PV_DICT: return *curbuf->b_p_dict != NUL 5305 ? (char_u *)&(curbuf->b_p_dict) : p->var; 5306 case PV_TSR: return *curbuf->b_p_tsr != NUL 5307 ? (char_u *)&(curbuf->b_p_tsr) : p->var; 5308 case PV_FP: return *curbuf->b_p_fp != NUL 5309 ? (char_u *)&(curbuf->b_p_fp) : p->var; 5310 #ifdef FEAT_QUICKFIX 5311 case PV_EFM: return *curbuf->b_p_efm != NUL 5312 ? (char_u *)&(curbuf->b_p_efm) : p->var; 5313 case PV_GP: return *curbuf->b_p_gp != NUL 5314 ? (char_u *)&(curbuf->b_p_gp) : p->var; 5315 case PV_MP: return *curbuf->b_p_mp != NUL 5316 ? (char_u *)&(curbuf->b_p_mp) : p->var; 5317 #endif 5318 #if defined(FEAT_BEVAL) && defined(FEAT_EVAL) 5319 case PV_BEXPR: return *curbuf->b_p_bexpr != NUL 5320 ? (char_u *)&(curbuf->b_p_bexpr) : p->var; 5321 #endif 5322 #if defined(FEAT_CRYPT) 5323 case PV_CM: return *curbuf->b_p_cm != NUL 5324 ? (char_u *)&(curbuf->b_p_cm) : p->var; 5325 #endif 5326 #ifdef FEAT_LINEBREAK 5327 case PV_SBR: return *curwin->w_p_sbr != NUL 5328 ? (char_u *)&(curwin->w_p_sbr) : p->var; 5329 #endif 5330 #ifdef FEAT_STL_OPT 5331 case PV_STL: return *curwin->w_p_stl != NUL 5332 ? (char_u *)&(curwin->w_p_stl) : p->var; 5333 #endif 5334 case PV_UL: return curbuf->b_p_ul != NO_LOCAL_UNDOLEVEL 5335 ? (char_u *)&(curbuf->b_p_ul) : p->var; 5336 #ifdef FEAT_LISP 5337 case PV_LW: return *curbuf->b_p_lw != NUL 5338 ? (char_u *)&(curbuf->b_p_lw) : p->var; 5339 #endif 5340 case PV_MENC: return *curbuf->b_p_menc != NUL 5341 ? (char_u *)&(curbuf->b_p_menc) : p->var; 5342 #ifdef FEAT_ARABIC 5343 case PV_ARAB: return (char_u *)&(curwin->w_p_arab); 5344 #endif 5345 case PV_LIST: return (char_u *)&(curwin->w_p_list); 5346 case PV_LCS: return *curwin->w_p_lcs != NUL 5347 ? (char_u *)&(curwin->w_p_lcs) : p->var; 5348 case PV_VE: return *curwin->w_p_ve != NUL 5349 ? (char_u *)&(curwin->w_p_ve) : p->var; 5350 #ifdef FEAT_SPELL 5351 case PV_SPELL: return (char_u *)&(curwin->w_p_spell); 5352 #endif 5353 #ifdef FEAT_SYN_HL 5354 case PV_CUC: return (char_u *)&(curwin->w_p_cuc); 5355 case PV_CUL: return (char_u *)&(curwin->w_p_cul); 5356 case PV_CULOPT: return (char_u *)&(curwin->w_p_culopt); 5357 case PV_CC: return (char_u *)&(curwin->w_p_cc); 5358 #endif 5359 #ifdef FEAT_DIFF 5360 case PV_DIFF: return (char_u *)&(curwin->w_p_diff); 5361 #endif 5362 #ifdef FEAT_FOLDING 5363 case PV_FDC: return (char_u *)&(curwin->w_p_fdc); 5364 case PV_FEN: return (char_u *)&(curwin->w_p_fen); 5365 case PV_FDI: return (char_u *)&(curwin->w_p_fdi); 5366 case PV_FDL: return (char_u *)&(curwin->w_p_fdl); 5367 case PV_FDM: return (char_u *)&(curwin->w_p_fdm); 5368 case PV_FML: return (char_u *)&(curwin->w_p_fml); 5369 case PV_FDN: return (char_u *)&(curwin->w_p_fdn); 5370 # ifdef FEAT_EVAL 5371 case PV_FDE: return (char_u *)&(curwin->w_p_fde); 5372 case PV_FDT: return (char_u *)&(curwin->w_p_fdt); 5373 # endif 5374 case PV_FMR: return (char_u *)&(curwin->w_p_fmr); 5375 #endif 5376 case PV_NU: return (char_u *)&(curwin->w_p_nu); 5377 case PV_RNU: return (char_u *)&(curwin->w_p_rnu); 5378 #ifdef FEAT_LINEBREAK 5379 case PV_NUW: return (char_u *)&(curwin->w_p_nuw); 5380 #endif 5381 case PV_WFH: return (char_u *)&(curwin->w_p_wfh); 5382 case PV_WFW: return (char_u *)&(curwin->w_p_wfw); 5383 #if defined(FEAT_QUICKFIX) 5384 case PV_PVW: return (char_u *)&(curwin->w_p_pvw); 5385 #endif 5386 #ifdef FEAT_RIGHTLEFT 5387 case PV_RL: return (char_u *)&(curwin->w_p_rl); 5388 case PV_RLC: return (char_u *)&(curwin->w_p_rlc); 5389 #endif 5390 case PV_SCROLL: return (char_u *)&(curwin->w_p_scr); 5391 case PV_WRAP: return (char_u *)&(curwin->w_p_wrap); 5392 #ifdef FEAT_LINEBREAK 5393 case PV_LBR: return (char_u *)&(curwin->w_p_lbr); 5394 case PV_BRI: return (char_u *)&(curwin->w_p_bri); 5395 case PV_BRIOPT: return (char_u *)&(curwin->w_p_briopt); 5396 #endif 5397 case PV_WCR: return (char_u *)&(curwin->w_p_wcr); 5398 case PV_SCBIND: return (char_u *)&(curwin->w_p_scb); 5399 case PV_CRBIND: return (char_u *)&(curwin->w_p_crb); 5400 #ifdef FEAT_CONCEAL 5401 case PV_COCU: return (char_u *)&(curwin->w_p_cocu); 5402 case PV_COLE: return (char_u *)&(curwin->w_p_cole); 5403 #endif 5404 #ifdef FEAT_TERMINAL 5405 case PV_TWK: return (char_u *)&(curwin->w_p_twk); 5406 case PV_TWS: return (char_u *)&(curwin->w_p_tws); 5407 case PV_TWSL: return (char_u *)&(curbuf->b_p_twsl); 5408 #endif 5409 5410 case PV_AI: return (char_u *)&(curbuf->b_p_ai); 5411 case PV_BIN: return (char_u *)&(curbuf->b_p_bin); 5412 case PV_BOMB: return (char_u *)&(curbuf->b_p_bomb); 5413 case PV_BH: return (char_u *)&(curbuf->b_p_bh); 5414 case PV_BT: return (char_u *)&(curbuf->b_p_bt); 5415 case PV_BL: return (char_u *)&(curbuf->b_p_bl); 5416 case PV_CI: return (char_u *)&(curbuf->b_p_ci); 5417 #ifdef FEAT_CINDENT 5418 case PV_CIN: return (char_u *)&(curbuf->b_p_cin); 5419 case PV_CINK: return (char_u *)&(curbuf->b_p_cink); 5420 case PV_CINO: return (char_u *)&(curbuf->b_p_cino); 5421 #endif 5422 #if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT) 5423 case PV_CINW: return (char_u *)&(curbuf->b_p_cinw); 5424 #endif 5425 case PV_COM: return (char_u *)&(curbuf->b_p_com); 5426 #ifdef FEAT_FOLDING 5427 case PV_CMS: return (char_u *)&(curbuf->b_p_cms); 5428 #endif 5429 case PV_CPT: return (char_u *)&(curbuf->b_p_cpt); 5430 #ifdef BACKSLASH_IN_FILENAME 5431 case PV_CSL: return (char_u *)&(curbuf->b_p_csl); 5432 #endif 5433 #ifdef FEAT_COMPL_FUNC 5434 case PV_CFU: return (char_u *)&(curbuf->b_p_cfu); 5435 case PV_OFU: return (char_u *)&(curbuf->b_p_ofu); 5436 #endif 5437 #ifdef FEAT_EVAL 5438 case PV_TFU: return (char_u *)&(curbuf->b_p_tfu); 5439 #endif 5440 case PV_EOL: return (char_u *)&(curbuf->b_p_eol); 5441 case PV_FIXEOL: return (char_u *)&(curbuf->b_p_fixeol); 5442 case PV_ET: return (char_u *)&(curbuf->b_p_et); 5443 case PV_FENC: return (char_u *)&(curbuf->b_p_fenc); 5444 case PV_FF: return (char_u *)&(curbuf->b_p_ff); 5445 case PV_FT: return (char_u *)&(curbuf->b_p_ft); 5446 case PV_FO: return (char_u *)&(curbuf->b_p_fo); 5447 case PV_FLP: return (char_u *)&(curbuf->b_p_flp); 5448 case PV_IMI: return (char_u *)&(curbuf->b_p_iminsert); 5449 case PV_IMS: return (char_u *)&(curbuf->b_p_imsearch); 5450 case PV_INF: return (char_u *)&(curbuf->b_p_inf); 5451 case PV_ISK: return (char_u *)&(curbuf->b_p_isk); 5452 #ifdef FEAT_FIND_ID 5453 # ifdef FEAT_EVAL 5454 case PV_INEX: return (char_u *)&(curbuf->b_p_inex); 5455 # endif 5456 #endif 5457 #if defined(FEAT_CINDENT) && defined(FEAT_EVAL) 5458 case PV_INDE: return (char_u *)&(curbuf->b_p_inde); 5459 case PV_INDK: return (char_u *)&(curbuf->b_p_indk); 5460 #endif 5461 #ifdef FEAT_EVAL 5462 case PV_FEX: return (char_u *)&(curbuf->b_p_fex); 5463 #endif 5464 #ifdef FEAT_CRYPT 5465 case PV_KEY: return (char_u *)&(curbuf->b_p_key); 5466 #endif 5467 #ifdef FEAT_LISP 5468 case PV_LISP: return (char_u *)&(curbuf->b_p_lisp); 5469 #endif 5470 case PV_ML: return (char_u *)&(curbuf->b_p_ml); 5471 case PV_MPS: return (char_u *)&(curbuf->b_p_mps); 5472 case PV_MA: return (char_u *)&(curbuf->b_p_ma); 5473 case PV_MOD: return (char_u *)&(curbuf->b_changed); 5474 case PV_NF: return (char_u *)&(curbuf->b_p_nf); 5475 case PV_PI: return (char_u *)&(curbuf->b_p_pi); 5476 #ifdef FEAT_TEXTOBJ 5477 case PV_QE: return (char_u *)&(curbuf->b_p_qe); 5478 #endif 5479 case PV_RO: return (char_u *)&(curbuf->b_p_ro); 5480 #ifdef FEAT_SMARTINDENT 5481 case PV_SI: return (char_u *)&(curbuf->b_p_si); 5482 #endif 5483 case PV_SN: return (char_u *)&(curbuf->b_p_sn); 5484 case PV_STS: return (char_u *)&(curbuf->b_p_sts); 5485 #ifdef FEAT_SEARCHPATH 5486 case PV_SUA: return (char_u *)&(curbuf->b_p_sua); 5487 #endif 5488 case PV_SWF: return (char_u *)&(curbuf->b_p_swf); 5489 #ifdef FEAT_SYN_HL 5490 case PV_SMC: return (char_u *)&(curbuf->b_p_smc); 5491 case PV_SYN: return (char_u *)&(curbuf->b_p_syn); 5492 #endif 5493 #ifdef FEAT_SPELL 5494 case PV_SPC: return (char_u *)&(curwin->w_s->b_p_spc); 5495 case PV_SPF: return (char_u *)&(curwin->w_s->b_p_spf); 5496 case PV_SPL: return (char_u *)&(curwin->w_s->b_p_spl); 5497 case PV_SPO: return (char_u *)&(curwin->w_s->b_p_spo); 5498 #endif 5499 case PV_SW: return (char_u *)&(curbuf->b_p_sw); 5500 case PV_TS: return (char_u *)&(curbuf->b_p_ts); 5501 case PV_TW: return (char_u *)&(curbuf->b_p_tw); 5502 case PV_TX: return (char_u *)&(curbuf->b_p_tx); 5503 #ifdef FEAT_PERSISTENT_UNDO 5504 case PV_UDF: return (char_u *)&(curbuf->b_p_udf); 5505 #endif 5506 case PV_WM: return (char_u *)&(curbuf->b_p_wm); 5507 #ifdef FEAT_KEYMAP 5508 case PV_KMAP: return (char_u *)&(curbuf->b_p_keymap); 5509 #endif 5510 #ifdef FEAT_SIGNS 5511 case PV_SCL: return (char_u *)&(curwin->w_p_scl); 5512 #endif 5513 #ifdef FEAT_VARTABS 5514 case PV_VSTS: return (char_u *)&(curbuf->b_p_vsts); 5515 case PV_VTS: return (char_u *)&(curbuf->b_p_vts); 5516 #endif 5517 default: iemsg(_("E356: get_varp ERROR")); 5518 } 5519 // always return a valid pointer to avoid a crash! 5520 return (char_u *)&(curbuf->b_p_wm); 5521 } 5522 5523 /* 5524 * Return a pointer to the variable for option at 'opt_idx' 5525 */ 5526 char_u * 5527 get_option_var(int opt_idx) 5528 { 5529 return options[opt_idx].var; 5530 } 5531 5532 /* 5533 * Return the full name of the option at 'opt_idx' 5534 */ 5535 char_u * 5536 get_option_fullname(int opt_idx) 5537 { 5538 return (char_u *)options[opt_idx].fullname; 5539 } 5540 5541 /* 5542 * Get the value of 'equalprg', either the buffer-local one or the global one. 5543 */ 5544 char_u * 5545 get_equalprg(void) 5546 { 5547 if (*curbuf->b_p_ep == NUL) 5548 return p_ep; 5549 return curbuf->b_p_ep; 5550 } 5551 5552 /* 5553 * Copy options from one window to another. 5554 * Used when splitting a window. 5555 */ 5556 void 5557 win_copy_options(win_T *wp_from, win_T *wp_to) 5558 { 5559 copy_winopt(&wp_from->w_onebuf_opt, &wp_to->w_onebuf_opt); 5560 copy_winopt(&wp_from->w_allbuf_opt, &wp_to->w_allbuf_opt); 5561 after_copy_winopt(wp_to); 5562 } 5563 5564 /* 5565 * After copying window options: update variables depending on options. 5566 */ 5567 void 5568 after_copy_winopt(win_T *wp UNUSED) 5569 { 5570 #ifdef FEAT_LINEBREAK 5571 briopt_check(wp); 5572 #endif 5573 #ifdef FEAT_SYN_HL 5574 fill_culopt_flags(NULL, wp); 5575 check_colorcolumn(wp); 5576 #endif 5577 set_chars_option(wp, &wp->w_p_lcs); 5578 } 5579 5580 /* 5581 * Copy the options from one winopt_T to another. 5582 * Doesn't free the old option values in "to", use clear_winopt() for that. 5583 * The 'scroll' option is not copied, because it depends on the window height. 5584 * The 'previewwindow' option is reset, there can be only one preview window. 5585 */ 5586 void 5587 copy_winopt(winopt_T *from, winopt_T *to) 5588 { 5589 #ifdef FEAT_ARABIC 5590 to->wo_arab = from->wo_arab; 5591 #endif 5592 to->wo_list = from->wo_list; 5593 to->wo_lcs = vim_strsave(from->wo_lcs); 5594 to->wo_nu = from->wo_nu; 5595 to->wo_rnu = from->wo_rnu; 5596 to->wo_ve = vim_strsave(from->wo_ve); 5597 to->wo_ve_flags = from->wo_ve_flags; 5598 #ifdef FEAT_LINEBREAK 5599 to->wo_nuw = from->wo_nuw; 5600 #endif 5601 #ifdef FEAT_RIGHTLEFT 5602 to->wo_rl = from->wo_rl; 5603 to->wo_rlc = vim_strsave(from->wo_rlc); 5604 #endif 5605 #ifdef FEAT_LINEBREAK 5606 to->wo_sbr = vim_strsave(from->wo_sbr); 5607 #endif 5608 #ifdef FEAT_STL_OPT 5609 to->wo_stl = vim_strsave(from->wo_stl); 5610 #endif 5611 to->wo_wrap = from->wo_wrap; 5612 #ifdef FEAT_DIFF 5613 to->wo_wrap_save = from->wo_wrap_save; 5614 #endif 5615 #ifdef FEAT_LINEBREAK 5616 to->wo_lbr = from->wo_lbr; 5617 to->wo_bri = from->wo_bri; 5618 to->wo_briopt = vim_strsave(from->wo_briopt); 5619 #endif 5620 to->wo_wcr = vim_strsave(from->wo_wcr); 5621 to->wo_scb = from->wo_scb; 5622 to->wo_scb_save = from->wo_scb_save; 5623 to->wo_crb = from->wo_crb; 5624 to->wo_crb_save = from->wo_crb_save; 5625 #ifdef FEAT_SPELL 5626 to->wo_spell = from->wo_spell; 5627 #endif 5628 #ifdef FEAT_SYN_HL 5629 to->wo_cuc = from->wo_cuc; 5630 to->wo_cul = from->wo_cul; 5631 to->wo_culopt = vim_strsave(from->wo_culopt); 5632 to->wo_cc = vim_strsave(from->wo_cc); 5633 #endif 5634 #ifdef FEAT_DIFF 5635 to->wo_diff = from->wo_diff; 5636 to->wo_diff_saved = from->wo_diff_saved; 5637 #endif 5638 #ifdef FEAT_CONCEAL 5639 to->wo_cocu = vim_strsave(from->wo_cocu); 5640 to->wo_cole = from->wo_cole; 5641 #endif 5642 #ifdef FEAT_TERMINAL 5643 to->wo_twk = vim_strsave(from->wo_twk); 5644 to->wo_tws = vim_strsave(from->wo_tws); 5645 #endif 5646 #ifdef FEAT_FOLDING 5647 to->wo_fdc = from->wo_fdc; 5648 to->wo_fdc_save = from->wo_fdc_save; 5649 to->wo_fen = from->wo_fen; 5650 to->wo_fen_save = from->wo_fen_save; 5651 to->wo_fdi = vim_strsave(from->wo_fdi); 5652 to->wo_fml = from->wo_fml; 5653 to->wo_fdl = from->wo_fdl; 5654 to->wo_fdl_save = from->wo_fdl_save; 5655 to->wo_fdm = vim_strsave(from->wo_fdm); 5656 to->wo_fdm_save = from->wo_diff_saved 5657 ? vim_strsave(from->wo_fdm_save) : empty_option; 5658 to->wo_fdn = from->wo_fdn; 5659 # ifdef FEAT_EVAL 5660 to->wo_fde = vim_strsave(from->wo_fde); 5661 to->wo_fdt = vim_strsave(from->wo_fdt); 5662 # endif 5663 to->wo_fmr = vim_strsave(from->wo_fmr); 5664 #endif 5665 #ifdef FEAT_SIGNS 5666 to->wo_scl = vim_strsave(from->wo_scl); 5667 #endif 5668 5669 #ifdef FEAT_EVAL 5670 // Copy the script context so that we know where the value was last set. 5671 mch_memmove(to->wo_script_ctx, from->wo_script_ctx, 5672 sizeof(to->wo_script_ctx)); 5673 #endif 5674 check_winopt(to); // don't want NULL pointers 5675 } 5676 5677 /* 5678 * Check string options in a window for a NULL value. 5679 */ 5680 static void 5681 check_win_options(win_T *win) 5682 { 5683 check_winopt(&win->w_onebuf_opt); 5684 check_winopt(&win->w_allbuf_opt); 5685 } 5686 5687 /* 5688 * Check for NULL pointers in a winopt_T and replace them with empty_option. 5689 */ 5690 static void 5691 check_winopt(winopt_T *wop UNUSED) 5692 { 5693 #ifdef FEAT_FOLDING 5694 check_string_option(&wop->wo_fdi); 5695 check_string_option(&wop->wo_fdm); 5696 check_string_option(&wop->wo_fdm_save); 5697 # ifdef FEAT_EVAL 5698 check_string_option(&wop->wo_fde); 5699 check_string_option(&wop->wo_fdt); 5700 # endif 5701 check_string_option(&wop->wo_fmr); 5702 #endif 5703 #ifdef FEAT_SIGNS 5704 check_string_option(&wop->wo_scl); 5705 #endif 5706 #ifdef FEAT_RIGHTLEFT 5707 check_string_option(&wop->wo_rlc); 5708 #endif 5709 #ifdef FEAT_LINEBREAK 5710 check_string_option(&wop->wo_sbr); 5711 #endif 5712 #ifdef FEAT_STL_OPT 5713 check_string_option(&wop->wo_stl); 5714 #endif 5715 #ifdef FEAT_SYN_HL 5716 check_string_option(&wop->wo_culopt); 5717 check_string_option(&wop->wo_cc); 5718 #endif 5719 #ifdef FEAT_CONCEAL 5720 check_string_option(&wop->wo_cocu); 5721 #endif 5722 #ifdef FEAT_TERMINAL 5723 check_string_option(&wop->wo_twk); 5724 check_string_option(&wop->wo_tws); 5725 #endif 5726 #ifdef FEAT_LINEBREAK 5727 check_string_option(&wop->wo_briopt); 5728 #endif 5729 check_string_option(&wop->wo_wcr); 5730 check_string_option(&wop->wo_lcs); 5731 check_string_option(&wop->wo_ve); 5732 } 5733 5734 /* 5735 * Free the allocated memory inside a winopt_T. 5736 */ 5737 void 5738 clear_winopt(winopt_T *wop UNUSED) 5739 { 5740 #ifdef FEAT_FOLDING 5741 clear_string_option(&wop->wo_fdi); 5742 clear_string_option(&wop->wo_fdm); 5743 clear_string_option(&wop->wo_fdm_save); 5744 # ifdef FEAT_EVAL 5745 clear_string_option(&wop->wo_fde); 5746 clear_string_option(&wop->wo_fdt); 5747 # endif 5748 clear_string_option(&wop->wo_fmr); 5749 #endif 5750 #ifdef FEAT_SIGNS 5751 clear_string_option(&wop->wo_scl); 5752 #endif 5753 #ifdef FEAT_LINEBREAK 5754 clear_string_option(&wop->wo_briopt); 5755 #endif 5756 clear_string_option(&wop->wo_wcr); 5757 #ifdef FEAT_RIGHTLEFT 5758 clear_string_option(&wop->wo_rlc); 5759 #endif 5760 #ifdef FEAT_LINEBREAK 5761 clear_string_option(&wop->wo_sbr); 5762 #endif 5763 #ifdef FEAT_STL_OPT 5764 clear_string_option(&wop->wo_stl); 5765 #endif 5766 #ifdef FEAT_SYN_HL 5767 clear_string_option(&wop->wo_culopt); 5768 clear_string_option(&wop->wo_cc); 5769 #endif 5770 #ifdef FEAT_CONCEAL 5771 clear_string_option(&wop->wo_cocu); 5772 #endif 5773 #ifdef FEAT_TERMINAL 5774 clear_string_option(&wop->wo_twk); 5775 clear_string_option(&wop->wo_tws); 5776 #endif 5777 clear_string_option(&wop->wo_lcs); 5778 clear_string_option(&wop->wo_ve); 5779 } 5780 5781 #ifdef FEAT_EVAL 5782 // Index into the options table for a buffer-local option enum. 5783 static int buf_opt_idx[BV_COUNT]; 5784 # define COPY_OPT_SCTX(buf, bv) buf->b_p_script_ctx[bv] = options[buf_opt_idx[bv]].script_ctx 5785 5786 /* 5787 * Initialize buf_opt_idx[] if not done already. 5788 */ 5789 static void 5790 init_buf_opt_idx(void) 5791 { 5792 static int did_init_buf_opt_idx = FALSE; 5793 int i; 5794 5795 if (did_init_buf_opt_idx) 5796 return; 5797 did_init_buf_opt_idx = TRUE; 5798 for (i = 0; !istermoption_idx(i); i++) 5799 if (options[i].indir & PV_BUF) 5800 buf_opt_idx[options[i].indir & PV_MASK] = i; 5801 } 5802 #else 5803 # define COPY_OPT_SCTX(buf, bv) 5804 #endif 5805 5806 /* 5807 * Copy global option values to local options for one buffer. 5808 * Used when creating a new buffer and sometimes when entering a buffer. 5809 * flags: 5810 * BCO_ENTER We will enter the buffer "buf". 5811 * BCO_ALWAYS Always copy the options, but only set b_p_initialized when 5812 * appropriate. 5813 * BCO_NOHELP Don't copy the values to a help buffer. 5814 */ 5815 void 5816 buf_copy_options(buf_T *buf, int flags) 5817 { 5818 int should_copy = TRUE; 5819 char_u *save_p_isk = NULL; // init for GCC 5820 int dont_do_help; 5821 int did_isk = FALSE; 5822 5823 /* 5824 * Skip this when the option defaults have not been set yet. Happens when 5825 * main() allocates the first buffer. 5826 */ 5827 if (p_cpo != NULL) 5828 { 5829 /* 5830 * Always copy when entering and 'cpo' contains 'S'. 5831 * Don't copy when already initialized. 5832 * Don't copy when 'cpo' contains 's' and not entering. 5833 * 'S' BCO_ENTER initialized 's' should_copy 5834 * yes yes X X TRUE 5835 * yes no yes X FALSE 5836 * no X yes X FALSE 5837 * X no no yes FALSE 5838 * X no no no TRUE 5839 * no yes no X TRUE 5840 */ 5841 if ((vim_strchr(p_cpo, CPO_BUFOPTGLOB) == NULL || !(flags & BCO_ENTER)) 5842 && (buf->b_p_initialized 5843 || (!(flags & BCO_ENTER) 5844 && vim_strchr(p_cpo, CPO_BUFOPT) != NULL))) 5845 should_copy = FALSE; 5846 5847 if (should_copy || (flags & BCO_ALWAYS)) 5848 { 5849 #ifdef FEAT_EVAL 5850 CLEAR_FIELD(buf->b_p_script_ctx); 5851 init_buf_opt_idx(); 5852 #endif 5853 // Don't copy the options specific to a help buffer when 5854 // BCO_NOHELP is given or the options were initialized already 5855 // (jumping back to a help file with CTRL-T or CTRL-O) 5856 dont_do_help = ((flags & BCO_NOHELP) && buf->b_help) 5857 || buf->b_p_initialized; 5858 if (dont_do_help) // don't free b_p_isk 5859 { 5860 save_p_isk = buf->b_p_isk; 5861 buf->b_p_isk = NULL; 5862 } 5863 /* 5864 * Always free the allocated strings. If not already initialized, 5865 * reset 'readonly' and copy 'fileformat'. 5866 */ 5867 if (!buf->b_p_initialized) 5868 { 5869 free_buf_options(buf, TRUE); 5870 buf->b_p_ro = FALSE; // don't copy readonly 5871 buf->b_p_tx = p_tx; 5872 buf->b_p_fenc = vim_strsave(p_fenc); 5873 switch (*p_ffs) 5874 { 5875 case 'm': 5876 buf->b_p_ff = vim_strsave((char_u *)FF_MAC); break; 5877 case 'd': 5878 buf->b_p_ff = vim_strsave((char_u *)FF_DOS); break; 5879 case 'u': 5880 buf->b_p_ff = vim_strsave((char_u *)FF_UNIX); break; 5881 default: 5882 buf->b_p_ff = vim_strsave(p_ff); 5883 } 5884 if (buf->b_p_ff != NULL) 5885 buf->b_start_ffc = *buf->b_p_ff; 5886 buf->b_p_bh = empty_option; 5887 buf->b_p_bt = empty_option; 5888 } 5889 else 5890 free_buf_options(buf, FALSE); 5891 5892 buf->b_p_ai = p_ai; 5893 COPY_OPT_SCTX(buf, BV_AI); 5894 buf->b_p_ai_nopaste = p_ai_nopaste; 5895 buf->b_p_sw = p_sw; 5896 COPY_OPT_SCTX(buf, BV_SW); 5897 buf->b_p_tw = p_tw; 5898 COPY_OPT_SCTX(buf, BV_TW); 5899 buf->b_p_tw_nopaste = p_tw_nopaste; 5900 buf->b_p_tw_nobin = p_tw_nobin; 5901 buf->b_p_wm = p_wm; 5902 COPY_OPT_SCTX(buf, BV_WM); 5903 buf->b_p_wm_nopaste = p_wm_nopaste; 5904 buf->b_p_wm_nobin = p_wm_nobin; 5905 buf->b_p_bin = p_bin; 5906 COPY_OPT_SCTX(buf, BV_BIN); 5907 buf->b_p_bomb = p_bomb; 5908 COPY_OPT_SCTX(buf, BV_BOMB); 5909 buf->b_p_fixeol = p_fixeol; 5910 COPY_OPT_SCTX(buf, BV_FIXEOL); 5911 buf->b_p_et = p_et; 5912 COPY_OPT_SCTX(buf, BV_ET); 5913 buf->b_p_et_nobin = p_et_nobin; 5914 buf->b_p_et_nopaste = p_et_nopaste; 5915 buf->b_p_ml = p_ml; 5916 COPY_OPT_SCTX(buf, BV_ML); 5917 buf->b_p_ml_nobin = p_ml_nobin; 5918 buf->b_p_inf = p_inf; 5919 COPY_OPT_SCTX(buf, BV_INF); 5920 if (cmdmod.cmod_flags & CMOD_NOSWAPFILE) 5921 buf->b_p_swf = FALSE; 5922 else 5923 { 5924 buf->b_p_swf = p_swf; 5925 COPY_OPT_SCTX(buf, BV_INF); 5926 } 5927 buf->b_p_cpt = vim_strsave(p_cpt); 5928 COPY_OPT_SCTX(buf, BV_CPT); 5929 #ifdef BACKSLASH_IN_FILENAME 5930 buf->b_p_csl = vim_strsave(p_csl); 5931 COPY_OPT_SCTX(buf, BV_CSL); 5932 #endif 5933 #ifdef FEAT_COMPL_FUNC 5934 buf->b_p_cfu = vim_strsave(p_cfu); 5935 COPY_OPT_SCTX(buf, BV_CFU); 5936 buf->b_p_ofu = vim_strsave(p_ofu); 5937 COPY_OPT_SCTX(buf, BV_OFU); 5938 #endif 5939 #ifdef FEAT_EVAL 5940 buf->b_p_tfu = vim_strsave(p_tfu); 5941 COPY_OPT_SCTX(buf, BV_TFU); 5942 #endif 5943 buf->b_p_sts = p_sts; 5944 COPY_OPT_SCTX(buf, BV_STS); 5945 buf->b_p_sts_nopaste = p_sts_nopaste; 5946 #ifdef FEAT_VARTABS 5947 buf->b_p_vsts = vim_strsave(p_vsts); 5948 COPY_OPT_SCTX(buf, BV_VSTS); 5949 if (p_vsts && p_vsts != empty_option) 5950 (void)tabstop_set(p_vsts, &buf->b_p_vsts_array); 5951 else 5952 buf->b_p_vsts_array = 0; 5953 buf->b_p_vsts_nopaste = p_vsts_nopaste 5954 ? vim_strsave(p_vsts_nopaste) : NULL; 5955 #endif 5956 buf->b_p_sn = p_sn; 5957 COPY_OPT_SCTX(buf, BV_SN); 5958 buf->b_p_com = vim_strsave(p_com); 5959 COPY_OPT_SCTX(buf, BV_COM); 5960 #ifdef FEAT_FOLDING 5961 buf->b_p_cms = vim_strsave(p_cms); 5962 COPY_OPT_SCTX(buf, BV_CMS); 5963 #endif 5964 buf->b_p_fo = vim_strsave(p_fo); 5965 COPY_OPT_SCTX(buf, BV_FO); 5966 buf->b_p_flp = vim_strsave(p_flp); 5967 COPY_OPT_SCTX(buf, BV_FLP); 5968 // NOTE: Valgrind may report a bogus memory leak for 'nrformats' 5969 // when it is set to 8 bytes in defaults.vim. 5970 buf->b_p_nf = vim_strsave(p_nf); 5971 COPY_OPT_SCTX(buf, BV_NF); 5972 buf->b_p_mps = vim_strsave(p_mps); 5973 COPY_OPT_SCTX(buf, BV_MPS); 5974 #ifdef FEAT_SMARTINDENT 5975 buf->b_p_si = p_si; 5976 COPY_OPT_SCTX(buf, BV_SI); 5977 #endif 5978 buf->b_p_ci = p_ci; 5979 COPY_OPT_SCTX(buf, BV_CI); 5980 #ifdef FEAT_CINDENT 5981 buf->b_p_cin = p_cin; 5982 COPY_OPT_SCTX(buf, BV_CIN); 5983 buf->b_p_cink = vim_strsave(p_cink); 5984 COPY_OPT_SCTX(buf, BV_CINK); 5985 buf->b_p_cino = vim_strsave(p_cino); 5986 COPY_OPT_SCTX(buf, BV_CINO); 5987 #endif 5988 // Don't copy 'filetype', it must be detected 5989 buf->b_p_ft = empty_option; 5990 buf->b_p_pi = p_pi; 5991 COPY_OPT_SCTX(buf, BV_PI); 5992 #if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT) 5993 buf->b_p_cinw = vim_strsave(p_cinw); 5994 COPY_OPT_SCTX(buf, BV_CINW); 5995 #endif 5996 #ifdef FEAT_LISP 5997 buf->b_p_lisp = p_lisp; 5998 COPY_OPT_SCTX(buf, BV_LISP); 5999 #endif 6000 #ifdef FEAT_SYN_HL 6001 // Don't copy 'syntax', it must be set 6002 buf->b_p_syn = empty_option; 6003 buf->b_p_smc = p_smc; 6004 COPY_OPT_SCTX(buf, BV_SMC); 6005 buf->b_s.b_syn_isk = empty_option; 6006 #endif 6007 #ifdef FEAT_SPELL 6008 buf->b_s.b_p_spc = vim_strsave(p_spc); 6009 COPY_OPT_SCTX(buf, BV_SPC); 6010 (void)compile_cap_prog(&buf->b_s); 6011 buf->b_s.b_p_spf = vim_strsave(p_spf); 6012 COPY_OPT_SCTX(buf, BV_SPF); 6013 buf->b_s.b_p_spl = vim_strsave(p_spl); 6014 COPY_OPT_SCTX(buf, BV_SPL); 6015 buf->b_s.b_p_spo = vim_strsave(p_spo); 6016 COPY_OPT_SCTX(buf, BV_SPO); 6017 #endif 6018 #if defined(FEAT_CINDENT) && defined(FEAT_EVAL) 6019 buf->b_p_inde = vim_strsave(p_inde); 6020 COPY_OPT_SCTX(buf, BV_INDE); 6021 buf->b_p_indk = vim_strsave(p_indk); 6022 COPY_OPT_SCTX(buf, BV_INDK); 6023 #endif 6024 buf->b_p_fp = empty_option; 6025 #if defined(FEAT_EVAL) 6026 buf->b_p_fex = vim_strsave(p_fex); 6027 COPY_OPT_SCTX(buf, BV_FEX); 6028 #endif 6029 #ifdef FEAT_CRYPT 6030 buf->b_p_key = vim_strsave(p_key); 6031 COPY_OPT_SCTX(buf, BV_KEY); 6032 #endif 6033 #ifdef FEAT_SEARCHPATH 6034 buf->b_p_sua = vim_strsave(p_sua); 6035 COPY_OPT_SCTX(buf, BV_SUA); 6036 #endif 6037 #ifdef FEAT_KEYMAP 6038 buf->b_p_keymap = vim_strsave(p_keymap); 6039 COPY_OPT_SCTX(buf, BV_KMAP); 6040 buf->b_kmap_state |= KEYMAP_INIT; 6041 #endif 6042 #ifdef FEAT_TERMINAL 6043 buf->b_p_twsl = p_twsl; 6044 COPY_OPT_SCTX(buf, BV_TWSL); 6045 #endif 6046 // This isn't really an option, but copying the langmap and IME 6047 // state from the current buffer is better than resetting it. 6048 buf->b_p_iminsert = p_iminsert; 6049 COPY_OPT_SCTX(buf, BV_IMI); 6050 buf->b_p_imsearch = p_imsearch; 6051 COPY_OPT_SCTX(buf, BV_IMS); 6052 6053 // options that are normally global but also have a local value 6054 // are not copied, start using the global value 6055 buf->b_p_ar = -1; 6056 buf->b_p_ul = NO_LOCAL_UNDOLEVEL; 6057 buf->b_p_bkc = empty_option; 6058 buf->b_bkc_flags = 0; 6059 #ifdef FEAT_QUICKFIX 6060 buf->b_p_gp = empty_option; 6061 buf->b_p_mp = empty_option; 6062 buf->b_p_efm = empty_option; 6063 #endif 6064 buf->b_p_ep = empty_option; 6065 buf->b_p_kp = empty_option; 6066 buf->b_p_path = empty_option; 6067 buf->b_p_tags = empty_option; 6068 buf->b_p_tc = empty_option; 6069 buf->b_tc_flags = 0; 6070 #ifdef FEAT_FIND_ID 6071 buf->b_p_def = empty_option; 6072 buf->b_p_inc = empty_option; 6073 # ifdef FEAT_EVAL 6074 buf->b_p_inex = vim_strsave(p_inex); 6075 COPY_OPT_SCTX(buf, BV_INEX); 6076 # endif 6077 #endif 6078 buf->b_p_dict = empty_option; 6079 buf->b_p_tsr = empty_option; 6080 #ifdef FEAT_TEXTOBJ 6081 buf->b_p_qe = vim_strsave(p_qe); 6082 COPY_OPT_SCTX(buf, BV_QE); 6083 #endif 6084 #if defined(FEAT_BEVAL) && defined(FEAT_EVAL) 6085 buf->b_p_bexpr = empty_option; 6086 #endif 6087 #if defined(FEAT_CRYPT) 6088 buf->b_p_cm = empty_option; 6089 #endif 6090 #ifdef FEAT_PERSISTENT_UNDO 6091 buf->b_p_udf = p_udf; 6092 COPY_OPT_SCTX(buf, BV_UDF); 6093 #endif 6094 #ifdef FEAT_LISP 6095 buf->b_p_lw = empty_option; 6096 #endif 6097 buf->b_p_menc = empty_option; 6098 6099 /* 6100 * Don't copy the options set by ex_help(), use the saved values, 6101 * when going from a help buffer to a non-help buffer. 6102 * Don't touch these at all when BCO_NOHELP is used and going from 6103 * or to a help buffer. 6104 */ 6105 if (dont_do_help) 6106 { 6107 buf->b_p_isk = save_p_isk; 6108 #ifdef FEAT_VARTABS 6109 if (p_vts && p_vts != empty_option && !buf->b_p_vts_array) 6110 (void)tabstop_set(p_vts, &buf->b_p_vts_array); 6111 else 6112 buf->b_p_vts_array = NULL; 6113 #endif 6114 } 6115 else 6116 { 6117 buf->b_p_isk = vim_strsave(p_isk); 6118 COPY_OPT_SCTX(buf, BV_ISK); 6119 did_isk = TRUE; 6120 buf->b_p_ts = p_ts; 6121 #ifdef FEAT_VARTABS 6122 buf->b_p_vts = vim_strsave(p_vts); 6123 COPY_OPT_SCTX(buf, BV_VTS); 6124 if (p_vts && p_vts != empty_option && !buf->b_p_vts_array) 6125 (void)tabstop_set(p_vts, &buf->b_p_vts_array); 6126 else 6127 buf->b_p_vts_array = NULL; 6128 #endif 6129 buf->b_help = FALSE; 6130 if (buf->b_p_bt[0] == 'h') 6131 clear_string_option(&buf->b_p_bt); 6132 buf->b_p_ma = p_ma; 6133 COPY_OPT_SCTX(buf, BV_MA); 6134 } 6135 } 6136 6137 /* 6138 * When the options should be copied (ignoring BCO_ALWAYS), set the 6139 * flag that indicates that the options have been initialized. 6140 */ 6141 if (should_copy) 6142 buf->b_p_initialized = TRUE; 6143 } 6144 6145 check_buf_options(buf); // make sure we don't have NULLs 6146 if (did_isk) 6147 (void)buf_init_chartab(buf, FALSE); 6148 } 6149 6150 /* 6151 * Reset the 'modifiable' option and its default value. 6152 */ 6153 void 6154 reset_modifiable(void) 6155 { 6156 int opt_idx; 6157 6158 curbuf->b_p_ma = FALSE; 6159 p_ma = FALSE; 6160 opt_idx = findoption((char_u *)"ma"); 6161 if (opt_idx >= 0) 6162 options[opt_idx].def_val[VI_DEFAULT] = FALSE; 6163 } 6164 6165 /* 6166 * Set the global value for 'iminsert' to the local value. 6167 */ 6168 void 6169 set_iminsert_global(void) 6170 { 6171 p_iminsert = curbuf->b_p_iminsert; 6172 } 6173 6174 /* 6175 * Set the global value for 'imsearch' to the local value. 6176 */ 6177 void 6178 set_imsearch_global(void) 6179 { 6180 p_imsearch = curbuf->b_p_imsearch; 6181 } 6182 6183 static int expand_option_idx = -1; 6184 static char_u expand_option_name[5] = {'t', '_', NUL, NUL, NUL}; 6185 static int expand_option_flags = 0; 6186 6187 void 6188 set_context_in_set_cmd( 6189 expand_T *xp, 6190 char_u *arg, 6191 int opt_flags) // OPT_GLOBAL and/or OPT_LOCAL 6192 { 6193 int nextchar; 6194 long_u flags = 0; // init for GCC 6195 int opt_idx = 0; // init for GCC 6196 char_u *p; 6197 char_u *s; 6198 int is_term_option = FALSE; 6199 int key; 6200 6201 expand_option_flags = opt_flags; 6202 6203 xp->xp_context = EXPAND_SETTINGS; 6204 if (*arg == NUL) 6205 { 6206 xp->xp_pattern = arg; 6207 return; 6208 } 6209 p = arg + STRLEN(arg) - 1; 6210 if (*p == ' ' && *(p - 1) != '\\') 6211 { 6212 xp->xp_pattern = p + 1; 6213 return; 6214 } 6215 while (p > arg) 6216 { 6217 s = p; 6218 // count number of backslashes before ' ' or ',' 6219 if (*p == ' ' || *p == ',') 6220 { 6221 while (s > arg && *(s - 1) == '\\') 6222 --s; 6223 } 6224 // break at a space with an even number of backslashes 6225 if (*p == ' ' && ((p - s) & 1) == 0) 6226 { 6227 ++p; 6228 break; 6229 } 6230 --p; 6231 } 6232 if (STRNCMP(p, "no", 2) == 0 && STRNCMP(p, "novice", 6) != 0) 6233 { 6234 xp->xp_context = EXPAND_BOOL_SETTINGS; 6235 p += 2; 6236 } 6237 if (STRNCMP(p, "inv", 3) == 0) 6238 { 6239 xp->xp_context = EXPAND_BOOL_SETTINGS; 6240 p += 3; 6241 } 6242 xp->xp_pattern = arg = p; 6243 if (*arg == '<') 6244 { 6245 while (*p != '>') 6246 if (*p++ == NUL) // expand terminal option name 6247 return; 6248 key = get_special_key_code(arg + 1); 6249 if (key == 0) // unknown name 6250 { 6251 xp->xp_context = EXPAND_NOTHING; 6252 return; 6253 } 6254 nextchar = *++p; 6255 is_term_option = TRUE; 6256 expand_option_name[2] = KEY2TERMCAP0(key); 6257 expand_option_name[3] = KEY2TERMCAP1(key); 6258 } 6259 else 6260 { 6261 if (p[0] == 't' && p[1] == '_') 6262 { 6263 p += 2; 6264 if (*p != NUL) 6265 ++p; 6266 if (*p == NUL) 6267 return; // expand option name 6268 nextchar = *++p; 6269 is_term_option = TRUE; 6270 expand_option_name[2] = p[-2]; 6271 expand_option_name[3] = p[-1]; 6272 } 6273 else 6274 { 6275 // Allow * wildcard 6276 while (ASCII_ISALNUM(*p) || *p == '_' || *p == '*') 6277 p++; 6278 if (*p == NUL) 6279 return; 6280 nextchar = *p; 6281 *p = NUL; 6282 opt_idx = findoption(arg); 6283 *p = nextchar; 6284 if (opt_idx == -1 || options[opt_idx].var == NULL) 6285 { 6286 xp->xp_context = EXPAND_NOTHING; 6287 return; 6288 } 6289 flags = options[opt_idx].flags; 6290 if (flags & P_BOOL) 6291 { 6292 xp->xp_context = EXPAND_NOTHING; 6293 return; 6294 } 6295 } 6296 } 6297 // handle "-=" and "+=" 6298 if ((nextchar == '-' || nextchar == '+' || nextchar == '^') && p[1] == '=') 6299 { 6300 ++p; 6301 nextchar = '='; 6302 } 6303 if ((nextchar != '=' && nextchar != ':') 6304 || xp->xp_context == EXPAND_BOOL_SETTINGS) 6305 { 6306 xp->xp_context = EXPAND_UNSUCCESSFUL; 6307 return; 6308 } 6309 if (xp->xp_context != EXPAND_BOOL_SETTINGS && p[1] == NUL) 6310 { 6311 xp->xp_context = EXPAND_OLD_SETTING; 6312 if (is_term_option) 6313 expand_option_idx = -1; 6314 else 6315 expand_option_idx = opt_idx; 6316 xp->xp_pattern = p + 1; 6317 return; 6318 } 6319 xp->xp_context = EXPAND_NOTHING; 6320 if (is_term_option || (flags & P_NUM)) 6321 return; 6322 6323 xp->xp_pattern = p + 1; 6324 6325 if (flags & P_EXPAND) 6326 { 6327 p = options[opt_idx].var; 6328 if (p == (char_u *)&p_bdir 6329 || p == (char_u *)&p_dir 6330 || p == (char_u *)&p_path 6331 || p == (char_u *)&p_pp 6332 || p == (char_u *)&p_rtp 6333 #ifdef FEAT_SEARCHPATH 6334 || p == (char_u *)&p_cdpath 6335 #endif 6336 #ifdef FEAT_SESSION 6337 || p == (char_u *)&p_vdir 6338 #endif 6339 ) 6340 { 6341 xp->xp_context = EXPAND_DIRECTORIES; 6342 if (p == (char_u *)&p_path 6343 #ifdef FEAT_SEARCHPATH 6344 || p == (char_u *)&p_cdpath 6345 #endif 6346 ) 6347 xp->xp_backslash = XP_BS_THREE; 6348 else 6349 xp->xp_backslash = XP_BS_ONE; 6350 } 6351 else if (p == (char_u *)&p_ft) 6352 { 6353 xp->xp_context = EXPAND_FILETYPE; 6354 } 6355 else 6356 { 6357 xp->xp_context = EXPAND_FILES; 6358 // for 'tags' need three backslashes for a space 6359 if (p == (char_u *)&p_tags) 6360 xp->xp_backslash = XP_BS_THREE; 6361 else 6362 xp->xp_backslash = XP_BS_ONE; 6363 } 6364 } 6365 6366 // For an option that is a list of file names, find the start of the 6367 // last file name. 6368 for (p = arg + STRLEN(arg) - 1; p > xp->xp_pattern; --p) 6369 { 6370 // count number of backslashes before ' ' or ',' 6371 if (*p == ' ' || *p == ',') 6372 { 6373 s = p; 6374 while (s > xp->xp_pattern && *(s - 1) == '\\') 6375 --s; 6376 if ((*p == ' ' && (xp->xp_backslash == XP_BS_THREE && (p - s) < 3)) 6377 || (*p == ',' && (flags & P_COMMA) && ((p - s) & 1) == 0)) 6378 { 6379 xp->xp_pattern = p + 1; 6380 break; 6381 } 6382 } 6383 6384 #ifdef FEAT_SPELL 6385 // for 'spellsuggest' start at "file:" 6386 if (options[opt_idx].var == (char_u *)&p_sps 6387 && STRNCMP(p, "file:", 5) == 0) 6388 { 6389 xp->xp_pattern = p + 5; 6390 break; 6391 } 6392 #endif 6393 } 6394 6395 return; 6396 } 6397 6398 int 6399 ExpandSettings( 6400 expand_T *xp, 6401 regmatch_T *regmatch, 6402 int *num_file, 6403 char_u ***file) 6404 { 6405 int num_normal = 0; // Nr of matching non-term-code settings 6406 int num_term = 0; // Nr of matching terminal code settings 6407 int opt_idx; 6408 int match; 6409 int count = 0; 6410 char_u *str; 6411 int loop; 6412 int is_term_opt; 6413 char_u name_buf[MAX_KEY_NAME_LEN]; 6414 static char *(names[]) = {"all", "termcap"}; 6415 int ic = regmatch->rm_ic; // remember the ignore-case flag 6416 6417 // do this loop twice: 6418 // loop == 0: count the number of matching options 6419 // loop == 1: copy the matching options into allocated memory 6420 for (loop = 0; loop <= 1; ++loop) 6421 { 6422 regmatch->rm_ic = ic; 6423 if (xp->xp_context != EXPAND_BOOL_SETTINGS) 6424 { 6425 for (match = 0; match < (int)ARRAY_LENGTH(names); ++match) 6426 if (vim_regexec(regmatch, (char_u *)names[match], (colnr_T)0)) 6427 { 6428 if (loop == 0) 6429 num_normal++; 6430 else 6431 (*file)[count++] = vim_strsave((char_u *)names[match]); 6432 } 6433 } 6434 for (opt_idx = 0; (str = (char_u *)options[opt_idx].fullname) != NULL; 6435 opt_idx++) 6436 { 6437 if (options[opt_idx].var == NULL) 6438 continue; 6439 if (xp->xp_context == EXPAND_BOOL_SETTINGS 6440 && !(options[opt_idx].flags & P_BOOL)) 6441 continue; 6442 is_term_opt = istermoption_idx(opt_idx); 6443 if (is_term_opt && num_normal > 0) 6444 continue; 6445 match = FALSE; 6446 if (vim_regexec(regmatch, str, (colnr_T)0) 6447 || (options[opt_idx].shortname != NULL 6448 && vim_regexec(regmatch, 6449 (char_u *)options[opt_idx].shortname, (colnr_T)0))) 6450 match = TRUE; 6451 else if (is_term_opt) 6452 { 6453 name_buf[0] = '<'; 6454 name_buf[1] = 't'; 6455 name_buf[2] = '_'; 6456 name_buf[3] = str[2]; 6457 name_buf[4] = str[3]; 6458 name_buf[5] = '>'; 6459 name_buf[6] = NUL; 6460 if (vim_regexec(regmatch, name_buf, (colnr_T)0)) 6461 { 6462 match = TRUE; 6463 str = name_buf; 6464 } 6465 } 6466 if (match) 6467 { 6468 if (loop == 0) 6469 { 6470 if (is_term_opt) 6471 num_term++; 6472 else 6473 num_normal++; 6474 } 6475 else 6476 (*file)[count++] = vim_strsave(str); 6477 } 6478 } 6479 /* 6480 * Check terminal key codes, these are not in the option table 6481 */ 6482 if (xp->xp_context != EXPAND_BOOL_SETTINGS && num_normal == 0) 6483 { 6484 for (opt_idx = 0; (str = get_termcode(opt_idx)) != NULL; opt_idx++) 6485 { 6486 if (!isprint(str[0]) || !isprint(str[1])) 6487 continue; 6488 6489 name_buf[0] = 't'; 6490 name_buf[1] = '_'; 6491 name_buf[2] = str[0]; 6492 name_buf[3] = str[1]; 6493 name_buf[4] = NUL; 6494 6495 match = FALSE; 6496 if (vim_regexec(regmatch, name_buf, (colnr_T)0)) 6497 match = TRUE; 6498 else 6499 { 6500 name_buf[0] = '<'; 6501 name_buf[1] = 't'; 6502 name_buf[2] = '_'; 6503 name_buf[3] = str[0]; 6504 name_buf[4] = str[1]; 6505 name_buf[5] = '>'; 6506 name_buf[6] = NUL; 6507 6508 if (vim_regexec(regmatch, name_buf, (colnr_T)0)) 6509 match = TRUE; 6510 } 6511 if (match) 6512 { 6513 if (loop == 0) 6514 num_term++; 6515 else 6516 (*file)[count++] = vim_strsave(name_buf); 6517 } 6518 } 6519 6520 /* 6521 * Check special key names. 6522 */ 6523 regmatch->rm_ic = TRUE; // ignore case here 6524 for (opt_idx = 0; (str = get_key_name(opt_idx)) != NULL; opt_idx++) 6525 { 6526 name_buf[0] = '<'; 6527 STRCPY(name_buf + 1, str); 6528 STRCAT(name_buf, ">"); 6529 6530 if (vim_regexec(regmatch, name_buf, (colnr_T)0)) 6531 { 6532 if (loop == 0) 6533 num_term++; 6534 else 6535 (*file)[count++] = vim_strsave(name_buf); 6536 } 6537 } 6538 } 6539 if (loop == 0) 6540 { 6541 if (num_normal > 0) 6542 *num_file = num_normal; 6543 else if (num_term > 0) 6544 *num_file = num_term; 6545 else 6546 return OK; 6547 *file = ALLOC_MULT(char_u *, *num_file); 6548 if (*file == NULL) 6549 { 6550 *file = (char_u **)""; 6551 return FAIL; 6552 } 6553 } 6554 } 6555 return OK; 6556 } 6557 6558 int 6559 ExpandOldSetting(int *num_file, char_u ***file) 6560 { 6561 char_u *var = NULL; // init for GCC 6562 char_u *buf; 6563 6564 *num_file = 0; 6565 *file = ALLOC_ONE(char_u *); 6566 if (*file == NULL) 6567 return FAIL; 6568 6569 /* 6570 * For a terminal key code expand_option_idx is < 0. 6571 */ 6572 if (expand_option_idx < 0) 6573 { 6574 var = find_termcode(expand_option_name + 2); 6575 if (var == NULL) 6576 expand_option_idx = findoption(expand_option_name); 6577 } 6578 6579 if (expand_option_idx >= 0) 6580 { 6581 // put string of option value in NameBuff 6582 option_value2string(&options[expand_option_idx], expand_option_flags); 6583 var = NameBuff; 6584 } 6585 else if (var == NULL) 6586 var = (char_u *)""; 6587 6588 // A backslash is required before some characters. This is the reverse of 6589 // what happens in do_set(). 6590 buf = vim_strsave_escaped(var, escape_chars); 6591 6592 if (buf == NULL) 6593 { 6594 VIM_CLEAR(*file); 6595 return FAIL; 6596 } 6597 6598 #ifdef BACKSLASH_IN_FILENAME 6599 // For MS-Windows et al. we don't double backslashes at the start and 6600 // before a file name character. 6601 for (var = buf; *var != NUL; MB_PTR_ADV(var)) 6602 if (var[0] == '\\' && var[1] == '\\' 6603 && expand_option_idx >= 0 6604 && (options[expand_option_idx].flags & P_EXPAND) 6605 && vim_isfilec(var[2]) 6606 && (var[2] != '\\' || (var == buf && var[4] != '\\'))) 6607 STRMOVE(var, var + 1); 6608 #endif 6609 6610 *file[0] = buf; 6611 *num_file = 1; 6612 return OK; 6613 } 6614 6615 /* 6616 * Get the value for the numeric or string option *opp in a nice format into 6617 * NameBuff[]. Must not be called with a hidden option! 6618 */ 6619 static void 6620 option_value2string( 6621 struct vimoption *opp, 6622 int opt_flags) // OPT_GLOBAL and/or OPT_LOCAL 6623 { 6624 char_u *varp; 6625 6626 varp = get_varp_scope(opp, opt_flags); 6627 6628 if (opp->flags & P_NUM) 6629 { 6630 long wc = 0; 6631 6632 if (wc_use_keyname(varp, &wc)) 6633 STRCPY(NameBuff, get_special_key_name((int)wc, 0)); 6634 else if (wc != 0) 6635 STRCPY(NameBuff, transchar((int)wc)); 6636 else 6637 sprintf((char *)NameBuff, "%ld", *(long *)varp); 6638 } 6639 else // P_STRING 6640 { 6641 varp = *(char_u **)(varp); 6642 if (varp == NULL) // just in case 6643 NameBuff[0] = NUL; 6644 #ifdef FEAT_CRYPT 6645 // don't show the actual value of 'key', only that it's set 6646 else if (opp->var == (char_u *)&p_key && *varp) 6647 STRCPY(NameBuff, "*****"); 6648 #endif 6649 else if (opp->flags & P_EXPAND) 6650 home_replace(NULL, varp, NameBuff, MAXPATHL, FALSE); 6651 // Translate 'pastetoggle' into special key names 6652 else if ((char_u **)opp->var == &p_pt) 6653 str2specialbuf(p_pt, NameBuff, MAXPATHL); 6654 else 6655 vim_strncpy(NameBuff, varp, MAXPATHL - 1); 6656 } 6657 } 6658 6659 /* 6660 * Return TRUE if "varp" points to 'wildchar' or 'wildcharm' and it can be 6661 * printed as a keyname. 6662 * "*wcp" is set to the value of the option if it's 'wildchar' or 'wildcharm'. 6663 */ 6664 static int 6665 wc_use_keyname(char_u *varp, long *wcp) 6666 { 6667 if (((long *)varp == &p_wc) || ((long *)varp == &p_wcm)) 6668 { 6669 *wcp = *(long *)varp; 6670 if (IS_SPECIAL(*wcp) || find_special_key_in_table((int)*wcp) >= 0) 6671 return TRUE; 6672 } 6673 return FALSE; 6674 } 6675 6676 /* 6677 * Return TRUE if "x" is present in 'shortmess' option, or 6678 * 'shortmess' contains 'a' and "x" is present in SHM_A. 6679 */ 6680 int 6681 shortmess(int x) 6682 { 6683 return p_shm != NULL && 6684 ( vim_strchr(p_shm, x) != NULL 6685 || (vim_strchr(p_shm, 'a') != NULL 6686 && vim_strchr((char_u *)SHM_A, x) != NULL)); 6687 } 6688 6689 /* 6690 * paste_option_changed() - Called after p_paste was set or reset. 6691 */ 6692 static void 6693 paste_option_changed(void) 6694 { 6695 static int old_p_paste = FALSE; 6696 static int save_sm = 0; 6697 static int save_sta = 0; 6698 #ifdef FEAT_CMDL_INFO 6699 static int save_ru = 0; 6700 #endif 6701 #ifdef FEAT_RIGHTLEFT 6702 static int save_ri = 0; 6703 static int save_hkmap = 0; 6704 #endif 6705 buf_T *buf; 6706 6707 if (p_paste) 6708 { 6709 /* 6710 * Paste switched from off to on. 6711 * Save the current values, so they can be restored later. 6712 */ 6713 if (!old_p_paste) 6714 { 6715 // save options for each buffer 6716 FOR_ALL_BUFFERS(buf) 6717 { 6718 buf->b_p_tw_nopaste = buf->b_p_tw; 6719 buf->b_p_wm_nopaste = buf->b_p_wm; 6720 buf->b_p_sts_nopaste = buf->b_p_sts; 6721 buf->b_p_ai_nopaste = buf->b_p_ai; 6722 buf->b_p_et_nopaste = buf->b_p_et; 6723 #ifdef FEAT_VARTABS 6724 if (buf->b_p_vsts_nopaste) 6725 vim_free(buf->b_p_vsts_nopaste); 6726 buf->b_p_vsts_nopaste = buf->b_p_vsts && buf->b_p_vsts != empty_option 6727 ? vim_strsave(buf->b_p_vsts) : NULL; 6728 #endif 6729 } 6730 6731 // save global options 6732 save_sm = p_sm; 6733 save_sta = p_sta; 6734 #ifdef FEAT_CMDL_INFO 6735 save_ru = p_ru; 6736 #endif 6737 #ifdef FEAT_RIGHTLEFT 6738 save_ri = p_ri; 6739 save_hkmap = p_hkmap; 6740 #endif 6741 // save global values for local buffer options 6742 p_ai_nopaste = p_ai; 6743 p_et_nopaste = p_et; 6744 p_sts_nopaste = p_sts; 6745 p_tw_nopaste = p_tw; 6746 p_wm_nopaste = p_wm; 6747 #ifdef FEAT_VARTABS 6748 if (p_vsts_nopaste) 6749 vim_free(p_vsts_nopaste); 6750 p_vsts_nopaste = p_vsts && p_vsts != empty_option ? vim_strsave(p_vsts) : NULL; 6751 #endif 6752 } 6753 6754 /* 6755 * Always set the option values, also when 'paste' is set when it is 6756 * already on. 6757 */ 6758 // set options for each buffer 6759 FOR_ALL_BUFFERS(buf) 6760 { 6761 buf->b_p_tw = 0; // textwidth is 0 6762 buf->b_p_wm = 0; // wrapmargin is 0 6763 buf->b_p_sts = 0; // softtabstop is 0 6764 buf->b_p_ai = 0; // no auto-indent 6765 buf->b_p_et = 0; // no expandtab 6766 #ifdef FEAT_VARTABS 6767 if (buf->b_p_vsts) 6768 free_string_option(buf->b_p_vsts); 6769 buf->b_p_vsts = empty_option; 6770 if (buf->b_p_vsts_array) 6771 vim_free(buf->b_p_vsts_array); 6772 buf->b_p_vsts_array = 0; 6773 #endif 6774 } 6775 6776 // set global options 6777 p_sm = 0; // no showmatch 6778 p_sta = 0; // no smarttab 6779 #ifdef FEAT_CMDL_INFO 6780 if (p_ru) 6781 status_redraw_all(); // redraw to remove the ruler 6782 p_ru = 0; // no ruler 6783 #endif 6784 #ifdef FEAT_RIGHTLEFT 6785 p_ri = 0; // no reverse insert 6786 p_hkmap = 0; // no Hebrew keyboard 6787 #endif 6788 // set global values for local buffer options 6789 p_tw = 0; 6790 p_wm = 0; 6791 p_sts = 0; 6792 p_ai = 0; 6793 #ifdef FEAT_VARTABS 6794 if (p_vsts) 6795 free_string_option(p_vsts); 6796 p_vsts = empty_option; 6797 #endif 6798 } 6799 6800 /* 6801 * Paste switched from on to off: Restore saved values. 6802 */ 6803 else if (old_p_paste) 6804 { 6805 // restore options for each buffer 6806 FOR_ALL_BUFFERS(buf) 6807 { 6808 buf->b_p_tw = buf->b_p_tw_nopaste; 6809 buf->b_p_wm = buf->b_p_wm_nopaste; 6810 buf->b_p_sts = buf->b_p_sts_nopaste; 6811 buf->b_p_ai = buf->b_p_ai_nopaste; 6812 buf->b_p_et = buf->b_p_et_nopaste; 6813 #ifdef FEAT_VARTABS 6814 if (buf->b_p_vsts) 6815 free_string_option(buf->b_p_vsts); 6816 buf->b_p_vsts = buf->b_p_vsts_nopaste 6817 ? vim_strsave(buf->b_p_vsts_nopaste) : empty_option; 6818 if (buf->b_p_vsts_array) 6819 vim_free(buf->b_p_vsts_array); 6820 if (buf->b_p_vsts && buf->b_p_vsts != empty_option) 6821 (void)tabstop_set(buf->b_p_vsts, &buf->b_p_vsts_array); 6822 else 6823 buf->b_p_vsts_array = 0; 6824 #endif 6825 } 6826 6827 // restore global options 6828 p_sm = save_sm; 6829 p_sta = save_sta; 6830 #ifdef FEAT_CMDL_INFO 6831 if (p_ru != save_ru) 6832 status_redraw_all(); // redraw to draw the ruler 6833 p_ru = save_ru; 6834 #endif 6835 #ifdef FEAT_RIGHTLEFT 6836 p_ri = save_ri; 6837 p_hkmap = save_hkmap; 6838 #endif 6839 // set global values for local buffer options 6840 p_ai = p_ai_nopaste; 6841 p_et = p_et_nopaste; 6842 p_sts = p_sts_nopaste; 6843 p_tw = p_tw_nopaste; 6844 p_wm = p_wm_nopaste; 6845 #ifdef FEAT_VARTABS 6846 if (p_vsts) 6847 free_string_option(p_vsts); 6848 p_vsts = p_vsts_nopaste ? vim_strsave(p_vsts_nopaste) : empty_option; 6849 #endif 6850 } 6851 6852 old_p_paste = p_paste; 6853 } 6854 6855 /* 6856 * vimrc_found() - Called when a ".vimrc" or "VIMINIT" has been found. 6857 * 6858 * Reset 'compatible' and set the values for options that didn't get set yet 6859 * to the Vim defaults. 6860 * Don't do this if the 'compatible' option has been set or reset before. 6861 * When "fname" is not NULL, use it to set $"envname" when it wasn't set yet. 6862 */ 6863 void 6864 vimrc_found(char_u *fname, char_u *envname) 6865 { 6866 int opt_idx; 6867 int dofree = FALSE; 6868 char_u *p; 6869 6870 if (!option_was_set((char_u *)"cp")) 6871 { 6872 p_cp = FALSE; 6873 for (opt_idx = 0; !istermoption_idx(opt_idx); opt_idx++) 6874 if (!(options[opt_idx].flags & (P_WAS_SET|P_VI_DEF))) 6875 set_option_default(opt_idx, OPT_FREE, FALSE); 6876 didset_options(); 6877 didset_options2(); 6878 } 6879 6880 if (fname != NULL) 6881 { 6882 p = vim_getenv(envname, &dofree); 6883 if (p == NULL) 6884 { 6885 // Set $MYVIMRC to the first vimrc file found. 6886 p = FullName_save(fname, FALSE); 6887 if (p != NULL) 6888 { 6889 vim_setenv(envname, p); 6890 vim_free(p); 6891 } 6892 } 6893 else if (dofree) 6894 vim_free(p); 6895 } 6896 } 6897 6898 /* 6899 * Set 'compatible' on or off. Called for "-C" and "-N" command line arg. 6900 */ 6901 void 6902 change_compatible(int on) 6903 { 6904 int opt_idx; 6905 6906 if (p_cp != on) 6907 { 6908 p_cp = on; 6909 compatible_set(); 6910 } 6911 opt_idx = findoption((char_u *)"cp"); 6912 if (opt_idx >= 0) 6913 options[opt_idx].flags |= P_WAS_SET; 6914 } 6915 6916 /* 6917 * Return TRUE when option "name" has been set. 6918 * Only works correctly for global options. 6919 */ 6920 int 6921 option_was_set(char_u *name) 6922 { 6923 int idx; 6924 6925 idx = findoption(name); 6926 if (idx < 0) // unknown option 6927 return FALSE; 6928 if (options[idx].flags & P_WAS_SET) 6929 return TRUE; 6930 return FALSE; 6931 } 6932 6933 /* 6934 * Reset the flag indicating option "name" was set. 6935 */ 6936 int 6937 reset_option_was_set(char_u *name) 6938 { 6939 int idx = findoption(name); 6940 6941 if (idx >= 0) 6942 { 6943 options[idx].flags &= ~P_WAS_SET; 6944 return OK; 6945 } 6946 return FAIL; 6947 } 6948 6949 /* 6950 * compatible_set() - Called when 'compatible' has been set or unset. 6951 * 6952 * When 'compatible' set: Set all relevant options (those that have the P_VIM) 6953 * flag) to a Vi compatible value. 6954 * When 'compatible' is unset: Set all options that have a different default 6955 * for Vim (without the P_VI_DEF flag) to that default. 6956 */ 6957 static void 6958 compatible_set(void) 6959 { 6960 int opt_idx; 6961 6962 for (opt_idx = 0; !istermoption_idx(opt_idx); opt_idx++) 6963 if ( ((options[opt_idx].flags & P_VIM) && p_cp) 6964 || (!(options[opt_idx].flags & P_VI_DEF) && !p_cp)) 6965 set_option_default(opt_idx, OPT_FREE, p_cp); 6966 didset_options(); 6967 didset_options2(); 6968 } 6969 6970 #if defined(FEAT_LINEBREAK) || defined(PROTO) 6971 6972 /* 6973 * fill_breakat_flags() -- called when 'breakat' changes value. 6974 */ 6975 void 6976 fill_breakat_flags(void) 6977 { 6978 char_u *p; 6979 int i; 6980 6981 for (i = 0; i < 256; i++) 6982 breakat_flags[i] = FALSE; 6983 6984 if (p_breakat != NULL) 6985 for (p = p_breakat; *p; p++) 6986 breakat_flags[*p] = TRUE; 6987 } 6988 #endif 6989 6990 /* 6991 * Check if backspacing over something is allowed. 6992 */ 6993 int 6994 can_bs( 6995 int what) // BS_INDENT, BS_EOL, BS_START or BS_NOSTOP 6996 { 6997 #ifdef FEAT_JOB_CHANNEL 6998 if (what == BS_START && bt_prompt(curbuf)) 6999 return FALSE; 7000 #endif 7001 switch (*p_bs) 7002 { 7003 case '3': return TRUE; 7004 case '2': return (what != BS_NOSTOP); 7005 case '1': return (what != BS_START); 7006 case '0': return FALSE; 7007 } 7008 return vim_strchr(p_bs, what) != NULL; 7009 } 7010 7011 /* 7012 * Return the effective 'scrolloff' value for the current window, using the 7013 * global value when appropriate. 7014 */ 7015 long 7016 get_scrolloff_value(void) 7017 { 7018 return curwin->w_p_so < 0 ? p_so : curwin->w_p_so; 7019 } 7020 7021 /* 7022 * Return the effective 'sidescrolloff' value for the current window, using the 7023 * global value when appropriate. 7024 */ 7025 long 7026 get_sidescrolloff_value(void) 7027 { 7028 return curwin->w_p_siso < 0 ? p_siso : curwin->w_p_siso; 7029 } 7030 7031 /* 7032 * Get the local or global value of 'backupcopy'. 7033 */ 7034 unsigned int 7035 get_bkc_value(buf_T *buf) 7036 { 7037 return buf->b_bkc_flags ? buf->b_bkc_flags : bkc_flags; 7038 } 7039 7040 /* 7041 * Get the local or global value of the 'virtualedit' flags. 7042 */ 7043 unsigned int 7044 get_ve_flags(void) 7045 { 7046 return (curwin->w_ve_flags ? curwin->w_ve_flags : ve_flags) 7047 & ~(VE_NONE | VE_NONEU); 7048 } 7049 7050 #if defined(FEAT_LINEBREAK) || defined(PROTO) 7051 /* 7052 * Get the local or global value of 'showbreak'. 7053 */ 7054 char_u * 7055 get_showbreak_value(win_T *win) 7056 { 7057 if (win->w_p_sbr == NULL || *win->w_p_sbr == NUL) 7058 return p_sbr; 7059 if (STRCMP(win->w_p_sbr, "NONE") == 0) 7060 return empty_option; 7061 return win->w_p_sbr; 7062 } 7063 #endif 7064 7065 #if defined(FEAT_EVAL) || defined(PROTO) 7066 /* 7067 * Get window or buffer local options. 7068 */ 7069 dict_T * 7070 get_winbuf_options(int bufopt) 7071 { 7072 dict_T *d; 7073 int opt_idx; 7074 7075 d = dict_alloc(); 7076 if (d == NULL) 7077 return NULL; 7078 7079 for (opt_idx = 0; !istermoption_idx(opt_idx); opt_idx++) 7080 { 7081 struct vimoption *opt = &options[opt_idx]; 7082 7083 if ((bufopt && (opt->indir & PV_BUF)) 7084 || (!bufopt && (opt->indir & PV_WIN))) 7085 { 7086 char_u *varp = get_varp(opt); 7087 7088 if (varp != NULL) 7089 { 7090 if (opt->flags & P_STRING) 7091 dict_add_string(d, opt->fullname, *(char_u **)varp); 7092 else if (opt->flags & P_NUM) 7093 dict_add_number(d, opt->fullname, *(long *)varp); 7094 else 7095 dict_add_number(d, opt->fullname, *(int *)varp); 7096 } 7097 } 7098 } 7099 7100 return d; 7101 } 7102 #endif 7103 7104 #if defined(FEAT_SYN_HL) || defined(PROTO) 7105 /* 7106 * This is called when 'culopt' is changed 7107 */ 7108 int 7109 fill_culopt_flags(char_u *val, win_T *wp) 7110 { 7111 char_u *p; 7112 char_u culopt_flags_new = 0; 7113 7114 if (val == NULL) 7115 p = wp->w_p_culopt; 7116 else 7117 p = val; 7118 while (*p != NUL) 7119 { 7120 if (STRNCMP(p, "line", 4) == 0) 7121 { 7122 p += 4; 7123 culopt_flags_new |= CULOPT_LINE; 7124 } 7125 else if (STRNCMP(p, "both", 4) == 0) 7126 { 7127 p += 4; 7128 culopt_flags_new |= CULOPT_LINE | CULOPT_NBR; 7129 } 7130 else if (STRNCMP(p, "number", 6) == 0) 7131 { 7132 p += 6; 7133 culopt_flags_new |= CULOPT_NBR; 7134 } 7135 else if (STRNCMP(p, "screenline", 10) == 0) 7136 { 7137 p += 10; 7138 culopt_flags_new |= CULOPT_SCRLINE; 7139 } 7140 7141 if (*p != ',' && *p != NUL) 7142 return FAIL; 7143 if (*p == ',') 7144 ++p; 7145 } 7146 7147 // Can't have both "line" and "screenline". 7148 if ((culopt_flags_new & CULOPT_LINE) && (culopt_flags_new & CULOPT_SCRLINE)) 7149 return FAIL; 7150 wp->w_p_culopt_flags = culopt_flags_new; 7151 7152 return OK; 7153 } 7154 #endif 7155 7156 /* 7157 * Get the value of 'magic' adjusted for Vim9 script. 7158 */ 7159 int 7160 magic_isset(void) 7161 { 7162 switch (magic_overruled) 7163 { 7164 case OPTION_MAGIC_ON: return TRUE; 7165 case OPTION_MAGIC_OFF: return FALSE; 7166 case OPTION_MAGIC_NOT_SET: break; 7167 } 7168 #ifdef FEAT_EVAL 7169 if (in_vim9script()) 7170 return TRUE; 7171 #endif 7172 return p_magic; 7173 } 7174