blob: 60c1141b6a069fe5fdceecca647b0e87ee21ba3a [file] [log] [blame]
Bram Moolenaaredf3f972016-08-29 22:49:24 +02001/* vi:set ts=8 sts=4 sw=4 noet:
Bram Moolenaar071d4272004-06-13 20:20:40 +00002 *
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.
Bram Moolenaarcea912a2016-10-12 14:20:24 +020025 * - Add documentation! One line in doc/quickref.txt, full description in
Bram Moolenaar071d4272004-06-13 20:20:40 +000026 * 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"
Bram Moolenaar0eddca42019-09-12 22:26:43 +020036#include "optiondefs.h"
Bram Moolenaar071d4272004-06-13 20:20:40 +000037
Bram Moolenaarbaaa7e92016-01-29 22:47:03 +010038static void set_options_default(int opt_flags);
Bram Moolenaar4bfa8af2018-02-03 15:14:46 +010039static void set_string_default_esc(char *name, char_u *val, int escape);
Bram Moolenaarbaaa7e92016-01-29 22:47:03 +010040static char_u *term_bg_default(void);
Bram Moolenaarbaaa7e92016-01-29 22:47:03 +010041static char_u *option_expand(int opt_idx, char_u *val);
42static void didset_options(void);
43static void didset_options2(void);
Bram Moolenaard1f56e62006-02-22 21:25:37 +000044#if defined(FEAT_EVAL) || defined(PROTO)
Bram Moolenaarbaaa7e92016-01-29 22:47:03 +010045static long_u *insecure_flag(int opt_idx, int opt_flags);
Bram Moolenaard1f56e62006-02-22 21:25:37 +000046#else
47# define insecure_flag(opt_idx, opt_flags) (&options[opt_idx].flags)
48#endif
Bram Moolenaarf9e3e092019-01-13 23:38:42 +010049static char *set_bool_option(int opt_idx, char_u *varp, int value, int opt_flags);
50static char *set_num_option(int opt_idx, char_u *varp, long value, char *errbuf, size_t errbuflen, int opt_flags);
Bram Moolenaar9cf4b502018-07-23 04:12:03 +020051static int find_key_option(char_u *arg_arg, int has_lt);
Bram Moolenaarbaaa7e92016-01-29 22:47:03 +010052static void showoptions(int all, int opt_flags);
Bram Moolenaarcacc6a52019-05-30 15:22:43 +020053static int optval_default(struct vimoption *, char_u *varp, int compatible);
Bram Moolenaarbaaa7e92016-01-29 22:47:03 +010054static void showoneopt(struct vimoption *, int opt_flags);
Bram Moolenaared18f2c2019-01-24 20:30:52 +010055static int put_setstring(FILE *fd, char *cmd, char *name, char_u **valuep, long_u flags);
Bram Moolenaarbaaa7e92016-01-29 22:47:03 +010056static int put_setnum(FILE *fd, char *cmd, char *name, long *valuep);
57static int put_setbool(FILE *fd, char *cmd, char *name, int value);
Bram Moolenaardac13472019-09-16 21:06:21 +020058static int istermoption(struct vimoption *p);
Bram Moolenaarbaaa7e92016-01-29 22:47:03 +010059static char_u *get_varp_scope(struct vimoption *p, int opt_flags);
60static char_u *get_varp(struct vimoption *);
Bram Moolenaar5843f5f2019-08-20 20:13:45 +020061static void check_win_options(win_T *win);
Bram Moolenaarbaaa7e92016-01-29 22:47:03 +010062static void option_value2string(struct vimoption *, int opt_flags);
63static void check_winopt(winopt_T *wop);
64static int wc_use_keyname(char_u *varp, long *wcp);
Bram Moolenaarbaaa7e92016-01-29 22:47:03 +010065static void paste_option_changed(void);
66static void compatible_set(void);
Bram Moolenaar071d4272004-06-13 20:20:40 +000067
68/*
69 * Initialize the options, first part.
70 *
71 * Called only once from main(), just after creating the first buffer.
Bram Moolenaar07268702018-03-01 21:57:32 +010072 * If "clean_arg" is TRUE Vim was started with --clean.
Bram Moolenaar071d4272004-06-13 20:20:40 +000073 */
74 void
Bram Moolenaar07268702018-03-01 21:57:32 +010075set_init_1(int clean_arg)
Bram Moolenaar071d4272004-06-13 20:20:40 +000076{
77 char_u *p;
78 int opt_idx;
Bram Moolenaara93fa7e2006-04-17 22:14:47 +000079 long_u n;
Bram Moolenaar071d4272004-06-13 20:20:40 +000080
81#ifdef FEAT_LANGMAP
82 langmap_init();
83#endif
84
85 /* Be Vi compatible by default */
86 p_cp = TRUE;
87
Bram Moolenaar4399ef42005-02-12 14:29:27 +000088 /* Use POSIX compatibility when $VIM_POSIX is set. */
89 if (mch_getenv((char_u *)"VIM_POSIX") != NULL)
Bram Moolenaar26a60b42005-02-22 08:49:11 +000090 {
Bram Moolenaar4399ef42005-02-12 14:29:27 +000091 set_string_default("cpo", (char_u *)CPO_ALL);
Bram Moolenaar9dfa3132019-05-04 21:08:40 +020092 set_string_default("shm", (char_u *)SHM_POSIX);
Bram Moolenaar26a60b42005-02-22 08:49:11 +000093 }
Bram Moolenaar4399ef42005-02-12 14:29:27 +000094
Bram Moolenaar071d4272004-06-13 20:20:40 +000095 /*
96 * Find default value for 'shell' option.
Bram Moolenaar7c626922005-02-07 22:01:03 +000097 * Don't use it if it is empty.
Bram Moolenaar071d4272004-06-13 20:20:40 +000098 */
Bram Moolenaar7c626922005-02-07 22:01:03 +000099 if (((p = mch_getenv((char_u *)"SHELL")) != NULL && *p != NUL)
Bram Moolenaar48e330a2016-02-23 14:53:34 +0100100#if defined(MSWIN)
Bram Moolenaar7c626922005-02-07 22:01:03 +0000101 || ((p = mch_getenv((char_u *)"COMSPEC")) != NULL && *p != NUL)
Bram Moolenaar6aa2cd42016-02-16 15:06:59 +0100102 || ((p = (char_u *)default_shell()) != NULL && *p != NUL)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000103#endif
Bram Moolenaar7c626922005-02-07 22:01:03 +0000104 )
Bram Moolenaar2efc44b2019-10-05 12:09:32 +0200105#if defined(MSWIN)
106 {
107 // For MS-Windows put the path in quotes instead of escaping spaces.
108 char_u *cmd;
109 size_t len;
110
111 if (vim_strchr(p, ' ') != NULL)
112 {
113 len = STRLEN(p) + 3; // two quotes and a trailing NUL
114 cmd = alloc(len);
Bram Moolenaar1671de32019-10-05 21:35:16 +0200115 if (cmd != NULL)
116 {
117 vim_snprintf((char *)cmd, len, "\"%s\"", p);
118 set_string_default("sh", cmd);
119 vim_free(cmd);
120 }
Bram Moolenaar2efc44b2019-10-05 12:09:32 +0200121 }
122 else
123 set_string_default("sh", p);
124 }
125#else
Bram Moolenaar4bfa8af2018-02-03 15:14:46 +0100126 set_string_default_esc("sh", p, TRUE);
Bram Moolenaar2efc44b2019-10-05 12:09:32 +0200127#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000128
129#ifdef FEAT_WILDIGN
130 /*
131 * Set the default for 'backupskip' to include environment variables for
132 * temp files.
133 */
134 {
135# ifdef UNIX
136 static char *(names[4]) = {"", "TMPDIR", "TEMP", "TMP"};
137# else
138 static char *(names[3]) = {"TMPDIR", "TEMP", "TMP"};
139# endif
Bram Moolenaar05159a02005-02-26 23:04:13 +0000140 int len;
141 garray_T ga;
142 int mustfree;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000143
144 ga_init2(&ga, 1, 100);
145 for (n = 0; n < (long)(sizeof(names) / sizeof(char *)); ++n)
146 {
Bram Moolenaar05159a02005-02-26 23:04:13 +0000147 mustfree = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000148# ifdef UNIX
149 if (*names[n] == NUL)
Bram Moolenaarb8e22a02018-04-12 21:37:34 +0200150# ifdef MACOS_X
151 p = (char_u *)"/private/tmp";
152# else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000153 p = (char_u *)"/tmp";
Bram Moolenaarb8e22a02018-04-12 21:37:34 +0200154# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000155 else
156# endif
Bram Moolenaar05159a02005-02-26 23:04:13 +0000157 p = vim_getenv((char_u *)names[n], &mustfree);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000158 if (p != NULL && *p != NUL)
159 {
160 /* First time count the NUL, otherwise count the ','. */
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000161 len = (int)STRLEN(p) + 3;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000162 if (ga_grow(&ga, len) == OK)
163 {
164 if (ga.ga_len > 0)
165 STRCAT(ga.ga_data, ",");
166 STRCAT(ga.ga_data, p);
167 add_pathsep(ga.ga_data);
168 STRCAT(ga.ga_data, "*");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000169 ga.ga_len += len;
170 }
171 }
Bram Moolenaar05159a02005-02-26 23:04:13 +0000172 if (mustfree)
173 vim_free(p);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000174 }
175 if (ga.ga_data != NULL)
176 {
177 set_string_default("bsk", ga.ga_data);
178 vim_free(ga.ga_data);
179 }
180 }
181#endif
182
183 /*
184 * 'maxmemtot' and 'maxmem' may have to be adjusted for available memory
185 */
186 opt_idx = findoption((char_u *)"maxmemtot");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000187 if (opt_idx >= 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000188 {
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000189#if !defined(HAVE_AVAIL_MEM) && !defined(HAVE_TOTAL_MEM)
190 if (options[opt_idx].def_val[VI_DEFAULT] == (char_u *)0L)
191#endif
192 {
Bram Moolenaar071d4272004-06-13 20:20:40 +0000193#ifdef HAVE_AVAIL_MEM
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000194 /* Use amount of memory available at this moment. */
Bram Moolenaar11b73d62012-06-29 15:51:30 +0200195 n = (mch_avail_mem(FALSE) >> 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000196#else
197# ifdef HAVE_TOTAL_MEM
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000198 /* Use amount of memory available to Vim. */
Bram Moolenaar914572a2007-05-01 11:37:47 +0000199 n = (mch_total_mem(FALSE) >> 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000200# else
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000201 n = (0x7fffffff >> 11);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000202# endif
203#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000204 options[opt_idx].def_val[VI_DEFAULT] = (char_u *)n;
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000205 opt_idx = findoption((char_u *)"maxmem");
206 if (opt_idx >= 0)
207 {
208#if !defined(HAVE_AVAIL_MEM) && !defined(HAVE_TOTAL_MEM)
Bram Moolenaar35be4532015-12-11 22:38:36 +0100209 if ((long)(long_i)options[opt_idx].def_val[VI_DEFAULT] > (long)n
210 || (long)(long_i)options[opt_idx].def_val[VI_DEFAULT] == 0L)
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000211#endif
212 options[opt_idx].def_val[VI_DEFAULT] = (char_u *)n;
213 }
214 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000215 }
216
Bram Moolenaar071d4272004-06-13 20:20:40 +0000217#ifdef FEAT_SEARCHPATH
218 {
219 char_u *cdpath;
220 char_u *buf;
221 int i;
222 int j;
Bram Moolenaar05159a02005-02-26 23:04:13 +0000223 int mustfree = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000224
225 /* Initialize the 'cdpath' option's default value. */
Bram Moolenaar05159a02005-02-26 23:04:13 +0000226 cdpath = vim_getenv((char_u *)"CDPATH", &mustfree);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000227 if (cdpath != NULL)
228 {
Bram Moolenaar964b3742019-05-24 18:54:09 +0200229 buf = alloc((STRLEN(cdpath) << 1) + 2);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000230 if (buf != NULL)
231 {
232 buf[0] = ','; /* start with ",", current dir first */
233 j = 1;
234 for (i = 0; cdpath[i] != NUL; ++i)
235 {
236 if (vim_ispathlistsep(cdpath[i]))
237 buf[j++] = ',';
238 else
239 {
240 if (cdpath[i] == ' ' || cdpath[i] == ',')
241 buf[j++] = '\\';
242 buf[j++] = cdpath[i];
243 }
244 }
245 buf[j] = NUL;
246 opt_idx = findoption((char_u *)"cdpath");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000247 if (opt_idx >= 0)
248 {
249 options[opt_idx].def_val[VI_DEFAULT] = buf;
250 options[opt_idx].flags |= P_DEF_ALLOCED;
251 }
Bram Moolenaara9d52e32010-07-31 16:44:19 +0200252 else
253 vim_free(buf); /* cannot happen */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000254 }
Bram Moolenaar05159a02005-02-26 23:04:13 +0000255 if (mustfree)
256 vim_free(cdpath);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000257 }
258 }
259#endif
260
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100261#if defined(FEAT_POSTSCRIPT) && (defined(MSWIN) || defined(VMS) || defined(EBCDIC) || defined(MAC) || defined(hpux))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000262 /* Set print encoding on platforms that don't default to latin1 */
263 set_string_default("penc",
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100264# if defined(MSWIN)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000265 (char_u *)"cp1252"
266# else
267# ifdef VMS
268 (char_u *)"dec-mcs"
269# else
270# ifdef EBCDIC
271 (char_u *)"ebcdic-uk"
272# else
273# ifdef MAC
274 (char_u *)"mac-roman"
275# else /* HPUX */
276 (char_u *)"hp-roman8"
277# endif
278# endif
279# endif
280# endif
281 );
282#endif
283
284#ifdef FEAT_POSTSCRIPT
285 /* 'printexpr' must be allocated to be able to evaluate it. */
286 set_string_default("pexpr",
Bram Moolenaar48e330a2016-02-23 14:53:34 +0100287# if defined(MSWIN)
Bram Moolenaared203462004-06-16 11:19:22 +0000288 (char_u *)"system('copy' . ' ' . v:fname_in . (&printdevice == '' ? ' LPT1:' : (' \"' . &printdevice . '\"'))) . delete(v:fname_in)"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000289# else
290# ifdef VMS
291 (char_u *)"system('print/delete' . (&printdevice == '' ? '' : ' /queue=' . &printdevice) . ' ' . v:fname_in)"
292
293# else
294 (char_u *)"system('lpr' . (&printdevice == '' ? '' : ' -P' . &printdevice) . ' ' . v:fname_in) . delete(v:fname_in) + v:shell_error"
295# endif
296# endif
297 );
298#endif
299
300 /*
301 * Set all the options (except the terminal options) to their default
302 * value. Also set the global value for local options.
303 */
304 set_options_default(0);
305
Bram Moolenaar07268702018-03-01 21:57:32 +0100306#ifdef CLEAN_RUNTIMEPATH
307 if (clean_arg)
308 {
309 opt_idx = findoption((char_u *)"runtimepath");
310 if (opt_idx >= 0)
311 {
312 options[opt_idx].def_val[VI_DEFAULT] = (char_u *)CLEAN_RUNTIMEPATH;
313 p_rtp = (char_u *)CLEAN_RUNTIMEPATH;
314 }
315 opt_idx = findoption((char_u *)"packpath");
316 if (opt_idx >= 0)
317 {
318 options[opt_idx].def_val[VI_DEFAULT] = (char_u *)CLEAN_RUNTIMEPATH;
319 p_pp = (char_u *)CLEAN_RUNTIMEPATH;
320 }
321 }
322#endif
323
Bram Moolenaar071d4272004-06-13 20:20:40 +0000324#ifdef FEAT_GUI
325 if (found_reverse_arg)
326 set_option_value((char_u *)"bg", 0L, (char_u *)"dark", 0);
327#endif
328
329 curbuf->b_p_initialized = TRUE;
330 curbuf->b_p_ar = -1; /* no local 'autoread' value */
Bram Moolenaarf5a2fd82013-11-06 05:26:15 +0100331 curbuf->b_p_ul = NO_LOCAL_UNDOLEVEL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000332 check_buf_options(curbuf);
333 check_win_options(curwin);
334 check_options();
335
336 /* Must be before option_expand(), because that one needs vim_isIDc() */
337 didset_options();
338
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +0000339#ifdef FEAT_SPELL
Bram Moolenaare68c25c2015-08-25 15:39:55 +0200340 /* Use the current chartab for the generic chartab. This is not in
341 * didset_options() because it only depends on 'encoding'. */
Bram Moolenaar6bb68362005-03-22 23:03:44 +0000342 init_spell_chartab();
343#endif
344
Bram Moolenaar071d4272004-06-13 20:20:40 +0000345 /*
346 * Expand environment variables and things like "~" for the defaults.
347 * If option_expand() returns non-NULL the variable is expanded. This can
348 * only happen for non-indirect options.
349 * Also set the default to the expanded value, so ":set" does not list
350 * them.
351 * Don't set the P_ALLOCED flag, because we don't want to free the
352 * default.
353 */
Bram Moolenaardac13472019-09-16 21:06:21 +0200354 for (opt_idx = 0; !istermoption_idx(opt_idx); opt_idx++)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000355 {
356 if ((options[opt_idx].flags & P_GETTEXT)
357 && options[opt_idx].var != NULL)
358 p = (char_u *)_(*(char **)options[opt_idx].var);
359 else
360 p = option_expand(opt_idx, NULL);
361 if (p != NULL && (p = vim_strsave(p)) != NULL)
362 {
363 *(char_u **)options[opt_idx].var = p;
364 /* VIMEXP
365 * Defaults for all expanded options are currently the same for Vi
366 * and Vim. When this changes, add some code here! Also need to
367 * split P_DEF_ALLOCED in two.
368 */
369 if (options[opt_idx].flags & P_DEF_ALLOCED)
370 vim_free(options[opt_idx].def_val[VI_DEFAULT]);
371 options[opt_idx].def_val[VI_DEFAULT] = p;
372 options[opt_idx].flags |= P_DEF_ALLOCED;
373 }
374 }
375
Bram Moolenaar071d4272004-06-13 20:20:40 +0000376 save_file_ff(curbuf); /* Buffer is unchanged */
377
Bram Moolenaar071d4272004-06-13 20:20:40 +0000378#if defined(FEAT_ARABIC)
379 /* Detect use of mlterm.
380 * Mlterm is a terminal emulator akin to xterm that has some special
381 * abilities (bidi namely).
382 * NOTE: mlterm's author is being asked to 'set' a variable
383 * instead of an environment variable due to inheritance.
384 */
385 if (mch_getenv((char_u *)"MLTERM") != NULL)
386 set_option_value((char_u *)"tbidi", 1L, NULL, 0);
387#endif
388
Bram Moolenaare68c25c2015-08-25 15:39:55 +0200389 didset_options2();
Bram Moolenaar071d4272004-06-13 20:20:40 +0000390
Bram Moolenaar4f974752019-02-17 17:44:42 +0100391# if defined(MSWIN) && defined(FEAT_GETTEXT)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000392 /*
393 * If $LANG isn't set, try to get a good value for it. This makes the
394 * right language be used automatically. Don't do this for English.
395 */
396 if (mch_getenv((char_u *)"LANG") == NULL)
397 {
398 char buf[20];
399
400 /* Could use LOCALE_SISO639LANGNAME, but it's not in Win95.
401 * LOCALE_SABBREVLANGNAME gives us three letters, like "enu", we use
402 * only the first two. */
403 n = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SABBREVLANGNAME,
404 (LPTSTR)buf, 20);
405 if (n >= 2 && STRNICMP(buf, "en", 2) != 0)
406 {
407 /* There are a few exceptions (probably more) */
408 if (STRNICMP(buf, "cht", 3) == 0 || STRNICMP(buf, "zht", 3) == 0)
409 STRCPY(buf, "zh_TW");
410 else if (STRNICMP(buf, "chs", 3) == 0
411 || STRNICMP(buf, "zhc", 3) == 0)
412 STRCPY(buf, "zh_CN");
413 else if (STRNICMP(buf, "jp", 2) == 0)
414 STRCPY(buf, "ja");
415 else
416 buf[2] = NUL; /* truncate to two-letter code */
Bram Moolenaar6aa2cd42016-02-16 15:06:59 +0100417 vim_setenv((char_u *)"LANG", (char_u *)buf);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000418 }
419 }
Bram Moolenaar26a60b42005-02-22 08:49:11 +0000420# else
Bram Moolenaar9d47f172006-03-15 23:03:01 +0000421# ifdef MACOS_CONVERT
Bram Moolenaarc1a11ed2008-06-24 22:09:24 +0000422 /* Moved to os_mac_conv.c to avoid dependency problems. */
423 mac_lang_init();
Bram Moolenaar26a60b42005-02-22 08:49:11 +0000424# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000425# endif
426
427 /* enc_locale() will try to find the encoding of the current locale. */
428 p = enc_locale();
429 if (p != NULL)
430 {
431 char_u *save_enc;
432
433 /* Try setting 'encoding' and check if the value is valid.
434 * If not, go back to the default "latin1". */
435 save_enc = p_enc;
436 p_enc = p;
Bram Moolenaar733f0a22007-03-02 18:56:27 +0000437 if (STRCMP(p_enc, "gb18030") == 0)
438 {
439 /* We don't support "gb18030", but "cp936" is a good substitute
440 * for practical purposes, thus use that. It's not an alias to
441 * still support conversion between gb18030 and utf-8. */
442 p_enc = vim_strsave((char_u *)"cp936");
443 vim_free(p);
444 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000445 if (mb_init() == NULL)
446 {
447 opt_idx = findoption((char_u *)"encoding");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000448 if (opt_idx >= 0)
449 {
450 options[opt_idx].def_val[VI_DEFAULT] = p_enc;
451 options[opt_idx].flags |= P_DEF_ALLOCED;
452 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000453
Bram Moolenaard0573012017-10-28 21:11:06 +0200454#if defined(MSWIN) || defined(MACOS_X) || defined(VMS)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +0100455 if (STRCMP(p_enc, "latin1") == 0 || enc_utf8)
Bram Moolenaarc0197e22004-09-13 20:26:32 +0000456 {
Bram Moolenaar362e1a32006-03-06 23:29:24 +0000457 /* Adjust the default for 'isprint' and 'iskeyword' to match
458 * latin1. Also set the defaults for when 'nocompatible' is
459 * set. */
Bram Moolenaarc0197e22004-09-13 20:26:32 +0000460 set_string_option_direct((char_u *)"isp", -1,
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +0000461 ISP_LATIN1, OPT_FREE, SID_NONE);
Bram Moolenaar362e1a32006-03-06 23:29:24 +0000462 set_string_option_direct((char_u *)"isk", -1,
463 ISK_LATIN1, OPT_FREE, SID_NONE);
464 opt_idx = findoption((char_u *)"isp");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000465 if (opt_idx >= 0)
466 options[opt_idx].def_val[VIM_DEFAULT] = ISP_LATIN1;
Bram Moolenaar362e1a32006-03-06 23:29:24 +0000467 opt_idx = findoption((char_u *)"isk");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000468 if (opt_idx >= 0)
469 options[opt_idx].def_val[VIM_DEFAULT] = ISK_LATIN1;
Bram Moolenaarc0197e22004-09-13 20:26:32 +0000470 (void)init_chartab();
471 }
472#endif
473
Bram Moolenaarafde13b2019-04-28 19:46:49 +0200474#if defined(MSWIN) && (!defined(FEAT_GUI) || defined(VIMDLL))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000475 /* Win32 console: When GetACP() returns a different value from
476 * GetConsoleCP() set 'termencoding'. */
Bram Moolenaarafde13b2019-04-28 19:46:49 +0200477 if (
478# ifdef VIMDLL
479 (!gui.in_use && !gui.starting) &&
480# endif
481 GetACP() != GetConsoleCP())
Bram Moolenaar071d4272004-06-13 20:20:40 +0000482 {
483 char buf[50];
484
Bram Moolenaaraa5df7e2019-02-03 14:53:10 +0100485 /* Win32 console: In ConPTY, GetConsoleCP() returns zero.
486 * Use an alternative value. */
487 if (GetConsoleCP() == 0)
488 sprintf(buf, "cp%ld", (long)GetACP());
489 else
490 sprintf(buf, "cp%ld", (long)GetConsoleCP());
Bram Moolenaar071d4272004-06-13 20:20:40 +0000491 p_tenc = vim_strsave((char_u *)buf);
492 if (p_tenc != NULL)
493 {
494 opt_idx = findoption((char_u *)"termencoding");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000495 if (opt_idx >= 0)
496 {
497 options[opt_idx].def_val[VI_DEFAULT] = p_tenc;
498 options[opt_idx].flags |= P_DEF_ALLOCED;
499 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000500 convert_setup(&input_conv, p_tenc, p_enc);
501 convert_setup(&output_conv, p_enc, p_tenc);
502 }
503 else
504 p_tenc = empty_option;
505 }
Bram Moolenaarfc3abf42019-01-24 15:54:21 +0100506#endif
Bram Moolenaar4f974752019-02-17 17:44:42 +0100507#if defined(MSWIN)
Bram Moolenaar05159a02005-02-26 23:04:13 +0000508 /* $HOME may have characters in active code page. */
509 init_homedir();
Bram Moolenaarfc3abf42019-01-24 15:54:21 +0100510#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000511 }
512 else
513 {
514 vim_free(p_enc);
515 p_enc = save_enc;
516 }
517 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000518
519#ifdef FEAT_MULTI_LANG
520 /* Set the default for 'helplang'. */
521 set_helplang_default(get_mess_lang());
522#endif
523}
524
525/*
526 * Set an option to its default value.
527 * This does not take care of side effects!
528 */
529 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +0100530set_option_default(
531 int opt_idx,
532 int opt_flags, /* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
533 int compatible) /* use Vi default value */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000534{
535 char_u *varp; /* pointer to variable for current option */
536 int dvi; /* index in def_val[] */
537 long_u flags;
Bram Moolenaard1f56e62006-02-22 21:25:37 +0000538 long_u *flagsp;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000539 int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
540
541 varp = get_varp_scope(&(options[opt_idx]), both ? OPT_LOCAL : opt_flags);
542 flags = options[opt_idx].flags;
Bram Moolenaar3638c682005-06-08 22:05:14 +0000543 if (varp != NULL) /* skip hidden option, nothing to do for it */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000544 {
545 dvi = ((flags & P_VI_DEF) || compatible) ? VI_DEFAULT : VIM_DEFAULT;
546 if (flags & P_STRING)
547 {
Bram Moolenaarb833c1e2018-05-05 16:36:06 +0200548 /* Use set_string_option_direct() for local options to handle
549 * freeing and allocating the value. */
550 if (options[opt_idx].indir != PV_NONE)
551 set_string_option_direct(NULL, opt_idx,
552 options[opt_idx].def_val[dvi], opt_flags, 0);
553 else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000554 {
Bram Moolenaarb833c1e2018-05-05 16:36:06 +0200555 if ((opt_flags & OPT_FREE) && (flags & P_ALLOCED))
556 free_string_option(*(char_u **)(varp));
557 *(char_u **)varp = options[opt_idx].def_val[dvi];
558 options[opt_idx].flags &= ~P_ALLOCED;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000559 }
560 }
561 else if (flags & P_NUM)
562 {
Bram Moolenaar5fc1a8b2006-10-17 16:34:24 +0000563 if (options[opt_idx].indir == PV_SCROLL)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000564 win_comp_scroll(curwin);
565 else
566 {
Bram Moolenaar375e3392019-01-31 18:26:10 +0100567 long def_val = (long)(long_i)options[opt_idx].def_val[dvi];
568
569 if ((long *)varp == &curwin->w_p_so
570 || (long *)varp == &curwin->w_p_siso)
571 // 'scrolloff' and 'sidescrolloff' local values have a
572 // different default value than the global default.
573 *(long *)varp = -1;
574 else
575 *(long *)varp = def_val;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000576 /* May also set global value for local option. */
577 if (both)
578 *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) =
Bram Moolenaar375e3392019-01-31 18:26:10 +0100579 def_val;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000580 }
581 }
582 else /* P_BOOL */
583 {
Bram Moolenaareb3593b2006-04-22 22:33:57 +0000584 /* the cast to long is required for Manx C, long_i is needed for
585 * MSVC */
586 *(int *)varp = (int)(long)(long_i)options[opt_idx].def_val[dvi];
Bram Moolenaar8243a792007-05-01 17:05:03 +0000587#ifdef UNIX
588 /* 'modeline' defaults to off for root */
589 if (options[opt_idx].indir == PV_ML && getuid() == ROOT_UID)
590 *(int *)varp = FALSE;
591#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000592 /* May also set global value for local option. */
593 if (both)
594 *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) =
595 *(int *)varp;
596 }
Bram Moolenaarb71eaae2006-01-20 23:10:18 +0000597
Bram Moolenaard1f56e62006-02-22 21:25:37 +0000598 /* The default value is not insecure. */
599 flagsp = insecure_flag(opt_idx, opt_flags);
600 *flagsp = *flagsp & ~P_INSECURE;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000601 }
602
603#ifdef FEAT_EVAL
Bram Moolenaarf29c1c62018-09-10 21:05:02 +0200604 set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000605#endif
606}
607
608/*
609 * Set all options (except terminal options) to their default value.
Bram Moolenaarb341dda2015-08-25 12:56:31 +0200610 * When "opt_flags" is non-zero skip 'encoding'.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000611 */
612 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +0100613set_options_default(
614 int opt_flags) /* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000615{
616 int i;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000617 win_T *wp;
Bram Moolenaarf740b292006-02-16 22:11:02 +0000618 tabpage_T *tp;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000619
Bram Moolenaardac13472019-09-16 21:06:21 +0200620 for (i = 0; !istermoption_idx(i); i++)
Bram Moolenaarb341dda2015-08-25 12:56:31 +0200621 if (!(options[i].flags & P_NODEFAULT)
Bram Moolenaare68c25c2015-08-25 15:39:55 +0200622 && (opt_flags == 0
Bram Moolenaarfc3abf42019-01-24 15:54:21 +0100623 || (options[i].var != (char_u *)&p_enc
Bram Moolenaar5ea87a02015-08-26 23:24:09 +0200624# if defined(FEAT_CRYPT)
Bram Moolenaare68c25c2015-08-25 15:39:55 +0200625 && options[i].var != (char_u *)&p_cm
Bram Moolenaar80606872015-08-25 21:27:35 +0200626 && options[i].var != (char_u *)&p_key
Bram Moolenaar5ea87a02015-08-26 23:24:09 +0200627# endif
Bram Moolenaarfc3abf42019-01-24 15:54:21 +0100628 )))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000629 set_option_default(i, opt_flags, p_cp);
630
Bram Moolenaar071d4272004-06-13 20:20:40 +0000631 /* The 'scroll' option must be computed for all windows. */
Bram Moolenaarf740b292006-02-16 22:11:02 +0000632 FOR_ALL_TAB_WINDOWS(tp, wp)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000633 win_comp_scroll(wp);
Bram Moolenaar5a4eceb2014-09-09 17:33:07 +0200634#ifdef FEAT_CINDENT
635 parse_cino(curbuf);
636#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000637}
638
639/*
640 * Set the Vi-default value of a string option.
641 * Used for 'sh', 'backupskip' and 'term'.
Bram Moolenaar4bfa8af2018-02-03 15:14:46 +0100642 * When "escape" is TRUE escape spaces with a backslash.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000643 */
Bram Moolenaar4bfa8af2018-02-03 15:14:46 +0100644 static void
645set_string_default_esc(char *name, char_u *val, int escape)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000646{
647 char_u *p;
648 int opt_idx;
649
Bram Moolenaar4bfa8af2018-02-03 15:14:46 +0100650 if (escape && vim_strchr(val, ' ') != NULL)
651 p = vim_strsave_escaped(val, (char_u *)" ");
652 else
653 p = vim_strsave(val);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000654 if (p != NULL) /* we don't want a NULL */
655 {
656 opt_idx = findoption((char_u *)name);
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000657 if (opt_idx >= 0)
658 {
659 if (options[opt_idx].flags & P_DEF_ALLOCED)
660 vim_free(options[opt_idx].def_val[VI_DEFAULT]);
661 options[opt_idx].def_val[VI_DEFAULT] = p;
662 options[opt_idx].flags |= P_DEF_ALLOCED;
663 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000664 }
665}
666
Bram Moolenaar4bfa8af2018-02-03 15:14:46 +0100667 void
668set_string_default(char *name, char_u *val)
669{
670 set_string_default_esc(name, val, FALSE);
671}
672
Bram Moolenaar071d4272004-06-13 20:20:40 +0000673/*
674 * Set the Vi-default value of a number option.
675 * Used for 'lines' and 'columns'.
676 */
677 void
Bram Moolenaar9b578142016-01-30 19:39:49 +0100678set_number_default(char *name, long val)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000679{
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000680 int opt_idx;
681
682 opt_idx = findoption((char_u *)name);
683 if (opt_idx >= 0)
Bram Moolenaareb3593b2006-04-22 22:33:57 +0000684 options[opt_idx].def_val[VI_DEFAULT] = (char_u *)(long_i)val;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000685}
686
Bram Moolenaarcacc6a52019-05-30 15:22:43 +0200687/*
688 * Set all window-local and buffer-local options to the Vim default.
689 * local-global options will use the global value.
Bram Moolenaar46451042019-08-24 15:50:46 +0200690 * When "do_buffer" is FALSE don't set buffer-local options.
Bram Moolenaarcacc6a52019-05-30 15:22:43 +0200691 */
692 void
Bram Moolenaar46451042019-08-24 15:50:46 +0200693set_local_options_default(win_T *wp, int do_buffer)
Bram Moolenaarcacc6a52019-05-30 15:22:43 +0200694{
695 win_T *save_curwin = curwin;
696 int i;
697
698 curwin = wp;
699 curbuf = curwin->w_buffer;
700 block_autocmds();
701
Bram Moolenaardac13472019-09-16 21:06:21 +0200702 for (i = 0; !istermoption_idx(i); i++)
Bram Moolenaarcacc6a52019-05-30 15:22:43 +0200703 {
704 struct vimoption *p = &(options[i]);
705 char_u *varp = get_varp_scope(p, OPT_LOCAL);
706
707 if (p->indir != PV_NONE
Bram Moolenaar46451042019-08-24 15:50:46 +0200708 && (do_buffer || (p->indir & PV_BUF) == 0)
Bram Moolenaarcacc6a52019-05-30 15:22:43 +0200709 && !(options[i].flags & P_NODEFAULT)
710 && !optval_default(p, varp, FALSE))
Bram Moolenaar86173482019-10-01 17:02:16 +0200711 set_option_default(i, OPT_FREE|OPT_LOCAL, FALSE);
Bram Moolenaarcacc6a52019-05-30 15:22:43 +0200712 }
713
714 unblock_autocmds();
715 curwin = save_curwin;
716 curbuf = curwin->w_buffer;
717}
718
Bram Moolenaarf461c8e2005-06-25 23:04:51 +0000719#if defined(EXITFREE) || defined(PROTO)
720/*
721 * Free all options.
722 */
723 void
Bram Moolenaar9b578142016-01-30 19:39:49 +0100724free_all_options(void)
Bram Moolenaarf461c8e2005-06-25 23:04:51 +0000725{
726 int i;
727
Bram Moolenaardac13472019-09-16 21:06:21 +0200728 for (i = 0; !istermoption_idx(i); i++)
Bram Moolenaarf461c8e2005-06-25 23:04:51 +0000729 {
730 if (options[i].indir == PV_NONE)
731 {
732 /* global option: free value and default value. */
Bram Moolenaar67391142017-02-19 21:07:04 +0100733 if ((options[i].flags & P_ALLOCED) && options[i].var != NULL)
Bram Moolenaarf461c8e2005-06-25 23:04:51 +0000734 free_string_option(*(char_u **)options[i].var);
735 if (options[i].flags & P_DEF_ALLOCED)
736 free_string_option(options[i].def_val[VI_DEFAULT]);
737 }
738 else if (options[i].var != VAR_WIN
739 && (options[i].flags & P_STRING))
740 /* buffer-local option: free global value */
741 free_string_option(*(char_u **)options[i].var);
742 }
743}
744#endif
745
746
Bram Moolenaar071d4272004-06-13 20:20:40 +0000747/*
748 * Initialize the options, part two: After getting Rows and Columns and
749 * setting 'term'.
750 */
751 void
Bram Moolenaar9b578142016-01-30 19:39:49 +0100752set_init_2(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000753{
Bram Moolenaar4399ef42005-02-12 14:29:27 +0000754 int idx;
755
Bram Moolenaar071d4272004-06-13 20:20:40 +0000756 /*
Bram Moolenaaraf2d20c2017-10-29 15:26:57 +0100757 * 'scroll' defaults to half the window height. The stored default is zero,
758 * which results in the actual value computed from the window height.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000759 */
Bram Moolenaar26a60b42005-02-22 08:49:11 +0000760 idx = findoption((char_u *)"scroll");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000761 if (idx >= 0 && !(options[idx].flags & P_WAS_SET))
Bram Moolenaar26a60b42005-02-22 08:49:11 +0000762 set_option_default(idx, OPT_LOCAL, p_cp);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000763 comp_col();
764
Bram Moolenaar4399ef42005-02-12 14:29:27 +0000765 /*
766 * 'window' is only for backwards compatibility with Vi.
767 * Default is Rows - 1.
768 */
Bram Moolenaard68071d2006-05-02 22:08:30 +0000769 if (!option_was_set((char_u *)"window"))
Bram Moolenaar4399ef42005-02-12 14:29:27 +0000770 p_window = Rows - 1;
771 set_number_default("window", Rows - 1);
772
Bram Moolenaarf740b292006-02-16 22:11:02 +0000773 /* For DOS console the default is always black. */
Bram Moolenaar4f974752019-02-17 17:44:42 +0100774#if !((defined(MSWIN)) && !defined(FEAT_GUI))
Bram Moolenaarf740b292006-02-16 22:11:02 +0000775 /*
776 * If 'background' wasn't set by the user, try guessing the value,
777 * depending on the terminal name. Only need to check for terminals
778 * with a dark background, that can handle color.
779 */
780 idx = findoption((char_u *)"bg");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000781 if (idx >= 0 && !(options[idx].flags & P_WAS_SET)
782 && *term_bg_default() == 'd')
Bram Moolenaar071d4272004-06-13 20:20:40 +0000783 {
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +0000784 set_string_option_direct(NULL, idx, (char_u *)"dark", OPT_FREE, 0);
Bram Moolenaarf740b292006-02-16 22:11:02 +0000785 /* don't mark it as set, when starting the GUI it may be
786 * changed again */
787 options[idx].flags &= ~P_WAS_SET;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000788 }
789#endif
Bram Moolenaar58d98232005-07-23 22:25:46 +0000790
791#ifdef CURSOR_SHAPE
792 parse_shape_opt(SHAPE_CURSOR); /* set cursor shapes from 'guicursor' */
793#endif
794#ifdef FEAT_MOUSESHAPE
795 parse_shape_opt(SHAPE_MOUSE); /* set mouse shapes from 'mouseshape' */
796#endif
797#ifdef FEAT_PRINTER
798 (void)parse_printoptions(); /* parse 'printoptions' default value */
799#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000800}
801
802/*
Bram Moolenaarf740b292006-02-16 22:11:02 +0000803 * Return "dark" or "light" depending on the kind of terminal.
804 * This is just guessing! Recognized are:
805 * "linux" Linux console
806 * "screen.linux" Linux console with screen
Bram Moolenaarc6da01a2017-09-07 22:37:36 +0200807 * "cygwin.*" Cygwin shell
808 * "putty.*" Putty program
Bram Moolenaarf740b292006-02-16 22:11:02 +0000809 * We also check the COLORFGBG environment variable, which is set by
810 * rxvt and derivatives. This variable contains either two or three
811 * values separated by semicolons; we want the last value in either
812 * case. If this value is 0-6 or 8, our background is dark.
813 */
814 static char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +0100815term_bg_default(void)
Bram Moolenaarf740b292006-02-16 22:11:02 +0000816{
Bram Moolenaar4f974752019-02-17 17:44:42 +0100817#if defined(MSWIN)
Bram Moolenaarc6da01a2017-09-07 22:37:36 +0200818 /* DOS console is nearly always black */
Bram Moolenaarf740b292006-02-16 22:11:02 +0000819 return (char_u *)"dark";
820#else
Bram Moolenaarfaa959a2006-02-20 21:37:40 +0000821 char_u *p;
822
Bram Moolenaarf740b292006-02-16 22:11:02 +0000823 if (STRCMP(T_NAME, "linux") == 0
824 || STRCMP(T_NAME, "screen.linux") == 0
Bram Moolenaarc6da01a2017-09-07 22:37:36 +0200825 || STRNCMP(T_NAME, "cygwin", 6) == 0
826 || STRNCMP(T_NAME, "putty", 5) == 0
Bram Moolenaarf740b292006-02-16 22:11:02 +0000827 || ((p = mch_getenv((char_u *)"COLORFGBG")) != NULL
828 && (p = vim_strrchr(p, ';')) != NULL
829 && ((p[1] >= '0' && p[1] <= '6') || p[1] == '8')
830 && p[2] == NUL))
831 return (char_u *)"dark";
832 return (char_u *)"light";
833#endif
834}
835
836/*
Bram Moolenaar071d4272004-06-13 20:20:40 +0000837 * Initialize the options, part three: After reading the .vimrc
838 */
839 void
Bram Moolenaar9b578142016-01-30 19:39:49 +0100840set_init_3(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000841{
Bram Moolenaar4f974752019-02-17 17:44:42 +0100842#if defined(UNIX) || defined(MSWIN)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000843/*
844 * Set 'shellpipe' and 'shellredir', depending on the 'shell' option.
845 * This is done after other initializations, where 'shell' might have been
846 * set, but only if they have not been set before.
847 */
848 char_u *p;
849 int idx_srr;
850 int do_srr;
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100851# ifdef FEAT_QUICKFIX
Bram Moolenaar071d4272004-06-13 20:20:40 +0000852 int idx_sp;
853 int do_sp;
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100854# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000855
856 idx_srr = findoption((char_u *)"srr");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000857 if (idx_srr < 0)
858 do_srr = FALSE;
859 else
860 do_srr = !(options[idx_srr].flags & P_WAS_SET);
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100861# ifdef FEAT_QUICKFIX
Bram Moolenaar071d4272004-06-13 20:20:40 +0000862 idx_sp = findoption((char_u *)"sp");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000863 if (idx_sp < 0)
864 do_sp = FALSE;
865 else
866 do_sp = !(options[idx_sp].flags & P_WAS_SET);
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100867# endif
Bram Moolenaar75a8d742014-05-07 15:10:21 +0200868 p = get_isolated_shell_name();
Bram Moolenaar071d4272004-06-13 20:20:40 +0000869 if (p != NULL)
870 {
871 /*
872 * Default for p_sp is "| tee", for p_srr is ">".
873 * For known shells it is changed here to include stderr.
874 */
875 if ( fnamecmp(p, "csh") == 0
876 || fnamecmp(p, "tcsh") == 0
Bram Moolenaar4f974752019-02-17 17:44:42 +0100877# if defined(MSWIN) // also check with .exe extension
Bram Moolenaar071d4272004-06-13 20:20:40 +0000878 || fnamecmp(p, "csh.exe") == 0
879 || fnamecmp(p, "tcsh.exe") == 0
880# endif
881 )
882 {
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100883# if defined(FEAT_QUICKFIX)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000884 if (do_sp)
885 {
Bram Moolenaar4f974752019-02-17 17:44:42 +0100886# ifdef MSWIN
Bram Moolenaar071d4272004-06-13 20:20:40 +0000887 p_sp = (char_u *)">&";
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100888# else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000889 p_sp = (char_u *)"|& tee";
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100890# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000891 options[idx_sp].def_val[VI_DEFAULT] = p_sp;
892 }
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100893# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000894 if (do_srr)
895 {
896 p_srr = (char_u *)">&";
897 options[idx_srr].def_val[VI_DEFAULT] = p_srr;
898 }
899 }
900 else
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100901 /* Always use bourne shell style redirection if we reach this */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000902 if ( fnamecmp(p, "sh") == 0
903 || fnamecmp(p, "ksh") == 0
Bram Moolenaarf1fda2d2011-04-28 12:57:36 +0200904 || fnamecmp(p, "mksh") == 0
905 || fnamecmp(p, "pdksh") == 0
Bram Moolenaar071d4272004-06-13 20:20:40 +0000906 || fnamecmp(p, "zsh") == 0
Bram Moolenaarc1e37902006-04-18 21:55:01 +0000907 || fnamecmp(p, "zsh-beta") == 0
Bram Moolenaar071d4272004-06-13 20:20:40 +0000908 || fnamecmp(p, "bash") == 0
Bram Moolenaar75a8d742014-05-07 15:10:21 +0200909 || fnamecmp(p, "fish") == 0
Bram Moolenaar4f974752019-02-17 17:44:42 +0100910# ifdef MSWIN
Bram Moolenaar071d4272004-06-13 20:20:40 +0000911 || fnamecmp(p, "cmd") == 0
912 || fnamecmp(p, "sh.exe") == 0
913 || fnamecmp(p, "ksh.exe") == 0
Bram Moolenaarf1fda2d2011-04-28 12:57:36 +0200914 || fnamecmp(p, "mksh.exe") == 0
915 || fnamecmp(p, "pdksh.exe") == 0
Bram Moolenaar071d4272004-06-13 20:20:40 +0000916 || fnamecmp(p, "zsh.exe") == 0
Bram Moolenaarc1e37902006-04-18 21:55:01 +0000917 || fnamecmp(p, "zsh-beta.exe") == 0
Bram Moolenaar071d4272004-06-13 20:20:40 +0000918 || fnamecmp(p, "bash.exe") == 0
919 || fnamecmp(p, "cmd.exe") == 0
Bram Moolenaar071d4272004-06-13 20:20:40 +0000920# endif
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100921 )
Bram Moolenaar071d4272004-06-13 20:20:40 +0000922 {
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100923# if defined(FEAT_QUICKFIX)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000924 if (do_sp)
925 {
Bram Moolenaar4f974752019-02-17 17:44:42 +0100926# ifdef MSWIN
Bram Moolenaar071d4272004-06-13 20:20:40 +0000927 p_sp = (char_u *)">%s 2>&1";
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100928# else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000929 p_sp = (char_u *)"2>&1| tee";
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100930# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000931 options[idx_sp].def_val[VI_DEFAULT] = p_sp;
932 }
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100933# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000934 if (do_srr)
935 {
936 p_srr = (char_u *)">%s 2>&1";
937 options[idx_srr].def_val[VI_DEFAULT] = p_srr;
938 }
939 }
940 vim_free(p);
941 }
942#endif
943
Bram Moolenaar4f974752019-02-17 17:44:42 +0100944#if defined(MSWIN)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000945 /*
Bram Moolenaara64ba222012-02-12 23:23:31 +0100946 * Set 'shellcmdflag', 'shellxquote', and 'shellquote' depending on the
947 * 'shell' option.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000948 * This is done after other initializations, where 'shell' might have been
949 * set, but only if they have not been set before. Default for p_shcf is
950 * "/c", for p_shq is "". For "sh" like shells it is changed here to
Bram Moolenaar48e330a2016-02-23 14:53:34 +0100951 * "-c" and "\"". And for Win32 we need to set p_sxq instead.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000952 */
Bram Moolenaarf4b8e572004-06-24 15:53:16 +0000953 if (strstr((char *)gettail(p_sh), "sh") != NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000954 {
955 int idx3;
956
957 idx3 = findoption((char_u *)"shcf");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000958 if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000959 {
960 p_shcf = (char_u *)"-c";
961 options[idx3].def_val[VI_DEFAULT] = p_shcf;
962 }
963
Bram Moolenaar071d4272004-06-13 20:20:40 +0000964 /* Somehow Win32 requires the quotes around the redirection too */
965 idx3 = findoption((char_u *)"sxq");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000966 if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000967 {
968 p_sxq = (char_u *)"\"";
969 options[idx3].def_val[VI_DEFAULT] = p_sxq;
970 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000971 }
Bram Moolenaara64ba222012-02-12 23:23:31 +0100972 else if (strstr((char *)gettail(p_sh), "cmd.exe") != NULL)
973 {
974 int idx3;
975
976 /*
977 * cmd.exe on Windows will strip the first and last double quote given
978 * on the command line, e.g. most of the time things like:
979 * cmd /c "my path/to/echo" "my args to echo"
980 * become:
981 * my path/to/echo" "my args to echo
982 * when executed.
983 *
Bram Moolenaar034b1152012-02-19 18:19:30 +0100984 * To avoid this, set shellxquote to surround the command in
985 * parenthesis. This appears to make most commands work, without
986 * breaking commands that worked previously, such as
987 * '"path with spaces/cmd" "a&b"'.
Bram Moolenaara64ba222012-02-12 23:23:31 +0100988 */
Bram Moolenaara64ba222012-02-12 23:23:31 +0100989 idx3 = findoption((char_u *)"sxq");
990 if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET))
991 {
Bram Moolenaar034b1152012-02-19 18:19:30 +0100992 p_sxq = (char_u *)"(";
Bram Moolenaara64ba222012-02-12 23:23:31 +0100993 options[idx3].def_val[VI_DEFAULT] = p_sxq;
994 }
995
Bram Moolenaara64ba222012-02-12 23:23:31 +0100996 idx3 = findoption((char_u *)"shcf");
997 if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET))
998 {
Bram Moolenaar034b1152012-02-19 18:19:30 +0100999 p_shcf = (char_u *)"/c";
Bram Moolenaara64ba222012-02-12 23:23:31 +01001000 options[idx3].def_val[VI_DEFAULT] = p_shcf;
1001 }
1002 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001003#endif
1004
Bram Moolenaarb5aedf32017-03-12 18:23:53 +01001005 if (BUFEMPTY())
Bram Moolenaar364fa5c2016-03-20 17:53:25 +01001006 {
1007 int idx_ffs = findoption((char_u *)"ffs");
1008
1009 /* Apply the first entry of 'fileformats' to the initial buffer. */
1010 if (idx_ffs >= 0 && (options[idx_ffs].flags & P_WAS_SET))
1011 set_fileformat(default_fileformat(), OPT_LOCAL);
1012 }
1013
Bram Moolenaar071d4272004-06-13 20:20:40 +00001014#ifdef FEAT_TITLE
1015 set_title_defaults();
1016#endif
1017}
1018
1019#if defined(FEAT_MULTI_LANG) || defined(PROTO)
1020/*
1021 * When 'helplang' is still at its default value, set it to "lang".
1022 * Only the first two characters of "lang" are used.
1023 */
1024 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01001025set_helplang_default(char_u *lang)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001026{
1027 int idx;
1028
1029 if (lang == NULL || STRLEN(lang) < 2) /* safety check */
1030 return;
1031 idx = findoption((char_u *)"hlg");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +00001032 if (idx >= 0 && !(options[idx].flags & P_WAS_SET))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001033 {
1034 if (options[idx].flags & P_ALLOCED)
1035 free_string_option(p_hlg);
1036 p_hlg = vim_strsave(lang);
1037 if (p_hlg == NULL)
1038 p_hlg = empty_option;
1039 else
Bram Moolenaarab79bcb2004-07-18 21:34:53 +00001040 {
Bram Moolenaardcd71cb2018-11-04 14:40:47 +01001041 // zh_CN becomes "cn", zh_TW becomes "tw"
Bram Moolenaarab79bcb2004-07-18 21:34:53 +00001042 if (STRNICMP(p_hlg, "zh_", 3) == 0 && STRLEN(p_hlg) >= 5)
1043 {
1044 p_hlg[0] = TOLOWER_ASC(p_hlg[3]);
1045 p_hlg[1] = TOLOWER_ASC(p_hlg[4]);
1046 }
Bram Moolenaardcd71cb2018-11-04 14:40:47 +01001047 // any C like setting, such as C.UTF-8, becomes "en"
1048 else if (STRLEN(p_hlg) >= 1 && *p_hlg == 'C')
1049 {
1050 p_hlg[0] = 'e';
1051 p_hlg[1] = 'n';
1052 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001053 p_hlg[2] = NUL;
Bram Moolenaarab79bcb2004-07-18 21:34:53 +00001054 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001055 options[idx].flags |= P_ALLOCED;
1056 }
1057}
1058#endif
1059
1060#ifdef FEAT_GUI
Bram Moolenaar071d4272004-06-13 20:20:40 +00001061 static char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01001062gui_bg_default(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001063{
1064 if (gui_get_lightness(gui.back_pixel) < 127)
1065 return (char_u *)"dark";
1066 return (char_u *)"light";
1067}
1068
1069/*
1070 * Option initializations that can only be done after opening the GUI window.
1071 */
1072 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01001073init_gui_options(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001074{
1075 /* Set the 'background' option according to the lightness of the
1076 * background color, unless the user has set it already. */
1077 if (!option_was_set((char_u *)"bg") && STRCMP(p_bg, gui_bg_default()) != 0)
1078 {
1079 set_option_value((char_u *)"bg", 0L, gui_bg_default(), 0);
1080 highlight_changed();
1081 }
1082}
1083#endif
1084
1085#ifdef FEAT_TITLE
1086/*
1087 * 'title' and 'icon' only default to true if they have not been set or reset
1088 * in .vimrc and we can read the old value.
1089 * When 'title' and 'icon' have been reset in .vimrc, we won't even check if
1090 * they can be reset. This reduces startup time when using X on a remote
1091 * machine.
1092 */
1093 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01001094set_title_defaults(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001095{
1096 int idx1;
1097 long val;
1098
1099 /*
1100 * If GUI is (going to be) used, we can always set the window title and
1101 * icon name. Saves a bit of time, because the X11 display server does
1102 * not need to be contacted.
1103 */
1104 idx1 = findoption((char_u *)"title");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +00001105 if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001106 {
1107#ifdef FEAT_GUI
1108 if (gui.starting || gui.in_use)
1109 val = TRUE;
1110 else
1111#endif
1112 val = mch_can_restore_title();
Bram Moolenaareb3593b2006-04-22 22:33:57 +00001113 options[idx1].def_val[VI_DEFAULT] = (char_u *)(long_i)val;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001114 p_title = val;
1115 }
1116 idx1 = findoption((char_u *)"icon");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +00001117 if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001118 {
1119#ifdef FEAT_GUI
1120 if (gui.starting || gui.in_use)
1121 val = TRUE;
1122 else
1123#endif
1124 val = mch_can_restore_icon();
Bram Moolenaareb3593b2006-04-22 22:33:57 +00001125 options[idx1].def_val[VI_DEFAULT] = (char_u *)(long_i)val;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001126 p_icon = val;
1127 }
1128}
1129#endif
1130
1131/*
1132 * Parse 'arg' for option settings.
1133 *
1134 * 'arg' may be IObuff, but only when no errors can be present and option
1135 * does not need to be expanded with option_expand().
1136 * "opt_flags":
1137 * 0 for ":set"
Bram Moolenaara3227e22006-03-08 21:32:40 +00001138 * OPT_GLOBAL for ":setglobal"
1139 * OPT_LOCAL for ":setlocal" and a modeline
Bram Moolenaar071d4272004-06-13 20:20:40 +00001140 * OPT_MODELINE for a modeline
Bram Moolenaara3227e22006-03-08 21:32:40 +00001141 * OPT_WINONLY to only set window-local options
1142 * OPT_NOWIN to skip setting window-local options
Bram Moolenaar071d4272004-06-13 20:20:40 +00001143 *
1144 * returns FAIL if an error is detected, OK otherwise
1145 */
1146 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01001147do_set(
1148 char_u *arg, /* option string (may be written to!) */
1149 int opt_flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001150{
1151 int opt_idx;
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001152 char *errmsg;
1153 char errbuf[80];
Bram Moolenaar071d4272004-06-13 20:20:40 +00001154 char_u *startarg;
1155 int prefix; /* 1: nothing, 0: "no", 2: "inv" in front of name */
1156 int nextchar; /* next non-white char after option name */
1157 int afterchar; /* character just after option name */
1158 int len;
1159 int i;
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02001160 varnumber_T value;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001161 int key;
1162 long_u flags; /* flags for current option */
1163 char_u *varp = NULL; /* pointer to variable for current option */
1164 int did_show = FALSE; /* already showed one value */
1165 int adding; /* "opt+=arg" */
1166 int prepending; /* "opt^=arg" */
1167 int removing; /* "opt-=arg" */
1168 int cp_val = 0;
1169 char_u key_name[2];
1170
1171 if (*arg == NUL)
1172 {
1173 showoptions(0, opt_flags);
Bram Moolenaar26a60b42005-02-22 08:49:11 +00001174 did_show = TRUE;
1175 goto theend;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001176 }
1177
1178 while (*arg != NUL) /* loop to process all options */
1179 {
1180 errmsg = NULL;
1181 startarg = arg; /* remember for error message */
1182
Bram Moolenaar293ee4d2004-12-09 21:34:53 +00001183 if (STRNCMP(arg, "all", 3) == 0 && !isalpha(arg[3])
1184 && !(opt_flags & OPT_MODELINE))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001185 {
1186 /*
1187 * ":set all" show all options.
1188 * ":set all&" set all options to their default value.
1189 */
1190 arg += 3;
1191 if (*arg == '&')
1192 {
1193 ++arg;
1194 /* Only for :set command set global value of local options. */
1195 set_options_default(OPT_FREE | opt_flags);
Bram Moolenaare68c25c2015-08-25 15:39:55 +02001196 didset_options();
1197 didset_options2();
Bram Moolenaarb341dda2015-08-25 12:56:31 +02001198 redraw_all_later(CLEAR);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001199 }
1200 else
Bram Moolenaar26a60b42005-02-22 08:49:11 +00001201 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001202 showoptions(1, opt_flags);
Bram Moolenaar26a60b42005-02-22 08:49:11 +00001203 did_show = TRUE;
1204 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001205 }
Bram Moolenaar293ee4d2004-12-09 21:34:53 +00001206 else if (STRNCMP(arg, "termcap", 7) == 0 && !(opt_flags & OPT_MODELINE))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001207 {
1208 showoptions(2, opt_flags);
1209 show_termcodes();
Bram Moolenaar26a60b42005-02-22 08:49:11 +00001210 did_show = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001211 arg += 7;
1212 }
1213 else
1214 {
1215 prefix = 1;
Bram Moolenaar2a7b9ee2009-06-16 15:50:33 +00001216 if (STRNCMP(arg, "no", 2) == 0 && STRNCMP(arg, "novice", 6) != 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001217 {
1218 prefix = 0;
1219 arg += 2;
1220 }
1221 else if (STRNCMP(arg, "inv", 3) == 0)
1222 {
1223 prefix = 2;
1224 arg += 3;
1225 }
1226
1227 /* find end of name */
1228 key = 0;
1229 if (*arg == '<')
1230 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001231 opt_idx = -1;
1232 /* look out for <t_>;> */
1233 if (arg[1] == 't' && arg[2] == '_' && arg[3] && arg[4])
1234 len = 5;
1235 else
1236 {
1237 len = 1;
1238 while (arg[len] != NUL && arg[len] != '>')
1239 ++len;
1240 }
1241 if (arg[len] != '>')
1242 {
1243 errmsg = e_invarg;
1244 goto skip;
1245 }
1246 arg[len] = NUL; /* put NUL after name */
1247 if (arg[1] == 't' && arg[2] == '_') /* could be term code */
1248 opt_idx = findoption(arg + 1);
1249 arg[len++] = '>'; /* restore '>' */
1250 if (opt_idx == -1)
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02001251 key = find_key_option(arg + 1, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001252 }
1253 else
1254 {
1255 len = 0;
1256 /*
1257 * The two characters after "t_" may not be alphanumeric.
1258 */
1259 if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
1260 len = 4;
1261 else
1262 while (ASCII_ISALNUM(arg[len]) || arg[len] == '_')
1263 ++len;
1264 nextchar = arg[len];
1265 arg[len] = NUL; /* put NUL after name */
1266 opt_idx = findoption(arg);
1267 arg[len] = nextchar; /* restore nextchar */
1268 if (opt_idx == -1)
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02001269 key = find_key_option(arg, FALSE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001270 }
1271
1272 /* remember character after option name */
1273 afterchar = arg[len];
1274
1275 /* skip white space, allow ":set ai ?" */
Bram Moolenaar1c465442017-03-12 20:10:05 +01001276 while (VIM_ISWHITE(arg[len]))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001277 ++len;
1278
1279 adding = FALSE;
1280 prepending = FALSE;
1281 removing = FALSE;
1282 if (arg[len] != NUL && arg[len + 1] == '=')
1283 {
1284 if (arg[len] == '+')
1285 {
1286 adding = TRUE; /* "+=" */
1287 ++len;
1288 }
1289 else if (arg[len] == '^')
1290 {
1291 prepending = TRUE; /* "^=" */
1292 ++len;
1293 }
1294 else if (arg[len] == '-')
1295 {
1296 removing = TRUE; /* "-=" */
1297 ++len;
1298 }
1299 }
1300 nextchar = arg[len];
1301
1302 if (opt_idx == -1 && key == 0) /* found a mismatch: skip */
1303 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001304 errmsg = N_("E518: Unknown option");
Bram Moolenaar071d4272004-06-13 20:20:40 +00001305 goto skip;
1306 }
1307
1308 if (opt_idx >= 0)
1309 {
1310 if (options[opt_idx].var == NULL) /* hidden option: skip */
1311 {
1312 /* Only give an error message when requesting the value of
1313 * a hidden option, ignore setting it. */
1314 if (vim_strchr((char_u *)"=:!&<", nextchar) == NULL
1315 && (!(options[opt_idx].flags & P_BOOL)
1316 || nextchar == '?'))
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001317 errmsg = N_("E519: Option not supported");
Bram Moolenaar071d4272004-06-13 20:20:40 +00001318 goto skip;
1319 }
1320
1321 flags = options[opt_idx].flags;
1322 varp = get_varp_scope(&(options[opt_idx]), opt_flags);
1323 }
1324 else
1325 {
1326 flags = P_STRING;
1327 if (key < 0)
1328 {
1329 key_name[0] = KEY2TERMCAP0(key);
1330 key_name[1] = KEY2TERMCAP1(key);
1331 }
1332 else
1333 {
1334 key_name[0] = KS_KEY;
1335 key_name[1] = (key & 0xff);
1336 }
1337 }
1338
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001339 /* Skip all options that are not window-local (used when showing
1340 * an already loaded buffer in a window). */
1341 if ((opt_flags & OPT_WINONLY)
1342 && (opt_idx < 0 || options[opt_idx].var != VAR_WIN))
1343 goto skip;
1344
Bram Moolenaara3227e22006-03-08 21:32:40 +00001345 /* Skip all options that are window-local (used for :vimgrep). */
1346 if ((opt_flags & OPT_NOWIN) && opt_idx >= 0
1347 && options[opt_idx].var == VAR_WIN)
1348 goto skip;
1349
Bram Moolenaar1bf0ddc2009-02-11 15:47:05 +00001350 /* Disallow changing some options from modelines. */
1351 if (opt_flags & OPT_MODELINE)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001352 {
Bram Moolenaar865242e2010-07-14 21:12:05 +02001353 if (flags & (P_SECURE | P_NO_ML))
Bram Moolenaar1bf0ddc2009-02-11 15:47:05 +00001354 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001355 errmsg = _("E520: Not allowed in a modeline");
Bram Moolenaar1bf0ddc2009-02-11 15:47:05 +00001356 goto skip;
1357 }
Bram Moolenaar110289e2019-05-23 15:38:06 +02001358 if ((flags & P_MLE) && !p_mle)
1359 {
1360 errmsg = _("E992: Not allowed in a modeline when 'modelineexpr' is off");
1361 goto skip;
1362 }
Bram Moolenaarf69d9a32009-02-11 21:48:40 +00001363#ifdef FEAT_DIFF
Bram Moolenaar1bf0ddc2009-02-11 15:47:05 +00001364 /* In diff mode some options are overruled. This avoids that
1365 * 'foldmethod' becomes "marker" instead of "diff" and that
1366 * "wrap" gets set. */
1367 if (curwin->w_p_diff
Bram Moolenaara9d52e32010-07-31 16:44:19 +02001368 && opt_idx >= 0 /* shut up coverity warning */
Bram Moolenaara6c07602017-03-05 21:18:27 +01001369 && (
1370#ifdef FEAT_FOLDING
1371 options[opt_idx].indir == PV_FDM ||
1372#endif
1373 options[opt_idx].indir == PV_WRAP))
Bram Moolenaar1bf0ddc2009-02-11 15:47:05 +00001374 goto skip;
Bram Moolenaarf69d9a32009-02-11 21:48:40 +00001375#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00001376 }
1377
1378#ifdef HAVE_SANDBOX
1379 /* Disallow changing some options in the sandbox */
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001380 if (sandbox != 0 && (flags & P_SECURE))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001381 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001382 errmsg = _(e_sandbox);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001383 goto skip;
1384 }
1385#endif
1386
1387 if (vim_strchr((char_u *)"?=:!&<", nextchar) != NULL)
1388 {
1389 arg += len;
1390 cp_val = p_cp;
1391 if (nextchar == '&' && arg[1] == 'v' && arg[2] == 'i')
1392 {
1393 if (arg[3] == 'm') /* "opt&vim": set to Vim default */
1394 {
1395 cp_val = FALSE;
1396 arg += 3;
1397 }
1398 else /* "opt&vi": set to Vi default */
1399 {
1400 cp_val = TRUE;
1401 arg += 2;
1402 }
1403 }
1404 if (vim_strchr((char_u *)"?!&<", nextchar) != NULL
Bram Moolenaar1c465442017-03-12 20:10:05 +01001405 && arg[1] != NUL && !VIM_ISWHITE(arg[1]))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001406 {
1407 errmsg = e_trailing;
1408 goto skip;
1409 }
1410 }
1411
1412 /*
Bram Moolenaar48e330a2016-02-23 14:53:34 +01001413 * allow '=' and ':' for hystorical reasons (MSDOS command.com
1414 * allows only one '=' character per "set" command line. grrr. (jw)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001415 */
1416 if (nextchar == '?'
1417 || (prefix == 1
1418 && vim_strchr((char_u *)"=:&<", nextchar) == NULL
1419 && !(flags & P_BOOL)))
1420 {
1421 /*
1422 * print value
1423 */
1424 if (did_show)
1425 msg_putchar('\n'); /* cursor below last one */
1426 else
1427 {
1428 gotocmdline(TRUE); /* cursor at status line */
1429 did_show = TRUE; /* remember that we did a line */
1430 }
1431 if (opt_idx >= 0)
1432 {
1433 showoneopt(&options[opt_idx], opt_flags);
1434#ifdef FEAT_EVAL
1435 if (p_verbose > 0)
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00001436 {
1437 /* Mention where the option was last set. */
1438 if (varp == options[opt_idx].var)
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02001439 last_set_msg(options[opt_idx].script_ctx);
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00001440 else if ((int)options[opt_idx].indir & PV_WIN)
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02001441 last_set_msg(curwin->w_p_script_ctx[
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00001442 (int)options[opt_idx].indir & PV_MASK]);
1443 else if ((int)options[opt_idx].indir & PV_BUF)
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02001444 last_set_msg(curbuf->b_p_script_ctx[
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00001445 (int)options[opt_idx].indir & PV_MASK]);
1446 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001447#endif
1448 }
1449 else
1450 {
1451 char_u *p;
1452
1453 p = find_termcode(key_name);
1454 if (p == NULL)
1455 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001456 errmsg = N_("E846: Key code not set");
Bram Moolenaar071d4272004-06-13 20:20:40 +00001457 goto skip;
1458 }
1459 else
1460 (void)show_one_termcode(key_name, p, TRUE);
1461 }
1462 if (nextchar != '?'
Bram Moolenaar1c465442017-03-12 20:10:05 +01001463 && nextchar != NUL && !VIM_ISWHITE(afterchar))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001464 errmsg = e_trailing;
1465 }
1466 else
1467 {
Bram Moolenaar247bb7e2018-11-20 14:27:07 +01001468 int value_is_replaced = !prepending && !adding && !removing;
Bram Moolenaar916a8182018-11-25 02:18:29 +01001469 int value_checked = FALSE;
Bram Moolenaar247bb7e2018-11-20 14:27:07 +01001470
Bram Moolenaar071d4272004-06-13 20:20:40 +00001471 if (flags & P_BOOL) /* boolean */
1472 {
1473 if (nextchar == '=' || nextchar == ':')
1474 {
1475 errmsg = e_invarg;
1476 goto skip;
1477 }
1478
1479 /*
1480 * ":set opt!": invert
1481 * ":set opt&": reset to default value
1482 * ":set opt<": reset to global value
1483 */
1484 if (nextchar == '!')
1485 value = *(int *)(varp) ^ 1;
1486 else if (nextchar == '&')
Bram Moolenaareb3593b2006-04-22 22:33:57 +00001487 value = (int)(long)(long_i)options[opt_idx].def_val[
Bram Moolenaar071d4272004-06-13 20:20:40 +00001488 ((flags & P_VI_DEF) || cp_val)
1489 ? VI_DEFAULT : VIM_DEFAULT];
1490 else if (nextchar == '<')
1491 {
1492 /* For 'autoread' -1 means to use global value. */
1493 if ((int *)varp == &curbuf->b_p_ar
1494 && opt_flags == OPT_LOCAL)
1495 value = -1;
1496 else
1497 value = *(int *)get_varp_scope(&(options[opt_idx]),
1498 OPT_GLOBAL);
1499 }
1500 else
1501 {
1502 /*
1503 * ":set invopt": invert
1504 * ":set opt" or ":set noopt": set or reset
1505 */
Bram Moolenaar1c465442017-03-12 20:10:05 +01001506 if (nextchar != NUL && !VIM_ISWHITE(afterchar))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001507 {
1508 errmsg = e_trailing;
1509 goto skip;
1510 }
1511 if (prefix == 2) /* inv */
1512 value = *(int *)(varp) ^ 1;
1513 else
1514 value = prefix;
1515 }
1516
1517 errmsg = set_bool_option(opt_idx, varp, (int)value,
1518 opt_flags);
1519 }
1520 else /* numeric or string */
1521 {
1522 if (vim_strchr((char_u *)"=:&<", nextchar) == NULL
1523 || prefix != 1)
1524 {
1525 errmsg = e_invarg;
1526 goto skip;
1527 }
1528
1529 if (flags & P_NUM) /* numeric */
1530 {
1531 /*
1532 * Different ways to set a number option:
1533 * & set to default value
1534 * < set to global value
1535 * <xx> accept special key codes for 'wildchar'
1536 * c accept any non-digit for 'wildchar'
1537 * [-]0-9 set number
1538 * other error
1539 */
1540 ++arg;
1541 if (nextchar == '&')
Bram Moolenaareb3593b2006-04-22 22:33:57 +00001542 value = (long)(long_i)options[opt_idx].def_val[
Bram Moolenaar071d4272004-06-13 20:20:40 +00001543 ((flags & P_VI_DEF) || cp_val)
1544 ? VI_DEFAULT : VIM_DEFAULT];
1545 else if (nextchar == '<')
Bram Moolenaarf5a2fd82013-11-06 05:26:15 +01001546 {
1547 /* For 'undolevels' NO_LOCAL_UNDOLEVEL means to
1548 * use the global value. */
1549 if ((long *)varp == &curbuf->b_p_ul
1550 && opt_flags == OPT_LOCAL)
1551 value = NO_LOCAL_UNDOLEVEL;
1552 else
1553 value = *(long *)get_varp_scope(
1554 &(options[opt_idx]), OPT_GLOBAL);
1555 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001556 else if (((long *)varp == &p_wc
1557 || (long *)varp == &p_wcm)
1558 && (*arg == '<'
1559 || *arg == '^'
Bram Moolenaar1c465442017-03-12 20:10:05 +01001560 || (*arg != NUL
1561 && (!arg[1] || VIM_ISWHITE(arg[1]))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001562 && !VIM_ISDIGIT(*arg))))
1563 {
Bram Moolenaardbe948d2017-07-23 22:50:51 +02001564 value = string_to_key(arg, FALSE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001565 if (value == 0 && (long *)varp != &p_wcm)
1566 {
1567 errmsg = e_invarg;
1568 goto skip;
1569 }
1570 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001571 else if (*arg == '-' || VIM_ISDIGIT(*arg))
1572 {
Bram Moolenaar18400e62015-01-27 15:58:40 +01001573 /* Allow negative (for 'undolevels'), octal and
1574 * hex numbers. */
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001575 vim_str2nr(arg, NULL, &i, STR2NR_ALL,
Bram Moolenaar16e9b852019-05-19 19:59:35 +02001576 &value, NULL, 0, TRUE);
Bram Moolenaar06e2c812019-06-12 19:05:48 +02001577 if (i == 0 || (arg[i] != NUL
1578 && !VIM_ISWHITE(arg[i])))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001579 {
Bram Moolenaar16e9b852019-05-19 19:59:35 +02001580 errmsg = N_("E521: Number required after =");
Bram Moolenaar071d4272004-06-13 20:20:40 +00001581 goto skip;
1582 }
1583 }
1584 else
1585 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001586 errmsg = N_("E521: Number required after =");
Bram Moolenaar071d4272004-06-13 20:20:40 +00001587 goto skip;
1588 }
1589
1590 if (adding)
1591 value = *(long *)varp + value;
1592 if (prepending)
1593 value = *(long *)varp * value;
1594 if (removing)
1595 value = *(long *)varp - value;
1596 errmsg = set_num_option(opt_idx, varp, value,
Bram Moolenaar555b2802005-05-19 21:08:39 +00001597 errbuf, sizeof(errbuf), opt_flags);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001598 }
1599 else if (opt_idx >= 0) /* string */
1600 {
Bram Moolenaar8efa0262017-08-20 15:47:20 +02001601 char_u *save_arg = NULL;
1602 char_u *s = NULL;
1603 char_u *oldval = NULL; /* previous value if *varp */
1604 char_u *newval;
1605 char_u *origval = NULL;
Bram Moolenaard7c96872019-06-15 17:12:48 +02001606 char_u *origval_l = NULL;
1607 char_u *origval_g = NULL;
Bram Moolenaarf2bd8ef2018-03-04 18:08:14 +01001608#if defined(FEAT_EVAL)
Bram Moolenaar8efa0262017-08-20 15:47:20 +02001609 char_u *saved_origval = NULL;
Bram Moolenaard7c96872019-06-15 17:12:48 +02001610 char_u *saved_origval_l = NULL;
1611 char_u *saved_origval_g = NULL;
Bram Moolenaar8efa0262017-08-20 15:47:20 +02001612 char_u *saved_newval = NULL;
Bram Moolenaar53744302015-07-17 17:38:22 +02001613#endif
Bram Moolenaar8efa0262017-08-20 15:47:20 +02001614 unsigned newlen;
1615 int comma;
1616 int bs;
1617 int new_value_alloced; /* new string option
Bram Moolenaar071d4272004-06-13 20:20:40 +00001618 was allocated */
1619
1620 /* When using ":set opt=val" for a global option
1621 * with a local value the local value will be
1622 * reset, use the global value here. */
1623 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
Bram Moolenaara23ccb82006-02-27 00:08:02 +00001624 && ((int)options[opt_idx].indir & PV_BOTH))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001625 varp = options[opt_idx].var;
1626
1627 /* The old value is kept until we are sure that the
1628 * new value is valid. */
1629 oldval = *(char_u **)varp;
Bram Moolenaar8efa0262017-08-20 15:47:20 +02001630
Bram Moolenaard7c96872019-06-15 17:12:48 +02001631 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
1632 {
1633 origval_l = *(char_u **)get_varp_scope(
1634 &(options[opt_idx]), OPT_LOCAL);
1635 origval_g = *(char_u **)get_varp_scope(
1636 &(options[opt_idx]), OPT_GLOBAL);
1637
1638 // A global-local string option might have an empty
1639 // option as value to indicate that the global
1640 // value should be used.
1641 if (((int)options[opt_idx].indir & PV_BOTH)
1642 && origval_l == empty_option)
1643 origval_l = origval_g;
1644 }
1645
1646 // When setting the local value of a global
1647 // option, the old value may be the global value.
Bram Moolenaar8efa0262017-08-20 15:47:20 +02001648 if (((int)options[opt_idx].indir & PV_BOTH)
1649 && (opt_flags & OPT_LOCAL))
1650 origval = *(char_u **)get_varp(
1651 &options[opt_idx]);
1652 else
1653 origval = oldval;
1654
Bram Moolenaar071d4272004-06-13 20:20:40 +00001655 if (nextchar == '&') /* set to default val */
1656 {
1657 newval = options[opt_idx].def_val[
1658 ((flags & P_VI_DEF) || cp_val)
1659 ? VI_DEFAULT : VIM_DEFAULT];
1660 if ((char_u **)varp == &p_bg)
1661 {
1662 /* guess the value of 'background' */
1663#ifdef FEAT_GUI
1664 if (gui.in_use)
1665 newval = gui_bg_default();
1666 else
1667#endif
Bram Moolenaarf740b292006-02-16 22:11:02 +00001668 newval = term_bg_default();
Bram Moolenaar071d4272004-06-13 20:20:40 +00001669 }
1670
1671 /* expand environment variables and ~ (since the
1672 * default value was already expanded, only
1673 * required when an environment variable was set
1674 * later */
1675 if (newval == NULL)
1676 newval = empty_option;
1677 else
1678 {
1679 s = option_expand(opt_idx, newval);
1680 if (s == NULL)
1681 s = newval;
1682 newval = vim_strsave(s);
1683 }
1684 new_value_alloced = TRUE;
1685 }
1686 else if (nextchar == '<') /* set to global val */
1687 {
1688 newval = vim_strsave(*(char_u **)get_varp_scope(
1689 &(options[opt_idx]), OPT_GLOBAL));
1690 new_value_alloced = TRUE;
1691 }
1692 else
1693 {
1694 ++arg; /* jump to after the '=' or ':' */
1695
1696 /*
1697 * Set 'keywordprg' to ":help" if an empty
1698 * value was passed to :set by the user.
1699 * Misuse errbuf[] for the resulting string.
1700 */
1701 if (varp == (char_u *)&p_kp
1702 && (*arg == NUL || *arg == ' '))
1703 {
1704 STRCPY(errbuf, ":help");
1705 save_arg = arg;
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001706 arg = (char_u *)errbuf;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001707 }
1708 /*
Bram Moolenaar4e5ccfa2011-11-30 11:15:47 +01001709 * Convert 'backspace' number to string, for
1710 * adding, prepending and removing string.
1711 */
1712 else if (varp == (char_u *)&p_bs
1713 && VIM_ISDIGIT(**(char_u **)varp))
1714 {
1715 i = getdigits((char_u **)varp);
1716 switch (i)
1717 {
1718 case 0:
1719 *(char_u **)varp = empty_option;
1720 break;
1721 case 1:
1722 *(char_u **)varp = vim_strsave(
1723 (char_u *)"indent,eol");
1724 break;
1725 case 2:
1726 *(char_u **)varp = vim_strsave(
1727 (char_u *)"indent,eol,start");
1728 break;
1729 }
1730 vim_free(oldval);
Bram Moolenaaredbc0d42017-08-20 16:11:51 +02001731 if (origval == oldval)
1732 origval = *(char_u **)varp;
Bram Moolenaard7c96872019-06-15 17:12:48 +02001733 if (origval_l == oldval)
1734 origval_l = *(char_u **)varp;
1735 if (origval_g == oldval)
1736 origval_g = *(char_u **)varp;
Bram Moolenaar4e5ccfa2011-11-30 11:15:47 +01001737 oldval = *(char_u **)varp;
1738 }
1739 /*
Bram Moolenaar071d4272004-06-13 20:20:40 +00001740 * Convert 'whichwrap' number to string, for
1741 * backwards compatibility with Vim 3.0.
1742 * Misuse errbuf[] for the resulting string.
1743 */
1744 else if (varp == (char_u *)&p_ww
1745 && VIM_ISDIGIT(*arg))
1746 {
1747 *errbuf = NUL;
1748 i = getdigits(&arg);
1749 if (i & 1)
1750 STRCAT(errbuf, "b,");
1751 if (i & 2)
1752 STRCAT(errbuf, "s,");
1753 if (i & 4)
1754 STRCAT(errbuf, "h,l,");
1755 if (i & 8)
1756 STRCAT(errbuf, "<,>,");
1757 if (i & 16)
1758 STRCAT(errbuf, "[,],");
1759 if (*errbuf != NUL) /* remove trailing , */
1760 errbuf[STRLEN(errbuf) - 1] = NUL;
1761 save_arg = arg;
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001762 arg = (char_u *)errbuf;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001763 }
1764 /*
1765 * Remove '>' before 'dir' and 'bdir', for
1766 * backwards compatibility with version 3.0
1767 */
1768 else if ( *arg == '>'
1769 && (varp == (char_u *)&p_dir
1770 || varp == (char_u *)&p_bdir))
1771 {
1772 ++arg;
1773 }
1774
Bram Moolenaar071d4272004-06-13 20:20:40 +00001775 /*
1776 * Copy the new string into allocated memory.
1777 * Can't use set_string_option_direct(), because
1778 * we need to remove the backslashes.
1779 */
1780 /* get a bit too much */
1781 newlen = (unsigned)STRLEN(arg) + 1;
1782 if (adding || prepending || removing)
1783 newlen += (unsigned)STRLEN(origval) + 1;
1784 newval = alloc(newlen);
1785 if (newval == NULL) /* out of mem, don't change */
1786 break;
1787 s = newval;
1788
1789 /*
1790 * Copy the string, skip over escaped chars.
1791 * For MS-DOS and WIN32 backslashes before normal
1792 * file name characters are not removed, and keep
1793 * backslash at start, for "\\machine\path", but
1794 * do remove it for "\\\\machine\\path".
1795 * The reverse is found in ExpandOldSetting().
1796 */
Bram Moolenaar1c465442017-03-12 20:10:05 +01001797 while (*arg && !VIM_ISWHITE(*arg))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001798 {
1799 if (*arg == '\\' && arg[1] != NUL
1800#ifdef BACKSLASH_IN_FILENAME
1801 && !((flags & P_EXPAND)
1802 && vim_isfilec(arg[1])
1803 && (arg[1] != '\\'
1804 || (s == newval
1805 && arg[2] != '\\')))
1806#endif
1807 )
1808 ++arg; /* remove backslash */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001809 if (has_mbyte
Bram Moolenaar0fa313a2005-08-10 21:07:57 +00001810 && (i = (*mb_ptr2len)(arg)) > 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001811 {
1812 /* copy multibyte char */
1813 mch_memmove(s, arg, (size_t)i);
1814 arg += i;
1815 s += i;
1816 }
1817 else
Bram Moolenaar071d4272004-06-13 20:20:40 +00001818 *s++ = *arg++;
1819 }
1820 *s = NUL;
1821
1822 /*
1823 * Expand environment variables and ~.
1824 * Don't do it when adding without inserting a
1825 * comma.
1826 */
1827 if (!(adding || prepending || removing)
1828 || (flags & P_COMMA))
1829 {
1830 s = option_expand(opt_idx, newval);
1831 if (s != NULL)
1832 {
1833 vim_free(newval);
1834 newlen = (unsigned)STRLEN(s) + 1;
1835 if (adding || prepending || removing)
1836 newlen += (unsigned)STRLEN(origval) + 1;
1837 newval = alloc(newlen);
1838 if (newval == NULL)
1839 break;
1840 STRCPY(newval, s);
1841 }
1842 }
1843
1844 /* locate newval[] in origval[] when removing it
1845 * and when adding to avoid duplicates */
1846 i = 0; /* init for GCC */
1847 if (removing || (flags & P_NODUP))
1848 {
1849 i = (int)STRLEN(newval);
1850 bs = 0;
1851 for (s = origval; *s; ++s)
1852 {
1853 if ((!(flags & P_COMMA)
1854 || s == origval
1855 || (s[-1] == ',' && !(bs & 1)))
1856 && STRNCMP(s, newval, i) == 0
1857 && (!(flags & P_COMMA)
1858 || s[i] == ','
1859 || s[i] == NUL))
1860 break;
Bram Moolenaar0b2f94d2011-03-22 14:35:05 +01001861 /* Count backslashes. Only a comma with an
Bram Moolenaar8f79acd2016-01-01 14:48:20 +01001862 * even number of backslashes or a single
1863 * backslash preceded by a comma before it
1864 * is recognized as a separator */
1865 if ((s > origval + 1
1866 && s[-1] == '\\'
1867 && s[-2] != ',')
1868 || (s == origval + 1
1869 && s[-1] == '\\'))
1870
Bram Moolenaar071d4272004-06-13 20:20:40 +00001871 ++bs;
1872 else
1873 bs = 0;
1874 }
1875
1876 /* do not add if already there */
1877 if ((adding || prepending) && *s)
1878 {
1879 prepending = FALSE;
1880 adding = FALSE;
1881 STRCPY(newval, origval);
1882 }
1883 }
1884
1885 /* concatenate the two strings; add a ',' if
1886 * needed */
1887 if (adding || prepending)
1888 {
1889 comma = ((flags & P_COMMA) && *origval != NUL
1890 && *newval != NUL);
1891 if (adding)
1892 {
1893 i = (int)STRLEN(origval);
Bram Moolenaara7b7b1c2015-06-19 14:06:43 +02001894 /* strip a trailing comma, would get 2 */
Bram Moolenaar17467472015-11-10 17:50:24 +01001895 if (comma && i > 1
1896 && (flags & P_ONECOMMA) == P_ONECOMMA
1897 && origval[i - 1] == ','
1898 && origval[i - 2] != '\\')
Bram Moolenaara7b7b1c2015-06-19 14:06:43 +02001899 i--;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001900 mch_memmove(newval + i + comma, newval,
1901 STRLEN(newval) + 1);
1902 mch_memmove(newval, origval, (size_t)i);
1903 }
1904 else
1905 {
1906 i = (int)STRLEN(newval);
Bram Moolenaarc1a11ed2008-06-24 22:09:24 +00001907 STRMOVE(newval + i + comma, origval);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001908 }
1909 if (comma)
1910 newval[i] = ',';
1911 }
1912
1913 /* Remove newval[] from origval[]. (Note: "i" has
1914 * been set above and is used here). */
1915 if (removing)
1916 {
1917 STRCPY(newval, origval);
1918 if (*s)
1919 {
1920 /* may need to remove a comma */
1921 if (flags & P_COMMA)
1922 {
1923 if (s == origval)
1924 {
1925 /* include comma after string */
1926 if (s[i] == ',')
1927 ++i;
1928 }
1929 else
1930 {
1931 /* include comma before string */
1932 --s;
1933 ++i;
1934 }
1935 }
Bram Moolenaarc1a11ed2008-06-24 22:09:24 +00001936 STRMOVE(newval + (s - origval), s + i);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001937 }
1938 }
1939
1940 if (flags & P_FLAGLIST)
1941 {
1942 /* Remove flags that appear twice. */
Bram Moolenaaraaaf57d2017-02-05 14:13:20 +01001943 for (s = newval; *s;)
Bram Moolenaarc8ce6152016-08-07 13:48:20 +02001944 {
1945 /* if options have P_FLAGLIST and
1946 * P_ONECOMMA such as 'whichwrap' */
1947 if (flags & P_ONECOMMA)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001948 {
Bram Moolenaarc8ce6152016-08-07 13:48:20 +02001949 if (*s != ',' && *(s + 1) == ','
1950 && vim_strchr(s + 2, *s) != NULL)
1951 {
1952 /* Remove the duplicated value and
1953 * the next comma. */
1954 STRMOVE(s, s + 2);
Bram Moolenaaraaaf57d2017-02-05 14:13:20 +01001955 continue;
Bram Moolenaarc8ce6152016-08-07 13:48:20 +02001956 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001957 }
Bram Moolenaarc8ce6152016-08-07 13:48:20 +02001958 else
1959 {
1960 if ((!(flags & P_COMMA) || *s != ',')
1961 && vim_strchr(s + 1, *s) != NULL)
1962 {
1963 STRMOVE(s, s + 1);
Bram Moolenaaraaaf57d2017-02-05 14:13:20 +01001964 continue;
Bram Moolenaarc8ce6152016-08-07 13:48:20 +02001965 }
1966 }
Bram Moolenaaraaaf57d2017-02-05 14:13:20 +01001967 ++s;
Bram Moolenaarc8ce6152016-08-07 13:48:20 +02001968 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001969 }
1970
1971 if (save_arg != NULL) /* number for 'whichwrap' */
1972 arg = save_arg;
1973 new_value_alloced = TRUE;
1974 }
1975
Bram Moolenaar8efa0262017-08-20 15:47:20 +02001976 /*
1977 * Set the new value.
1978 */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001979 *(char_u **)(varp) = newval;
1980
Bram Moolenaarf2bd8ef2018-03-04 18:08:14 +01001981#if defined(FEAT_EVAL)
Bram Moolenaar5cbb8db2015-07-17 23:08:29 +02001982 if (!starting
1983# ifdef FEAT_CRYPT
1984 && options[opt_idx].indir != PV_KEY
1985# endif
Bram Moolenaar182a17b2017-06-25 20:57:18 +02001986 && origval != NULL && newval != NULL)
1987 {
Bram Moolenaar53744302015-07-17 17:38:22 +02001988 /* origval may be freed by
1989 * did_set_string_option(), make a copy. */
1990 saved_origval = vim_strsave(origval);
Bram Moolenaar182a17b2017-06-25 20:57:18 +02001991 /* newval (and varp) may become invalid if the
1992 * buffer is closed by autocommands. */
1993 saved_newval = vim_strsave(newval);
Bram Moolenaard7c96872019-06-15 17:12:48 +02001994 if (origval_l != NULL)
1995 saved_origval_l = vim_strsave(origval_l);
1996 if (origval_g != NULL)
1997 saved_origval_g = vim_strsave(origval_g);
Bram Moolenaar182a17b2017-06-25 20:57:18 +02001998 }
Bram Moolenaar53744302015-07-17 17:38:22 +02001999#endif
2000
Bram Moolenaar247bb7e2018-11-20 14:27:07 +01002001 {
2002 long_u *p = insecure_flag(opt_idx, opt_flags);
Bram Moolenaar48f377a2018-12-21 13:03:28 +01002003 int secure_saved = secure;
Bram Moolenaar247bb7e2018-11-20 14:27:07 +01002004
2005 // When an option is set in the sandbox, from a
2006 // modeline or in secure mode, then deal with side
2007 // effects in secure mode. Also when the value was
2008 // set with the P_INSECURE flag and is not
2009 // completely replaced.
Bram Moolenaar82b033e2019-03-24 14:02:04 +01002010 if ((opt_flags & OPT_MODELINE)
Bram Moolenaar247bb7e2018-11-20 14:27:07 +01002011#ifdef HAVE_SANDBOX
Bram Moolenaar82b033e2019-03-24 14:02:04 +01002012 || sandbox != 0
Bram Moolenaar247bb7e2018-11-20 14:27:07 +01002013#endif
Bram Moolenaar82b033e2019-03-24 14:02:04 +01002014 || (!value_is_replaced && (*p & P_INSECURE)))
2015 secure = 1;
Bram Moolenaar247bb7e2018-11-20 14:27:07 +01002016
Bram Moolenaar48f377a2018-12-21 13:03:28 +01002017 // Handle side effects, and set the global value
2018 // for ":set" on local options. Note: when setting
2019 // 'syntax' or 'filetype' autocommands may be
2020 // triggered that can cause havoc.
2021 errmsg = did_set_string_option(
2022 opt_idx, (char_u **)varp,
Bram Moolenaar916a8182018-11-25 02:18:29 +01002023 new_value_alloced, oldval, errbuf,
2024 opt_flags, &value_checked);
Bram Moolenaar247bb7e2018-11-20 14:27:07 +01002025
Bram Moolenaar48f377a2018-12-21 13:03:28 +01002026 secure = secure_saved;
Bram Moolenaar247bb7e2018-11-20 14:27:07 +01002027 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002028
Bram Moolenaarf2bd8ef2018-03-04 18:08:14 +01002029#if defined(FEAT_EVAL)
Bram Moolenaar8efa0262017-08-20 15:47:20 +02002030 if (errmsg == NULL)
Bram Moolenaard7c96872019-06-15 17:12:48 +02002031 trigger_optionsset_string(
2032 opt_idx, opt_flags, saved_origval,
2033 saved_origval_l, saved_origval_g,
2034 saved_newval);
Bram Moolenaar8efa0262017-08-20 15:47:20 +02002035 vim_free(saved_origval);
Bram Moolenaard7c96872019-06-15 17:12:48 +02002036 vim_free(saved_origval_l);
2037 vim_free(saved_origval_g);
Bram Moolenaar8efa0262017-08-20 15:47:20 +02002038 vim_free(saved_newval);
2039#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00002040 /* If error detected, print the error message. */
2041 if (errmsg != NULL)
2042 goto skip;
2043 }
2044 else /* key code option */
2045 {
2046 char_u *p;
2047
2048 if (nextchar == '&')
2049 {
2050 if (add_termcap_entry(key_name, TRUE) == FAIL)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002051 errmsg = N_("E522: Not found in termcap");
Bram Moolenaar071d4272004-06-13 20:20:40 +00002052 }
2053 else
2054 {
2055 ++arg; /* jump to after the '=' or ':' */
Bram Moolenaar1c465442017-03-12 20:10:05 +01002056 for (p = arg; *p && !VIM_ISWHITE(*p); ++p)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002057 if (*p == '\\' && p[1] != NUL)
2058 ++p;
2059 nextchar = *p;
2060 *p = NUL;
2061 add_termcode(key_name, arg, FALSE);
2062 *p = nextchar;
2063 }
2064 if (full_screen)
2065 ttest(FALSE);
2066 redraw_all_later(CLEAR);
2067 }
2068 }
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002069
Bram Moolenaar071d4272004-06-13 20:20:40 +00002070 if (opt_idx >= 0)
Bram Moolenaar916a8182018-11-25 02:18:29 +01002071 did_set_option(
2072 opt_idx, opt_flags, value_is_replaced, value_checked);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002073 }
2074
2075skip:
2076 /*
2077 * Advance to next argument.
2078 * - skip until a blank found, taking care of backslashes
2079 * - skip blanks
2080 * - skip one "=val" argument (for hidden options ":set gfn =xx")
2081 */
2082 for (i = 0; i < 2 ; ++i)
2083 {
Bram Moolenaar1c465442017-03-12 20:10:05 +01002084 while (*arg != NUL && !VIM_ISWHITE(*arg))
Bram Moolenaar071d4272004-06-13 20:20:40 +00002085 if (*arg++ == '\\' && *arg != NUL)
2086 ++arg;
2087 arg = skipwhite(arg);
2088 if (*arg != '=')
2089 break;
2090 }
2091 }
2092
2093 if (errmsg != NULL)
2094 {
Bram Moolenaarce0842a2005-07-18 21:58:11 +00002095 vim_strncpy(IObuff, (char_u *)_(errmsg), IOSIZE - 1);
Bram Moolenaara93fa7e2006-04-17 22:14:47 +00002096 i = (int)STRLEN(IObuff) + 2;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002097 if (i + (arg - startarg) < IOSIZE)
2098 {
2099 /* append the argument with the error */
2100 STRCAT(IObuff, ": ");
2101 mch_memmove(IObuff + i, startarg, (arg - startarg));
2102 IObuff[i + (arg - startarg)] = NUL;
2103 }
2104 /* make sure all characters are printable */
2105 trans_characters(IObuff, IOSIZE);
2106
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002107 ++no_wait_return; // wait_return done later
2108 emsg((char *)IObuff); // show error highlighted
Bram Moolenaar071d4272004-06-13 20:20:40 +00002109 --no_wait_return;
2110
2111 return FAIL;
2112 }
2113
2114 arg = skipwhite(arg);
2115 }
2116
Bram Moolenaar26a60b42005-02-22 08:49:11 +00002117theend:
2118 if (silent_mode && did_show)
2119 {
2120 /* After displaying option values in silent mode. */
2121 silent_mode = FALSE;
2122 info_message = TRUE; /* use mch_msg(), not mch_errmsg() */
2123 msg_putchar('\n');
2124 cursor_on(); /* msg_start() switches it off */
2125 out_flush();
2126 silent_mode = TRUE;
2127 info_message = FALSE; /* use mch_msg(), not mch_errmsg() */
2128 }
2129
Bram Moolenaar071d4272004-06-13 20:20:40 +00002130 return OK;
2131}
2132
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002133/*
2134 * Call this when an option has been given a new value through a user command.
2135 * Sets the P_WAS_SET flag and takes care of the P_INSECURE flag.
2136 */
Bram Moolenaardac13472019-09-16 21:06:21 +02002137 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01002138did_set_option(
2139 int opt_idx,
Bram Moolenaar916a8182018-11-25 02:18:29 +01002140 int opt_flags, // possibly with OPT_MODELINE
2141 int new_value, // value was replaced completely
2142 int value_checked) // value was checked to be safe, no need to set the
2143 // P_INSECURE flag.
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002144{
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002145 long_u *p;
2146
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002147 options[opt_idx].flags |= P_WAS_SET;
2148
2149 /* When an option is set in the sandbox, from a modeline or in secure mode
2150 * set the P_INSECURE flag. Otherwise, if a new value is stored reset the
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002151 * flag. */
2152 p = insecure_flag(opt_idx, opt_flags);
Bram Moolenaar916a8182018-11-25 02:18:29 +01002153 if (!value_checked && (secure
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002154#ifdef HAVE_SANDBOX
2155 || sandbox != 0
2156#endif
Bram Moolenaar916a8182018-11-25 02:18:29 +01002157 || (opt_flags & OPT_MODELINE)))
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002158 *p = *p | P_INSECURE;
2159 else if (new_value)
2160 *p = *p & ~P_INSECURE;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002161}
2162
Bram Moolenaar071d4272004-06-13 20:20:40 +00002163/*
2164 * Convert a key name or string into a key value.
2165 * Used for 'wildchar' and 'cedit' options.
Bram Moolenaardbe948d2017-07-23 22:50:51 +02002166 * When "multi_byte" is TRUE allow for multi-byte characters.
Bram Moolenaar071d4272004-06-13 20:20:40 +00002167 */
Bram Moolenaardbe948d2017-07-23 22:50:51 +02002168 int
2169string_to_key(char_u *arg, int multi_byte)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002170{
2171 if (*arg == '<')
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02002172 return find_key_option(arg + 1, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002173 if (*arg == '^')
2174 return Ctrl_chr(arg[1]);
Bram Moolenaardbe948d2017-07-23 22:50:51 +02002175 if (multi_byte)
2176 return PTR2CHAR(arg);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002177 return *arg;
2178}
2179
Bram Moolenaardac13472019-09-16 21:06:21 +02002180#if defined(FEAT_CMDWIN) || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002181/*
2182 * Check value of 'cedit' and set cedit_key.
2183 * Returns NULL if value is OK, error message otherwise.
2184 */
Bram Moolenaardac13472019-09-16 21:06:21 +02002185 char *
Bram Moolenaar9b578142016-01-30 19:39:49 +01002186check_cedit(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002187{
2188 int n;
2189
2190 if (*p_cedit == NUL)
2191 cedit_key = -1;
2192 else
2193 {
Bram Moolenaardbe948d2017-07-23 22:50:51 +02002194 n = string_to_key(p_cedit, FALSE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002195 if (vim_isprintc(n))
2196 return e_invarg;
2197 cedit_key = n;
2198 }
2199 return NULL;
2200}
2201#endif
2202
2203#ifdef FEAT_TITLE
2204/*
2205 * When changing 'title', 'titlestring', 'icon' or 'iconstring', call
2206 * maketitle() to create and display it.
2207 * When switching the title or icon off, call mch_restore_title() to get
2208 * the old value back.
2209 */
Bram Moolenaardac13472019-09-16 21:06:21 +02002210 void
Bram Moolenaar84a93082018-06-16 22:58:15 +02002211did_set_title(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002212{
2213 if (starting != NO_SCREEN
2214#ifdef FEAT_GUI
2215 && !gui.starting
2216#endif
2217 )
Bram Moolenaar071d4272004-06-13 20:20:40 +00002218 maketitle();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002219}
2220#endif
2221
2222/*
2223 * set_options_bin - called when 'bin' changes value.
2224 */
2225 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01002226set_options_bin(
2227 int oldval,
2228 int newval,
2229 int opt_flags) /* OPT_LOCAL and/or OPT_GLOBAL */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002230{
2231 /*
2232 * The option values that are changed when 'bin' changes are
2233 * copied when 'bin is set and restored when 'bin' is reset.
2234 */
2235 if (newval)
2236 {
2237 if (!oldval) /* switched on */
2238 {
2239 if (!(opt_flags & OPT_GLOBAL))
2240 {
2241 curbuf->b_p_tw_nobin = curbuf->b_p_tw;
2242 curbuf->b_p_wm_nobin = curbuf->b_p_wm;
2243 curbuf->b_p_ml_nobin = curbuf->b_p_ml;
2244 curbuf->b_p_et_nobin = curbuf->b_p_et;
2245 }
2246 if (!(opt_flags & OPT_LOCAL))
2247 {
2248 p_tw_nobin = p_tw;
2249 p_wm_nobin = p_wm;
2250 p_ml_nobin = p_ml;
2251 p_et_nobin = p_et;
2252 }
2253 }
2254
2255 if (!(opt_flags & OPT_GLOBAL))
2256 {
2257 curbuf->b_p_tw = 0; /* no automatic line wrap */
2258 curbuf->b_p_wm = 0; /* no automatic line wrap */
2259 curbuf->b_p_ml = 0; /* no modelines */
2260 curbuf->b_p_et = 0; /* no expandtab */
2261 }
2262 if (!(opt_flags & OPT_LOCAL))
2263 {
2264 p_tw = 0;
2265 p_wm = 0;
2266 p_ml = FALSE;
2267 p_et = FALSE;
2268 p_bin = TRUE; /* needed when called for the "-b" argument */
2269 }
2270 }
2271 else if (oldval) /* switched off */
2272 {
2273 if (!(opt_flags & OPT_GLOBAL))
2274 {
2275 curbuf->b_p_tw = curbuf->b_p_tw_nobin;
2276 curbuf->b_p_wm = curbuf->b_p_wm_nobin;
2277 curbuf->b_p_ml = curbuf->b_p_ml_nobin;
2278 curbuf->b_p_et = curbuf->b_p_et_nobin;
2279 }
2280 if (!(opt_flags & OPT_LOCAL))
2281 {
2282 p_tw = p_tw_nobin;
2283 p_wm = p_wm_nobin;
2284 p_ml = p_ml_nobin;
2285 p_et = p_et_nobin;
2286 }
2287 }
2288}
2289
Bram Moolenaar071d4272004-06-13 20:20:40 +00002290/*
2291 * Expand environment variables for some string options.
2292 * These string options cannot be indirect!
2293 * If "val" is NULL expand the current value of the option.
2294 * Return pointer to NameBuff, or NULL when not expanded.
2295 */
2296 static char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01002297option_expand(int opt_idx, char_u *val)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002298{
2299 /* if option doesn't need expansion nothing to do */
2300 if (!(options[opt_idx].flags & P_EXPAND) || options[opt_idx].var == NULL)
2301 return NULL;
2302
2303 /* If val is longer than MAXPATHL no meaningful expansion can be done,
2304 * expand_env() would truncate the string. */
2305 if (val != NULL && STRLEN(val) > MAXPATHL)
2306 return NULL;
2307
2308 if (val == NULL)
2309 val = *(char_u **)options[opt_idx].var;
2310
2311 /*
2312 * Expanding this with NameBuff, expand_env() must not be passed IObuff.
2313 * Escape spaces when expanding 'tags', they are used to separate file
2314 * names.
Bram Moolenaar24bbcfe2005-06-28 23:32:02 +00002315 * For 'spellsuggest' expand after "file:".
Bram Moolenaar071d4272004-06-13 20:20:40 +00002316 */
2317 expand_env_esc(val, NameBuff, MAXPATHL,
Bram Moolenaar9f0545d2007-09-26 20:36:32 +00002318 (char_u **)options[opt_idx].var == &p_tags, FALSE,
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00002319#ifdef FEAT_SPELL
Bram Moolenaar24bbcfe2005-06-28 23:32:02 +00002320 (char_u **)options[opt_idx].var == &p_sps ? (char_u *)"file:" :
2321#endif
2322 NULL);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002323 if (STRCMP(NameBuff, val) == 0) /* they are the same */
2324 return NULL;
2325
2326 return NameBuff;
2327}
2328
2329/*
2330 * After setting various option values: recompute variables that depend on
2331 * option values.
2332 */
2333 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01002334didset_options(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002335{
2336 /* initialize the table for 'iskeyword' et.al. */
2337 (void)init_chartab();
2338
Bram Moolenaardac13472019-09-16 21:06:21 +02002339 didset_string_options();
2340
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00002341#ifdef FEAT_SPELL
Bram Moolenaar8aff23a2005-08-19 20:40:30 +00002342 (void)spell_check_msm();
Bram Moolenaar24bbcfe2005-06-28 23:32:02 +00002343 (void)spell_check_sps();
Bram Moolenaar860cae12010-06-05 23:22:07 +02002344 (void)compile_cap_prog(curwin->w_s);
Bram Moolenaare68c25c2015-08-25 15:39:55 +02002345 (void)did_set_spell_option(TRUE);
Bram Moolenaard857f0e2005-06-21 22:37:39 +00002346#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00002347#ifdef FEAT_CMDWIN
Bram Moolenaar010ee962019-09-25 20:37:36 +02002348 // set cedit_key
Bram Moolenaar071d4272004-06-13 20:20:40 +00002349 (void)check_cedit();
2350#endif
Bram Moolenaar597a4222014-06-25 14:39:50 +02002351#ifdef FEAT_LINEBREAK
Bram Moolenaare68c25c2015-08-25 15:39:55 +02002352 /* initialize the table for 'breakat'. */
2353 fill_breakat_flags();
2354#endif
Bram Moolenaar010ee962019-09-25 20:37:36 +02002355 after_copy_winopt(curwin);
Bram Moolenaare68c25c2015-08-25 15:39:55 +02002356}
2357
2358/*
2359 * More side effects of setting options.
2360 */
2361 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01002362didset_options2(void)
Bram Moolenaare68c25c2015-08-25 15:39:55 +02002363{
2364 /* Initialize the highlight_attr[] table. */
2365 (void)highlight_changed();
2366
2367 /* Parse default for 'wildmode' */
2368 check_opt_wim();
2369
2370 (void)set_chars_option(&p_lcs);
Bram Moolenaare68c25c2015-08-25 15:39:55 +02002371 /* Parse default for 'fillchars'. */
2372 (void)set_chars_option(&p_fcs);
Bram Moolenaare68c25c2015-08-25 15:39:55 +02002373
2374#ifdef FEAT_CLIPBOARD
2375 /* Parse default for 'clipboard' */
2376 (void)check_clipboard_option();
2377#endif
Bram Moolenaar04958cb2018-06-23 19:23:02 +02002378#ifdef FEAT_VARTABS
Bram Moolenaar55c77cf2019-02-16 19:05:11 +01002379 vim_free(curbuf->b_p_vsts_array);
Bram Moolenaar04958cb2018-06-23 19:23:02 +02002380 tabstop_set(curbuf->b_p_vsts, &curbuf->b_p_vsts_array);
Bram Moolenaar55c77cf2019-02-16 19:05:11 +01002381 vim_free(curbuf->b_p_vts_array);
Bram Moolenaar04958cb2018-06-23 19:23:02 +02002382 tabstop_set(curbuf->b_p_vts, &curbuf->b_p_vts_array);
2383#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00002384}
2385
2386/*
2387 * Check for string options that are NULL (normally only termcap options).
2388 */
2389 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01002390check_options(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002391{
2392 int opt_idx;
2393
2394 for (opt_idx = 0; options[opt_idx].fullname != NULL; opt_idx++)
2395 if ((options[opt_idx].flags & P_STRING) && options[opt_idx].var != NULL)
2396 check_string_option((char_u **)get_varp(&(options[opt_idx])));
2397}
2398
2399/*
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02002400 * Return the option index found by a pointer into term_strings[].
2401 * Return -1 if not found.
Bram Moolenaar071d4272004-06-13 20:20:40 +00002402 */
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02002403 int
2404get_term_opt_idx(char_u **p)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002405{
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02002406 int opt_idx;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002407
2408 for (opt_idx = 1; options[opt_idx].fullname != NULL; opt_idx++)
2409 if (options[opt_idx].var == (char_u *)p)
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02002410 return opt_idx;
2411 return -1; // cannot happen: didn't find it!
2412}
2413
2414/*
2415 * Mark a terminal option as allocated, found by a pointer into term_strings[].
2416 * Return the option index or -1 if not found.
2417 */
2418 int
2419set_term_option_alloced(char_u **p)
2420{
2421 int opt_idx = get_term_opt_idx(p);
2422
2423 if (opt_idx >= 0)
2424 options[opt_idx].flags |= P_ALLOCED;
2425 return opt_idx;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002426}
2427
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002428#if defined(FEAT_EVAL) || defined(PROTO)
2429/*
2430 * Return TRUE when option "opt" was set from a modeline or in secure mode.
2431 * Return FALSE when it wasn't.
2432 * Return -1 for an unknown option.
2433 */
2434 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01002435was_set_insecurely(char_u *opt, int opt_flags)
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002436{
2437 int idx = findoption(opt);
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002438 long_u *flagp;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002439
2440 if (idx >= 0)
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002441 {
2442 flagp = insecure_flag(idx, opt_flags);
2443 return (*flagp & P_INSECURE) != 0;
2444 }
Bram Moolenaar95f09602016-11-10 20:01:45 +01002445 internal_error("was_set_insecurely()");
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002446 return -1;
2447}
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002448
2449/*
2450 * Get a pointer to the flags used for the P_INSECURE flag of option
2451 * "opt_idx". For some local options a local flags field is used.
2452 */
2453 static long_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01002454insecure_flag(int opt_idx, int opt_flags)
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002455{
2456 if (opt_flags & OPT_LOCAL)
2457 switch ((int)options[opt_idx].indir)
2458 {
2459#ifdef FEAT_STL_OPT
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002460 case PV_STL: return &curwin->w_p_stl_flags;
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002461#endif
2462#ifdef FEAT_EVAL
Bram Moolenaar2e978902006-05-13 12:37:50 +00002463# ifdef FEAT_FOLDING
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002464 case PV_FDE: return &curwin->w_p_fde_flags;
2465 case PV_FDT: return &curwin->w_p_fdt_flags;
Bram Moolenaar2e978902006-05-13 12:37:50 +00002466# endif
Bram Moolenaar9b2200a2006-03-20 21:55:45 +00002467# ifdef FEAT_BEVAL
2468 case PV_BEXPR: return &curbuf->b_p_bexpr_flags;
2469# endif
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002470# if defined(FEAT_CINDENT)
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002471 case PV_INDE: return &curbuf->b_p_inde_flags;
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002472# endif
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002473 case PV_FEX: return &curbuf->b_p_fex_flags;
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002474# ifdef FEAT_FIND_ID
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002475 case PV_INEX: return &curbuf->b_p_inex_flags;
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002476# endif
2477#endif
2478 }
2479
2480 /* Nothing special, return global flags field. */
2481 return &options[opt_idx].flags;
2482}
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002483#endif
2484
Bram Moolenaardac13472019-09-16 21:06:21 +02002485#if defined(FEAT_TITLE) || defined(PROTO)
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002486/*
2487 * Redraw the window title and/or tab page text later.
2488 */
Bram Moolenaardac13472019-09-16 21:06:21 +02002489void redraw_titles(void)
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002490{
2491 need_maketitle = TRUE;
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002492 redraw_tabline = TRUE;
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002493}
2494#endif
2495
Bram Moolenaar071d4272004-06-13 20:20:40 +00002496/*
Bram Moolenaar8f130ed2019-04-10 22:15:19 +02002497 * Return TRUE if "val" is a valid name: only consists of alphanumeric ASCII
2498 * characters or characters in "allowed".
2499 */
Bram Moolenaare677df82019-09-02 22:31:11 +02002500 int
Bram Moolenaar8f130ed2019-04-10 22:15:19 +02002501valid_name(char_u *val, char *allowed)
2502{
2503 char_u *s;
2504
2505 for (s = val; *s != NUL; ++s)
2506 if (!ASCII_ISALNUM(*s) && vim_strchr((char_u *)allowed, *s) == NULL)
2507 return FALSE;
2508 return TRUE;
2509}
2510
Bram Moolenaardac13472019-09-16 21:06:21 +02002511#if defined(FEAT_CLIPBOARD) || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002512/*
2513 * Extract the items in the 'clipboard' option and set global values.
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002514 * Return an error message or NULL for success.
Bram Moolenaar071d4272004-06-13 20:20:40 +00002515 */
Bram Moolenaardac13472019-09-16 21:06:21 +02002516 char *
Bram Moolenaar9b578142016-01-30 19:39:49 +01002517check_clipboard_option(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002518{
Bram Moolenaarbf9680e2010-12-02 21:43:16 +01002519 int new_unnamed = 0;
Bram Moolenaar89af4392012-07-10 18:31:54 +02002520 int new_autoselect_star = FALSE;
2521 int new_autoselect_plus = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002522 int new_autoselectml = FALSE;
Bram Moolenaar3a6eaa52009-06-16 13:23:06 +00002523 int new_html = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002524 regprog_T *new_exclude_prog = NULL;
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002525 char *errmsg = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002526 char_u *p;
2527
2528 for (p = p_cb; *p != NUL; )
2529 {
2530 if (STRNCMP(p, "unnamed", 7) == 0 && (p[7] == ',' || p[7] == NUL))
2531 {
Bram Moolenaarbf9680e2010-12-02 21:43:16 +01002532 new_unnamed |= CLIP_UNNAMED;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002533 p += 7;
2534 }
Bram Moolenaar11b73d62012-06-29 15:51:30 +02002535 else if (STRNCMP(p, "unnamedplus", 11) == 0
Bram Moolenaarbf9680e2010-12-02 21:43:16 +01002536 && (p[11] == ',' || p[11] == NUL))
2537 {
2538 new_unnamed |= CLIP_UNNAMED_PLUS;
2539 p += 11;
2540 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002541 else if (STRNCMP(p, "autoselect", 10) == 0
Bram Moolenaar89af4392012-07-10 18:31:54 +02002542 && (p[10] == ',' || p[10] == NUL))
Bram Moolenaar071d4272004-06-13 20:20:40 +00002543 {
Bram Moolenaar89af4392012-07-10 18:31:54 +02002544 new_autoselect_star = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002545 p += 10;
2546 }
Bram Moolenaar89af4392012-07-10 18:31:54 +02002547 else if (STRNCMP(p, "autoselectplus", 14) == 0
2548 && (p[14] == ',' || p[14] == NUL))
2549 {
2550 new_autoselect_plus = TRUE;
2551 p += 14;
2552 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002553 else if (STRNCMP(p, "autoselectml", 12) == 0
Bram Moolenaar89af4392012-07-10 18:31:54 +02002554 && (p[12] == ',' || p[12] == NUL))
Bram Moolenaar071d4272004-06-13 20:20:40 +00002555 {
2556 new_autoselectml = TRUE;
2557 p += 12;
2558 }
Bram Moolenaar3a6eaa52009-06-16 13:23:06 +00002559 else if (STRNCMP(p, "html", 4) == 0 && (p[4] == ',' || p[4] == NUL))
2560 {
2561 new_html = TRUE;
2562 p += 4;
2563 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002564 else if (STRNCMP(p, "exclude:", 8) == 0 && new_exclude_prog == NULL)
2565 {
2566 p += 8;
2567 new_exclude_prog = vim_regcomp(p, RE_MAGIC);
2568 if (new_exclude_prog == NULL)
2569 errmsg = e_invarg;
2570 break;
2571 }
2572 else
2573 {
2574 errmsg = e_invarg;
2575 break;
2576 }
2577 if (*p == ',')
2578 ++p;
2579 }
2580 if (errmsg == NULL)
2581 {
2582 clip_unnamed = new_unnamed;
Bram Moolenaar89af4392012-07-10 18:31:54 +02002583 clip_autoselect_star = new_autoselect_star;
2584 clip_autoselect_plus = new_autoselect_plus;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002585 clip_autoselectml = new_autoselectml;
Bram Moolenaar3a6eaa52009-06-16 13:23:06 +00002586 clip_html = new_html;
Bram Moolenaar473de612013-06-08 18:19:48 +02002587 vim_regfree(clip_exclude_prog);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002588 clip_exclude_prog = new_exclude_prog;
Bram Moolenaara76638f2010-06-05 12:49:46 +02002589#ifdef FEAT_GUI_GTK
2590 if (gui.in_use)
2591 {
2592 gui_gtk_set_selection_targets();
2593 gui_gtk_set_dnd_targets();
2594 }
2595#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00002596 }
2597 else
Bram Moolenaar473de612013-06-08 18:19:48 +02002598 vim_regfree(new_exclude_prog);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002599
2600 return errmsg;
2601}
2602#endif
2603
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002604#if defined(FEAT_EVAL) || defined(PROTO)
2605/*
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002606 * Set the script_ctx for an option, taking care of setting the buffer- or
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002607 * window-local value.
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002608 */
Bram Moolenaardac13472019-09-16 21:06:21 +02002609 void
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002610set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002611{
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002612 int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
2613 int indir = (int)options[opt_idx].indir;
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002614 sctx_T new_script_ctx = script_ctx;
2615
2616 new_script_ctx.sc_lnum += sourcing_lnum;
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002617
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002618 /* Remember where the option was set. For local options need to do that
2619 * in the buffer or window structure. */
2620 if (both || (opt_flags & OPT_GLOBAL) || (indir & (PV_BUF|PV_WIN)) == 0)
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002621 options[opt_idx].script_ctx = new_script_ctx;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002622 if (both || (opt_flags & OPT_LOCAL))
2623 {
2624 if (indir & PV_BUF)
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002625 curbuf->b_p_script_ctx[indir & PV_MASK] = new_script_ctx;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002626 else if (indir & PV_WIN)
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002627 curwin->w_p_script_ctx[indir & PV_MASK] = new_script_ctx;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002628 }
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002629}
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02002630
2631/*
2632 * Set the script_ctx for a termcap option.
2633 * "name" must be the two character code, e.g. "RV".
2634 * When "name" is NULL use "opt_idx".
2635 */
2636 void
2637set_term_option_sctx_idx(char *name, int opt_idx)
2638{
2639 char_u buf[5];
2640 int idx;
2641
2642 if (name == NULL)
2643 idx = opt_idx;
2644 else
2645 {
2646 buf[0] = 't';
2647 buf[1] = '_';
2648 buf[2] = name[0];
2649 buf[3] = name[1];
2650 buf[4] = 0;
2651 idx = findoption(buf);
2652 }
2653 if (idx >= 0)
2654 set_option_sctx_idx(idx, OPT_GLOBAL, current_sctx);
2655}
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002656#endif
2657
Bram Moolenaar071d4272004-06-13 20:20:40 +00002658/*
2659 * Set the value of a boolean option, and take care of side effects.
2660 * Returns NULL for success, or an error message for an error.
2661 */
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002662 static char *
Bram Moolenaar9b578142016-01-30 19:39:49 +01002663set_bool_option(
2664 int opt_idx, /* index in options[] table */
2665 char_u *varp, /* pointer to the option variable */
2666 int value, /* new value */
2667 int opt_flags) /* OPT_LOCAL and/or OPT_GLOBAL */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002668{
2669 int old_value = *(int *)varp;
Bram Moolenaar983f2f12019-06-16 16:41:41 +02002670#if defined(FEAT_EVAL)
Bram Moolenaard7c96872019-06-15 17:12:48 +02002671 int old_global_value = 0;
Bram Moolenaar983f2f12019-06-16 16:41:41 +02002672#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00002673
Bram Moolenaar071d4272004-06-13 20:20:40 +00002674 /* Disallow changing some options from secure mode */
2675 if ((secure
2676#ifdef HAVE_SANDBOX
2677 || sandbox != 0
2678#endif
2679 ) && (options[opt_idx].flags & P_SECURE))
2680 return e_secure;
2681
Bram Moolenaar983f2f12019-06-16 16:41:41 +02002682#if defined(FEAT_EVAL)
Bram Moolenaard7c96872019-06-15 17:12:48 +02002683 // Save the global value before changing anything. This is needed as for
2684 // a global-only option setting the "local value" in fact sets the global
2685 // value (since there is only one value).
2686 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
2687 old_global_value = *(int *)get_varp_scope(&(options[opt_idx]),
2688 OPT_GLOBAL);
Bram Moolenaar983f2f12019-06-16 16:41:41 +02002689#endif
Bram Moolenaard7c96872019-06-15 17:12:48 +02002690
Bram Moolenaar071d4272004-06-13 20:20:40 +00002691 *(int *)varp = value; /* set the new value */
2692#ifdef FEAT_EVAL
2693 /* Remember where the option was set. */
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002694 set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002695#endif
2696
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002697#ifdef FEAT_GUI
2698 need_mouse_correct = TRUE;
2699#endif
2700
Bram Moolenaar071d4272004-06-13 20:20:40 +00002701 /* May set global value for local option. */
2702 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
2703 *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = value;
2704
2705 /*
2706 * Handle side effects of changing a bool option.
2707 */
2708
2709 /* 'compatible' */
2710 if ((int *)varp == &p_cp)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002711 compatible_set();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002712
Bram Moolenaar920694c2016-08-21 17:45:02 +02002713#ifdef FEAT_LANGMAP
2714 if ((int *)varp == &p_lrm)
2715 /* 'langremap' -> !'langnoremap' */
2716 p_lnr = !p_lrm;
2717 else if ((int *)varp == &p_lnr)
2718 /* 'langnoremap' -> !'langremap' */
2719 p_lrm = !p_lnr;
2720#endif
2721
Bram Moolenaar8c63e0e2018-09-25 22:17:54 +02002722#ifdef FEAT_SYN_HL
2723 else if ((int *)varp == &curwin->w_p_cul && !value && old_value)
2724 reset_cursorline();
2725#endif
2726
Bram Moolenaar374d32d2012-01-04 19:34:37 +01002727#ifdef FEAT_PERSISTENT_UNDO
2728 /* 'undofile' */
2729 else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf)
2730 {
Bram Moolenaare8d8fd22012-10-21 03:46:05 +02002731 /* Only take action when the option was set. When reset we do not
2732 * delete the undo file, the option may be set again without making
2733 * any changes in between. */
2734 if (curbuf->b_p_udf || p_udf)
Bram Moolenaar374d32d2012-01-04 19:34:37 +01002735 {
Bram Moolenaare8d8fd22012-10-21 03:46:05 +02002736 char_u hash[UNDO_HASH_SIZE];
2737 buf_T *save_curbuf = curbuf;
2738
Bram Moolenaar29323592016-07-24 22:04:11 +02002739 FOR_ALL_BUFFERS(curbuf)
Bram Moolenaar374d32d2012-01-04 19:34:37 +01002740 {
Bram Moolenaare8d8fd22012-10-21 03:46:05 +02002741 /* When 'undofile' is set globally: for every buffer, otherwise
2742 * only for the current buffer: Try to read in the undofile,
2743 * if one exists, the buffer wasn't changed and the buffer was
2744 * loaded */
2745 if ((curbuf == save_curbuf
2746 || (opt_flags & OPT_GLOBAL) || opt_flags == 0)
2747 && !curbufIsChanged() && curbuf->b_ml.ml_mfp != NULL)
2748 {
2749 u_compute_hash(hash);
2750 u_read_undo(NULL, hash, curbuf->b_fname);
2751 }
Bram Moolenaar374d32d2012-01-04 19:34:37 +01002752 }
Bram Moolenaare8d8fd22012-10-21 03:46:05 +02002753 curbuf = save_curbuf;
Bram Moolenaar374d32d2012-01-04 19:34:37 +01002754 }
Bram Moolenaar374d32d2012-01-04 19:34:37 +01002755 }
2756#endif
2757
Bram Moolenaar071d4272004-06-13 20:20:40 +00002758 else if ((int *)varp == &curbuf->b_p_ro)
2759 {
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +00002760 /* when 'readonly' is reset globally, also reset readonlymode */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002761 if (!curbuf->b_p_ro && (opt_flags & OPT_LOCAL) == 0)
2762 readonlymode = FALSE;
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +00002763
2764 /* when 'readonly' is set may give W10 again */
2765 if (curbuf->b_p_ro)
2766 curbuf->b_did_warn = FALSE;
2767
Bram Moolenaar071d4272004-06-13 20:20:40 +00002768#ifdef FEAT_TITLE
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002769 redraw_titles();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002770#endif
2771 }
2772
Bram Moolenaar9c449722010-07-20 18:44:27 +02002773#ifdef FEAT_GUI
2774 else if ((int *)varp == &p_mh)
2775 {
2776 if (!p_mh)
2777 gui_mch_mousehide(FALSE);
2778 }
2779#endif
2780
Bram Moolenaara539df02010-08-01 14:35:05 +02002781 /* when 'modifiable' is changed, redraw the window title */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002782 else if ((int *)varp == &curbuf->b_p_ma)
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002783 {
Bram Moolenaar423802d2017-07-30 16:52:24 +02002784# ifdef FEAT_TERMINAL
2785 /* Cannot set 'modifiable' when in Terminal mode. */
Bram Moolenaard7db27b2018-03-07 23:02:33 +01002786 if (curbuf->b_p_ma && (term_in_normal_mode() || (bt_terminal(curbuf)
2787 && curbuf->b_term != NULL && !term_is_finished(curbuf))))
Bram Moolenaar423802d2017-07-30 16:52:24 +02002788 {
2789 curbuf->b_p_ma = FALSE;
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002790 return N_("E946: Cannot make a terminal with running job modifiable");
Bram Moolenaar423802d2017-07-30 16:52:24 +02002791 }
2792# endif
2793# ifdef FEAT_TITLE
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002794 redraw_titles();
Bram Moolenaar423802d2017-07-30 16:52:24 +02002795# endif
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002796 }
Bram Moolenaar423802d2017-07-30 16:52:24 +02002797#ifdef FEAT_TITLE
Bram Moolenaar071d4272004-06-13 20:20:40 +00002798 /* when 'endofline' is changed, redraw the window title */
2799 else if ((int *)varp == &curbuf->b_p_eol)
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002800 {
2801 redraw_titles();
2802 }
Bram Moolenaar34d72d42015-07-17 14:18:08 +02002803 /* when 'fixeol' is changed, redraw the window title */
2804 else if ((int *)varp == &curbuf->b_p_fixeol)
2805 {
2806 redraw_titles();
2807 }
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002808 /* when 'bomb' is changed, redraw the window title and tab page text */
Bram Moolenaar83eb8852007-08-12 13:51:26 +00002809 else if ((int *)varp == &curbuf->b_p_bomb)
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002810 {
2811 redraw_titles();
2812 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002813#endif
2814
2815 /* when 'bin' is set also set some other options */
2816 else if ((int *)varp == &curbuf->b_p_bin)
2817 {
2818 set_options_bin(old_value, curbuf->b_p_bin, opt_flags);
2819#ifdef FEAT_TITLE
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002820 redraw_titles();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002821#endif
2822 }
2823
Bram Moolenaar071d4272004-06-13 20:20:40 +00002824 /* when 'buflisted' changes, trigger autocommands */
2825 else if ((int *)varp == &curbuf->b_p_bl && old_value != curbuf->b_p_bl)
2826 {
2827 apply_autocmds(curbuf->b_p_bl ? EVENT_BUFADD : EVENT_BUFDELETE,
2828 NULL, NULL, TRUE, curbuf);
2829 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002830
2831 /* when 'swf' is set, create swapfile, when reset remove swapfile */
2832 else if ((int *)varp == &curbuf->b_p_swf)
2833 {
2834 if (curbuf->b_p_swf && p_uc)
2835 ml_open_file(curbuf); /* create the swap file */
2836 else
Bram Moolenaard55de222007-05-06 13:38:48 +00002837 /* no need to reset curbuf->b_may_swap, ml_open_file() will check
2838 * buf->b_p_swf */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002839 mf_close_file(curbuf, TRUE); /* remove the swap file */
2840 }
2841
2842 /* when 'terse' is set change 'shortmess' */
2843 else if ((int *)varp == &p_terse)
2844 {
2845 char_u *p;
2846
2847 p = vim_strchr(p_shm, SHM_SEARCH);
2848
2849 /* insert 's' in p_shm */
2850 if (p_terse && p == NULL)
2851 {
2852 STRCPY(IObuff, p_shm);
2853 STRCAT(IObuff, "s");
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002854 set_string_option_direct((char_u *)"shm", -1, IObuff, OPT_FREE, 0);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002855 }
2856 /* remove 's' from p_shm */
2857 else if (!p_terse && p != NULL)
Bram Moolenaarc1a11ed2008-06-24 22:09:24 +00002858 STRMOVE(p, p + 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002859 }
2860
2861 /* when 'paste' is set or reset also change other options */
2862 else if ((int *)varp == &p_paste)
2863 {
2864 paste_option_changed();
2865 }
2866
2867 /* when 'insertmode' is set from an autocommand need to do work here */
2868 else if ((int *)varp == &p_im)
2869 {
2870 if (p_im)
2871 {
2872 if ((State & INSERT) == 0)
2873 need_start_insertmode = TRUE;
2874 stop_insert_mode = FALSE;
2875 }
Bram Moolenaar00672e12016-06-26 18:38:13 +02002876 /* only reset if it was set previously */
2877 else if (old_value)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002878 {
2879 need_start_insertmode = FALSE;
2880 stop_insert_mode = TRUE;
Bram Moolenaard12f5c12006-01-25 22:10:52 +00002881 if (restart_edit != 0 && mode_displayed)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002882 clear_cmdline = TRUE; /* remove "(insert)" */
2883 restart_edit = 0;
2884 }
2885 }
2886
2887 /* when 'ignorecase' is set or reset and 'hlsearch' is set, redraw */
2888 else if ((int *)varp == &p_ic && p_hls)
2889 {
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00002890 redraw_all_later(SOME_VALID);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002891 }
2892
2893#ifdef FEAT_SEARCH_EXTRA
2894 /* when 'hlsearch' is set or reset: reset no_hlsearch */
2895 else if ((int *)varp == &p_hls)
2896 {
Bram Moolenaar451fc7b2018-04-27 22:53:07 +02002897 set_no_hlsearch(FALSE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002898 }
2899#endif
2900
Bram Moolenaar071d4272004-06-13 20:20:40 +00002901 /* when 'scrollbind' is set: snapshot the current position to avoid a jump
2902 * at the end of normal_cmd() */
2903 else if ((int *)varp == &curwin->w_p_scb)
2904 {
2905 if (curwin->w_p_scb)
Bram Moolenaar04c5c9e2013-07-09 13:44:59 +02002906 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00002907 do_check_scrollbind(FALSE);
Bram Moolenaar04c5c9e2013-07-09 13:44:59 +02002908 curwin->w_scbind_pos = curwin->w_topline;
2909 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002910 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002911
Bram Moolenaar4033c552017-09-16 20:54:51 +02002912#if defined(FEAT_QUICKFIX)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002913 /* There can be only one window with 'previewwindow' set. */
2914 else if ((int *)varp == &curwin->w_p_pvw)
2915 {
2916 if (curwin->w_p_pvw)
2917 {
2918 win_T *win;
2919
Bram Moolenaar29323592016-07-24 22:04:11 +02002920 FOR_ALL_WINDOWS(win)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002921 if (win->w_p_pvw && win != curwin)
2922 {
2923 curwin->w_p_pvw = FALSE;
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002924 return N_("E590: A preview window already exists");
Bram Moolenaar071d4272004-06-13 20:20:40 +00002925 }
2926 }
2927 }
2928#endif
2929
2930 /* when 'textmode' is set or reset also change 'fileformat' */
2931 else if ((int *)varp == &curbuf->b_p_tx)
2932 {
2933 set_fileformat(curbuf->b_p_tx ? EOL_DOS : EOL_UNIX, opt_flags);
2934 }
2935
2936 /* when 'textauto' is set or reset also change 'fileformats' */
2937 else if ((int *)varp == &p_ta)
Bram Moolenaarabab0b02019-03-30 18:47:01 +01002938 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00002939 set_string_option_direct((char_u *)"ffs", -1,
2940 p_ta ? (char_u *)DFLT_FFS_VIM : (char_u *)"",
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002941 OPT_FREE | opt_flags, 0);
Bram Moolenaarabab0b02019-03-30 18:47:01 +01002942 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002943
2944 /*
2945 * When 'lisp' option changes include/exclude '-' in
2946 * keyword characters.
2947 */
2948#ifdef FEAT_LISP
2949 else if (varp == (char_u *)&(curbuf->b_p_lisp))
2950 {
2951 (void)buf_init_chartab(curbuf, FALSE); /* ignore errors */
2952 }
2953#endif
2954
2955#ifdef FEAT_TITLE
2956 /* when 'title' changed, may need to change the title; same for 'icon' */
Bram Moolenaar84a93082018-06-16 22:58:15 +02002957 else if ((int *)varp == &p_title || (int *)varp == &p_icon)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002958 {
Bram Moolenaar84a93082018-06-16 22:58:15 +02002959 did_set_title();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002960 }
2961#endif
2962
2963 else if ((int *)varp == &curbuf->b_changed)
2964 {
2965 if (!value)
2966 save_file_ff(curbuf); /* Buffer is unchanged */
2967#ifdef FEAT_TITLE
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002968 redraw_titles();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002969#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00002970 modified_was_set = value;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002971 }
2972
2973#ifdef BACKSLASH_IN_FILENAME
2974 else if ((int *)varp == &p_ssl)
2975 {
2976 if (p_ssl)
2977 {
2978 psepc = '/';
2979 psepcN = '\\';
2980 pseps[0] = '/';
Bram Moolenaar071d4272004-06-13 20:20:40 +00002981 }
2982 else
2983 {
2984 psepc = '\\';
2985 psepcN = '/';
2986 pseps[0] = '\\';
Bram Moolenaar071d4272004-06-13 20:20:40 +00002987 }
2988
2989 /* need to adjust the file name arguments and buffer names. */
2990 buflist_slash_adjust();
2991 alist_slash_adjust();
2992# ifdef FEAT_EVAL
2993 scriptnames_slash_adjust();
2994# endif
2995 }
2996#endif
2997
2998 /* If 'wrap' is set, set w_leftcol to zero. */
2999 else if ((int *)varp == &curwin->w_p_wrap)
3000 {
3001 if (curwin->w_p_wrap)
3002 curwin->w_leftcol = 0;
3003 }
3004
Bram Moolenaar071d4272004-06-13 20:20:40 +00003005 else if ((int *)varp == &p_ea)
3006 {
3007 if (p_ea && !old_value)
3008 win_equal(curwin, FALSE, 0);
3009 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003010
3011 else if ((int *)varp == &p_wiv)
3012 {
3013 /*
3014 * When 'weirdinvert' changed, set/reset 't_xs'.
3015 * Then set 'weirdinvert' according to value of 't_xs'.
3016 */
3017 if (p_wiv && !old_value)
3018 T_XS = (char_u *)"y";
3019 else if (!p_wiv && old_value)
3020 T_XS = empty_option;
3021 p_wiv = (*T_XS != NUL);
3022 }
3023
Bram Moolenaarc3719bd2017-11-18 22:13:31 +01003024#ifdef FEAT_BEVAL_GUI
Bram Moolenaar071d4272004-06-13 20:20:40 +00003025 else if ((int *)varp == &p_beval)
3026 {
Bram Moolenaar51b0f372017-11-18 18:52:04 +01003027 if (!balloonEvalForTerm)
3028 {
3029 if (p_beval && !old_value)
3030 gui_mch_enable_beval_area(balloonEval);
3031 else if (!p_beval && old_value)
3032 gui_mch_disable_beval_area(balloonEval);
3033 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003034 }
Bram Moolenaar8dff8182006-04-06 20:18:50 +00003035#endif
Bram Moolenaarc3719bd2017-11-18 22:13:31 +01003036#ifdef FEAT_BEVAL_TERM
Bram Moolenaar51b0f372017-11-18 18:52:04 +01003037 else if ((int *)varp == &p_bevalterm)
3038 {
3039 mch_bevalterm_changed();
3040 }
Bram Moolenaarc3719bd2017-11-18 22:13:31 +01003041#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003042
Bram Moolenaar8dff8182006-04-06 20:18:50 +00003043#ifdef FEAT_AUTOCHDIR
Bram Moolenaar071d4272004-06-13 20:20:40 +00003044 else if ((int *)varp == &p_acd)
3045 {
Bram Moolenaar498efdb2006-09-05 14:31:54 +00003046 /* Change directories when the 'acd' option is set now. */
Bram Moolenaar6f470022018-04-10 18:47:20 +02003047 DO_AUTOCHDIR;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003048 }
3049#endif
3050
3051#ifdef FEAT_DIFF
3052 /* 'diff' */
3053 else if ((int *)varp == &curwin->w_p_diff)
3054 {
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00003055 /* May add or remove the buffer from the list of diff buffers. */
3056 diff_buf_adjust(curwin);
3057# ifdef FEAT_FOLDING
Bram Moolenaar071d4272004-06-13 20:20:40 +00003058 if (foldmethodIsDiff(curwin))
3059 foldUpdateAll(curwin);
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00003060# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003061 }
3062#endif
3063
Bram Moolenaarf2bd8ef2018-03-04 18:08:14 +01003064#ifdef HAVE_INPUT_METHOD
Bram Moolenaar071d4272004-06-13 20:20:40 +00003065 /* 'imdisable' */
3066 else if ((int *)varp == &p_imdisable)
3067 {
3068 /* Only de-activate it here, it will be enabled when changing mode. */
3069 if (p_imdisable)
3070 im_set_active(FALSE);
Bram Moolenaar725a9622011-10-12 16:57:13 +02003071 else if (State & INSERT)
3072 /* When the option is set from an autocommand, it may need to take
3073 * effect right away. */
3074 im_set_active(curbuf->b_p_iminsert == B_IMODE_IM);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003075 }
3076#endif
3077
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00003078#ifdef FEAT_SPELL
Bram Moolenaar0cb032e2005-04-23 20:52:00 +00003079 /* 'spell' */
3080 else if ((int *)varp == &curwin->w_p_spell)
3081 {
3082 if (curwin->w_p_spell)
3083 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003084 char *errmsg = did_set_spelllang(curwin);
3085
Bram Moolenaar0cb032e2005-04-23 20:52:00 +00003086 if (errmsg != NULL)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003087 emsg(_(errmsg));
Bram Moolenaar0cb032e2005-04-23 20:52:00 +00003088 }
3089 }
3090#endif
3091
Bram Moolenaar071d4272004-06-13 20:20:40 +00003092#ifdef FEAT_ARABIC
3093 if ((int *)varp == &curwin->w_p_arab)
3094 {
3095 if (curwin->w_p_arab)
3096 {
3097 /*
3098 * 'arabic' is set, handle various sub-settings.
3099 */
3100 if (!p_tbidi)
3101 {
3102 /* set rightleft mode */
3103 if (!curwin->w_p_rl)
3104 {
3105 curwin->w_p_rl = TRUE;
3106 changed_window_setting();
3107 }
3108
3109 /* Enable Arabic shaping (major part of what Arabic requires) */
3110 if (!p_arshape)
3111 {
3112 p_arshape = TRUE;
3113 redraw_later_clear();
3114 }
3115 }
3116
3117 /* Arabic requires a utf-8 encoding, inform the user if its not
3118 * set. */
3119 if (STRCMP(p_enc, "utf-8") != 0)
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00003120 {
Bram Moolenaar496c5262009-03-18 14:42:00 +00003121 static char *w_arabic = N_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'");
3122
Bram Moolenaar8820b482017-03-16 17:23:31 +01003123 msg_source(HL_ATTR(HLF_W));
Bram Moolenaar32526b32019-01-19 17:43:09 +01003124 msg_attr(_(w_arabic), HL_ATTR(HLF_W));
Bram Moolenaar496c5262009-03-18 14:42:00 +00003125#ifdef FEAT_EVAL
3126 set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_arabic), -1);
3127#endif
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00003128 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003129
Bram Moolenaar071d4272004-06-13 20:20:40 +00003130 /* set 'delcombine' */
3131 p_deco = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003132
3133# ifdef FEAT_KEYMAP
3134 /* Force-set the necessary keymap for arabic */
3135 set_option_value((char_u *)"keymap", 0L, (char_u *)"arabic",
3136 OPT_LOCAL);
3137# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003138 }
3139 else
3140 {
3141 /*
3142 * 'arabic' is reset, handle various sub-settings.
3143 */
3144 if (!p_tbidi)
3145 {
3146 /* reset rightleft mode */
3147 if (curwin->w_p_rl)
3148 {
3149 curwin->w_p_rl = FALSE;
3150 changed_window_setting();
3151 }
3152
3153 /* 'arabicshape' isn't reset, it is a global option and
3154 * another window may still need it "on". */
3155 }
3156
3157 /* 'delcombine' isn't reset, it is a global option and another
3158 * window may still want it "on". */
3159
3160# ifdef FEAT_KEYMAP
3161 /* Revert to the default keymap */
3162 curbuf->b_p_iminsert = B_IMODE_NONE;
3163 curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
3164# endif
3165 }
Bram Moolenaar801f8b82009-07-29 13:42:05 +00003166 }
3167
Bram Moolenaar319bdbd2009-09-11 13:20:33 +00003168#endif
3169
Bram Moolenaar44826212019-08-22 21:23:20 +02003170#if defined(FEAT_SIGNS) && defined(FEAT_GUI)
3171 else if (((int *)varp == &curwin->w_p_nu
3172 || (int *)varp == &curwin->w_p_rnu)
3173 && gui.in_use
3174 && (*curwin->w_p_scl == 'n' && *(curwin->w_p_scl + 1) == 'u')
3175 && curbuf->b_signlist != NULL)
3176 {
3177 // If the 'number' or 'relativenumber' options are modified and
3178 // 'signcolumn' is set to 'number', then clear the screen for a full
3179 // refresh. Otherwise the sign icons are not displayed properly in the
3180 // number column. If the 'number' option is set and only the
3181 // 'relativenumber' option is toggled, then don't refresh the screen
3182 // (optimization).
3183 if (!(curwin->w_p_nu && ((int *)varp == &curwin->w_p_rnu)))
3184 redraw_all_later(CLEAR);
3185 }
3186#endif
3187
Bram Moolenaar61be73b2016-04-29 22:59:22 +02003188#ifdef FEAT_TERMGUICOLORS
3189 /* 'termguicolors' */
3190 else if ((int *)varp == &p_tgc)
Bram Moolenaar8a633e32016-04-21 21:10:14 +02003191 {
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003192# ifdef FEAT_VTP
3193 /* Do not turn on 'tgc' when 24-bit colors are not supported. */
Bram Moolenaarafde13b2019-04-28 19:46:49 +02003194 if (
3195# ifdef VIMDLL
3196 !gui.in_use && !gui.starting &&
3197# endif
3198 !has_vtp_working())
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003199 {
3200 p_tgc = 0;
Bram Moolenaaraa5df7e2019-02-03 14:53:10 +01003201 return N_("E954: 24-bit colors are not supported on this environment");
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003202 }
Bram Moolenaarc5cd8852018-05-01 15:47:38 +02003203 if (is_term_win32())
3204 swap_tcap();
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003205# endif
Bram Moolenaar8a633e32016-04-21 21:10:14 +02003206# ifdef FEAT_GUI
3207 if (!gui.in_use && !gui.starting)
3208# endif
3209 highlight_gui_started();
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003210# ifdef FEAT_VTP
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003211 /* reset t_Co */
Bram Moolenaarc5cd8852018-05-01 15:47:38 +02003212 if (is_term_win32())
Bram Moolenaarb0eb14f2018-06-28 15:29:52 +02003213 {
3214 control_console_color_rgb();
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003215 set_termname(T_NAME);
Bram Moolenaarb0eb14f2018-06-28 15:29:52 +02003216 init_highlight(TRUE, FALSE);
3217 }
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003218# endif
Bram Moolenaar8a633e32016-04-21 21:10:14 +02003219 }
3220#endif
3221
Bram Moolenaar071d4272004-06-13 20:20:40 +00003222 /*
3223 * End of handling side effects for bool options.
3224 */
3225
Bram Moolenaar53744302015-07-17 17:38:22 +02003226 /* after handling side effects, call autocommand */
3227
Bram Moolenaar071d4272004-06-13 20:20:40 +00003228 options[opt_idx].flags |= P_WAS_SET;
3229
Bram Moolenaarf2bd8ef2018-03-04 18:08:14 +01003230#if defined(FEAT_EVAL)
Bram Moolenaar3f3fb0b2018-09-21 11:59:32 +02003231 // Don't do this while starting up or recursively.
3232 if (!starting && *get_vim_var_str(VV_OPTION_TYPE) == NUL)
Bram Moolenaar53744302015-07-17 17:38:22 +02003233 {
Bram Moolenaard7c96872019-06-15 17:12:48 +02003234 char_u buf_old[2], buf_old_global[2], buf_new[2], buf_type[7];
Bram Moolenaar3f3fb0b2018-09-21 11:59:32 +02003235
Bram Moolenaarfb9bc482015-07-17 22:04:48 +02003236 vim_snprintf((char *)buf_old, 2, "%d", old_value ? TRUE: FALSE);
Bram Moolenaard7c96872019-06-15 17:12:48 +02003237 vim_snprintf((char *)buf_old_global, 2, "%d",
3238 old_global_value ? TRUE: FALSE);
Bram Moolenaarfb9bc482015-07-17 22:04:48 +02003239 vim_snprintf((char *)buf_new, 2, "%d", value ? TRUE: FALSE);
Bram Moolenaard7c96872019-06-15 17:12:48 +02003240 vim_snprintf((char *)buf_type, 7, "%s",
3241 (opt_flags & OPT_LOCAL) ? "local" : "global");
Bram Moolenaar53744302015-07-17 17:38:22 +02003242 set_vim_var_string(VV_OPTION_NEW, buf_new, -1);
3243 set_vim_var_string(VV_OPTION_OLD, buf_old, -1);
3244 set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
Bram Moolenaard7c96872019-06-15 17:12:48 +02003245 if (opt_flags & OPT_LOCAL)
3246 {
3247 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setlocal", -1);
3248 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
3249 }
3250 if (opt_flags & OPT_GLOBAL)
3251 {
3252 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setglobal", -1);
3253 set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old, -1);
3254 }
3255 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
3256 {
3257 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"set", -1);
3258 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
3259 set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old_global, -1);
3260 }
3261 if (opt_flags & OPT_MODELINE)
3262 {
3263 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"modeline", -1);
3264 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
3265 }
3266 apply_autocmds(EVENT_OPTIONSET, (char_u *)options[opt_idx].fullname,
3267 NULL, FALSE, NULL);
Bram Moolenaar53744302015-07-17 17:38:22 +02003268 reset_v_option_vars();
3269 }
3270#endif
3271
Bram Moolenaar071d4272004-06-13 20:20:40 +00003272 comp_col(); /* in case 'ruler' or 'showcmd' changed */
Bram Moolenaar913077c2012-03-28 19:59:04 +02003273 if (curwin->w_curswant != MAXCOL
Bram Moolenaar488eb262015-03-13 11:23:50 +01003274 && (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0)
Bram Moolenaar913077c2012-03-28 19:59:04 +02003275 curwin->w_set_curswant = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003276 check_redraw(options[opt_idx].flags);
3277
3278 return NULL;
3279}
3280
3281/*
3282 * Set the value of a number option, and take care of side effects.
3283 * Returns NULL for success, or an error message for an error.
3284 */
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003285 static char *
Bram Moolenaar9b578142016-01-30 19:39:49 +01003286set_num_option(
3287 int opt_idx, /* index in options[] table */
3288 char_u *varp, /* pointer to the option variable */
3289 long value, /* new value */
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003290 char *errbuf, /* buffer for error messages */
Bram Moolenaar9b578142016-01-30 19:39:49 +01003291 size_t errbuflen, /* length of "errbuf" */
3292 int opt_flags) /* OPT_LOCAL, OPT_GLOBAL and
Bram Moolenaar071d4272004-06-13 20:20:40 +00003293 OPT_MODELINE */
3294{
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003295 char *errmsg = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003296 long old_value = *(long *)varp;
Bram Moolenaar983f2f12019-06-16 16:41:41 +02003297#if defined(FEAT_EVAL)
Bram Moolenaard7c96872019-06-15 17:12:48 +02003298 long old_global_value = 0; // only used when setting a local and
3299 // global option
Bram Moolenaar983f2f12019-06-16 16:41:41 +02003300#endif
Bram Moolenaard7c96872019-06-15 17:12:48 +02003301 long old_Rows = Rows; // remember old Rows
3302 long old_Columns = Columns; // remember old Columns
Bram Moolenaar071d4272004-06-13 20:20:40 +00003303 long *pp = (long *)varp;
3304
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00003305 /* Disallow changing some options from secure mode. */
3306 if ((secure
3307#ifdef HAVE_SANDBOX
3308 || sandbox != 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00003309#endif
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00003310 ) && (options[opt_idx].flags & P_SECURE))
3311 return e_secure;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003312
Bram Moolenaar983f2f12019-06-16 16:41:41 +02003313#if defined(FEAT_EVAL)
Bram Moolenaard7c96872019-06-15 17:12:48 +02003314 // Save the global value before changing anything. This is needed as for
3315 // a global-only option setting the "local value" infact sets the global
3316 // value (since there is only one value).
3317 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
Bram Moolenaar983f2f12019-06-16 16:41:41 +02003318 old_global_value = *(long *)get_varp_scope(&(options[opt_idx]),
3319 OPT_GLOBAL);
3320#endif
Bram Moolenaard7c96872019-06-15 17:12:48 +02003321
Bram Moolenaar071d4272004-06-13 20:20:40 +00003322 *pp = value;
3323#ifdef FEAT_EVAL
3324 /* Remember where the option was set. */
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02003325 set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003326#endif
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00003327#ifdef FEAT_GUI
3328 need_mouse_correct = TRUE;
3329#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003330
Bram Moolenaar14f24742012-08-08 18:01:05 +02003331 if (curbuf->b_p_sw < 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003332 {
3333 errmsg = e_positive;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02003334#ifdef FEAT_VARTABS
3335 // Use the first 'vartabstop' value, or 'tabstop' if vts isn't in use.
3336 curbuf->b_p_sw = tabstop_count(curbuf->b_p_vts_array) > 0
3337 ? tabstop_first(curbuf->b_p_vts_array)
3338 : curbuf->b_p_ts;
3339#else
Bram Moolenaar071d4272004-06-13 20:20:40 +00003340 curbuf->b_p_sw = curbuf->b_p_ts;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02003341#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003342 }
3343
3344 /*
3345 * Number options that need some action when changed
3346 */
Bram Moolenaar071d4272004-06-13 20:20:40 +00003347 if (pp == &p_wh || pp == &p_hh)
3348 {
Bram Moolenaar1c3c1042018-06-12 16:49:30 +02003349 // 'winheight' and 'helpheight'
Bram Moolenaar071d4272004-06-13 20:20:40 +00003350 if (p_wh < 1)
3351 {
3352 errmsg = e_positive;
3353 p_wh = 1;
3354 }
3355 if (p_wmh > p_wh)
3356 {
3357 errmsg = e_winheight;
3358 p_wh = p_wmh;
3359 }
3360 if (p_hh < 0)
3361 {
3362 errmsg = e_positive;
3363 p_hh = 0;
3364 }
3365
3366 /* Change window height NOW */
Bram Moolenaar459ca562016-11-10 18:16:33 +01003367 if (!ONE_WINDOW)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003368 {
3369 if (pp == &p_wh && curwin->w_height < p_wh)
3370 win_setheight((int)p_wh);
3371 if (pp == &p_hh && curbuf->b_help && curwin->w_height < p_hh)
3372 win_setheight((int)p_hh);
3373 }
3374 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003375 else if (pp == &p_wmh)
3376 {
Bram Moolenaar1c3c1042018-06-12 16:49:30 +02003377 // 'winminheight'
Bram Moolenaar071d4272004-06-13 20:20:40 +00003378 if (p_wmh < 0)
3379 {
3380 errmsg = e_positive;
3381 p_wmh = 0;
3382 }
3383 if (p_wmh > p_wh)
3384 {
3385 errmsg = e_winheight;
3386 p_wmh = p_wh;
3387 }
3388 win_setminheight();
3389 }
Bram Moolenaar592e0a22004-07-03 16:05:59 +00003390 else if (pp == &p_wiw)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003391 {
Bram Moolenaar1c3c1042018-06-12 16:49:30 +02003392 // 'winwidth'
Bram Moolenaar071d4272004-06-13 20:20:40 +00003393 if (p_wiw < 1)
3394 {
3395 errmsg = e_positive;
3396 p_wiw = 1;
3397 }
3398 if (p_wmw > p_wiw)
3399 {
3400 errmsg = e_winwidth;
3401 p_wiw = p_wmw;
3402 }
3403
3404 /* Change window width NOW */
Bram Moolenaar459ca562016-11-10 18:16:33 +01003405 if (!ONE_WINDOW && curwin->w_width < p_wiw)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003406 win_setwidth((int)p_wiw);
3407 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003408 else if (pp == &p_wmw)
3409 {
Bram Moolenaar1c3c1042018-06-12 16:49:30 +02003410 // 'winminwidth'
Bram Moolenaar071d4272004-06-13 20:20:40 +00003411 if (p_wmw < 0)
3412 {
3413 errmsg = e_positive;
3414 p_wmw = 0;
3415 }
3416 if (p_wmw > p_wiw)
3417 {
3418 errmsg = e_winwidth;
3419 p_wmw = p_wiw;
3420 }
Bram Moolenaar1c3c1042018-06-12 16:49:30 +02003421 win_setminwidth();
Bram Moolenaar071d4272004-06-13 20:20:40 +00003422 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003423
Bram Moolenaar071d4272004-06-13 20:20:40 +00003424 /* (re)set last window status line */
3425 else if (pp == &p_ls)
3426 {
3427 last_status(FALSE);
3428 }
Bram Moolenaar4c7ed462006-02-15 22:18:42 +00003429
3430 /* (re)set tab page line */
Bram Moolenaarfaa959a2006-02-20 21:37:40 +00003431 else if (pp == &p_stal)
Bram Moolenaar4c7ed462006-02-15 22:18:42 +00003432 {
3433 shell_new_rows(); /* recompute window positions and heights */
3434 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003435
3436#ifdef FEAT_GUI
3437 else if (pp == &p_linespace)
3438 {
Bram Moolenaar02743632005-07-25 20:42:36 +00003439 /* Recompute gui.char_height and resize the Vim window to keep the
3440 * same number of lines. */
3441 if (gui.in_use && gui_mch_adjust_charheight() == OK)
Bram Moolenaar3964b7e2006-03-27 20:59:33 +00003442 gui_set_shellsize(FALSE, FALSE, RESIZE_VERT);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003443 }
3444#endif
3445
3446#ifdef FEAT_FOLDING
3447 /* 'foldlevel' */
3448 else if (pp == &curwin->w_p_fdl)
3449 {
3450 if (curwin->w_p_fdl < 0)
3451 curwin->w_p_fdl = 0;
3452 newFoldLevel();
3453 }
3454
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00003455 /* 'foldminlines' */
Bram Moolenaar071d4272004-06-13 20:20:40 +00003456 else if (pp == &curwin->w_p_fml)
3457 {
3458 foldUpdateAll(curwin);
3459 }
3460
3461 /* 'foldnestmax' */
3462 else if (pp == &curwin->w_p_fdn)
3463 {
3464 if (foldmethodIsSyntax(curwin) || foldmethodIsIndent(curwin))
3465 foldUpdateAll(curwin);
3466 }
3467
3468 /* 'foldcolumn' */
3469 else if (pp == &curwin->w_p_fdc)
3470 {
3471 if (curwin->w_p_fdc < 0)
3472 {
3473 errmsg = e_positive;
3474 curwin->w_p_fdc = 0;
3475 }
3476 else if (curwin->w_p_fdc > 12)
3477 {
3478 errmsg = e_invarg;
3479 curwin->w_p_fdc = 12;
3480 }
3481 }
Bram Moolenaar6bcbcc52013-11-05 07:13:41 +01003482#endif /* FEAT_FOLDING */
Bram Moolenaar071d4272004-06-13 20:20:40 +00003483
Bram Moolenaar6bcbcc52013-11-05 07:13:41 +01003484#if defined(FEAT_FOLDING) || defined(FEAT_CINDENT)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003485 /* 'shiftwidth' or 'tabstop' */
3486 else if (pp == &curbuf->b_p_sw || pp == &curbuf->b_p_ts)
3487 {
Bram Moolenaar6bcbcc52013-11-05 07:13:41 +01003488# ifdef FEAT_FOLDING
Bram Moolenaar071d4272004-06-13 20:20:40 +00003489 if (foldmethodIsIndent(curwin))
3490 foldUpdateAll(curwin);
Bram Moolenaar6bcbcc52013-11-05 07:13:41 +01003491# endif
3492# ifdef FEAT_CINDENT
3493 /* When 'shiftwidth' changes, or it's zero and 'tabstop' changes:
3494 * parse 'cinoptions'. */
3495 if (pp == &curbuf->b_p_sw || curbuf->b_p_sw == 0)
3496 parse_cino(curbuf);
3497# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003498 }
Bram Moolenaar6bcbcc52013-11-05 07:13:41 +01003499#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003500
Bram Moolenaar362e1a32006-03-06 23:29:24 +00003501 /* 'maxcombine' */
3502 else if (pp == &p_mco)
3503 {
3504 if (p_mco > MAX_MCO)
3505 p_mco = MAX_MCO;
3506 else if (p_mco < 0)
3507 p_mco = 0;
3508 screenclear(); /* will re-allocate the screen */
3509 }
Bram Moolenaar362e1a32006-03-06 23:29:24 +00003510
Bram Moolenaar071d4272004-06-13 20:20:40 +00003511 else if (pp == &curbuf->b_p_iminsert)
3512 {
3513 if (curbuf->b_p_iminsert < 0 || curbuf->b_p_iminsert > B_IMODE_LAST)
3514 {
3515 errmsg = e_invarg;
3516 curbuf->b_p_iminsert = B_IMODE_NONE;
3517 }
3518 p_iminsert = curbuf->b_p_iminsert;
3519 if (termcap_active) /* don't do this in the alternate screen */
3520 showmode();
Bram Moolenaar4033c552017-09-16 20:54:51 +02003521#if defined(FEAT_KEYMAP)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003522 /* Show/unshow value of 'keymap' in status lines. */
3523 status_redraw_curbuf();
3524#endif
3525 }
3526
Bram Moolenaar5c6dbcb2017-08-30 22:00:20 +02003527#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
3528 /* 'imstyle' */
3529 else if (pp == &p_imst)
3530 {
3531 if (p_imst != IM_ON_THE_SPOT && p_imst != IM_OVER_THE_SPOT)
3532 errmsg = e_invarg;
3533 }
3534#endif
3535
Bram Moolenaar4399ef42005-02-12 14:29:27 +00003536 else if (pp == &p_window)
3537 {
3538 if (p_window < 1)
3539 p_window = 1;
3540 else if (p_window >= Rows)
3541 p_window = Rows - 1;
3542 }
3543
Bram Moolenaar071d4272004-06-13 20:20:40 +00003544 else if (pp == &curbuf->b_p_imsearch)
3545 {
3546 if (curbuf->b_p_imsearch < -1 || curbuf->b_p_imsearch > B_IMODE_LAST)
3547 {
3548 errmsg = e_invarg;
3549 curbuf->b_p_imsearch = B_IMODE_NONE;
3550 }
3551 p_imsearch = curbuf->b_p_imsearch;
3552 }
3553
3554#ifdef FEAT_TITLE
3555 /* if 'titlelen' has changed, redraw the title */
3556 else if (pp == &p_titlelen)
3557 {
3558 if (p_titlelen < 0)
3559 {
3560 errmsg = e_positive;
3561 p_titlelen = 85;
3562 }
3563 if (starting != NO_SCREEN && old_value != p_titlelen)
3564 need_maketitle = TRUE;
3565 }
3566#endif
3567
3568 /* if p_ch changed value, change the command line height */
3569 else if (pp == &p_ch)
3570 {
3571 if (p_ch < 1)
3572 {
3573 errmsg = e_positive;
3574 p_ch = 1;
3575 }
Bram Moolenaar719939c2007-09-25 12:51:28 +00003576 if (p_ch > Rows - min_rows() + 1)
3577 p_ch = Rows - min_rows() + 1;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003578
3579 /* Only compute the new window layout when startup has been
3580 * completed. Otherwise the frame sizes may be wrong. */
3581 if (p_ch != old_value && full_screen
3582#ifdef FEAT_GUI
3583 && !gui.starting
3584#endif
3585 )
Bram Moolenaarc6fe9192006-04-09 21:54:49 +00003586 command_height();
Bram Moolenaar071d4272004-06-13 20:20:40 +00003587 }
3588
3589 /* when 'updatecount' changes from zero to non-zero, open swap files */
3590 else if (pp == &p_uc)
3591 {
3592 if (p_uc < 0)
3593 {
3594 errmsg = e_positive;
3595 p_uc = 100;
3596 }
3597 if (p_uc && !old_value)
3598 ml_open_files();
3599 }
Bram Moolenaar860cae12010-06-05 23:22:07 +02003600#ifdef FEAT_CONCEAL
Bram Moolenaarf5963f72010-07-23 22:10:27 +02003601 else if (pp == &curwin->w_p_cole)
Bram Moolenaar860cae12010-06-05 23:22:07 +02003602 {
Bram Moolenaarf5963f72010-07-23 22:10:27 +02003603 if (curwin->w_p_cole < 0)
Bram Moolenaar860cae12010-06-05 23:22:07 +02003604 {
3605 errmsg = e_positive;
Bram Moolenaarf5963f72010-07-23 22:10:27 +02003606 curwin->w_p_cole = 0;
Bram Moolenaar860cae12010-06-05 23:22:07 +02003607 }
Bram Moolenaarf5963f72010-07-23 22:10:27 +02003608 else if (curwin->w_p_cole > 3)
Bram Moolenaar860cae12010-06-05 23:22:07 +02003609 {
3610 errmsg = e_invarg;
Bram Moolenaarf5963f72010-07-23 22:10:27 +02003611 curwin->w_p_cole = 3;
Bram Moolenaar860cae12010-06-05 23:22:07 +02003612 }
3613 }
3614#endif
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00003615#ifdef MZSCHEME_GUI_THREADS
Bram Moolenaar325b7a22004-07-05 15:58:32 +00003616 else if (pp == &p_mzq)
3617 mzvim_reset_timer();
3618#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003619
Bram Moolenaarf42dd3c2017-01-28 16:06:38 +01003620#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
3621 /* 'pyxversion' */
3622 else if (pp == &p_pyx)
3623 {
3624 if (p_pyx != 0 && p_pyx != 2 && p_pyx != 3)
3625 errmsg = e_invarg;
3626 }
3627#endif
3628
Bram Moolenaar071d4272004-06-13 20:20:40 +00003629 /* sync undo before 'undolevels' changes */
3630 else if (pp == &p_ul)
3631 {
3632 /* use the old value, otherwise u_sync() may not work properly */
3633 p_ul = old_value;
Bram Moolenaar779b74b2006-04-10 14:55:34 +00003634 u_sync(TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003635 p_ul = value;
3636 }
Bram Moolenaarf5a2fd82013-11-06 05:26:15 +01003637 else if (pp == &curbuf->b_p_ul)
3638 {
3639 /* use the old value, otherwise u_sync() may not work properly */
3640 curbuf->b_p_ul = old_value;
3641 u_sync(TRUE);
3642 curbuf->b_p_ul = value;
3643 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003644
Bram Moolenaar592e0a22004-07-03 16:05:59 +00003645#ifdef FEAT_LINEBREAK
3646 /* 'numberwidth' must be positive */
3647 else if (pp == &curwin->w_p_nuw)
3648 {
3649 if (curwin->w_p_nuw < 1)
3650 {
3651 errmsg = e_positive;
3652 curwin->w_p_nuw = 1;
3653 }
Bram Moolenaarf8a07122019-07-01 22:06:07 +02003654 if (curwin->w_p_nuw > 20)
Bram Moolenaar592e0a22004-07-03 16:05:59 +00003655 {
3656 errmsg = e_invarg;
Bram Moolenaarf8a07122019-07-01 22:06:07 +02003657 curwin->w_p_nuw = 20;
Bram Moolenaar592e0a22004-07-03 16:05:59 +00003658 }
Bram Moolenaar1e7813a2015-03-31 18:31:03 +02003659 curwin->w_nrwidth_line_count = 0; /* trigger a redraw */
Bram Moolenaar592e0a22004-07-03 16:05:59 +00003660 }
3661#endif
3662
Bram Moolenaar1a384422010-07-14 19:53:30 +02003663 else if (pp == &curbuf->b_p_tw)
3664 {
3665 if (curbuf->b_p_tw < 0)
3666 {
3667 errmsg = e_positive;
3668 curbuf->b_p_tw = 0;
3669 }
3670#ifdef FEAT_SYN_HL
Bram Moolenaar1a384422010-07-14 19:53:30 +02003671 {
3672 win_T *wp;
3673 tabpage_T *tp;
3674
3675 FOR_ALL_TAB_WINDOWS(tp, wp)
3676 check_colorcolumn(wp);
3677 }
Bram Moolenaar1a384422010-07-14 19:53:30 +02003678#endif
3679 }
3680
Bram Moolenaar071d4272004-06-13 20:20:40 +00003681 /*
3682 * Check the bounds for numeric options here
3683 */
3684 if (Rows < min_rows() && full_screen)
3685 {
3686 if (errbuf != NULL)
3687 {
Bram Moolenaar555b2802005-05-19 21:08:39 +00003688 vim_snprintf((char *)errbuf, errbuflen,
3689 _("E593: Need at least %d lines"), min_rows());
Bram Moolenaar071d4272004-06-13 20:20:40 +00003690 errmsg = errbuf;
3691 }
3692 Rows = min_rows();
3693 }
3694 if (Columns < MIN_COLUMNS && full_screen)
3695 {
3696 if (errbuf != NULL)
3697 {
Bram Moolenaar555b2802005-05-19 21:08:39 +00003698 vim_snprintf((char *)errbuf, errbuflen,
3699 _("E594: Need at least %d columns"), MIN_COLUMNS);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003700 errmsg = errbuf;
3701 }
3702 Columns = MIN_COLUMNS;
3703 }
Bram Moolenaare057d402013-06-30 17:51:51 +02003704 limit_screen_size();
Bram Moolenaar071d4272004-06-13 20:20:40 +00003705
Bram Moolenaar071d4272004-06-13 20:20:40 +00003706 /*
3707 * If the screen (shell) height has been changed, assume it is the
3708 * physical screenheight.
3709 */
3710 if (old_Rows != Rows || old_Columns != Columns)
3711 {
3712 /* Changing the screen size is not allowed while updating the screen. */
3713 if (updating_screen)
3714 *pp = old_value;
3715 else if (full_screen
3716#ifdef FEAT_GUI
3717 && !gui.starting
3718#endif
3719 )
3720 set_shellsize((int)Columns, (int)Rows, TRUE);
3721 else
3722 {
3723 /* Postpone the resizing; check the size and cmdline position for
3724 * messages. */
3725 check_shellsize();
3726 if (cmdline_row > Rows - p_ch && Rows > p_ch)
3727 cmdline_row = Rows - p_ch;
3728 }
Bram Moolenaard68071d2006-05-02 22:08:30 +00003729 if (p_window >= Rows || !option_was_set((char_u *)"window"))
Bram Moolenaar4399ef42005-02-12 14:29:27 +00003730 p_window = Rows - 1;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003731 }
3732
Bram Moolenaar071d4272004-06-13 20:20:40 +00003733 if (curbuf->b_p_ts <= 0)
3734 {
3735 errmsg = e_positive;
3736 curbuf->b_p_ts = 8;
3737 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003738 if (p_tm < 0)
3739 {
3740 errmsg = e_positive;
3741 p_tm = 0;
3742 }
3743 if ((curwin->w_p_scr <= 0
3744 || (curwin->w_p_scr > curwin->w_height
3745 && curwin->w_height > 0))
3746 && full_screen)
3747 {
3748 if (pp == &(curwin->w_p_scr))
3749 {
3750 if (curwin->w_p_scr != 0)
3751 errmsg = e_scroll;
3752 win_comp_scroll(curwin);
3753 }
3754 /* If 'scroll' became invalid because of a side effect silently adjust
3755 * it. */
3756 else if (curwin->w_p_scr <= 0)
3757 curwin->w_p_scr = 1;
3758 else /* curwin->w_p_scr > curwin->w_height */
3759 curwin->w_p_scr = curwin->w_height;
3760 }
Bram Moolenaar991e10f2008-10-02 20:48:41 +00003761 if (p_hi < 0)
3762 {
3763 errmsg = e_positive;
3764 p_hi = 0;
3765 }
Bram Moolenaar78159bb2014-06-25 11:48:54 +02003766 else if (p_hi > 10000)
3767 {
3768 errmsg = e_invarg;
3769 p_hi = 10000;
3770 }
Bram Moolenaarfbc0d2e2013-05-19 19:40:29 +02003771 if (p_re < 0 || p_re > 2)
3772 {
3773 errmsg = e_invarg;
3774 p_re = 0;
3775 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003776 if (p_report < 0)
3777 {
3778 errmsg = e_positive;
3779 p_report = 1;
3780 }
Bram Moolenaar1e015462005-09-25 22:16:38 +00003781 if ((p_sj < -100 || p_sj >= Rows) && full_screen)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003782 {
3783 if (Rows != old_Rows) /* Rows changed, just adjust p_sj */
3784 p_sj = Rows / 2;
3785 else
3786 {
3787 errmsg = e_scroll;
3788 p_sj = 1;
3789 }
3790 }
3791 if (p_so < 0 && full_screen)
3792 {
Bram Moolenaar375e3392019-01-31 18:26:10 +01003793 errmsg = e_positive;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003794 p_so = 0;
3795 }
3796 if (p_siso < 0 && full_screen)
3797 {
3798 errmsg = e_positive;
3799 p_siso = 0;
3800 }
3801#ifdef FEAT_CMDWIN
3802 if (p_cwh < 1)
3803 {
3804 errmsg = e_positive;
3805 p_cwh = 1;
3806 }
3807#endif
3808 if (p_ut < 0)
3809 {
3810 errmsg = e_positive;
3811 p_ut = 2000;
3812 }
3813 if (p_ss < 0)
3814 {
3815 errmsg = e_positive;
3816 p_ss = 0;
3817 }
3818
3819 /* May set global value for local option. */
3820 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
3821 *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = *pp;
3822
3823 options[opt_idx].flags |= P_WAS_SET;
3824
Bram Moolenaarf2bd8ef2018-03-04 18:08:14 +01003825#if defined(FEAT_EVAL)
Bram Moolenaar3f3fb0b2018-09-21 11:59:32 +02003826 // Don't do this while starting up, failure or recursively.
3827 if (!starting && errmsg == NULL && *get_vim_var_str(VV_OPTION_TYPE) == NUL)
Bram Moolenaar53744302015-07-17 17:38:22 +02003828 {
Bram Moolenaard7c96872019-06-15 17:12:48 +02003829 char_u buf_old[11], buf_old_global[11], buf_new[11], buf_type[7];
Bram Moolenaarfb9bc482015-07-17 22:04:48 +02003830 vim_snprintf((char *)buf_old, 10, "%ld", old_value);
Bram Moolenaard7c96872019-06-15 17:12:48 +02003831 vim_snprintf((char *)buf_old_global, 10, "%ld", old_global_value);
Bram Moolenaarfb9bc482015-07-17 22:04:48 +02003832 vim_snprintf((char *)buf_new, 10, "%ld", value);
3833 vim_snprintf((char *)buf_type, 7, "%s", (opt_flags & OPT_LOCAL) ? "local" : "global");
Bram Moolenaar53744302015-07-17 17:38:22 +02003834 set_vim_var_string(VV_OPTION_NEW, buf_new, -1);
3835 set_vim_var_string(VV_OPTION_OLD, buf_old, -1);
3836 set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
Bram Moolenaard7c96872019-06-15 17:12:48 +02003837 if (opt_flags & OPT_LOCAL)
3838 {
3839 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setlocal", -1);
3840 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
3841 }
3842 if (opt_flags & OPT_GLOBAL)
3843 {
3844 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setglobal", -1);
3845 set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old, -1);
3846 }
3847 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
3848 {
3849 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"set", -1);
3850 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
3851 set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old_global, -1);
3852 }
3853 if (opt_flags & OPT_MODELINE)
3854 {
3855 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"modeline", -1);
3856 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
3857 }
3858 apply_autocmds(EVENT_OPTIONSET, (char_u *)options[opt_idx].fullname,
3859 NULL, FALSE, NULL);
Bram Moolenaar53744302015-07-17 17:38:22 +02003860 reset_v_option_vars();
3861 }
3862#endif
3863
Bram Moolenaar071d4272004-06-13 20:20:40 +00003864 comp_col(); /* in case 'columns' or 'ls' changed */
Bram Moolenaar913077c2012-03-28 19:59:04 +02003865 if (curwin->w_curswant != MAXCOL
Bram Moolenaar488eb262015-03-13 11:23:50 +01003866 && (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0)
Bram Moolenaar913077c2012-03-28 19:59:04 +02003867 curwin->w_set_curswant = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003868 check_redraw(options[opt_idx].flags);
3869
3870 return errmsg;
3871}
3872
3873/*
3874 * Called after an option changed: check if something needs to be redrawn.
3875 */
Bram Moolenaardac13472019-09-16 21:06:21 +02003876 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01003877check_redraw(long_u flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003878{
3879 /* Careful: P_RCLR and P_RALL are a combination of other P_ flags */
Bram Moolenaar70b2a562012-01-10 22:26:17 +01003880 int doclear = (flags & P_RCLR) == P_RCLR;
3881 int all = ((flags & P_RALL) == P_RALL || doclear);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003882
Bram Moolenaar071d4272004-06-13 20:20:40 +00003883 if ((flags & P_RSTAT) || all) /* mark all status lines dirty */
3884 status_redraw_all();
Bram Moolenaar071d4272004-06-13 20:20:40 +00003885
3886 if ((flags & P_RBUF) || (flags & P_RWIN) || all)
3887 changed_window_setting();
3888 if (flags & P_RBUF)
3889 redraw_curbuf_later(NOT_VALID);
Bram Moolenaara2477fd2016-12-03 15:13:20 +01003890 if (flags & P_RWINONLY)
3891 redraw_later(NOT_VALID);
Bram Moolenaar70b2a562012-01-10 22:26:17 +01003892 if (doclear)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003893 redraw_all_later(CLEAR);
3894 else if (all)
3895 redraw_all_later(NOT_VALID);
3896}
3897
3898/*
3899 * Find index for option 'arg'.
3900 * Return -1 if not found.
3901 */
Bram Moolenaardac13472019-09-16 21:06:21 +02003902 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01003903findoption(char_u *arg)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003904{
3905 int opt_idx;
3906 char *s, *p;
3907 static short quick_tab[27] = {0, 0}; /* quick access table */
3908 int is_term_opt;
3909
3910 /*
3911 * For first call: Initialize the quick-access table.
3912 * It contains the index for the first option that starts with a certain
3913 * letter. There are 26 letters, plus the first "t_" option.
3914 */
3915 if (quick_tab[1] == 0)
3916 {
3917 p = options[0].fullname;
3918 for (opt_idx = 1; (s = options[opt_idx].fullname) != NULL; opt_idx++)
3919 {
3920 if (s[0] != p[0])
3921 {
3922 if (s[0] == 't' && s[1] == '_')
3923 quick_tab[26] = opt_idx;
3924 else
3925 quick_tab[CharOrdLow(s[0])] = opt_idx;
3926 }
3927 p = s;
3928 }
3929 }
3930
3931 /*
3932 * Check for name starting with an illegal character.
3933 */
3934#ifdef EBCDIC
3935 if (!islower(arg[0]))
3936#else
3937 if (arg[0] < 'a' || arg[0] > 'z')
3938#endif
3939 return -1;
3940
3941 is_term_opt = (arg[0] == 't' && arg[1] == '_');
3942 if (is_term_opt)
3943 opt_idx = quick_tab[26];
3944 else
3945 opt_idx = quick_tab[CharOrdLow(arg[0])];
3946 for ( ; (s = options[opt_idx].fullname) != NULL; opt_idx++)
3947 {
3948 if (STRCMP(arg, s) == 0) /* match full name */
3949 break;
3950 }
3951 if (s == NULL && !is_term_opt)
3952 {
3953 opt_idx = quick_tab[CharOrdLow(arg[0])];
3954 for ( ; options[opt_idx].fullname != NULL; opt_idx++)
3955 {
3956 s = options[opt_idx].shortname;
3957 if (s != NULL && STRCMP(arg, s) == 0) /* match short name */
3958 break;
3959 s = NULL;
3960 }
3961 }
3962 if (s == NULL)
3963 opt_idx = -1;
3964 return opt_idx;
3965}
3966
Bram Moolenaar325b7a22004-07-05 15:58:32 +00003967#if defined(FEAT_EVAL) || defined(FEAT_TCL) || defined(FEAT_MZSCHEME)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003968/*
3969 * Get the value for an option.
3970 *
3971 * Returns:
3972 * Number or Toggle option: 1, *numval gets value.
3973 * String option: 0, *stringval gets allocated string.
3974 * Hidden Number or Toggle option: -1.
3975 * hidden String option: -2.
3976 * unknown option: -3.
3977 */
3978 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01003979get_option_value(
3980 char_u *name,
3981 long *numval,
3982 char_u **stringval, /* NULL when only checking existence */
3983 int opt_flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003984{
3985 int opt_idx;
3986 char_u *varp;
3987
3988 opt_idx = findoption(name);
3989 if (opt_idx < 0) /* unknown option */
Bram Moolenaare353c402017-02-04 19:49:16 +01003990 {
3991 int key;
3992
3993 if (STRLEN(name) == 4 && name[0] == 't' && name[1] == '_'
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02003994 && (key = find_key_option(name, FALSE)) != 0)
Bram Moolenaare353c402017-02-04 19:49:16 +01003995 {
3996 char_u key_name[2];
3997 char_u *p;
3998
3999 if (key < 0)
4000 {
4001 key_name[0] = KEY2TERMCAP0(key);
4002 key_name[1] = KEY2TERMCAP1(key);
4003 }
4004 else
4005 {
4006 key_name[0] = KS_KEY;
4007 key_name[1] = (key & 0xff);
4008 }
4009 p = find_termcode(key_name);
4010 if (p != NULL)
4011 {
4012 if (stringval != NULL)
4013 *stringval = vim_strsave(p);
4014 return 0;
4015 }
4016 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004017 return -3;
Bram Moolenaare353c402017-02-04 19:49:16 +01004018 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004019
4020 varp = get_varp_scope(&(options[opt_idx]), opt_flags);
4021
4022 if (options[opt_idx].flags & P_STRING)
4023 {
4024 if (varp == NULL) /* hidden option */
4025 return -2;
4026 if (stringval != NULL)
4027 {
4028#ifdef FEAT_CRYPT
4029 /* never return the value of the crypt key */
Bram Moolenaarc1a11ed2008-06-24 22:09:24 +00004030 if ((char_u **)varp == &curbuf->b_p_key
4031 && **(char_u **)(varp) != NUL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004032 *stringval = vim_strsave((char_u *)"*****");
4033 else
4034#endif
4035 *stringval = vim_strsave(*(char_u **)(varp));
4036 }
4037 return 0;
4038 }
4039
4040 if (varp == NULL) /* hidden option */
4041 return -1;
4042 if (options[opt_idx].flags & P_NUM)
4043 *numval = *(long *)varp;
4044 else
4045 {
4046 /* Special case: 'modified' is b_changed, but we also want to consider
4047 * it set when 'ff' or 'fenc' changed. */
4048 if ((int *)varp == &curbuf->b_changed)
4049 *numval = curbufIsChanged();
4050 else
Bram Moolenaar2acfbed2016-07-01 23:14:02 +02004051 *numval = (long) *(int *)varp;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004052 }
4053 return 1;
4054}
4055#endif
4056
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004057#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) || defined(PROTO)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004058/*
4059 * Returns the option attributes and its value. Unlike the above function it
4060 * will return either global value or local value of the option depending on
4061 * what was requested, but it will never return global value if it was
4062 * requested to return local one and vice versa. Neither it will return
4063 * buffer-local value if it was requested to return window-local one.
4064 *
4065 * Pretends that option is absent if it is not present in the requested scope
4066 * (i.e. has no global, window-local or buffer-local value depending on
4067 * opt_type). Uses
4068 *
4069 * Returned flags:
Bram Moolenaar75a8d742014-05-07 15:10:21 +02004070 * 0 hidden or unknown option, also option that does not have requested
4071 * type (see SREQ_* in vim.h)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004072 * see SOPT_* in vim.h for other flags
4073 *
4074 * Possible opt_type values: see SREQ_* in vim.h
4075 */
4076 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01004077get_option_value_strict(
4078 char_u *name,
4079 long *numval,
4080 char_u **stringval, /* NULL when only obtaining attributes */
4081 int opt_type,
4082 void *from)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004083{
4084 int opt_idx;
Bram Moolenaar68001862013-05-11 13:45:05 +02004085 char_u *varp = NULL;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004086 struct vimoption *p;
4087 int r = 0;
4088
4089 opt_idx = findoption(name);
4090 if (opt_idx < 0)
4091 return 0;
4092
4093 p = &(options[opt_idx]);
4094
4095 /* Hidden option */
4096 if (p->var == NULL)
4097 return 0;
4098
4099 if (p->flags & P_BOOL)
4100 r |= SOPT_BOOL;
4101 else if (p->flags & P_NUM)
4102 r |= SOPT_NUM;
4103 else if (p->flags & P_STRING)
4104 r |= SOPT_STRING;
4105
4106 if (p->indir == PV_NONE)
4107 {
4108 if (opt_type == SREQ_GLOBAL)
4109 r |= SOPT_GLOBAL;
4110 else
4111 return 0; /* Did not request global-only option */
4112 }
4113 else
4114 {
4115 if (p->indir & PV_BOTH)
4116 r |= SOPT_GLOBAL;
4117 else if (opt_type == SREQ_GLOBAL)
4118 return 0; /* Requested global option */
4119
4120 if (p->indir & PV_WIN)
4121 {
4122 if (opt_type == SREQ_BUF)
4123 return 0; /* Did not request window-local option */
4124 else
4125 r |= SOPT_WIN;
4126 }
4127 else if (p->indir & PV_BUF)
4128 {
4129 if (opt_type == SREQ_WIN)
4130 return 0; /* Did not request buffer-local option */
4131 else
4132 r |= SOPT_BUF;
4133 }
4134 }
4135
4136 if (stringval == NULL)
4137 return r;
4138
4139 if (opt_type == SREQ_GLOBAL)
4140 varp = p->var;
4141 else
4142 {
4143 if (opt_type == SREQ_BUF)
4144 {
4145 /* Special case: 'modified' is b_changed, but we also want to
4146 * consider it set when 'ff' or 'fenc' changed. */
4147 if (p->indir == PV_MOD)
4148 {
Bram Moolenaardefe6422018-06-24 15:14:07 +02004149 *numval = bufIsChanged((buf_T *)from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004150 varp = NULL;
4151 }
4152#ifdef FEAT_CRYPT
4153 else if (p->indir == PV_KEY)
4154 {
4155 /* never return the value of the crypt key */
4156 *stringval = NULL;
4157 varp = NULL;
4158 }
4159#endif
4160 else
4161 {
Bram Moolenaardefe6422018-06-24 15:14:07 +02004162 buf_T *save_curbuf = curbuf;
4163
4164 // only getting a pointer, no need to use aucmd_prepbuf()
4165 curbuf = (buf_T *)from;
4166 curwin->w_buffer = curbuf;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004167 varp = get_varp(p);
Bram Moolenaardefe6422018-06-24 15:14:07 +02004168 curbuf = save_curbuf;
4169 curwin->w_buffer = curbuf;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004170 }
4171 }
4172 else if (opt_type == SREQ_WIN)
4173 {
Bram Moolenaardefe6422018-06-24 15:14:07 +02004174 win_T *save_curwin = curwin;
4175
4176 curwin = (win_T *)from;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004177 curbuf = curwin->w_buffer;
4178 varp = get_varp(p);
4179 curwin = save_curwin;
4180 curbuf = curwin->w_buffer;
4181 }
4182 if (varp == p->var)
4183 return (r | SOPT_UNSET);
4184 }
4185
4186 if (varp != NULL)
4187 {
4188 if (p->flags & P_STRING)
4189 *stringval = vim_strsave(*(char_u **)(varp));
4190 else if (p->flags & P_NUM)
4191 *numval = *(long *) varp;
4192 else
4193 *numval = *(int *)varp;
4194 }
4195
4196 return r;
4197}
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004198
4199/*
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02004200 * Iterate over options. First argument is a pointer to a pointer to a
4201 * structure inside options[] array, second is option type like in the above
4202 * function.
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004203 *
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02004204 * If first argument points to NULL it is assumed that iteration just started
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004205 * and caller needs the very first value.
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02004206 * If first argument points to the end marker function returns NULL and sets
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004207 * first argument to NULL.
4208 *
4209 * Returns full option name for current option on each call.
4210 */
4211 char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01004212option_iter_next(void **option, int opt_type)
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004213{
4214 struct vimoption *ret = NULL;
4215 do
4216 {
4217 if (*option == NULL)
4218 *option = (void *) options;
4219 else if (((struct vimoption *) (*option))->fullname == NULL)
4220 {
4221 *option = NULL;
4222 return NULL;
4223 }
4224 else
4225 *option = (void *) (((struct vimoption *) (*option)) + 1);
4226
4227 ret = ((struct vimoption *) (*option));
4228
4229 /* Hidden option */
4230 if (ret->var == NULL)
4231 {
4232 ret = NULL;
4233 continue;
4234 }
4235
4236 switch (opt_type)
4237 {
4238 case SREQ_GLOBAL:
4239 if (!(ret->indir == PV_NONE || ret->indir & PV_BOTH))
4240 ret = NULL;
4241 break;
4242 case SREQ_BUF:
4243 if (!(ret->indir & PV_BUF))
4244 ret = NULL;
4245 break;
4246 case SREQ_WIN:
4247 if (!(ret->indir & PV_WIN))
4248 ret = NULL;
4249 break;
4250 default:
Bram Moolenaar95f09602016-11-10 20:01:45 +01004251 internal_error("option_iter_next()");
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004252 return NULL;
4253 }
4254 }
4255 while (ret == NULL);
4256
4257 return (char_u *)ret->fullname;
4258}
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004259#endif
4260
Bram Moolenaar071d4272004-06-13 20:20:40 +00004261/*
Bram Moolenaardac13472019-09-16 21:06:21 +02004262 * Return the flags for the option at 'opt_idx'.
4263 */
4264 long_u
4265get_option_flags(int opt_idx)
4266{
4267 return options[opt_idx].flags;
4268}
4269
4270/*
4271 * Set a flag for the option at 'opt_idx'.
4272 */
4273 void
4274set_option_flag(int opt_idx, long_u flag)
4275{
4276 options[opt_idx].flags |= flag;
4277}
4278
4279/*
4280 * Clear a flag for the option at 'opt_idx'.
4281 */
4282 void
4283clear_option_flag(int opt_idx, long_u flag)
4284{
4285 options[opt_idx].flags &= ~flag;
4286}
4287
4288/*
4289 * Returns TRUE if the option at 'opt_idx' is a global option
4290 */
4291 int
4292is_global_option(int opt_idx)
4293{
4294 return options[opt_idx].indir == PV_NONE;
4295}
4296
4297/*
4298 * Returns TRUE if the option at 'opt_idx' is a global option which also has a
4299 * local value.
4300 */
4301 int
4302is_global_local_option(int opt_idx)
4303{
4304 return options[opt_idx].indir & PV_BOTH;
4305}
4306
4307/*
4308 * Returns TRUE if the option at 'opt_idx' is a window-local option
4309 */
4310 int
4311is_window_local_option(int opt_idx)
4312{
4313 return options[opt_idx].var == VAR_WIN;
4314}
4315
4316/*
4317 * Returns TRUE if the option at 'opt_idx' is a hidden option
4318 */
4319 int
4320is_hidden_option(int opt_idx)
4321{
4322 return options[opt_idx].var == NULL;
4323}
4324
4325#if defined(FEAT_CRYPT) || defined(PROTO)
4326/*
4327 * Returns TRUE if the option at 'opt_idx' is a crypt key option
4328 */
4329 int
4330is_crypt_key_option(int opt_idx)
4331{
4332 return options[opt_idx].indir == PV_KEY;
4333}
4334#endif
4335
4336/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00004337 * Set the value of option "name".
4338 * Use "string" for string options, use "number" for other options.
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004339 *
4340 * Returns NULL on success or error message on error.
Bram Moolenaar071d4272004-06-13 20:20:40 +00004341 */
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004342 char *
Bram Moolenaar9b578142016-01-30 19:39:49 +01004343set_option_value(
4344 char_u *name,
4345 long number,
4346 char_u *string,
4347 int opt_flags) /* OPT_LOCAL or 0 (both) */
Bram Moolenaar071d4272004-06-13 20:20:40 +00004348{
4349 int opt_idx;
4350 char_u *varp;
Bram Moolenaara93fa7e2006-04-17 22:14:47 +00004351 long_u flags;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004352
4353 opt_idx = findoption(name);
Bram Moolenaarfc1421e2006-04-20 22:17:20 +00004354 if (opt_idx < 0)
Bram Moolenaare353c402017-02-04 19:49:16 +01004355 {
4356 int key;
4357
4358 if (STRLEN(name) == 4 && name[0] == 't' && name[1] == '_'
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02004359 && (key = find_key_option(name, FALSE)) != 0)
Bram Moolenaare353c402017-02-04 19:49:16 +01004360 {
4361 char_u key_name[2];
4362
4363 if (key < 0)
4364 {
4365 key_name[0] = KEY2TERMCAP0(key);
4366 key_name[1] = KEY2TERMCAP1(key);
4367 }
4368 else
4369 {
4370 key_name[0] = KS_KEY;
4371 key_name[1] = (key & 0xff);
4372 }
4373 add_termcode(key_name, string, FALSE);
4374 if (full_screen)
4375 ttest(FALSE);
4376 redraw_all_later(CLEAR);
4377 return NULL;
4378 }
4379
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004380 semsg(_("E355: Unknown option: %s"), name);
Bram Moolenaare353c402017-02-04 19:49:16 +01004381 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004382 else
4383 {
4384 flags = options[opt_idx].flags;
4385#ifdef HAVE_SANDBOX
4386 /* Disallow changing some options in the sandbox */
4387 if (sandbox > 0 && (flags & P_SECURE))
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00004388 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004389 emsg(_(e_sandbox));
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004390 return NULL;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00004391 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004392#endif
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00004393 if (flags & P_STRING)
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004394 return set_string_option(opt_idx, string, opt_flags);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004395 else
4396 {
Bram Moolenaarb3163762008-07-08 15:15:08 +00004397 varp = get_varp_scope(&(options[opt_idx]), opt_flags);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004398 if (varp != NULL) /* hidden option is not changed */
4399 {
Bram Moolenaar96bb6212007-06-19 18:52:53 +00004400 if (number == 0 && string != NULL)
4401 {
Bram Moolenaarfe86f2d2008-11-28 20:29:07 +00004402 int idx;
Bram Moolenaar96bb6212007-06-19 18:52:53 +00004403
4404 /* Either we are given a string or we are setting option
4405 * to zero. */
Bram Moolenaarfe86f2d2008-11-28 20:29:07 +00004406 for (idx = 0; string[idx] == '0'; ++idx)
Bram Moolenaar96bb6212007-06-19 18:52:53 +00004407 ;
Bram Moolenaarfe86f2d2008-11-28 20:29:07 +00004408 if (string[idx] != NUL || idx == 0)
Bram Moolenaar96bb6212007-06-19 18:52:53 +00004409 {
4410 /* There's another character after zeros or the string
4411 * is empty. In both cases, we are trying to set a
4412 * num option using a string. */
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004413 semsg(_("E521: Number required: &%s = '%s'"),
Bram Moolenaar96bb6212007-06-19 18:52:53 +00004414 name, string);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004415 return NULL; /* do nothing as we hit an error */
Bram Moolenaar96bb6212007-06-19 18:52:53 +00004416
4417 }
4418 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004419 if (flags & P_NUM)
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004420 return set_num_option(opt_idx, varp, number,
Bram Moolenaar555b2802005-05-19 21:08:39 +00004421 NULL, 0, opt_flags);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004422 else
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004423 return set_bool_option(opt_idx, varp, (int)number,
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00004424 opt_flags);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004425 }
4426 }
4427 }
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004428 return NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004429}
4430
4431/*
4432 * Get the terminal code for a terminal option.
4433 * Returns NULL when not found.
4434 */
4435 char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01004436get_term_code(char_u *tname)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004437{
4438 int opt_idx;
4439 char_u *varp;
4440
4441 if (tname[0] != 't' || tname[1] != '_' ||
4442 tname[2] == NUL || tname[3] == NUL)
4443 return NULL;
4444 if ((opt_idx = findoption(tname)) >= 0)
4445 {
4446 varp = get_varp(&(options[opt_idx]));
4447 if (varp != NULL)
4448 varp = *(char_u **)(varp);
4449 return varp;
4450 }
4451 return find_termcode(tname + 2);
4452}
4453
4454 char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01004455get_highlight_default(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004456{
4457 int i;
4458
4459 i = findoption((char_u *)"hl");
4460 if (i >= 0)
4461 return options[i].def_val[VI_DEFAULT];
4462 return (char_u *)NULL;
4463}
4464
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00004465 char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01004466get_encoding_default(void)
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00004467{
4468 int i;
4469
4470 i = findoption((char_u *)"enc");
4471 if (i >= 0)
4472 return options[i].def_val[VI_DEFAULT];
4473 return (char_u *)NULL;
4474}
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00004475
Bram Moolenaar071d4272004-06-13 20:20:40 +00004476/*
4477 * Translate a string like "t_xx", "<t_xx>" or "<S-Tab>" to a key number.
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02004478 * When "has_lt" is true there is a '<' before "*arg_arg".
4479 * Returns 0 when the key is not recognized.
Bram Moolenaar071d4272004-06-13 20:20:40 +00004480 */
4481 static int
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02004482find_key_option(char_u *arg_arg, int has_lt)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004483{
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02004484 int key = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004485 int modifiers;
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02004486 char_u *arg = arg_arg;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004487
4488 /*
4489 * Don't use get_special_key_code() for t_xx, we don't want it to call
4490 * add_termcap_entry().
4491 */
4492 if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
4493 key = TERMCAP2KEY(arg[2], arg[3]);
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02004494 else if (has_lt)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004495 {
4496 --arg; /* put arg at the '<' */
4497 modifiers = 0;
Bram Moolenaar35a4cfa2016-08-14 16:07:48 +02004498 key = find_special_key(&arg, &modifiers, TRUE, TRUE, FALSE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004499 if (modifiers) /* can't handle modifiers here */
4500 key = 0;
4501 }
4502 return key;
4503}
4504
4505/*
4506 * if 'all' == 0: show changed options
4507 * if 'all' == 1: show all normal options
4508 * if 'all' == 2: show all terminal options
4509 */
4510 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01004511showoptions(
4512 int all,
4513 int opt_flags) /* OPT_LOCAL and/or OPT_GLOBAL */
Bram Moolenaar071d4272004-06-13 20:20:40 +00004514{
4515 struct vimoption *p;
4516 int col;
4517 int isterm;
4518 char_u *varp;
4519 struct vimoption **items;
4520 int item_count;
4521 int run;
4522 int row, rows;
4523 int cols;
4524 int i;
4525 int len;
4526
4527#define INC 20
4528#define GAP 3
4529
Bram Moolenaarc799fe22019-05-28 23:08:19 +02004530 items = ALLOC_MULT(struct vimoption *, PARAM_COUNT);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004531 if (items == NULL)
4532 return;
4533
4534 /* Highlight title */
4535 if (all == 2)
Bram Moolenaar32526b32019-01-19 17:43:09 +01004536 msg_puts_title(_("\n--- Terminal codes ---"));
Bram Moolenaar071d4272004-06-13 20:20:40 +00004537 else if (opt_flags & OPT_GLOBAL)
Bram Moolenaar32526b32019-01-19 17:43:09 +01004538 msg_puts_title(_("\n--- Global option values ---"));
Bram Moolenaar071d4272004-06-13 20:20:40 +00004539 else if (opt_flags & OPT_LOCAL)
Bram Moolenaar32526b32019-01-19 17:43:09 +01004540 msg_puts_title(_("\n--- Local option values ---"));
Bram Moolenaar071d4272004-06-13 20:20:40 +00004541 else
Bram Moolenaar32526b32019-01-19 17:43:09 +01004542 msg_puts_title(_("\n--- Options ---"));
Bram Moolenaar071d4272004-06-13 20:20:40 +00004543
4544 /*
4545 * do the loop two times:
4546 * 1. display the short items
4547 * 2. display the long items (only strings and numbers)
4548 */
4549 for (run = 1; run <= 2 && !got_int; ++run)
4550 {
4551 /*
4552 * collect the items in items[]
4553 */
4554 item_count = 0;
4555 for (p = &options[0]; p->fullname != NULL; p++)
4556 {
Bram Moolenaarf86db782018-10-25 13:31:37 +02004557 // apply :filter /pat/
4558 if (message_filtered((char_u *) p->fullname))
4559 continue;
4560
Bram Moolenaar071d4272004-06-13 20:20:40 +00004561 varp = NULL;
4562 isterm = istermoption(p);
4563 if (opt_flags != 0)
4564 {
4565 if (p->indir != PV_NONE && !isterm)
4566 varp = get_varp_scope(p, opt_flags);
4567 }
4568 else
4569 varp = get_varp(p);
4570 if (varp != NULL
4571 && ((all == 2 && isterm)
4572 || (all == 1 && !isterm)
Bram Moolenaarcacc6a52019-05-30 15:22:43 +02004573 || (all == 0 && !optval_default(p, varp, p_cp))))
Bram Moolenaar071d4272004-06-13 20:20:40 +00004574 {
4575 if (p->flags & P_BOOL)
4576 len = 1; /* a toggle option fits always */
4577 else
4578 {
4579 option_value2string(p, opt_flags);
4580 len = (int)STRLEN(p->fullname) + vim_strsize(NameBuff) + 1;
4581 }
4582 if ((len <= INC - GAP && run == 1) ||
4583 (len > INC - GAP && run == 2))
4584 items[item_count++] = p;
4585 }
4586 }
4587
4588 /*
4589 * display the items
4590 */
4591 if (run == 1)
4592 {
4593 cols = (Columns + GAP - 3) / INC;
4594 if (cols == 0)
4595 cols = 1;
4596 rows = (item_count + cols - 1) / cols;
4597 }
4598 else /* run == 2 */
4599 rows = item_count;
4600 for (row = 0; row < rows && !got_int; ++row)
4601 {
4602 msg_putchar('\n'); /* go to next line */
4603 if (got_int) /* 'q' typed in more */
4604 break;
4605 col = 0;
4606 for (i = row; i < item_count; i += rows)
4607 {
4608 msg_col = col; /* make columns */
4609 showoneopt(items[i], opt_flags);
4610 col += INC;
4611 }
4612 out_flush();
4613 ui_breakcheck();
4614 }
4615 }
4616 vim_free(items);
4617}
4618
4619/*
4620 * Return TRUE if option "p" has its default value.
4621 */
4622 static int
Bram Moolenaarcacc6a52019-05-30 15:22:43 +02004623optval_default(struct vimoption *p, char_u *varp, int compatible)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004624{
4625 int dvi;
4626
4627 if (varp == NULL)
4628 return TRUE; /* hidden option is always at default */
Bram Moolenaarcacc6a52019-05-30 15:22:43 +02004629 dvi = ((p->flags & P_VI_DEF) || compatible) ? VI_DEFAULT : VIM_DEFAULT;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004630 if (p->flags & P_NUM)
Bram Moolenaareb3593b2006-04-22 22:33:57 +00004631 return (*(long *)varp == (long)(long_i)p->def_val[dvi]);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004632 if (p->flags & P_BOOL)
Bram Moolenaareb3593b2006-04-22 22:33:57 +00004633 /* the cast to long is required for Manx C, long_i is
4634 * needed for MSVC */
4635 return (*(int *)varp == (int)(long)(long_i)p->def_val[dvi]);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004636 /* P_STRING */
4637 return (STRCMP(*(char_u **)varp, p->def_val[dvi]) == 0);
4638}
4639
4640/*
4641 * showoneopt: show the value of one option
4642 * must not be called with a hidden option!
4643 */
4644 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01004645showoneopt(
4646 struct vimoption *p,
4647 int opt_flags) /* OPT_LOCAL or OPT_GLOBAL */
Bram Moolenaar071d4272004-06-13 20:20:40 +00004648{
Bram Moolenaar26a60b42005-02-22 08:49:11 +00004649 char_u *varp;
4650 int save_silent = silent_mode;
4651
4652 silent_mode = FALSE;
4653 info_message = TRUE; /* use mch_msg(), not mch_errmsg() */
Bram Moolenaar071d4272004-06-13 20:20:40 +00004654
4655 varp = get_varp_scope(p, opt_flags);
4656
4657 /* for 'modified' we also need to check if 'ff' or 'fenc' changed. */
4658 if ((p->flags & P_BOOL) && ((int *)varp == &curbuf->b_changed
4659 ? !curbufIsChanged() : !*(int *)varp))
Bram Moolenaar32526b32019-01-19 17:43:09 +01004660 msg_puts("no");
Bram Moolenaar071d4272004-06-13 20:20:40 +00004661 else if ((p->flags & P_BOOL) && *(int *)varp < 0)
Bram Moolenaar32526b32019-01-19 17:43:09 +01004662 msg_puts("--");
Bram Moolenaar071d4272004-06-13 20:20:40 +00004663 else
Bram Moolenaar32526b32019-01-19 17:43:09 +01004664 msg_puts(" ");
4665 msg_puts(p->fullname);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004666 if (!(p->flags & P_BOOL))
4667 {
4668 msg_putchar('=');
4669 /* put value string in NameBuff */
4670 option_value2string(p, opt_flags);
4671 msg_outtrans(NameBuff);
4672 }
Bram Moolenaar26a60b42005-02-22 08:49:11 +00004673
4674 silent_mode = save_silent;
4675 info_message = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004676}
4677
4678/*
4679 * Write modified options as ":set" commands to a file.
4680 *
4681 * There are three values for "opt_flags":
4682 * OPT_GLOBAL: Write global option values and fresh values of
4683 * buffer-local options (used for start of a session
4684 * file).
4685 * OPT_GLOBAL + OPT_LOCAL: Idem, add fresh values of window-local options for
4686 * curwin (used for a vimrc file).
4687 * OPT_LOCAL: Write buffer-local option values for curbuf, fresh
4688 * and local values for window-local options of
4689 * curwin. Local values are also written when at the
4690 * default value, because a modeline or autocommand
4691 * may have set them when doing ":edit file" and the
4692 * user has set them back at the default or fresh
4693 * value.
4694 * When "local_only" is TRUE, don't write fresh
4695 * values, only local values (for ":mkview").
4696 * (fresh value = value used for a new buffer or window for a local option).
4697 *
4698 * Return FAIL on error, OK otherwise.
4699 */
4700 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01004701makeset(FILE *fd, int opt_flags, int local_only)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004702{
4703 struct vimoption *p;
4704 char_u *varp; /* currently used value */
4705 char_u *varp_fresh; /* local value */
4706 char_u *varp_local = NULL; /* fresh value */
4707 char *cmd;
4708 int round;
Bram Moolenaar7fd16022007-09-06 14:35:35 +00004709 int pri;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004710
4711 /*
4712 * The options that don't have a default (terminal name, columns, lines)
4713 * are never written. Terminal options are also not written.
Bram Moolenaar7fd16022007-09-06 14:35:35 +00004714 * Do the loop over "options[]" twice: once for options with the
4715 * P_PRI_MKRC flag and once without.
Bram Moolenaar071d4272004-06-13 20:20:40 +00004716 */
Bram Moolenaar7fd16022007-09-06 14:35:35 +00004717 for (pri = 1; pri >= 0; --pri)
4718 {
4719 for (p = &options[0]; !istermoption(p); p++)
4720 if (!(p->flags & P_NO_MKRC)
4721 && !istermoption(p)
4722 && ((pri == 1) == ((p->flags & P_PRI_MKRC) != 0)))
Bram Moolenaar071d4272004-06-13 20:20:40 +00004723 {
4724 /* skip global option when only doing locals */
4725 if (p->indir == PV_NONE && !(opt_flags & OPT_GLOBAL))
4726 continue;
4727
4728 /* Do not store options like 'bufhidden' and 'syntax' in a vimrc
4729 * file, they are always buffer-specific. */
4730 if ((opt_flags & OPT_GLOBAL) && (p->flags & P_NOGLOB))
4731 continue;
4732
4733 /* Global values are only written when not at the default value. */
4734 varp = get_varp_scope(p, opt_flags);
Bram Moolenaarcacc6a52019-05-30 15:22:43 +02004735 if ((opt_flags & OPT_GLOBAL) && optval_default(p, varp, p_cp))
Bram Moolenaar071d4272004-06-13 20:20:40 +00004736 continue;
4737
4738 round = 2;
4739 if (p->indir != PV_NONE)
4740 {
4741 if (p->var == VAR_WIN)
4742 {
4743 /* skip window-local option when only doing globals */
4744 if (!(opt_flags & OPT_LOCAL))
4745 continue;
4746 /* When fresh value of window-local option is not at the
4747 * default, need to write it too. */
4748 if (!(opt_flags & OPT_GLOBAL) && !local_only)
4749 {
4750 varp_fresh = get_varp_scope(p, OPT_GLOBAL);
Bram Moolenaarcacc6a52019-05-30 15:22:43 +02004751 if (!optval_default(p, varp_fresh, p_cp))
Bram Moolenaar071d4272004-06-13 20:20:40 +00004752 {
4753 round = 1;
4754 varp_local = varp;
4755 varp = varp_fresh;
4756 }
4757 }
4758 }
4759 }
4760
4761 /* Round 1: fresh value for window-local options.
4762 * Round 2: other values */
4763 for ( ; round <= 2; varp = varp_local, ++round)
4764 {
4765 if (round == 1 || (opt_flags & OPT_GLOBAL))
4766 cmd = "set";
4767 else
4768 cmd = "setlocal";
4769
4770 if (p->flags & P_BOOL)
4771 {
4772 if (put_setbool(fd, cmd, p->fullname, *(int *)varp) == FAIL)
4773 return FAIL;
4774 }
4775 else if (p->flags & P_NUM)
4776 {
4777 if (put_setnum(fd, cmd, p->fullname, (long *)varp) == FAIL)
4778 return FAIL;
4779 }
4780 else /* P_STRING */
4781 {
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00004782 int do_endif = FALSE;
4783
Bram Moolenaar071d4272004-06-13 20:20:40 +00004784 /* Don't set 'syntax' and 'filetype' again if the value is
4785 * already right, avoids reloading the syntax file. */
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00004786 if (
Bram Moolenaarf2bd8ef2018-03-04 18:08:14 +01004787#if defined(FEAT_SYN_HL)
4788 p->indir == PV_SYN ||
4789#endif
4790 p->indir == PV_FT)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004791 {
4792 if (fprintf(fd, "if &%s != '%s'", p->fullname,
4793 *(char_u **)(varp)) < 0
4794 || put_eol(fd) < 0)
4795 return FAIL;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00004796 do_endif = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004797 }
4798 if (put_setstring(fd, cmd, p->fullname, (char_u **)varp,
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004799 p->flags) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004800 return FAIL;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00004801 if (do_endif)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004802 {
4803 if (put_line(fd, "endif") == FAIL)
4804 return FAIL;
4805 }
4806 }
4807 }
4808 }
Bram Moolenaar7fd16022007-09-06 14:35:35 +00004809 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004810 return OK;
4811}
4812
4813#if defined(FEAT_FOLDING) || defined(PROTO)
4814/*
4815 * Generate set commands for the local fold options only. Used when
4816 * 'sessionoptions' or 'viewoptions' contains "folds" but not "options".
4817 */
4818 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01004819makefoldset(FILE *fd)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004820{
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004821 if (put_setstring(fd, "setlocal", "fdm", &curwin->w_p_fdm, 0) == FAIL
Bram Moolenaar071d4272004-06-13 20:20:40 +00004822# ifdef FEAT_EVAL
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004823 || put_setstring(fd, "setlocal", "fde", &curwin->w_p_fde, 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004824 == FAIL
4825# endif
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004826 || put_setstring(fd, "setlocal", "fmr", &curwin->w_p_fmr, 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004827 == FAIL
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004828 || put_setstring(fd, "setlocal", "fdi", &curwin->w_p_fdi, 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004829 == FAIL
4830 || put_setnum(fd, "setlocal", "fdl", &curwin->w_p_fdl) == FAIL
4831 || put_setnum(fd, "setlocal", "fml", &curwin->w_p_fml) == FAIL
4832 || put_setnum(fd, "setlocal", "fdn", &curwin->w_p_fdn) == FAIL
4833 || put_setbool(fd, "setlocal", "fen", curwin->w_p_fen) == FAIL
4834 )
4835 return FAIL;
4836
4837 return OK;
4838}
4839#endif
4840
4841 static int
Bram Moolenaar9b578142016-01-30 19:39:49 +01004842put_setstring(
4843 FILE *fd,
4844 char *cmd,
4845 char *name,
4846 char_u **valuep,
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004847 long_u flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004848{
4849 char_u *s;
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004850 char_u *buf = NULL;
4851 char_u *part = NULL;
4852 char_u *p;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004853
4854 if (fprintf(fd, "%s %s=", cmd, name) < 0)
4855 return FAIL;
4856 if (*valuep != NULL)
4857 {
4858 /* Output 'pastetoggle' as key names. For other
4859 * options some characters have to be escaped with
4860 * CTRL-V or backslash */
4861 if (valuep == &p_pt)
4862 {
4863 s = *valuep;
4864 while (*s != NUL)
Bram Moolenaar7d96acd2008-06-09 15:07:54 +00004865 if (put_escstr(fd, str2special(&s, FALSE), 2) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004866 return FAIL;
4867 }
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004868 // expand the option value, replace $HOME by ~
4869 else if ((flags & P_EXPAND) != 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004870 {
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004871 int size = (int)STRLEN(*valuep) + 1;
4872
4873 // replace home directory in the whole option value into "buf"
4874 buf = alloc(size);
Bram Moolenaarf8441472011-04-28 17:24:58 +02004875 if (buf == NULL)
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004876 goto fail;
4877 home_replace(NULL, *valuep, buf, size, FALSE);
4878
4879 // If the option value is longer than MAXPATHL, we need to append
4880 // earch comma separated part of the option separately, so that it
4881 // can be expanded when read back.
4882 if (size >= MAXPATHL && (flags & P_COMMA) != 0
4883 && vim_strchr(*valuep, ',') != NULL)
4884 {
4885 part = alloc(size);
4886 if (part == NULL)
4887 goto fail;
4888
4889 // write line break to clear the option, e.g. ':set rtp='
4890 if (put_eol(fd) == FAIL)
4891 goto fail;
4892
4893 p = buf;
4894 while (*p != NUL)
4895 {
4896 // for each comma separated option part, append value to
4897 // the option, :set rtp+=value
4898 if (fprintf(fd, "%s %s+=", cmd, name) < 0)
4899 goto fail;
4900 (void)copy_option_part(&p, part, size, ",");
4901 if (put_escstr(fd, part, 2) == FAIL || put_eol(fd) == FAIL)
4902 goto fail;
4903 }
4904 vim_free(buf);
4905 vim_free(part);
4906 return OK;
4907 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004908 if (put_escstr(fd, buf, 2) == FAIL)
Bram Moolenaarf8441472011-04-28 17:24:58 +02004909 {
4910 vim_free(buf);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004911 return FAIL;
Bram Moolenaarf8441472011-04-28 17:24:58 +02004912 }
4913 vim_free(buf);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004914 }
4915 else if (put_escstr(fd, *valuep, 2) == FAIL)
4916 return FAIL;
4917 }
4918 if (put_eol(fd) < 0)
4919 return FAIL;
4920 return OK;
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004921fail:
4922 vim_free(buf);
4923 vim_free(part);
4924 return FAIL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004925}
4926
4927 static int
Bram Moolenaar9b578142016-01-30 19:39:49 +01004928put_setnum(
4929 FILE *fd,
4930 char *cmd,
4931 char *name,
4932 long *valuep)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004933{
4934 long wc;
4935
4936 if (fprintf(fd, "%s %s=", cmd, name) < 0)
4937 return FAIL;
4938 if (wc_use_keyname((char_u *)valuep, &wc))
4939 {
4940 /* print 'wildchar' and 'wildcharm' as a key name */
4941 if (fputs((char *)get_special_key_name((int)wc, 0), fd) < 0)
4942 return FAIL;
4943 }
4944 else if (fprintf(fd, "%ld", *valuep) < 0)
4945 return FAIL;
4946 if (put_eol(fd) < 0)
4947 return FAIL;
4948 return OK;
4949}
4950
4951 static int
Bram Moolenaar9b578142016-01-30 19:39:49 +01004952put_setbool(
4953 FILE *fd,
4954 char *cmd,
4955 char *name,
4956 int value)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004957{
Bram Moolenaar893de922007-10-02 18:40:57 +00004958 if (value < 0) /* global/local option using global value */
4959 return OK;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004960 if (fprintf(fd, "%s %s%s", cmd, value ? "" : "no", name) < 0
4961 || put_eol(fd) < 0)
4962 return FAIL;
4963 return OK;
4964}
4965
4966/*
4967 * Clear all the terminal options.
4968 * If the option has been allocated, free the memory.
4969 * Terminal options are never hidden or indirect.
4970 */
4971 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01004972clear_termoptions(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004973{
Bram Moolenaar071d4272004-06-13 20:20:40 +00004974 /*
4975 * Reset a few things before clearing the old options. This may cause
4976 * outputting a few things that the terminal doesn't understand, but the
4977 * screen will be cleared later, so this is OK.
4978 */
4979#ifdef FEAT_MOUSE_TTY
4980 mch_setmouse(FALSE); /* switch mouse off */
4981#endif
4982#ifdef FEAT_TITLE
Bram Moolenaar40385db2018-08-07 22:31:44 +02004983 mch_restore_title(SAVE_RESTORE_BOTH); /* restore window titles */
Bram Moolenaar071d4272004-06-13 20:20:40 +00004984#endif
4985#if defined(FEAT_XCLIPBOARD) && defined(FEAT_GUI)
4986 /* When starting the GUI close the display opened for the clipboard.
4987 * After restoring the title, because that will need the display. */
4988 if (gui.starting)
4989 clear_xterm_clip();
4990#endif
Bram Moolenaarcea912a2016-10-12 14:20:24 +02004991 stoptermcap(); /* stop termcap mode */
Bram Moolenaar071d4272004-06-13 20:20:40 +00004992
Bram Moolenaarf461c8e2005-06-25 23:04:51 +00004993 free_termoptions();
4994}
4995
4996 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01004997free_termoptions(void)
Bram Moolenaarf461c8e2005-06-25 23:04:51 +00004998{
4999 struct vimoption *p;
5000
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02005001 for (p = options; p->fullname != NULL; p++)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005002 if (istermoption(p))
5003 {
5004 if (p->flags & P_ALLOCED)
5005 free_string_option(*(char_u **)(p->var));
5006 if (p->flags & P_DEF_ALLOCED)
5007 free_string_option(p->def_val[VI_DEFAULT]);
5008 *(char_u **)(p->var) = empty_option;
5009 p->def_val[VI_DEFAULT] = empty_option;
5010 p->flags &= ~(P_ALLOCED|P_DEF_ALLOCED);
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02005011#ifdef FEAT_EVAL
5012 // remember where the option was cleared
5013 set_option_sctx_idx((int)(p - options), OPT_GLOBAL, current_sctx);
5014#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005015 }
5016 clear_termcodes();
5017}
5018
5019/*
Bram Moolenaar363cb672009-07-22 12:28:17 +00005020 * Free the string for one term option, if it was allocated.
5021 * Set the string to empty_option and clear allocated flag.
5022 * "var" points to the option value.
5023 */
5024 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005025free_one_termoption(char_u *var)
Bram Moolenaar363cb672009-07-22 12:28:17 +00005026{
5027 struct vimoption *p;
5028
5029 for (p = &options[0]; p->fullname != NULL; p++)
5030 if (p->var == var)
5031 {
5032 if (p->flags & P_ALLOCED)
5033 free_string_option(*(char_u **)(p->var));
5034 *(char_u **)(p->var) = empty_option;
5035 p->flags &= ~P_ALLOCED;
5036 break;
5037 }
5038}
5039
5040/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005041 * Set the terminal option defaults to the current value.
5042 * Used after setting the terminal name.
5043 */
5044 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005045set_term_defaults(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005046{
5047 struct vimoption *p;
5048
5049 for (p = &options[0]; p->fullname != NULL; p++)
5050 {
5051 if (istermoption(p) && p->def_val[VI_DEFAULT] != *(char_u **)(p->var))
5052 {
5053 if (p->flags & P_DEF_ALLOCED)
5054 {
5055 free_string_option(p->def_val[VI_DEFAULT]);
5056 p->flags &= ~P_DEF_ALLOCED;
5057 }
5058 p->def_val[VI_DEFAULT] = *(char_u **)(p->var);
5059 if (p->flags & P_ALLOCED)
5060 {
5061 p->flags |= P_DEF_ALLOCED;
5062 p->flags &= ~P_ALLOCED; /* don't free the value now */
5063 }
5064 }
5065 }
5066}
5067
5068/*
5069 * return TRUE if 'p' starts with 't_'
5070 */
5071 static int
Bram Moolenaar9b578142016-01-30 19:39:49 +01005072istermoption(struct vimoption *p)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005073{
5074 return (p->fullname[0] == 't' && p->fullname[1] == '_');
5075}
5076
Bram Moolenaardac13472019-09-16 21:06:21 +02005077/*
5078 * Returns TRUE if the option at 'opt_idx' starts with 't_'
5079 */
5080 int
5081istermoption_idx(int opt_idx)
5082{
5083 return istermoption(&options[opt_idx]);
5084}
5085
Bram Moolenaar113e1072019-01-20 15:30:40 +01005086#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005087/*
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005088 * Unset local option value, similar to ":set opt<".
5089 */
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005090 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005091unset_global_local_option(char_u *name, void *from)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005092{
5093 struct vimoption *p;
5094 int opt_idx;
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005095 buf_T *buf = (buf_T *)from;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005096
5097 opt_idx = findoption(name);
Bram Moolenaarbd8539a2015-08-11 18:53:03 +02005098 if (opt_idx < 0)
5099 return;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005100 p = &(options[opt_idx]);
5101
5102 switch ((int)p->indir)
5103 {
5104 /* global option with local value: use local value if it's been set */
5105 case PV_EP:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005106 clear_string_option(&buf->b_p_ep);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005107 break;
5108 case PV_KP:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005109 clear_string_option(&buf->b_p_kp);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005110 break;
5111 case PV_PATH:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005112 clear_string_option(&buf->b_p_path);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005113 break;
5114 case PV_AR:
5115 buf->b_p_ar = -1;
5116 break;
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02005117 case PV_BKC:
5118 clear_string_option(&buf->b_p_bkc);
5119 buf->b_bkc_flags = 0;
5120 break;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005121 case PV_TAGS:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005122 clear_string_option(&buf->b_p_tags);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005123 break;
Bram Moolenaar0f6562e2015-11-24 18:48:14 +01005124 case PV_TC:
5125 clear_string_option(&buf->b_p_tc);
5126 buf->b_tc_flags = 0;
5127 break;
Bram Moolenaar375e3392019-01-31 18:26:10 +01005128 case PV_SISO:
5129 curwin->w_p_siso = -1;
5130 break;
5131 case PV_SO:
5132 curwin->w_p_so = -1;
5133 break;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005134#ifdef FEAT_FIND_ID
5135 case PV_DEF:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005136 clear_string_option(&buf->b_p_def);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005137 break;
5138 case PV_INC:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005139 clear_string_option(&buf->b_p_inc);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005140 break;
5141#endif
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005142 case PV_DICT:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005143 clear_string_option(&buf->b_p_dict);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005144 break;
5145 case PV_TSR:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005146 clear_string_option(&buf->b_p_tsr);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005147 break;
Bram Moolenaar9be7c042017-01-14 14:28:30 +01005148 case PV_FP:
5149 clear_string_option(&buf->b_p_fp);
5150 break;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005151#ifdef FEAT_QUICKFIX
5152 case PV_EFM:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005153 clear_string_option(&buf->b_p_efm);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005154 break;
5155 case PV_GP:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005156 clear_string_option(&buf->b_p_gp);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005157 break;
5158 case PV_MP:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005159 clear_string_option(&buf->b_p_mp);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005160 break;
5161#endif
5162#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
5163 case PV_BEXPR:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005164 clear_string_option(&buf->b_p_bexpr);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005165 break;
5166#endif
5167#if defined(FEAT_CRYPT)
5168 case PV_CM:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005169 clear_string_option(&buf->b_p_cm);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005170 break;
5171#endif
5172#ifdef FEAT_STL_OPT
5173 case PV_STL:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005174 clear_string_option(&((win_T *)from)->w_p_stl);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005175 break;
5176#endif
Bram Moolenaarf5a2fd82013-11-06 05:26:15 +01005177 case PV_UL:
5178 buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
5179 break;
Bram Moolenaaraf6c1312014-03-12 18:55:58 +01005180#ifdef FEAT_LISP
5181 case PV_LW:
5182 clear_string_option(&buf->b_p_lw);
5183 break;
5184#endif
Bram Moolenaar2c7292d2017-03-05 17:43:31 +01005185 case PV_MENC:
5186 clear_string_option(&buf->b_p_menc);
5187 break;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005188 }
5189}
Bram Moolenaar113e1072019-01-20 15:30:40 +01005190#endif
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005191
5192/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005193 * Get pointer to option variable, depending on local or global scope.
5194 */
5195 static char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01005196get_varp_scope(struct vimoption *p, int opt_flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005197{
5198 if ((opt_flags & OPT_GLOBAL) && p->indir != PV_NONE)
5199 {
5200 if (p->var == VAR_WIN)
5201 return (char_u *)GLOBAL_WO(get_varp(p));
5202 return p->var;
5203 }
Bram Moolenaara23ccb82006-02-27 00:08:02 +00005204 if ((opt_flags & OPT_LOCAL) && ((int)p->indir & PV_BOTH))
Bram Moolenaar071d4272004-06-13 20:20:40 +00005205 {
5206 switch ((int)p->indir)
5207 {
Bram Moolenaar9be7c042017-01-14 14:28:30 +01005208 case PV_FP: return (char_u *)&(curbuf->b_p_fp);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005209#ifdef FEAT_QUICKFIX
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005210 case PV_EFM: return (char_u *)&(curbuf->b_p_efm);
5211 case PV_GP: return (char_u *)&(curbuf->b_p_gp);
5212 case PV_MP: return (char_u *)&(curbuf->b_p_mp);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005213#endif
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005214 case PV_EP: return (char_u *)&(curbuf->b_p_ep);
5215 case PV_KP: return (char_u *)&(curbuf->b_p_kp);
5216 case PV_PATH: return (char_u *)&(curbuf->b_p_path);
Bram Moolenaara23ccb82006-02-27 00:08:02 +00005217 case PV_AR: return (char_u *)&(curbuf->b_p_ar);
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005218 case PV_TAGS: return (char_u *)&(curbuf->b_p_tags);
Bram Moolenaar0f6562e2015-11-24 18:48:14 +01005219 case PV_TC: return (char_u *)&(curbuf->b_p_tc);
Bram Moolenaar375e3392019-01-31 18:26:10 +01005220 case PV_SISO: return (char_u *)&(curwin->w_p_siso);
5221 case PV_SO: return (char_u *)&(curwin->w_p_so);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005222#ifdef FEAT_FIND_ID
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005223 case PV_DEF: return (char_u *)&(curbuf->b_p_def);
5224 case PV_INC: return (char_u *)&(curbuf->b_p_inc);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005225#endif
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005226 case PV_DICT: return (char_u *)&(curbuf->b_p_dict);
5227 case PV_TSR: return (char_u *)&(curbuf->b_p_tsr);
Bram Moolenaar9b2200a2006-03-20 21:55:45 +00005228#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
5229 case PV_BEXPR: return (char_u *)&(curbuf->b_p_bexpr);
5230#endif
Bram Moolenaar49771f42010-07-20 17:32:38 +02005231#if defined(FEAT_CRYPT)
5232 case PV_CM: return (char_u *)&(curbuf->b_p_cm);
5233#endif
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005234#ifdef FEAT_STL_OPT
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005235 case PV_STL: return (char_u *)&(curwin->w_p_stl);
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005236#endif
Bram Moolenaarf5a2fd82013-11-06 05:26:15 +01005237 case PV_UL: return (char_u *)&(curbuf->b_p_ul);
Bram Moolenaaraf6c1312014-03-12 18:55:58 +01005238#ifdef FEAT_LISP
5239 case PV_LW: return (char_u *)&(curbuf->b_p_lw);
5240#endif
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02005241 case PV_BKC: return (char_u *)&(curbuf->b_p_bkc);
Bram Moolenaar2c7292d2017-03-05 17:43:31 +01005242 case PV_MENC: return (char_u *)&(curbuf->b_p_menc);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005243 }
5244 return NULL; /* "cannot happen" */
5245 }
5246 return get_varp(p);
5247}
5248
5249/*
Bram Moolenaardac13472019-09-16 21:06:21 +02005250 * Get pointer to option variable at 'opt_idx', depending on local or global
5251 * scope.
5252 */
5253 char_u *
5254get_option_varp_scope(int opt_idx, int opt_flags)
5255{
5256 return get_varp_scope(&(options[opt_idx]), opt_flags);
5257}
5258
5259/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005260 * Get pointer to option variable.
5261 */
5262 static char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01005263get_varp(struct vimoption *p)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005264{
5265 /* hidden option, always return NULL */
5266 if (p->var == NULL)
5267 return NULL;
5268
5269 switch ((int)p->indir)
5270 {
5271 case PV_NONE: return p->var;
5272
5273 /* global option with local value: use local value if it's been set */
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005274 case PV_EP: return *curbuf->b_p_ep != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005275 ? (char_u *)&curbuf->b_p_ep : p->var;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005276 case PV_KP: return *curbuf->b_p_kp != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005277 ? (char_u *)&curbuf->b_p_kp : p->var;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005278 case PV_PATH: return *curbuf->b_p_path != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005279 ? (char_u *)&(curbuf->b_p_path) : p->var;
Bram Moolenaara23ccb82006-02-27 00:08:02 +00005280 case PV_AR: return curbuf->b_p_ar >= 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00005281 ? (char_u *)&(curbuf->b_p_ar) : p->var;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005282 case PV_TAGS: return *curbuf->b_p_tags != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005283 ? (char_u *)&(curbuf->b_p_tags) : p->var;
Bram Moolenaar0f6562e2015-11-24 18:48:14 +01005284 case PV_TC: return *curbuf->b_p_tc != NUL
5285 ? (char_u *)&(curbuf->b_p_tc) : p->var;
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02005286 case PV_BKC: return *curbuf->b_p_bkc != NUL
5287 ? (char_u *)&(curbuf->b_p_bkc) : p->var;
Bram Moolenaar375e3392019-01-31 18:26:10 +01005288 case PV_SISO: return curwin->w_p_siso >= 0
5289 ? (char_u *)&(curwin->w_p_siso) : p->var;
5290 case PV_SO: return curwin->w_p_so >= 0
5291 ? (char_u *)&(curwin->w_p_so) : p->var;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005292#ifdef FEAT_FIND_ID
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005293 case PV_DEF: return *curbuf->b_p_def != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005294 ? (char_u *)&(curbuf->b_p_def) : p->var;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005295 case PV_INC: return *curbuf->b_p_inc != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005296 ? (char_u *)&(curbuf->b_p_inc) : p->var;
5297#endif
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005298 case PV_DICT: return *curbuf->b_p_dict != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005299 ? (char_u *)&(curbuf->b_p_dict) : p->var;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005300 case PV_TSR: return *curbuf->b_p_tsr != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005301 ? (char_u *)&(curbuf->b_p_tsr) : p->var;
Bram Moolenaar9be7c042017-01-14 14:28:30 +01005302 case PV_FP: return *curbuf->b_p_fp != NUL
5303 ? (char_u *)&(curbuf->b_p_fp) : p->var;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005304#ifdef FEAT_QUICKFIX
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005305 case PV_EFM: return *curbuf->b_p_efm != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005306 ? (char_u *)&(curbuf->b_p_efm) : p->var;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005307 case PV_GP: return *curbuf->b_p_gp != NUL
5308 ? (char_u *)&(curbuf->b_p_gp) : p->var;
5309 case PV_MP: return *curbuf->b_p_mp != NUL
5310 ? (char_u *)&(curbuf->b_p_mp) : p->var;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005311#endif
Bram Moolenaar9b2200a2006-03-20 21:55:45 +00005312#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
5313 case PV_BEXPR: return *curbuf->b_p_bexpr != NUL
5314 ? (char_u *)&(curbuf->b_p_bexpr) : p->var;
5315#endif
Bram Moolenaar49771f42010-07-20 17:32:38 +02005316#if defined(FEAT_CRYPT)
5317 case PV_CM: return *curbuf->b_p_cm != NUL
5318 ? (char_u *)&(curbuf->b_p_cm) : p->var;
5319#endif
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005320#ifdef FEAT_STL_OPT
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005321 case PV_STL: return *curwin->w_p_stl != NUL
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005322 ? (char_u *)&(curwin->w_p_stl) : p->var;
5323#endif
Bram Moolenaarf5a2fd82013-11-06 05:26:15 +01005324 case PV_UL: return curbuf->b_p_ul != NO_LOCAL_UNDOLEVEL
5325 ? (char_u *)&(curbuf->b_p_ul) : p->var;
Bram Moolenaaraf6c1312014-03-12 18:55:58 +01005326#ifdef FEAT_LISP
5327 case PV_LW: return *curbuf->b_p_lw != NUL
5328 ? (char_u *)&(curbuf->b_p_lw) : p->var;
5329#endif
Bram Moolenaar2c7292d2017-03-05 17:43:31 +01005330 case PV_MENC: return *curbuf->b_p_menc != NUL
5331 ? (char_u *)&(curbuf->b_p_menc) : p->var;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005332#ifdef FEAT_ARABIC
5333 case PV_ARAB: return (char_u *)&(curwin->w_p_arab);
5334#endif
5335 case PV_LIST: return (char_u *)&(curwin->w_p_list);
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005336#ifdef FEAT_SPELL
Bram Moolenaar217ad922005-03-20 22:37:15 +00005337 case PV_SPELL: return (char_u *)&(curwin->w_p_spell);
5338#endif
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005339#ifdef FEAT_SYN_HL
5340 case PV_CUC: return (char_u *)&(curwin->w_p_cuc);
5341 case PV_CUL: return (char_u *)&(curwin->w_p_cul);
Bram Moolenaar410e98a2019-09-09 22:05:49 +02005342 case PV_CULOPT: return (char_u *)&(curwin->w_p_culopt);
Bram Moolenaar1a384422010-07-14 19:53:30 +02005343 case PV_CC: return (char_u *)&(curwin->w_p_cc);
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005344#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005345#ifdef FEAT_DIFF
5346 case PV_DIFF: return (char_u *)&(curwin->w_p_diff);
5347#endif
5348#ifdef FEAT_FOLDING
5349 case PV_FDC: return (char_u *)&(curwin->w_p_fdc);
5350 case PV_FEN: return (char_u *)&(curwin->w_p_fen);
5351 case PV_FDI: return (char_u *)&(curwin->w_p_fdi);
5352 case PV_FDL: return (char_u *)&(curwin->w_p_fdl);
5353 case PV_FDM: return (char_u *)&(curwin->w_p_fdm);
5354 case PV_FML: return (char_u *)&(curwin->w_p_fml);
5355 case PV_FDN: return (char_u *)&(curwin->w_p_fdn);
5356# ifdef FEAT_EVAL
5357 case PV_FDE: return (char_u *)&(curwin->w_p_fde);
5358 case PV_FDT: return (char_u *)&(curwin->w_p_fdt);
5359# endif
5360 case PV_FMR: return (char_u *)&(curwin->w_p_fmr);
5361#endif
5362 case PV_NU: return (char_u *)&(curwin->w_p_nu);
Bram Moolenaar64486672010-05-16 15:46:46 +02005363 case PV_RNU: return (char_u *)&(curwin->w_p_rnu);
Bram Moolenaar592e0a22004-07-03 16:05:59 +00005364#ifdef FEAT_LINEBREAK
5365 case PV_NUW: return (char_u *)&(curwin->w_p_nuw);
5366#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005367 case PV_WFH: return (char_u *)&(curwin->w_p_wfh);
Bram Moolenaar97b2ad32006-03-18 21:40:56 +00005368 case PV_WFW: return (char_u *)&(curwin->w_p_wfw);
Bram Moolenaar4033c552017-09-16 20:54:51 +02005369#if defined(FEAT_QUICKFIX)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005370 case PV_PVW: return (char_u *)&(curwin->w_p_pvw);
5371#endif
5372#ifdef FEAT_RIGHTLEFT
5373 case PV_RL: return (char_u *)&(curwin->w_p_rl);
5374 case PV_RLC: return (char_u *)&(curwin->w_p_rlc);
5375#endif
5376 case PV_SCROLL: return (char_u *)&(curwin->w_p_scr);
5377 case PV_WRAP: return (char_u *)&(curwin->w_p_wrap);
5378#ifdef FEAT_LINEBREAK
5379 case PV_LBR: return (char_u *)&(curwin->w_p_lbr);
Bram Moolenaar597a4222014-06-25 14:39:50 +02005380 case PV_BRI: return (char_u *)&(curwin->w_p_bri);
5381 case PV_BRIOPT: return (char_u *)&(curwin->w_p_briopt);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005382#endif
Bram Moolenaar4d784b22019-05-25 19:51:39 +02005383 case PV_WCR: return (char_u *)&(curwin->w_p_wcr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005384 case PV_SCBIND: return (char_u *)&(curwin->w_p_scb);
Bram Moolenaar860cae12010-06-05 23:22:07 +02005385 case PV_CRBIND: return (char_u *)&(curwin->w_p_crb);
Bram Moolenaar860cae12010-06-05 23:22:07 +02005386#ifdef FEAT_CONCEAL
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005387 case PV_COCU: return (char_u *)&(curwin->w_p_cocu);
5388 case PV_COLE: return (char_u *)&(curwin->w_p_cole);
5389#endif
5390#ifdef FEAT_TERMINAL
Bram Moolenaar6d150f72018-04-21 20:03:20 +02005391 case PV_TWK: return (char_u *)&(curwin->w_p_twk);
5392 case PV_TWS: return (char_u *)&(curwin->w_p_tws);
5393 case PV_TWSL: return (char_u *)&(curbuf->b_p_twsl);
Bram Moolenaar860cae12010-06-05 23:22:07 +02005394#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005395
5396 case PV_AI: return (char_u *)&(curbuf->b_p_ai);
5397 case PV_BIN: return (char_u *)&(curbuf->b_p_bin);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005398 case PV_BOMB: return (char_u *)&(curbuf->b_p_bomb);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005399 case PV_BH: return (char_u *)&(curbuf->b_p_bh);
5400 case PV_BT: return (char_u *)&(curbuf->b_p_bt);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005401 case PV_BL: return (char_u *)&(curbuf->b_p_bl);
5402 case PV_CI: return (char_u *)&(curbuf->b_p_ci);
5403#ifdef FEAT_CINDENT
5404 case PV_CIN: return (char_u *)&(curbuf->b_p_cin);
5405 case PV_CINK: return (char_u *)&(curbuf->b_p_cink);
5406 case PV_CINO: return (char_u *)&(curbuf->b_p_cino);
5407#endif
5408#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
5409 case PV_CINW: return (char_u *)&(curbuf->b_p_cinw);
5410#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005411 case PV_COM: return (char_u *)&(curbuf->b_p_com);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005412#ifdef FEAT_FOLDING
5413 case PV_CMS: return (char_u *)&(curbuf->b_p_cms);
5414#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005415 case PV_CPT: return (char_u *)&(curbuf->b_p_cpt);
Bram Moolenaare2c453d2019-08-21 14:37:09 +02005416#ifdef BACKSLASH_IN_FILENAME
Bram Moolenaarac3150d2019-07-28 16:36:39 +02005417 case PV_CSL: return (char_u *)&(curbuf->b_p_csl);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005418#endif
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00005419#ifdef FEAT_COMPL_FUNC
5420 case PV_CFU: return (char_u *)&(curbuf->b_p_cfu);
Bram Moolenaare344bea2005-09-01 20:46:49 +00005421 case PV_OFU: return (char_u *)&(curbuf->b_p_ofu);
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00005422#endif
Bram Moolenaar45e18cb2019-04-28 18:05:35 +02005423#ifdef FEAT_EVAL
5424 case PV_TFU: return (char_u *)&(curbuf->b_p_tfu);
5425#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005426 case PV_EOL: return (char_u *)&(curbuf->b_p_eol);
Bram Moolenaar34d72d42015-07-17 14:18:08 +02005427 case PV_FIXEOL: return (char_u *)&(curbuf->b_p_fixeol);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005428 case PV_ET: return (char_u *)&(curbuf->b_p_et);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005429 case PV_FENC: return (char_u *)&(curbuf->b_p_fenc);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005430 case PV_FF: return (char_u *)&(curbuf->b_p_ff);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005431 case PV_FT: return (char_u *)&(curbuf->b_p_ft);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005432 case PV_FO: return (char_u *)&(curbuf->b_p_fo);
Bram Moolenaar86b68352004-12-27 21:59:20 +00005433 case PV_FLP: return (char_u *)&(curbuf->b_p_flp);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005434 case PV_IMI: return (char_u *)&(curbuf->b_p_iminsert);
5435 case PV_IMS: return (char_u *)&(curbuf->b_p_imsearch);
5436 case PV_INF: return (char_u *)&(curbuf->b_p_inf);
5437 case PV_ISK: return (char_u *)&(curbuf->b_p_isk);
5438#ifdef FEAT_FIND_ID
5439# ifdef FEAT_EVAL
5440 case PV_INEX: return (char_u *)&(curbuf->b_p_inex);
5441# endif
5442#endif
5443#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
5444 case PV_INDE: return (char_u *)&(curbuf->b_p_inde);
5445 case PV_INDK: return (char_u *)&(curbuf->b_p_indk);
5446#endif
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005447#ifdef FEAT_EVAL
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +00005448 case PV_FEX: return (char_u *)&(curbuf->b_p_fex);
5449#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005450#ifdef FEAT_CRYPT
5451 case PV_KEY: return (char_u *)&(curbuf->b_p_key);
5452#endif
5453#ifdef FEAT_LISP
5454 case PV_LISP: return (char_u *)&(curbuf->b_p_lisp);
5455#endif
5456 case PV_ML: return (char_u *)&(curbuf->b_p_ml);
5457 case PV_MPS: return (char_u *)&(curbuf->b_p_mps);
5458 case PV_MA: return (char_u *)&(curbuf->b_p_ma);
5459 case PV_MOD: return (char_u *)&(curbuf->b_changed);
5460 case PV_NF: return (char_u *)&(curbuf->b_p_nf);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005461 case PV_PI: return (char_u *)&(curbuf->b_p_pi);
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00005462#ifdef FEAT_TEXTOBJ
5463 case PV_QE: return (char_u *)&(curbuf->b_p_qe);
5464#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005465 case PV_RO: return (char_u *)&(curbuf->b_p_ro);
5466#ifdef FEAT_SMARTINDENT
5467 case PV_SI: return (char_u *)&(curbuf->b_p_si);
5468#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005469 case PV_SN: return (char_u *)&(curbuf->b_p_sn);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005470 case PV_STS: return (char_u *)&(curbuf->b_p_sts);
5471#ifdef FEAT_SEARCHPATH
5472 case PV_SUA: return (char_u *)&(curbuf->b_p_sua);
5473#endif
5474 case PV_SWF: return (char_u *)&(curbuf->b_p_swf);
5475#ifdef FEAT_SYN_HL
Bram Moolenaar3b56eb32005-07-11 22:40:32 +00005476 case PV_SMC: return (char_u *)&(curbuf->b_p_smc);
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005477 case PV_SYN: return (char_u *)&(curbuf->b_p_syn);
5478#endif
5479#ifdef FEAT_SPELL
Bram Moolenaar860cae12010-06-05 23:22:07 +02005480 case PV_SPC: return (char_u *)&(curwin->w_s->b_p_spc);
5481 case PV_SPF: return (char_u *)&(curwin->w_s->b_p_spf);
5482 case PV_SPL: return (char_u *)&(curwin->w_s->b_p_spl);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005483#endif
5484 case PV_SW: return (char_u *)&(curbuf->b_p_sw);
5485 case PV_TS: return (char_u *)&(curbuf->b_p_ts);
5486 case PV_TW: return (char_u *)&(curbuf->b_p_tw);
5487 case PV_TX: return (char_u *)&(curbuf->b_p_tx);
Bram Moolenaar55debbe2010-05-23 23:34:36 +02005488#ifdef FEAT_PERSISTENT_UNDO
5489 case PV_UDF: return (char_u *)&(curbuf->b_p_udf);
5490#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005491 case PV_WM: return (char_u *)&(curbuf->b_p_wm);
5492#ifdef FEAT_KEYMAP
5493 case PV_KMAP: return (char_u *)&(curbuf->b_p_keymap);
5494#endif
Bram Moolenaar95ec9d62016-08-12 18:29:59 +02005495#ifdef FEAT_SIGNS
5496 case PV_SCL: return (char_u *)&(curwin->w_p_scl);
5497#endif
Bram Moolenaar04958cb2018-06-23 19:23:02 +02005498#ifdef FEAT_VARTABS
5499 case PV_VSTS: return (char_u *)&(curbuf->b_p_vsts);
5500 case PV_VTS: return (char_u *)&(curbuf->b_p_vts);
5501#endif
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01005502 default: iemsg(_("E356: get_varp ERROR"));
Bram Moolenaar071d4272004-06-13 20:20:40 +00005503 }
5504 /* always return a valid pointer to avoid a crash! */
5505 return (char_u *)&(curbuf->b_p_wm);
5506}
5507
5508/*
Bram Moolenaardac13472019-09-16 21:06:21 +02005509 * Return a pointer to the variable for option at 'opt_idx'
5510 */
5511 char_u *
5512get_option_var(int opt_idx)
5513{
5514 return options[opt_idx].var;
5515}
5516
5517/*
5518 * Return the full name of the option at 'opt_idx'
5519 */
5520 char_u *
5521get_option_fullname(int opt_idx)
5522{
5523 return (char_u *)options[opt_idx].fullname;
5524}
5525
5526/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005527 * Get the value of 'equalprg', either the buffer-local one or the global one.
5528 */
5529 char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01005530get_equalprg(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005531{
5532 if (*curbuf->b_p_ep == NUL)
5533 return p_ep;
5534 return curbuf->b_p_ep;
5535}
5536
Bram Moolenaar071d4272004-06-13 20:20:40 +00005537/*
5538 * Copy options from one window to another.
5539 * Used when splitting a window.
5540 */
5541 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005542win_copy_options(win_T *wp_from, win_T *wp_to)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005543{
5544 copy_winopt(&wp_from->w_onebuf_opt, &wp_to->w_onebuf_opt);
5545 copy_winopt(&wp_from->w_allbuf_opt, &wp_to->w_allbuf_opt);
Bram Moolenaar010ee962019-09-25 20:37:36 +02005546 after_copy_winopt(wp_to);
5547}
5548
5549/*
5550 * After copying window options: update variables depending on options.
5551 */
5552 void
Bram Moolenaar473952e2019-09-28 16:30:04 +02005553after_copy_winopt(win_T *wp UNUSED)
Bram Moolenaar010ee962019-09-25 20:37:36 +02005554{
5555#ifdef FEAT_LINEBREAK
5556 briopt_check(wp);
Bram Moolenaar285ed7e2014-08-24 21:39:49 +02005557#endif
Bram Moolenaar017ba072019-09-14 21:01:23 +02005558#ifdef FEAT_SYN_HL
Bram Moolenaar010ee962019-09-25 20:37:36 +02005559 fill_culopt_flags(NULL, wp);
5560 check_colorcolumn(wp);
Bram Moolenaar017ba072019-09-14 21:01:23 +02005561#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005562}
Bram Moolenaar071d4272004-06-13 20:20:40 +00005563
5564/*
5565 * Copy the options from one winopt_T to another.
5566 * Doesn't free the old option values in "to", use clear_winopt() for that.
5567 * The 'scroll' option is not copied, because it depends on the window height.
5568 * The 'previewwindow' option is reset, there can be only one preview window.
5569 */
5570 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005571copy_winopt(winopt_T *from, winopt_T *to)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005572{
5573#ifdef FEAT_ARABIC
5574 to->wo_arab = from->wo_arab;
5575#endif
5576 to->wo_list = from->wo_list;
5577 to->wo_nu = from->wo_nu;
Bram Moolenaar64486672010-05-16 15:46:46 +02005578 to->wo_rnu = from->wo_rnu;
Bram Moolenaar592e0a22004-07-03 16:05:59 +00005579#ifdef FEAT_LINEBREAK
5580 to->wo_nuw = from->wo_nuw;
5581#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005582#ifdef FEAT_RIGHTLEFT
5583 to->wo_rl = from->wo_rl;
5584 to->wo_rlc = vim_strsave(from->wo_rlc);
5585#endif
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005586#ifdef FEAT_STL_OPT
5587 to->wo_stl = vim_strsave(from->wo_stl);
5588#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005589 to->wo_wrap = from->wo_wrap;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005590#ifdef FEAT_DIFF
5591 to->wo_wrap_save = from->wo_wrap_save;
5592#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005593#ifdef FEAT_LINEBREAK
5594 to->wo_lbr = from->wo_lbr;
Bram Moolenaar597a4222014-06-25 14:39:50 +02005595 to->wo_bri = from->wo_bri;
5596 to->wo_briopt = vim_strsave(from->wo_briopt);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005597#endif
Bram Moolenaar4d784b22019-05-25 19:51:39 +02005598 to->wo_wcr = vim_strsave(from->wo_wcr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005599 to->wo_scb = from->wo_scb;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005600 to->wo_scb_save = from->wo_scb_save;
Bram Moolenaar4161dcc2010-12-02 15:33:21 +01005601 to->wo_crb = from->wo_crb;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005602 to->wo_crb_save = from->wo_crb_save;
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005603#ifdef FEAT_SPELL
Bram Moolenaar217ad922005-03-20 22:37:15 +00005604 to->wo_spell = from->wo_spell;
5605#endif
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005606#ifdef FEAT_SYN_HL
5607 to->wo_cuc = from->wo_cuc;
5608 to->wo_cul = from->wo_cul;
Bram Moolenaar410e98a2019-09-09 22:05:49 +02005609 to->wo_culopt = vim_strsave(from->wo_culopt);
Bram Moolenaar1a384422010-07-14 19:53:30 +02005610 to->wo_cc = vim_strsave(from->wo_cc);
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005611#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005612#ifdef FEAT_DIFF
5613 to->wo_diff = from->wo_diff;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005614 to->wo_diff_saved = from->wo_diff_saved;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005615#endif
Bram Moolenaarf5963f72010-07-23 22:10:27 +02005616#ifdef FEAT_CONCEAL
5617 to->wo_cocu = vim_strsave(from->wo_cocu);
Bram Moolenaard497a302010-07-23 22:27:03 +02005618 to->wo_cole = from->wo_cole;
Bram Moolenaarf5963f72010-07-23 22:10:27 +02005619#endif
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005620#ifdef FEAT_TERMINAL
Bram Moolenaar6d150f72018-04-21 20:03:20 +02005621 to->wo_twk = vim_strsave(from->wo_twk);
5622 to->wo_tws = vim_strsave(from->wo_tws);
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005623#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005624#ifdef FEAT_FOLDING
5625 to->wo_fdc = from->wo_fdc;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005626 to->wo_fdc_save = from->wo_fdc_save;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005627 to->wo_fen = from->wo_fen;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005628 to->wo_fen_save = from->wo_fen_save;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005629 to->wo_fdi = vim_strsave(from->wo_fdi);
5630 to->wo_fml = from->wo_fml;
5631 to->wo_fdl = from->wo_fdl;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005632 to->wo_fdl_save = from->wo_fdl_save;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005633 to->wo_fdm = vim_strsave(from->wo_fdm);
Bram Moolenaara87aa802013-07-03 15:47:03 +02005634 to->wo_fdm_save = from->wo_diff_saved
5635 ? vim_strsave(from->wo_fdm_save) : empty_option;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005636 to->wo_fdn = from->wo_fdn;
5637# ifdef FEAT_EVAL
5638 to->wo_fde = vim_strsave(from->wo_fde);
5639 to->wo_fdt = vim_strsave(from->wo_fdt);
5640# endif
5641 to->wo_fmr = vim_strsave(from->wo_fmr);
5642#endif
Bram Moolenaar95ec9d62016-08-12 18:29:59 +02005643#ifdef FEAT_SIGNS
5644 to->wo_scl = vim_strsave(from->wo_scl);
5645#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005646 check_winopt(to); /* don't want NULL pointers */
5647}
5648
5649/*
5650 * Check string options in a window for a NULL value.
5651 */
Bram Moolenaar5843f5f2019-08-20 20:13:45 +02005652 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005653check_win_options(win_T *win)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005654{
5655 check_winopt(&win->w_onebuf_opt);
5656 check_winopt(&win->w_allbuf_opt);
5657}
5658
5659/*
5660 * Check for NULL pointers in a winopt_T and replace them with empty_option.
5661 */
Bram Moolenaar8dc907d2014-06-25 14:44:10 +02005662 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005663check_winopt(winopt_T *wop UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005664{
5665#ifdef FEAT_FOLDING
5666 check_string_option(&wop->wo_fdi);
5667 check_string_option(&wop->wo_fdm);
Bram Moolenaara87aa802013-07-03 15:47:03 +02005668 check_string_option(&wop->wo_fdm_save);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005669# ifdef FEAT_EVAL
5670 check_string_option(&wop->wo_fde);
5671 check_string_option(&wop->wo_fdt);
5672# endif
5673 check_string_option(&wop->wo_fmr);
5674#endif
Bram Moolenaar95ec9d62016-08-12 18:29:59 +02005675#ifdef FEAT_SIGNS
5676 check_string_option(&wop->wo_scl);
5677#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005678#ifdef FEAT_RIGHTLEFT
5679 check_string_option(&wop->wo_rlc);
5680#endif
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005681#ifdef FEAT_STL_OPT
5682 check_string_option(&wop->wo_stl);
5683#endif
Bram Moolenaar1a384422010-07-14 19:53:30 +02005684#ifdef FEAT_SYN_HL
Bram Moolenaar410e98a2019-09-09 22:05:49 +02005685 check_string_option(&wop->wo_culopt);
Bram Moolenaar1a384422010-07-14 19:53:30 +02005686 check_string_option(&wop->wo_cc);
5687#endif
Bram Moolenaarf5963f72010-07-23 22:10:27 +02005688#ifdef FEAT_CONCEAL
5689 check_string_option(&wop->wo_cocu);
5690#endif
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005691#ifdef FEAT_TERMINAL
Bram Moolenaar6d150f72018-04-21 20:03:20 +02005692 check_string_option(&wop->wo_twk);
5693 check_string_option(&wop->wo_tws);
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005694#endif
Bram Moolenaar597a4222014-06-25 14:39:50 +02005695#ifdef FEAT_LINEBREAK
5696 check_string_option(&wop->wo_briopt);
5697#endif
Bram Moolenaar4d784b22019-05-25 19:51:39 +02005698 check_string_option(&wop->wo_wcr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005699}
5700
5701/*
5702 * Free the allocated memory inside a winopt_T.
5703 */
Bram Moolenaar071d4272004-06-13 20:20:40 +00005704 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005705clear_winopt(winopt_T *wop UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005706{
5707#ifdef FEAT_FOLDING
5708 clear_string_option(&wop->wo_fdi);
5709 clear_string_option(&wop->wo_fdm);
Bram Moolenaara87aa802013-07-03 15:47:03 +02005710 clear_string_option(&wop->wo_fdm_save);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005711# ifdef FEAT_EVAL
5712 clear_string_option(&wop->wo_fde);
5713 clear_string_option(&wop->wo_fdt);
5714# endif
5715 clear_string_option(&wop->wo_fmr);
5716#endif
Bram Moolenaar95ec9d62016-08-12 18:29:59 +02005717#ifdef FEAT_SIGNS
5718 clear_string_option(&wop->wo_scl);
5719#endif
Bram Moolenaar597a4222014-06-25 14:39:50 +02005720#ifdef FEAT_LINEBREAK
5721 clear_string_option(&wop->wo_briopt);
5722#endif
Bram Moolenaar4d784b22019-05-25 19:51:39 +02005723 clear_string_option(&wop->wo_wcr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005724#ifdef FEAT_RIGHTLEFT
5725 clear_string_option(&wop->wo_rlc);
5726#endif
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005727#ifdef FEAT_STL_OPT
5728 clear_string_option(&wop->wo_stl);
5729#endif
Bram Moolenaar1a384422010-07-14 19:53:30 +02005730#ifdef FEAT_SYN_HL
Bram Moolenaar410e98a2019-09-09 22:05:49 +02005731 clear_string_option(&wop->wo_culopt);
Bram Moolenaar1a384422010-07-14 19:53:30 +02005732 clear_string_option(&wop->wo_cc);
5733#endif
Bram Moolenaarf5963f72010-07-23 22:10:27 +02005734#ifdef FEAT_CONCEAL
5735 clear_string_option(&wop->wo_cocu);
5736#endif
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005737#ifdef FEAT_TERMINAL
Bram Moolenaar6d150f72018-04-21 20:03:20 +02005738 clear_string_option(&wop->wo_twk);
5739 clear_string_option(&wop->wo_tws);
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005740#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005741}
5742
5743/*
5744 * Copy global option values to local options for one buffer.
5745 * Used when creating a new buffer and sometimes when entering a buffer.
5746 * flags:
5747 * BCO_ENTER We will enter the buf buffer.
5748 * BCO_ALWAYS Always copy the options, but only set b_p_initialized when
5749 * appropriate.
5750 * BCO_NOHELP Don't copy the values to a help buffer.
5751 */
5752 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005753buf_copy_options(buf_T *buf, int flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005754{
5755 int should_copy = TRUE;
5756 char_u *save_p_isk = NULL; /* init for GCC */
5757 int dont_do_help;
5758 int did_isk = FALSE;
5759
5760 /*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005761 * Skip this when the option defaults have not been set yet. Happens when
5762 * main() allocates the first buffer.
5763 */
5764 if (p_cpo != NULL)
5765 {
5766 /*
5767 * Always copy when entering and 'cpo' contains 'S'.
5768 * Don't copy when already initialized.
5769 * Don't copy when 'cpo' contains 's' and not entering.
5770 * 'S' BCO_ENTER initialized 's' should_copy
5771 * yes yes X X TRUE
5772 * yes no yes X FALSE
5773 * no X yes X FALSE
5774 * X no no yes FALSE
5775 * X no no no TRUE
5776 * no yes no X TRUE
5777 */
5778 if ((vim_strchr(p_cpo, CPO_BUFOPTGLOB) == NULL || !(flags & BCO_ENTER))
5779 && (buf->b_p_initialized
5780 || (!(flags & BCO_ENTER)
5781 && vim_strchr(p_cpo, CPO_BUFOPT) != NULL)))
5782 should_copy = FALSE;
5783
5784 if (should_copy || (flags & BCO_ALWAYS))
5785 {
5786 /* Don't copy the options specific to a help buffer when
5787 * BCO_NOHELP is given or the options were initialized already
5788 * (jumping back to a help file with CTRL-T or CTRL-O) */
5789 dont_do_help = ((flags & BCO_NOHELP) && buf->b_help)
5790 || buf->b_p_initialized;
5791 if (dont_do_help) /* don't free b_p_isk */
5792 {
5793 save_p_isk = buf->b_p_isk;
5794 buf->b_p_isk = NULL;
5795 }
5796 /*
Bram Moolenaar40385db2018-08-07 22:31:44 +02005797 * Always free the allocated strings. If not already initialized,
5798 * reset 'readonly' and copy 'fileformat'.
Bram Moolenaar071d4272004-06-13 20:20:40 +00005799 */
5800 if (!buf->b_p_initialized)
5801 {
5802 free_buf_options(buf, TRUE);
5803 buf->b_p_ro = FALSE; /* don't copy readonly */
5804 buf->b_p_tx = p_tx;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005805 buf->b_p_fenc = vim_strsave(p_fenc);
Bram Moolenaare8ef3a02016-10-12 17:45:29 +02005806 switch (*p_ffs)
5807 {
5808 case 'm':
5809 buf->b_p_ff = vim_strsave((char_u *)FF_MAC); break;
5810 case 'd':
5811 buf->b_p_ff = vim_strsave((char_u *)FF_DOS); break;
5812 case 'u':
5813 buf->b_p_ff = vim_strsave((char_u *)FF_UNIX); break;
5814 default:
5815 buf->b_p_ff = vim_strsave(p_ff);
5816 }
5817 if (buf->b_p_ff != NULL)
5818 buf->b_start_ffc = *buf->b_p_ff;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005819 buf->b_p_bh = empty_option;
5820 buf->b_p_bt = empty_option;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005821 }
5822 else
5823 free_buf_options(buf, FALSE);
5824
5825 buf->b_p_ai = p_ai;
5826 buf->b_p_ai_nopaste = p_ai_nopaste;
5827 buf->b_p_sw = p_sw;
5828 buf->b_p_tw = p_tw;
5829 buf->b_p_tw_nopaste = p_tw_nopaste;
5830 buf->b_p_tw_nobin = p_tw_nobin;
5831 buf->b_p_wm = p_wm;
5832 buf->b_p_wm_nopaste = p_wm_nopaste;
5833 buf->b_p_wm_nobin = p_wm_nobin;
5834 buf->b_p_bin = p_bin;
Bram Moolenaare8bb2552005-07-08 22:26:47 +00005835 buf->b_p_bomb = p_bomb;
Bram Moolenaarb388be02015-07-22 22:19:38 +02005836 buf->b_p_fixeol = p_fixeol;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005837 buf->b_p_et = p_et;
5838 buf->b_p_et_nobin = p_et_nobin;
Bram Moolenaar54f018c2015-09-15 17:30:40 +02005839 buf->b_p_et_nopaste = p_et_nopaste;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005840 buf->b_p_ml = p_ml;
5841 buf->b_p_ml_nobin = p_ml_nobin;
5842 buf->b_p_inf = p_inf;
Bram Moolenaar3bab9392017-04-07 15:42:25 +02005843 buf->b_p_swf = cmdmod.noswapfile ? FALSE : p_swf;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005844 buf->b_p_cpt = vim_strsave(p_cpt);
Bram Moolenaare2c453d2019-08-21 14:37:09 +02005845#ifdef BACKSLASH_IN_FILENAME
Bram Moolenaarac3150d2019-07-28 16:36:39 +02005846 buf->b_p_csl = vim_strsave(p_csl);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005847#endif
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00005848#ifdef FEAT_COMPL_FUNC
5849 buf->b_p_cfu = vim_strsave(p_cfu);
Bram Moolenaare344bea2005-09-01 20:46:49 +00005850 buf->b_p_ofu = vim_strsave(p_ofu);
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00005851#endif
Bram Moolenaar45e18cb2019-04-28 18:05:35 +02005852#ifdef FEAT_EVAL
5853 buf->b_p_tfu = vim_strsave(p_tfu);
5854#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005855 buf->b_p_sts = p_sts;
5856 buf->b_p_sts_nopaste = p_sts_nopaste;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02005857#ifdef FEAT_VARTABS
5858 buf->b_p_vsts = vim_strsave(p_vsts);
5859 if (p_vsts && p_vsts != empty_option)
5860 tabstop_set(p_vsts, &buf->b_p_vsts_array);
5861 else
5862 buf->b_p_vsts_array = 0;
5863 buf->b_p_vsts_nopaste = p_vsts_nopaste
5864 ? vim_strsave(p_vsts_nopaste) : NULL;
5865#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005866 buf->b_p_sn = p_sn;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005867 buf->b_p_com = vim_strsave(p_com);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005868#ifdef FEAT_FOLDING
5869 buf->b_p_cms = vim_strsave(p_cms);
5870#endif
5871 buf->b_p_fo = vim_strsave(p_fo);
Bram Moolenaar86b68352004-12-27 21:59:20 +00005872 buf->b_p_flp = vim_strsave(p_flp);
Bram Moolenaar473952e2019-09-28 16:30:04 +02005873 // NOTE: Valgrind may report a bogus memory leak for 'nrformats'
5874 // when it is set to 8 bytes in defaults.vim.
Bram Moolenaar071d4272004-06-13 20:20:40 +00005875 buf->b_p_nf = vim_strsave(p_nf);
5876 buf->b_p_mps = vim_strsave(p_mps);
5877#ifdef FEAT_SMARTINDENT
5878 buf->b_p_si = p_si;
5879#endif
5880 buf->b_p_ci = p_ci;
5881#ifdef FEAT_CINDENT
5882 buf->b_p_cin = p_cin;
5883 buf->b_p_cink = vim_strsave(p_cink);
5884 buf->b_p_cino = vim_strsave(p_cino);
5885#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005886 /* Don't copy 'filetype', it must be detected */
5887 buf->b_p_ft = empty_option;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005888 buf->b_p_pi = p_pi;
5889#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
5890 buf->b_p_cinw = vim_strsave(p_cinw);
5891#endif
5892#ifdef FEAT_LISP
5893 buf->b_p_lisp = p_lisp;
5894#endif
5895#ifdef FEAT_SYN_HL
5896 /* Don't copy 'syntax', it must be set */
5897 buf->b_p_syn = empty_option;
Bram Moolenaar3b56eb32005-07-11 22:40:32 +00005898 buf->b_p_smc = p_smc;
Bram Moolenaarb8060fe2016-01-19 22:29:28 +01005899 buf->b_s.b_syn_isk = empty_option;
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005900#endif
5901#ifdef FEAT_SPELL
Bram Moolenaard5784f92010-10-13 14:05:35 +02005902 buf->b_s.b_p_spc = vim_strsave(p_spc);
Bram Moolenaar860cae12010-06-05 23:22:07 +02005903 (void)compile_cap_prog(&buf->b_s);
5904 buf->b_s.b_p_spf = vim_strsave(p_spf);
5905 buf->b_s.b_p_spl = vim_strsave(p_spl);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005906#endif
5907#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
5908 buf->b_p_inde = vim_strsave(p_inde);
5909 buf->b_p_indk = vim_strsave(p_indk);
5910#endif
Bram Moolenaar9be7c042017-01-14 14:28:30 +01005911 buf->b_p_fp = empty_option;
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +00005912#if defined(FEAT_EVAL)
5913 buf->b_p_fex = vim_strsave(p_fex);
5914#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005915#ifdef FEAT_CRYPT
5916 buf->b_p_key = vim_strsave(p_key);
5917#endif
5918#ifdef FEAT_SEARCHPATH
5919 buf->b_p_sua = vim_strsave(p_sua);
5920#endif
5921#ifdef FEAT_KEYMAP
5922 buf->b_p_keymap = vim_strsave(p_keymap);
5923 buf->b_kmap_state |= KEYMAP_INIT;
5924#endif
Bram Moolenaar6d150f72018-04-21 20:03:20 +02005925#ifdef FEAT_TERMINAL
5926 buf->b_p_twsl = p_twsl;
5927#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005928 /* This isn't really an option, but copying the langmap and IME
5929 * state from the current buffer is better than resetting it. */
5930 buf->b_p_iminsert = p_iminsert;
5931 buf->b_p_imsearch = p_imsearch;
5932
5933 /* options that are normally global but also have a local value
5934 * are not copied, start using the global value */
5935 buf->b_p_ar = -1;
Bram Moolenaarf5a2fd82013-11-06 05:26:15 +01005936 buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02005937 buf->b_p_bkc = empty_option;
5938 buf->b_bkc_flags = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005939#ifdef FEAT_QUICKFIX
5940 buf->b_p_gp = empty_option;
5941 buf->b_p_mp = empty_option;
5942 buf->b_p_efm = empty_option;
5943#endif
5944 buf->b_p_ep = empty_option;
5945 buf->b_p_kp = empty_option;
5946 buf->b_p_path = empty_option;
5947 buf->b_p_tags = empty_option;
Bram Moolenaar0f6562e2015-11-24 18:48:14 +01005948 buf->b_p_tc = empty_option;
5949 buf->b_tc_flags = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005950#ifdef FEAT_FIND_ID
5951 buf->b_p_def = empty_option;
5952 buf->b_p_inc = empty_option;
5953# ifdef FEAT_EVAL
5954 buf->b_p_inex = vim_strsave(p_inex);
5955# endif
5956#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005957 buf->b_p_dict = empty_option;
5958 buf->b_p_tsr = empty_option;
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00005959#ifdef FEAT_TEXTOBJ
5960 buf->b_p_qe = vim_strsave(p_qe);
5961#endif
Bram Moolenaar9b2200a2006-03-20 21:55:45 +00005962#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
5963 buf->b_p_bexpr = empty_option;
5964#endif
Bram Moolenaar49771f42010-07-20 17:32:38 +02005965#if defined(FEAT_CRYPT)
5966 buf->b_p_cm = empty_option;
5967#endif
Bram Moolenaar55debbe2010-05-23 23:34:36 +02005968#ifdef FEAT_PERSISTENT_UNDO
5969 buf->b_p_udf = p_udf;
5970#endif
Bram Moolenaaraf6c1312014-03-12 18:55:58 +01005971#ifdef FEAT_LISP
5972 buf->b_p_lw = empty_option;
5973#endif
Bram Moolenaar2c7292d2017-03-05 17:43:31 +01005974 buf->b_p_menc = empty_option;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005975
5976 /*
5977 * Don't copy the options set by ex_help(), use the saved values,
5978 * when going from a help buffer to a non-help buffer.
5979 * Don't touch these at all when BCO_NOHELP is used and going from
5980 * or to a help buffer.
5981 */
5982 if (dont_do_help)
Bram Moolenaar04958cb2018-06-23 19:23:02 +02005983 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00005984 buf->b_p_isk = save_p_isk;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02005985#ifdef FEAT_VARTABS
5986 if (p_vts && p_vts != empty_option && !buf->b_p_vts_array)
5987 tabstop_set(p_vts, &buf->b_p_vts_array);
5988 else
5989 buf->b_p_vts_array = NULL;
5990#endif
5991 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00005992 else
5993 {
5994 buf->b_p_isk = vim_strsave(p_isk);
5995 did_isk = TRUE;
5996 buf->b_p_ts = p_ts;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02005997#ifdef FEAT_VARTABS
5998 buf->b_p_vts = vim_strsave(p_vts);
5999 if (p_vts && p_vts != empty_option && !buf->b_p_vts_array)
6000 tabstop_set(p_vts, &buf->b_p_vts_array);
6001 else
6002 buf->b_p_vts_array = NULL;
6003#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006004 buf->b_help = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006005 if (buf->b_p_bt[0] == 'h')
6006 clear_string_option(&buf->b_p_bt);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006007 buf->b_p_ma = p_ma;
6008 }
6009 }
6010
6011 /*
6012 * When the options should be copied (ignoring BCO_ALWAYS), set the
6013 * flag that indicates that the options have been initialized.
6014 */
6015 if (should_copy)
6016 buf->b_p_initialized = TRUE;
6017 }
6018
6019 check_buf_options(buf); /* make sure we don't have NULLs */
6020 if (did_isk)
6021 (void)buf_init_chartab(buf, FALSE);
6022}
6023
6024/*
6025 * Reset the 'modifiable' option and its default value.
6026 */
6027 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006028reset_modifiable(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006029{
6030 int opt_idx;
6031
6032 curbuf->b_p_ma = FALSE;
6033 p_ma = FALSE;
6034 opt_idx = findoption((char_u *)"ma");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +00006035 if (opt_idx >= 0)
6036 options[opt_idx].def_val[VI_DEFAULT] = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006037}
6038
6039/*
6040 * Set the global value for 'iminsert' to the local value.
6041 */
6042 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006043set_iminsert_global(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006044{
6045 p_iminsert = curbuf->b_p_iminsert;
6046}
6047
6048/*
6049 * Set the global value for 'imsearch' to the local value.
6050 */
6051 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006052set_imsearch_global(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006053{
6054 p_imsearch = curbuf->b_p_imsearch;
6055}
6056
Bram Moolenaar071d4272004-06-13 20:20:40 +00006057static int expand_option_idx = -1;
6058static char_u expand_option_name[5] = {'t', '_', NUL, NUL, NUL};
6059static int expand_option_flags = 0;
6060
6061 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006062set_context_in_set_cmd(
6063 expand_T *xp,
6064 char_u *arg,
6065 int opt_flags) /* OPT_GLOBAL and/or OPT_LOCAL */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006066{
6067 int nextchar;
6068 long_u flags = 0; /* init for GCC */
6069 int opt_idx = 0; /* init for GCC */
6070 char_u *p;
6071 char_u *s;
6072 int is_term_option = FALSE;
6073 int key;
6074
6075 expand_option_flags = opt_flags;
6076
6077 xp->xp_context = EXPAND_SETTINGS;
6078 if (*arg == NUL)
6079 {
6080 xp->xp_pattern = arg;
6081 return;
6082 }
6083 p = arg + STRLEN(arg) - 1;
6084 if (*p == ' ' && *(p - 1) != '\\')
6085 {
6086 xp->xp_pattern = p + 1;
6087 return;
6088 }
6089 while (p > arg)
6090 {
6091 s = p;
6092 /* count number of backslashes before ' ' or ',' */
6093 if (*p == ' ' || *p == ',')
6094 {
6095 while (s > arg && *(s - 1) == '\\')
6096 --s;
6097 }
6098 /* break at a space with an even number of backslashes */
6099 if (*p == ' ' && ((p - s) & 1) == 0)
6100 {
6101 ++p;
6102 break;
6103 }
6104 --p;
6105 }
Bram Moolenaar2a7b9ee2009-06-16 15:50:33 +00006106 if (STRNCMP(p, "no", 2) == 0 && STRNCMP(p, "novice", 6) != 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006107 {
6108 xp->xp_context = EXPAND_BOOL_SETTINGS;
6109 p += 2;
6110 }
6111 if (STRNCMP(p, "inv", 3) == 0)
6112 {
6113 xp->xp_context = EXPAND_BOOL_SETTINGS;
6114 p += 3;
6115 }
6116 xp->xp_pattern = arg = p;
6117 if (*arg == '<')
6118 {
6119 while (*p != '>')
6120 if (*p++ == NUL) /* expand terminal option name */
6121 return;
6122 key = get_special_key_code(arg + 1);
6123 if (key == 0) /* unknown name */
6124 {
6125 xp->xp_context = EXPAND_NOTHING;
6126 return;
6127 }
6128 nextchar = *++p;
6129 is_term_option = TRUE;
6130 expand_option_name[2] = KEY2TERMCAP0(key);
6131 expand_option_name[3] = KEY2TERMCAP1(key);
6132 }
6133 else
6134 {
6135 if (p[0] == 't' && p[1] == '_')
6136 {
6137 p += 2;
6138 if (*p != NUL)
6139 ++p;
6140 if (*p == NUL)
6141 return; /* expand option name */
6142 nextchar = *++p;
6143 is_term_option = TRUE;
6144 expand_option_name[2] = p[-2];
6145 expand_option_name[3] = p[-1];
6146 }
6147 else
6148 {
6149 /* Allow * wildcard */
6150 while (ASCII_ISALNUM(*p) || *p == '_' || *p == '*')
6151 p++;
6152 if (*p == NUL)
6153 return;
6154 nextchar = *p;
6155 *p = NUL;
6156 opt_idx = findoption(arg);
6157 *p = nextchar;
6158 if (opt_idx == -1 || options[opt_idx].var == NULL)
6159 {
6160 xp->xp_context = EXPAND_NOTHING;
6161 return;
6162 }
6163 flags = options[opt_idx].flags;
6164 if (flags & P_BOOL)
6165 {
6166 xp->xp_context = EXPAND_NOTHING;
6167 return;
6168 }
6169 }
6170 }
6171 /* handle "-=" and "+=" */
6172 if ((nextchar == '-' || nextchar == '+' || nextchar == '^') && p[1] == '=')
6173 {
6174 ++p;
6175 nextchar = '=';
6176 }
6177 if ((nextchar != '=' && nextchar != ':')
6178 || xp->xp_context == EXPAND_BOOL_SETTINGS)
6179 {
6180 xp->xp_context = EXPAND_UNSUCCESSFUL;
6181 return;
6182 }
6183 if (xp->xp_context != EXPAND_BOOL_SETTINGS && p[1] == NUL)
6184 {
6185 xp->xp_context = EXPAND_OLD_SETTING;
6186 if (is_term_option)
6187 expand_option_idx = -1;
6188 else
6189 expand_option_idx = opt_idx;
6190 xp->xp_pattern = p + 1;
6191 return;
6192 }
6193 xp->xp_context = EXPAND_NOTHING;
6194 if (is_term_option || (flags & P_NUM))
6195 return;
6196
6197 xp->xp_pattern = p + 1;
6198
6199 if (flags & P_EXPAND)
6200 {
6201 p = options[opt_idx].var;
6202 if (p == (char_u *)&p_bdir
6203 || p == (char_u *)&p_dir
6204 || p == (char_u *)&p_path
Bram Moolenaarf6fee0e2016-02-21 23:02:49 +01006205 || p == (char_u *)&p_pp
Bram Moolenaar071d4272004-06-13 20:20:40 +00006206 || p == (char_u *)&p_rtp
6207#ifdef FEAT_SEARCHPATH
6208 || p == (char_u *)&p_cdpath
6209#endif
6210#ifdef FEAT_SESSION
6211 || p == (char_u *)&p_vdir
6212#endif
6213 )
6214 {
6215 xp->xp_context = EXPAND_DIRECTORIES;
6216 if (p == (char_u *)&p_path
6217#ifdef FEAT_SEARCHPATH
6218 || p == (char_u *)&p_cdpath
6219#endif
6220 )
6221 xp->xp_backslash = XP_BS_THREE;
6222 else
6223 xp->xp_backslash = XP_BS_ONE;
6224 }
6225 else
6226 {
6227 xp->xp_context = EXPAND_FILES;
6228 /* for 'tags' need three backslashes for a space */
6229 if (p == (char_u *)&p_tags)
6230 xp->xp_backslash = XP_BS_THREE;
6231 else
6232 xp->xp_backslash = XP_BS_ONE;
6233 }
6234 }
6235
6236 /* For an option that is a list of file names, find the start of the
6237 * last file name. */
6238 for (p = arg + STRLEN(arg) - 1; p > xp->xp_pattern; --p)
6239 {
6240 /* count number of backslashes before ' ' or ',' */
6241 if (*p == ' ' || *p == ',')
6242 {
6243 s = p;
6244 while (s > xp->xp_pattern && *(s - 1) == '\\')
6245 --s;
6246 if ((*p == ' ' && (xp->xp_backslash == XP_BS_THREE && (p - s) < 3))
6247 || (*p == ',' && (flags & P_COMMA) && ((p - s) & 1) == 0))
6248 {
6249 xp->xp_pattern = p + 1;
6250 break;
6251 }
6252 }
Bram Moolenaar24bbcfe2005-06-28 23:32:02 +00006253
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00006254#ifdef FEAT_SPELL
Bram Moolenaar24bbcfe2005-06-28 23:32:02 +00006255 /* for 'spellsuggest' start at "file:" */
6256 if (options[opt_idx].var == (char_u *)&p_sps
6257 && STRNCMP(p, "file:", 5) == 0)
6258 {
6259 xp->xp_pattern = p + 5;
6260 break;
6261 }
6262#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006263 }
6264
6265 return;
6266}
6267
6268 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006269ExpandSettings(
6270 expand_T *xp,
6271 regmatch_T *regmatch,
6272 int *num_file,
6273 char_u ***file)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006274{
6275 int num_normal = 0; /* Nr of matching non-term-code settings */
6276 int num_term = 0; /* Nr of matching terminal code settings */
6277 int opt_idx;
6278 int match;
6279 int count = 0;
6280 char_u *str;
6281 int loop;
6282 int is_term_opt;
6283 char_u name_buf[MAX_KEY_NAME_LEN];
6284 static char *(names[]) = {"all", "termcap"};
6285 int ic = regmatch->rm_ic; /* remember the ignore-case flag */
6286
6287 /* do this loop twice:
6288 * loop == 0: count the number of matching options
6289 * loop == 1: copy the matching options into allocated memory
6290 */
6291 for (loop = 0; loop <= 1; ++loop)
6292 {
6293 regmatch->rm_ic = ic;
6294 if (xp->xp_context != EXPAND_BOOL_SETTINGS)
6295 {
Bram Moolenaar2c4278f2009-05-17 11:33:22 +00006296 for (match = 0; match < (int)(sizeof(names) / sizeof(char *));
6297 ++match)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006298 if (vim_regexec(regmatch, (char_u *)names[match], (colnr_T)0))
6299 {
6300 if (loop == 0)
6301 num_normal++;
6302 else
6303 (*file)[count++] = vim_strsave((char_u *)names[match]);
6304 }
6305 }
6306 for (opt_idx = 0; (str = (char_u *)options[opt_idx].fullname) != NULL;
6307 opt_idx++)
6308 {
6309 if (options[opt_idx].var == NULL)
6310 continue;
6311 if (xp->xp_context == EXPAND_BOOL_SETTINGS
6312 && !(options[opt_idx].flags & P_BOOL))
6313 continue;
Bram Moolenaardac13472019-09-16 21:06:21 +02006314 is_term_opt = istermoption_idx(opt_idx);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006315 if (is_term_opt && num_normal > 0)
6316 continue;
6317 match = FALSE;
6318 if (vim_regexec(regmatch, str, (colnr_T)0)
6319 || (options[opt_idx].shortname != NULL
6320 && vim_regexec(regmatch,
6321 (char_u *)options[opt_idx].shortname, (colnr_T)0)))
6322 match = TRUE;
6323 else if (is_term_opt)
6324 {
6325 name_buf[0] = '<';
6326 name_buf[1] = 't';
6327 name_buf[2] = '_';
6328 name_buf[3] = str[2];
6329 name_buf[4] = str[3];
6330 name_buf[5] = '>';
6331 name_buf[6] = NUL;
6332 if (vim_regexec(regmatch, name_buf, (colnr_T)0))
6333 {
6334 match = TRUE;
6335 str = name_buf;
6336 }
6337 }
6338 if (match)
6339 {
6340 if (loop == 0)
6341 {
6342 if (is_term_opt)
6343 num_term++;
6344 else
6345 num_normal++;
6346 }
6347 else
6348 (*file)[count++] = vim_strsave(str);
6349 }
6350 }
6351 /*
6352 * Check terminal key codes, these are not in the option table
6353 */
6354 if (xp->xp_context != EXPAND_BOOL_SETTINGS && num_normal == 0)
6355 {
6356 for (opt_idx = 0; (str = get_termcode(opt_idx)) != NULL; opt_idx++)
6357 {
6358 if (!isprint(str[0]) || !isprint(str[1]))
6359 continue;
6360
6361 name_buf[0] = 't';
6362 name_buf[1] = '_';
6363 name_buf[2] = str[0];
6364 name_buf[3] = str[1];
6365 name_buf[4] = NUL;
6366
6367 match = FALSE;
6368 if (vim_regexec(regmatch, name_buf, (colnr_T)0))
6369 match = TRUE;
6370 else
6371 {
6372 name_buf[0] = '<';
6373 name_buf[1] = 't';
6374 name_buf[2] = '_';
6375 name_buf[3] = str[0];
6376 name_buf[4] = str[1];
6377 name_buf[5] = '>';
6378 name_buf[6] = NUL;
6379
6380 if (vim_regexec(regmatch, name_buf, (colnr_T)0))
6381 match = TRUE;
6382 }
6383 if (match)
6384 {
6385 if (loop == 0)
6386 num_term++;
6387 else
6388 (*file)[count++] = vim_strsave(name_buf);
6389 }
6390 }
6391
6392 /*
6393 * Check special key names.
6394 */
6395 regmatch->rm_ic = TRUE; /* ignore case here */
6396 for (opt_idx = 0; (str = get_key_name(opt_idx)) != NULL; opt_idx++)
6397 {
6398 name_buf[0] = '<';
6399 STRCPY(name_buf + 1, str);
6400 STRCAT(name_buf, ">");
6401
6402 if (vim_regexec(regmatch, name_buf, (colnr_T)0))
6403 {
6404 if (loop == 0)
6405 num_term++;
6406 else
6407 (*file)[count++] = vim_strsave(name_buf);
6408 }
6409 }
6410 }
6411 if (loop == 0)
6412 {
6413 if (num_normal > 0)
6414 *num_file = num_normal;
6415 else if (num_term > 0)
6416 *num_file = num_term;
6417 else
6418 return OK;
Bram Moolenaarc799fe22019-05-28 23:08:19 +02006419 *file = ALLOC_MULT(char_u *, *num_file);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006420 if (*file == NULL)
6421 {
6422 *file = (char_u **)"";
6423 return FAIL;
6424 }
6425 }
6426 }
6427 return OK;
6428}
6429
6430 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006431ExpandOldSetting(int *num_file, char_u ***file)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006432{
6433 char_u *var = NULL; /* init for GCC */
6434 char_u *buf;
6435
6436 *num_file = 0;
Bram Moolenaarc799fe22019-05-28 23:08:19 +02006437 *file = ALLOC_ONE(char_u *);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006438 if (*file == NULL)
6439 return FAIL;
6440
6441 /*
6442 * For a terminal key code expand_option_idx is < 0.
6443 */
6444 if (expand_option_idx < 0)
6445 {
6446 var = find_termcode(expand_option_name + 2);
6447 if (var == NULL)
6448 expand_option_idx = findoption(expand_option_name);
6449 }
6450
6451 if (expand_option_idx >= 0)
6452 {
6453 /* put string of option value in NameBuff */
6454 option_value2string(&options[expand_option_idx], expand_option_flags);
6455 var = NameBuff;
6456 }
6457 else if (var == NULL)
6458 var = (char_u *)"";
6459
6460 /* A backslash is required before some characters. This is the reverse of
6461 * what happens in do_set(). */
6462 buf = vim_strsave_escaped(var, escape_chars);
6463
6464 if (buf == NULL)
6465 {
Bram Moolenaard23a8232018-02-10 18:45:26 +01006466 VIM_CLEAR(*file);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006467 return FAIL;
6468 }
6469
6470#ifdef BACKSLASH_IN_FILENAME
6471 /* For MS-Windows et al. we don't double backslashes at the start and
6472 * before a file name character. */
Bram Moolenaar91acfff2017-03-12 19:22:36 +01006473 for (var = buf; *var != NUL; MB_PTR_ADV(var))
Bram Moolenaar071d4272004-06-13 20:20:40 +00006474 if (var[0] == '\\' && var[1] == '\\'
6475 && expand_option_idx >= 0
6476 && (options[expand_option_idx].flags & P_EXPAND)
6477 && vim_isfilec(var[2])
6478 && (var[2] != '\\' || (var == buf && var[4] != '\\')))
Bram Moolenaarc1a11ed2008-06-24 22:09:24 +00006479 STRMOVE(var, var + 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006480#endif
6481
6482 *file[0] = buf;
6483 *num_file = 1;
6484 return OK;
6485}
Bram Moolenaar071d4272004-06-13 20:20:40 +00006486
6487/*
6488 * Get the value for the numeric or string option *opp in a nice format into
6489 * NameBuff[]. Must not be called with a hidden option!
6490 */
6491 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006492option_value2string(
6493 struct vimoption *opp,
6494 int opt_flags) /* OPT_GLOBAL and/or OPT_LOCAL */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006495{
6496 char_u *varp;
6497
6498 varp = get_varp_scope(opp, opt_flags);
6499
6500 if (opp->flags & P_NUM)
6501 {
6502 long wc = 0;
6503
6504 if (wc_use_keyname(varp, &wc))
6505 STRCPY(NameBuff, get_special_key_name((int)wc, 0));
6506 else if (wc != 0)
6507 STRCPY(NameBuff, transchar((int)wc));
6508 else
6509 sprintf((char *)NameBuff, "%ld", *(long *)varp);
6510 }
6511 else /* P_STRING */
6512 {
6513 varp = *(char_u **)(varp);
6514 if (varp == NULL) /* just in case */
6515 NameBuff[0] = NUL;
6516#ifdef FEAT_CRYPT
6517 /* don't show the actual value of 'key', only that it's set */
Bram Moolenaareb3593b2006-04-22 22:33:57 +00006518 else if (opp->var == (char_u *)&p_key && *varp)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006519 STRCPY(NameBuff, "*****");
6520#endif
6521 else if (opp->flags & P_EXPAND)
6522 home_replace(NULL, varp, NameBuff, MAXPATHL, FALSE);
6523 /* Translate 'pastetoggle' into special key names */
6524 else if ((char_u **)opp->var == &p_pt)
6525 str2specialbuf(p_pt, NameBuff, MAXPATHL);
6526 else
Bram Moolenaarce0842a2005-07-18 21:58:11 +00006527 vim_strncpy(NameBuff, varp, MAXPATHL - 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006528 }
6529}
6530
6531/*
6532 * Return TRUE if "varp" points to 'wildchar' or 'wildcharm' and it can be
6533 * printed as a keyname.
6534 * "*wcp" is set to the value of the option if it's 'wildchar' or 'wildcharm'.
6535 */
6536 static int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006537wc_use_keyname(char_u *varp, long *wcp)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006538{
6539 if (((long *)varp == &p_wc) || ((long *)varp == &p_wcm))
6540 {
6541 *wcp = *(long *)varp;
6542 if (IS_SPECIAL(*wcp) || find_special_key_in_table((int)*wcp) >= 0)
6543 return TRUE;
6544 }
6545 return FALSE;
6546}
6547
Bram Moolenaar071d4272004-06-13 20:20:40 +00006548/*
6549 * Return TRUE if format option 'x' is in effect.
6550 * Take care of no formatting when 'paste' is set.
6551 */
6552 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006553has_format_option(int x)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006554{
6555 if (p_paste)
6556 return FALSE;
6557 return (vim_strchr(curbuf->b_p_fo, x) != NULL);
6558}
6559
6560/*
6561 * Return TRUE if "x" is present in 'shortmess' option, or
6562 * 'shortmess' contains 'a' and "x" is present in SHM_A.
6563 */
6564 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006565shortmess(int x)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006566{
Bram Moolenaar7f29f7a2012-02-29 13:51:37 +01006567 return p_shm != NULL &&
6568 ( vim_strchr(p_shm, x) != NULL
Bram Moolenaar071d4272004-06-13 20:20:40 +00006569 || (vim_strchr(p_shm, 'a') != NULL
6570 && vim_strchr((char_u *)SHM_A, x) != NULL));
6571}
6572
6573/*
6574 * paste_option_changed() - Called after p_paste was set or reset.
6575 */
6576 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006577paste_option_changed(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006578{
6579 static int old_p_paste = FALSE;
6580 static int save_sm = 0;
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006581 static int save_sta = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006582#ifdef FEAT_CMDL_INFO
6583 static int save_ru = 0;
6584#endif
6585#ifdef FEAT_RIGHTLEFT
6586 static int save_ri = 0;
6587 static int save_hkmap = 0;
6588#endif
6589 buf_T *buf;
6590
6591 if (p_paste)
6592 {
6593 /*
6594 * Paste switched from off to on.
6595 * Save the current values, so they can be restored later.
6596 */
6597 if (!old_p_paste)
6598 {
6599 /* save options for each buffer */
Bram Moolenaar29323592016-07-24 22:04:11 +02006600 FOR_ALL_BUFFERS(buf)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006601 {
6602 buf->b_p_tw_nopaste = buf->b_p_tw;
6603 buf->b_p_wm_nopaste = buf->b_p_wm;
6604 buf->b_p_sts_nopaste = buf->b_p_sts;
6605 buf->b_p_ai_nopaste = buf->b_p_ai;
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006606 buf->b_p_et_nopaste = buf->b_p_et;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02006607#ifdef FEAT_VARTABS
6608 if (buf->b_p_vsts_nopaste)
6609 vim_free(buf->b_p_vsts_nopaste);
6610 buf->b_p_vsts_nopaste = buf->b_p_vsts && buf->b_p_vsts != empty_option
6611 ? vim_strsave(buf->b_p_vsts) : NULL;
6612#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006613 }
6614
6615 /* save global options */
6616 save_sm = p_sm;
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006617 save_sta = p_sta;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006618#ifdef FEAT_CMDL_INFO
6619 save_ru = p_ru;
6620#endif
6621#ifdef FEAT_RIGHTLEFT
6622 save_ri = p_ri;
6623 save_hkmap = p_hkmap;
6624#endif
6625 /* save global values for local buffer options */
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006626 p_ai_nopaste = p_ai;
6627 p_et_nopaste = p_et;
6628 p_sts_nopaste = p_sts;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006629 p_tw_nopaste = p_tw;
6630 p_wm_nopaste = p_wm;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02006631#ifdef FEAT_VARTABS
6632 if (p_vsts_nopaste)
6633 vim_free(p_vsts_nopaste);
6634 p_vsts_nopaste = p_vsts && p_vsts != empty_option ? vim_strsave(p_vsts) : NULL;
6635#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006636 }
6637
6638 /*
6639 * Always set the option values, also when 'paste' is set when it is
6640 * already on.
6641 */
6642 /* set options for each buffer */
Bram Moolenaar29323592016-07-24 22:04:11 +02006643 FOR_ALL_BUFFERS(buf)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006644 {
6645 buf->b_p_tw = 0; /* textwidth is 0 */
6646 buf->b_p_wm = 0; /* wrapmargin is 0 */
6647 buf->b_p_sts = 0; /* softtabstop is 0 */
6648 buf->b_p_ai = 0; /* no auto-indent */
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006649 buf->b_p_et = 0; /* no expandtab */
Bram Moolenaar04958cb2018-06-23 19:23:02 +02006650#ifdef FEAT_VARTABS
6651 if (buf->b_p_vsts)
6652 free_string_option(buf->b_p_vsts);
6653 buf->b_p_vsts = empty_option;
6654 if (buf->b_p_vsts_array)
6655 vim_free(buf->b_p_vsts_array);
6656 buf->b_p_vsts_array = 0;
6657#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006658 }
6659
6660 /* set global options */
6661 p_sm = 0; /* no showmatch */
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006662 p_sta = 0; /* no smarttab */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006663#ifdef FEAT_CMDL_INFO
Bram Moolenaar071d4272004-06-13 20:20:40 +00006664 if (p_ru)
6665 status_redraw_all(); /* redraw to remove the ruler */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006666 p_ru = 0; /* no ruler */
6667#endif
6668#ifdef FEAT_RIGHTLEFT
6669 p_ri = 0; /* no reverse insert */
6670 p_hkmap = 0; /* no Hebrew keyboard */
6671#endif
6672 /* set global values for local buffer options */
6673 p_tw = 0;
6674 p_wm = 0;
6675 p_sts = 0;
6676 p_ai = 0;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02006677#ifdef FEAT_VARTABS
6678 if (p_vsts)
6679 free_string_option(p_vsts);
6680 p_vsts = empty_option;
6681#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006682 }
6683
6684 /*
6685 * Paste switched from on to off: Restore saved values.
6686 */
6687 else if (old_p_paste)
6688 {
6689 /* restore options for each buffer */
Bram Moolenaar29323592016-07-24 22:04:11 +02006690 FOR_ALL_BUFFERS(buf)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006691 {
6692 buf->b_p_tw = buf->b_p_tw_nopaste;
6693 buf->b_p_wm = buf->b_p_wm_nopaste;
6694 buf->b_p_sts = buf->b_p_sts_nopaste;
6695 buf->b_p_ai = buf->b_p_ai_nopaste;
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006696 buf->b_p_et = buf->b_p_et_nopaste;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02006697#ifdef FEAT_VARTABS
6698 if (buf->b_p_vsts)
6699 free_string_option(buf->b_p_vsts);
6700 buf->b_p_vsts = buf->b_p_vsts_nopaste
6701 ? vim_strsave(buf->b_p_vsts_nopaste) : empty_option;
6702 if (buf->b_p_vsts_array)
6703 vim_free(buf->b_p_vsts_array);
6704 if (buf->b_p_vsts && buf->b_p_vsts != empty_option)
6705 tabstop_set(buf->b_p_vsts, &buf->b_p_vsts_array);
6706 else
6707 buf->b_p_vsts_array = 0;
6708#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006709 }
6710
6711 /* restore global options */
6712 p_sm = save_sm;
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006713 p_sta = save_sta;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006714#ifdef FEAT_CMDL_INFO
Bram Moolenaar071d4272004-06-13 20:20:40 +00006715 if (p_ru != save_ru)
6716 status_redraw_all(); /* redraw to draw the ruler */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006717 p_ru = save_ru;
6718#endif
6719#ifdef FEAT_RIGHTLEFT
6720 p_ri = save_ri;
6721 p_hkmap = save_hkmap;
6722#endif
6723 /* set global values for local buffer options */
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006724 p_ai = p_ai_nopaste;
6725 p_et = p_et_nopaste;
6726 p_sts = p_sts_nopaste;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006727 p_tw = p_tw_nopaste;
6728 p_wm = p_wm_nopaste;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02006729#ifdef FEAT_VARTABS
6730 if (p_vsts)
6731 free_string_option(p_vsts);
6732 p_vsts = p_vsts_nopaste ? vim_strsave(p_vsts_nopaste) : empty_option;
6733#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006734 }
6735
6736 old_p_paste = p_paste;
6737}
6738
6739/*
6740 * vimrc_found() - Called when a ".vimrc" or "VIMINIT" has been found.
6741 *
6742 * Reset 'compatible' and set the values for options that didn't get set yet
6743 * to the Vim defaults.
6744 * Don't do this if the 'compatible' option has been set or reset before.
Bram Moolenaar910f66f2006-04-05 20:41:53 +00006745 * When "fname" is not NULL, use it to set $"envname" when it wasn't set yet.
Bram Moolenaar071d4272004-06-13 20:20:40 +00006746 */
6747 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006748vimrc_found(char_u *fname, char_u *envname)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006749{
Bram Moolenaar910f66f2006-04-05 20:41:53 +00006750 int opt_idx;
Bram Moolenaar4c3f5362006-04-11 21:38:50 +00006751 int dofree = FALSE;
Bram Moolenaar910f66f2006-04-05 20:41:53 +00006752 char_u *p;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006753
6754 if (!option_was_set((char_u *)"cp"))
6755 {
6756 p_cp = FALSE;
Bram Moolenaardac13472019-09-16 21:06:21 +02006757 for (opt_idx = 0; !istermoption_idx(opt_idx); opt_idx++)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006758 if (!(options[opt_idx].flags & (P_WAS_SET|P_VI_DEF)))
6759 set_option_default(opt_idx, OPT_FREE, FALSE);
6760 didset_options();
Bram Moolenaare68c25c2015-08-25 15:39:55 +02006761 didset_options2();
Bram Moolenaar071d4272004-06-13 20:20:40 +00006762 }
Bram Moolenaar910f66f2006-04-05 20:41:53 +00006763
6764 if (fname != NULL)
6765 {
6766 p = vim_getenv(envname, &dofree);
6767 if (p == NULL)
6768 {
6769 /* Set $MYVIMRC to the first vimrc file found. */
6770 p = FullName_save(fname, FALSE);
6771 if (p != NULL)
6772 {
6773 vim_setenv(envname, p);
6774 vim_free(p);
6775 }
6776 }
6777 else if (dofree)
6778 vim_free(p);
6779 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00006780}
6781
6782/*
6783 * Set 'compatible' on or off. Called for "-C" and "-N" command line arg.
6784 */
6785 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006786change_compatible(int on)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006787{
Bram Moolenaarfc1421e2006-04-20 22:17:20 +00006788 int opt_idx;
6789
Bram Moolenaar071d4272004-06-13 20:20:40 +00006790 if (p_cp != on)
6791 {
6792 p_cp = on;
6793 compatible_set();
6794 }
Bram Moolenaarfc1421e2006-04-20 22:17:20 +00006795 opt_idx = findoption((char_u *)"cp");
6796 if (opt_idx >= 0)
6797 options[opt_idx].flags |= P_WAS_SET;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006798}
6799
6800/*
6801 * Return TRUE when option "name" has been set.
Bram Moolenaar1a4a75c2013-07-28 16:03:06 +02006802 * Only works correctly for global options.
Bram Moolenaar071d4272004-06-13 20:20:40 +00006803 */
6804 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006805option_was_set(char_u *name)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006806{
6807 int idx;
6808
6809 idx = findoption(name);
6810 if (idx < 0) /* unknown option */
6811 return FALSE;
6812 if (options[idx].flags & P_WAS_SET)
6813 return TRUE;
6814 return FALSE;
6815}
6816
6817/*
Bram Moolenaar15d55de2012-12-05 14:43:02 +01006818 * Reset the flag indicating option "name" was set.
6819 */
Bram Moolenaarfe8ef982018-09-13 20:31:54 +02006820 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006821reset_option_was_set(char_u *name)
Bram Moolenaar15d55de2012-12-05 14:43:02 +01006822{
6823 int idx = findoption(name);
6824
6825 if (idx >= 0)
Bram Moolenaarfe8ef982018-09-13 20:31:54 +02006826 {
Bram Moolenaar15d55de2012-12-05 14:43:02 +01006827 options[idx].flags &= ~P_WAS_SET;
Bram Moolenaarfe8ef982018-09-13 20:31:54 +02006828 return OK;
6829 }
6830 return FAIL;
Bram Moolenaar15d55de2012-12-05 14:43:02 +01006831}
6832
6833/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00006834 * compatible_set() - Called when 'compatible' has been set or unset.
6835 *
6836 * When 'compatible' set: Set all relevant options (those that have the P_VIM)
6837 * flag) to a Vi compatible value.
6838 * When 'compatible' is unset: Set all options that have a different default
6839 * for Vim (without the P_VI_DEF flag) to that default.
6840 */
6841 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006842compatible_set(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006843{
6844 int opt_idx;
6845
Bram Moolenaardac13472019-09-16 21:06:21 +02006846 for (opt_idx = 0; !istermoption_idx(opt_idx); opt_idx++)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006847 if ( ((options[opt_idx].flags & P_VIM) && p_cp)
6848 || (!(options[opt_idx].flags & P_VI_DEF) && !p_cp))
6849 set_option_default(opt_idx, OPT_FREE, p_cp);
6850 didset_options();
Bram Moolenaare68c25c2015-08-25 15:39:55 +02006851 didset_options2();
Bram Moolenaar071d4272004-06-13 20:20:40 +00006852}
6853
Bram Moolenaardac13472019-09-16 21:06:21 +02006854#if defined(FEAT_LINEBREAK) || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006855
Bram Moolenaar071d4272004-06-13 20:20:40 +00006856/*
6857 * fill_breakat_flags() -- called when 'breakat' changes value.
6858 */
Bram Moolenaardac13472019-09-16 21:06:21 +02006859 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006860fill_breakat_flags(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006861{
Bram Moolenaarac6e65f2005-08-29 22:25:38 +00006862 char_u *p;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006863 int i;
6864
6865 for (i = 0; i < 256; i++)
6866 breakat_flags[i] = FALSE;
6867
6868 if (p_breakat != NULL)
Bram Moolenaarac6e65f2005-08-29 22:25:38 +00006869 for (p = p_breakat; *p; p++)
6870 breakat_flags[*p] = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006871}
Bram Moolenaar071d4272004-06-13 20:20:40 +00006872#endif
6873
6874/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00006875 * Read the 'wildmode' option, fill wim_flags[].
6876 */
Bram Moolenaardac13472019-09-16 21:06:21 +02006877 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006878check_opt_wim(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006879{
6880 char_u new_wim_flags[4];
6881 char_u *p;
6882 int i;
6883 int idx = 0;
6884
6885 for (i = 0; i < 4; ++i)
6886 new_wim_flags[i] = 0;
6887
6888 for (p = p_wim; *p; ++p)
6889 {
6890 for (i = 0; ASCII_ISALPHA(p[i]); ++i)
6891 ;
6892 if (p[i] != NUL && p[i] != ',' && p[i] != ':')
6893 return FAIL;
6894 if (i == 7 && STRNCMP(p, "longest", 7) == 0)
6895 new_wim_flags[idx] |= WIM_LONGEST;
6896 else if (i == 4 && STRNCMP(p, "full", 4) == 0)
6897 new_wim_flags[idx] |= WIM_FULL;
6898 else if (i == 4 && STRNCMP(p, "list", 4) == 0)
6899 new_wim_flags[idx] |= WIM_LIST;
6900 else
6901 return FAIL;
6902 p += i;
6903 if (*p == NUL)
6904 break;
6905 if (*p == ',')
6906 {
6907 if (idx == 3)
6908 return FAIL;
6909 ++idx;
6910 }
6911 }
6912
6913 /* fill remaining entries with last flag */
6914 while (idx < 3)
6915 {
6916 new_wim_flags[idx + 1] = new_wim_flags[idx];
6917 ++idx;
6918 }
6919
6920 /* only when there are no errors, wim_flags[] is changed */
6921 for (i = 0; i < 4; ++i)
6922 wim_flags[i] = new_wim_flags[i];
6923 return OK;
6924}
6925
6926/*
6927 * Check if backspacing over something is allowed.
6928 */
6929 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006930can_bs(
6931 int what) /* BS_INDENT, BS_EOL or BS_START */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006932{
Bram Moolenaar6b810d92018-06-04 17:28:44 +02006933#ifdef FEAT_JOB_CHANNEL
6934 if (what == BS_START && bt_prompt(curbuf))
6935 return FALSE;
6936#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006937 switch (*p_bs)
6938 {
6939 case '2': return TRUE;
6940 case '1': return (what != BS_START);
6941 case '0': return FALSE;
6942 }
6943 return vim_strchr(p_bs, what) != NULL;
6944}
6945
6946/*
6947 * Save the current values of 'fileformat' and 'fileencoding', so that we know
6948 * the file must be considered changed when the value is different.
6949 */
6950 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006951save_file_ff(buf_T *buf)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006952{
6953 buf->b_start_ffc = *buf->b_p_ff;
6954 buf->b_start_eol = buf->b_p_eol;
Bram Moolenaar83eb8852007-08-12 13:51:26 +00006955 buf->b_start_bomb = buf->b_p_bomb;
6956
Bram Moolenaar071d4272004-06-13 20:20:40 +00006957 /* Only use free/alloc when necessary, they take time. */
6958 if (buf->b_start_fenc == NULL
6959 || STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0)
6960 {
6961 vim_free(buf->b_start_fenc);
6962 buf->b_start_fenc = vim_strsave(buf->b_p_fenc);
6963 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00006964}
6965
6966/*
6967 * Return TRUE if 'fileformat' and/or 'fileencoding' has a different value
6968 * from when editing started (save_file_ff() called).
Bram Moolenaar83eb8852007-08-12 13:51:26 +00006969 * Also when 'endofline' was changed and 'binary' is set, or when 'bomb' was
6970 * changed and 'binary' is not set.
Bram Moolenaar34d72d42015-07-17 14:18:08 +02006971 * Also when 'endofline' was changed and 'fixeol' is not set.
Bram Moolenaar164c60f2011-01-22 00:11:50 +01006972 * When "ignore_empty" is true don't consider a new, empty buffer to be
6973 * changed.
Bram Moolenaar071d4272004-06-13 20:20:40 +00006974 */
6975 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006976file_ff_differs(buf_T *buf, int ignore_empty)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006977{
Bram Moolenaar9cffde92007-07-24 07:51:18 +00006978 /* In a buffer that was never loaded the options are not valid. */
6979 if (buf->b_flags & BF_NEVERLOADED)
6980 return FALSE;
Bram Moolenaar164c60f2011-01-22 00:11:50 +01006981 if (ignore_empty
6982 && (buf->b_flags & BF_NEW)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006983 && buf->b_ml.ml_line_count == 1
6984 && *ml_get_buf(buf, (linenr_T)1, FALSE) == NUL)
6985 return FALSE;
6986 if (buf->b_start_ffc != *buf->b_p_ff)
6987 return TRUE;
Bram Moolenaar34d72d42015-07-17 14:18:08 +02006988 if ((buf->b_p_bin || !buf->b_p_fixeol) && buf->b_start_eol != buf->b_p_eol)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006989 return TRUE;
Bram Moolenaar83eb8852007-08-12 13:51:26 +00006990 if (!buf->b_p_bin && buf->b_start_bomb != buf->b_p_bomb)
6991 return TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006992 if (buf->b_start_fenc == NULL)
6993 return (*buf->b_p_fenc != NUL);
6994 return (STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006995}
6996
6997/*
Bram Moolenaar375e3392019-01-31 18:26:10 +01006998 * Return the effective 'scrolloff' value for the current window, using the
6999 * global value when appropriate.
7000 */
7001 long
7002get_scrolloff_value(void)
7003{
7004 return curwin->w_p_so < 0 ? p_so : curwin->w_p_so;
7005}
7006
7007/*
7008 * Return the effective 'sidescrolloff' value for the current window, using the
7009 * global value when appropriate.
7010 */
7011 long
7012get_sidescrolloff_value(void)
7013{
7014 return curwin->w_p_siso < 0 ? p_siso : curwin->w_p_siso;
7015}
7016
7017/*
Bram Moolenaar8c7694a2013-01-17 17:02:05 +01007018 * Check matchpairs option for "*initc".
7019 * If there is a match set "*initc" to the matching character and "*findc" to
7020 * the opposite character. Set "*backwards" to the direction.
7021 * When "switchit" is TRUE swap the direction.
7022 */
7023 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01007024find_mps_values(
7025 int *initc,
7026 int *findc,
7027 int *backwards,
7028 int switchit)
Bram Moolenaar8c7694a2013-01-17 17:02:05 +01007029{
7030 char_u *ptr;
7031
7032 ptr = curbuf->b_p_mps;
7033 while (*ptr != NUL)
7034 {
Bram Moolenaar8c7694a2013-01-17 17:02:05 +01007035 if (has_mbyte)
7036 {
7037 char_u *prev;
7038
7039 if (mb_ptr2char(ptr) == *initc)
7040 {
7041 if (switchit)
7042 {
7043 *findc = *initc;
7044 *initc = mb_ptr2char(ptr + mb_ptr2len(ptr) + 1);
7045 *backwards = TRUE;
7046 }
7047 else
7048 {
7049 *findc = mb_ptr2char(ptr + mb_ptr2len(ptr) + 1);
7050 *backwards = FALSE;
7051 }
7052 return;
7053 }
7054 prev = ptr;
7055 ptr += mb_ptr2len(ptr) + 1;
7056 if (mb_ptr2char(ptr) == *initc)
7057 {
7058 if (switchit)
7059 {
7060 *findc = *initc;
7061 *initc = mb_ptr2char(prev);
7062 *backwards = FALSE;
7063 }
7064 else
7065 {
7066 *findc = mb_ptr2char(prev);
7067 *backwards = TRUE;
7068 }
7069 return;
7070 }
7071 ptr += mb_ptr2len(ptr);
7072 }
7073 else
Bram Moolenaar8c7694a2013-01-17 17:02:05 +01007074 {
7075 if (*ptr == *initc)
7076 {
7077 if (switchit)
7078 {
7079 *backwards = TRUE;
7080 *findc = *initc;
7081 *initc = ptr[2];
7082 }
7083 else
7084 {
7085 *backwards = FALSE;
7086 *findc = ptr[2];
7087 }
7088 return;
7089 }
7090 ptr += 2;
7091 if (*ptr == *initc)
7092 {
7093 if (switchit)
7094 {
7095 *backwards = FALSE;
7096 *findc = *initc;
7097 *initc = ptr[-2];
7098 }
7099 else
7100 {
7101 *backwards = TRUE;
7102 *findc = ptr[-2];
7103 }
7104 return;
7105 }
7106 ++ptr;
7107 }
7108 if (*ptr == ',')
7109 ++ptr;
7110 }
7111}
Bram Moolenaar597a4222014-06-25 14:39:50 +02007112
7113#if defined(FEAT_LINEBREAK) || defined(PROTO)
7114/*
7115 * This is called when 'breakindentopt' is changed and when a window is
7116 * initialized.
7117 */
Bram Moolenaardac13472019-09-16 21:06:21 +02007118 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01007119briopt_check(win_T *wp)
Bram Moolenaar597a4222014-06-25 14:39:50 +02007120{
7121 char_u *p;
7122 int bri_shift = 0;
7123 long bri_min = 20;
7124 int bri_sbr = FALSE;
7125
Bram Moolenaar285ed7e2014-08-24 21:39:49 +02007126 p = wp->w_p_briopt;
Bram Moolenaar597a4222014-06-25 14:39:50 +02007127 while (*p != NUL)
7128 {
7129 if (STRNCMP(p, "shift:", 6) == 0
7130 && ((p[6] == '-' && VIM_ISDIGIT(p[7])) || VIM_ISDIGIT(p[6])))
7131 {
7132 p += 6;
7133 bri_shift = getdigits(&p);
7134 }
7135 else if (STRNCMP(p, "min:", 4) == 0 && VIM_ISDIGIT(p[4]))
7136 {
7137 p += 4;
7138 bri_min = getdigits(&p);
7139 }
7140 else if (STRNCMP(p, "sbr", 3) == 0)
7141 {
7142 p += 3;
7143 bri_sbr = TRUE;
7144 }
7145 if (*p != ',' && *p != NUL)
7146 return FAIL;
7147 if (*p == ',')
7148 ++p;
7149 }
7150
Bram Moolenaar285ed7e2014-08-24 21:39:49 +02007151 wp->w_p_brishift = bri_shift;
7152 wp->w_p_brimin = bri_min;
7153 wp->w_p_brisbr = bri_sbr;
Bram Moolenaar597a4222014-06-25 14:39:50 +02007154
7155 return OK;
7156}
7157#endif
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02007158
7159/*
7160 * Get the local or global value of 'backupcopy'.
7161 */
7162 unsigned int
Bram Moolenaar9b578142016-01-30 19:39:49 +01007163get_bkc_value(buf_T *buf)
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02007164{
7165 return buf->b_bkc_flags ? buf->b_bkc_flags : bkc_flags;
7166}
Bram Moolenaar95ec9d62016-08-12 18:29:59 +02007167
7168#if defined(FEAT_SIGNS) || defined(PROTO)
7169/*
7170 * Return TRUE when window "wp" has a column to draw signs in.
7171 */
7172 int
7173signcolumn_on(win_T *wp)
7174{
Bram Moolenaar394c5d82019-06-17 21:48:05 +02007175 // If 'signcolumn' is set to 'number', signs are displayed in the 'number'
7176 // column (if present). Otherwise signs are to be displayed in the sign
7177 // column.
7178 if (*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u')
7179 return wp->w_buffer->b_signlist != NULL && !wp->w_p_nu && !wp->w_p_rnu;
7180
Bram Moolenaar95ec9d62016-08-12 18:29:59 +02007181 if (*wp->w_p_scl == 'n')
7182 return FALSE;
7183 if (*wp->w_p_scl == 'y')
7184 return TRUE;
7185 return (wp->w_buffer->b_signlist != NULL
7186# ifdef FEAT_NETBEANS_INTG
7187 || wp->w_buffer->b_has_sign_column
7188# endif
7189 );
7190}
7191#endif
Bram Moolenaarb5ae48e2016-08-12 22:23:25 +02007192
7193#if defined(FEAT_EVAL) || defined(PROTO)
7194/*
7195 * Get window or buffer local options.
7196 */
7197 dict_T *
7198get_winbuf_options(int bufopt)
7199{
7200 dict_T *d;
7201 int opt_idx;
7202
7203 d = dict_alloc();
7204 if (d == NULL)
7205 return NULL;
7206
Bram Moolenaardac13472019-09-16 21:06:21 +02007207 for (opt_idx = 0; !istermoption_idx(opt_idx); opt_idx++)
Bram Moolenaarb5ae48e2016-08-12 22:23:25 +02007208 {
7209 struct vimoption *opt = &options[opt_idx];
7210
7211 if ((bufopt && (opt->indir & PV_BUF))
7212 || (!bufopt && (opt->indir & PV_WIN)))
7213 {
7214 char_u *varp = get_varp(opt);
7215
7216 if (varp != NULL)
7217 {
7218 if (opt->flags & P_STRING)
Bram Moolenaare0be1672018-07-08 16:50:37 +02007219 dict_add_string(d, opt->fullname, *(char_u **)varp);
Bram Moolenaar789a5c02016-09-12 19:51:11 +02007220 else if (opt->flags & P_NUM)
Bram Moolenaare0be1672018-07-08 16:50:37 +02007221 dict_add_number(d, opt->fullname, *(long *)varp);
Bram Moolenaarb5ae48e2016-08-12 22:23:25 +02007222 else
Bram Moolenaare0be1672018-07-08 16:50:37 +02007223 dict_add_number(d, opt->fullname, *(int *)varp);
Bram Moolenaarb5ae48e2016-08-12 22:23:25 +02007224 }
7225 }
7226 }
7227
7228 return d;
7229}
7230#endif
Bram Moolenaar017ba072019-09-14 21:01:23 +02007231
Bram Moolenaardac13472019-09-16 21:06:21 +02007232#if defined(FEAT_SYN_HL) || defined(PROTO)
Bram Moolenaar017ba072019-09-14 21:01:23 +02007233/*
7234 * This is called when 'culopt' is changed
7235 */
Bram Moolenaardac13472019-09-16 21:06:21 +02007236 int
Bram Moolenaar017ba072019-09-14 21:01:23 +02007237fill_culopt_flags(char_u *val, win_T *wp)
7238{
7239 char_u *p;
7240 char_u culopt_flags_new = 0;
7241
7242 if (val == NULL)
7243 p = wp->w_p_culopt;
7244 else
7245 p = val;
7246 while (*p != NUL)
7247 {
7248 if (STRNCMP(p, "line", 4) == 0)
7249 {
7250 p += 4;
7251 culopt_flags_new |= CULOPT_LINE;
7252 }
7253 else if (STRNCMP(p, "both", 4) == 0)
7254 {
7255 p += 4;
7256 culopt_flags_new |= CULOPT_LINE | CULOPT_NBR;
7257 }
7258 else if (STRNCMP(p, "number", 6) == 0)
7259 {
7260 p += 6;
7261 culopt_flags_new |= CULOPT_NBR;
7262 }
7263 else if (STRNCMP(p, "screenline", 10) == 0)
7264 {
7265 p += 10;
7266 culopt_flags_new |= CULOPT_SCRLINE;
7267 }
7268
7269 if (*p != ',' && *p != NUL)
7270 return FAIL;
7271 if (*p == ',')
7272 ++p;
7273 }
7274
7275 // Can't have both "line" and "screenline".
7276 if ((culopt_flags_new & CULOPT_LINE) && (culopt_flags_new & CULOPT_SCRLINE))
7277 return FAIL;
7278 wp->w_p_culopt_flags = culopt_flags_new;
7279
7280 return OK;
7281}
7282#endif