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