blob: 3d408143e94dd1373ef769d4aafa951a84f07797 [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 Moolenaar4bfa8af2018-02-03 15:14:46 +0100105 set_string_default_esc("sh", p, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000106
107#ifdef FEAT_WILDIGN
108 /*
109 * Set the default for 'backupskip' to include environment variables for
110 * temp files.
111 */
112 {
113# ifdef UNIX
114 static char *(names[4]) = {"", "TMPDIR", "TEMP", "TMP"};
115# else
116 static char *(names[3]) = {"TMPDIR", "TEMP", "TMP"};
117# endif
Bram Moolenaar05159a02005-02-26 23:04:13 +0000118 int len;
119 garray_T ga;
120 int mustfree;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000121
122 ga_init2(&ga, 1, 100);
123 for (n = 0; n < (long)(sizeof(names) / sizeof(char *)); ++n)
124 {
Bram Moolenaar05159a02005-02-26 23:04:13 +0000125 mustfree = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000126# ifdef UNIX
127 if (*names[n] == NUL)
Bram Moolenaarb8e22a02018-04-12 21:37:34 +0200128# ifdef MACOS_X
129 p = (char_u *)"/private/tmp";
130# else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000131 p = (char_u *)"/tmp";
Bram Moolenaarb8e22a02018-04-12 21:37:34 +0200132# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000133 else
134# endif
Bram Moolenaar05159a02005-02-26 23:04:13 +0000135 p = vim_getenv((char_u *)names[n], &mustfree);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000136 if (p != NULL && *p != NUL)
137 {
138 /* First time count the NUL, otherwise count the ','. */
Bram Moolenaara93fa7e2006-04-17 22:14:47 +0000139 len = (int)STRLEN(p) + 3;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000140 if (ga_grow(&ga, len) == OK)
141 {
142 if (ga.ga_len > 0)
143 STRCAT(ga.ga_data, ",");
144 STRCAT(ga.ga_data, p);
145 add_pathsep(ga.ga_data);
146 STRCAT(ga.ga_data, "*");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000147 ga.ga_len += len;
148 }
149 }
Bram Moolenaar05159a02005-02-26 23:04:13 +0000150 if (mustfree)
151 vim_free(p);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000152 }
153 if (ga.ga_data != NULL)
154 {
155 set_string_default("bsk", ga.ga_data);
156 vim_free(ga.ga_data);
157 }
158 }
159#endif
160
161 /*
162 * 'maxmemtot' and 'maxmem' may have to be adjusted for available memory
163 */
164 opt_idx = findoption((char_u *)"maxmemtot");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000165 if (opt_idx >= 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000166 {
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000167#if !defined(HAVE_AVAIL_MEM) && !defined(HAVE_TOTAL_MEM)
168 if (options[opt_idx].def_val[VI_DEFAULT] == (char_u *)0L)
169#endif
170 {
Bram Moolenaar071d4272004-06-13 20:20:40 +0000171#ifdef HAVE_AVAIL_MEM
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000172 /* Use amount of memory available at this moment. */
Bram Moolenaar11b73d62012-06-29 15:51:30 +0200173 n = (mch_avail_mem(FALSE) >> 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000174#else
175# ifdef HAVE_TOTAL_MEM
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000176 /* Use amount of memory available to Vim. */
Bram Moolenaar914572a2007-05-01 11:37:47 +0000177 n = (mch_total_mem(FALSE) >> 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000178# else
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000179 n = (0x7fffffff >> 11);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000180# endif
181#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000182 options[opt_idx].def_val[VI_DEFAULT] = (char_u *)n;
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000183 opt_idx = findoption((char_u *)"maxmem");
184 if (opt_idx >= 0)
185 {
186#if !defined(HAVE_AVAIL_MEM) && !defined(HAVE_TOTAL_MEM)
Bram Moolenaar35be4532015-12-11 22:38:36 +0100187 if ((long)(long_i)options[opt_idx].def_val[VI_DEFAULT] > (long)n
188 || (long)(long_i)options[opt_idx].def_val[VI_DEFAULT] == 0L)
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000189#endif
190 options[opt_idx].def_val[VI_DEFAULT] = (char_u *)n;
191 }
192 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000193 }
194
Bram Moolenaar071d4272004-06-13 20:20:40 +0000195#ifdef FEAT_SEARCHPATH
196 {
197 char_u *cdpath;
198 char_u *buf;
199 int i;
200 int j;
Bram Moolenaar05159a02005-02-26 23:04:13 +0000201 int mustfree = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000202
203 /* Initialize the 'cdpath' option's default value. */
Bram Moolenaar05159a02005-02-26 23:04:13 +0000204 cdpath = vim_getenv((char_u *)"CDPATH", &mustfree);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000205 if (cdpath != NULL)
206 {
Bram Moolenaar964b3742019-05-24 18:54:09 +0200207 buf = alloc((STRLEN(cdpath) << 1) + 2);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000208 if (buf != NULL)
209 {
210 buf[0] = ','; /* start with ",", current dir first */
211 j = 1;
212 for (i = 0; cdpath[i] != NUL; ++i)
213 {
214 if (vim_ispathlistsep(cdpath[i]))
215 buf[j++] = ',';
216 else
217 {
218 if (cdpath[i] == ' ' || cdpath[i] == ',')
219 buf[j++] = '\\';
220 buf[j++] = cdpath[i];
221 }
222 }
223 buf[j] = NUL;
224 opt_idx = findoption((char_u *)"cdpath");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000225 if (opt_idx >= 0)
226 {
227 options[opt_idx].def_val[VI_DEFAULT] = buf;
228 options[opt_idx].flags |= P_DEF_ALLOCED;
229 }
Bram Moolenaara9d52e32010-07-31 16:44:19 +0200230 else
231 vim_free(buf); /* cannot happen */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000232 }
Bram Moolenaar05159a02005-02-26 23:04:13 +0000233 if (mustfree)
234 vim_free(cdpath);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000235 }
236 }
237#endif
238
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100239#if defined(FEAT_POSTSCRIPT) && (defined(MSWIN) || defined(VMS) || defined(EBCDIC) || defined(MAC) || defined(hpux))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000240 /* Set print encoding on platforms that don't default to latin1 */
241 set_string_default("penc",
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100242# if defined(MSWIN)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000243 (char_u *)"cp1252"
244# else
245# ifdef VMS
246 (char_u *)"dec-mcs"
247# else
248# ifdef EBCDIC
249 (char_u *)"ebcdic-uk"
250# else
251# ifdef MAC
252 (char_u *)"mac-roman"
253# else /* HPUX */
254 (char_u *)"hp-roman8"
255# endif
256# endif
257# endif
258# endif
259 );
260#endif
261
262#ifdef FEAT_POSTSCRIPT
263 /* 'printexpr' must be allocated to be able to evaluate it. */
264 set_string_default("pexpr",
Bram Moolenaar48e330a2016-02-23 14:53:34 +0100265# if defined(MSWIN)
Bram Moolenaared203462004-06-16 11:19:22 +0000266 (char_u *)"system('copy' . ' ' . v:fname_in . (&printdevice == '' ? ' LPT1:' : (' \"' . &printdevice . '\"'))) . delete(v:fname_in)"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000267# else
268# ifdef VMS
269 (char_u *)"system('print/delete' . (&printdevice == '' ? '' : ' /queue=' . &printdevice) . ' ' . v:fname_in)"
270
271# else
272 (char_u *)"system('lpr' . (&printdevice == '' ? '' : ' -P' . &printdevice) . ' ' . v:fname_in) . delete(v:fname_in) + v:shell_error"
273# endif
274# endif
275 );
276#endif
277
278 /*
279 * Set all the options (except the terminal options) to their default
280 * value. Also set the global value for local options.
281 */
282 set_options_default(0);
283
Bram Moolenaar07268702018-03-01 21:57:32 +0100284#ifdef CLEAN_RUNTIMEPATH
285 if (clean_arg)
286 {
287 opt_idx = findoption((char_u *)"runtimepath");
288 if (opt_idx >= 0)
289 {
290 options[opt_idx].def_val[VI_DEFAULT] = (char_u *)CLEAN_RUNTIMEPATH;
291 p_rtp = (char_u *)CLEAN_RUNTIMEPATH;
292 }
293 opt_idx = findoption((char_u *)"packpath");
294 if (opt_idx >= 0)
295 {
296 options[opt_idx].def_val[VI_DEFAULT] = (char_u *)CLEAN_RUNTIMEPATH;
297 p_pp = (char_u *)CLEAN_RUNTIMEPATH;
298 }
299 }
300#endif
301
Bram Moolenaar071d4272004-06-13 20:20:40 +0000302#ifdef FEAT_GUI
303 if (found_reverse_arg)
304 set_option_value((char_u *)"bg", 0L, (char_u *)"dark", 0);
305#endif
306
307 curbuf->b_p_initialized = TRUE;
308 curbuf->b_p_ar = -1; /* no local 'autoread' value */
Bram Moolenaarf5a2fd82013-11-06 05:26:15 +0100309 curbuf->b_p_ul = NO_LOCAL_UNDOLEVEL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000310 check_buf_options(curbuf);
311 check_win_options(curwin);
312 check_options();
313
314 /* Must be before option_expand(), because that one needs vim_isIDc() */
315 didset_options();
316
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +0000317#ifdef FEAT_SPELL
Bram Moolenaare68c25c2015-08-25 15:39:55 +0200318 /* Use the current chartab for the generic chartab. This is not in
319 * didset_options() because it only depends on 'encoding'. */
Bram Moolenaar6bb68362005-03-22 23:03:44 +0000320 init_spell_chartab();
321#endif
322
Bram Moolenaar071d4272004-06-13 20:20:40 +0000323 /*
324 * Expand environment variables and things like "~" for the defaults.
325 * If option_expand() returns non-NULL the variable is expanded. This can
326 * only happen for non-indirect options.
327 * Also set the default to the expanded value, so ":set" does not list
328 * them.
329 * Don't set the P_ALLOCED flag, because we don't want to free the
330 * default.
331 */
Bram Moolenaardac13472019-09-16 21:06:21 +0200332 for (opt_idx = 0; !istermoption_idx(opt_idx); opt_idx++)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000333 {
334 if ((options[opt_idx].flags & P_GETTEXT)
335 && options[opt_idx].var != NULL)
336 p = (char_u *)_(*(char **)options[opt_idx].var);
337 else
338 p = option_expand(opt_idx, NULL);
339 if (p != NULL && (p = vim_strsave(p)) != NULL)
340 {
341 *(char_u **)options[opt_idx].var = p;
342 /* VIMEXP
343 * Defaults for all expanded options are currently the same for Vi
344 * and Vim. When this changes, add some code here! Also need to
345 * split P_DEF_ALLOCED in two.
346 */
347 if (options[opt_idx].flags & P_DEF_ALLOCED)
348 vim_free(options[opt_idx].def_val[VI_DEFAULT]);
349 options[opt_idx].def_val[VI_DEFAULT] = p;
350 options[opt_idx].flags |= P_DEF_ALLOCED;
351 }
352 }
353
Bram Moolenaar071d4272004-06-13 20:20:40 +0000354 save_file_ff(curbuf); /* Buffer is unchanged */
355
Bram Moolenaar071d4272004-06-13 20:20:40 +0000356#if defined(FEAT_ARABIC)
357 /* Detect use of mlterm.
358 * Mlterm is a terminal emulator akin to xterm that has some special
359 * abilities (bidi namely).
360 * NOTE: mlterm's author is being asked to 'set' a variable
361 * instead of an environment variable due to inheritance.
362 */
363 if (mch_getenv((char_u *)"MLTERM") != NULL)
364 set_option_value((char_u *)"tbidi", 1L, NULL, 0);
365#endif
366
Bram Moolenaare68c25c2015-08-25 15:39:55 +0200367 didset_options2();
Bram Moolenaar071d4272004-06-13 20:20:40 +0000368
Bram Moolenaar4f974752019-02-17 17:44:42 +0100369# if defined(MSWIN) && defined(FEAT_GETTEXT)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000370 /*
371 * If $LANG isn't set, try to get a good value for it. This makes the
372 * right language be used automatically. Don't do this for English.
373 */
374 if (mch_getenv((char_u *)"LANG") == NULL)
375 {
376 char buf[20];
377
378 /* Could use LOCALE_SISO639LANGNAME, but it's not in Win95.
379 * LOCALE_SABBREVLANGNAME gives us three letters, like "enu", we use
380 * only the first two. */
381 n = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SABBREVLANGNAME,
382 (LPTSTR)buf, 20);
383 if (n >= 2 && STRNICMP(buf, "en", 2) != 0)
384 {
385 /* There are a few exceptions (probably more) */
386 if (STRNICMP(buf, "cht", 3) == 0 || STRNICMP(buf, "zht", 3) == 0)
387 STRCPY(buf, "zh_TW");
388 else if (STRNICMP(buf, "chs", 3) == 0
389 || STRNICMP(buf, "zhc", 3) == 0)
390 STRCPY(buf, "zh_CN");
391 else if (STRNICMP(buf, "jp", 2) == 0)
392 STRCPY(buf, "ja");
393 else
394 buf[2] = NUL; /* truncate to two-letter code */
Bram Moolenaar6aa2cd42016-02-16 15:06:59 +0100395 vim_setenv((char_u *)"LANG", (char_u *)buf);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000396 }
397 }
Bram Moolenaar26a60b42005-02-22 08:49:11 +0000398# else
Bram Moolenaar9d47f172006-03-15 23:03:01 +0000399# ifdef MACOS_CONVERT
Bram Moolenaarc1a11ed2008-06-24 22:09:24 +0000400 /* Moved to os_mac_conv.c to avoid dependency problems. */
401 mac_lang_init();
Bram Moolenaar26a60b42005-02-22 08:49:11 +0000402# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000403# endif
404
405 /* enc_locale() will try to find the encoding of the current locale. */
406 p = enc_locale();
407 if (p != NULL)
408 {
409 char_u *save_enc;
410
411 /* Try setting 'encoding' and check if the value is valid.
412 * If not, go back to the default "latin1". */
413 save_enc = p_enc;
414 p_enc = p;
Bram Moolenaar733f0a22007-03-02 18:56:27 +0000415 if (STRCMP(p_enc, "gb18030") == 0)
416 {
417 /* We don't support "gb18030", but "cp936" is a good substitute
418 * for practical purposes, thus use that. It's not an alias to
419 * still support conversion between gb18030 and utf-8. */
420 p_enc = vim_strsave((char_u *)"cp936");
421 vim_free(p);
422 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000423 if (mb_init() == NULL)
424 {
425 opt_idx = findoption((char_u *)"encoding");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000426 if (opt_idx >= 0)
427 {
428 options[opt_idx].def_val[VI_DEFAULT] = p_enc;
429 options[opt_idx].flags |= P_DEF_ALLOCED;
430 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000431
Bram Moolenaard0573012017-10-28 21:11:06 +0200432#if defined(MSWIN) || defined(MACOS_X) || defined(VMS)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +0100433 if (STRCMP(p_enc, "latin1") == 0 || enc_utf8)
Bram Moolenaarc0197e22004-09-13 20:26:32 +0000434 {
Bram Moolenaar362e1a32006-03-06 23:29:24 +0000435 /* Adjust the default for 'isprint' and 'iskeyword' to match
436 * latin1. Also set the defaults for when 'nocompatible' is
437 * set. */
Bram Moolenaarc0197e22004-09-13 20:26:32 +0000438 set_string_option_direct((char_u *)"isp", -1,
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +0000439 ISP_LATIN1, OPT_FREE, SID_NONE);
Bram Moolenaar362e1a32006-03-06 23:29:24 +0000440 set_string_option_direct((char_u *)"isk", -1,
441 ISK_LATIN1, OPT_FREE, SID_NONE);
442 opt_idx = findoption((char_u *)"isp");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000443 if (opt_idx >= 0)
444 options[opt_idx].def_val[VIM_DEFAULT] = ISP_LATIN1;
Bram Moolenaar362e1a32006-03-06 23:29:24 +0000445 opt_idx = findoption((char_u *)"isk");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000446 if (opt_idx >= 0)
447 options[opt_idx].def_val[VIM_DEFAULT] = ISK_LATIN1;
Bram Moolenaarc0197e22004-09-13 20:26:32 +0000448 (void)init_chartab();
449 }
450#endif
451
Bram Moolenaarafde13b2019-04-28 19:46:49 +0200452#if defined(MSWIN) && (!defined(FEAT_GUI) || defined(VIMDLL))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000453 /* Win32 console: When GetACP() returns a different value from
454 * GetConsoleCP() set 'termencoding'. */
Bram Moolenaarafde13b2019-04-28 19:46:49 +0200455 if (
456# ifdef VIMDLL
457 (!gui.in_use && !gui.starting) &&
458# endif
459 GetACP() != GetConsoleCP())
Bram Moolenaar071d4272004-06-13 20:20:40 +0000460 {
461 char buf[50];
462
Bram Moolenaaraa5df7e2019-02-03 14:53:10 +0100463 /* Win32 console: In ConPTY, GetConsoleCP() returns zero.
464 * Use an alternative value. */
465 if (GetConsoleCP() == 0)
466 sprintf(buf, "cp%ld", (long)GetACP());
467 else
468 sprintf(buf, "cp%ld", (long)GetConsoleCP());
Bram Moolenaar071d4272004-06-13 20:20:40 +0000469 p_tenc = vim_strsave((char_u *)buf);
470 if (p_tenc != NULL)
471 {
472 opt_idx = findoption((char_u *)"termencoding");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000473 if (opt_idx >= 0)
474 {
475 options[opt_idx].def_val[VI_DEFAULT] = p_tenc;
476 options[opt_idx].flags |= P_DEF_ALLOCED;
477 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000478 convert_setup(&input_conv, p_tenc, p_enc);
479 convert_setup(&output_conv, p_enc, p_tenc);
480 }
481 else
482 p_tenc = empty_option;
483 }
Bram Moolenaarfc3abf42019-01-24 15:54:21 +0100484#endif
Bram Moolenaar4f974752019-02-17 17:44:42 +0100485#if defined(MSWIN)
Bram Moolenaar05159a02005-02-26 23:04:13 +0000486 /* $HOME may have characters in active code page. */
487 init_homedir();
Bram Moolenaarfc3abf42019-01-24 15:54:21 +0100488#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000489 }
490 else
491 {
492 vim_free(p_enc);
493 p_enc = save_enc;
494 }
495 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000496
497#ifdef FEAT_MULTI_LANG
498 /* Set the default for 'helplang'. */
499 set_helplang_default(get_mess_lang());
500#endif
501}
502
503/*
504 * Set an option to its default value.
505 * This does not take care of side effects!
506 */
507 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +0100508set_option_default(
509 int opt_idx,
510 int opt_flags, /* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
511 int compatible) /* use Vi default value */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000512{
513 char_u *varp; /* pointer to variable for current option */
514 int dvi; /* index in def_val[] */
515 long_u flags;
Bram Moolenaard1f56e62006-02-22 21:25:37 +0000516 long_u *flagsp;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000517 int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
518
519 varp = get_varp_scope(&(options[opt_idx]), both ? OPT_LOCAL : opt_flags);
520 flags = options[opt_idx].flags;
Bram Moolenaar3638c682005-06-08 22:05:14 +0000521 if (varp != NULL) /* skip hidden option, nothing to do for it */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000522 {
523 dvi = ((flags & P_VI_DEF) || compatible) ? VI_DEFAULT : VIM_DEFAULT;
524 if (flags & P_STRING)
525 {
Bram Moolenaarb833c1e2018-05-05 16:36:06 +0200526 /* Use set_string_option_direct() for local options to handle
527 * freeing and allocating the value. */
528 if (options[opt_idx].indir != PV_NONE)
529 set_string_option_direct(NULL, opt_idx,
530 options[opt_idx].def_val[dvi], opt_flags, 0);
531 else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000532 {
Bram Moolenaarb833c1e2018-05-05 16:36:06 +0200533 if ((opt_flags & OPT_FREE) && (flags & P_ALLOCED))
534 free_string_option(*(char_u **)(varp));
535 *(char_u **)varp = options[opt_idx].def_val[dvi];
536 options[opt_idx].flags &= ~P_ALLOCED;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000537 }
538 }
539 else if (flags & P_NUM)
540 {
Bram Moolenaar5fc1a8b2006-10-17 16:34:24 +0000541 if (options[opt_idx].indir == PV_SCROLL)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000542 win_comp_scroll(curwin);
543 else
544 {
Bram Moolenaar375e3392019-01-31 18:26:10 +0100545 long def_val = (long)(long_i)options[opt_idx].def_val[dvi];
546
547 if ((long *)varp == &curwin->w_p_so
548 || (long *)varp == &curwin->w_p_siso)
549 // 'scrolloff' and 'sidescrolloff' local values have a
550 // different default value than the global default.
551 *(long *)varp = -1;
552 else
553 *(long *)varp = def_val;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000554 /* May also set global value for local option. */
555 if (both)
556 *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) =
Bram Moolenaar375e3392019-01-31 18:26:10 +0100557 def_val;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000558 }
559 }
560 else /* P_BOOL */
561 {
Bram Moolenaareb3593b2006-04-22 22:33:57 +0000562 /* the cast to long is required for Manx C, long_i is needed for
563 * MSVC */
564 *(int *)varp = (int)(long)(long_i)options[opt_idx].def_val[dvi];
Bram Moolenaar8243a792007-05-01 17:05:03 +0000565#ifdef UNIX
566 /* 'modeline' defaults to off for root */
567 if (options[opt_idx].indir == PV_ML && getuid() == ROOT_UID)
568 *(int *)varp = FALSE;
569#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000570 /* May also set global value for local option. */
571 if (both)
572 *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) =
573 *(int *)varp;
574 }
Bram Moolenaarb71eaae2006-01-20 23:10:18 +0000575
Bram Moolenaard1f56e62006-02-22 21:25:37 +0000576 /* The default value is not insecure. */
577 flagsp = insecure_flag(opt_idx, opt_flags);
578 *flagsp = *flagsp & ~P_INSECURE;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000579 }
580
581#ifdef FEAT_EVAL
Bram Moolenaarf29c1c62018-09-10 21:05:02 +0200582 set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000583#endif
584}
585
586/*
587 * Set all options (except terminal options) to their default value.
Bram Moolenaarb341dda2015-08-25 12:56:31 +0200588 * When "opt_flags" is non-zero skip 'encoding'.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000589 */
590 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +0100591set_options_default(
592 int opt_flags) /* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000593{
594 int i;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000595 win_T *wp;
Bram Moolenaarf740b292006-02-16 22:11:02 +0000596 tabpage_T *tp;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000597
Bram Moolenaardac13472019-09-16 21:06:21 +0200598 for (i = 0; !istermoption_idx(i); i++)
Bram Moolenaarb341dda2015-08-25 12:56:31 +0200599 if (!(options[i].flags & P_NODEFAULT)
Bram Moolenaare68c25c2015-08-25 15:39:55 +0200600 && (opt_flags == 0
Bram Moolenaarfc3abf42019-01-24 15:54:21 +0100601 || (options[i].var != (char_u *)&p_enc
Bram Moolenaar5ea87a02015-08-26 23:24:09 +0200602# if defined(FEAT_CRYPT)
Bram Moolenaare68c25c2015-08-25 15:39:55 +0200603 && options[i].var != (char_u *)&p_cm
Bram Moolenaar80606872015-08-25 21:27:35 +0200604 && options[i].var != (char_u *)&p_key
Bram Moolenaar5ea87a02015-08-26 23:24:09 +0200605# endif
Bram Moolenaarfc3abf42019-01-24 15:54:21 +0100606 )))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000607 set_option_default(i, opt_flags, p_cp);
608
Bram Moolenaar071d4272004-06-13 20:20:40 +0000609 /* The 'scroll' option must be computed for all windows. */
Bram Moolenaarf740b292006-02-16 22:11:02 +0000610 FOR_ALL_TAB_WINDOWS(tp, wp)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000611 win_comp_scroll(wp);
Bram Moolenaar5a4eceb2014-09-09 17:33:07 +0200612#ifdef FEAT_CINDENT
613 parse_cino(curbuf);
614#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000615}
616
617/*
618 * Set the Vi-default value of a string option.
619 * Used for 'sh', 'backupskip' and 'term'.
Bram Moolenaar4bfa8af2018-02-03 15:14:46 +0100620 * When "escape" is TRUE escape spaces with a backslash.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000621 */
Bram Moolenaar4bfa8af2018-02-03 15:14:46 +0100622 static void
623set_string_default_esc(char *name, char_u *val, int escape)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000624{
625 char_u *p;
626 int opt_idx;
627
Bram Moolenaar4bfa8af2018-02-03 15:14:46 +0100628 if (escape && vim_strchr(val, ' ') != NULL)
629 p = vim_strsave_escaped(val, (char_u *)" ");
630 else
631 p = vim_strsave(val);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000632 if (p != NULL) /* we don't want a NULL */
633 {
634 opt_idx = findoption((char_u *)name);
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000635 if (opt_idx >= 0)
636 {
637 if (options[opt_idx].flags & P_DEF_ALLOCED)
638 vim_free(options[opt_idx].def_val[VI_DEFAULT]);
639 options[opt_idx].def_val[VI_DEFAULT] = p;
640 options[opt_idx].flags |= P_DEF_ALLOCED;
641 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000642 }
643}
644
Bram Moolenaar4bfa8af2018-02-03 15:14:46 +0100645 void
646set_string_default(char *name, char_u *val)
647{
648 set_string_default_esc(name, val, FALSE);
649}
650
Bram Moolenaar071d4272004-06-13 20:20:40 +0000651/*
652 * Set the Vi-default value of a number option.
653 * Used for 'lines' and 'columns'.
654 */
655 void
Bram Moolenaar9b578142016-01-30 19:39:49 +0100656set_number_default(char *name, long val)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000657{
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000658 int opt_idx;
659
660 opt_idx = findoption((char_u *)name);
661 if (opt_idx >= 0)
Bram Moolenaareb3593b2006-04-22 22:33:57 +0000662 options[opt_idx].def_val[VI_DEFAULT] = (char_u *)(long_i)val;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000663}
664
Bram Moolenaarcacc6a52019-05-30 15:22:43 +0200665/*
666 * Set all window-local and buffer-local options to the Vim default.
667 * local-global options will use the global value.
Bram Moolenaar46451042019-08-24 15:50:46 +0200668 * When "do_buffer" is FALSE don't set buffer-local options.
Bram Moolenaarcacc6a52019-05-30 15:22:43 +0200669 */
670 void
Bram Moolenaar46451042019-08-24 15:50:46 +0200671set_local_options_default(win_T *wp, int do_buffer)
Bram Moolenaarcacc6a52019-05-30 15:22:43 +0200672{
673 win_T *save_curwin = curwin;
674 int i;
675
676 curwin = wp;
677 curbuf = curwin->w_buffer;
678 block_autocmds();
679
Bram Moolenaardac13472019-09-16 21:06:21 +0200680 for (i = 0; !istermoption_idx(i); i++)
Bram Moolenaarcacc6a52019-05-30 15:22:43 +0200681 {
682 struct vimoption *p = &(options[i]);
683 char_u *varp = get_varp_scope(p, OPT_LOCAL);
684
685 if (p->indir != PV_NONE
Bram Moolenaar46451042019-08-24 15:50:46 +0200686 && (do_buffer || (p->indir & PV_BUF) == 0)
Bram Moolenaarcacc6a52019-05-30 15:22:43 +0200687 && !(options[i].flags & P_NODEFAULT)
688 && !optval_default(p, varp, FALSE))
Bram Moolenaar86173482019-10-01 17:02:16 +0200689 set_option_default(i, OPT_FREE|OPT_LOCAL, FALSE);
Bram Moolenaarcacc6a52019-05-30 15:22:43 +0200690 }
691
692 unblock_autocmds();
693 curwin = save_curwin;
694 curbuf = curwin->w_buffer;
695}
696
Bram Moolenaarf461c8e2005-06-25 23:04:51 +0000697#if defined(EXITFREE) || defined(PROTO)
698/*
699 * Free all options.
700 */
701 void
Bram Moolenaar9b578142016-01-30 19:39:49 +0100702free_all_options(void)
Bram Moolenaarf461c8e2005-06-25 23:04:51 +0000703{
704 int i;
705
Bram Moolenaardac13472019-09-16 21:06:21 +0200706 for (i = 0; !istermoption_idx(i); i++)
Bram Moolenaarf461c8e2005-06-25 23:04:51 +0000707 {
708 if (options[i].indir == PV_NONE)
709 {
710 /* global option: free value and default value. */
Bram Moolenaar67391142017-02-19 21:07:04 +0100711 if ((options[i].flags & P_ALLOCED) && options[i].var != NULL)
Bram Moolenaarf461c8e2005-06-25 23:04:51 +0000712 free_string_option(*(char_u **)options[i].var);
713 if (options[i].flags & P_DEF_ALLOCED)
714 free_string_option(options[i].def_val[VI_DEFAULT]);
715 }
716 else if (options[i].var != VAR_WIN
717 && (options[i].flags & P_STRING))
718 /* buffer-local option: free global value */
719 free_string_option(*(char_u **)options[i].var);
720 }
721}
722#endif
723
724
Bram Moolenaar071d4272004-06-13 20:20:40 +0000725/*
726 * Initialize the options, part two: After getting Rows and Columns and
727 * setting 'term'.
728 */
729 void
Bram Moolenaar9b578142016-01-30 19:39:49 +0100730set_init_2(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000731{
Bram Moolenaar4399ef42005-02-12 14:29:27 +0000732 int idx;
733
Bram Moolenaar071d4272004-06-13 20:20:40 +0000734 /*
Bram Moolenaaraf2d20c2017-10-29 15:26:57 +0100735 * 'scroll' defaults to half the window height. The stored default is zero,
736 * which results in the actual value computed from the window height.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000737 */
Bram Moolenaar26a60b42005-02-22 08:49:11 +0000738 idx = findoption((char_u *)"scroll");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000739 if (idx >= 0 && !(options[idx].flags & P_WAS_SET))
Bram Moolenaar26a60b42005-02-22 08:49:11 +0000740 set_option_default(idx, OPT_LOCAL, p_cp);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000741 comp_col();
742
Bram Moolenaar4399ef42005-02-12 14:29:27 +0000743 /*
744 * 'window' is only for backwards compatibility with Vi.
745 * Default is Rows - 1.
746 */
Bram Moolenaard68071d2006-05-02 22:08:30 +0000747 if (!option_was_set((char_u *)"window"))
Bram Moolenaar4399ef42005-02-12 14:29:27 +0000748 p_window = Rows - 1;
749 set_number_default("window", Rows - 1);
750
Bram Moolenaarf740b292006-02-16 22:11:02 +0000751 /* For DOS console the default is always black. */
Bram Moolenaar4f974752019-02-17 17:44:42 +0100752#if !((defined(MSWIN)) && !defined(FEAT_GUI))
Bram Moolenaarf740b292006-02-16 22:11:02 +0000753 /*
754 * If 'background' wasn't set by the user, try guessing the value,
755 * depending on the terminal name. Only need to check for terminals
756 * with a dark background, that can handle color.
757 */
758 idx = findoption((char_u *)"bg");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000759 if (idx >= 0 && !(options[idx].flags & P_WAS_SET)
760 && *term_bg_default() == 'd')
Bram Moolenaar071d4272004-06-13 20:20:40 +0000761 {
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +0000762 set_string_option_direct(NULL, idx, (char_u *)"dark", OPT_FREE, 0);
Bram Moolenaarf740b292006-02-16 22:11:02 +0000763 /* don't mark it as set, when starting the GUI it may be
764 * changed again */
765 options[idx].flags &= ~P_WAS_SET;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000766 }
767#endif
Bram Moolenaar58d98232005-07-23 22:25:46 +0000768
769#ifdef CURSOR_SHAPE
770 parse_shape_opt(SHAPE_CURSOR); /* set cursor shapes from 'guicursor' */
771#endif
772#ifdef FEAT_MOUSESHAPE
773 parse_shape_opt(SHAPE_MOUSE); /* set mouse shapes from 'mouseshape' */
774#endif
775#ifdef FEAT_PRINTER
776 (void)parse_printoptions(); /* parse 'printoptions' default value */
777#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000778}
779
780/*
Bram Moolenaarf740b292006-02-16 22:11:02 +0000781 * Return "dark" or "light" depending on the kind of terminal.
782 * This is just guessing! Recognized are:
783 * "linux" Linux console
784 * "screen.linux" Linux console with screen
Bram Moolenaarc6da01a2017-09-07 22:37:36 +0200785 * "cygwin.*" Cygwin shell
786 * "putty.*" Putty program
Bram Moolenaarf740b292006-02-16 22:11:02 +0000787 * We also check the COLORFGBG environment variable, which is set by
788 * rxvt and derivatives. This variable contains either two or three
789 * values separated by semicolons; we want the last value in either
790 * case. If this value is 0-6 or 8, our background is dark.
791 */
792 static char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +0100793term_bg_default(void)
Bram Moolenaarf740b292006-02-16 22:11:02 +0000794{
Bram Moolenaar4f974752019-02-17 17:44:42 +0100795#if defined(MSWIN)
Bram Moolenaarc6da01a2017-09-07 22:37:36 +0200796 /* DOS console is nearly always black */
Bram Moolenaarf740b292006-02-16 22:11:02 +0000797 return (char_u *)"dark";
798#else
Bram Moolenaarfaa959a2006-02-20 21:37:40 +0000799 char_u *p;
800
Bram Moolenaarf740b292006-02-16 22:11:02 +0000801 if (STRCMP(T_NAME, "linux") == 0
802 || STRCMP(T_NAME, "screen.linux") == 0
Bram Moolenaarc6da01a2017-09-07 22:37:36 +0200803 || STRNCMP(T_NAME, "cygwin", 6) == 0
804 || STRNCMP(T_NAME, "putty", 5) == 0
Bram Moolenaarf740b292006-02-16 22:11:02 +0000805 || ((p = mch_getenv((char_u *)"COLORFGBG")) != NULL
806 && (p = vim_strrchr(p, ';')) != NULL
807 && ((p[1] >= '0' && p[1] <= '6') || p[1] == '8')
808 && p[2] == NUL))
809 return (char_u *)"dark";
810 return (char_u *)"light";
811#endif
812}
813
814/*
Bram Moolenaar071d4272004-06-13 20:20:40 +0000815 * Initialize the options, part three: After reading the .vimrc
816 */
817 void
Bram Moolenaar9b578142016-01-30 19:39:49 +0100818set_init_3(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000819{
Bram Moolenaar4f974752019-02-17 17:44:42 +0100820#if defined(UNIX) || defined(MSWIN)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000821/*
822 * Set 'shellpipe' and 'shellredir', depending on the 'shell' option.
823 * This is done after other initializations, where 'shell' might have been
824 * set, but only if they have not been set before.
825 */
826 char_u *p;
827 int idx_srr;
828 int do_srr;
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100829# ifdef FEAT_QUICKFIX
Bram Moolenaar071d4272004-06-13 20:20:40 +0000830 int idx_sp;
831 int do_sp;
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100832# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000833
834 idx_srr = findoption((char_u *)"srr");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000835 if (idx_srr < 0)
836 do_srr = FALSE;
837 else
838 do_srr = !(options[idx_srr].flags & P_WAS_SET);
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100839# ifdef FEAT_QUICKFIX
Bram Moolenaar071d4272004-06-13 20:20:40 +0000840 idx_sp = findoption((char_u *)"sp");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000841 if (idx_sp < 0)
842 do_sp = FALSE;
843 else
844 do_sp = !(options[idx_sp].flags & P_WAS_SET);
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100845# endif
Bram Moolenaar75a8d742014-05-07 15:10:21 +0200846 p = get_isolated_shell_name();
Bram Moolenaar071d4272004-06-13 20:20:40 +0000847 if (p != NULL)
848 {
849 /*
850 * Default for p_sp is "| tee", for p_srr is ">".
851 * For known shells it is changed here to include stderr.
852 */
853 if ( fnamecmp(p, "csh") == 0
854 || fnamecmp(p, "tcsh") == 0
Bram Moolenaar4f974752019-02-17 17:44:42 +0100855# if defined(MSWIN) // also check with .exe extension
Bram Moolenaar071d4272004-06-13 20:20:40 +0000856 || fnamecmp(p, "csh.exe") == 0
857 || fnamecmp(p, "tcsh.exe") == 0
858# endif
859 )
860 {
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100861# if defined(FEAT_QUICKFIX)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000862 if (do_sp)
863 {
Bram Moolenaar4f974752019-02-17 17:44:42 +0100864# ifdef MSWIN
Bram Moolenaar071d4272004-06-13 20:20:40 +0000865 p_sp = (char_u *)">&";
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100866# else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000867 p_sp = (char_u *)"|& tee";
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100868# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000869 options[idx_sp].def_val[VI_DEFAULT] = p_sp;
870 }
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100871# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000872 if (do_srr)
873 {
874 p_srr = (char_u *)">&";
875 options[idx_srr].def_val[VI_DEFAULT] = p_srr;
876 }
877 }
878 else
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100879 /* Always use bourne shell style redirection if we reach this */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000880 if ( fnamecmp(p, "sh") == 0
881 || fnamecmp(p, "ksh") == 0
Bram Moolenaarf1fda2d2011-04-28 12:57:36 +0200882 || fnamecmp(p, "mksh") == 0
883 || fnamecmp(p, "pdksh") == 0
Bram Moolenaar071d4272004-06-13 20:20:40 +0000884 || fnamecmp(p, "zsh") == 0
Bram Moolenaarc1e37902006-04-18 21:55:01 +0000885 || fnamecmp(p, "zsh-beta") == 0
Bram Moolenaar071d4272004-06-13 20:20:40 +0000886 || fnamecmp(p, "bash") == 0
Bram Moolenaar75a8d742014-05-07 15:10:21 +0200887 || fnamecmp(p, "fish") == 0
Bram Moolenaar4f974752019-02-17 17:44:42 +0100888# ifdef MSWIN
Bram Moolenaar071d4272004-06-13 20:20:40 +0000889 || fnamecmp(p, "cmd") == 0
890 || fnamecmp(p, "sh.exe") == 0
891 || fnamecmp(p, "ksh.exe") == 0
Bram Moolenaarf1fda2d2011-04-28 12:57:36 +0200892 || fnamecmp(p, "mksh.exe") == 0
893 || fnamecmp(p, "pdksh.exe") == 0
Bram Moolenaar071d4272004-06-13 20:20:40 +0000894 || fnamecmp(p, "zsh.exe") == 0
Bram Moolenaarc1e37902006-04-18 21:55:01 +0000895 || fnamecmp(p, "zsh-beta.exe") == 0
Bram Moolenaar071d4272004-06-13 20:20:40 +0000896 || fnamecmp(p, "bash.exe") == 0
897 || fnamecmp(p, "cmd.exe") == 0
Bram Moolenaar071d4272004-06-13 20:20:40 +0000898# endif
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100899 )
Bram Moolenaar071d4272004-06-13 20:20:40 +0000900 {
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100901# if defined(FEAT_QUICKFIX)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000902 if (do_sp)
903 {
Bram Moolenaar4f974752019-02-17 17:44:42 +0100904# ifdef MSWIN
Bram Moolenaar071d4272004-06-13 20:20:40 +0000905 p_sp = (char_u *)">%s 2>&1";
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100906# else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000907 p_sp = (char_u *)"2>&1| tee";
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100908# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000909 options[idx_sp].def_val[VI_DEFAULT] = p_sp;
910 }
Bram Moolenaare7fedb62015-12-31 19:07:19 +0100911# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000912 if (do_srr)
913 {
914 p_srr = (char_u *)">%s 2>&1";
915 options[idx_srr].def_val[VI_DEFAULT] = p_srr;
916 }
917 }
918 vim_free(p);
919 }
920#endif
921
Bram Moolenaar4f974752019-02-17 17:44:42 +0100922#if defined(MSWIN)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000923 /*
Bram Moolenaara64ba222012-02-12 23:23:31 +0100924 * Set 'shellcmdflag', 'shellxquote', and 'shellquote' depending on the
925 * 'shell' option.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000926 * This is done after other initializations, where 'shell' might have been
927 * set, but only if they have not been set before. Default for p_shcf is
928 * "/c", for p_shq is "". For "sh" like shells it is changed here to
Bram Moolenaar48e330a2016-02-23 14:53:34 +0100929 * "-c" and "\"". And for Win32 we need to set p_sxq instead.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000930 */
Bram Moolenaarf4b8e572004-06-24 15:53:16 +0000931 if (strstr((char *)gettail(p_sh), "sh") != NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000932 {
933 int idx3;
934
935 idx3 = findoption((char_u *)"shcf");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000936 if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000937 {
938 p_shcf = (char_u *)"-c";
939 options[idx3].def_val[VI_DEFAULT] = p_shcf;
940 }
941
Bram Moolenaar071d4272004-06-13 20:20:40 +0000942 /* Somehow Win32 requires the quotes around the redirection too */
943 idx3 = findoption((char_u *)"sxq");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +0000944 if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000945 {
946 p_sxq = (char_u *)"\"";
947 options[idx3].def_val[VI_DEFAULT] = p_sxq;
948 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000949 }
Bram Moolenaara64ba222012-02-12 23:23:31 +0100950 else if (strstr((char *)gettail(p_sh), "cmd.exe") != NULL)
951 {
952 int idx3;
953
954 /*
955 * cmd.exe on Windows will strip the first and last double quote given
956 * on the command line, e.g. most of the time things like:
957 * cmd /c "my path/to/echo" "my args to echo"
958 * become:
959 * my path/to/echo" "my args to echo
960 * when executed.
961 *
Bram Moolenaar034b1152012-02-19 18:19:30 +0100962 * To avoid this, set shellxquote to surround the command in
963 * parenthesis. This appears to make most commands work, without
964 * breaking commands that worked previously, such as
965 * '"path with spaces/cmd" "a&b"'.
Bram Moolenaara64ba222012-02-12 23:23:31 +0100966 */
Bram Moolenaara64ba222012-02-12 23:23:31 +0100967 idx3 = findoption((char_u *)"sxq");
968 if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET))
969 {
Bram Moolenaar034b1152012-02-19 18:19:30 +0100970 p_sxq = (char_u *)"(";
Bram Moolenaara64ba222012-02-12 23:23:31 +0100971 options[idx3].def_val[VI_DEFAULT] = p_sxq;
972 }
973
Bram Moolenaara64ba222012-02-12 23:23:31 +0100974 idx3 = findoption((char_u *)"shcf");
975 if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET))
976 {
Bram Moolenaar034b1152012-02-19 18:19:30 +0100977 p_shcf = (char_u *)"/c";
Bram Moolenaara64ba222012-02-12 23:23:31 +0100978 options[idx3].def_val[VI_DEFAULT] = p_shcf;
979 }
980 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000981#endif
982
Bram Moolenaarb5aedf32017-03-12 18:23:53 +0100983 if (BUFEMPTY())
Bram Moolenaar364fa5c2016-03-20 17:53:25 +0100984 {
985 int idx_ffs = findoption((char_u *)"ffs");
986
987 /* Apply the first entry of 'fileformats' to the initial buffer. */
988 if (idx_ffs >= 0 && (options[idx_ffs].flags & P_WAS_SET))
989 set_fileformat(default_fileformat(), OPT_LOCAL);
990 }
991
Bram Moolenaar071d4272004-06-13 20:20:40 +0000992#ifdef FEAT_TITLE
993 set_title_defaults();
994#endif
995}
996
997#if defined(FEAT_MULTI_LANG) || defined(PROTO)
998/*
999 * When 'helplang' is still at its default value, set it to "lang".
1000 * Only the first two characters of "lang" are used.
1001 */
1002 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01001003set_helplang_default(char_u *lang)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001004{
1005 int idx;
1006
1007 if (lang == NULL || STRLEN(lang) < 2) /* safety check */
1008 return;
1009 idx = findoption((char_u *)"hlg");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +00001010 if (idx >= 0 && !(options[idx].flags & P_WAS_SET))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001011 {
1012 if (options[idx].flags & P_ALLOCED)
1013 free_string_option(p_hlg);
1014 p_hlg = vim_strsave(lang);
1015 if (p_hlg == NULL)
1016 p_hlg = empty_option;
1017 else
Bram Moolenaarab79bcb2004-07-18 21:34:53 +00001018 {
Bram Moolenaardcd71cb2018-11-04 14:40:47 +01001019 // zh_CN becomes "cn", zh_TW becomes "tw"
Bram Moolenaarab79bcb2004-07-18 21:34:53 +00001020 if (STRNICMP(p_hlg, "zh_", 3) == 0 && STRLEN(p_hlg) >= 5)
1021 {
1022 p_hlg[0] = TOLOWER_ASC(p_hlg[3]);
1023 p_hlg[1] = TOLOWER_ASC(p_hlg[4]);
1024 }
Bram Moolenaardcd71cb2018-11-04 14:40:47 +01001025 // any C like setting, such as C.UTF-8, becomes "en"
1026 else if (STRLEN(p_hlg) >= 1 && *p_hlg == 'C')
1027 {
1028 p_hlg[0] = 'e';
1029 p_hlg[1] = 'n';
1030 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001031 p_hlg[2] = NUL;
Bram Moolenaarab79bcb2004-07-18 21:34:53 +00001032 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001033 options[idx].flags |= P_ALLOCED;
1034 }
1035}
1036#endif
1037
1038#ifdef FEAT_GUI
Bram Moolenaar071d4272004-06-13 20:20:40 +00001039 static char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01001040gui_bg_default(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001041{
1042 if (gui_get_lightness(gui.back_pixel) < 127)
1043 return (char_u *)"dark";
1044 return (char_u *)"light";
1045}
1046
1047/*
1048 * Option initializations that can only be done after opening the GUI window.
1049 */
1050 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01001051init_gui_options(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001052{
1053 /* Set the 'background' option according to the lightness of the
1054 * background color, unless the user has set it already. */
1055 if (!option_was_set((char_u *)"bg") && STRCMP(p_bg, gui_bg_default()) != 0)
1056 {
1057 set_option_value((char_u *)"bg", 0L, gui_bg_default(), 0);
1058 highlight_changed();
1059 }
1060}
1061#endif
1062
1063#ifdef FEAT_TITLE
1064/*
1065 * 'title' and 'icon' only default to true if they have not been set or reset
1066 * in .vimrc and we can read the old value.
1067 * When 'title' and 'icon' have been reset in .vimrc, we won't even check if
1068 * they can be reset. This reduces startup time when using X on a remote
1069 * machine.
1070 */
1071 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01001072set_title_defaults(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001073{
1074 int idx1;
1075 long val;
1076
1077 /*
1078 * If GUI is (going to be) used, we can always set the window title and
1079 * icon name. Saves a bit of time, because the X11 display server does
1080 * not need to be contacted.
1081 */
1082 idx1 = findoption((char_u *)"title");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +00001083 if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001084 {
1085#ifdef FEAT_GUI
1086 if (gui.starting || gui.in_use)
1087 val = TRUE;
1088 else
1089#endif
1090 val = mch_can_restore_title();
Bram Moolenaareb3593b2006-04-22 22:33:57 +00001091 options[idx1].def_val[VI_DEFAULT] = (char_u *)(long_i)val;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001092 p_title = val;
1093 }
1094 idx1 = findoption((char_u *)"icon");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +00001095 if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001096 {
1097#ifdef FEAT_GUI
1098 if (gui.starting || gui.in_use)
1099 val = TRUE;
1100 else
1101#endif
1102 val = mch_can_restore_icon();
Bram Moolenaareb3593b2006-04-22 22:33:57 +00001103 options[idx1].def_val[VI_DEFAULT] = (char_u *)(long_i)val;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001104 p_icon = val;
1105 }
1106}
1107#endif
1108
1109/*
1110 * Parse 'arg' for option settings.
1111 *
1112 * 'arg' may be IObuff, but only when no errors can be present and option
1113 * does not need to be expanded with option_expand().
1114 * "opt_flags":
1115 * 0 for ":set"
Bram Moolenaara3227e22006-03-08 21:32:40 +00001116 * OPT_GLOBAL for ":setglobal"
1117 * OPT_LOCAL for ":setlocal" and a modeline
Bram Moolenaar071d4272004-06-13 20:20:40 +00001118 * OPT_MODELINE for a modeline
Bram Moolenaara3227e22006-03-08 21:32:40 +00001119 * OPT_WINONLY to only set window-local options
1120 * OPT_NOWIN to skip setting window-local options
Bram Moolenaar071d4272004-06-13 20:20:40 +00001121 *
1122 * returns FAIL if an error is detected, OK otherwise
1123 */
1124 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01001125do_set(
1126 char_u *arg, /* option string (may be written to!) */
1127 int opt_flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001128{
1129 int opt_idx;
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001130 char *errmsg;
1131 char errbuf[80];
Bram Moolenaar071d4272004-06-13 20:20:40 +00001132 char_u *startarg;
1133 int prefix; /* 1: nothing, 0: "no", 2: "inv" in front of name */
1134 int nextchar; /* next non-white char after option name */
1135 int afterchar; /* character just after option name */
1136 int len;
1137 int i;
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02001138 varnumber_T value;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001139 int key;
1140 long_u flags; /* flags for current option */
1141 char_u *varp = NULL; /* pointer to variable for current option */
1142 int did_show = FALSE; /* already showed one value */
1143 int adding; /* "opt+=arg" */
1144 int prepending; /* "opt^=arg" */
1145 int removing; /* "opt-=arg" */
1146 int cp_val = 0;
1147 char_u key_name[2];
1148
1149 if (*arg == NUL)
1150 {
1151 showoptions(0, opt_flags);
Bram Moolenaar26a60b42005-02-22 08:49:11 +00001152 did_show = TRUE;
1153 goto theend;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001154 }
1155
1156 while (*arg != NUL) /* loop to process all options */
1157 {
1158 errmsg = NULL;
1159 startarg = arg; /* remember for error message */
1160
Bram Moolenaar293ee4d2004-12-09 21:34:53 +00001161 if (STRNCMP(arg, "all", 3) == 0 && !isalpha(arg[3])
1162 && !(opt_flags & OPT_MODELINE))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001163 {
1164 /*
1165 * ":set all" show all options.
1166 * ":set all&" set all options to their default value.
1167 */
1168 arg += 3;
1169 if (*arg == '&')
1170 {
1171 ++arg;
1172 /* Only for :set command set global value of local options. */
1173 set_options_default(OPT_FREE | opt_flags);
Bram Moolenaare68c25c2015-08-25 15:39:55 +02001174 didset_options();
1175 didset_options2();
Bram Moolenaarb341dda2015-08-25 12:56:31 +02001176 redraw_all_later(CLEAR);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001177 }
1178 else
Bram Moolenaar26a60b42005-02-22 08:49:11 +00001179 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001180 showoptions(1, opt_flags);
Bram Moolenaar26a60b42005-02-22 08:49:11 +00001181 did_show = TRUE;
1182 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001183 }
Bram Moolenaar293ee4d2004-12-09 21:34:53 +00001184 else if (STRNCMP(arg, "termcap", 7) == 0 && !(opt_flags & OPT_MODELINE))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001185 {
1186 showoptions(2, opt_flags);
1187 show_termcodes();
Bram Moolenaar26a60b42005-02-22 08:49:11 +00001188 did_show = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001189 arg += 7;
1190 }
1191 else
1192 {
1193 prefix = 1;
Bram Moolenaar2a7b9ee2009-06-16 15:50:33 +00001194 if (STRNCMP(arg, "no", 2) == 0 && STRNCMP(arg, "novice", 6) != 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001195 {
1196 prefix = 0;
1197 arg += 2;
1198 }
1199 else if (STRNCMP(arg, "inv", 3) == 0)
1200 {
1201 prefix = 2;
1202 arg += 3;
1203 }
1204
1205 /* find end of name */
1206 key = 0;
1207 if (*arg == '<')
1208 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001209 opt_idx = -1;
1210 /* look out for <t_>;> */
1211 if (arg[1] == 't' && arg[2] == '_' && arg[3] && arg[4])
1212 len = 5;
1213 else
1214 {
1215 len = 1;
1216 while (arg[len] != NUL && arg[len] != '>')
1217 ++len;
1218 }
1219 if (arg[len] != '>')
1220 {
1221 errmsg = e_invarg;
1222 goto skip;
1223 }
1224 arg[len] = NUL; /* put NUL after name */
1225 if (arg[1] == 't' && arg[2] == '_') /* could be term code */
1226 opt_idx = findoption(arg + 1);
1227 arg[len++] = '>'; /* restore '>' */
1228 if (opt_idx == -1)
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02001229 key = find_key_option(arg + 1, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001230 }
1231 else
1232 {
1233 len = 0;
1234 /*
1235 * The two characters after "t_" may not be alphanumeric.
1236 */
1237 if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
1238 len = 4;
1239 else
1240 while (ASCII_ISALNUM(arg[len]) || arg[len] == '_')
1241 ++len;
1242 nextchar = arg[len];
1243 arg[len] = NUL; /* put NUL after name */
1244 opt_idx = findoption(arg);
1245 arg[len] = nextchar; /* restore nextchar */
1246 if (opt_idx == -1)
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02001247 key = find_key_option(arg, FALSE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001248 }
1249
1250 /* remember character after option name */
1251 afterchar = arg[len];
1252
1253 /* skip white space, allow ":set ai ?" */
Bram Moolenaar1c465442017-03-12 20:10:05 +01001254 while (VIM_ISWHITE(arg[len]))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001255 ++len;
1256
1257 adding = FALSE;
1258 prepending = FALSE;
1259 removing = FALSE;
1260 if (arg[len] != NUL && arg[len + 1] == '=')
1261 {
1262 if (arg[len] == '+')
1263 {
1264 adding = TRUE; /* "+=" */
1265 ++len;
1266 }
1267 else if (arg[len] == '^')
1268 {
1269 prepending = TRUE; /* "^=" */
1270 ++len;
1271 }
1272 else if (arg[len] == '-')
1273 {
1274 removing = TRUE; /* "-=" */
1275 ++len;
1276 }
1277 }
1278 nextchar = arg[len];
1279
1280 if (opt_idx == -1 && key == 0) /* found a mismatch: skip */
1281 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001282 errmsg = N_("E518: Unknown option");
Bram Moolenaar071d4272004-06-13 20:20:40 +00001283 goto skip;
1284 }
1285
1286 if (opt_idx >= 0)
1287 {
1288 if (options[opt_idx].var == NULL) /* hidden option: skip */
1289 {
1290 /* Only give an error message when requesting the value of
1291 * a hidden option, ignore setting it. */
1292 if (vim_strchr((char_u *)"=:!&<", nextchar) == NULL
1293 && (!(options[opt_idx].flags & P_BOOL)
1294 || nextchar == '?'))
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001295 errmsg = N_("E519: Option not supported");
Bram Moolenaar071d4272004-06-13 20:20:40 +00001296 goto skip;
1297 }
1298
1299 flags = options[opt_idx].flags;
1300 varp = get_varp_scope(&(options[opt_idx]), opt_flags);
1301 }
1302 else
1303 {
1304 flags = P_STRING;
1305 if (key < 0)
1306 {
1307 key_name[0] = KEY2TERMCAP0(key);
1308 key_name[1] = KEY2TERMCAP1(key);
1309 }
1310 else
1311 {
1312 key_name[0] = KS_KEY;
1313 key_name[1] = (key & 0xff);
1314 }
1315 }
1316
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001317 /* Skip all options that are not window-local (used when showing
1318 * an already loaded buffer in a window). */
1319 if ((opt_flags & OPT_WINONLY)
1320 && (opt_idx < 0 || options[opt_idx].var != VAR_WIN))
1321 goto skip;
1322
Bram Moolenaara3227e22006-03-08 21:32:40 +00001323 /* Skip all options that are window-local (used for :vimgrep). */
1324 if ((opt_flags & OPT_NOWIN) && opt_idx >= 0
1325 && options[opt_idx].var == VAR_WIN)
1326 goto skip;
1327
Bram Moolenaar1bf0ddc2009-02-11 15:47:05 +00001328 /* Disallow changing some options from modelines. */
1329 if (opt_flags & OPT_MODELINE)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001330 {
Bram Moolenaar865242e2010-07-14 21:12:05 +02001331 if (flags & (P_SECURE | P_NO_ML))
Bram Moolenaar1bf0ddc2009-02-11 15:47:05 +00001332 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001333 errmsg = _("E520: Not allowed in a modeline");
Bram Moolenaar1bf0ddc2009-02-11 15:47:05 +00001334 goto skip;
1335 }
Bram Moolenaar110289e2019-05-23 15:38:06 +02001336 if ((flags & P_MLE) && !p_mle)
1337 {
1338 errmsg = _("E992: Not allowed in a modeline when 'modelineexpr' is off");
1339 goto skip;
1340 }
Bram Moolenaarf69d9a32009-02-11 21:48:40 +00001341#ifdef FEAT_DIFF
Bram Moolenaar1bf0ddc2009-02-11 15:47:05 +00001342 /* In diff mode some options are overruled. This avoids that
1343 * 'foldmethod' becomes "marker" instead of "diff" and that
1344 * "wrap" gets set. */
1345 if (curwin->w_p_diff
Bram Moolenaara9d52e32010-07-31 16:44:19 +02001346 && opt_idx >= 0 /* shut up coverity warning */
Bram Moolenaara6c07602017-03-05 21:18:27 +01001347 && (
1348#ifdef FEAT_FOLDING
1349 options[opt_idx].indir == PV_FDM ||
1350#endif
1351 options[opt_idx].indir == PV_WRAP))
Bram Moolenaar1bf0ddc2009-02-11 15:47:05 +00001352 goto skip;
Bram Moolenaarf69d9a32009-02-11 21:48:40 +00001353#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00001354 }
1355
1356#ifdef HAVE_SANDBOX
1357 /* Disallow changing some options in the sandbox */
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001358 if (sandbox != 0 && (flags & P_SECURE))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001359 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001360 errmsg = _(e_sandbox);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001361 goto skip;
1362 }
1363#endif
1364
1365 if (vim_strchr((char_u *)"?=:!&<", nextchar) != NULL)
1366 {
1367 arg += len;
1368 cp_val = p_cp;
1369 if (nextchar == '&' && arg[1] == 'v' && arg[2] == 'i')
1370 {
1371 if (arg[3] == 'm') /* "opt&vim": set to Vim default */
1372 {
1373 cp_val = FALSE;
1374 arg += 3;
1375 }
1376 else /* "opt&vi": set to Vi default */
1377 {
1378 cp_val = TRUE;
1379 arg += 2;
1380 }
1381 }
1382 if (vim_strchr((char_u *)"?!&<", nextchar) != NULL
Bram Moolenaar1c465442017-03-12 20:10:05 +01001383 && arg[1] != NUL && !VIM_ISWHITE(arg[1]))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001384 {
1385 errmsg = e_trailing;
1386 goto skip;
1387 }
1388 }
1389
1390 /*
Bram Moolenaar48e330a2016-02-23 14:53:34 +01001391 * allow '=' and ':' for hystorical reasons (MSDOS command.com
1392 * allows only one '=' character per "set" command line. grrr. (jw)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001393 */
1394 if (nextchar == '?'
1395 || (prefix == 1
1396 && vim_strchr((char_u *)"=:&<", nextchar) == NULL
1397 && !(flags & P_BOOL)))
1398 {
1399 /*
1400 * print value
1401 */
1402 if (did_show)
1403 msg_putchar('\n'); /* cursor below last one */
1404 else
1405 {
1406 gotocmdline(TRUE); /* cursor at status line */
1407 did_show = TRUE; /* remember that we did a line */
1408 }
1409 if (opt_idx >= 0)
1410 {
1411 showoneopt(&options[opt_idx], opt_flags);
1412#ifdef FEAT_EVAL
1413 if (p_verbose > 0)
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00001414 {
1415 /* Mention where the option was last set. */
1416 if (varp == options[opt_idx].var)
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02001417 last_set_msg(options[opt_idx].script_ctx);
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00001418 else if ((int)options[opt_idx].indir & PV_WIN)
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02001419 last_set_msg(curwin->w_p_script_ctx[
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00001420 (int)options[opt_idx].indir & PV_MASK]);
1421 else if ((int)options[opt_idx].indir & PV_BUF)
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02001422 last_set_msg(curbuf->b_p_script_ctx[
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00001423 (int)options[opt_idx].indir & PV_MASK]);
1424 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001425#endif
1426 }
1427 else
1428 {
1429 char_u *p;
1430
1431 p = find_termcode(key_name);
1432 if (p == NULL)
1433 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001434 errmsg = N_("E846: Key code not set");
Bram Moolenaar071d4272004-06-13 20:20:40 +00001435 goto skip;
1436 }
1437 else
1438 (void)show_one_termcode(key_name, p, TRUE);
1439 }
1440 if (nextchar != '?'
Bram Moolenaar1c465442017-03-12 20:10:05 +01001441 && nextchar != NUL && !VIM_ISWHITE(afterchar))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001442 errmsg = e_trailing;
1443 }
1444 else
1445 {
Bram Moolenaar247bb7e2018-11-20 14:27:07 +01001446 int value_is_replaced = !prepending && !adding && !removing;
Bram Moolenaar916a8182018-11-25 02:18:29 +01001447 int value_checked = FALSE;
Bram Moolenaar247bb7e2018-11-20 14:27:07 +01001448
Bram Moolenaar071d4272004-06-13 20:20:40 +00001449 if (flags & P_BOOL) /* boolean */
1450 {
1451 if (nextchar == '=' || nextchar == ':')
1452 {
1453 errmsg = e_invarg;
1454 goto skip;
1455 }
1456
1457 /*
1458 * ":set opt!": invert
1459 * ":set opt&": reset to default value
1460 * ":set opt<": reset to global value
1461 */
1462 if (nextchar == '!')
1463 value = *(int *)(varp) ^ 1;
1464 else if (nextchar == '&')
Bram Moolenaareb3593b2006-04-22 22:33:57 +00001465 value = (int)(long)(long_i)options[opt_idx].def_val[
Bram Moolenaar071d4272004-06-13 20:20:40 +00001466 ((flags & P_VI_DEF) || cp_val)
1467 ? VI_DEFAULT : VIM_DEFAULT];
1468 else if (nextchar == '<')
1469 {
1470 /* For 'autoread' -1 means to use global value. */
1471 if ((int *)varp == &curbuf->b_p_ar
1472 && opt_flags == OPT_LOCAL)
1473 value = -1;
1474 else
1475 value = *(int *)get_varp_scope(&(options[opt_idx]),
1476 OPT_GLOBAL);
1477 }
1478 else
1479 {
1480 /*
1481 * ":set invopt": invert
1482 * ":set opt" or ":set noopt": set or reset
1483 */
Bram Moolenaar1c465442017-03-12 20:10:05 +01001484 if (nextchar != NUL && !VIM_ISWHITE(afterchar))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001485 {
1486 errmsg = e_trailing;
1487 goto skip;
1488 }
1489 if (prefix == 2) /* inv */
1490 value = *(int *)(varp) ^ 1;
1491 else
1492 value = prefix;
1493 }
1494
1495 errmsg = set_bool_option(opt_idx, varp, (int)value,
1496 opt_flags);
1497 }
1498 else /* numeric or string */
1499 {
1500 if (vim_strchr((char_u *)"=:&<", nextchar) == NULL
1501 || prefix != 1)
1502 {
1503 errmsg = e_invarg;
1504 goto skip;
1505 }
1506
1507 if (flags & P_NUM) /* numeric */
1508 {
1509 /*
1510 * Different ways to set a number option:
1511 * & set to default value
1512 * < set to global value
1513 * <xx> accept special key codes for 'wildchar'
1514 * c accept any non-digit for 'wildchar'
1515 * [-]0-9 set number
1516 * other error
1517 */
1518 ++arg;
1519 if (nextchar == '&')
Bram Moolenaareb3593b2006-04-22 22:33:57 +00001520 value = (long)(long_i)options[opt_idx].def_val[
Bram Moolenaar071d4272004-06-13 20:20:40 +00001521 ((flags & P_VI_DEF) || cp_val)
1522 ? VI_DEFAULT : VIM_DEFAULT];
1523 else if (nextchar == '<')
Bram Moolenaarf5a2fd82013-11-06 05:26:15 +01001524 {
1525 /* For 'undolevels' NO_LOCAL_UNDOLEVEL means to
1526 * use the global value. */
1527 if ((long *)varp == &curbuf->b_p_ul
1528 && opt_flags == OPT_LOCAL)
1529 value = NO_LOCAL_UNDOLEVEL;
1530 else
1531 value = *(long *)get_varp_scope(
1532 &(options[opt_idx]), OPT_GLOBAL);
1533 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001534 else if (((long *)varp == &p_wc
1535 || (long *)varp == &p_wcm)
1536 && (*arg == '<'
1537 || *arg == '^'
Bram Moolenaar1c465442017-03-12 20:10:05 +01001538 || (*arg != NUL
1539 && (!arg[1] || VIM_ISWHITE(arg[1]))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001540 && !VIM_ISDIGIT(*arg))))
1541 {
Bram Moolenaardbe948d2017-07-23 22:50:51 +02001542 value = string_to_key(arg, FALSE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001543 if (value == 0 && (long *)varp != &p_wcm)
1544 {
1545 errmsg = e_invarg;
1546 goto skip;
1547 }
1548 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001549 else if (*arg == '-' || VIM_ISDIGIT(*arg))
1550 {
Bram Moolenaar18400e62015-01-27 15:58:40 +01001551 /* Allow negative (for 'undolevels'), octal and
1552 * hex numbers. */
Bram Moolenaar887c1fe2016-01-02 17:56:35 +01001553 vim_str2nr(arg, NULL, &i, STR2NR_ALL,
Bram Moolenaar16e9b852019-05-19 19:59:35 +02001554 &value, NULL, 0, TRUE);
Bram Moolenaar06e2c812019-06-12 19:05:48 +02001555 if (i == 0 || (arg[i] != NUL
1556 && !VIM_ISWHITE(arg[i])))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001557 {
Bram Moolenaar16e9b852019-05-19 19:59:35 +02001558 errmsg = N_("E521: Number required after =");
Bram Moolenaar071d4272004-06-13 20:20:40 +00001559 goto skip;
1560 }
1561 }
1562 else
1563 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001564 errmsg = N_("E521: Number required after =");
Bram Moolenaar071d4272004-06-13 20:20:40 +00001565 goto skip;
1566 }
1567
1568 if (adding)
1569 value = *(long *)varp + value;
1570 if (prepending)
1571 value = *(long *)varp * value;
1572 if (removing)
1573 value = *(long *)varp - value;
1574 errmsg = set_num_option(opt_idx, varp, value,
Bram Moolenaar555b2802005-05-19 21:08:39 +00001575 errbuf, sizeof(errbuf), opt_flags);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001576 }
1577 else if (opt_idx >= 0) /* string */
1578 {
Bram Moolenaar8efa0262017-08-20 15:47:20 +02001579 char_u *save_arg = NULL;
1580 char_u *s = NULL;
1581 char_u *oldval = NULL; /* previous value if *varp */
1582 char_u *newval;
1583 char_u *origval = NULL;
Bram Moolenaard7c96872019-06-15 17:12:48 +02001584 char_u *origval_l = NULL;
1585 char_u *origval_g = NULL;
Bram Moolenaarf2bd8ef2018-03-04 18:08:14 +01001586#if defined(FEAT_EVAL)
Bram Moolenaar8efa0262017-08-20 15:47:20 +02001587 char_u *saved_origval = NULL;
Bram Moolenaard7c96872019-06-15 17:12:48 +02001588 char_u *saved_origval_l = NULL;
1589 char_u *saved_origval_g = NULL;
Bram Moolenaar8efa0262017-08-20 15:47:20 +02001590 char_u *saved_newval = NULL;
Bram Moolenaar53744302015-07-17 17:38:22 +02001591#endif
Bram Moolenaar8efa0262017-08-20 15:47:20 +02001592 unsigned newlen;
1593 int comma;
1594 int bs;
1595 int new_value_alloced; /* new string option
Bram Moolenaar071d4272004-06-13 20:20:40 +00001596 was allocated */
1597
1598 /* When using ":set opt=val" for a global option
1599 * with a local value the local value will be
1600 * reset, use the global value here. */
1601 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
Bram Moolenaara23ccb82006-02-27 00:08:02 +00001602 && ((int)options[opt_idx].indir & PV_BOTH))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001603 varp = options[opt_idx].var;
1604
1605 /* The old value is kept until we are sure that the
1606 * new value is valid. */
1607 oldval = *(char_u **)varp;
Bram Moolenaar8efa0262017-08-20 15:47:20 +02001608
Bram Moolenaard7c96872019-06-15 17:12:48 +02001609 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
1610 {
1611 origval_l = *(char_u **)get_varp_scope(
1612 &(options[opt_idx]), OPT_LOCAL);
1613 origval_g = *(char_u **)get_varp_scope(
1614 &(options[opt_idx]), OPT_GLOBAL);
1615
1616 // A global-local string option might have an empty
1617 // option as value to indicate that the global
1618 // value should be used.
1619 if (((int)options[opt_idx].indir & PV_BOTH)
1620 && origval_l == empty_option)
1621 origval_l = origval_g;
1622 }
1623
1624 // When setting the local value of a global
1625 // option, the old value may be the global value.
Bram Moolenaar8efa0262017-08-20 15:47:20 +02001626 if (((int)options[opt_idx].indir & PV_BOTH)
1627 && (opt_flags & OPT_LOCAL))
1628 origval = *(char_u **)get_varp(
1629 &options[opt_idx]);
1630 else
1631 origval = oldval;
1632
Bram Moolenaar071d4272004-06-13 20:20:40 +00001633 if (nextchar == '&') /* set to default val */
1634 {
1635 newval = options[opt_idx].def_val[
1636 ((flags & P_VI_DEF) || cp_val)
1637 ? VI_DEFAULT : VIM_DEFAULT];
1638 if ((char_u **)varp == &p_bg)
1639 {
1640 /* guess the value of 'background' */
1641#ifdef FEAT_GUI
1642 if (gui.in_use)
1643 newval = gui_bg_default();
1644 else
1645#endif
Bram Moolenaarf740b292006-02-16 22:11:02 +00001646 newval = term_bg_default();
Bram Moolenaar071d4272004-06-13 20:20:40 +00001647 }
1648
1649 /* expand environment variables and ~ (since the
1650 * default value was already expanded, only
1651 * required when an environment variable was set
1652 * later */
1653 if (newval == NULL)
1654 newval = empty_option;
1655 else
1656 {
1657 s = option_expand(opt_idx, newval);
1658 if (s == NULL)
1659 s = newval;
1660 newval = vim_strsave(s);
1661 }
1662 new_value_alloced = TRUE;
1663 }
1664 else if (nextchar == '<') /* set to global val */
1665 {
1666 newval = vim_strsave(*(char_u **)get_varp_scope(
1667 &(options[opt_idx]), OPT_GLOBAL));
1668 new_value_alloced = TRUE;
1669 }
1670 else
1671 {
1672 ++arg; /* jump to after the '=' or ':' */
1673
1674 /*
1675 * Set 'keywordprg' to ":help" if an empty
1676 * value was passed to :set by the user.
1677 * Misuse errbuf[] for the resulting string.
1678 */
1679 if (varp == (char_u *)&p_kp
1680 && (*arg == NUL || *arg == ' '))
1681 {
1682 STRCPY(errbuf, ":help");
1683 save_arg = arg;
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001684 arg = (char_u *)errbuf;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001685 }
1686 /*
Bram Moolenaar4e5ccfa2011-11-30 11:15:47 +01001687 * Convert 'backspace' number to string, for
1688 * adding, prepending and removing string.
1689 */
1690 else if (varp == (char_u *)&p_bs
1691 && VIM_ISDIGIT(**(char_u **)varp))
1692 {
1693 i = getdigits((char_u **)varp);
1694 switch (i)
1695 {
1696 case 0:
1697 *(char_u **)varp = empty_option;
1698 break;
1699 case 1:
1700 *(char_u **)varp = vim_strsave(
1701 (char_u *)"indent,eol");
1702 break;
1703 case 2:
1704 *(char_u **)varp = vim_strsave(
1705 (char_u *)"indent,eol,start");
1706 break;
1707 }
1708 vim_free(oldval);
Bram Moolenaaredbc0d42017-08-20 16:11:51 +02001709 if (origval == oldval)
1710 origval = *(char_u **)varp;
Bram Moolenaard7c96872019-06-15 17:12:48 +02001711 if (origval_l == oldval)
1712 origval_l = *(char_u **)varp;
1713 if (origval_g == oldval)
1714 origval_g = *(char_u **)varp;
Bram Moolenaar4e5ccfa2011-11-30 11:15:47 +01001715 oldval = *(char_u **)varp;
1716 }
1717 /*
Bram Moolenaar071d4272004-06-13 20:20:40 +00001718 * Convert 'whichwrap' number to string, for
1719 * backwards compatibility with Vim 3.0.
1720 * Misuse errbuf[] for the resulting string.
1721 */
1722 else if (varp == (char_u *)&p_ww
1723 && VIM_ISDIGIT(*arg))
1724 {
1725 *errbuf = NUL;
1726 i = getdigits(&arg);
1727 if (i & 1)
1728 STRCAT(errbuf, "b,");
1729 if (i & 2)
1730 STRCAT(errbuf, "s,");
1731 if (i & 4)
1732 STRCAT(errbuf, "h,l,");
1733 if (i & 8)
1734 STRCAT(errbuf, "<,>,");
1735 if (i & 16)
1736 STRCAT(errbuf, "[,],");
1737 if (*errbuf != NUL) /* remove trailing , */
1738 errbuf[STRLEN(errbuf) - 1] = NUL;
1739 save_arg = arg;
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01001740 arg = (char_u *)errbuf;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001741 }
1742 /*
1743 * Remove '>' before 'dir' and 'bdir', for
1744 * backwards compatibility with version 3.0
1745 */
1746 else if ( *arg == '>'
1747 && (varp == (char_u *)&p_dir
1748 || varp == (char_u *)&p_bdir))
1749 {
1750 ++arg;
1751 }
1752
Bram Moolenaar071d4272004-06-13 20:20:40 +00001753 /*
1754 * Copy the new string into allocated memory.
1755 * Can't use set_string_option_direct(), because
1756 * we need to remove the backslashes.
1757 */
1758 /* get a bit too much */
1759 newlen = (unsigned)STRLEN(arg) + 1;
1760 if (adding || prepending || removing)
1761 newlen += (unsigned)STRLEN(origval) + 1;
1762 newval = alloc(newlen);
1763 if (newval == NULL) /* out of mem, don't change */
1764 break;
1765 s = newval;
1766
1767 /*
1768 * Copy the string, skip over escaped chars.
1769 * For MS-DOS and WIN32 backslashes before normal
1770 * file name characters are not removed, and keep
1771 * backslash at start, for "\\machine\path", but
1772 * do remove it for "\\\\machine\\path".
1773 * The reverse is found in ExpandOldSetting().
1774 */
Bram Moolenaar1c465442017-03-12 20:10:05 +01001775 while (*arg && !VIM_ISWHITE(*arg))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001776 {
1777 if (*arg == '\\' && arg[1] != NUL
1778#ifdef BACKSLASH_IN_FILENAME
1779 && !((flags & P_EXPAND)
1780 && vim_isfilec(arg[1])
1781 && (arg[1] != '\\'
1782 || (s == newval
1783 && arg[2] != '\\')))
1784#endif
1785 )
1786 ++arg; /* remove backslash */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001787 if (has_mbyte
Bram Moolenaar0fa313a2005-08-10 21:07:57 +00001788 && (i = (*mb_ptr2len)(arg)) > 1)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001789 {
1790 /* copy multibyte char */
1791 mch_memmove(s, arg, (size_t)i);
1792 arg += i;
1793 s += i;
1794 }
1795 else
Bram Moolenaar071d4272004-06-13 20:20:40 +00001796 *s++ = *arg++;
1797 }
1798 *s = NUL;
1799
1800 /*
1801 * Expand environment variables and ~.
1802 * Don't do it when adding without inserting a
1803 * comma.
1804 */
1805 if (!(adding || prepending || removing)
1806 || (flags & P_COMMA))
1807 {
1808 s = option_expand(opt_idx, newval);
1809 if (s != NULL)
1810 {
1811 vim_free(newval);
1812 newlen = (unsigned)STRLEN(s) + 1;
1813 if (adding || prepending || removing)
1814 newlen += (unsigned)STRLEN(origval) + 1;
1815 newval = alloc(newlen);
1816 if (newval == NULL)
1817 break;
1818 STRCPY(newval, s);
1819 }
1820 }
1821
1822 /* locate newval[] in origval[] when removing it
1823 * and when adding to avoid duplicates */
1824 i = 0; /* init for GCC */
1825 if (removing || (flags & P_NODUP))
1826 {
1827 i = (int)STRLEN(newval);
1828 bs = 0;
1829 for (s = origval; *s; ++s)
1830 {
1831 if ((!(flags & P_COMMA)
1832 || s == origval
1833 || (s[-1] == ',' && !(bs & 1)))
1834 && STRNCMP(s, newval, i) == 0
1835 && (!(flags & P_COMMA)
1836 || s[i] == ','
1837 || s[i] == NUL))
1838 break;
Bram Moolenaar0b2f94d2011-03-22 14:35:05 +01001839 /* Count backslashes. Only a comma with an
Bram Moolenaar8f79acd2016-01-01 14:48:20 +01001840 * even number of backslashes or a single
1841 * backslash preceded by a comma before it
1842 * is recognized as a separator */
1843 if ((s > origval + 1
1844 && s[-1] == '\\'
1845 && s[-2] != ',')
1846 || (s == origval + 1
1847 && s[-1] == '\\'))
1848
Bram Moolenaar071d4272004-06-13 20:20:40 +00001849 ++bs;
1850 else
1851 bs = 0;
1852 }
1853
1854 /* do not add if already there */
1855 if ((adding || prepending) && *s)
1856 {
1857 prepending = FALSE;
1858 adding = FALSE;
1859 STRCPY(newval, origval);
1860 }
1861 }
1862
1863 /* concatenate the two strings; add a ',' if
1864 * needed */
1865 if (adding || prepending)
1866 {
1867 comma = ((flags & P_COMMA) && *origval != NUL
1868 && *newval != NUL);
1869 if (adding)
1870 {
1871 i = (int)STRLEN(origval);
Bram Moolenaara7b7b1c2015-06-19 14:06:43 +02001872 /* strip a trailing comma, would get 2 */
Bram Moolenaar17467472015-11-10 17:50:24 +01001873 if (comma && i > 1
1874 && (flags & P_ONECOMMA) == P_ONECOMMA
1875 && origval[i - 1] == ','
1876 && origval[i - 2] != '\\')
Bram Moolenaara7b7b1c2015-06-19 14:06:43 +02001877 i--;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001878 mch_memmove(newval + i + comma, newval,
1879 STRLEN(newval) + 1);
1880 mch_memmove(newval, origval, (size_t)i);
1881 }
1882 else
1883 {
1884 i = (int)STRLEN(newval);
Bram Moolenaarc1a11ed2008-06-24 22:09:24 +00001885 STRMOVE(newval + i + comma, origval);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001886 }
1887 if (comma)
1888 newval[i] = ',';
1889 }
1890
1891 /* Remove newval[] from origval[]. (Note: "i" has
1892 * been set above and is used here). */
1893 if (removing)
1894 {
1895 STRCPY(newval, origval);
1896 if (*s)
1897 {
1898 /* may need to remove a comma */
1899 if (flags & P_COMMA)
1900 {
1901 if (s == origval)
1902 {
1903 /* include comma after string */
1904 if (s[i] == ',')
1905 ++i;
1906 }
1907 else
1908 {
1909 /* include comma before string */
1910 --s;
1911 ++i;
1912 }
1913 }
Bram Moolenaarc1a11ed2008-06-24 22:09:24 +00001914 STRMOVE(newval + (s - origval), s + i);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001915 }
1916 }
1917
1918 if (flags & P_FLAGLIST)
1919 {
1920 /* Remove flags that appear twice. */
Bram Moolenaaraaaf57d2017-02-05 14:13:20 +01001921 for (s = newval; *s;)
Bram Moolenaarc8ce6152016-08-07 13:48:20 +02001922 {
1923 /* if options have P_FLAGLIST and
1924 * P_ONECOMMA such as 'whichwrap' */
1925 if (flags & P_ONECOMMA)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001926 {
Bram Moolenaarc8ce6152016-08-07 13:48:20 +02001927 if (*s != ',' && *(s + 1) == ','
1928 && vim_strchr(s + 2, *s) != NULL)
1929 {
1930 /* Remove the duplicated value and
1931 * the next comma. */
1932 STRMOVE(s, s + 2);
Bram Moolenaaraaaf57d2017-02-05 14:13:20 +01001933 continue;
Bram Moolenaarc8ce6152016-08-07 13:48:20 +02001934 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001935 }
Bram Moolenaarc8ce6152016-08-07 13:48:20 +02001936 else
1937 {
1938 if ((!(flags & P_COMMA) || *s != ',')
1939 && vim_strchr(s + 1, *s) != NULL)
1940 {
1941 STRMOVE(s, s + 1);
Bram Moolenaaraaaf57d2017-02-05 14:13:20 +01001942 continue;
Bram Moolenaarc8ce6152016-08-07 13:48:20 +02001943 }
1944 }
Bram Moolenaaraaaf57d2017-02-05 14:13:20 +01001945 ++s;
Bram Moolenaarc8ce6152016-08-07 13:48:20 +02001946 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001947 }
1948
1949 if (save_arg != NULL) /* number for 'whichwrap' */
1950 arg = save_arg;
1951 new_value_alloced = TRUE;
1952 }
1953
Bram Moolenaar8efa0262017-08-20 15:47:20 +02001954 /*
1955 * Set the new value.
1956 */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001957 *(char_u **)(varp) = newval;
1958
Bram Moolenaarf2bd8ef2018-03-04 18:08:14 +01001959#if defined(FEAT_EVAL)
Bram Moolenaar5cbb8db2015-07-17 23:08:29 +02001960 if (!starting
1961# ifdef FEAT_CRYPT
1962 && options[opt_idx].indir != PV_KEY
1963# endif
Bram Moolenaar182a17b2017-06-25 20:57:18 +02001964 && origval != NULL && newval != NULL)
1965 {
Bram Moolenaar53744302015-07-17 17:38:22 +02001966 /* origval may be freed by
1967 * did_set_string_option(), make a copy. */
1968 saved_origval = vim_strsave(origval);
Bram Moolenaar182a17b2017-06-25 20:57:18 +02001969 /* newval (and varp) may become invalid if the
1970 * buffer is closed by autocommands. */
1971 saved_newval = vim_strsave(newval);
Bram Moolenaard7c96872019-06-15 17:12:48 +02001972 if (origval_l != NULL)
1973 saved_origval_l = vim_strsave(origval_l);
1974 if (origval_g != NULL)
1975 saved_origval_g = vim_strsave(origval_g);
Bram Moolenaar182a17b2017-06-25 20:57:18 +02001976 }
Bram Moolenaar53744302015-07-17 17:38:22 +02001977#endif
1978
Bram Moolenaar247bb7e2018-11-20 14:27:07 +01001979 {
1980 long_u *p = insecure_flag(opt_idx, opt_flags);
Bram Moolenaar48f377a2018-12-21 13:03:28 +01001981 int secure_saved = secure;
Bram Moolenaar247bb7e2018-11-20 14:27:07 +01001982
1983 // When an option is set in the sandbox, from a
1984 // modeline or in secure mode, then deal with side
1985 // effects in secure mode. Also when the value was
1986 // set with the P_INSECURE flag and is not
1987 // completely replaced.
Bram Moolenaar82b033e2019-03-24 14:02:04 +01001988 if ((opt_flags & OPT_MODELINE)
Bram Moolenaar247bb7e2018-11-20 14:27:07 +01001989#ifdef HAVE_SANDBOX
Bram Moolenaar82b033e2019-03-24 14:02:04 +01001990 || sandbox != 0
Bram Moolenaar247bb7e2018-11-20 14:27:07 +01001991#endif
Bram Moolenaar82b033e2019-03-24 14:02:04 +01001992 || (!value_is_replaced && (*p & P_INSECURE)))
1993 secure = 1;
Bram Moolenaar247bb7e2018-11-20 14:27:07 +01001994
Bram Moolenaar48f377a2018-12-21 13:03:28 +01001995 // Handle side effects, and set the global value
1996 // for ":set" on local options. Note: when setting
1997 // 'syntax' or 'filetype' autocommands may be
1998 // triggered that can cause havoc.
1999 errmsg = did_set_string_option(
2000 opt_idx, (char_u **)varp,
Bram Moolenaar916a8182018-11-25 02:18:29 +01002001 new_value_alloced, oldval, errbuf,
2002 opt_flags, &value_checked);
Bram Moolenaar247bb7e2018-11-20 14:27:07 +01002003
Bram Moolenaar48f377a2018-12-21 13:03:28 +01002004 secure = secure_saved;
Bram Moolenaar247bb7e2018-11-20 14:27:07 +01002005 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002006
Bram Moolenaarf2bd8ef2018-03-04 18:08:14 +01002007#if defined(FEAT_EVAL)
Bram Moolenaar8efa0262017-08-20 15:47:20 +02002008 if (errmsg == NULL)
Bram Moolenaard7c96872019-06-15 17:12:48 +02002009 trigger_optionsset_string(
2010 opt_idx, opt_flags, saved_origval,
2011 saved_origval_l, saved_origval_g,
2012 saved_newval);
Bram Moolenaar8efa0262017-08-20 15:47:20 +02002013 vim_free(saved_origval);
Bram Moolenaard7c96872019-06-15 17:12:48 +02002014 vim_free(saved_origval_l);
2015 vim_free(saved_origval_g);
Bram Moolenaar8efa0262017-08-20 15:47:20 +02002016 vim_free(saved_newval);
2017#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00002018 /* If error detected, print the error message. */
2019 if (errmsg != NULL)
2020 goto skip;
2021 }
2022 else /* key code option */
2023 {
2024 char_u *p;
2025
2026 if (nextchar == '&')
2027 {
2028 if (add_termcap_entry(key_name, TRUE) == FAIL)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002029 errmsg = N_("E522: Not found in termcap");
Bram Moolenaar071d4272004-06-13 20:20:40 +00002030 }
2031 else
2032 {
2033 ++arg; /* jump to after the '=' or ':' */
Bram Moolenaar1c465442017-03-12 20:10:05 +01002034 for (p = arg; *p && !VIM_ISWHITE(*p); ++p)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002035 if (*p == '\\' && p[1] != NUL)
2036 ++p;
2037 nextchar = *p;
2038 *p = NUL;
2039 add_termcode(key_name, arg, FALSE);
2040 *p = nextchar;
2041 }
2042 if (full_screen)
2043 ttest(FALSE);
2044 redraw_all_later(CLEAR);
2045 }
2046 }
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002047
Bram Moolenaar071d4272004-06-13 20:20:40 +00002048 if (opt_idx >= 0)
Bram Moolenaar916a8182018-11-25 02:18:29 +01002049 did_set_option(
2050 opt_idx, opt_flags, value_is_replaced, value_checked);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002051 }
2052
2053skip:
2054 /*
2055 * Advance to next argument.
2056 * - skip until a blank found, taking care of backslashes
2057 * - skip blanks
2058 * - skip one "=val" argument (for hidden options ":set gfn =xx")
2059 */
2060 for (i = 0; i < 2 ; ++i)
2061 {
Bram Moolenaar1c465442017-03-12 20:10:05 +01002062 while (*arg != NUL && !VIM_ISWHITE(*arg))
Bram Moolenaar071d4272004-06-13 20:20:40 +00002063 if (*arg++ == '\\' && *arg != NUL)
2064 ++arg;
2065 arg = skipwhite(arg);
2066 if (*arg != '=')
2067 break;
2068 }
2069 }
2070
2071 if (errmsg != NULL)
2072 {
Bram Moolenaarce0842a2005-07-18 21:58:11 +00002073 vim_strncpy(IObuff, (char_u *)_(errmsg), IOSIZE - 1);
Bram Moolenaara93fa7e2006-04-17 22:14:47 +00002074 i = (int)STRLEN(IObuff) + 2;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002075 if (i + (arg - startarg) < IOSIZE)
2076 {
2077 /* append the argument with the error */
2078 STRCAT(IObuff, ": ");
2079 mch_memmove(IObuff + i, startarg, (arg - startarg));
2080 IObuff[i + (arg - startarg)] = NUL;
2081 }
2082 /* make sure all characters are printable */
2083 trans_characters(IObuff, IOSIZE);
2084
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002085 ++no_wait_return; // wait_return done later
2086 emsg((char *)IObuff); // show error highlighted
Bram Moolenaar071d4272004-06-13 20:20:40 +00002087 --no_wait_return;
2088
2089 return FAIL;
2090 }
2091
2092 arg = skipwhite(arg);
2093 }
2094
Bram Moolenaar26a60b42005-02-22 08:49:11 +00002095theend:
2096 if (silent_mode && did_show)
2097 {
2098 /* After displaying option values in silent mode. */
2099 silent_mode = FALSE;
2100 info_message = TRUE; /* use mch_msg(), not mch_errmsg() */
2101 msg_putchar('\n');
2102 cursor_on(); /* msg_start() switches it off */
2103 out_flush();
2104 silent_mode = TRUE;
2105 info_message = FALSE; /* use mch_msg(), not mch_errmsg() */
2106 }
2107
Bram Moolenaar071d4272004-06-13 20:20:40 +00002108 return OK;
2109}
2110
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002111/*
2112 * Call this when an option has been given a new value through a user command.
2113 * Sets the P_WAS_SET flag and takes care of the P_INSECURE flag.
2114 */
Bram Moolenaardac13472019-09-16 21:06:21 +02002115 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01002116did_set_option(
2117 int opt_idx,
Bram Moolenaar916a8182018-11-25 02:18:29 +01002118 int opt_flags, // possibly with OPT_MODELINE
2119 int new_value, // value was replaced completely
2120 int value_checked) // value was checked to be safe, no need to set the
2121 // P_INSECURE flag.
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002122{
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002123 long_u *p;
2124
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002125 options[opt_idx].flags |= P_WAS_SET;
2126
2127 /* When an option is set in the sandbox, from a modeline or in secure mode
2128 * set the P_INSECURE flag. Otherwise, if a new value is stored reset the
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002129 * flag. */
2130 p = insecure_flag(opt_idx, opt_flags);
Bram Moolenaar916a8182018-11-25 02:18:29 +01002131 if (!value_checked && (secure
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002132#ifdef HAVE_SANDBOX
2133 || sandbox != 0
2134#endif
Bram Moolenaar916a8182018-11-25 02:18:29 +01002135 || (opt_flags & OPT_MODELINE)))
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002136 *p = *p | P_INSECURE;
2137 else if (new_value)
2138 *p = *p & ~P_INSECURE;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002139}
2140
Bram Moolenaar071d4272004-06-13 20:20:40 +00002141/*
2142 * Convert a key name or string into a key value.
2143 * Used for 'wildchar' and 'cedit' options.
Bram Moolenaardbe948d2017-07-23 22:50:51 +02002144 * When "multi_byte" is TRUE allow for multi-byte characters.
Bram Moolenaar071d4272004-06-13 20:20:40 +00002145 */
Bram Moolenaardbe948d2017-07-23 22:50:51 +02002146 int
2147string_to_key(char_u *arg, int multi_byte)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002148{
2149 if (*arg == '<')
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02002150 return find_key_option(arg + 1, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002151 if (*arg == '^')
2152 return Ctrl_chr(arg[1]);
Bram Moolenaardbe948d2017-07-23 22:50:51 +02002153 if (multi_byte)
2154 return PTR2CHAR(arg);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002155 return *arg;
2156}
2157
Bram Moolenaardac13472019-09-16 21:06:21 +02002158#if defined(FEAT_CMDWIN) || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002159/*
2160 * Check value of 'cedit' and set cedit_key.
2161 * Returns NULL if value is OK, error message otherwise.
2162 */
Bram Moolenaardac13472019-09-16 21:06:21 +02002163 char *
Bram Moolenaar9b578142016-01-30 19:39:49 +01002164check_cedit(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002165{
2166 int n;
2167
2168 if (*p_cedit == NUL)
2169 cedit_key = -1;
2170 else
2171 {
Bram Moolenaardbe948d2017-07-23 22:50:51 +02002172 n = string_to_key(p_cedit, FALSE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002173 if (vim_isprintc(n))
2174 return e_invarg;
2175 cedit_key = n;
2176 }
2177 return NULL;
2178}
2179#endif
2180
2181#ifdef FEAT_TITLE
2182/*
2183 * When changing 'title', 'titlestring', 'icon' or 'iconstring', call
2184 * maketitle() to create and display it.
2185 * When switching the title or icon off, call mch_restore_title() to get
2186 * the old value back.
2187 */
Bram Moolenaardac13472019-09-16 21:06:21 +02002188 void
Bram Moolenaar84a93082018-06-16 22:58:15 +02002189did_set_title(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002190{
2191 if (starting != NO_SCREEN
2192#ifdef FEAT_GUI
2193 && !gui.starting
2194#endif
2195 )
Bram Moolenaar071d4272004-06-13 20:20:40 +00002196 maketitle();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002197}
2198#endif
2199
2200/*
2201 * set_options_bin - called when 'bin' changes value.
2202 */
2203 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01002204set_options_bin(
2205 int oldval,
2206 int newval,
2207 int opt_flags) /* OPT_LOCAL and/or OPT_GLOBAL */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002208{
2209 /*
2210 * The option values that are changed when 'bin' changes are
2211 * copied when 'bin is set and restored when 'bin' is reset.
2212 */
2213 if (newval)
2214 {
2215 if (!oldval) /* switched on */
2216 {
2217 if (!(opt_flags & OPT_GLOBAL))
2218 {
2219 curbuf->b_p_tw_nobin = curbuf->b_p_tw;
2220 curbuf->b_p_wm_nobin = curbuf->b_p_wm;
2221 curbuf->b_p_ml_nobin = curbuf->b_p_ml;
2222 curbuf->b_p_et_nobin = curbuf->b_p_et;
2223 }
2224 if (!(opt_flags & OPT_LOCAL))
2225 {
2226 p_tw_nobin = p_tw;
2227 p_wm_nobin = p_wm;
2228 p_ml_nobin = p_ml;
2229 p_et_nobin = p_et;
2230 }
2231 }
2232
2233 if (!(opt_flags & OPT_GLOBAL))
2234 {
2235 curbuf->b_p_tw = 0; /* no automatic line wrap */
2236 curbuf->b_p_wm = 0; /* no automatic line wrap */
2237 curbuf->b_p_ml = 0; /* no modelines */
2238 curbuf->b_p_et = 0; /* no expandtab */
2239 }
2240 if (!(opt_flags & OPT_LOCAL))
2241 {
2242 p_tw = 0;
2243 p_wm = 0;
2244 p_ml = FALSE;
2245 p_et = FALSE;
2246 p_bin = TRUE; /* needed when called for the "-b" argument */
2247 }
2248 }
2249 else if (oldval) /* switched off */
2250 {
2251 if (!(opt_flags & OPT_GLOBAL))
2252 {
2253 curbuf->b_p_tw = curbuf->b_p_tw_nobin;
2254 curbuf->b_p_wm = curbuf->b_p_wm_nobin;
2255 curbuf->b_p_ml = curbuf->b_p_ml_nobin;
2256 curbuf->b_p_et = curbuf->b_p_et_nobin;
2257 }
2258 if (!(opt_flags & OPT_LOCAL))
2259 {
2260 p_tw = p_tw_nobin;
2261 p_wm = p_wm_nobin;
2262 p_ml = p_ml_nobin;
2263 p_et = p_et_nobin;
2264 }
2265 }
2266}
2267
Bram Moolenaar071d4272004-06-13 20:20:40 +00002268/*
2269 * Expand environment variables for some string options.
2270 * These string options cannot be indirect!
2271 * If "val" is NULL expand the current value of the option.
2272 * Return pointer to NameBuff, or NULL when not expanded.
2273 */
2274 static char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01002275option_expand(int opt_idx, char_u *val)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002276{
2277 /* if option doesn't need expansion nothing to do */
2278 if (!(options[opt_idx].flags & P_EXPAND) || options[opt_idx].var == NULL)
2279 return NULL;
2280
2281 /* If val is longer than MAXPATHL no meaningful expansion can be done,
2282 * expand_env() would truncate the string. */
2283 if (val != NULL && STRLEN(val) > MAXPATHL)
2284 return NULL;
2285
2286 if (val == NULL)
2287 val = *(char_u **)options[opt_idx].var;
2288
2289 /*
2290 * Expanding this with NameBuff, expand_env() must not be passed IObuff.
2291 * Escape spaces when expanding 'tags', they are used to separate file
2292 * names.
Bram Moolenaar24bbcfe2005-06-28 23:32:02 +00002293 * For 'spellsuggest' expand after "file:".
Bram Moolenaar071d4272004-06-13 20:20:40 +00002294 */
2295 expand_env_esc(val, NameBuff, MAXPATHL,
Bram Moolenaar9f0545d2007-09-26 20:36:32 +00002296 (char_u **)options[opt_idx].var == &p_tags, FALSE,
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00002297#ifdef FEAT_SPELL
Bram Moolenaar24bbcfe2005-06-28 23:32:02 +00002298 (char_u **)options[opt_idx].var == &p_sps ? (char_u *)"file:" :
2299#endif
2300 NULL);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002301 if (STRCMP(NameBuff, val) == 0) /* they are the same */
2302 return NULL;
2303
2304 return NameBuff;
2305}
2306
2307/*
2308 * After setting various option values: recompute variables that depend on
2309 * option values.
2310 */
2311 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01002312didset_options(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002313{
2314 /* initialize the table for 'iskeyword' et.al. */
2315 (void)init_chartab();
2316
Bram Moolenaardac13472019-09-16 21:06:21 +02002317 didset_string_options();
2318
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00002319#ifdef FEAT_SPELL
Bram Moolenaar8aff23a2005-08-19 20:40:30 +00002320 (void)spell_check_msm();
Bram Moolenaar24bbcfe2005-06-28 23:32:02 +00002321 (void)spell_check_sps();
Bram Moolenaar860cae12010-06-05 23:22:07 +02002322 (void)compile_cap_prog(curwin->w_s);
Bram Moolenaare68c25c2015-08-25 15:39:55 +02002323 (void)did_set_spell_option(TRUE);
Bram Moolenaard857f0e2005-06-21 22:37:39 +00002324#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00002325#ifdef FEAT_CMDWIN
Bram Moolenaar010ee962019-09-25 20:37:36 +02002326 // set cedit_key
Bram Moolenaar071d4272004-06-13 20:20:40 +00002327 (void)check_cedit();
2328#endif
Bram Moolenaar597a4222014-06-25 14:39:50 +02002329#ifdef FEAT_LINEBREAK
Bram Moolenaare68c25c2015-08-25 15:39:55 +02002330 /* initialize the table for 'breakat'. */
2331 fill_breakat_flags();
2332#endif
Bram Moolenaar010ee962019-09-25 20:37:36 +02002333 after_copy_winopt(curwin);
Bram Moolenaare68c25c2015-08-25 15:39:55 +02002334}
2335
2336/*
2337 * More side effects of setting options.
2338 */
2339 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01002340didset_options2(void)
Bram Moolenaare68c25c2015-08-25 15:39:55 +02002341{
2342 /* Initialize the highlight_attr[] table. */
2343 (void)highlight_changed();
2344
2345 /* Parse default for 'wildmode' */
2346 check_opt_wim();
2347
2348 (void)set_chars_option(&p_lcs);
Bram Moolenaare68c25c2015-08-25 15:39:55 +02002349 /* Parse default for 'fillchars'. */
2350 (void)set_chars_option(&p_fcs);
Bram Moolenaare68c25c2015-08-25 15:39:55 +02002351
2352#ifdef FEAT_CLIPBOARD
2353 /* Parse default for 'clipboard' */
2354 (void)check_clipboard_option();
2355#endif
Bram Moolenaar04958cb2018-06-23 19:23:02 +02002356#ifdef FEAT_VARTABS
Bram Moolenaar55c77cf2019-02-16 19:05:11 +01002357 vim_free(curbuf->b_p_vsts_array);
Bram Moolenaar04958cb2018-06-23 19:23:02 +02002358 tabstop_set(curbuf->b_p_vsts, &curbuf->b_p_vsts_array);
Bram Moolenaar55c77cf2019-02-16 19:05:11 +01002359 vim_free(curbuf->b_p_vts_array);
Bram Moolenaar04958cb2018-06-23 19:23:02 +02002360 tabstop_set(curbuf->b_p_vts, &curbuf->b_p_vts_array);
2361#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00002362}
2363
2364/*
2365 * Check for string options that are NULL (normally only termcap options).
2366 */
2367 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01002368check_options(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002369{
2370 int opt_idx;
2371
2372 for (opt_idx = 0; options[opt_idx].fullname != NULL; opt_idx++)
2373 if ((options[opt_idx].flags & P_STRING) && options[opt_idx].var != NULL)
2374 check_string_option((char_u **)get_varp(&(options[opt_idx])));
2375}
2376
2377/*
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02002378 * Return the option index found by a pointer into term_strings[].
2379 * Return -1 if not found.
Bram Moolenaar071d4272004-06-13 20:20:40 +00002380 */
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02002381 int
2382get_term_opt_idx(char_u **p)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002383{
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02002384 int opt_idx;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002385
2386 for (opt_idx = 1; options[opt_idx].fullname != NULL; opt_idx++)
2387 if (options[opt_idx].var == (char_u *)p)
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02002388 return opt_idx;
2389 return -1; // cannot happen: didn't find it!
2390}
2391
2392/*
2393 * Mark a terminal option as allocated, found by a pointer into term_strings[].
2394 * Return the option index or -1 if not found.
2395 */
2396 int
2397set_term_option_alloced(char_u **p)
2398{
2399 int opt_idx = get_term_opt_idx(p);
2400
2401 if (opt_idx >= 0)
2402 options[opt_idx].flags |= P_ALLOCED;
2403 return opt_idx;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002404}
2405
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002406#if defined(FEAT_EVAL) || defined(PROTO)
2407/*
2408 * Return TRUE when option "opt" was set from a modeline or in secure mode.
2409 * Return FALSE when it wasn't.
2410 * Return -1 for an unknown option.
2411 */
2412 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01002413was_set_insecurely(char_u *opt, int opt_flags)
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002414{
2415 int idx = findoption(opt);
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002416 long_u *flagp;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002417
2418 if (idx >= 0)
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002419 {
2420 flagp = insecure_flag(idx, opt_flags);
2421 return (*flagp & P_INSECURE) != 0;
2422 }
Bram Moolenaar95f09602016-11-10 20:01:45 +01002423 internal_error("was_set_insecurely()");
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002424 return -1;
2425}
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002426
2427/*
2428 * Get a pointer to the flags used for the P_INSECURE flag of option
2429 * "opt_idx". For some local options a local flags field is used.
2430 */
2431 static long_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01002432insecure_flag(int opt_idx, int opt_flags)
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002433{
2434 if (opt_flags & OPT_LOCAL)
2435 switch ((int)options[opt_idx].indir)
2436 {
2437#ifdef FEAT_STL_OPT
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002438 case PV_STL: return &curwin->w_p_stl_flags;
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002439#endif
2440#ifdef FEAT_EVAL
Bram Moolenaar2e978902006-05-13 12:37:50 +00002441# ifdef FEAT_FOLDING
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002442 case PV_FDE: return &curwin->w_p_fde_flags;
2443 case PV_FDT: return &curwin->w_p_fdt_flags;
Bram Moolenaar2e978902006-05-13 12:37:50 +00002444# endif
Bram Moolenaar9b2200a2006-03-20 21:55:45 +00002445# ifdef FEAT_BEVAL
2446 case PV_BEXPR: return &curbuf->b_p_bexpr_flags;
2447# endif
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002448# if defined(FEAT_CINDENT)
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002449 case PV_INDE: return &curbuf->b_p_inde_flags;
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002450# endif
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002451 case PV_FEX: return &curbuf->b_p_fex_flags;
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002452# ifdef FEAT_FIND_ID
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002453 case PV_INEX: return &curbuf->b_p_inex_flags;
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002454# endif
2455#endif
2456 }
2457
2458 /* Nothing special, return global flags field. */
2459 return &options[opt_idx].flags;
2460}
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002461#endif
2462
Bram Moolenaardac13472019-09-16 21:06:21 +02002463#if defined(FEAT_TITLE) || defined(PROTO)
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002464/*
2465 * Redraw the window title and/or tab page text later.
2466 */
Bram Moolenaardac13472019-09-16 21:06:21 +02002467void redraw_titles(void)
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002468{
2469 need_maketitle = TRUE;
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002470 redraw_tabline = TRUE;
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002471}
2472#endif
2473
Bram Moolenaar071d4272004-06-13 20:20:40 +00002474/*
Bram Moolenaar8f130ed2019-04-10 22:15:19 +02002475 * Return TRUE if "val" is a valid name: only consists of alphanumeric ASCII
2476 * characters or characters in "allowed".
2477 */
Bram Moolenaare677df82019-09-02 22:31:11 +02002478 int
Bram Moolenaar8f130ed2019-04-10 22:15:19 +02002479valid_name(char_u *val, char *allowed)
2480{
2481 char_u *s;
2482
2483 for (s = val; *s != NUL; ++s)
2484 if (!ASCII_ISALNUM(*s) && vim_strchr((char_u *)allowed, *s) == NULL)
2485 return FALSE;
2486 return TRUE;
2487}
2488
Bram Moolenaardac13472019-09-16 21:06:21 +02002489#if defined(FEAT_CLIPBOARD) || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002490/*
2491 * Extract the items in the 'clipboard' option and set global values.
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002492 * Return an error message or NULL for success.
Bram Moolenaar071d4272004-06-13 20:20:40 +00002493 */
Bram Moolenaardac13472019-09-16 21:06:21 +02002494 char *
Bram Moolenaar9b578142016-01-30 19:39:49 +01002495check_clipboard_option(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002496{
Bram Moolenaarbf9680e2010-12-02 21:43:16 +01002497 int new_unnamed = 0;
Bram Moolenaar89af4392012-07-10 18:31:54 +02002498 int new_autoselect_star = FALSE;
2499 int new_autoselect_plus = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002500 int new_autoselectml = FALSE;
Bram Moolenaar3a6eaa52009-06-16 13:23:06 +00002501 int new_html = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002502 regprog_T *new_exclude_prog = NULL;
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002503 char *errmsg = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002504 char_u *p;
2505
2506 for (p = p_cb; *p != NUL; )
2507 {
2508 if (STRNCMP(p, "unnamed", 7) == 0 && (p[7] == ',' || p[7] == NUL))
2509 {
Bram Moolenaarbf9680e2010-12-02 21:43:16 +01002510 new_unnamed |= CLIP_UNNAMED;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002511 p += 7;
2512 }
Bram Moolenaar11b73d62012-06-29 15:51:30 +02002513 else if (STRNCMP(p, "unnamedplus", 11) == 0
Bram Moolenaarbf9680e2010-12-02 21:43:16 +01002514 && (p[11] == ',' || p[11] == NUL))
2515 {
2516 new_unnamed |= CLIP_UNNAMED_PLUS;
2517 p += 11;
2518 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002519 else if (STRNCMP(p, "autoselect", 10) == 0
Bram Moolenaar89af4392012-07-10 18:31:54 +02002520 && (p[10] == ',' || p[10] == NUL))
Bram Moolenaar071d4272004-06-13 20:20:40 +00002521 {
Bram Moolenaar89af4392012-07-10 18:31:54 +02002522 new_autoselect_star = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002523 p += 10;
2524 }
Bram Moolenaar89af4392012-07-10 18:31:54 +02002525 else if (STRNCMP(p, "autoselectplus", 14) == 0
2526 && (p[14] == ',' || p[14] == NUL))
2527 {
2528 new_autoselect_plus = TRUE;
2529 p += 14;
2530 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002531 else if (STRNCMP(p, "autoselectml", 12) == 0
Bram Moolenaar89af4392012-07-10 18:31:54 +02002532 && (p[12] == ',' || p[12] == NUL))
Bram Moolenaar071d4272004-06-13 20:20:40 +00002533 {
2534 new_autoselectml = TRUE;
2535 p += 12;
2536 }
Bram Moolenaar3a6eaa52009-06-16 13:23:06 +00002537 else if (STRNCMP(p, "html", 4) == 0 && (p[4] == ',' || p[4] == NUL))
2538 {
2539 new_html = TRUE;
2540 p += 4;
2541 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002542 else if (STRNCMP(p, "exclude:", 8) == 0 && new_exclude_prog == NULL)
2543 {
2544 p += 8;
2545 new_exclude_prog = vim_regcomp(p, RE_MAGIC);
2546 if (new_exclude_prog == NULL)
2547 errmsg = e_invarg;
2548 break;
2549 }
2550 else
2551 {
2552 errmsg = e_invarg;
2553 break;
2554 }
2555 if (*p == ',')
2556 ++p;
2557 }
2558 if (errmsg == NULL)
2559 {
2560 clip_unnamed = new_unnamed;
Bram Moolenaar89af4392012-07-10 18:31:54 +02002561 clip_autoselect_star = new_autoselect_star;
2562 clip_autoselect_plus = new_autoselect_plus;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002563 clip_autoselectml = new_autoselectml;
Bram Moolenaar3a6eaa52009-06-16 13:23:06 +00002564 clip_html = new_html;
Bram Moolenaar473de612013-06-08 18:19:48 +02002565 vim_regfree(clip_exclude_prog);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002566 clip_exclude_prog = new_exclude_prog;
Bram Moolenaara76638f2010-06-05 12:49:46 +02002567#ifdef FEAT_GUI_GTK
2568 if (gui.in_use)
2569 {
2570 gui_gtk_set_selection_targets();
2571 gui_gtk_set_dnd_targets();
2572 }
2573#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00002574 }
2575 else
Bram Moolenaar473de612013-06-08 18:19:48 +02002576 vim_regfree(new_exclude_prog);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002577
2578 return errmsg;
2579}
2580#endif
2581
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002582#if defined(FEAT_EVAL) || defined(PROTO)
2583/*
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002584 * Set the script_ctx for an option, taking care of setting the buffer- or
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002585 * window-local value.
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002586 */
Bram Moolenaardac13472019-09-16 21:06:21 +02002587 void
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002588set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002589{
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002590 int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
2591 int indir = (int)options[opt_idx].indir;
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002592 sctx_T new_script_ctx = script_ctx;
2593
2594 new_script_ctx.sc_lnum += sourcing_lnum;
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002595
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002596 /* Remember where the option was set. For local options need to do that
2597 * in the buffer or window structure. */
2598 if (both || (opt_flags & OPT_GLOBAL) || (indir & (PV_BUF|PV_WIN)) == 0)
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002599 options[opt_idx].script_ctx = new_script_ctx;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002600 if (both || (opt_flags & OPT_LOCAL))
2601 {
2602 if (indir & PV_BUF)
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002603 curbuf->b_p_script_ctx[indir & PV_MASK] = new_script_ctx;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002604 else if (indir & PV_WIN)
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002605 curwin->w_p_script_ctx[indir & PV_MASK] = new_script_ctx;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002606 }
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002607}
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02002608
2609/*
2610 * Set the script_ctx for a termcap option.
2611 * "name" must be the two character code, e.g. "RV".
2612 * When "name" is NULL use "opt_idx".
2613 */
2614 void
2615set_term_option_sctx_idx(char *name, int opt_idx)
2616{
2617 char_u buf[5];
2618 int idx;
2619
2620 if (name == NULL)
2621 idx = opt_idx;
2622 else
2623 {
2624 buf[0] = 't';
2625 buf[1] = '_';
2626 buf[2] = name[0];
2627 buf[3] = name[1];
2628 buf[4] = 0;
2629 idx = findoption(buf);
2630 }
2631 if (idx >= 0)
2632 set_option_sctx_idx(idx, OPT_GLOBAL, current_sctx);
2633}
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002634#endif
2635
Bram Moolenaar071d4272004-06-13 20:20:40 +00002636/*
2637 * Set the value of a boolean option, and take care of side effects.
2638 * Returns NULL for success, or an error message for an error.
2639 */
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002640 static char *
Bram Moolenaar9b578142016-01-30 19:39:49 +01002641set_bool_option(
2642 int opt_idx, /* index in options[] table */
2643 char_u *varp, /* pointer to the option variable */
2644 int value, /* new value */
2645 int opt_flags) /* OPT_LOCAL and/or OPT_GLOBAL */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002646{
2647 int old_value = *(int *)varp;
Bram Moolenaar983f2f12019-06-16 16:41:41 +02002648#if defined(FEAT_EVAL)
Bram Moolenaard7c96872019-06-15 17:12:48 +02002649 int old_global_value = 0;
Bram Moolenaar983f2f12019-06-16 16:41:41 +02002650#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00002651
Bram Moolenaar071d4272004-06-13 20:20:40 +00002652 /* Disallow changing some options from secure mode */
2653 if ((secure
2654#ifdef HAVE_SANDBOX
2655 || sandbox != 0
2656#endif
2657 ) && (options[opt_idx].flags & P_SECURE))
2658 return e_secure;
2659
Bram Moolenaar983f2f12019-06-16 16:41:41 +02002660#if defined(FEAT_EVAL)
Bram Moolenaard7c96872019-06-15 17:12:48 +02002661 // Save the global value before changing anything. This is needed as for
2662 // a global-only option setting the "local value" in fact sets the global
2663 // value (since there is only one value).
2664 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
2665 old_global_value = *(int *)get_varp_scope(&(options[opt_idx]),
2666 OPT_GLOBAL);
Bram Moolenaar983f2f12019-06-16 16:41:41 +02002667#endif
Bram Moolenaard7c96872019-06-15 17:12:48 +02002668
Bram Moolenaar071d4272004-06-13 20:20:40 +00002669 *(int *)varp = value; /* set the new value */
2670#ifdef FEAT_EVAL
2671 /* Remember where the option was set. */
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002672 set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002673#endif
2674
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002675#ifdef FEAT_GUI
2676 need_mouse_correct = TRUE;
2677#endif
2678
Bram Moolenaar071d4272004-06-13 20:20:40 +00002679 /* May set global value for local option. */
2680 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
2681 *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = value;
2682
2683 /*
2684 * Handle side effects of changing a bool option.
2685 */
2686
2687 /* 'compatible' */
2688 if ((int *)varp == &p_cp)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002689 compatible_set();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002690
Bram Moolenaar920694c2016-08-21 17:45:02 +02002691#ifdef FEAT_LANGMAP
2692 if ((int *)varp == &p_lrm)
2693 /* 'langremap' -> !'langnoremap' */
2694 p_lnr = !p_lrm;
2695 else if ((int *)varp == &p_lnr)
2696 /* 'langnoremap' -> !'langremap' */
2697 p_lrm = !p_lnr;
2698#endif
2699
Bram Moolenaar8c63e0e2018-09-25 22:17:54 +02002700#ifdef FEAT_SYN_HL
2701 else if ((int *)varp == &curwin->w_p_cul && !value && old_value)
2702 reset_cursorline();
2703#endif
2704
Bram Moolenaar374d32d2012-01-04 19:34:37 +01002705#ifdef FEAT_PERSISTENT_UNDO
2706 /* 'undofile' */
2707 else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf)
2708 {
Bram Moolenaare8d8fd22012-10-21 03:46:05 +02002709 /* Only take action when the option was set. When reset we do not
2710 * delete the undo file, the option may be set again without making
2711 * any changes in between. */
2712 if (curbuf->b_p_udf || p_udf)
Bram Moolenaar374d32d2012-01-04 19:34:37 +01002713 {
Bram Moolenaare8d8fd22012-10-21 03:46:05 +02002714 char_u hash[UNDO_HASH_SIZE];
2715 buf_T *save_curbuf = curbuf;
2716
Bram Moolenaar29323592016-07-24 22:04:11 +02002717 FOR_ALL_BUFFERS(curbuf)
Bram Moolenaar374d32d2012-01-04 19:34:37 +01002718 {
Bram Moolenaare8d8fd22012-10-21 03:46:05 +02002719 /* When 'undofile' is set globally: for every buffer, otherwise
2720 * only for the current buffer: Try to read in the undofile,
2721 * if one exists, the buffer wasn't changed and the buffer was
2722 * loaded */
2723 if ((curbuf == save_curbuf
2724 || (opt_flags & OPT_GLOBAL) || opt_flags == 0)
2725 && !curbufIsChanged() && curbuf->b_ml.ml_mfp != NULL)
2726 {
2727 u_compute_hash(hash);
2728 u_read_undo(NULL, hash, curbuf->b_fname);
2729 }
Bram Moolenaar374d32d2012-01-04 19:34:37 +01002730 }
Bram Moolenaare8d8fd22012-10-21 03:46:05 +02002731 curbuf = save_curbuf;
Bram Moolenaar374d32d2012-01-04 19:34:37 +01002732 }
Bram Moolenaar374d32d2012-01-04 19:34:37 +01002733 }
2734#endif
2735
Bram Moolenaar071d4272004-06-13 20:20:40 +00002736 else if ((int *)varp == &curbuf->b_p_ro)
2737 {
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +00002738 /* when 'readonly' is reset globally, also reset readonlymode */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002739 if (!curbuf->b_p_ro && (opt_flags & OPT_LOCAL) == 0)
2740 readonlymode = FALSE;
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +00002741
2742 /* when 'readonly' is set may give W10 again */
2743 if (curbuf->b_p_ro)
2744 curbuf->b_did_warn = FALSE;
2745
Bram Moolenaar071d4272004-06-13 20:20:40 +00002746#ifdef FEAT_TITLE
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002747 redraw_titles();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002748#endif
2749 }
2750
Bram Moolenaar9c449722010-07-20 18:44:27 +02002751#ifdef FEAT_GUI
2752 else if ((int *)varp == &p_mh)
2753 {
2754 if (!p_mh)
2755 gui_mch_mousehide(FALSE);
2756 }
2757#endif
2758
Bram Moolenaara539df02010-08-01 14:35:05 +02002759 /* when 'modifiable' is changed, redraw the window title */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002760 else if ((int *)varp == &curbuf->b_p_ma)
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002761 {
Bram Moolenaar423802d2017-07-30 16:52:24 +02002762# ifdef FEAT_TERMINAL
2763 /* Cannot set 'modifiable' when in Terminal mode. */
Bram Moolenaard7db27b2018-03-07 23:02:33 +01002764 if (curbuf->b_p_ma && (term_in_normal_mode() || (bt_terminal(curbuf)
2765 && curbuf->b_term != NULL && !term_is_finished(curbuf))))
Bram Moolenaar423802d2017-07-30 16:52:24 +02002766 {
2767 curbuf->b_p_ma = FALSE;
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002768 return N_("E946: Cannot make a terminal with running job modifiable");
Bram Moolenaar423802d2017-07-30 16:52:24 +02002769 }
2770# endif
2771# ifdef FEAT_TITLE
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002772 redraw_titles();
Bram Moolenaar423802d2017-07-30 16:52:24 +02002773# endif
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002774 }
Bram Moolenaar423802d2017-07-30 16:52:24 +02002775#ifdef FEAT_TITLE
Bram Moolenaar071d4272004-06-13 20:20:40 +00002776 /* when 'endofline' is changed, redraw the window title */
2777 else if ((int *)varp == &curbuf->b_p_eol)
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002778 {
2779 redraw_titles();
2780 }
Bram Moolenaar34d72d42015-07-17 14:18:08 +02002781 /* when 'fixeol' is changed, redraw the window title */
2782 else if ((int *)varp == &curbuf->b_p_fixeol)
2783 {
2784 redraw_titles();
2785 }
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002786 /* when 'bomb' is changed, redraw the window title and tab page text */
Bram Moolenaar83eb8852007-08-12 13:51:26 +00002787 else if ((int *)varp == &curbuf->b_p_bomb)
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002788 {
2789 redraw_titles();
2790 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002791#endif
2792
2793 /* when 'bin' is set also set some other options */
2794 else if ((int *)varp == &curbuf->b_p_bin)
2795 {
2796 set_options_bin(old_value, curbuf->b_p_bin, opt_flags);
2797#ifdef FEAT_TITLE
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002798 redraw_titles();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002799#endif
2800 }
2801
Bram Moolenaar071d4272004-06-13 20:20:40 +00002802 /* when 'buflisted' changes, trigger autocommands */
2803 else if ((int *)varp == &curbuf->b_p_bl && old_value != curbuf->b_p_bl)
2804 {
2805 apply_autocmds(curbuf->b_p_bl ? EVENT_BUFADD : EVENT_BUFDELETE,
2806 NULL, NULL, TRUE, curbuf);
2807 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002808
2809 /* when 'swf' is set, create swapfile, when reset remove swapfile */
2810 else if ((int *)varp == &curbuf->b_p_swf)
2811 {
2812 if (curbuf->b_p_swf && p_uc)
2813 ml_open_file(curbuf); /* create the swap file */
2814 else
Bram Moolenaard55de222007-05-06 13:38:48 +00002815 /* no need to reset curbuf->b_may_swap, ml_open_file() will check
2816 * buf->b_p_swf */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002817 mf_close_file(curbuf, TRUE); /* remove the swap file */
2818 }
2819
2820 /* when 'terse' is set change 'shortmess' */
2821 else if ((int *)varp == &p_terse)
2822 {
2823 char_u *p;
2824
2825 p = vim_strchr(p_shm, SHM_SEARCH);
2826
2827 /* insert 's' in p_shm */
2828 if (p_terse && p == NULL)
2829 {
2830 STRCPY(IObuff, p_shm);
2831 STRCAT(IObuff, "s");
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002832 set_string_option_direct((char_u *)"shm", -1, IObuff, OPT_FREE, 0);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002833 }
2834 /* remove 's' from p_shm */
2835 else if (!p_terse && p != NULL)
Bram Moolenaarc1a11ed2008-06-24 22:09:24 +00002836 STRMOVE(p, p + 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002837 }
2838
2839 /* when 'paste' is set or reset also change other options */
2840 else if ((int *)varp == &p_paste)
2841 {
2842 paste_option_changed();
2843 }
2844
2845 /* when 'insertmode' is set from an autocommand need to do work here */
2846 else if ((int *)varp == &p_im)
2847 {
2848 if (p_im)
2849 {
2850 if ((State & INSERT) == 0)
2851 need_start_insertmode = TRUE;
2852 stop_insert_mode = FALSE;
2853 }
Bram Moolenaar00672e12016-06-26 18:38:13 +02002854 /* only reset if it was set previously */
2855 else if (old_value)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002856 {
2857 need_start_insertmode = FALSE;
2858 stop_insert_mode = TRUE;
Bram Moolenaard12f5c12006-01-25 22:10:52 +00002859 if (restart_edit != 0 && mode_displayed)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002860 clear_cmdline = TRUE; /* remove "(insert)" */
2861 restart_edit = 0;
2862 }
2863 }
2864
2865 /* when 'ignorecase' is set or reset and 'hlsearch' is set, redraw */
2866 else if ((int *)varp == &p_ic && p_hls)
2867 {
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00002868 redraw_all_later(SOME_VALID);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002869 }
2870
2871#ifdef FEAT_SEARCH_EXTRA
2872 /* when 'hlsearch' is set or reset: reset no_hlsearch */
2873 else if ((int *)varp == &p_hls)
2874 {
Bram Moolenaar451fc7b2018-04-27 22:53:07 +02002875 set_no_hlsearch(FALSE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002876 }
2877#endif
2878
Bram Moolenaar071d4272004-06-13 20:20:40 +00002879 /* when 'scrollbind' is set: snapshot the current position to avoid a jump
2880 * at the end of normal_cmd() */
2881 else if ((int *)varp == &curwin->w_p_scb)
2882 {
2883 if (curwin->w_p_scb)
Bram Moolenaar04c5c9e2013-07-09 13:44:59 +02002884 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00002885 do_check_scrollbind(FALSE);
Bram Moolenaar04c5c9e2013-07-09 13:44:59 +02002886 curwin->w_scbind_pos = curwin->w_topline;
2887 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002888 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002889
Bram Moolenaar4033c552017-09-16 20:54:51 +02002890#if defined(FEAT_QUICKFIX)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002891 /* There can be only one window with 'previewwindow' set. */
2892 else if ((int *)varp == &curwin->w_p_pvw)
2893 {
2894 if (curwin->w_p_pvw)
2895 {
2896 win_T *win;
2897
Bram Moolenaar29323592016-07-24 22:04:11 +02002898 FOR_ALL_WINDOWS(win)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002899 if (win->w_p_pvw && win != curwin)
2900 {
2901 curwin->w_p_pvw = FALSE;
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002902 return N_("E590: A preview window already exists");
Bram Moolenaar071d4272004-06-13 20:20:40 +00002903 }
2904 }
2905 }
2906#endif
2907
2908 /* when 'textmode' is set or reset also change 'fileformat' */
2909 else if ((int *)varp == &curbuf->b_p_tx)
2910 {
2911 set_fileformat(curbuf->b_p_tx ? EOL_DOS : EOL_UNIX, opt_flags);
2912 }
2913
2914 /* when 'textauto' is set or reset also change 'fileformats' */
2915 else if ((int *)varp == &p_ta)
Bram Moolenaarabab0b02019-03-30 18:47:01 +01002916 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00002917 set_string_option_direct((char_u *)"ffs", -1,
2918 p_ta ? (char_u *)DFLT_FFS_VIM : (char_u *)"",
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002919 OPT_FREE | opt_flags, 0);
Bram Moolenaarabab0b02019-03-30 18:47:01 +01002920 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002921
2922 /*
2923 * When 'lisp' option changes include/exclude '-' in
2924 * keyword characters.
2925 */
2926#ifdef FEAT_LISP
2927 else if (varp == (char_u *)&(curbuf->b_p_lisp))
2928 {
2929 (void)buf_init_chartab(curbuf, FALSE); /* ignore errors */
2930 }
2931#endif
2932
2933#ifdef FEAT_TITLE
2934 /* when 'title' changed, may need to change the title; same for 'icon' */
Bram Moolenaar84a93082018-06-16 22:58:15 +02002935 else if ((int *)varp == &p_title || (int *)varp == &p_icon)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002936 {
Bram Moolenaar84a93082018-06-16 22:58:15 +02002937 did_set_title();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002938 }
2939#endif
2940
2941 else if ((int *)varp == &curbuf->b_changed)
2942 {
2943 if (!value)
2944 save_file_ff(curbuf); /* Buffer is unchanged */
2945#ifdef FEAT_TITLE
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002946 redraw_titles();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002947#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00002948 modified_was_set = value;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002949 }
2950
2951#ifdef BACKSLASH_IN_FILENAME
2952 else if ((int *)varp == &p_ssl)
2953 {
2954 if (p_ssl)
2955 {
2956 psepc = '/';
2957 psepcN = '\\';
2958 pseps[0] = '/';
Bram Moolenaar071d4272004-06-13 20:20:40 +00002959 }
2960 else
2961 {
2962 psepc = '\\';
2963 psepcN = '/';
2964 pseps[0] = '\\';
Bram Moolenaar071d4272004-06-13 20:20:40 +00002965 }
2966
2967 /* need to adjust the file name arguments and buffer names. */
2968 buflist_slash_adjust();
2969 alist_slash_adjust();
2970# ifdef FEAT_EVAL
2971 scriptnames_slash_adjust();
2972# endif
2973 }
2974#endif
2975
2976 /* If 'wrap' is set, set w_leftcol to zero. */
2977 else if ((int *)varp == &curwin->w_p_wrap)
2978 {
2979 if (curwin->w_p_wrap)
2980 curwin->w_leftcol = 0;
2981 }
2982
Bram Moolenaar071d4272004-06-13 20:20:40 +00002983 else if ((int *)varp == &p_ea)
2984 {
2985 if (p_ea && !old_value)
2986 win_equal(curwin, FALSE, 0);
2987 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002988
2989 else if ((int *)varp == &p_wiv)
2990 {
2991 /*
2992 * When 'weirdinvert' changed, set/reset 't_xs'.
2993 * Then set 'weirdinvert' according to value of 't_xs'.
2994 */
2995 if (p_wiv && !old_value)
2996 T_XS = (char_u *)"y";
2997 else if (!p_wiv && old_value)
2998 T_XS = empty_option;
2999 p_wiv = (*T_XS != NUL);
3000 }
3001
Bram Moolenaarc3719bd2017-11-18 22:13:31 +01003002#ifdef FEAT_BEVAL_GUI
Bram Moolenaar071d4272004-06-13 20:20:40 +00003003 else if ((int *)varp == &p_beval)
3004 {
Bram Moolenaar51b0f372017-11-18 18:52:04 +01003005 if (!balloonEvalForTerm)
3006 {
3007 if (p_beval && !old_value)
3008 gui_mch_enable_beval_area(balloonEval);
3009 else if (!p_beval && old_value)
3010 gui_mch_disable_beval_area(balloonEval);
3011 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003012 }
Bram Moolenaar8dff8182006-04-06 20:18:50 +00003013#endif
Bram Moolenaarc3719bd2017-11-18 22:13:31 +01003014#ifdef FEAT_BEVAL_TERM
Bram Moolenaar51b0f372017-11-18 18:52:04 +01003015 else if ((int *)varp == &p_bevalterm)
3016 {
3017 mch_bevalterm_changed();
3018 }
Bram Moolenaarc3719bd2017-11-18 22:13:31 +01003019#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003020
Bram Moolenaar8dff8182006-04-06 20:18:50 +00003021#ifdef FEAT_AUTOCHDIR
Bram Moolenaar071d4272004-06-13 20:20:40 +00003022 else if ((int *)varp == &p_acd)
3023 {
Bram Moolenaar498efdb2006-09-05 14:31:54 +00003024 /* Change directories when the 'acd' option is set now. */
Bram Moolenaar6f470022018-04-10 18:47:20 +02003025 DO_AUTOCHDIR;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003026 }
3027#endif
3028
3029#ifdef FEAT_DIFF
3030 /* 'diff' */
3031 else if ((int *)varp == &curwin->w_p_diff)
3032 {
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00003033 /* May add or remove the buffer from the list of diff buffers. */
3034 diff_buf_adjust(curwin);
3035# ifdef FEAT_FOLDING
Bram Moolenaar071d4272004-06-13 20:20:40 +00003036 if (foldmethodIsDiff(curwin))
3037 foldUpdateAll(curwin);
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00003038# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003039 }
3040#endif
3041
Bram Moolenaarf2bd8ef2018-03-04 18:08:14 +01003042#ifdef HAVE_INPUT_METHOD
Bram Moolenaar071d4272004-06-13 20:20:40 +00003043 /* 'imdisable' */
3044 else if ((int *)varp == &p_imdisable)
3045 {
3046 /* Only de-activate it here, it will be enabled when changing mode. */
3047 if (p_imdisable)
3048 im_set_active(FALSE);
Bram Moolenaar725a9622011-10-12 16:57:13 +02003049 else if (State & INSERT)
3050 /* When the option is set from an autocommand, it may need to take
3051 * effect right away. */
3052 im_set_active(curbuf->b_p_iminsert == B_IMODE_IM);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003053 }
3054#endif
3055
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00003056#ifdef FEAT_SPELL
Bram Moolenaar0cb032e2005-04-23 20:52:00 +00003057 /* 'spell' */
3058 else if ((int *)varp == &curwin->w_p_spell)
3059 {
3060 if (curwin->w_p_spell)
3061 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003062 char *errmsg = did_set_spelllang(curwin);
3063
Bram Moolenaar0cb032e2005-04-23 20:52:00 +00003064 if (errmsg != NULL)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003065 emsg(_(errmsg));
Bram Moolenaar0cb032e2005-04-23 20:52:00 +00003066 }
3067 }
3068#endif
3069
Bram Moolenaar071d4272004-06-13 20:20:40 +00003070#ifdef FEAT_ARABIC
3071 if ((int *)varp == &curwin->w_p_arab)
3072 {
3073 if (curwin->w_p_arab)
3074 {
3075 /*
3076 * 'arabic' is set, handle various sub-settings.
3077 */
3078 if (!p_tbidi)
3079 {
3080 /* set rightleft mode */
3081 if (!curwin->w_p_rl)
3082 {
3083 curwin->w_p_rl = TRUE;
3084 changed_window_setting();
3085 }
3086
3087 /* Enable Arabic shaping (major part of what Arabic requires) */
3088 if (!p_arshape)
3089 {
3090 p_arshape = TRUE;
3091 redraw_later_clear();
3092 }
3093 }
3094
3095 /* Arabic requires a utf-8 encoding, inform the user if its not
3096 * set. */
3097 if (STRCMP(p_enc, "utf-8") != 0)
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00003098 {
Bram Moolenaar496c5262009-03-18 14:42:00 +00003099 static char *w_arabic = N_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'");
3100
Bram Moolenaar8820b482017-03-16 17:23:31 +01003101 msg_source(HL_ATTR(HLF_W));
Bram Moolenaar32526b32019-01-19 17:43:09 +01003102 msg_attr(_(w_arabic), HL_ATTR(HLF_W));
Bram Moolenaar496c5262009-03-18 14:42:00 +00003103#ifdef FEAT_EVAL
3104 set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_arabic), -1);
3105#endif
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00003106 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003107
Bram Moolenaar071d4272004-06-13 20:20:40 +00003108 /* set 'delcombine' */
3109 p_deco = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003110
3111# ifdef FEAT_KEYMAP
3112 /* Force-set the necessary keymap for arabic */
3113 set_option_value((char_u *)"keymap", 0L, (char_u *)"arabic",
3114 OPT_LOCAL);
3115# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003116 }
3117 else
3118 {
3119 /*
3120 * 'arabic' is reset, handle various sub-settings.
3121 */
3122 if (!p_tbidi)
3123 {
3124 /* reset rightleft mode */
3125 if (curwin->w_p_rl)
3126 {
3127 curwin->w_p_rl = FALSE;
3128 changed_window_setting();
3129 }
3130
3131 /* 'arabicshape' isn't reset, it is a global option and
3132 * another window may still need it "on". */
3133 }
3134
3135 /* 'delcombine' isn't reset, it is a global option and another
3136 * window may still want it "on". */
3137
3138# ifdef FEAT_KEYMAP
3139 /* Revert to the default keymap */
3140 curbuf->b_p_iminsert = B_IMODE_NONE;
3141 curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
3142# endif
3143 }
Bram Moolenaar801f8b82009-07-29 13:42:05 +00003144 }
3145
Bram Moolenaar319bdbd2009-09-11 13:20:33 +00003146#endif
3147
Bram Moolenaar44826212019-08-22 21:23:20 +02003148#if defined(FEAT_SIGNS) && defined(FEAT_GUI)
3149 else if (((int *)varp == &curwin->w_p_nu
3150 || (int *)varp == &curwin->w_p_rnu)
3151 && gui.in_use
3152 && (*curwin->w_p_scl == 'n' && *(curwin->w_p_scl + 1) == 'u')
3153 && curbuf->b_signlist != NULL)
3154 {
3155 // If the 'number' or 'relativenumber' options are modified and
3156 // 'signcolumn' is set to 'number', then clear the screen for a full
3157 // refresh. Otherwise the sign icons are not displayed properly in the
3158 // number column. If the 'number' option is set and only the
3159 // 'relativenumber' option is toggled, then don't refresh the screen
3160 // (optimization).
3161 if (!(curwin->w_p_nu && ((int *)varp == &curwin->w_p_rnu)))
3162 redraw_all_later(CLEAR);
3163 }
3164#endif
3165
Bram Moolenaar61be73b2016-04-29 22:59:22 +02003166#ifdef FEAT_TERMGUICOLORS
3167 /* 'termguicolors' */
3168 else if ((int *)varp == &p_tgc)
Bram Moolenaar8a633e32016-04-21 21:10:14 +02003169 {
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003170# ifdef FEAT_VTP
3171 /* Do not turn on 'tgc' when 24-bit colors are not supported. */
Bram Moolenaarafde13b2019-04-28 19:46:49 +02003172 if (
3173# ifdef VIMDLL
3174 !gui.in_use && !gui.starting &&
3175# endif
3176 !has_vtp_working())
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003177 {
3178 p_tgc = 0;
Bram Moolenaaraa5df7e2019-02-03 14:53:10 +01003179 return N_("E954: 24-bit colors are not supported on this environment");
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003180 }
Bram Moolenaarc5cd8852018-05-01 15:47:38 +02003181 if (is_term_win32())
3182 swap_tcap();
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003183# endif
Bram Moolenaar8a633e32016-04-21 21:10:14 +02003184# ifdef FEAT_GUI
3185 if (!gui.in_use && !gui.starting)
3186# endif
3187 highlight_gui_started();
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003188# ifdef FEAT_VTP
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003189 /* reset t_Co */
Bram Moolenaarc5cd8852018-05-01 15:47:38 +02003190 if (is_term_win32())
Bram Moolenaarb0eb14f2018-06-28 15:29:52 +02003191 {
3192 control_console_color_rgb();
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003193 set_termname(T_NAME);
Bram Moolenaarb0eb14f2018-06-28 15:29:52 +02003194 init_highlight(TRUE, FALSE);
3195 }
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003196# endif
Bram Moolenaar8a633e32016-04-21 21:10:14 +02003197 }
3198#endif
3199
Bram Moolenaar071d4272004-06-13 20:20:40 +00003200 /*
3201 * End of handling side effects for bool options.
3202 */
3203
Bram Moolenaar53744302015-07-17 17:38:22 +02003204 /* after handling side effects, call autocommand */
3205
Bram Moolenaar071d4272004-06-13 20:20:40 +00003206 options[opt_idx].flags |= P_WAS_SET;
3207
Bram Moolenaarf2bd8ef2018-03-04 18:08:14 +01003208#if defined(FEAT_EVAL)
Bram Moolenaar3f3fb0b2018-09-21 11:59:32 +02003209 // Don't do this while starting up or recursively.
3210 if (!starting && *get_vim_var_str(VV_OPTION_TYPE) == NUL)
Bram Moolenaar53744302015-07-17 17:38:22 +02003211 {
Bram Moolenaard7c96872019-06-15 17:12:48 +02003212 char_u buf_old[2], buf_old_global[2], buf_new[2], buf_type[7];
Bram Moolenaar3f3fb0b2018-09-21 11:59:32 +02003213
Bram Moolenaarfb9bc482015-07-17 22:04:48 +02003214 vim_snprintf((char *)buf_old, 2, "%d", old_value ? TRUE: FALSE);
Bram Moolenaard7c96872019-06-15 17:12:48 +02003215 vim_snprintf((char *)buf_old_global, 2, "%d",
3216 old_global_value ? TRUE: FALSE);
Bram Moolenaarfb9bc482015-07-17 22:04:48 +02003217 vim_snprintf((char *)buf_new, 2, "%d", value ? TRUE: FALSE);
Bram Moolenaard7c96872019-06-15 17:12:48 +02003218 vim_snprintf((char *)buf_type, 7, "%s",
3219 (opt_flags & OPT_LOCAL) ? "local" : "global");
Bram Moolenaar53744302015-07-17 17:38:22 +02003220 set_vim_var_string(VV_OPTION_NEW, buf_new, -1);
3221 set_vim_var_string(VV_OPTION_OLD, buf_old, -1);
3222 set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
Bram Moolenaard7c96872019-06-15 17:12:48 +02003223 if (opt_flags & OPT_LOCAL)
3224 {
3225 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setlocal", -1);
3226 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
3227 }
3228 if (opt_flags & OPT_GLOBAL)
3229 {
3230 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setglobal", -1);
3231 set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old, -1);
3232 }
3233 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
3234 {
3235 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"set", -1);
3236 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
3237 set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old_global, -1);
3238 }
3239 if (opt_flags & OPT_MODELINE)
3240 {
3241 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"modeline", -1);
3242 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
3243 }
3244 apply_autocmds(EVENT_OPTIONSET, (char_u *)options[opt_idx].fullname,
3245 NULL, FALSE, NULL);
Bram Moolenaar53744302015-07-17 17:38:22 +02003246 reset_v_option_vars();
3247 }
3248#endif
3249
Bram Moolenaar071d4272004-06-13 20:20:40 +00003250 comp_col(); /* in case 'ruler' or 'showcmd' changed */
Bram Moolenaar913077c2012-03-28 19:59:04 +02003251 if (curwin->w_curswant != MAXCOL
Bram Moolenaar488eb262015-03-13 11:23:50 +01003252 && (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0)
Bram Moolenaar913077c2012-03-28 19:59:04 +02003253 curwin->w_set_curswant = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003254 check_redraw(options[opt_idx].flags);
3255
3256 return NULL;
3257}
3258
3259/*
3260 * Set the value of a number option, and take care of side effects.
3261 * Returns NULL for success, or an error message for an error.
3262 */
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003263 static char *
Bram Moolenaar9b578142016-01-30 19:39:49 +01003264set_num_option(
3265 int opt_idx, /* index in options[] table */
3266 char_u *varp, /* pointer to the option variable */
3267 long value, /* new value */
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003268 char *errbuf, /* buffer for error messages */
Bram Moolenaar9b578142016-01-30 19:39:49 +01003269 size_t errbuflen, /* length of "errbuf" */
3270 int opt_flags) /* OPT_LOCAL, OPT_GLOBAL and
Bram Moolenaar071d4272004-06-13 20:20:40 +00003271 OPT_MODELINE */
3272{
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003273 char *errmsg = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003274 long old_value = *(long *)varp;
Bram Moolenaar983f2f12019-06-16 16:41:41 +02003275#if defined(FEAT_EVAL)
Bram Moolenaard7c96872019-06-15 17:12:48 +02003276 long old_global_value = 0; // only used when setting a local and
3277 // global option
Bram Moolenaar983f2f12019-06-16 16:41:41 +02003278#endif
Bram Moolenaard7c96872019-06-15 17:12:48 +02003279 long old_Rows = Rows; // remember old Rows
3280 long old_Columns = Columns; // remember old Columns
Bram Moolenaar071d4272004-06-13 20:20:40 +00003281 long *pp = (long *)varp;
3282
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00003283 /* Disallow changing some options from secure mode. */
3284 if ((secure
3285#ifdef HAVE_SANDBOX
3286 || sandbox != 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00003287#endif
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00003288 ) && (options[opt_idx].flags & P_SECURE))
3289 return e_secure;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003290
Bram Moolenaar983f2f12019-06-16 16:41:41 +02003291#if defined(FEAT_EVAL)
Bram Moolenaard7c96872019-06-15 17:12:48 +02003292 // Save the global value before changing anything. This is needed as for
3293 // a global-only option setting the "local value" infact sets the global
3294 // value (since there is only one value).
3295 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
Bram Moolenaar983f2f12019-06-16 16:41:41 +02003296 old_global_value = *(long *)get_varp_scope(&(options[opt_idx]),
3297 OPT_GLOBAL);
3298#endif
Bram Moolenaard7c96872019-06-15 17:12:48 +02003299
Bram Moolenaar071d4272004-06-13 20:20:40 +00003300 *pp = value;
3301#ifdef FEAT_EVAL
3302 /* Remember where the option was set. */
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02003303 set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003304#endif
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00003305#ifdef FEAT_GUI
3306 need_mouse_correct = TRUE;
3307#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003308
Bram Moolenaar14f24742012-08-08 18:01:05 +02003309 if (curbuf->b_p_sw < 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003310 {
3311 errmsg = e_positive;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02003312#ifdef FEAT_VARTABS
3313 // Use the first 'vartabstop' value, or 'tabstop' if vts isn't in use.
3314 curbuf->b_p_sw = tabstop_count(curbuf->b_p_vts_array) > 0
3315 ? tabstop_first(curbuf->b_p_vts_array)
3316 : curbuf->b_p_ts;
3317#else
Bram Moolenaar071d4272004-06-13 20:20:40 +00003318 curbuf->b_p_sw = curbuf->b_p_ts;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02003319#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003320 }
3321
3322 /*
3323 * Number options that need some action when changed
3324 */
Bram Moolenaar071d4272004-06-13 20:20:40 +00003325 if (pp == &p_wh || pp == &p_hh)
3326 {
Bram Moolenaar1c3c1042018-06-12 16:49:30 +02003327 // 'winheight' and 'helpheight'
Bram Moolenaar071d4272004-06-13 20:20:40 +00003328 if (p_wh < 1)
3329 {
3330 errmsg = e_positive;
3331 p_wh = 1;
3332 }
3333 if (p_wmh > p_wh)
3334 {
3335 errmsg = e_winheight;
3336 p_wh = p_wmh;
3337 }
3338 if (p_hh < 0)
3339 {
3340 errmsg = e_positive;
3341 p_hh = 0;
3342 }
3343
3344 /* Change window height NOW */
Bram Moolenaar459ca562016-11-10 18:16:33 +01003345 if (!ONE_WINDOW)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003346 {
3347 if (pp == &p_wh && curwin->w_height < p_wh)
3348 win_setheight((int)p_wh);
3349 if (pp == &p_hh && curbuf->b_help && curwin->w_height < p_hh)
3350 win_setheight((int)p_hh);
3351 }
3352 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003353 else if (pp == &p_wmh)
3354 {
Bram Moolenaar1c3c1042018-06-12 16:49:30 +02003355 // 'winminheight'
Bram Moolenaar071d4272004-06-13 20:20:40 +00003356 if (p_wmh < 0)
3357 {
3358 errmsg = e_positive;
3359 p_wmh = 0;
3360 }
3361 if (p_wmh > p_wh)
3362 {
3363 errmsg = e_winheight;
3364 p_wmh = p_wh;
3365 }
3366 win_setminheight();
3367 }
Bram Moolenaar592e0a22004-07-03 16:05:59 +00003368 else if (pp == &p_wiw)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003369 {
Bram Moolenaar1c3c1042018-06-12 16:49:30 +02003370 // 'winwidth'
Bram Moolenaar071d4272004-06-13 20:20:40 +00003371 if (p_wiw < 1)
3372 {
3373 errmsg = e_positive;
3374 p_wiw = 1;
3375 }
3376 if (p_wmw > p_wiw)
3377 {
3378 errmsg = e_winwidth;
3379 p_wiw = p_wmw;
3380 }
3381
3382 /* Change window width NOW */
Bram Moolenaar459ca562016-11-10 18:16:33 +01003383 if (!ONE_WINDOW && curwin->w_width < p_wiw)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003384 win_setwidth((int)p_wiw);
3385 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003386 else if (pp == &p_wmw)
3387 {
Bram Moolenaar1c3c1042018-06-12 16:49:30 +02003388 // 'winminwidth'
Bram Moolenaar071d4272004-06-13 20:20:40 +00003389 if (p_wmw < 0)
3390 {
3391 errmsg = e_positive;
3392 p_wmw = 0;
3393 }
3394 if (p_wmw > p_wiw)
3395 {
3396 errmsg = e_winwidth;
3397 p_wmw = p_wiw;
3398 }
Bram Moolenaar1c3c1042018-06-12 16:49:30 +02003399 win_setminwidth();
Bram Moolenaar071d4272004-06-13 20:20:40 +00003400 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003401
Bram Moolenaar071d4272004-06-13 20:20:40 +00003402 /* (re)set last window status line */
3403 else if (pp == &p_ls)
3404 {
3405 last_status(FALSE);
3406 }
Bram Moolenaar4c7ed462006-02-15 22:18:42 +00003407
3408 /* (re)set tab page line */
Bram Moolenaarfaa959a2006-02-20 21:37:40 +00003409 else if (pp == &p_stal)
Bram Moolenaar4c7ed462006-02-15 22:18:42 +00003410 {
3411 shell_new_rows(); /* recompute window positions and heights */
3412 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003413
3414#ifdef FEAT_GUI
3415 else if (pp == &p_linespace)
3416 {
Bram Moolenaar02743632005-07-25 20:42:36 +00003417 /* Recompute gui.char_height and resize the Vim window to keep the
3418 * same number of lines. */
3419 if (gui.in_use && gui_mch_adjust_charheight() == OK)
Bram Moolenaar3964b7e2006-03-27 20:59:33 +00003420 gui_set_shellsize(FALSE, FALSE, RESIZE_VERT);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003421 }
3422#endif
3423
3424#ifdef FEAT_FOLDING
3425 /* 'foldlevel' */
3426 else if (pp == &curwin->w_p_fdl)
3427 {
3428 if (curwin->w_p_fdl < 0)
3429 curwin->w_p_fdl = 0;
3430 newFoldLevel();
3431 }
3432
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00003433 /* 'foldminlines' */
Bram Moolenaar071d4272004-06-13 20:20:40 +00003434 else if (pp == &curwin->w_p_fml)
3435 {
3436 foldUpdateAll(curwin);
3437 }
3438
3439 /* 'foldnestmax' */
3440 else if (pp == &curwin->w_p_fdn)
3441 {
3442 if (foldmethodIsSyntax(curwin) || foldmethodIsIndent(curwin))
3443 foldUpdateAll(curwin);
3444 }
3445
3446 /* 'foldcolumn' */
3447 else if (pp == &curwin->w_p_fdc)
3448 {
3449 if (curwin->w_p_fdc < 0)
3450 {
3451 errmsg = e_positive;
3452 curwin->w_p_fdc = 0;
3453 }
3454 else if (curwin->w_p_fdc > 12)
3455 {
3456 errmsg = e_invarg;
3457 curwin->w_p_fdc = 12;
3458 }
3459 }
Bram Moolenaar6bcbcc52013-11-05 07:13:41 +01003460#endif /* FEAT_FOLDING */
Bram Moolenaar071d4272004-06-13 20:20:40 +00003461
Bram Moolenaar6bcbcc52013-11-05 07:13:41 +01003462#if defined(FEAT_FOLDING) || defined(FEAT_CINDENT)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003463 /* 'shiftwidth' or 'tabstop' */
3464 else if (pp == &curbuf->b_p_sw || pp == &curbuf->b_p_ts)
3465 {
Bram Moolenaar6bcbcc52013-11-05 07:13:41 +01003466# ifdef FEAT_FOLDING
Bram Moolenaar071d4272004-06-13 20:20:40 +00003467 if (foldmethodIsIndent(curwin))
3468 foldUpdateAll(curwin);
Bram Moolenaar6bcbcc52013-11-05 07:13:41 +01003469# endif
3470# ifdef FEAT_CINDENT
3471 /* When 'shiftwidth' changes, or it's zero and 'tabstop' changes:
3472 * parse 'cinoptions'. */
3473 if (pp == &curbuf->b_p_sw || curbuf->b_p_sw == 0)
3474 parse_cino(curbuf);
3475# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003476 }
Bram Moolenaar6bcbcc52013-11-05 07:13:41 +01003477#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003478
Bram Moolenaar362e1a32006-03-06 23:29:24 +00003479 /* 'maxcombine' */
3480 else if (pp == &p_mco)
3481 {
3482 if (p_mco > MAX_MCO)
3483 p_mco = MAX_MCO;
3484 else if (p_mco < 0)
3485 p_mco = 0;
3486 screenclear(); /* will re-allocate the screen */
3487 }
Bram Moolenaar362e1a32006-03-06 23:29:24 +00003488
Bram Moolenaar071d4272004-06-13 20:20:40 +00003489 else if (pp == &curbuf->b_p_iminsert)
3490 {
3491 if (curbuf->b_p_iminsert < 0 || curbuf->b_p_iminsert > B_IMODE_LAST)
3492 {
3493 errmsg = e_invarg;
3494 curbuf->b_p_iminsert = B_IMODE_NONE;
3495 }
3496 p_iminsert = curbuf->b_p_iminsert;
3497 if (termcap_active) /* don't do this in the alternate screen */
3498 showmode();
Bram Moolenaar4033c552017-09-16 20:54:51 +02003499#if defined(FEAT_KEYMAP)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003500 /* Show/unshow value of 'keymap' in status lines. */
3501 status_redraw_curbuf();
3502#endif
3503 }
3504
Bram Moolenaar5c6dbcb2017-08-30 22:00:20 +02003505#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
3506 /* 'imstyle' */
3507 else if (pp == &p_imst)
3508 {
3509 if (p_imst != IM_ON_THE_SPOT && p_imst != IM_OVER_THE_SPOT)
3510 errmsg = e_invarg;
3511 }
3512#endif
3513
Bram Moolenaar4399ef42005-02-12 14:29:27 +00003514 else if (pp == &p_window)
3515 {
3516 if (p_window < 1)
3517 p_window = 1;
3518 else if (p_window >= Rows)
3519 p_window = Rows - 1;
3520 }
3521
Bram Moolenaar071d4272004-06-13 20:20:40 +00003522 else if (pp == &curbuf->b_p_imsearch)
3523 {
3524 if (curbuf->b_p_imsearch < -1 || curbuf->b_p_imsearch > B_IMODE_LAST)
3525 {
3526 errmsg = e_invarg;
3527 curbuf->b_p_imsearch = B_IMODE_NONE;
3528 }
3529 p_imsearch = curbuf->b_p_imsearch;
3530 }
3531
3532#ifdef FEAT_TITLE
3533 /* if 'titlelen' has changed, redraw the title */
3534 else if (pp == &p_titlelen)
3535 {
3536 if (p_titlelen < 0)
3537 {
3538 errmsg = e_positive;
3539 p_titlelen = 85;
3540 }
3541 if (starting != NO_SCREEN && old_value != p_titlelen)
3542 need_maketitle = TRUE;
3543 }
3544#endif
3545
3546 /* if p_ch changed value, change the command line height */
3547 else if (pp == &p_ch)
3548 {
3549 if (p_ch < 1)
3550 {
3551 errmsg = e_positive;
3552 p_ch = 1;
3553 }
Bram Moolenaar719939c2007-09-25 12:51:28 +00003554 if (p_ch > Rows - min_rows() + 1)
3555 p_ch = Rows - min_rows() + 1;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003556
3557 /* Only compute the new window layout when startup has been
3558 * completed. Otherwise the frame sizes may be wrong. */
3559 if (p_ch != old_value && full_screen
3560#ifdef FEAT_GUI
3561 && !gui.starting
3562#endif
3563 )
Bram Moolenaarc6fe9192006-04-09 21:54:49 +00003564 command_height();
Bram Moolenaar071d4272004-06-13 20:20:40 +00003565 }
3566
3567 /* when 'updatecount' changes from zero to non-zero, open swap files */
3568 else if (pp == &p_uc)
3569 {
3570 if (p_uc < 0)
3571 {
3572 errmsg = e_positive;
3573 p_uc = 100;
3574 }
3575 if (p_uc && !old_value)
3576 ml_open_files();
3577 }
Bram Moolenaar860cae12010-06-05 23:22:07 +02003578#ifdef FEAT_CONCEAL
Bram Moolenaarf5963f72010-07-23 22:10:27 +02003579 else if (pp == &curwin->w_p_cole)
Bram Moolenaar860cae12010-06-05 23:22:07 +02003580 {
Bram Moolenaarf5963f72010-07-23 22:10:27 +02003581 if (curwin->w_p_cole < 0)
Bram Moolenaar860cae12010-06-05 23:22:07 +02003582 {
3583 errmsg = e_positive;
Bram Moolenaarf5963f72010-07-23 22:10:27 +02003584 curwin->w_p_cole = 0;
Bram Moolenaar860cae12010-06-05 23:22:07 +02003585 }
Bram Moolenaarf5963f72010-07-23 22:10:27 +02003586 else if (curwin->w_p_cole > 3)
Bram Moolenaar860cae12010-06-05 23:22:07 +02003587 {
3588 errmsg = e_invarg;
Bram Moolenaarf5963f72010-07-23 22:10:27 +02003589 curwin->w_p_cole = 3;
Bram Moolenaar860cae12010-06-05 23:22:07 +02003590 }
3591 }
3592#endif
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00003593#ifdef MZSCHEME_GUI_THREADS
Bram Moolenaar325b7a22004-07-05 15:58:32 +00003594 else if (pp == &p_mzq)
3595 mzvim_reset_timer();
3596#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003597
Bram Moolenaarf42dd3c2017-01-28 16:06:38 +01003598#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
3599 /* 'pyxversion' */
3600 else if (pp == &p_pyx)
3601 {
3602 if (p_pyx != 0 && p_pyx != 2 && p_pyx != 3)
3603 errmsg = e_invarg;
3604 }
3605#endif
3606
Bram Moolenaar071d4272004-06-13 20:20:40 +00003607 /* sync undo before 'undolevels' changes */
3608 else if (pp == &p_ul)
3609 {
3610 /* use the old value, otherwise u_sync() may not work properly */
3611 p_ul = old_value;
Bram Moolenaar779b74b2006-04-10 14:55:34 +00003612 u_sync(TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003613 p_ul = value;
3614 }
Bram Moolenaarf5a2fd82013-11-06 05:26:15 +01003615 else if (pp == &curbuf->b_p_ul)
3616 {
3617 /* use the old value, otherwise u_sync() may not work properly */
3618 curbuf->b_p_ul = old_value;
3619 u_sync(TRUE);
3620 curbuf->b_p_ul = value;
3621 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003622
Bram Moolenaar592e0a22004-07-03 16:05:59 +00003623#ifdef FEAT_LINEBREAK
3624 /* 'numberwidth' must be positive */
3625 else if (pp == &curwin->w_p_nuw)
3626 {
3627 if (curwin->w_p_nuw < 1)
3628 {
3629 errmsg = e_positive;
3630 curwin->w_p_nuw = 1;
3631 }
Bram Moolenaarf8a07122019-07-01 22:06:07 +02003632 if (curwin->w_p_nuw > 20)
Bram Moolenaar592e0a22004-07-03 16:05:59 +00003633 {
3634 errmsg = e_invarg;
Bram Moolenaarf8a07122019-07-01 22:06:07 +02003635 curwin->w_p_nuw = 20;
Bram Moolenaar592e0a22004-07-03 16:05:59 +00003636 }
Bram Moolenaar1e7813a2015-03-31 18:31:03 +02003637 curwin->w_nrwidth_line_count = 0; /* trigger a redraw */
Bram Moolenaar592e0a22004-07-03 16:05:59 +00003638 }
3639#endif
3640
Bram Moolenaar1a384422010-07-14 19:53:30 +02003641 else if (pp == &curbuf->b_p_tw)
3642 {
3643 if (curbuf->b_p_tw < 0)
3644 {
3645 errmsg = e_positive;
3646 curbuf->b_p_tw = 0;
3647 }
3648#ifdef FEAT_SYN_HL
Bram Moolenaar1a384422010-07-14 19:53:30 +02003649 {
3650 win_T *wp;
3651 tabpage_T *tp;
3652
3653 FOR_ALL_TAB_WINDOWS(tp, wp)
3654 check_colorcolumn(wp);
3655 }
Bram Moolenaar1a384422010-07-14 19:53:30 +02003656#endif
3657 }
3658
Bram Moolenaar071d4272004-06-13 20:20:40 +00003659 /*
3660 * Check the bounds for numeric options here
3661 */
3662 if (Rows < min_rows() && full_screen)
3663 {
3664 if (errbuf != NULL)
3665 {
Bram Moolenaar555b2802005-05-19 21:08:39 +00003666 vim_snprintf((char *)errbuf, errbuflen,
3667 _("E593: Need at least %d lines"), min_rows());
Bram Moolenaar071d4272004-06-13 20:20:40 +00003668 errmsg = errbuf;
3669 }
3670 Rows = min_rows();
3671 }
3672 if (Columns < MIN_COLUMNS && full_screen)
3673 {
3674 if (errbuf != NULL)
3675 {
Bram Moolenaar555b2802005-05-19 21:08:39 +00003676 vim_snprintf((char *)errbuf, errbuflen,
3677 _("E594: Need at least %d columns"), MIN_COLUMNS);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003678 errmsg = errbuf;
3679 }
3680 Columns = MIN_COLUMNS;
3681 }
Bram Moolenaare057d402013-06-30 17:51:51 +02003682 limit_screen_size();
Bram Moolenaar071d4272004-06-13 20:20:40 +00003683
Bram Moolenaar071d4272004-06-13 20:20:40 +00003684 /*
3685 * If the screen (shell) height has been changed, assume it is the
3686 * physical screenheight.
3687 */
3688 if (old_Rows != Rows || old_Columns != Columns)
3689 {
3690 /* Changing the screen size is not allowed while updating the screen. */
3691 if (updating_screen)
3692 *pp = old_value;
3693 else if (full_screen
3694#ifdef FEAT_GUI
3695 && !gui.starting
3696#endif
3697 )
3698 set_shellsize((int)Columns, (int)Rows, TRUE);
3699 else
3700 {
3701 /* Postpone the resizing; check the size and cmdline position for
3702 * messages. */
3703 check_shellsize();
3704 if (cmdline_row > Rows - p_ch && Rows > p_ch)
3705 cmdline_row = Rows - p_ch;
3706 }
Bram Moolenaard68071d2006-05-02 22:08:30 +00003707 if (p_window >= Rows || !option_was_set((char_u *)"window"))
Bram Moolenaar4399ef42005-02-12 14:29:27 +00003708 p_window = Rows - 1;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003709 }
3710
Bram Moolenaar071d4272004-06-13 20:20:40 +00003711 if (curbuf->b_p_ts <= 0)
3712 {
3713 errmsg = e_positive;
3714 curbuf->b_p_ts = 8;
3715 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003716 if (p_tm < 0)
3717 {
3718 errmsg = e_positive;
3719 p_tm = 0;
3720 }
3721 if ((curwin->w_p_scr <= 0
3722 || (curwin->w_p_scr > curwin->w_height
3723 && curwin->w_height > 0))
3724 && full_screen)
3725 {
3726 if (pp == &(curwin->w_p_scr))
3727 {
3728 if (curwin->w_p_scr != 0)
3729 errmsg = e_scroll;
3730 win_comp_scroll(curwin);
3731 }
3732 /* If 'scroll' became invalid because of a side effect silently adjust
3733 * it. */
3734 else if (curwin->w_p_scr <= 0)
3735 curwin->w_p_scr = 1;
3736 else /* curwin->w_p_scr > curwin->w_height */
3737 curwin->w_p_scr = curwin->w_height;
3738 }
Bram Moolenaar991e10f2008-10-02 20:48:41 +00003739 if (p_hi < 0)
3740 {
3741 errmsg = e_positive;
3742 p_hi = 0;
3743 }
Bram Moolenaar78159bb2014-06-25 11:48:54 +02003744 else if (p_hi > 10000)
3745 {
3746 errmsg = e_invarg;
3747 p_hi = 10000;
3748 }
Bram Moolenaarfbc0d2e2013-05-19 19:40:29 +02003749 if (p_re < 0 || p_re > 2)
3750 {
3751 errmsg = e_invarg;
3752 p_re = 0;
3753 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003754 if (p_report < 0)
3755 {
3756 errmsg = e_positive;
3757 p_report = 1;
3758 }
Bram Moolenaar1e015462005-09-25 22:16:38 +00003759 if ((p_sj < -100 || p_sj >= Rows) && full_screen)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003760 {
3761 if (Rows != old_Rows) /* Rows changed, just adjust p_sj */
3762 p_sj = Rows / 2;
3763 else
3764 {
3765 errmsg = e_scroll;
3766 p_sj = 1;
3767 }
3768 }
3769 if (p_so < 0 && full_screen)
3770 {
Bram Moolenaar375e3392019-01-31 18:26:10 +01003771 errmsg = e_positive;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003772 p_so = 0;
3773 }
3774 if (p_siso < 0 && full_screen)
3775 {
3776 errmsg = e_positive;
3777 p_siso = 0;
3778 }
3779#ifdef FEAT_CMDWIN
3780 if (p_cwh < 1)
3781 {
3782 errmsg = e_positive;
3783 p_cwh = 1;
3784 }
3785#endif
3786 if (p_ut < 0)
3787 {
3788 errmsg = e_positive;
3789 p_ut = 2000;
3790 }
3791 if (p_ss < 0)
3792 {
3793 errmsg = e_positive;
3794 p_ss = 0;
3795 }
3796
3797 /* May set global value for local option. */
3798 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
3799 *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = *pp;
3800
3801 options[opt_idx].flags |= P_WAS_SET;
3802
Bram Moolenaarf2bd8ef2018-03-04 18:08:14 +01003803#if defined(FEAT_EVAL)
Bram Moolenaar3f3fb0b2018-09-21 11:59:32 +02003804 // Don't do this while starting up, failure or recursively.
3805 if (!starting && errmsg == NULL && *get_vim_var_str(VV_OPTION_TYPE) == NUL)
Bram Moolenaar53744302015-07-17 17:38:22 +02003806 {
Bram Moolenaard7c96872019-06-15 17:12:48 +02003807 char_u buf_old[11], buf_old_global[11], buf_new[11], buf_type[7];
Bram Moolenaarfb9bc482015-07-17 22:04:48 +02003808 vim_snprintf((char *)buf_old, 10, "%ld", old_value);
Bram Moolenaard7c96872019-06-15 17:12:48 +02003809 vim_snprintf((char *)buf_old_global, 10, "%ld", old_global_value);
Bram Moolenaarfb9bc482015-07-17 22:04:48 +02003810 vim_snprintf((char *)buf_new, 10, "%ld", value);
3811 vim_snprintf((char *)buf_type, 7, "%s", (opt_flags & OPT_LOCAL) ? "local" : "global");
Bram Moolenaar53744302015-07-17 17:38:22 +02003812 set_vim_var_string(VV_OPTION_NEW, buf_new, -1);
3813 set_vim_var_string(VV_OPTION_OLD, buf_old, -1);
3814 set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
Bram Moolenaard7c96872019-06-15 17:12:48 +02003815 if (opt_flags & OPT_LOCAL)
3816 {
3817 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setlocal", -1);
3818 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
3819 }
3820 if (opt_flags & OPT_GLOBAL)
3821 {
3822 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setglobal", -1);
3823 set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old, -1);
3824 }
3825 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
3826 {
3827 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"set", -1);
3828 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
3829 set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old_global, -1);
3830 }
3831 if (opt_flags & OPT_MODELINE)
3832 {
3833 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"modeline", -1);
3834 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
3835 }
3836 apply_autocmds(EVENT_OPTIONSET, (char_u *)options[opt_idx].fullname,
3837 NULL, FALSE, NULL);
Bram Moolenaar53744302015-07-17 17:38:22 +02003838 reset_v_option_vars();
3839 }
3840#endif
3841
Bram Moolenaar071d4272004-06-13 20:20:40 +00003842 comp_col(); /* in case 'columns' or 'ls' changed */
Bram Moolenaar913077c2012-03-28 19:59:04 +02003843 if (curwin->w_curswant != MAXCOL
Bram Moolenaar488eb262015-03-13 11:23:50 +01003844 && (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0)
Bram Moolenaar913077c2012-03-28 19:59:04 +02003845 curwin->w_set_curswant = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003846 check_redraw(options[opt_idx].flags);
3847
3848 return errmsg;
3849}
3850
3851/*
3852 * Called after an option changed: check if something needs to be redrawn.
3853 */
Bram Moolenaardac13472019-09-16 21:06:21 +02003854 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01003855check_redraw(long_u flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003856{
3857 /* Careful: P_RCLR and P_RALL are a combination of other P_ flags */
Bram Moolenaar70b2a562012-01-10 22:26:17 +01003858 int doclear = (flags & P_RCLR) == P_RCLR;
3859 int all = ((flags & P_RALL) == P_RALL || doclear);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003860
Bram Moolenaar071d4272004-06-13 20:20:40 +00003861 if ((flags & P_RSTAT) || all) /* mark all status lines dirty */
3862 status_redraw_all();
Bram Moolenaar071d4272004-06-13 20:20:40 +00003863
3864 if ((flags & P_RBUF) || (flags & P_RWIN) || all)
3865 changed_window_setting();
3866 if (flags & P_RBUF)
3867 redraw_curbuf_later(NOT_VALID);
Bram Moolenaara2477fd2016-12-03 15:13:20 +01003868 if (flags & P_RWINONLY)
3869 redraw_later(NOT_VALID);
Bram Moolenaar70b2a562012-01-10 22:26:17 +01003870 if (doclear)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003871 redraw_all_later(CLEAR);
3872 else if (all)
3873 redraw_all_later(NOT_VALID);
3874}
3875
3876/*
3877 * Find index for option 'arg'.
3878 * Return -1 if not found.
3879 */
Bram Moolenaardac13472019-09-16 21:06:21 +02003880 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01003881findoption(char_u *arg)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003882{
3883 int opt_idx;
3884 char *s, *p;
3885 static short quick_tab[27] = {0, 0}; /* quick access table */
3886 int is_term_opt;
3887
3888 /*
3889 * For first call: Initialize the quick-access table.
3890 * It contains the index for the first option that starts with a certain
3891 * letter. There are 26 letters, plus the first "t_" option.
3892 */
3893 if (quick_tab[1] == 0)
3894 {
3895 p = options[0].fullname;
3896 for (opt_idx = 1; (s = options[opt_idx].fullname) != NULL; opt_idx++)
3897 {
3898 if (s[0] != p[0])
3899 {
3900 if (s[0] == 't' && s[1] == '_')
3901 quick_tab[26] = opt_idx;
3902 else
3903 quick_tab[CharOrdLow(s[0])] = opt_idx;
3904 }
3905 p = s;
3906 }
3907 }
3908
3909 /*
3910 * Check for name starting with an illegal character.
3911 */
3912#ifdef EBCDIC
3913 if (!islower(arg[0]))
3914#else
3915 if (arg[0] < 'a' || arg[0] > 'z')
3916#endif
3917 return -1;
3918
3919 is_term_opt = (arg[0] == 't' && arg[1] == '_');
3920 if (is_term_opt)
3921 opt_idx = quick_tab[26];
3922 else
3923 opt_idx = quick_tab[CharOrdLow(arg[0])];
3924 for ( ; (s = options[opt_idx].fullname) != NULL; opt_idx++)
3925 {
3926 if (STRCMP(arg, s) == 0) /* match full name */
3927 break;
3928 }
3929 if (s == NULL && !is_term_opt)
3930 {
3931 opt_idx = quick_tab[CharOrdLow(arg[0])];
3932 for ( ; options[opt_idx].fullname != NULL; opt_idx++)
3933 {
3934 s = options[opt_idx].shortname;
3935 if (s != NULL && STRCMP(arg, s) == 0) /* match short name */
3936 break;
3937 s = NULL;
3938 }
3939 }
3940 if (s == NULL)
3941 opt_idx = -1;
3942 return opt_idx;
3943}
3944
Bram Moolenaar325b7a22004-07-05 15:58:32 +00003945#if defined(FEAT_EVAL) || defined(FEAT_TCL) || defined(FEAT_MZSCHEME)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003946/*
3947 * Get the value for an option.
3948 *
3949 * Returns:
3950 * Number or Toggle option: 1, *numval gets value.
3951 * String option: 0, *stringval gets allocated string.
3952 * Hidden Number or Toggle option: -1.
3953 * hidden String option: -2.
3954 * unknown option: -3.
3955 */
3956 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01003957get_option_value(
3958 char_u *name,
3959 long *numval,
3960 char_u **stringval, /* NULL when only checking existence */
3961 int opt_flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003962{
3963 int opt_idx;
3964 char_u *varp;
3965
3966 opt_idx = findoption(name);
3967 if (opt_idx < 0) /* unknown option */
Bram Moolenaare353c402017-02-04 19:49:16 +01003968 {
3969 int key;
3970
3971 if (STRLEN(name) == 4 && name[0] == 't' && name[1] == '_'
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02003972 && (key = find_key_option(name, FALSE)) != 0)
Bram Moolenaare353c402017-02-04 19:49:16 +01003973 {
3974 char_u key_name[2];
3975 char_u *p;
3976
3977 if (key < 0)
3978 {
3979 key_name[0] = KEY2TERMCAP0(key);
3980 key_name[1] = KEY2TERMCAP1(key);
3981 }
3982 else
3983 {
3984 key_name[0] = KS_KEY;
3985 key_name[1] = (key & 0xff);
3986 }
3987 p = find_termcode(key_name);
3988 if (p != NULL)
3989 {
3990 if (stringval != NULL)
3991 *stringval = vim_strsave(p);
3992 return 0;
3993 }
3994 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003995 return -3;
Bram Moolenaare353c402017-02-04 19:49:16 +01003996 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003997
3998 varp = get_varp_scope(&(options[opt_idx]), opt_flags);
3999
4000 if (options[opt_idx].flags & P_STRING)
4001 {
4002 if (varp == NULL) /* hidden option */
4003 return -2;
4004 if (stringval != NULL)
4005 {
4006#ifdef FEAT_CRYPT
4007 /* never return the value of the crypt key */
Bram Moolenaarc1a11ed2008-06-24 22:09:24 +00004008 if ((char_u **)varp == &curbuf->b_p_key
4009 && **(char_u **)(varp) != NUL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004010 *stringval = vim_strsave((char_u *)"*****");
4011 else
4012#endif
4013 *stringval = vim_strsave(*(char_u **)(varp));
4014 }
4015 return 0;
4016 }
4017
4018 if (varp == NULL) /* hidden option */
4019 return -1;
4020 if (options[opt_idx].flags & P_NUM)
4021 *numval = *(long *)varp;
4022 else
4023 {
4024 /* Special case: 'modified' is b_changed, but we also want to consider
4025 * it set when 'ff' or 'fenc' changed. */
4026 if ((int *)varp == &curbuf->b_changed)
4027 *numval = curbufIsChanged();
4028 else
Bram Moolenaar2acfbed2016-07-01 23:14:02 +02004029 *numval = (long) *(int *)varp;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004030 }
4031 return 1;
4032}
4033#endif
4034
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004035#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) || defined(PROTO)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004036/*
4037 * Returns the option attributes and its value. Unlike the above function it
4038 * will return either global value or local value of the option depending on
4039 * what was requested, but it will never return global value if it was
4040 * requested to return local one and vice versa. Neither it will return
4041 * buffer-local value if it was requested to return window-local one.
4042 *
4043 * Pretends that option is absent if it is not present in the requested scope
4044 * (i.e. has no global, window-local or buffer-local value depending on
4045 * opt_type). Uses
4046 *
4047 * Returned flags:
Bram Moolenaar75a8d742014-05-07 15:10:21 +02004048 * 0 hidden or unknown option, also option that does not have requested
4049 * type (see SREQ_* in vim.h)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004050 * see SOPT_* in vim.h for other flags
4051 *
4052 * Possible opt_type values: see SREQ_* in vim.h
4053 */
4054 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01004055get_option_value_strict(
4056 char_u *name,
4057 long *numval,
4058 char_u **stringval, /* NULL when only obtaining attributes */
4059 int opt_type,
4060 void *from)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004061{
4062 int opt_idx;
Bram Moolenaar68001862013-05-11 13:45:05 +02004063 char_u *varp = NULL;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004064 struct vimoption *p;
4065 int r = 0;
4066
4067 opt_idx = findoption(name);
4068 if (opt_idx < 0)
4069 return 0;
4070
4071 p = &(options[opt_idx]);
4072
4073 /* Hidden option */
4074 if (p->var == NULL)
4075 return 0;
4076
4077 if (p->flags & P_BOOL)
4078 r |= SOPT_BOOL;
4079 else if (p->flags & P_NUM)
4080 r |= SOPT_NUM;
4081 else if (p->flags & P_STRING)
4082 r |= SOPT_STRING;
4083
4084 if (p->indir == PV_NONE)
4085 {
4086 if (opt_type == SREQ_GLOBAL)
4087 r |= SOPT_GLOBAL;
4088 else
4089 return 0; /* Did not request global-only option */
4090 }
4091 else
4092 {
4093 if (p->indir & PV_BOTH)
4094 r |= SOPT_GLOBAL;
4095 else if (opt_type == SREQ_GLOBAL)
4096 return 0; /* Requested global option */
4097
4098 if (p->indir & PV_WIN)
4099 {
4100 if (opt_type == SREQ_BUF)
4101 return 0; /* Did not request window-local option */
4102 else
4103 r |= SOPT_WIN;
4104 }
4105 else if (p->indir & PV_BUF)
4106 {
4107 if (opt_type == SREQ_WIN)
4108 return 0; /* Did not request buffer-local option */
4109 else
4110 r |= SOPT_BUF;
4111 }
4112 }
4113
4114 if (stringval == NULL)
4115 return r;
4116
4117 if (opt_type == SREQ_GLOBAL)
4118 varp = p->var;
4119 else
4120 {
4121 if (opt_type == SREQ_BUF)
4122 {
4123 /* Special case: 'modified' is b_changed, but we also want to
4124 * consider it set when 'ff' or 'fenc' changed. */
4125 if (p->indir == PV_MOD)
4126 {
Bram Moolenaardefe6422018-06-24 15:14:07 +02004127 *numval = bufIsChanged((buf_T *)from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004128 varp = NULL;
4129 }
4130#ifdef FEAT_CRYPT
4131 else if (p->indir == PV_KEY)
4132 {
4133 /* never return the value of the crypt key */
4134 *stringval = NULL;
4135 varp = NULL;
4136 }
4137#endif
4138 else
4139 {
Bram Moolenaardefe6422018-06-24 15:14:07 +02004140 buf_T *save_curbuf = curbuf;
4141
4142 // only getting a pointer, no need to use aucmd_prepbuf()
4143 curbuf = (buf_T *)from;
4144 curwin->w_buffer = curbuf;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004145 varp = get_varp(p);
Bram Moolenaardefe6422018-06-24 15:14:07 +02004146 curbuf = save_curbuf;
4147 curwin->w_buffer = curbuf;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004148 }
4149 }
4150 else if (opt_type == SREQ_WIN)
4151 {
Bram Moolenaardefe6422018-06-24 15:14:07 +02004152 win_T *save_curwin = curwin;
4153
4154 curwin = (win_T *)from;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004155 curbuf = curwin->w_buffer;
4156 varp = get_varp(p);
4157 curwin = save_curwin;
4158 curbuf = curwin->w_buffer;
4159 }
4160 if (varp == p->var)
4161 return (r | SOPT_UNSET);
4162 }
4163
4164 if (varp != NULL)
4165 {
4166 if (p->flags & P_STRING)
4167 *stringval = vim_strsave(*(char_u **)(varp));
4168 else if (p->flags & P_NUM)
4169 *numval = *(long *) varp;
4170 else
4171 *numval = *(int *)varp;
4172 }
4173
4174 return r;
4175}
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004176
4177/*
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02004178 * Iterate over options. First argument is a pointer to a pointer to a
4179 * structure inside options[] array, second is option type like in the above
4180 * function.
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004181 *
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02004182 * If first argument points to NULL it is assumed that iteration just started
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004183 * and caller needs the very first value.
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02004184 * If first argument points to the end marker function returns NULL and sets
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004185 * first argument to NULL.
4186 *
4187 * Returns full option name for current option on each call.
4188 */
4189 char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01004190option_iter_next(void **option, int opt_type)
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004191{
4192 struct vimoption *ret = NULL;
4193 do
4194 {
4195 if (*option == NULL)
4196 *option = (void *) options;
4197 else if (((struct vimoption *) (*option))->fullname == NULL)
4198 {
4199 *option = NULL;
4200 return NULL;
4201 }
4202 else
4203 *option = (void *) (((struct vimoption *) (*option)) + 1);
4204
4205 ret = ((struct vimoption *) (*option));
4206
4207 /* Hidden option */
4208 if (ret->var == NULL)
4209 {
4210 ret = NULL;
4211 continue;
4212 }
4213
4214 switch (opt_type)
4215 {
4216 case SREQ_GLOBAL:
4217 if (!(ret->indir == PV_NONE || ret->indir & PV_BOTH))
4218 ret = NULL;
4219 break;
4220 case SREQ_BUF:
4221 if (!(ret->indir & PV_BUF))
4222 ret = NULL;
4223 break;
4224 case SREQ_WIN:
4225 if (!(ret->indir & PV_WIN))
4226 ret = NULL;
4227 break;
4228 default:
Bram Moolenaar95f09602016-11-10 20:01:45 +01004229 internal_error("option_iter_next()");
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004230 return NULL;
4231 }
4232 }
4233 while (ret == NULL);
4234
4235 return (char_u *)ret->fullname;
4236}
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004237#endif
4238
Bram Moolenaar071d4272004-06-13 20:20:40 +00004239/*
Bram Moolenaardac13472019-09-16 21:06:21 +02004240 * Return the flags for the option at 'opt_idx'.
4241 */
4242 long_u
4243get_option_flags(int opt_idx)
4244{
4245 return options[opt_idx].flags;
4246}
4247
4248/*
4249 * Set a flag for the option at 'opt_idx'.
4250 */
4251 void
4252set_option_flag(int opt_idx, long_u flag)
4253{
4254 options[opt_idx].flags |= flag;
4255}
4256
4257/*
4258 * Clear a flag for the option at 'opt_idx'.
4259 */
4260 void
4261clear_option_flag(int opt_idx, long_u flag)
4262{
4263 options[opt_idx].flags &= ~flag;
4264}
4265
4266/*
4267 * Returns TRUE if the option at 'opt_idx' is a global option
4268 */
4269 int
4270is_global_option(int opt_idx)
4271{
4272 return options[opt_idx].indir == PV_NONE;
4273}
4274
4275/*
4276 * Returns TRUE if the option at 'opt_idx' is a global option which also has a
4277 * local value.
4278 */
4279 int
4280is_global_local_option(int opt_idx)
4281{
4282 return options[opt_idx].indir & PV_BOTH;
4283}
4284
4285/*
4286 * Returns TRUE if the option at 'opt_idx' is a window-local option
4287 */
4288 int
4289is_window_local_option(int opt_idx)
4290{
4291 return options[opt_idx].var == VAR_WIN;
4292}
4293
4294/*
4295 * Returns TRUE if the option at 'opt_idx' is a hidden option
4296 */
4297 int
4298is_hidden_option(int opt_idx)
4299{
4300 return options[opt_idx].var == NULL;
4301}
4302
4303#if defined(FEAT_CRYPT) || defined(PROTO)
4304/*
4305 * Returns TRUE if the option at 'opt_idx' is a crypt key option
4306 */
4307 int
4308is_crypt_key_option(int opt_idx)
4309{
4310 return options[opt_idx].indir == PV_KEY;
4311}
4312#endif
4313
4314/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00004315 * Set the value of option "name".
4316 * Use "string" for string options, use "number" for other options.
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004317 *
4318 * Returns NULL on success or error message on error.
Bram Moolenaar071d4272004-06-13 20:20:40 +00004319 */
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004320 char *
Bram Moolenaar9b578142016-01-30 19:39:49 +01004321set_option_value(
4322 char_u *name,
4323 long number,
4324 char_u *string,
4325 int opt_flags) /* OPT_LOCAL or 0 (both) */
Bram Moolenaar071d4272004-06-13 20:20:40 +00004326{
4327 int opt_idx;
4328 char_u *varp;
Bram Moolenaara93fa7e2006-04-17 22:14:47 +00004329 long_u flags;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004330
4331 opt_idx = findoption(name);
Bram Moolenaarfc1421e2006-04-20 22:17:20 +00004332 if (opt_idx < 0)
Bram Moolenaare353c402017-02-04 19:49:16 +01004333 {
4334 int key;
4335
4336 if (STRLEN(name) == 4 && name[0] == 't' && name[1] == '_'
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02004337 && (key = find_key_option(name, FALSE)) != 0)
Bram Moolenaare353c402017-02-04 19:49:16 +01004338 {
4339 char_u key_name[2];
4340
4341 if (key < 0)
4342 {
4343 key_name[0] = KEY2TERMCAP0(key);
4344 key_name[1] = KEY2TERMCAP1(key);
4345 }
4346 else
4347 {
4348 key_name[0] = KS_KEY;
4349 key_name[1] = (key & 0xff);
4350 }
4351 add_termcode(key_name, string, FALSE);
4352 if (full_screen)
4353 ttest(FALSE);
4354 redraw_all_later(CLEAR);
4355 return NULL;
4356 }
4357
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004358 semsg(_("E355: Unknown option: %s"), name);
Bram Moolenaare353c402017-02-04 19:49:16 +01004359 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004360 else
4361 {
4362 flags = options[opt_idx].flags;
4363#ifdef HAVE_SANDBOX
4364 /* Disallow changing some options in the sandbox */
4365 if (sandbox > 0 && (flags & P_SECURE))
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00004366 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004367 emsg(_(e_sandbox));
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004368 return NULL;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00004369 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004370#endif
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00004371 if (flags & P_STRING)
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004372 return set_string_option(opt_idx, string, opt_flags);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004373 else
4374 {
Bram Moolenaarb3163762008-07-08 15:15:08 +00004375 varp = get_varp_scope(&(options[opt_idx]), opt_flags);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004376 if (varp != NULL) /* hidden option is not changed */
4377 {
Bram Moolenaar96bb6212007-06-19 18:52:53 +00004378 if (number == 0 && string != NULL)
4379 {
Bram Moolenaarfe86f2d2008-11-28 20:29:07 +00004380 int idx;
Bram Moolenaar96bb6212007-06-19 18:52:53 +00004381
4382 /* Either we are given a string or we are setting option
4383 * to zero. */
Bram Moolenaarfe86f2d2008-11-28 20:29:07 +00004384 for (idx = 0; string[idx] == '0'; ++idx)
Bram Moolenaar96bb6212007-06-19 18:52:53 +00004385 ;
Bram Moolenaarfe86f2d2008-11-28 20:29:07 +00004386 if (string[idx] != NUL || idx == 0)
Bram Moolenaar96bb6212007-06-19 18:52:53 +00004387 {
4388 /* There's another character after zeros or the string
4389 * is empty. In both cases, we are trying to set a
4390 * num option using a string. */
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004391 semsg(_("E521: Number required: &%s = '%s'"),
Bram Moolenaar96bb6212007-06-19 18:52:53 +00004392 name, string);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004393 return NULL; /* do nothing as we hit an error */
Bram Moolenaar96bb6212007-06-19 18:52:53 +00004394
4395 }
4396 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004397 if (flags & P_NUM)
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004398 return set_num_option(opt_idx, varp, number,
Bram Moolenaar555b2802005-05-19 21:08:39 +00004399 NULL, 0, opt_flags);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004400 else
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004401 return set_bool_option(opt_idx, varp, (int)number,
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00004402 opt_flags);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004403 }
4404 }
4405 }
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004406 return NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004407}
4408
4409/*
4410 * Get the terminal code for a terminal option.
4411 * Returns NULL when not found.
4412 */
4413 char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01004414get_term_code(char_u *tname)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004415{
4416 int opt_idx;
4417 char_u *varp;
4418
4419 if (tname[0] != 't' || tname[1] != '_' ||
4420 tname[2] == NUL || tname[3] == NUL)
4421 return NULL;
4422 if ((opt_idx = findoption(tname)) >= 0)
4423 {
4424 varp = get_varp(&(options[opt_idx]));
4425 if (varp != NULL)
4426 varp = *(char_u **)(varp);
4427 return varp;
4428 }
4429 return find_termcode(tname + 2);
4430}
4431
4432 char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01004433get_highlight_default(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004434{
4435 int i;
4436
4437 i = findoption((char_u *)"hl");
4438 if (i >= 0)
4439 return options[i].def_val[VI_DEFAULT];
4440 return (char_u *)NULL;
4441}
4442
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00004443 char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01004444get_encoding_default(void)
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00004445{
4446 int i;
4447
4448 i = findoption((char_u *)"enc");
4449 if (i >= 0)
4450 return options[i].def_val[VI_DEFAULT];
4451 return (char_u *)NULL;
4452}
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00004453
Bram Moolenaar071d4272004-06-13 20:20:40 +00004454/*
4455 * Translate a string like "t_xx", "<t_xx>" or "<S-Tab>" to a key number.
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02004456 * When "has_lt" is true there is a '<' before "*arg_arg".
4457 * Returns 0 when the key is not recognized.
Bram Moolenaar071d4272004-06-13 20:20:40 +00004458 */
4459 static int
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02004460find_key_option(char_u *arg_arg, int has_lt)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004461{
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02004462 int key = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004463 int modifiers;
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02004464 char_u *arg = arg_arg;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004465
4466 /*
4467 * Don't use get_special_key_code() for t_xx, we don't want it to call
4468 * add_termcap_entry().
4469 */
4470 if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
4471 key = TERMCAP2KEY(arg[2], arg[3]);
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02004472 else if (has_lt)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004473 {
4474 --arg; /* put arg at the '<' */
4475 modifiers = 0;
Bram Moolenaar35a4cfa2016-08-14 16:07:48 +02004476 key = find_special_key(&arg, &modifiers, TRUE, TRUE, FALSE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004477 if (modifiers) /* can't handle modifiers here */
4478 key = 0;
4479 }
4480 return key;
4481}
4482
4483/*
4484 * if 'all' == 0: show changed options
4485 * if 'all' == 1: show all normal options
4486 * if 'all' == 2: show all terminal options
4487 */
4488 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01004489showoptions(
4490 int all,
4491 int opt_flags) /* OPT_LOCAL and/or OPT_GLOBAL */
Bram Moolenaar071d4272004-06-13 20:20:40 +00004492{
4493 struct vimoption *p;
4494 int col;
4495 int isterm;
4496 char_u *varp;
4497 struct vimoption **items;
4498 int item_count;
4499 int run;
4500 int row, rows;
4501 int cols;
4502 int i;
4503 int len;
4504
4505#define INC 20
4506#define GAP 3
4507
Bram Moolenaarc799fe22019-05-28 23:08:19 +02004508 items = ALLOC_MULT(struct vimoption *, PARAM_COUNT);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004509 if (items == NULL)
4510 return;
4511
4512 /* Highlight title */
4513 if (all == 2)
Bram Moolenaar32526b32019-01-19 17:43:09 +01004514 msg_puts_title(_("\n--- Terminal codes ---"));
Bram Moolenaar071d4272004-06-13 20:20:40 +00004515 else if (opt_flags & OPT_GLOBAL)
Bram Moolenaar32526b32019-01-19 17:43:09 +01004516 msg_puts_title(_("\n--- Global option values ---"));
Bram Moolenaar071d4272004-06-13 20:20:40 +00004517 else if (opt_flags & OPT_LOCAL)
Bram Moolenaar32526b32019-01-19 17:43:09 +01004518 msg_puts_title(_("\n--- Local option values ---"));
Bram Moolenaar071d4272004-06-13 20:20:40 +00004519 else
Bram Moolenaar32526b32019-01-19 17:43:09 +01004520 msg_puts_title(_("\n--- Options ---"));
Bram Moolenaar071d4272004-06-13 20:20:40 +00004521
4522 /*
4523 * do the loop two times:
4524 * 1. display the short items
4525 * 2. display the long items (only strings and numbers)
4526 */
4527 for (run = 1; run <= 2 && !got_int; ++run)
4528 {
4529 /*
4530 * collect the items in items[]
4531 */
4532 item_count = 0;
4533 for (p = &options[0]; p->fullname != NULL; p++)
4534 {
Bram Moolenaarf86db782018-10-25 13:31:37 +02004535 // apply :filter /pat/
4536 if (message_filtered((char_u *) p->fullname))
4537 continue;
4538
Bram Moolenaar071d4272004-06-13 20:20:40 +00004539 varp = NULL;
4540 isterm = istermoption(p);
4541 if (opt_flags != 0)
4542 {
4543 if (p->indir != PV_NONE && !isterm)
4544 varp = get_varp_scope(p, opt_flags);
4545 }
4546 else
4547 varp = get_varp(p);
4548 if (varp != NULL
4549 && ((all == 2 && isterm)
4550 || (all == 1 && !isterm)
Bram Moolenaarcacc6a52019-05-30 15:22:43 +02004551 || (all == 0 && !optval_default(p, varp, p_cp))))
Bram Moolenaar071d4272004-06-13 20:20:40 +00004552 {
4553 if (p->flags & P_BOOL)
4554 len = 1; /* a toggle option fits always */
4555 else
4556 {
4557 option_value2string(p, opt_flags);
4558 len = (int)STRLEN(p->fullname) + vim_strsize(NameBuff) + 1;
4559 }
4560 if ((len <= INC - GAP && run == 1) ||
4561 (len > INC - GAP && run == 2))
4562 items[item_count++] = p;
4563 }
4564 }
4565
4566 /*
4567 * display the items
4568 */
4569 if (run == 1)
4570 {
4571 cols = (Columns + GAP - 3) / INC;
4572 if (cols == 0)
4573 cols = 1;
4574 rows = (item_count + cols - 1) / cols;
4575 }
4576 else /* run == 2 */
4577 rows = item_count;
4578 for (row = 0; row < rows && !got_int; ++row)
4579 {
4580 msg_putchar('\n'); /* go to next line */
4581 if (got_int) /* 'q' typed in more */
4582 break;
4583 col = 0;
4584 for (i = row; i < item_count; i += rows)
4585 {
4586 msg_col = col; /* make columns */
4587 showoneopt(items[i], opt_flags);
4588 col += INC;
4589 }
4590 out_flush();
4591 ui_breakcheck();
4592 }
4593 }
4594 vim_free(items);
4595}
4596
4597/*
4598 * Return TRUE if option "p" has its default value.
4599 */
4600 static int
Bram Moolenaarcacc6a52019-05-30 15:22:43 +02004601optval_default(struct vimoption *p, char_u *varp, int compatible)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004602{
4603 int dvi;
4604
4605 if (varp == NULL)
4606 return TRUE; /* hidden option is always at default */
Bram Moolenaarcacc6a52019-05-30 15:22:43 +02004607 dvi = ((p->flags & P_VI_DEF) || compatible) ? VI_DEFAULT : VIM_DEFAULT;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004608 if (p->flags & P_NUM)
Bram Moolenaareb3593b2006-04-22 22:33:57 +00004609 return (*(long *)varp == (long)(long_i)p->def_val[dvi]);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004610 if (p->flags & P_BOOL)
Bram Moolenaareb3593b2006-04-22 22:33:57 +00004611 /* the cast to long is required for Manx C, long_i is
4612 * needed for MSVC */
4613 return (*(int *)varp == (int)(long)(long_i)p->def_val[dvi]);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004614 /* P_STRING */
4615 return (STRCMP(*(char_u **)varp, p->def_val[dvi]) == 0);
4616}
4617
4618/*
4619 * showoneopt: show the value of one option
4620 * must not be called with a hidden option!
4621 */
4622 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01004623showoneopt(
4624 struct vimoption *p,
4625 int opt_flags) /* OPT_LOCAL or OPT_GLOBAL */
Bram Moolenaar071d4272004-06-13 20:20:40 +00004626{
Bram Moolenaar26a60b42005-02-22 08:49:11 +00004627 char_u *varp;
4628 int save_silent = silent_mode;
4629
4630 silent_mode = FALSE;
4631 info_message = TRUE; /* use mch_msg(), not mch_errmsg() */
Bram Moolenaar071d4272004-06-13 20:20:40 +00004632
4633 varp = get_varp_scope(p, opt_flags);
4634
4635 /* for 'modified' we also need to check if 'ff' or 'fenc' changed. */
4636 if ((p->flags & P_BOOL) && ((int *)varp == &curbuf->b_changed
4637 ? !curbufIsChanged() : !*(int *)varp))
Bram Moolenaar32526b32019-01-19 17:43:09 +01004638 msg_puts("no");
Bram Moolenaar071d4272004-06-13 20:20:40 +00004639 else if ((p->flags & P_BOOL) && *(int *)varp < 0)
Bram Moolenaar32526b32019-01-19 17:43:09 +01004640 msg_puts("--");
Bram Moolenaar071d4272004-06-13 20:20:40 +00004641 else
Bram Moolenaar32526b32019-01-19 17:43:09 +01004642 msg_puts(" ");
4643 msg_puts(p->fullname);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004644 if (!(p->flags & P_BOOL))
4645 {
4646 msg_putchar('=');
4647 /* put value string in NameBuff */
4648 option_value2string(p, opt_flags);
4649 msg_outtrans(NameBuff);
4650 }
Bram Moolenaar26a60b42005-02-22 08:49:11 +00004651
4652 silent_mode = save_silent;
4653 info_message = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004654}
4655
4656/*
4657 * Write modified options as ":set" commands to a file.
4658 *
4659 * There are three values for "opt_flags":
4660 * OPT_GLOBAL: Write global option values and fresh values of
4661 * buffer-local options (used for start of a session
4662 * file).
4663 * OPT_GLOBAL + OPT_LOCAL: Idem, add fresh values of window-local options for
4664 * curwin (used for a vimrc file).
4665 * OPT_LOCAL: Write buffer-local option values for curbuf, fresh
4666 * and local values for window-local options of
4667 * curwin. Local values are also written when at the
4668 * default value, because a modeline or autocommand
4669 * may have set them when doing ":edit file" and the
4670 * user has set them back at the default or fresh
4671 * value.
4672 * When "local_only" is TRUE, don't write fresh
4673 * values, only local values (for ":mkview").
4674 * (fresh value = value used for a new buffer or window for a local option).
4675 *
4676 * Return FAIL on error, OK otherwise.
4677 */
4678 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01004679makeset(FILE *fd, int opt_flags, int local_only)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004680{
4681 struct vimoption *p;
4682 char_u *varp; /* currently used value */
4683 char_u *varp_fresh; /* local value */
4684 char_u *varp_local = NULL; /* fresh value */
4685 char *cmd;
4686 int round;
Bram Moolenaar7fd16022007-09-06 14:35:35 +00004687 int pri;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004688
4689 /*
4690 * The options that don't have a default (terminal name, columns, lines)
4691 * are never written. Terminal options are also not written.
Bram Moolenaar7fd16022007-09-06 14:35:35 +00004692 * Do the loop over "options[]" twice: once for options with the
4693 * P_PRI_MKRC flag and once without.
Bram Moolenaar071d4272004-06-13 20:20:40 +00004694 */
Bram Moolenaar7fd16022007-09-06 14:35:35 +00004695 for (pri = 1; pri >= 0; --pri)
4696 {
4697 for (p = &options[0]; !istermoption(p); p++)
4698 if (!(p->flags & P_NO_MKRC)
4699 && !istermoption(p)
4700 && ((pri == 1) == ((p->flags & P_PRI_MKRC) != 0)))
Bram Moolenaar071d4272004-06-13 20:20:40 +00004701 {
4702 /* skip global option when only doing locals */
4703 if (p->indir == PV_NONE && !(opt_flags & OPT_GLOBAL))
4704 continue;
4705
4706 /* Do not store options like 'bufhidden' and 'syntax' in a vimrc
4707 * file, they are always buffer-specific. */
4708 if ((opt_flags & OPT_GLOBAL) && (p->flags & P_NOGLOB))
4709 continue;
4710
4711 /* Global values are only written when not at the default value. */
4712 varp = get_varp_scope(p, opt_flags);
Bram Moolenaarcacc6a52019-05-30 15:22:43 +02004713 if ((opt_flags & OPT_GLOBAL) && optval_default(p, varp, p_cp))
Bram Moolenaar071d4272004-06-13 20:20:40 +00004714 continue;
4715
4716 round = 2;
4717 if (p->indir != PV_NONE)
4718 {
4719 if (p->var == VAR_WIN)
4720 {
4721 /* skip window-local option when only doing globals */
4722 if (!(opt_flags & OPT_LOCAL))
4723 continue;
4724 /* When fresh value of window-local option is not at the
4725 * default, need to write it too. */
4726 if (!(opt_flags & OPT_GLOBAL) && !local_only)
4727 {
4728 varp_fresh = get_varp_scope(p, OPT_GLOBAL);
Bram Moolenaarcacc6a52019-05-30 15:22:43 +02004729 if (!optval_default(p, varp_fresh, p_cp))
Bram Moolenaar071d4272004-06-13 20:20:40 +00004730 {
4731 round = 1;
4732 varp_local = varp;
4733 varp = varp_fresh;
4734 }
4735 }
4736 }
4737 }
4738
4739 /* Round 1: fresh value for window-local options.
4740 * Round 2: other values */
4741 for ( ; round <= 2; varp = varp_local, ++round)
4742 {
4743 if (round == 1 || (opt_flags & OPT_GLOBAL))
4744 cmd = "set";
4745 else
4746 cmd = "setlocal";
4747
4748 if (p->flags & P_BOOL)
4749 {
4750 if (put_setbool(fd, cmd, p->fullname, *(int *)varp) == FAIL)
4751 return FAIL;
4752 }
4753 else if (p->flags & P_NUM)
4754 {
4755 if (put_setnum(fd, cmd, p->fullname, (long *)varp) == FAIL)
4756 return FAIL;
4757 }
4758 else /* P_STRING */
4759 {
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00004760 int do_endif = FALSE;
4761
Bram Moolenaar071d4272004-06-13 20:20:40 +00004762 /* Don't set 'syntax' and 'filetype' again if the value is
4763 * already right, avoids reloading the syntax file. */
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00004764 if (
Bram Moolenaarf2bd8ef2018-03-04 18:08:14 +01004765#if defined(FEAT_SYN_HL)
4766 p->indir == PV_SYN ||
4767#endif
4768 p->indir == PV_FT)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004769 {
4770 if (fprintf(fd, "if &%s != '%s'", p->fullname,
4771 *(char_u **)(varp)) < 0
4772 || put_eol(fd) < 0)
4773 return FAIL;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00004774 do_endif = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004775 }
4776 if (put_setstring(fd, cmd, p->fullname, (char_u **)varp,
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004777 p->flags) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004778 return FAIL;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00004779 if (do_endif)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004780 {
4781 if (put_line(fd, "endif") == FAIL)
4782 return FAIL;
4783 }
4784 }
4785 }
4786 }
Bram Moolenaar7fd16022007-09-06 14:35:35 +00004787 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004788 return OK;
4789}
4790
4791#if defined(FEAT_FOLDING) || defined(PROTO)
4792/*
4793 * Generate set commands for the local fold options only. Used when
4794 * 'sessionoptions' or 'viewoptions' contains "folds" but not "options".
4795 */
4796 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01004797makefoldset(FILE *fd)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004798{
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004799 if (put_setstring(fd, "setlocal", "fdm", &curwin->w_p_fdm, 0) == FAIL
Bram Moolenaar071d4272004-06-13 20:20:40 +00004800# ifdef FEAT_EVAL
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004801 || put_setstring(fd, "setlocal", "fde", &curwin->w_p_fde, 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004802 == FAIL
4803# endif
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004804 || put_setstring(fd, "setlocal", "fmr", &curwin->w_p_fmr, 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004805 == FAIL
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004806 || put_setstring(fd, "setlocal", "fdi", &curwin->w_p_fdi, 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004807 == FAIL
4808 || put_setnum(fd, "setlocal", "fdl", &curwin->w_p_fdl) == FAIL
4809 || put_setnum(fd, "setlocal", "fml", &curwin->w_p_fml) == FAIL
4810 || put_setnum(fd, "setlocal", "fdn", &curwin->w_p_fdn) == FAIL
4811 || put_setbool(fd, "setlocal", "fen", curwin->w_p_fen) == FAIL
4812 )
4813 return FAIL;
4814
4815 return OK;
4816}
4817#endif
4818
4819 static int
Bram Moolenaar9b578142016-01-30 19:39:49 +01004820put_setstring(
4821 FILE *fd,
4822 char *cmd,
4823 char *name,
4824 char_u **valuep,
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004825 long_u flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004826{
4827 char_u *s;
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004828 char_u *buf = NULL;
4829 char_u *part = NULL;
4830 char_u *p;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004831
4832 if (fprintf(fd, "%s %s=", cmd, name) < 0)
4833 return FAIL;
4834 if (*valuep != NULL)
4835 {
4836 /* Output 'pastetoggle' as key names. For other
4837 * options some characters have to be escaped with
4838 * CTRL-V or backslash */
4839 if (valuep == &p_pt)
4840 {
4841 s = *valuep;
4842 while (*s != NUL)
Bram Moolenaar7d96acd2008-06-09 15:07:54 +00004843 if (put_escstr(fd, str2special(&s, FALSE), 2) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004844 return FAIL;
4845 }
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004846 // expand the option value, replace $HOME by ~
4847 else if ((flags & P_EXPAND) != 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004848 {
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004849 int size = (int)STRLEN(*valuep) + 1;
4850
4851 // replace home directory in the whole option value into "buf"
4852 buf = alloc(size);
Bram Moolenaarf8441472011-04-28 17:24:58 +02004853 if (buf == NULL)
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004854 goto fail;
4855 home_replace(NULL, *valuep, buf, size, FALSE);
4856
4857 // If the option value is longer than MAXPATHL, we need to append
4858 // earch comma separated part of the option separately, so that it
4859 // can be expanded when read back.
4860 if (size >= MAXPATHL && (flags & P_COMMA) != 0
4861 && vim_strchr(*valuep, ',') != NULL)
4862 {
4863 part = alloc(size);
4864 if (part == NULL)
4865 goto fail;
4866
4867 // write line break to clear the option, e.g. ':set rtp='
4868 if (put_eol(fd) == FAIL)
4869 goto fail;
4870
4871 p = buf;
4872 while (*p != NUL)
4873 {
4874 // for each comma separated option part, append value to
4875 // the option, :set rtp+=value
4876 if (fprintf(fd, "%s %s+=", cmd, name) < 0)
4877 goto fail;
4878 (void)copy_option_part(&p, part, size, ",");
4879 if (put_escstr(fd, part, 2) == FAIL || put_eol(fd) == FAIL)
4880 goto fail;
4881 }
4882 vim_free(buf);
4883 vim_free(part);
4884 return OK;
4885 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004886 if (put_escstr(fd, buf, 2) == FAIL)
Bram Moolenaarf8441472011-04-28 17:24:58 +02004887 {
4888 vim_free(buf);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004889 return FAIL;
Bram Moolenaarf8441472011-04-28 17:24:58 +02004890 }
4891 vim_free(buf);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004892 }
4893 else if (put_escstr(fd, *valuep, 2) == FAIL)
4894 return FAIL;
4895 }
4896 if (put_eol(fd) < 0)
4897 return FAIL;
4898 return OK;
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004899fail:
4900 vim_free(buf);
4901 vim_free(part);
4902 return FAIL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004903}
4904
4905 static int
Bram Moolenaar9b578142016-01-30 19:39:49 +01004906put_setnum(
4907 FILE *fd,
4908 char *cmd,
4909 char *name,
4910 long *valuep)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004911{
4912 long wc;
4913
4914 if (fprintf(fd, "%s %s=", cmd, name) < 0)
4915 return FAIL;
4916 if (wc_use_keyname((char_u *)valuep, &wc))
4917 {
4918 /* print 'wildchar' and 'wildcharm' as a key name */
4919 if (fputs((char *)get_special_key_name((int)wc, 0), fd) < 0)
4920 return FAIL;
4921 }
4922 else if (fprintf(fd, "%ld", *valuep) < 0)
4923 return FAIL;
4924 if (put_eol(fd) < 0)
4925 return FAIL;
4926 return OK;
4927}
4928
4929 static int
Bram Moolenaar9b578142016-01-30 19:39:49 +01004930put_setbool(
4931 FILE *fd,
4932 char *cmd,
4933 char *name,
4934 int value)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004935{
Bram Moolenaar893de922007-10-02 18:40:57 +00004936 if (value < 0) /* global/local option using global value */
4937 return OK;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004938 if (fprintf(fd, "%s %s%s", cmd, value ? "" : "no", name) < 0
4939 || put_eol(fd) < 0)
4940 return FAIL;
4941 return OK;
4942}
4943
4944/*
4945 * Clear all the terminal options.
4946 * If the option has been allocated, free the memory.
4947 * Terminal options are never hidden or indirect.
4948 */
4949 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01004950clear_termoptions(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004951{
Bram Moolenaar071d4272004-06-13 20:20:40 +00004952 /*
4953 * Reset a few things before clearing the old options. This may cause
4954 * outputting a few things that the terminal doesn't understand, but the
4955 * screen will be cleared later, so this is OK.
4956 */
4957#ifdef FEAT_MOUSE_TTY
4958 mch_setmouse(FALSE); /* switch mouse off */
4959#endif
4960#ifdef FEAT_TITLE
Bram Moolenaar40385db2018-08-07 22:31:44 +02004961 mch_restore_title(SAVE_RESTORE_BOTH); /* restore window titles */
Bram Moolenaar071d4272004-06-13 20:20:40 +00004962#endif
4963#if defined(FEAT_XCLIPBOARD) && defined(FEAT_GUI)
4964 /* When starting the GUI close the display opened for the clipboard.
4965 * After restoring the title, because that will need the display. */
4966 if (gui.starting)
4967 clear_xterm_clip();
4968#endif
Bram Moolenaarcea912a2016-10-12 14:20:24 +02004969 stoptermcap(); /* stop termcap mode */
Bram Moolenaar071d4272004-06-13 20:20:40 +00004970
Bram Moolenaarf461c8e2005-06-25 23:04:51 +00004971 free_termoptions();
4972}
4973
4974 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01004975free_termoptions(void)
Bram Moolenaarf461c8e2005-06-25 23:04:51 +00004976{
4977 struct vimoption *p;
4978
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02004979 for (p = options; p->fullname != NULL; p++)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004980 if (istermoption(p))
4981 {
4982 if (p->flags & P_ALLOCED)
4983 free_string_option(*(char_u **)(p->var));
4984 if (p->flags & P_DEF_ALLOCED)
4985 free_string_option(p->def_val[VI_DEFAULT]);
4986 *(char_u **)(p->var) = empty_option;
4987 p->def_val[VI_DEFAULT] = empty_option;
4988 p->flags &= ~(P_ALLOCED|P_DEF_ALLOCED);
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02004989#ifdef FEAT_EVAL
4990 // remember where the option was cleared
4991 set_option_sctx_idx((int)(p - options), OPT_GLOBAL, current_sctx);
4992#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00004993 }
4994 clear_termcodes();
4995}
4996
4997/*
Bram Moolenaar363cb672009-07-22 12:28:17 +00004998 * Free the string for one term option, if it was allocated.
4999 * Set the string to empty_option and clear allocated flag.
5000 * "var" points to the option value.
5001 */
5002 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005003free_one_termoption(char_u *var)
Bram Moolenaar363cb672009-07-22 12:28:17 +00005004{
5005 struct vimoption *p;
5006
5007 for (p = &options[0]; p->fullname != NULL; p++)
5008 if (p->var == var)
5009 {
5010 if (p->flags & P_ALLOCED)
5011 free_string_option(*(char_u **)(p->var));
5012 *(char_u **)(p->var) = empty_option;
5013 p->flags &= ~P_ALLOCED;
5014 break;
5015 }
5016}
5017
5018/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005019 * Set the terminal option defaults to the current value.
5020 * Used after setting the terminal name.
5021 */
5022 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005023set_term_defaults(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005024{
5025 struct vimoption *p;
5026
5027 for (p = &options[0]; p->fullname != NULL; p++)
5028 {
5029 if (istermoption(p) && p->def_val[VI_DEFAULT] != *(char_u **)(p->var))
5030 {
5031 if (p->flags & P_DEF_ALLOCED)
5032 {
5033 free_string_option(p->def_val[VI_DEFAULT]);
5034 p->flags &= ~P_DEF_ALLOCED;
5035 }
5036 p->def_val[VI_DEFAULT] = *(char_u **)(p->var);
5037 if (p->flags & P_ALLOCED)
5038 {
5039 p->flags |= P_DEF_ALLOCED;
5040 p->flags &= ~P_ALLOCED; /* don't free the value now */
5041 }
5042 }
5043 }
5044}
5045
5046/*
5047 * return TRUE if 'p' starts with 't_'
5048 */
5049 static int
Bram Moolenaar9b578142016-01-30 19:39:49 +01005050istermoption(struct vimoption *p)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005051{
5052 return (p->fullname[0] == 't' && p->fullname[1] == '_');
5053}
5054
Bram Moolenaardac13472019-09-16 21:06:21 +02005055/*
5056 * Returns TRUE if the option at 'opt_idx' starts with 't_'
5057 */
5058 int
5059istermoption_idx(int opt_idx)
5060{
5061 return istermoption(&options[opt_idx]);
5062}
5063
Bram Moolenaar113e1072019-01-20 15:30:40 +01005064#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005065/*
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005066 * Unset local option value, similar to ":set opt<".
5067 */
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005068 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005069unset_global_local_option(char_u *name, void *from)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005070{
5071 struct vimoption *p;
5072 int opt_idx;
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005073 buf_T *buf = (buf_T *)from;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005074
5075 opt_idx = findoption(name);
Bram Moolenaarbd8539a2015-08-11 18:53:03 +02005076 if (opt_idx < 0)
5077 return;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005078 p = &(options[opt_idx]);
5079
5080 switch ((int)p->indir)
5081 {
5082 /* global option with local value: use local value if it's been set */
5083 case PV_EP:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005084 clear_string_option(&buf->b_p_ep);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005085 break;
5086 case PV_KP:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005087 clear_string_option(&buf->b_p_kp);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005088 break;
5089 case PV_PATH:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005090 clear_string_option(&buf->b_p_path);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005091 break;
5092 case PV_AR:
5093 buf->b_p_ar = -1;
5094 break;
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02005095 case PV_BKC:
5096 clear_string_option(&buf->b_p_bkc);
5097 buf->b_bkc_flags = 0;
5098 break;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005099 case PV_TAGS:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005100 clear_string_option(&buf->b_p_tags);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005101 break;
Bram Moolenaar0f6562e2015-11-24 18:48:14 +01005102 case PV_TC:
5103 clear_string_option(&buf->b_p_tc);
5104 buf->b_tc_flags = 0;
5105 break;
Bram Moolenaar375e3392019-01-31 18:26:10 +01005106 case PV_SISO:
5107 curwin->w_p_siso = -1;
5108 break;
5109 case PV_SO:
5110 curwin->w_p_so = -1;
5111 break;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005112#ifdef FEAT_FIND_ID
5113 case PV_DEF:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005114 clear_string_option(&buf->b_p_def);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005115 break;
5116 case PV_INC:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005117 clear_string_option(&buf->b_p_inc);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005118 break;
5119#endif
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005120 case PV_DICT:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005121 clear_string_option(&buf->b_p_dict);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005122 break;
5123 case PV_TSR:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005124 clear_string_option(&buf->b_p_tsr);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005125 break;
Bram Moolenaar9be7c042017-01-14 14:28:30 +01005126 case PV_FP:
5127 clear_string_option(&buf->b_p_fp);
5128 break;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005129#ifdef FEAT_QUICKFIX
5130 case PV_EFM:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005131 clear_string_option(&buf->b_p_efm);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005132 break;
5133 case PV_GP:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005134 clear_string_option(&buf->b_p_gp);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005135 break;
5136 case PV_MP:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005137 clear_string_option(&buf->b_p_mp);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005138 break;
5139#endif
5140#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
5141 case PV_BEXPR:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005142 clear_string_option(&buf->b_p_bexpr);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005143 break;
5144#endif
5145#if defined(FEAT_CRYPT)
5146 case PV_CM:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005147 clear_string_option(&buf->b_p_cm);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005148 break;
5149#endif
5150#ifdef FEAT_STL_OPT
5151 case PV_STL:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005152 clear_string_option(&((win_T *)from)->w_p_stl);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005153 break;
5154#endif
Bram Moolenaarf5a2fd82013-11-06 05:26:15 +01005155 case PV_UL:
5156 buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
5157 break;
Bram Moolenaaraf6c1312014-03-12 18:55:58 +01005158#ifdef FEAT_LISP
5159 case PV_LW:
5160 clear_string_option(&buf->b_p_lw);
5161 break;
5162#endif
Bram Moolenaar2c7292d2017-03-05 17:43:31 +01005163 case PV_MENC:
5164 clear_string_option(&buf->b_p_menc);
5165 break;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005166 }
5167}
Bram Moolenaar113e1072019-01-20 15:30:40 +01005168#endif
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005169
5170/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005171 * Get pointer to option variable, depending on local or global scope.
5172 */
5173 static char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01005174get_varp_scope(struct vimoption *p, int opt_flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005175{
5176 if ((opt_flags & OPT_GLOBAL) && p->indir != PV_NONE)
5177 {
5178 if (p->var == VAR_WIN)
5179 return (char_u *)GLOBAL_WO(get_varp(p));
5180 return p->var;
5181 }
Bram Moolenaara23ccb82006-02-27 00:08:02 +00005182 if ((opt_flags & OPT_LOCAL) && ((int)p->indir & PV_BOTH))
Bram Moolenaar071d4272004-06-13 20:20:40 +00005183 {
5184 switch ((int)p->indir)
5185 {
Bram Moolenaar9be7c042017-01-14 14:28:30 +01005186 case PV_FP: return (char_u *)&(curbuf->b_p_fp);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005187#ifdef FEAT_QUICKFIX
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005188 case PV_EFM: return (char_u *)&(curbuf->b_p_efm);
5189 case PV_GP: return (char_u *)&(curbuf->b_p_gp);
5190 case PV_MP: return (char_u *)&(curbuf->b_p_mp);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005191#endif
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005192 case PV_EP: return (char_u *)&(curbuf->b_p_ep);
5193 case PV_KP: return (char_u *)&(curbuf->b_p_kp);
5194 case PV_PATH: return (char_u *)&(curbuf->b_p_path);
Bram Moolenaara23ccb82006-02-27 00:08:02 +00005195 case PV_AR: return (char_u *)&(curbuf->b_p_ar);
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005196 case PV_TAGS: return (char_u *)&(curbuf->b_p_tags);
Bram Moolenaar0f6562e2015-11-24 18:48:14 +01005197 case PV_TC: return (char_u *)&(curbuf->b_p_tc);
Bram Moolenaar375e3392019-01-31 18:26:10 +01005198 case PV_SISO: return (char_u *)&(curwin->w_p_siso);
5199 case PV_SO: return (char_u *)&(curwin->w_p_so);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005200#ifdef FEAT_FIND_ID
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005201 case PV_DEF: return (char_u *)&(curbuf->b_p_def);
5202 case PV_INC: return (char_u *)&(curbuf->b_p_inc);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005203#endif
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005204 case PV_DICT: return (char_u *)&(curbuf->b_p_dict);
5205 case PV_TSR: return (char_u *)&(curbuf->b_p_tsr);
Bram Moolenaar9b2200a2006-03-20 21:55:45 +00005206#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
5207 case PV_BEXPR: return (char_u *)&(curbuf->b_p_bexpr);
5208#endif
Bram Moolenaar49771f42010-07-20 17:32:38 +02005209#if defined(FEAT_CRYPT)
5210 case PV_CM: return (char_u *)&(curbuf->b_p_cm);
5211#endif
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005212#ifdef FEAT_STL_OPT
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005213 case PV_STL: return (char_u *)&(curwin->w_p_stl);
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005214#endif
Bram Moolenaarf5a2fd82013-11-06 05:26:15 +01005215 case PV_UL: return (char_u *)&(curbuf->b_p_ul);
Bram Moolenaaraf6c1312014-03-12 18:55:58 +01005216#ifdef FEAT_LISP
5217 case PV_LW: return (char_u *)&(curbuf->b_p_lw);
5218#endif
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02005219 case PV_BKC: return (char_u *)&(curbuf->b_p_bkc);
Bram Moolenaar2c7292d2017-03-05 17:43:31 +01005220 case PV_MENC: return (char_u *)&(curbuf->b_p_menc);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005221 }
5222 return NULL; /* "cannot happen" */
5223 }
5224 return get_varp(p);
5225}
5226
5227/*
Bram Moolenaardac13472019-09-16 21:06:21 +02005228 * Get pointer to option variable at 'opt_idx', depending on local or global
5229 * scope.
5230 */
5231 char_u *
5232get_option_varp_scope(int opt_idx, int opt_flags)
5233{
5234 return get_varp_scope(&(options[opt_idx]), opt_flags);
5235}
5236
5237/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005238 * Get pointer to option variable.
5239 */
5240 static char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01005241get_varp(struct vimoption *p)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005242{
5243 /* hidden option, always return NULL */
5244 if (p->var == NULL)
5245 return NULL;
5246
5247 switch ((int)p->indir)
5248 {
5249 case PV_NONE: return p->var;
5250
5251 /* global option with local value: use local value if it's been set */
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005252 case PV_EP: return *curbuf->b_p_ep != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005253 ? (char_u *)&curbuf->b_p_ep : p->var;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005254 case PV_KP: return *curbuf->b_p_kp != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005255 ? (char_u *)&curbuf->b_p_kp : p->var;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005256 case PV_PATH: return *curbuf->b_p_path != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005257 ? (char_u *)&(curbuf->b_p_path) : p->var;
Bram Moolenaara23ccb82006-02-27 00:08:02 +00005258 case PV_AR: return curbuf->b_p_ar >= 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00005259 ? (char_u *)&(curbuf->b_p_ar) : p->var;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005260 case PV_TAGS: return *curbuf->b_p_tags != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005261 ? (char_u *)&(curbuf->b_p_tags) : p->var;
Bram Moolenaar0f6562e2015-11-24 18:48:14 +01005262 case PV_TC: return *curbuf->b_p_tc != NUL
5263 ? (char_u *)&(curbuf->b_p_tc) : p->var;
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02005264 case PV_BKC: return *curbuf->b_p_bkc != NUL
5265 ? (char_u *)&(curbuf->b_p_bkc) : p->var;
Bram Moolenaar375e3392019-01-31 18:26:10 +01005266 case PV_SISO: return curwin->w_p_siso >= 0
5267 ? (char_u *)&(curwin->w_p_siso) : p->var;
5268 case PV_SO: return curwin->w_p_so >= 0
5269 ? (char_u *)&(curwin->w_p_so) : p->var;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005270#ifdef FEAT_FIND_ID
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005271 case PV_DEF: return *curbuf->b_p_def != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005272 ? (char_u *)&(curbuf->b_p_def) : p->var;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005273 case PV_INC: return *curbuf->b_p_inc != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005274 ? (char_u *)&(curbuf->b_p_inc) : p->var;
5275#endif
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005276 case PV_DICT: return *curbuf->b_p_dict != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005277 ? (char_u *)&(curbuf->b_p_dict) : p->var;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005278 case PV_TSR: return *curbuf->b_p_tsr != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005279 ? (char_u *)&(curbuf->b_p_tsr) : p->var;
Bram Moolenaar9be7c042017-01-14 14:28:30 +01005280 case PV_FP: return *curbuf->b_p_fp != NUL
5281 ? (char_u *)&(curbuf->b_p_fp) : p->var;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005282#ifdef FEAT_QUICKFIX
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005283 case PV_EFM: return *curbuf->b_p_efm != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005284 ? (char_u *)&(curbuf->b_p_efm) : p->var;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005285 case PV_GP: return *curbuf->b_p_gp != NUL
5286 ? (char_u *)&(curbuf->b_p_gp) : p->var;
5287 case PV_MP: return *curbuf->b_p_mp != NUL
5288 ? (char_u *)&(curbuf->b_p_mp) : p->var;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005289#endif
Bram Moolenaar9b2200a2006-03-20 21:55:45 +00005290#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
5291 case PV_BEXPR: return *curbuf->b_p_bexpr != NUL
5292 ? (char_u *)&(curbuf->b_p_bexpr) : p->var;
5293#endif
Bram Moolenaar49771f42010-07-20 17:32:38 +02005294#if defined(FEAT_CRYPT)
5295 case PV_CM: return *curbuf->b_p_cm != NUL
5296 ? (char_u *)&(curbuf->b_p_cm) : p->var;
5297#endif
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005298#ifdef FEAT_STL_OPT
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005299 case PV_STL: return *curwin->w_p_stl != NUL
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005300 ? (char_u *)&(curwin->w_p_stl) : p->var;
5301#endif
Bram Moolenaarf5a2fd82013-11-06 05:26:15 +01005302 case PV_UL: return curbuf->b_p_ul != NO_LOCAL_UNDOLEVEL
5303 ? (char_u *)&(curbuf->b_p_ul) : p->var;
Bram Moolenaaraf6c1312014-03-12 18:55:58 +01005304#ifdef FEAT_LISP
5305 case PV_LW: return *curbuf->b_p_lw != NUL
5306 ? (char_u *)&(curbuf->b_p_lw) : p->var;
5307#endif
Bram Moolenaar2c7292d2017-03-05 17:43:31 +01005308 case PV_MENC: return *curbuf->b_p_menc != NUL
5309 ? (char_u *)&(curbuf->b_p_menc) : p->var;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005310#ifdef FEAT_ARABIC
5311 case PV_ARAB: return (char_u *)&(curwin->w_p_arab);
5312#endif
5313 case PV_LIST: return (char_u *)&(curwin->w_p_list);
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005314#ifdef FEAT_SPELL
Bram Moolenaar217ad922005-03-20 22:37:15 +00005315 case PV_SPELL: return (char_u *)&(curwin->w_p_spell);
5316#endif
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005317#ifdef FEAT_SYN_HL
5318 case PV_CUC: return (char_u *)&(curwin->w_p_cuc);
5319 case PV_CUL: return (char_u *)&(curwin->w_p_cul);
Bram Moolenaar410e98a2019-09-09 22:05:49 +02005320 case PV_CULOPT: return (char_u *)&(curwin->w_p_culopt);
Bram Moolenaar1a384422010-07-14 19:53:30 +02005321 case PV_CC: return (char_u *)&(curwin->w_p_cc);
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005322#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005323#ifdef FEAT_DIFF
5324 case PV_DIFF: return (char_u *)&(curwin->w_p_diff);
5325#endif
5326#ifdef FEAT_FOLDING
5327 case PV_FDC: return (char_u *)&(curwin->w_p_fdc);
5328 case PV_FEN: return (char_u *)&(curwin->w_p_fen);
5329 case PV_FDI: return (char_u *)&(curwin->w_p_fdi);
5330 case PV_FDL: return (char_u *)&(curwin->w_p_fdl);
5331 case PV_FDM: return (char_u *)&(curwin->w_p_fdm);
5332 case PV_FML: return (char_u *)&(curwin->w_p_fml);
5333 case PV_FDN: return (char_u *)&(curwin->w_p_fdn);
5334# ifdef FEAT_EVAL
5335 case PV_FDE: return (char_u *)&(curwin->w_p_fde);
5336 case PV_FDT: return (char_u *)&(curwin->w_p_fdt);
5337# endif
5338 case PV_FMR: return (char_u *)&(curwin->w_p_fmr);
5339#endif
5340 case PV_NU: return (char_u *)&(curwin->w_p_nu);
Bram Moolenaar64486672010-05-16 15:46:46 +02005341 case PV_RNU: return (char_u *)&(curwin->w_p_rnu);
Bram Moolenaar592e0a22004-07-03 16:05:59 +00005342#ifdef FEAT_LINEBREAK
5343 case PV_NUW: return (char_u *)&(curwin->w_p_nuw);
5344#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005345 case PV_WFH: return (char_u *)&(curwin->w_p_wfh);
Bram Moolenaar97b2ad32006-03-18 21:40:56 +00005346 case PV_WFW: return (char_u *)&(curwin->w_p_wfw);
Bram Moolenaar4033c552017-09-16 20:54:51 +02005347#if defined(FEAT_QUICKFIX)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005348 case PV_PVW: return (char_u *)&(curwin->w_p_pvw);
5349#endif
5350#ifdef FEAT_RIGHTLEFT
5351 case PV_RL: return (char_u *)&(curwin->w_p_rl);
5352 case PV_RLC: return (char_u *)&(curwin->w_p_rlc);
5353#endif
5354 case PV_SCROLL: return (char_u *)&(curwin->w_p_scr);
5355 case PV_WRAP: return (char_u *)&(curwin->w_p_wrap);
5356#ifdef FEAT_LINEBREAK
5357 case PV_LBR: return (char_u *)&(curwin->w_p_lbr);
Bram Moolenaar597a4222014-06-25 14:39:50 +02005358 case PV_BRI: return (char_u *)&(curwin->w_p_bri);
5359 case PV_BRIOPT: return (char_u *)&(curwin->w_p_briopt);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005360#endif
Bram Moolenaar4d784b22019-05-25 19:51:39 +02005361 case PV_WCR: return (char_u *)&(curwin->w_p_wcr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005362 case PV_SCBIND: return (char_u *)&(curwin->w_p_scb);
Bram Moolenaar860cae12010-06-05 23:22:07 +02005363 case PV_CRBIND: return (char_u *)&(curwin->w_p_crb);
Bram Moolenaar860cae12010-06-05 23:22:07 +02005364#ifdef FEAT_CONCEAL
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005365 case PV_COCU: return (char_u *)&(curwin->w_p_cocu);
5366 case PV_COLE: return (char_u *)&(curwin->w_p_cole);
5367#endif
5368#ifdef FEAT_TERMINAL
Bram Moolenaar6d150f72018-04-21 20:03:20 +02005369 case PV_TWK: return (char_u *)&(curwin->w_p_twk);
5370 case PV_TWS: return (char_u *)&(curwin->w_p_tws);
5371 case PV_TWSL: return (char_u *)&(curbuf->b_p_twsl);
Bram Moolenaar860cae12010-06-05 23:22:07 +02005372#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005373
5374 case PV_AI: return (char_u *)&(curbuf->b_p_ai);
5375 case PV_BIN: return (char_u *)&(curbuf->b_p_bin);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005376 case PV_BOMB: return (char_u *)&(curbuf->b_p_bomb);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005377 case PV_BH: return (char_u *)&(curbuf->b_p_bh);
5378 case PV_BT: return (char_u *)&(curbuf->b_p_bt);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005379 case PV_BL: return (char_u *)&(curbuf->b_p_bl);
5380 case PV_CI: return (char_u *)&(curbuf->b_p_ci);
5381#ifdef FEAT_CINDENT
5382 case PV_CIN: return (char_u *)&(curbuf->b_p_cin);
5383 case PV_CINK: return (char_u *)&(curbuf->b_p_cink);
5384 case PV_CINO: return (char_u *)&(curbuf->b_p_cino);
5385#endif
5386#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
5387 case PV_CINW: return (char_u *)&(curbuf->b_p_cinw);
5388#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005389 case PV_COM: return (char_u *)&(curbuf->b_p_com);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005390#ifdef FEAT_FOLDING
5391 case PV_CMS: return (char_u *)&(curbuf->b_p_cms);
5392#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005393 case PV_CPT: return (char_u *)&(curbuf->b_p_cpt);
Bram Moolenaare2c453d2019-08-21 14:37:09 +02005394#ifdef BACKSLASH_IN_FILENAME
Bram Moolenaarac3150d2019-07-28 16:36:39 +02005395 case PV_CSL: return (char_u *)&(curbuf->b_p_csl);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005396#endif
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00005397#ifdef FEAT_COMPL_FUNC
5398 case PV_CFU: return (char_u *)&(curbuf->b_p_cfu);
Bram Moolenaare344bea2005-09-01 20:46:49 +00005399 case PV_OFU: return (char_u *)&(curbuf->b_p_ofu);
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00005400#endif
Bram Moolenaar45e18cb2019-04-28 18:05:35 +02005401#ifdef FEAT_EVAL
5402 case PV_TFU: return (char_u *)&(curbuf->b_p_tfu);
5403#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005404 case PV_EOL: return (char_u *)&(curbuf->b_p_eol);
Bram Moolenaar34d72d42015-07-17 14:18:08 +02005405 case PV_FIXEOL: return (char_u *)&(curbuf->b_p_fixeol);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005406 case PV_ET: return (char_u *)&(curbuf->b_p_et);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005407 case PV_FENC: return (char_u *)&(curbuf->b_p_fenc);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005408 case PV_FF: return (char_u *)&(curbuf->b_p_ff);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005409 case PV_FT: return (char_u *)&(curbuf->b_p_ft);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005410 case PV_FO: return (char_u *)&(curbuf->b_p_fo);
Bram Moolenaar86b68352004-12-27 21:59:20 +00005411 case PV_FLP: return (char_u *)&(curbuf->b_p_flp);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005412 case PV_IMI: return (char_u *)&(curbuf->b_p_iminsert);
5413 case PV_IMS: return (char_u *)&(curbuf->b_p_imsearch);
5414 case PV_INF: return (char_u *)&(curbuf->b_p_inf);
5415 case PV_ISK: return (char_u *)&(curbuf->b_p_isk);
5416#ifdef FEAT_FIND_ID
5417# ifdef FEAT_EVAL
5418 case PV_INEX: return (char_u *)&(curbuf->b_p_inex);
5419# endif
5420#endif
5421#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
5422 case PV_INDE: return (char_u *)&(curbuf->b_p_inde);
5423 case PV_INDK: return (char_u *)&(curbuf->b_p_indk);
5424#endif
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005425#ifdef FEAT_EVAL
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +00005426 case PV_FEX: return (char_u *)&(curbuf->b_p_fex);
5427#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005428#ifdef FEAT_CRYPT
5429 case PV_KEY: return (char_u *)&(curbuf->b_p_key);
5430#endif
5431#ifdef FEAT_LISP
5432 case PV_LISP: return (char_u *)&(curbuf->b_p_lisp);
5433#endif
5434 case PV_ML: return (char_u *)&(curbuf->b_p_ml);
5435 case PV_MPS: return (char_u *)&(curbuf->b_p_mps);
5436 case PV_MA: return (char_u *)&(curbuf->b_p_ma);
5437 case PV_MOD: return (char_u *)&(curbuf->b_changed);
5438 case PV_NF: return (char_u *)&(curbuf->b_p_nf);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005439 case PV_PI: return (char_u *)&(curbuf->b_p_pi);
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00005440#ifdef FEAT_TEXTOBJ
5441 case PV_QE: return (char_u *)&(curbuf->b_p_qe);
5442#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005443 case PV_RO: return (char_u *)&(curbuf->b_p_ro);
5444#ifdef FEAT_SMARTINDENT
5445 case PV_SI: return (char_u *)&(curbuf->b_p_si);
5446#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005447 case PV_SN: return (char_u *)&(curbuf->b_p_sn);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005448 case PV_STS: return (char_u *)&(curbuf->b_p_sts);
5449#ifdef FEAT_SEARCHPATH
5450 case PV_SUA: return (char_u *)&(curbuf->b_p_sua);
5451#endif
5452 case PV_SWF: return (char_u *)&(curbuf->b_p_swf);
5453#ifdef FEAT_SYN_HL
Bram Moolenaar3b56eb32005-07-11 22:40:32 +00005454 case PV_SMC: return (char_u *)&(curbuf->b_p_smc);
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005455 case PV_SYN: return (char_u *)&(curbuf->b_p_syn);
5456#endif
5457#ifdef FEAT_SPELL
Bram Moolenaar860cae12010-06-05 23:22:07 +02005458 case PV_SPC: return (char_u *)&(curwin->w_s->b_p_spc);
5459 case PV_SPF: return (char_u *)&(curwin->w_s->b_p_spf);
5460 case PV_SPL: return (char_u *)&(curwin->w_s->b_p_spl);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005461#endif
5462 case PV_SW: return (char_u *)&(curbuf->b_p_sw);
5463 case PV_TS: return (char_u *)&(curbuf->b_p_ts);
5464 case PV_TW: return (char_u *)&(curbuf->b_p_tw);
5465 case PV_TX: return (char_u *)&(curbuf->b_p_tx);
Bram Moolenaar55debbe2010-05-23 23:34:36 +02005466#ifdef FEAT_PERSISTENT_UNDO
5467 case PV_UDF: return (char_u *)&(curbuf->b_p_udf);
5468#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005469 case PV_WM: return (char_u *)&(curbuf->b_p_wm);
5470#ifdef FEAT_KEYMAP
5471 case PV_KMAP: return (char_u *)&(curbuf->b_p_keymap);
5472#endif
Bram Moolenaar95ec9d62016-08-12 18:29:59 +02005473#ifdef FEAT_SIGNS
5474 case PV_SCL: return (char_u *)&(curwin->w_p_scl);
5475#endif
Bram Moolenaar04958cb2018-06-23 19:23:02 +02005476#ifdef FEAT_VARTABS
5477 case PV_VSTS: return (char_u *)&(curbuf->b_p_vsts);
5478 case PV_VTS: return (char_u *)&(curbuf->b_p_vts);
5479#endif
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01005480 default: iemsg(_("E356: get_varp ERROR"));
Bram Moolenaar071d4272004-06-13 20:20:40 +00005481 }
5482 /* always return a valid pointer to avoid a crash! */
5483 return (char_u *)&(curbuf->b_p_wm);
5484}
5485
5486/*
Bram Moolenaardac13472019-09-16 21:06:21 +02005487 * Return a pointer to the variable for option at 'opt_idx'
5488 */
5489 char_u *
5490get_option_var(int opt_idx)
5491{
5492 return options[opt_idx].var;
5493}
5494
5495/*
5496 * Return the full name of the option at 'opt_idx'
5497 */
5498 char_u *
5499get_option_fullname(int opt_idx)
5500{
5501 return (char_u *)options[opt_idx].fullname;
5502}
5503
5504/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005505 * Get the value of 'equalprg', either the buffer-local one or the global one.
5506 */
5507 char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01005508get_equalprg(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005509{
5510 if (*curbuf->b_p_ep == NUL)
5511 return p_ep;
5512 return curbuf->b_p_ep;
5513}
5514
Bram Moolenaar071d4272004-06-13 20:20:40 +00005515/*
5516 * Copy options from one window to another.
5517 * Used when splitting a window.
5518 */
5519 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005520win_copy_options(win_T *wp_from, win_T *wp_to)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005521{
5522 copy_winopt(&wp_from->w_onebuf_opt, &wp_to->w_onebuf_opt);
5523 copy_winopt(&wp_from->w_allbuf_opt, &wp_to->w_allbuf_opt);
Bram Moolenaar010ee962019-09-25 20:37:36 +02005524 after_copy_winopt(wp_to);
5525}
5526
5527/*
5528 * After copying window options: update variables depending on options.
5529 */
5530 void
Bram Moolenaar473952e2019-09-28 16:30:04 +02005531after_copy_winopt(win_T *wp UNUSED)
Bram Moolenaar010ee962019-09-25 20:37:36 +02005532{
5533#ifdef FEAT_LINEBREAK
5534 briopt_check(wp);
Bram Moolenaar285ed7e2014-08-24 21:39:49 +02005535#endif
Bram Moolenaar017ba072019-09-14 21:01:23 +02005536#ifdef FEAT_SYN_HL
Bram Moolenaar010ee962019-09-25 20:37:36 +02005537 fill_culopt_flags(NULL, wp);
5538 check_colorcolumn(wp);
Bram Moolenaar017ba072019-09-14 21:01:23 +02005539#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005540}
Bram Moolenaar071d4272004-06-13 20:20:40 +00005541
5542/*
5543 * Copy the options from one winopt_T to another.
5544 * Doesn't free the old option values in "to", use clear_winopt() for that.
5545 * The 'scroll' option is not copied, because it depends on the window height.
5546 * The 'previewwindow' option is reset, there can be only one preview window.
5547 */
5548 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005549copy_winopt(winopt_T *from, winopt_T *to)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005550{
5551#ifdef FEAT_ARABIC
5552 to->wo_arab = from->wo_arab;
5553#endif
5554 to->wo_list = from->wo_list;
5555 to->wo_nu = from->wo_nu;
Bram Moolenaar64486672010-05-16 15:46:46 +02005556 to->wo_rnu = from->wo_rnu;
Bram Moolenaar592e0a22004-07-03 16:05:59 +00005557#ifdef FEAT_LINEBREAK
5558 to->wo_nuw = from->wo_nuw;
5559#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005560#ifdef FEAT_RIGHTLEFT
5561 to->wo_rl = from->wo_rl;
5562 to->wo_rlc = vim_strsave(from->wo_rlc);
5563#endif
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005564#ifdef FEAT_STL_OPT
5565 to->wo_stl = vim_strsave(from->wo_stl);
5566#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005567 to->wo_wrap = from->wo_wrap;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005568#ifdef FEAT_DIFF
5569 to->wo_wrap_save = from->wo_wrap_save;
5570#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005571#ifdef FEAT_LINEBREAK
5572 to->wo_lbr = from->wo_lbr;
Bram Moolenaar597a4222014-06-25 14:39:50 +02005573 to->wo_bri = from->wo_bri;
5574 to->wo_briopt = vim_strsave(from->wo_briopt);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005575#endif
Bram Moolenaar4d784b22019-05-25 19:51:39 +02005576 to->wo_wcr = vim_strsave(from->wo_wcr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005577 to->wo_scb = from->wo_scb;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005578 to->wo_scb_save = from->wo_scb_save;
Bram Moolenaar4161dcc2010-12-02 15:33:21 +01005579 to->wo_crb = from->wo_crb;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005580 to->wo_crb_save = from->wo_crb_save;
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005581#ifdef FEAT_SPELL
Bram Moolenaar217ad922005-03-20 22:37:15 +00005582 to->wo_spell = from->wo_spell;
5583#endif
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005584#ifdef FEAT_SYN_HL
5585 to->wo_cuc = from->wo_cuc;
5586 to->wo_cul = from->wo_cul;
Bram Moolenaar410e98a2019-09-09 22:05:49 +02005587 to->wo_culopt = vim_strsave(from->wo_culopt);
Bram Moolenaar1a384422010-07-14 19:53:30 +02005588 to->wo_cc = vim_strsave(from->wo_cc);
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005589#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005590#ifdef FEAT_DIFF
5591 to->wo_diff = from->wo_diff;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005592 to->wo_diff_saved = from->wo_diff_saved;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005593#endif
Bram Moolenaarf5963f72010-07-23 22:10:27 +02005594#ifdef FEAT_CONCEAL
5595 to->wo_cocu = vim_strsave(from->wo_cocu);
Bram Moolenaard497a302010-07-23 22:27:03 +02005596 to->wo_cole = from->wo_cole;
Bram Moolenaarf5963f72010-07-23 22:10:27 +02005597#endif
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005598#ifdef FEAT_TERMINAL
Bram Moolenaar6d150f72018-04-21 20:03:20 +02005599 to->wo_twk = vim_strsave(from->wo_twk);
5600 to->wo_tws = vim_strsave(from->wo_tws);
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005601#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005602#ifdef FEAT_FOLDING
5603 to->wo_fdc = from->wo_fdc;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005604 to->wo_fdc_save = from->wo_fdc_save;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005605 to->wo_fen = from->wo_fen;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005606 to->wo_fen_save = from->wo_fen_save;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005607 to->wo_fdi = vim_strsave(from->wo_fdi);
5608 to->wo_fml = from->wo_fml;
5609 to->wo_fdl = from->wo_fdl;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005610 to->wo_fdl_save = from->wo_fdl_save;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005611 to->wo_fdm = vim_strsave(from->wo_fdm);
Bram Moolenaara87aa802013-07-03 15:47:03 +02005612 to->wo_fdm_save = from->wo_diff_saved
5613 ? vim_strsave(from->wo_fdm_save) : empty_option;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005614 to->wo_fdn = from->wo_fdn;
5615# ifdef FEAT_EVAL
5616 to->wo_fde = vim_strsave(from->wo_fde);
5617 to->wo_fdt = vim_strsave(from->wo_fdt);
5618# endif
5619 to->wo_fmr = vim_strsave(from->wo_fmr);
5620#endif
Bram Moolenaar95ec9d62016-08-12 18:29:59 +02005621#ifdef FEAT_SIGNS
5622 to->wo_scl = vim_strsave(from->wo_scl);
5623#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005624 check_winopt(to); /* don't want NULL pointers */
5625}
5626
5627/*
5628 * Check string options in a window for a NULL value.
5629 */
Bram Moolenaar5843f5f2019-08-20 20:13:45 +02005630 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005631check_win_options(win_T *win)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005632{
5633 check_winopt(&win->w_onebuf_opt);
5634 check_winopt(&win->w_allbuf_opt);
5635}
5636
5637/*
5638 * Check for NULL pointers in a winopt_T and replace them with empty_option.
5639 */
Bram Moolenaar8dc907d2014-06-25 14:44:10 +02005640 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005641check_winopt(winopt_T *wop UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005642{
5643#ifdef FEAT_FOLDING
5644 check_string_option(&wop->wo_fdi);
5645 check_string_option(&wop->wo_fdm);
Bram Moolenaara87aa802013-07-03 15:47:03 +02005646 check_string_option(&wop->wo_fdm_save);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005647# ifdef FEAT_EVAL
5648 check_string_option(&wop->wo_fde);
5649 check_string_option(&wop->wo_fdt);
5650# endif
5651 check_string_option(&wop->wo_fmr);
5652#endif
Bram Moolenaar95ec9d62016-08-12 18:29:59 +02005653#ifdef FEAT_SIGNS
5654 check_string_option(&wop->wo_scl);
5655#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005656#ifdef FEAT_RIGHTLEFT
5657 check_string_option(&wop->wo_rlc);
5658#endif
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005659#ifdef FEAT_STL_OPT
5660 check_string_option(&wop->wo_stl);
5661#endif
Bram Moolenaar1a384422010-07-14 19:53:30 +02005662#ifdef FEAT_SYN_HL
Bram Moolenaar410e98a2019-09-09 22:05:49 +02005663 check_string_option(&wop->wo_culopt);
Bram Moolenaar1a384422010-07-14 19:53:30 +02005664 check_string_option(&wop->wo_cc);
5665#endif
Bram Moolenaarf5963f72010-07-23 22:10:27 +02005666#ifdef FEAT_CONCEAL
5667 check_string_option(&wop->wo_cocu);
5668#endif
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005669#ifdef FEAT_TERMINAL
Bram Moolenaar6d150f72018-04-21 20:03:20 +02005670 check_string_option(&wop->wo_twk);
5671 check_string_option(&wop->wo_tws);
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005672#endif
Bram Moolenaar597a4222014-06-25 14:39:50 +02005673#ifdef FEAT_LINEBREAK
5674 check_string_option(&wop->wo_briopt);
5675#endif
Bram Moolenaar4d784b22019-05-25 19:51:39 +02005676 check_string_option(&wop->wo_wcr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005677}
5678
5679/*
5680 * Free the allocated memory inside a winopt_T.
5681 */
Bram Moolenaar071d4272004-06-13 20:20:40 +00005682 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005683clear_winopt(winopt_T *wop UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005684{
5685#ifdef FEAT_FOLDING
5686 clear_string_option(&wop->wo_fdi);
5687 clear_string_option(&wop->wo_fdm);
Bram Moolenaara87aa802013-07-03 15:47:03 +02005688 clear_string_option(&wop->wo_fdm_save);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005689# ifdef FEAT_EVAL
5690 clear_string_option(&wop->wo_fde);
5691 clear_string_option(&wop->wo_fdt);
5692# endif
5693 clear_string_option(&wop->wo_fmr);
5694#endif
Bram Moolenaar95ec9d62016-08-12 18:29:59 +02005695#ifdef FEAT_SIGNS
5696 clear_string_option(&wop->wo_scl);
5697#endif
Bram Moolenaar597a4222014-06-25 14:39:50 +02005698#ifdef FEAT_LINEBREAK
5699 clear_string_option(&wop->wo_briopt);
5700#endif
Bram Moolenaar4d784b22019-05-25 19:51:39 +02005701 clear_string_option(&wop->wo_wcr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005702#ifdef FEAT_RIGHTLEFT
5703 clear_string_option(&wop->wo_rlc);
5704#endif
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005705#ifdef FEAT_STL_OPT
5706 clear_string_option(&wop->wo_stl);
5707#endif
Bram Moolenaar1a384422010-07-14 19:53:30 +02005708#ifdef FEAT_SYN_HL
Bram Moolenaar410e98a2019-09-09 22:05:49 +02005709 clear_string_option(&wop->wo_culopt);
Bram Moolenaar1a384422010-07-14 19:53:30 +02005710 clear_string_option(&wop->wo_cc);
5711#endif
Bram Moolenaarf5963f72010-07-23 22:10:27 +02005712#ifdef FEAT_CONCEAL
5713 clear_string_option(&wop->wo_cocu);
5714#endif
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005715#ifdef FEAT_TERMINAL
Bram Moolenaar6d150f72018-04-21 20:03:20 +02005716 clear_string_option(&wop->wo_twk);
5717 clear_string_option(&wop->wo_tws);
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005718#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005719}
5720
5721/*
5722 * Copy global option values to local options for one buffer.
5723 * Used when creating a new buffer and sometimes when entering a buffer.
5724 * flags:
5725 * BCO_ENTER We will enter the buf buffer.
5726 * BCO_ALWAYS Always copy the options, but only set b_p_initialized when
5727 * appropriate.
5728 * BCO_NOHELP Don't copy the values to a help buffer.
5729 */
5730 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005731buf_copy_options(buf_T *buf, int flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005732{
5733 int should_copy = TRUE;
5734 char_u *save_p_isk = NULL; /* init for GCC */
5735 int dont_do_help;
5736 int did_isk = FALSE;
5737
5738 /*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005739 * Skip this when the option defaults have not been set yet. Happens when
5740 * main() allocates the first buffer.
5741 */
5742 if (p_cpo != NULL)
5743 {
5744 /*
5745 * Always copy when entering and 'cpo' contains 'S'.
5746 * Don't copy when already initialized.
5747 * Don't copy when 'cpo' contains 's' and not entering.
5748 * 'S' BCO_ENTER initialized 's' should_copy
5749 * yes yes X X TRUE
5750 * yes no yes X FALSE
5751 * no X yes X FALSE
5752 * X no no yes FALSE
5753 * X no no no TRUE
5754 * no yes no X TRUE
5755 */
5756 if ((vim_strchr(p_cpo, CPO_BUFOPTGLOB) == NULL || !(flags & BCO_ENTER))
5757 && (buf->b_p_initialized
5758 || (!(flags & BCO_ENTER)
5759 && vim_strchr(p_cpo, CPO_BUFOPT) != NULL)))
5760 should_copy = FALSE;
5761
5762 if (should_copy || (flags & BCO_ALWAYS))
5763 {
5764 /* Don't copy the options specific to a help buffer when
5765 * BCO_NOHELP is given or the options were initialized already
5766 * (jumping back to a help file with CTRL-T or CTRL-O) */
5767 dont_do_help = ((flags & BCO_NOHELP) && buf->b_help)
5768 || buf->b_p_initialized;
5769 if (dont_do_help) /* don't free b_p_isk */
5770 {
5771 save_p_isk = buf->b_p_isk;
5772 buf->b_p_isk = NULL;
5773 }
5774 /*
Bram Moolenaar40385db2018-08-07 22:31:44 +02005775 * Always free the allocated strings. If not already initialized,
5776 * reset 'readonly' and copy 'fileformat'.
Bram Moolenaar071d4272004-06-13 20:20:40 +00005777 */
5778 if (!buf->b_p_initialized)
5779 {
5780 free_buf_options(buf, TRUE);
5781 buf->b_p_ro = FALSE; /* don't copy readonly */
5782 buf->b_p_tx = p_tx;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005783 buf->b_p_fenc = vim_strsave(p_fenc);
Bram Moolenaare8ef3a02016-10-12 17:45:29 +02005784 switch (*p_ffs)
5785 {
5786 case 'm':
5787 buf->b_p_ff = vim_strsave((char_u *)FF_MAC); break;
5788 case 'd':
5789 buf->b_p_ff = vim_strsave((char_u *)FF_DOS); break;
5790 case 'u':
5791 buf->b_p_ff = vim_strsave((char_u *)FF_UNIX); break;
5792 default:
5793 buf->b_p_ff = vim_strsave(p_ff);
5794 }
5795 if (buf->b_p_ff != NULL)
5796 buf->b_start_ffc = *buf->b_p_ff;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005797 buf->b_p_bh = empty_option;
5798 buf->b_p_bt = empty_option;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005799 }
5800 else
5801 free_buf_options(buf, FALSE);
5802
5803 buf->b_p_ai = p_ai;
5804 buf->b_p_ai_nopaste = p_ai_nopaste;
5805 buf->b_p_sw = p_sw;
5806 buf->b_p_tw = p_tw;
5807 buf->b_p_tw_nopaste = p_tw_nopaste;
5808 buf->b_p_tw_nobin = p_tw_nobin;
5809 buf->b_p_wm = p_wm;
5810 buf->b_p_wm_nopaste = p_wm_nopaste;
5811 buf->b_p_wm_nobin = p_wm_nobin;
5812 buf->b_p_bin = p_bin;
Bram Moolenaare8bb2552005-07-08 22:26:47 +00005813 buf->b_p_bomb = p_bomb;
Bram Moolenaarb388be02015-07-22 22:19:38 +02005814 buf->b_p_fixeol = p_fixeol;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005815 buf->b_p_et = p_et;
5816 buf->b_p_et_nobin = p_et_nobin;
Bram Moolenaar54f018c2015-09-15 17:30:40 +02005817 buf->b_p_et_nopaste = p_et_nopaste;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005818 buf->b_p_ml = p_ml;
5819 buf->b_p_ml_nobin = p_ml_nobin;
5820 buf->b_p_inf = p_inf;
Bram Moolenaar3bab9392017-04-07 15:42:25 +02005821 buf->b_p_swf = cmdmod.noswapfile ? FALSE : p_swf;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005822 buf->b_p_cpt = vim_strsave(p_cpt);
Bram Moolenaare2c453d2019-08-21 14:37:09 +02005823#ifdef BACKSLASH_IN_FILENAME
Bram Moolenaarac3150d2019-07-28 16:36:39 +02005824 buf->b_p_csl = vim_strsave(p_csl);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005825#endif
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00005826#ifdef FEAT_COMPL_FUNC
5827 buf->b_p_cfu = vim_strsave(p_cfu);
Bram Moolenaare344bea2005-09-01 20:46:49 +00005828 buf->b_p_ofu = vim_strsave(p_ofu);
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00005829#endif
Bram Moolenaar45e18cb2019-04-28 18:05:35 +02005830#ifdef FEAT_EVAL
5831 buf->b_p_tfu = vim_strsave(p_tfu);
5832#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005833 buf->b_p_sts = p_sts;
5834 buf->b_p_sts_nopaste = p_sts_nopaste;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02005835#ifdef FEAT_VARTABS
5836 buf->b_p_vsts = vim_strsave(p_vsts);
5837 if (p_vsts && p_vsts != empty_option)
5838 tabstop_set(p_vsts, &buf->b_p_vsts_array);
5839 else
5840 buf->b_p_vsts_array = 0;
5841 buf->b_p_vsts_nopaste = p_vsts_nopaste
5842 ? vim_strsave(p_vsts_nopaste) : NULL;
5843#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005844 buf->b_p_sn = p_sn;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005845 buf->b_p_com = vim_strsave(p_com);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005846#ifdef FEAT_FOLDING
5847 buf->b_p_cms = vim_strsave(p_cms);
5848#endif
5849 buf->b_p_fo = vim_strsave(p_fo);
Bram Moolenaar86b68352004-12-27 21:59:20 +00005850 buf->b_p_flp = vim_strsave(p_flp);
Bram Moolenaar473952e2019-09-28 16:30:04 +02005851 // NOTE: Valgrind may report a bogus memory leak for 'nrformats'
5852 // when it is set to 8 bytes in defaults.vim.
Bram Moolenaar071d4272004-06-13 20:20:40 +00005853 buf->b_p_nf = vim_strsave(p_nf);
5854 buf->b_p_mps = vim_strsave(p_mps);
5855#ifdef FEAT_SMARTINDENT
5856 buf->b_p_si = p_si;
5857#endif
5858 buf->b_p_ci = p_ci;
5859#ifdef FEAT_CINDENT
5860 buf->b_p_cin = p_cin;
5861 buf->b_p_cink = vim_strsave(p_cink);
5862 buf->b_p_cino = vim_strsave(p_cino);
5863#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005864 /* Don't copy 'filetype', it must be detected */
5865 buf->b_p_ft = empty_option;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005866 buf->b_p_pi = p_pi;
5867#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
5868 buf->b_p_cinw = vim_strsave(p_cinw);
5869#endif
5870#ifdef FEAT_LISP
5871 buf->b_p_lisp = p_lisp;
5872#endif
5873#ifdef FEAT_SYN_HL
5874 /* Don't copy 'syntax', it must be set */
5875 buf->b_p_syn = empty_option;
Bram Moolenaar3b56eb32005-07-11 22:40:32 +00005876 buf->b_p_smc = p_smc;
Bram Moolenaarb8060fe2016-01-19 22:29:28 +01005877 buf->b_s.b_syn_isk = empty_option;
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005878#endif
5879#ifdef FEAT_SPELL
Bram Moolenaard5784f92010-10-13 14:05:35 +02005880 buf->b_s.b_p_spc = vim_strsave(p_spc);
Bram Moolenaar860cae12010-06-05 23:22:07 +02005881 (void)compile_cap_prog(&buf->b_s);
5882 buf->b_s.b_p_spf = vim_strsave(p_spf);
5883 buf->b_s.b_p_spl = vim_strsave(p_spl);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005884#endif
5885#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
5886 buf->b_p_inde = vim_strsave(p_inde);
5887 buf->b_p_indk = vim_strsave(p_indk);
5888#endif
Bram Moolenaar9be7c042017-01-14 14:28:30 +01005889 buf->b_p_fp = empty_option;
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +00005890#if defined(FEAT_EVAL)
5891 buf->b_p_fex = vim_strsave(p_fex);
5892#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005893#ifdef FEAT_CRYPT
5894 buf->b_p_key = vim_strsave(p_key);
5895#endif
5896#ifdef FEAT_SEARCHPATH
5897 buf->b_p_sua = vim_strsave(p_sua);
5898#endif
5899#ifdef FEAT_KEYMAP
5900 buf->b_p_keymap = vim_strsave(p_keymap);
5901 buf->b_kmap_state |= KEYMAP_INIT;
5902#endif
Bram Moolenaar6d150f72018-04-21 20:03:20 +02005903#ifdef FEAT_TERMINAL
5904 buf->b_p_twsl = p_twsl;
5905#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005906 /* This isn't really an option, but copying the langmap and IME
5907 * state from the current buffer is better than resetting it. */
5908 buf->b_p_iminsert = p_iminsert;
5909 buf->b_p_imsearch = p_imsearch;
5910
5911 /* options that are normally global but also have a local value
5912 * are not copied, start using the global value */
5913 buf->b_p_ar = -1;
Bram Moolenaarf5a2fd82013-11-06 05:26:15 +01005914 buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02005915 buf->b_p_bkc = empty_option;
5916 buf->b_bkc_flags = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005917#ifdef FEAT_QUICKFIX
5918 buf->b_p_gp = empty_option;
5919 buf->b_p_mp = empty_option;
5920 buf->b_p_efm = empty_option;
5921#endif
5922 buf->b_p_ep = empty_option;
5923 buf->b_p_kp = empty_option;
5924 buf->b_p_path = empty_option;
5925 buf->b_p_tags = empty_option;
Bram Moolenaar0f6562e2015-11-24 18:48:14 +01005926 buf->b_p_tc = empty_option;
5927 buf->b_tc_flags = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005928#ifdef FEAT_FIND_ID
5929 buf->b_p_def = empty_option;
5930 buf->b_p_inc = empty_option;
5931# ifdef FEAT_EVAL
5932 buf->b_p_inex = vim_strsave(p_inex);
5933# endif
5934#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005935 buf->b_p_dict = empty_option;
5936 buf->b_p_tsr = empty_option;
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00005937#ifdef FEAT_TEXTOBJ
5938 buf->b_p_qe = vim_strsave(p_qe);
5939#endif
Bram Moolenaar9b2200a2006-03-20 21:55:45 +00005940#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
5941 buf->b_p_bexpr = empty_option;
5942#endif
Bram Moolenaar49771f42010-07-20 17:32:38 +02005943#if defined(FEAT_CRYPT)
5944 buf->b_p_cm = empty_option;
5945#endif
Bram Moolenaar55debbe2010-05-23 23:34:36 +02005946#ifdef FEAT_PERSISTENT_UNDO
5947 buf->b_p_udf = p_udf;
5948#endif
Bram Moolenaaraf6c1312014-03-12 18:55:58 +01005949#ifdef FEAT_LISP
5950 buf->b_p_lw = empty_option;
5951#endif
Bram Moolenaar2c7292d2017-03-05 17:43:31 +01005952 buf->b_p_menc = empty_option;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005953
5954 /*
5955 * Don't copy the options set by ex_help(), use the saved values,
5956 * when going from a help buffer to a non-help buffer.
5957 * Don't touch these at all when BCO_NOHELP is used and going from
5958 * or to a help buffer.
5959 */
5960 if (dont_do_help)
Bram Moolenaar04958cb2018-06-23 19:23:02 +02005961 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00005962 buf->b_p_isk = save_p_isk;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02005963#ifdef FEAT_VARTABS
5964 if (p_vts && p_vts != empty_option && !buf->b_p_vts_array)
5965 tabstop_set(p_vts, &buf->b_p_vts_array);
5966 else
5967 buf->b_p_vts_array = NULL;
5968#endif
5969 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00005970 else
5971 {
5972 buf->b_p_isk = vim_strsave(p_isk);
5973 did_isk = TRUE;
5974 buf->b_p_ts = p_ts;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02005975#ifdef FEAT_VARTABS
5976 buf->b_p_vts = vim_strsave(p_vts);
5977 if (p_vts && p_vts != empty_option && !buf->b_p_vts_array)
5978 tabstop_set(p_vts, &buf->b_p_vts_array);
5979 else
5980 buf->b_p_vts_array = NULL;
5981#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005982 buf->b_help = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005983 if (buf->b_p_bt[0] == 'h')
5984 clear_string_option(&buf->b_p_bt);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005985 buf->b_p_ma = p_ma;
5986 }
5987 }
5988
5989 /*
5990 * When the options should be copied (ignoring BCO_ALWAYS), set the
5991 * flag that indicates that the options have been initialized.
5992 */
5993 if (should_copy)
5994 buf->b_p_initialized = TRUE;
5995 }
5996
5997 check_buf_options(buf); /* make sure we don't have NULLs */
5998 if (did_isk)
5999 (void)buf_init_chartab(buf, FALSE);
6000}
6001
6002/*
6003 * Reset the 'modifiable' option and its default value.
6004 */
6005 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006006reset_modifiable(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006007{
6008 int opt_idx;
6009
6010 curbuf->b_p_ma = FALSE;
6011 p_ma = FALSE;
6012 opt_idx = findoption((char_u *)"ma");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +00006013 if (opt_idx >= 0)
6014 options[opt_idx].def_val[VI_DEFAULT] = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006015}
6016
6017/*
6018 * Set the global value for 'iminsert' to the local value.
6019 */
6020 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006021set_iminsert_global(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006022{
6023 p_iminsert = curbuf->b_p_iminsert;
6024}
6025
6026/*
6027 * Set the global value for 'imsearch' to the local value.
6028 */
6029 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006030set_imsearch_global(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006031{
6032 p_imsearch = curbuf->b_p_imsearch;
6033}
6034
Bram Moolenaar071d4272004-06-13 20:20:40 +00006035static int expand_option_idx = -1;
6036static char_u expand_option_name[5] = {'t', '_', NUL, NUL, NUL};
6037static int expand_option_flags = 0;
6038
6039 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006040set_context_in_set_cmd(
6041 expand_T *xp,
6042 char_u *arg,
6043 int opt_flags) /* OPT_GLOBAL and/or OPT_LOCAL */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006044{
6045 int nextchar;
6046 long_u flags = 0; /* init for GCC */
6047 int opt_idx = 0; /* init for GCC */
6048 char_u *p;
6049 char_u *s;
6050 int is_term_option = FALSE;
6051 int key;
6052
6053 expand_option_flags = opt_flags;
6054
6055 xp->xp_context = EXPAND_SETTINGS;
6056 if (*arg == NUL)
6057 {
6058 xp->xp_pattern = arg;
6059 return;
6060 }
6061 p = arg + STRLEN(arg) - 1;
6062 if (*p == ' ' && *(p - 1) != '\\')
6063 {
6064 xp->xp_pattern = p + 1;
6065 return;
6066 }
6067 while (p > arg)
6068 {
6069 s = p;
6070 /* count number of backslashes before ' ' or ',' */
6071 if (*p == ' ' || *p == ',')
6072 {
6073 while (s > arg && *(s - 1) == '\\')
6074 --s;
6075 }
6076 /* break at a space with an even number of backslashes */
6077 if (*p == ' ' && ((p - s) & 1) == 0)
6078 {
6079 ++p;
6080 break;
6081 }
6082 --p;
6083 }
Bram Moolenaar2a7b9ee2009-06-16 15:50:33 +00006084 if (STRNCMP(p, "no", 2) == 0 && STRNCMP(p, "novice", 6) != 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006085 {
6086 xp->xp_context = EXPAND_BOOL_SETTINGS;
6087 p += 2;
6088 }
6089 if (STRNCMP(p, "inv", 3) == 0)
6090 {
6091 xp->xp_context = EXPAND_BOOL_SETTINGS;
6092 p += 3;
6093 }
6094 xp->xp_pattern = arg = p;
6095 if (*arg == '<')
6096 {
6097 while (*p != '>')
6098 if (*p++ == NUL) /* expand terminal option name */
6099 return;
6100 key = get_special_key_code(arg + 1);
6101 if (key == 0) /* unknown name */
6102 {
6103 xp->xp_context = EXPAND_NOTHING;
6104 return;
6105 }
6106 nextchar = *++p;
6107 is_term_option = TRUE;
6108 expand_option_name[2] = KEY2TERMCAP0(key);
6109 expand_option_name[3] = KEY2TERMCAP1(key);
6110 }
6111 else
6112 {
6113 if (p[0] == 't' && p[1] == '_')
6114 {
6115 p += 2;
6116 if (*p != NUL)
6117 ++p;
6118 if (*p == NUL)
6119 return; /* expand option name */
6120 nextchar = *++p;
6121 is_term_option = TRUE;
6122 expand_option_name[2] = p[-2];
6123 expand_option_name[3] = p[-1];
6124 }
6125 else
6126 {
6127 /* Allow * wildcard */
6128 while (ASCII_ISALNUM(*p) || *p == '_' || *p == '*')
6129 p++;
6130 if (*p == NUL)
6131 return;
6132 nextchar = *p;
6133 *p = NUL;
6134 opt_idx = findoption(arg);
6135 *p = nextchar;
6136 if (opt_idx == -1 || options[opt_idx].var == NULL)
6137 {
6138 xp->xp_context = EXPAND_NOTHING;
6139 return;
6140 }
6141 flags = options[opt_idx].flags;
6142 if (flags & P_BOOL)
6143 {
6144 xp->xp_context = EXPAND_NOTHING;
6145 return;
6146 }
6147 }
6148 }
6149 /* handle "-=" and "+=" */
6150 if ((nextchar == '-' || nextchar == '+' || nextchar == '^') && p[1] == '=')
6151 {
6152 ++p;
6153 nextchar = '=';
6154 }
6155 if ((nextchar != '=' && nextchar != ':')
6156 || xp->xp_context == EXPAND_BOOL_SETTINGS)
6157 {
6158 xp->xp_context = EXPAND_UNSUCCESSFUL;
6159 return;
6160 }
6161 if (xp->xp_context != EXPAND_BOOL_SETTINGS && p[1] == NUL)
6162 {
6163 xp->xp_context = EXPAND_OLD_SETTING;
6164 if (is_term_option)
6165 expand_option_idx = -1;
6166 else
6167 expand_option_idx = opt_idx;
6168 xp->xp_pattern = p + 1;
6169 return;
6170 }
6171 xp->xp_context = EXPAND_NOTHING;
6172 if (is_term_option || (flags & P_NUM))
6173 return;
6174
6175 xp->xp_pattern = p + 1;
6176
6177 if (flags & P_EXPAND)
6178 {
6179 p = options[opt_idx].var;
6180 if (p == (char_u *)&p_bdir
6181 || p == (char_u *)&p_dir
6182 || p == (char_u *)&p_path
Bram Moolenaarf6fee0e2016-02-21 23:02:49 +01006183 || p == (char_u *)&p_pp
Bram Moolenaar071d4272004-06-13 20:20:40 +00006184 || p == (char_u *)&p_rtp
6185#ifdef FEAT_SEARCHPATH
6186 || p == (char_u *)&p_cdpath
6187#endif
6188#ifdef FEAT_SESSION
6189 || p == (char_u *)&p_vdir
6190#endif
6191 )
6192 {
6193 xp->xp_context = EXPAND_DIRECTORIES;
6194 if (p == (char_u *)&p_path
6195#ifdef FEAT_SEARCHPATH
6196 || p == (char_u *)&p_cdpath
6197#endif
6198 )
6199 xp->xp_backslash = XP_BS_THREE;
6200 else
6201 xp->xp_backslash = XP_BS_ONE;
6202 }
6203 else
6204 {
6205 xp->xp_context = EXPAND_FILES;
6206 /* for 'tags' need three backslashes for a space */
6207 if (p == (char_u *)&p_tags)
6208 xp->xp_backslash = XP_BS_THREE;
6209 else
6210 xp->xp_backslash = XP_BS_ONE;
6211 }
6212 }
6213
6214 /* For an option that is a list of file names, find the start of the
6215 * last file name. */
6216 for (p = arg + STRLEN(arg) - 1; p > xp->xp_pattern; --p)
6217 {
6218 /* count number of backslashes before ' ' or ',' */
6219 if (*p == ' ' || *p == ',')
6220 {
6221 s = p;
6222 while (s > xp->xp_pattern && *(s - 1) == '\\')
6223 --s;
6224 if ((*p == ' ' && (xp->xp_backslash == XP_BS_THREE && (p - s) < 3))
6225 || (*p == ',' && (flags & P_COMMA) && ((p - s) & 1) == 0))
6226 {
6227 xp->xp_pattern = p + 1;
6228 break;
6229 }
6230 }
Bram Moolenaar24bbcfe2005-06-28 23:32:02 +00006231
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00006232#ifdef FEAT_SPELL
Bram Moolenaar24bbcfe2005-06-28 23:32:02 +00006233 /* for 'spellsuggest' start at "file:" */
6234 if (options[opt_idx].var == (char_u *)&p_sps
6235 && STRNCMP(p, "file:", 5) == 0)
6236 {
6237 xp->xp_pattern = p + 5;
6238 break;
6239 }
6240#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006241 }
6242
6243 return;
6244}
6245
6246 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006247ExpandSettings(
6248 expand_T *xp,
6249 regmatch_T *regmatch,
6250 int *num_file,
6251 char_u ***file)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006252{
6253 int num_normal = 0; /* Nr of matching non-term-code settings */
6254 int num_term = 0; /* Nr of matching terminal code settings */
6255 int opt_idx;
6256 int match;
6257 int count = 0;
6258 char_u *str;
6259 int loop;
6260 int is_term_opt;
6261 char_u name_buf[MAX_KEY_NAME_LEN];
6262 static char *(names[]) = {"all", "termcap"};
6263 int ic = regmatch->rm_ic; /* remember the ignore-case flag */
6264
6265 /* do this loop twice:
6266 * loop == 0: count the number of matching options
6267 * loop == 1: copy the matching options into allocated memory
6268 */
6269 for (loop = 0; loop <= 1; ++loop)
6270 {
6271 regmatch->rm_ic = ic;
6272 if (xp->xp_context != EXPAND_BOOL_SETTINGS)
6273 {
Bram Moolenaar2c4278f2009-05-17 11:33:22 +00006274 for (match = 0; match < (int)(sizeof(names) / sizeof(char *));
6275 ++match)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006276 if (vim_regexec(regmatch, (char_u *)names[match], (colnr_T)0))
6277 {
6278 if (loop == 0)
6279 num_normal++;
6280 else
6281 (*file)[count++] = vim_strsave((char_u *)names[match]);
6282 }
6283 }
6284 for (opt_idx = 0; (str = (char_u *)options[opt_idx].fullname) != NULL;
6285 opt_idx++)
6286 {
6287 if (options[opt_idx].var == NULL)
6288 continue;
6289 if (xp->xp_context == EXPAND_BOOL_SETTINGS
6290 && !(options[opt_idx].flags & P_BOOL))
6291 continue;
Bram Moolenaardac13472019-09-16 21:06:21 +02006292 is_term_opt = istermoption_idx(opt_idx);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006293 if (is_term_opt && num_normal > 0)
6294 continue;
6295 match = FALSE;
6296 if (vim_regexec(regmatch, str, (colnr_T)0)
6297 || (options[opt_idx].shortname != NULL
6298 && vim_regexec(regmatch,
6299 (char_u *)options[opt_idx].shortname, (colnr_T)0)))
6300 match = TRUE;
6301 else if (is_term_opt)
6302 {
6303 name_buf[0] = '<';
6304 name_buf[1] = 't';
6305 name_buf[2] = '_';
6306 name_buf[3] = str[2];
6307 name_buf[4] = str[3];
6308 name_buf[5] = '>';
6309 name_buf[6] = NUL;
6310 if (vim_regexec(regmatch, name_buf, (colnr_T)0))
6311 {
6312 match = TRUE;
6313 str = name_buf;
6314 }
6315 }
6316 if (match)
6317 {
6318 if (loop == 0)
6319 {
6320 if (is_term_opt)
6321 num_term++;
6322 else
6323 num_normal++;
6324 }
6325 else
6326 (*file)[count++] = vim_strsave(str);
6327 }
6328 }
6329 /*
6330 * Check terminal key codes, these are not in the option table
6331 */
6332 if (xp->xp_context != EXPAND_BOOL_SETTINGS && num_normal == 0)
6333 {
6334 for (opt_idx = 0; (str = get_termcode(opt_idx)) != NULL; opt_idx++)
6335 {
6336 if (!isprint(str[0]) || !isprint(str[1]))
6337 continue;
6338
6339 name_buf[0] = 't';
6340 name_buf[1] = '_';
6341 name_buf[2] = str[0];
6342 name_buf[3] = str[1];
6343 name_buf[4] = NUL;
6344
6345 match = FALSE;
6346 if (vim_regexec(regmatch, name_buf, (colnr_T)0))
6347 match = TRUE;
6348 else
6349 {
6350 name_buf[0] = '<';
6351 name_buf[1] = 't';
6352 name_buf[2] = '_';
6353 name_buf[3] = str[0];
6354 name_buf[4] = str[1];
6355 name_buf[5] = '>';
6356 name_buf[6] = NUL;
6357
6358 if (vim_regexec(regmatch, name_buf, (colnr_T)0))
6359 match = TRUE;
6360 }
6361 if (match)
6362 {
6363 if (loop == 0)
6364 num_term++;
6365 else
6366 (*file)[count++] = vim_strsave(name_buf);
6367 }
6368 }
6369
6370 /*
6371 * Check special key names.
6372 */
6373 regmatch->rm_ic = TRUE; /* ignore case here */
6374 for (opt_idx = 0; (str = get_key_name(opt_idx)) != NULL; opt_idx++)
6375 {
6376 name_buf[0] = '<';
6377 STRCPY(name_buf + 1, str);
6378 STRCAT(name_buf, ">");
6379
6380 if (vim_regexec(regmatch, name_buf, (colnr_T)0))
6381 {
6382 if (loop == 0)
6383 num_term++;
6384 else
6385 (*file)[count++] = vim_strsave(name_buf);
6386 }
6387 }
6388 }
6389 if (loop == 0)
6390 {
6391 if (num_normal > 0)
6392 *num_file = num_normal;
6393 else if (num_term > 0)
6394 *num_file = num_term;
6395 else
6396 return OK;
Bram Moolenaarc799fe22019-05-28 23:08:19 +02006397 *file = ALLOC_MULT(char_u *, *num_file);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006398 if (*file == NULL)
6399 {
6400 *file = (char_u **)"";
6401 return FAIL;
6402 }
6403 }
6404 }
6405 return OK;
6406}
6407
6408 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006409ExpandOldSetting(int *num_file, char_u ***file)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006410{
6411 char_u *var = NULL; /* init for GCC */
6412 char_u *buf;
6413
6414 *num_file = 0;
Bram Moolenaarc799fe22019-05-28 23:08:19 +02006415 *file = ALLOC_ONE(char_u *);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006416 if (*file == NULL)
6417 return FAIL;
6418
6419 /*
6420 * For a terminal key code expand_option_idx is < 0.
6421 */
6422 if (expand_option_idx < 0)
6423 {
6424 var = find_termcode(expand_option_name + 2);
6425 if (var == NULL)
6426 expand_option_idx = findoption(expand_option_name);
6427 }
6428
6429 if (expand_option_idx >= 0)
6430 {
6431 /* put string of option value in NameBuff */
6432 option_value2string(&options[expand_option_idx], expand_option_flags);
6433 var = NameBuff;
6434 }
6435 else if (var == NULL)
6436 var = (char_u *)"";
6437
6438 /* A backslash is required before some characters. This is the reverse of
6439 * what happens in do_set(). */
6440 buf = vim_strsave_escaped(var, escape_chars);
6441
6442 if (buf == NULL)
6443 {
Bram Moolenaard23a8232018-02-10 18:45:26 +01006444 VIM_CLEAR(*file);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006445 return FAIL;
6446 }
6447
6448#ifdef BACKSLASH_IN_FILENAME
6449 /* For MS-Windows et al. we don't double backslashes at the start and
6450 * before a file name character. */
Bram Moolenaar91acfff2017-03-12 19:22:36 +01006451 for (var = buf; *var != NUL; MB_PTR_ADV(var))
Bram Moolenaar071d4272004-06-13 20:20:40 +00006452 if (var[0] == '\\' && var[1] == '\\'
6453 && expand_option_idx >= 0
6454 && (options[expand_option_idx].flags & P_EXPAND)
6455 && vim_isfilec(var[2])
6456 && (var[2] != '\\' || (var == buf && var[4] != '\\')))
Bram Moolenaarc1a11ed2008-06-24 22:09:24 +00006457 STRMOVE(var, var + 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006458#endif
6459
6460 *file[0] = buf;
6461 *num_file = 1;
6462 return OK;
6463}
Bram Moolenaar071d4272004-06-13 20:20:40 +00006464
6465/*
6466 * Get the value for the numeric or string option *opp in a nice format into
6467 * NameBuff[]. Must not be called with a hidden option!
6468 */
6469 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006470option_value2string(
6471 struct vimoption *opp,
6472 int opt_flags) /* OPT_GLOBAL and/or OPT_LOCAL */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006473{
6474 char_u *varp;
6475
6476 varp = get_varp_scope(opp, opt_flags);
6477
6478 if (opp->flags & P_NUM)
6479 {
6480 long wc = 0;
6481
6482 if (wc_use_keyname(varp, &wc))
6483 STRCPY(NameBuff, get_special_key_name((int)wc, 0));
6484 else if (wc != 0)
6485 STRCPY(NameBuff, transchar((int)wc));
6486 else
6487 sprintf((char *)NameBuff, "%ld", *(long *)varp);
6488 }
6489 else /* P_STRING */
6490 {
6491 varp = *(char_u **)(varp);
6492 if (varp == NULL) /* just in case */
6493 NameBuff[0] = NUL;
6494#ifdef FEAT_CRYPT
6495 /* don't show the actual value of 'key', only that it's set */
Bram Moolenaareb3593b2006-04-22 22:33:57 +00006496 else if (opp->var == (char_u *)&p_key && *varp)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006497 STRCPY(NameBuff, "*****");
6498#endif
6499 else if (opp->flags & P_EXPAND)
6500 home_replace(NULL, varp, NameBuff, MAXPATHL, FALSE);
6501 /* Translate 'pastetoggle' into special key names */
6502 else if ((char_u **)opp->var == &p_pt)
6503 str2specialbuf(p_pt, NameBuff, MAXPATHL);
6504 else
Bram Moolenaarce0842a2005-07-18 21:58:11 +00006505 vim_strncpy(NameBuff, varp, MAXPATHL - 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006506 }
6507}
6508
6509/*
6510 * Return TRUE if "varp" points to 'wildchar' or 'wildcharm' and it can be
6511 * printed as a keyname.
6512 * "*wcp" is set to the value of the option if it's 'wildchar' or 'wildcharm'.
6513 */
6514 static int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006515wc_use_keyname(char_u *varp, long *wcp)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006516{
6517 if (((long *)varp == &p_wc) || ((long *)varp == &p_wcm))
6518 {
6519 *wcp = *(long *)varp;
6520 if (IS_SPECIAL(*wcp) || find_special_key_in_table((int)*wcp) >= 0)
6521 return TRUE;
6522 }
6523 return FALSE;
6524}
6525
Bram Moolenaar071d4272004-06-13 20:20:40 +00006526/*
6527 * Return TRUE if format option 'x' is in effect.
6528 * Take care of no formatting when 'paste' is set.
6529 */
6530 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006531has_format_option(int x)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006532{
6533 if (p_paste)
6534 return FALSE;
6535 return (vim_strchr(curbuf->b_p_fo, x) != NULL);
6536}
6537
6538/*
6539 * Return TRUE if "x" is present in 'shortmess' option, or
6540 * 'shortmess' contains 'a' and "x" is present in SHM_A.
6541 */
6542 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006543shortmess(int x)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006544{
Bram Moolenaar7f29f7a2012-02-29 13:51:37 +01006545 return p_shm != NULL &&
6546 ( vim_strchr(p_shm, x) != NULL
Bram Moolenaar071d4272004-06-13 20:20:40 +00006547 || (vim_strchr(p_shm, 'a') != NULL
6548 && vim_strchr((char_u *)SHM_A, x) != NULL));
6549}
6550
6551/*
6552 * paste_option_changed() - Called after p_paste was set or reset.
6553 */
6554 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006555paste_option_changed(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006556{
6557 static int old_p_paste = FALSE;
6558 static int save_sm = 0;
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006559 static int save_sta = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006560#ifdef FEAT_CMDL_INFO
6561 static int save_ru = 0;
6562#endif
6563#ifdef FEAT_RIGHTLEFT
6564 static int save_ri = 0;
6565 static int save_hkmap = 0;
6566#endif
6567 buf_T *buf;
6568
6569 if (p_paste)
6570 {
6571 /*
6572 * Paste switched from off to on.
6573 * Save the current values, so they can be restored later.
6574 */
6575 if (!old_p_paste)
6576 {
6577 /* save options for each buffer */
Bram Moolenaar29323592016-07-24 22:04:11 +02006578 FOR_ALL_BUFFERS(buf)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006579 {
6580 buf->b_p_tw_nopaste = buf->b_p_tw;
6581 buf->b_p_wm_nopaste = buf->b_p_wm;
6582 buf->b_p_sts_nopaste = buf->b_p_sts;
6583 buf->b_p_ai_nopaste = buf->b_p_ai;
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006584 buf->b_p_et_nopaste = buf->b_p_et;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02006585#ifdef FEAT_VARTABS
6586 if (buf->b_p_vsts_nopaste)
6587 vim_free(buf->b_p_vsts_nopaste);
6588 buf->b_p_vsts_nopaste = buf->b_p_vsts && buf->b_p_vsts != empty_option
6589 ? vim_strsave(buf->b_p_vsts) : NULL;
6590#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006591 }
6592
6593 /* save global options */
6594 save_sm = p_sm;
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006595 save_sta = p_sta;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006596#ifdef FEAT_CMDL_INFO
6597 save_ru = p_ru;
6598#endif
6599#ifdef FEAT_RIGHTLEFT
6600 save_ri = p_ri;
6601 save_hkmap = p_hkmap;
6602#endif
6603 /* save global values for local buffer options */
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006604 p_ai_nopaste = p_ai;
6605 p_et_nopaste = p_et;
6606 p_sts_nopaste = p_sts;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006607 p_tw_nopaste = p_tw;
6608 p_wm_nopaste = p_wm;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02006609#ifdef FEAT_VARTABS
6610 if (p_vsts_nopaste)
6611 vim_free(p_vsts_nopaste);
6612 p_vsts_nopaste = p_vsts && p_vsts != empty_option ? vim_strsave(p_vsts) : NULL;
6613#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006614 }
6615
6616 /*
6617 * Always set the option values, also when 'paste' is set when it is
6618 * already on.
6619 */
6620 /* set options for each buffer */
Bram Moolenaar29323592016-07-24 22:04:11 +02006621 FOR_ALL_BUFFERS(buf)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006622 {
6623 buf->b_p_tw = 0; /* textwidth is 0 */
6624 buf->b_p_wm = 0; /* wrapmargin is 0 */
6625 buf->b_p_sts = 0; /* softtabstop is 0 */
6626 buf->b_p_ai = 0; /* no auto-indent */
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006627 buf->b_p_et = 0; /* no expandtab */
Bram Moolenaar04958cb2018-06-23 19:23:02 +02006628#ifdef FEAT_VARTABS
6629 if (buf->b_p_vsts)
6630 free_string_option(buf->b_p_vsts);
6631 buf->b_p_vsts = empty_option;
6632 if (buf->b_p_vsts_array)
6633 vim_free(buf->b_p_vsts_array);
6634 buf->b_p_vsts_array = 0;
6635#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006636 }
6637
6638 /* set global options */
6639 p_sm = 0; /* no showmatch */
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006640 p_sta = 0; /* no smarttab */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006641#ifdef FEAT_CMDL_INFO
Bram Moolenaar071d4272004-06-13 20:20:40 +00006642 if (p_ru)
6643 status_redraw_all(); /* redraw to remove the ruler */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006644 p_ru = 0; /* no ruler */
6645#endif
6646#ifdef FEAT_RIGHTLEFT
6647 p_ri = 0; /* no reverse insert */
6648 p_hkmap = 0; /* no Hebrew keyboard */
6649#endif
6650 /* set global values for local buffer options */
6651 p_tw = 0;
6652 p_wm = 0;
6653 p_sts = 0;
6654 p_ai = 0;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02006655#ifdef FEAT_VARTABS
6656 if (p_vsts)
6657 free_string_option(p_vsts);
6658 p_vsts = empty_option;
6659#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006660 }
6661
6662 /*
6663 * Paste switched from on to off: Restore saved values.
6664 */
6665 else if (old_p_paste)
6666 {
6667 /* restore options for each buffer */
Bram Moolenaar29323592016-07-24 22:04:11 +02006668 FOR_ALL_BUFFERS(buf)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006669 {
6670 buf->b_p_tw = buf->b_p_tw_nopaste;
6671 buf->b_p_wm = buf->b_p_wm_nopaste;
6672 buf->b_p_sts = buf->b_p_sts_nopaste;
6673 buf->b_p_ai = buf->b_p_ai_nopaste;
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006674 buf->b_p_et = buf->b_p_et_nopaste;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02006675#ifdef FEAT_VARTABS
6676 if (buf->b_p_vsts)
6677 free_string_option(buf->b_p_vsts);
6678 buf->b_p_vsts = buf->b_p_vsts_nopaste
6679 ? vim_strsave(buf->b_p_vsts_nopaste) : empty_option;
6680 if (buf->b_p_vsts_array)
6681 vim_free(buf->b_p_vsts_array);
6682 if (buf->b_p_vsts && buf->b_p_vsts != empty_option)
6683 tabstop_set(buf->b_p_vsts, &buf->b_p_vsts_array);
6684 else
6685 buf->b_p_vsts_array = 0;
6686#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006687 }
6688
6689 /* restore global options */
6690 p_sm = save_sm;
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006691 p_sta = save_sta;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006692#ifdef FEAT_CMDL_INFO
Bram Moolenaar071d4272004-06-13 20:20:40 +00006693 if (p_ru != save_ru)
6694 status_redraw_all(); /* redraw to draw the ruler */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006695 p_ru = save_ru;
6696#endif
6697#ifdef FEAT_RIGHTLEFT
6698 p_ri = save_ri;
6699 p_hkmap = save_hkmap;
6700#endif
6701 /* set global values for local buffer options */
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006702 p_ai = p_ai_nopaste;
6703 p_et = p_et_nopaste;
6704 p_sts = p_sts_nopaste;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006705 p_tw = p_tw_nopaste;
6706 p_wm = p_wm_nopaste;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02006707#ifdef FEAT_VARTABS
6708 if (p_vsts)
6709 free_string_option(p_vsts);
6710 p_vsts = p_vsts_nopaste ? vim_strsave(p_vsts_nopaste) : empty_option;
6711#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006712 }
6713
6714 old_p_paste = p_paste;
6715}
6716
6717/*
6718 * vimrc_found() - Called when a ".vimrc" or "VIMINIT" has been found.
6719 *
6720 * Reset 'compatible' and set the values for options that didn't get set yet
6721 * to the Vim defaults.
6722 * Don't do this if the 'compatible' option has been set or reset before.
Bram Moolenaar910f66f2006-04-05 20:41:53 +00006723 * When "fname" is not NULL, use it to set $"envname" when it wasn't set yet.
Bram Moolenaar071d4272004-06-13 20:20:40 +00006724 */
6725 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006726vimrc_found(char_u *fname, char_u *envname)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006727{
Bram Moolenaar910f66f2006-04-05 20:41:53 +00006728 int opt_idx;
Bram Moolenaar4c3f5362006-04-11 21:38:50 +00006729 int dofree = FALSE;
Bram Moolenaar910f66f2006-04-05 20:41:53 +00006730 char_u *p;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006731
6732 if (!option_was_set((char_u *)"cp"))
6733 {
6734 p_cp = FALSE;
Bram Moolenaardac13472019-09-16 21:06:21 +02006735 for (opt_idx = 0; !istermoption_idx(opt_idx); opt_idx++)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006736 if (!(options[opt_idx].flags & (P_WAS_SET|P_VI_DEF)))
6737 set_option_default(opt_idx, OPT_FREE, FALSE);
6738 didset_options();
Bram Moolenaare68c25c2015-08-25 15:39:55 +02006739 didset_options2();
Bram Moolenaar071d4272004-06-13 20:20:40 +00006740 }
Bram Moolenaar910f66f2006-04-05 20:41:53 +00006741
6742 if (fname != NULL)
6743 {
6744 p = vim_getenv(envname, &dofree);
6745 if (p == NULL)
6746 {
6747 /* Set $MYVIMRC to the first vimrc file found. */
6748 p = FullName_save(fname, FALSE);
6749 if (p != NULL)
6750 {
6751 vim_setenv(envname, p);
6752 vim_free(p);
6753 }
6754 }
6755 else if (dofree)
6756 vim_free(p);
6757 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00006758}
6759
6760/*
6761 * Set 'compatible' on or off. Called for "-C" and "-N" command line arg.
6762 */
6763 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006764change_compatible(int on)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006765{
Bram Moolenaarfc1421e2006-04-20 22:17:20 +00006766 int opt_idx;
6767
Bram Moolenaar071d4272004-06-13 20:20:40 +00006768 if (p_cp != on)
6769 {
6770 p_cp = on;
6771 compatible_set();
6772 }
Bram Moolenaarfc1421e2006-04-20 22:17:20 +00006773 opt_idx = findoption((char_u *)"cp");
6774 if (opt_idx >= 0)
6775 options[opt_idx].flags |= P_WAS_SET;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006776}
6777
6778/*
6779 * Return TRUE when option "name" has been set.
Bram Moolenaar1a4a75c2013-07-28 16:03:06 +02006780 * Only works correctly for global options.
Bram Moolenaar071d4272004-06-13 20:20:40 +00006781 */
6782 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006783option_was_set(char_u *name)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006784{
6785 int idx;
6786
6787 idx = findoption(name);
6788 if (idx < 0) /* unknown option */
6789 return FALSE;
6790 if (options[idx].flags & P_WAS_SET)
6791 return TRUE;
6792 return FALSE;
6793}
6794
6795/*
Bram Moolenaar15d55de2012-12-05 14:43:02 +01006796 * Reset the flag indicating option "name" was set.
6797 */
Bram Moolenaarfe8ef982018-09-13 20:31:54 +02006798 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006799reset_option_was_set(char_u *name)
Bram Moolenaar15d55de2012-12-05 14:43:02 +01006800{
6801 int idx = findoption(name);
6802
6803 if (idx >= 0)
Bram Moolenaarfe8ef982018-09-13 20:31:54 +02006804 {
Bram Moolenaar15d55de2012-12-05 14:43:02 +01006805 options[idx].flags &= ~P_WAS_SET;
Bram Moolenaarfe8ef982018-09-13 20:31:54 +02006806 return OK;
6807 }
6808 return FAIL;
Bram Moolenaar15d55de2012-12-05 14:43:02 +01006809}
6810
6811/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00006812 * compatible_set() - Called when 'compatible' has been set or unset.
6813 *
6814 * When 'compatible' set: Set all relevant options (those that have the P_VIM)
6815 * flag) to a Vi compatible value.
6816 * When 'compatible' is unset: Set all options that have a different default
6817 * for Vim (without the P_VI_DEF flag) to that default.
6818 */
6819 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006820compatible_set(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006821{
6822 int opt_idx;
6823
Bram Moolenaardac13472019-09-16 21:06:21 +02006824 for (opt_idx = 0; !istermoption_idx(opt_idx); opt_idx++)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006825 if ( ((options[opt_idx].flags & P_VIM) && p_cp)
6826 || (!(options[opt_idx].flags & P_VI_DEF) && !p_cp))
6827 set_option_default(opt_idx, OPT_FREE, p_cp);
6828 didset_options();
Bram Moolenaare68c25c2015-08-25 15:39:55 +02006829 didset_options2();
Bram Moolenaar071d4272004-06-13 20:20:40 +00006830}
6831
Bram Moolenaardac13472019-09-16 21:06:21 +02006832#if defined(FEAT_LINEBREAK) || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006833
Bram Moolenaar071d4272004-06-13 20:20:40 +00006834/*
6835 * fill_breakat_flags() -- called when 'breakat' changes value.
6836 */
Bram Moolenaardac13472019-09-16 21:06:21 +02006837 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006838fill_breakat_flags(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006839{
Bram Moolenaarac6e65f2005-08-29 22:25:38 +00006840 char_u *p;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006841 int i;
6842
6843 for (i = 0; i < 256; i++)
6844 breakat_flags[i] = FALSE;
6845
6846 if (p_breakat != NULL)
Bram Moolenaarac6e65f2005-08-29 22:25:38 +00006847 for (p = p_breakat; *p; p++)
6848 breakat_flags[*p] = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006849}
Bram Moolenaar071d4272004-06-13 20:20:40 +00006850#endif
6851
6852/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00006853 * Read the 'wildmode' option, fill wim_flags[].
6854 */
Bram Moolenaardac13472019-09-16 21:06:21 +02006855 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006856check_opt_wim(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006857{
6858 char_u new_wim_flags[4];
6859 char_u *p;
6860 int i;
6861 int idx = 0;
6862
6863 for (i = 0; i < 4; ++i)
6864 new_wim_flags[i] = 0;
6865
6866 for (p = p_wim; *p; ++p)
6867 {
6868 for (i = 0; ASCII_ISALPHA(p[i]); ++i)
6869 ;
6870 if (p[i] != NUL && p[i] != ',' && p[i] != ':')
6871 return FAIL;
6872 if (i == 7 && STRNCMP(p, "longest", 7) == 0)
6873 new_wim_flags[idx] |= WIM_LONGEST;
6874 else if (i == 4 && STRNCMP(p, "full", 4) == 0)
6875 new_wim_flags[idx] |= WIM_FULL;
6876 else if (i == 4 && STRNCMP(p, "list", 4) == 0)
6877 new_wim_flags[idx] |= WIM_LIST;
6878 else
6879 return FAIL;
6880 p += i;
6881 if (*p == NUL)
6882 break;
6883 if (*p == ',')
6884 {
6885 if (idx == 3)
6886 return FAIL;
6887 ++idx;
6888 }
6889 }
6890
6891 /* fill remaining entries with last flag */
6892 while (idx < 3)
6893 {
6894 new_wim_flags[idx + 1] = new_wim_flags[idx];
6895 ++idx;
6896 }
6897
6898 /* only when there are no errors, wim_flags[] is changed */
6899 for (i = 0; i < 4; ++i)
6900 wim_flags[i] = new_wim_flags[i];
6901 return OK;
6902}
6903
6904/*
6905 * Check if backspacing over something is allowed.
6906 */
6907 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006908can_bs(
6909 int what) /* BS_INDENT, BS_EOL or BS_START */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006910{
Bram Moolenaar6b810d92018-06-04 17:28:44 +02006911#ifdef FEAT_JOB_CHANNEL
6912 if (what == BS_START && bt_prompt(curbuf))
6913 return FALSE;
6914#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006915 switch (*p_bs)
6916 {
6917 case '2': return TRUE;
6918 case '1': return (what != BS_START);
6919 case '0': return FALSE;
6920 }
6921 return vim_strchr(p_bs, what) != NULL;
6922}
6923
6924/*
6925 * Save the current values of 'fileformat' and 'fileencoding', so that we know
6926 * the file must be considered changed when the value is different.
6927 */
6928 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006929save_file_ff(buf_T *buf)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006930{
6931 buf->b_start_ffc = *buf->b_p_ff;
6932 buf->b_start_eol = buf->b_p_eol;
Bram Moolenaar83eb8852007-08-12 13:51:26 +00006933 buf->b_start_bomb = buf->b_p_bomb;
6934
Bram Moolenaar071d4272004-06-13 20:20:40 +00006935 /* Only use free/alloc when necessary, they take time. */
6936 if (buf->b_start_fenc == NULL
6937 || STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0)
6938 {
6939 vim_free(buf->b_start_fenc);
6940 buf->b_start_fenc = vim_strsave(buf->b_p_fenc);
6941 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00006942}
6943
6944/*
6945 * Return TRUE if 'fileformat' and/or 'fileencoding' has a different value
6946 * from when editing started (save_file_ff() called).
Bram Moolenaar83eb8852007-08-12 13:51:26 +00006947 * Also when 'endofline' was changed and 'binary' is set, or when 'bomb' was
6948 * changed and 'binary' is not set.
Bram Moolenaar34d72d42015-07-17 14:18:08 +02006949 * Also when 'endofline' was changed and 'fixeol' is not set.
Bram Moolenaar164c60f2011-01-22 00:11:50 +01006950 * When "ignore_empty" is true don't consider a new, empty buffer to be
6951 * changed.
Bram Moolenaar071d4272004-06-13 20:20:40 +00006952 */
6953 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006954file_ff_differs(buf_T *buf, int ignore_empty)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006955{
Bram Moolenaar9cffde92007-07-24 07:51:18 +00006956 /* In a buffer that was never loaded the options are not valid. */
6957 if (buf->b_flags & BF_NEVERLOADED)
6958 return FALSE;
Bram Moolenaar164c60f2011-01-22 00:11:50 +01006959 if (ignore_empty
6960 && (buf->b_flags & BF_NEW)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006961 && buf->b_ml.ml_line_count == 1
6962 && *ml_get_buf(buf, (linenr_T)1, FALSE) == NUL)
6963 return FALSE;
6964 if (buf->b_start_ffc != *buf->b_p_ff)
6965 return TRUE;
Bram Moolenaar34d72d42015-07-17 14:18:08 +02006966 if ((buf->b_p_bin || !buf->b_p_fixeol) && buf->b_start_eol != buf->b_p_eol)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006967 return TRUE;
Bram Moolenaar83eb8852007-08-12 13:51:26 +00006968 if (!buf->b_p_bin && buf->b_start_bomb != buf->b_p_bomb)
6969 return TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006970 if (buf->b_start_fenc == NULL)
6971 return (*buf->b_p_fenc != NUL);
6972 return (STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006973}
6974
6975/*
Bram Moolenaar375e3392019-01-31 18:26:10 +01006976 * Return the effective 'scrolloff' value for the current window, using the
6977 * global value when appropriate.
6978 */
6979 long
6980get_scrolloff_value(void)
6981{
6982 return curwin->w_p_so < 0 ? p_so : curwin->w_p_so;
6983}
6984
6985/*
6986 * Return the effective 'sidescrolloff' value for the current window, using the
6987 * global value when appropriate.
6988 */
6989 long
6990get_sidescrolloff_value(void)
6991{
6992 return curwin->w_p_siso < 0 ? p_siso : curwin->w_p_siso;
6993}
6994
6995/*
Bram Moolenaar8c7694a2013-01-17 17:02:05 +01006996 * Check matchpairs option for "*initc".
6997 * If there is a match set "*initc" to the matching character and "*findc" to
6998 * the opposite character. Set "*backwards" to the direction.
6999 * When "switchit" is TRUE swap the direction.
7000 */
7001 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01007002find_mps_values(
7003 int *initc,
7004 int *findc,
7005 int *backwards,
7006 int switchit)
Bram Moolenaar8c7694a2013-01-17 17:02:05 +01007007{
7008 char_u *ptr;
7009
7010 ptr = curbuf->b_p_mps;
7011 while (*ptr != NUL)
7012 {
Bram Moolenaar8c7694a2013-01-17 17:02:05 +01007013 if (has_mbyte)
7014 {
7015 char_u *prev;
7016
7017 if (mb_ptr2char(ptr) == *initc)
7018 {
7019 if (switchit)
7020 {
7021 *findc = *initc;
7022 *initc = mb_ptr2char(ptr + mb_ptr2len(ptr) + 1);
7023 *backwards = TRUE;
7024 }
7025 else
7026 {
7027 *findc = mb_ptr2char(ptr + mb_ptr2len(ptr) + 1);
7028 *backwards = FALSE;
7029 }
7030 return;
7031 }
7032 prev = ptr;
7033 ptr += mb_ptr2len(ptr) + 1;
7034 if (mb_ptr2char(ptr) == *initc)
7035 {
7036 if (switchit)
7037 {
7038 *findc = *initc;
7039 *initc = mb_ptr2char(prev);
7040 *backwards = FALSE;
7041 }
7042 else
7043 {
7044 *findc = mb_ptr2char(prev);
7045 *backwards = TRUE;
7046 }
7047 return;
7048 }
7049 ptr += mb_ptr2len(ptr);
7050 }
7051 else
Bram Moolenaar8c7694a2013-01-17 17:02:05 +01007052 {
7053 if (*ptr == *initc)
7054 {
7055 if (switchit)
7056 {
7057 *backwards = TRUE;
7058 *findc = *initc;
7059 *initc = ptr[2];
7060 }
7061 else
7062 {
7063 *backwards = FALSE;
7064 *findc = ptr[2];
7065 }
7066 return;
7067 }
7068 ptr += 2;
7069 if (*ptr == *initc)
7070 {
7071 if (switchit)
7072 {
7073 *backwards = FALSE;
7074 *findc = *initc;
7075 *initc = ptr[-2];
7076 }
7077 else
7078 {
7079 *backwards = TRUE;
7080 *findc = ptr[-2];
7081 }
7082 return;
7083 }
7084 ++ptr;
7085 }
7086 if (*ptr == ',')
7087 ++ptr;
7088 }
7089}
Bram Moolenaar597a4222014-06-25 14:39:50 +02007090
7091#if defined(FEAT_LINEBREAK) || defined(PROTO)
7092/*
7093 * This is called when 'breakindentopt' is changed and when a window is
7094 * initialized.
7095 */
Bram Moolenaardac13472019-09-16 21:06:21 +02007096 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01007097briopt_check(win_T *wp)
Bram Moolenaar597a4222014-06-25 14:39:50 +02007098{
7099 char_u *p;
7100 int bri_shift = 0;
7101 long bri_min = 20;
7102 int bri_sbr = FALSE;
7103
Bram Moolenaar285ed7e2014-08-24 21:39:49 +02007104 p = wp->w_p_briopt;
Bram Moolenaar597a4222014-06-25 14:39:50 +02007105 while (*p != NUL)
7106 {
7107 if (STRNCMP(p, "shift:", 6) == 0
7108 && ((p[6] == '-' && VIM_ISDIGIT(p[7])) || VIM_ISDIGIT(p[6])))
7109 {
7110 p += 6;
7111 bri_shift = getdigits(&p);
7112 }
7113 else if (STRNCMP(p, "min:", 4) == 0 && VIM_ISDIGIT(p[4]))
7114 {
7115 p += 4;
7116 bri_min = getdigits(&p);
7117 }
7118 else if (STRNCMP(p, "sbr", 3) == 0)
7119 {
7120 p += 3;
7121 bri_sbr = TRUE;
7122 }
7123 if (*p != ',' && *p != NUL)
7124 return FAIL;
7125 if (*p == ',')
7126 ++p;
7127 }
7128
Bram Moolenaar285ed7e2014-08-24 21:39:49 +02007129 wp->w_p_brishift = bri_shift;
7130 wp->w_p_brimin = bri_min;
7131 wp->w_p_brisbr = bri_sbr;
Bram Moolenaar597a4222014-06-25 14:39:50 +02007132
7133 return OK;
7134}
7135#endif
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02007136
7137/*
7138 * Get the local or global value of 'backupcopy'.
7139 */
7140 unsigned int
Bram Moolenaar9b578142016-01-30 19:39:49 +01007141get_bkc_value(buf_T *buf)
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02007142{
7143 return buf->b_bkc_flags ? buf->b_bkc_flags : bkc_flags;
7144}
Bram Moolenaar95ec9d62016-08-12 18:29:59 +02007145
7146#if defined(FEAT_SIGNS) || defined(PROTO)
7147/*
7148 * Return TRUE when window "wp" has a column to draw signs in.
7149 */
7150 int
7151signcolumn_on(win_T *wp)
7152{
Bram Moolenaar394c5d82019-06-17 21:48:05 +02007153 // If 'signcolumn' is set to 'number', signs are displayed in the 'number'
7154 // column (if present). Otherwise signs are to be displayed in the sign
7155 // column.
7156 if (*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u')
7157 return wp->w_buffer->b_signlist != NULL && !wp->w_p_nu && !wp->w_p_rnu;
7158
Bram Moolenaar95ec9d62016-08-12 18:29:59 +02007159 if (*wp->w_p_scl == 'n')
7160 return FALSE;
7161 if (*wp->w_p_scl == 'y')
7162 return TRUE;
7163 return (wp->w_buffer->b_signlist != NULL
7164# ifdef FEAT_NETBEANS_INTG
7165 || wp->w_buffer->b_has_sign_column
7166# endif
7167 );
7168}
7169#endif
Bram Moolenaarb5ae48e2016-08-12 22:23:25 +02007170
7171#if defined(FEAT_EVAL) || defined(PROTO)
7172/*
7173 * Get window or buffer local options.
7174 */
7175 dict_T *
7176get_winbuf_options(int bufopt)
7177{
7178 dict_T *d;
7179 int opt_idx;
7180
7181 d = dict_alloc();
7182 if (d == NULL)
7183 return NULL;
7184
Bram Moolenaardac13472019-09-16 21:06:21 +02007185 for (opt_idx = 0; !istermoption_idx(opt_idx); opt_idx++)
Bram Moolenaarb5ae48e2016-08-12 22:23:25 +02007186 {
7187 struct vimoption *opt = &options[opt_idx];
7188
7189 if ((bufopt && (opt->indir & PV_BUF))
7190 || (!bufopt && (opt->indir & PV_WIN)))
7191 {
7192 char_u *varp = get_varp(opt);
7193
7194 if (varp != NULL)
7195 {
7196 if (opt->flags & P_STRING)
Bram Moolenaare0be1672018-07-08 16:50:37 +02007197 dict_add_string(d, opt->fullname, *(char_u **)varp);
Bram Moolenaar789a5c02016-09-12 19:51:11 +02007198 else if (opt->flags & P_NUM)
Bram Moolenaare0be1672018-07-08 16:50:37 +02007199 dict_add_number(d, opt->fullname, *(long *)varp);
Bram Moolenaarb5ae48e2016-08-12 22:23:25 +02007200 else
Bram Moolenaare0be1672018-07-08 16:50:37 +02007201 dict_add_number(d, opt->fullname, *(int *)varp);
Bram Moolenaarb5ae48e2016-08-12 22:23:25 +02007202 }
7203 }
7204 }
7205
7206 return d;
7207}
7208#endif
Bram Moolenaar017ba072019-09-14 21:01:23 +02007209
Bram Moolenaardac13472019-09-16 21:06:21 +02007210#if defined(FEAT_SYN_HL) || defined(PROTO)
Bram Moolenaar017ba072019-09-14 21:01:23 +02007211/*
7212 * This is called when 'culopt' is changed
7213 */
Bram Moolenaardac13472019-09-16 21:06:21 +02007214 int
Bram Moolenaar017ba072019-09-14 21:01:23 +02007215fill_culopt_flags(char_u *val, win_T *wp)
7216{
7217 char_u *p;
7218 char_u culopt_flags_new = 0;
7219
7220 if (val == NULL)
7221 p = wp->w_p_culopt;
7222 else
7223 p = val;
7224 while (*p != NUL)
7225 {
7226 if (STRNCMP(p, "line", 4) == 0)
7227 {
7228 p += 4;
7229 culopt_flags_new |= CULOPT_LINE;
7230 }
7231 else if (STRNCMP(p, "both", 4) == 0)
7232 {
7233 p += 4;
7234 culopt_flags_new |= CULOPT_LINE | CULOPT_NBR;
7235 }
7236 else if (STRNCMP(p, "number", 6) == 0)
7237 {
7238 p += 6;
7239 culopt_flags_new |= CULOPT_NBR;
7240 }
7241 else if (STRNCMP(p, "screenline", 10) == 0)
7242 {
7243 p += 10;
7244 culopt_flags_new |= CULOPT_SCRLINE;
7245 }
7246
7247 if (*p != ',' && *p != NUL)
7248 return FAIL;
7249 if (*p == ',')
7250 ++p;
7251 }
7252
7253 // Can't have both "line" and "screenline".
7254 if ((culopt_flags_new & CULOPT_LINE) && (culopt_flags_new & CULOPT_SCRLINE))
7255 return FAIL;
7256 wp->w_p_culopt_flags = culopt_flags_new;
7257
7258 return OK;
7259}
7260#endif