blob: 1ffa11d121708447f7ff12d8c34a770786f3ec84 [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))
689 set_option_default(i, OPT_LOCAL, FALSE);
690 }
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
2326 /* set cedit_key */
2327 (void)check_cedit();
2328#endif
Bram Moolenaar597a4222014-06-25 14:39:50 +02002329#ifdef FEAT_LINEBREAK
Bram Moolenaar285ed7e2014-08-24 21:39:49 +02002330 briopt_check(curwin);
Bram Moolenaar597a4222014-06-25 14:39:50 +02002331#endif
Bram Moolenaare68c25c2015-08-25 15:39:55 +02002332#ifdef FEAT_LINEBREAK
2333 /* initialize the table for 'breakat'. */
2334 fill_breakat_flags();
2335#endif
Bram Moolenaar017ba072019-09-14 21:01:23 +02002336#ifdef FEAT_SYN_HL
2337 fill_culopt_flags(NULL, curwin);
2338#endif
Bram Moolenaare68c25c2015-08-25 15:39:55 +02002339}
2340
2341/*
2342 * More side effects of setting options.
2343 */
2344 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01002345didset_options2(void)
Bram Moolenaare68c25c2015-08-25 15:39:55 +02002346{
2347 /* Initialize the highlight_attr[] table. */
2348 (void)highlight_changed();
2349
2350 /* Parse default for 'wildmode' */
2351 check_opt_wim();
2352
2353 (void)set_chars_option(&p_lcs);
Bram Moolenaare68c25c2015-08-25 15:39:55 +02002354 /* Parse default for 'fillchars'. */
2355 (void)set_chars_option(&p_fcs);
Bram Moolenaare68c25c2015-08-25 15:39:55 +02002356
2357#ifdef FEAT_CLIPBOARD
2358 /* Parse default for 'clipboard' */
2359 (void)check_clipboard_option();
2360#endif
Bram Moolenaar04958cb2018-06-23 19:23:02 +02002361#ifdef FEAT_VARTABS
Bram Moolenaar55c77cf2019-02-16 19:05:11 +01002362 vim_free(curbuf->b_p_vsts_array);
Bram Moolenaar04958cb2018-06-23 19:23:02 +02002363 tabstop_set(curbuf->b_p_vsts, &curbuf->b_p_vsts_array);
Bram Moolenaar55c77cf2019-02-16 19:05:11 +01002364 vim_free(curbuf->b_p_vts_array);
Bram Moolenaar04958cb2018-06-23 19:23:02 +02002365 tabstop_set(curbuf->b_p_vts, &curbuf->b_p_vts_array);
2366#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00002367}
2368
2369/*
2370 * Check for string options that are NULL (normally only termcap options).
2371 */
2372 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01002373check_options(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002374{
2375 int opt_idx;
2376
2377 for (opt_idx = 0; options[opt_idx].fullname != NULL; opt_idx++)
2378 if ((options[opt_idx].flags & P_STRING) && options[opt_idx].var != NULL)
2379 check_string_option((char_u **)get_varp(&(options[opt_idx])));
2380}
2381
2382/*
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02002383 * Return the option index found by a pointer into term_strings[].
2384 * Return -1 if not found.
Bram Moolenaar071d4272004-06-13 20:20:40 +00002385 */
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02002386 int
2387get_term_opt_idx(char_u **p)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002388{
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02002389 int opt_idx;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002390
2391 for (opt_idx = 1; options[opt_idx].fullname != NULL; opt_idx++)
2392 if (options[opt_idx].var == (char_u *)p)
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02002393 return opt_idx;
2394 return -1; // cannot happen: didn't find it!
2395}
2396
2397/*
2398 * Mark a terminal option as allocated, found by a pointer into term_strings[].
2399 * Return the option index or -1 if not found.
2400 */
2401 int
2402set_term_option_alloced(char_u **p)
2403{
2404 int opt_idx = get_term_opt_idx(p);
2405
2406 if (opt_idx >= 0)
2407 options[opt_idx].flags |= P_ALLOCED;
2408 return opt_idx;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002409}
2410
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002411#if defined(FEAT_EVAL) || defined(PROTO)
2412/*
2413 * Return TRUE when option "opt" was set from a modeline or in secure mode.
2414 * Return FALSE when it wasn't.
2415 * Return -1 for an unknown option.
2416 */
2417 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01002418was_set_insecurely(char_u *opt, int opt_flags)
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002419{
2420 int idx = findoption(opt);
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002421 long_u *flagp;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002422
2423 if (idx >= 0)
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002424 {
2425 flagp = insecure_flag(idx, opt_flags);
2426 return (*flagp & P_INSECURE) != 0;
2427 }
Bram Moolenaar95f09602016-11-10 20:01:45 +01002428 internal_error("was_set_insecurely()");
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002429 return -1;
2430}
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002431
2432/*
2433 * Get a pointer to the flags used for the P_INSECURE flag of option
2434 * "opt_idx". For some local options a local flags field is used.
2435 */
2436 static long_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01002437insecure_flag(int opt_idx, int opt_flags)
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002438{
2439 if (opt_flags & OPT_LOCAL)
2440 switch ((int)options[opt_idx].indir)
2441 {
2442#ifdef FEAT_STL_OPT
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002443 case PV_STL: return &curwin->w_p_stl_flags;
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002444#endif
2445#ifdef FEAT_EVAL
Bram Moolenaar2e978902006-05-13 12:37:50 +00002446# ifdef FEAT_FOLDING
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002447 case PV_FDE: return &curwin->w_p_fde_flags;
2448 case PV_FDT: return &curwin->w_p_fdt_flags;
Bram Moolenaar2e978902006-05-13 12:37:50 +00002449# endif
Bram Moolenaar9b2200a2006-03-20 21:55:45 +00002450# ifdef FEAT_BEVAL
2451 case PV_BEXPR: return &curbuf->b_p_bexpr_flags;
2452# endif
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002453# if defined(FEAT_CINDENT)
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002454 case PV_INDE: return &curbuf->b_p_inde_flags;
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002455# endif
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002456 case PV_FEX: return &curbuf->b_p_fex_flags;
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002457# ifdef FEAT_FIND_ID
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002458 case PV_INEX: return &curbuf->b_p_inex_flags;
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002459# endif
2460#endif
2461 }
2462
2463 /* Nothing special, return global flags field. */
2464 return &options[opt_idx].flags;
2465}
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002466#endif
2467
Bram Moolenaardac13472019-09-16 21:06:21 +02002468#if defined(FEAT_TITLE) || defined(PROTO)
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002469/*
2470 * Redraw the window title and/or tab page text later.
2471 */
Bram Moolenaardac13472019-09-16 21:06:21 +02002472void redraw_titles(void)
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002473{
2474 need_maketitle = TRUE;
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002475 redraw_tabline = TRUE;
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002476}
2477#endif
2478
Bram Moolenaar071d4272004-06-13 20:20:40 +00002479/*
Bram Moolenaar8f130ed2019-04-10 22:15:19 +02002480 * Return TRUE if "val" is a valid name: only consists of alphanumeric ASCII
2481 * characters or characters in "allowed".
2482 */
Bram Moolenaare677df82019-09-02 22:31:11 +02002483 int
Bram Moolenaar8f130ed2019-04-10 22:15:19 +02002484valid_name(char_u *val, char *allowed)
2485{
2486 char_u *s;
2487
2488 for (s = val; *s != NUL; ++s)
2489 if (!ASCII_ISALNUM(*s) && vim_strchr((char_u *)allowed, *s) == NULL)
2490 return FALSE;
2491 return TRUE;
2492}
2493
Bram Moolenaardac13472019-09-16 21:06:21 +02002494#if defined(FEAT_CLIPBOARD) || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002495/*
2496 * Extract the items in the 'clipboard' option and set global values.
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002497 * Return an error message or NULL for success.
Bram Moolenaar071d4272004-06-13 20:20:40 +00002498 */
Bram Moolenaardac13472019-09-16 21:06:21 +02002499 char *
Bram Moolenaar9b578142016-01-30 19:39:49 +01002500check_clipboard_option(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002501{
Bram Moolenaarbf9680e2010-12-02 21:43:16 +01002502 int new_unnamed = 0;
Bram Moolenaar89af4392012-07-10 18:31:54 +02002503 int new_autoselect_star = FALSE;
2504 int new_autoselect_plus = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002505 int new_autoselectml = FALSE;
Bram Moolenaar3a6eaa52009-06-16 13:23:06 +00002506 int new_html = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002507 regprog_T *new_exclude_prog = NULL;
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002508 char *errmsg = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002509 char_u *p;
2510
2511 for (p = p_cb; *p != NUL; )
2512 {
2513 if (STRNCMP(p, "unnamed", 7) == 0 && (p[7] == ',' || p[7] == NUL))
2514 {
Bram Moolenaarbf9680e2010-12-02 21:43:16 +01002515 new_unnamed |= CLIP_UNNAMED;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002516 p += 7;
2517 }
Bram Moolenaar11b73d62012-06-29 15:51:30 +02002518 else if (STRNCMP(p, "unnamedplus", 11) == 0
Bram Moolenaarbf9680e2010-12-02 21:43:16 +01002519 && (p[11] == ',' || p[11] == NUL))
2520 {
2521 new_unnamed |= CLIP_UNNAMED_PLUS;
2522 p += 11;
2523 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002524 else if (STRNCMP(p, "autoselect", 10) == 0
Bram Moolenaar89af4392012-07-10 18:31:54 +02002525 && (p[10] == ',' || p[10] == NUL))
Bram Moolenaar071d4272004-06-13 20:20:40 +00002526 {
Bram Moolenaar89af4392012-07-10 18:31:54 +02002527 new_autoselect_star = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002528 p += 10;
2529 }
Bram Moolenaar89af4392012-07-10 18:31:54 +02002530 else if (STRNCMP(p, "autoselectplus", 14) == 0
2531 && (p[14] == ',' || p[14] == NUL))
2532 {
2533 new_autoselect_plus = TRUE;
2534 p += 14;
2535 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002536 else if (STRNCMP(p, "autoselectml", 12) == 0
Bram Moolenaar89af4392012-07-10 18:31:54 +02002537 && (p[12] == ',' || p[12] == NUL))
Bram Moolenaar071d4272004-06-13 20:20:40 +00002538 {
2539 new_autoselectml = TRUE;
2540 p += 12;
2541 }
Bram Moolenaar3a6eaa52009-06-16 13:23:06 +00002542 else if (STRNCMP(p, "html", 4) == 0 && (p[4] == ',' || p[4] == NUL))
2543 {
2544 new_html = TRUE;
2545 p += 4;
2546 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002547 else if (STRNCMP(p, "exclude:", 8) == 0 && new_exclude_prog == NULL)
2548 {
2549 p += 8;
2550 new_exclude_prog = vim_regcomp(p, RE_MAGIC);
2551 if (new_exclude_prog == NULL)
2552 errmsg = e_invarg;
2553 break;
2554 }
2555 else
2556 {
2557 errmsg = e_invarg;
2558 break;
2559 }
2560 if (*p == ',')
2561 ++p;
2562 }
2563 if (errmsg == NULL)
2564 {
2565 clip_unnamed = new_unnamed;
Bram Moolenaar89af4392012-07-10 18:31:54 +02002566 clip_autoselect_star = new_autoselect_star;
2567 clip_autoselect_plus = new_autoselect_plus;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002568 clip_autoselectml = new_autoselectml;
Bram Moolenaar3a6eaa52009-06-16 13:23:06 +00002569 clip_html = new_html;
Bram Moolenaar473de612013-06-08 18:19:48 +02002570 vim_regfree(clip_exclude_prog);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002571 clip_exclude_prog = new_exclude_prog;
Bram Moolenaara76638f2010-06-05 12:49:46 +02002572#ifdef FEAT_GUI_GTK
2573 if (gui.in_use)
2574 {
2575 gui_gtk_set_selection_targets();
2576 gui_gtk_set_dnd_targets();
2577 }
2578#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00002579 }
2580 else
Bram Moolenaar473de612013-06-08 18:19:48 +02002581 vim_regfree(new_exclude_prog);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002582
2583 return errmsg;
2584}
2585#endif
2586
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002587#if defined(FEAT_EVAL) || defined(PROTO)
2588/*
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002589 * Set the script_ctx for an option, taking care of setting the buffer- or
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002590 * window-local value.
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002591 */
Bram Moolenaardac13472019-09-16 21:06:21 +02002592 void
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002593set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002594{
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002595 int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
2596 int indir = (int)options[opt_idx].indir;
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002597 sctx_T new_script_ctx = script_ctx;
2598
2599 new_script_ctx.sc_lnum += sourcing_lnum;
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002600
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002601 /* Remember where the option was set. For local options need to do that
2602 * in the buffer or window structure. */
2603 if (both || (opt_flags & OPT_GLOBAL) || (indir & (PV_BUF|PV_WIN)) == 0)
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002604 options[opt_idx].script_ctx = new_script_ctx;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002605 if (both || (opt_flags & OPT_LOCAL))
2606 {
2607 if (indir & PV_BUF)
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002608 curbuf->b_p_script_ctx[indir & PV_MASK] = new_script_ctx;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002609 else if (indir & PV_WIN)
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002610 curwin->w_p_script_ctx[indir & PV_MASK] = new_script_ctx;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002611 }
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002612}
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02002613
2614/*
2615 * Set the script_ctx for a termcap option.
2616 * "name" must be the two character code, e.g. "RV".
2617 * When "name" is NULL use "opt_idx".
2618 */
2619 void
2620set_term_option_sctx_idx(char *name, int opt_idx)
2621{
2622 char_u buf[5];
2623 int idx;
2624
2625 if (name == NULL)
2626 idx = opt_idx;
2627 else
2628 {
2629 buf[0] = 't';
2630 buf[1] = '_';
2631 buf[2] = name[0];
2632 buf[3] = name[1];
2633 buf[4] = 0;
2634 idx = findoption(buf);
2635 }
2636 if (idx >= 0)
2637 set_option_sctx_idx(idx, OPT_GLOBAL, current_sctx);
2638}
Bram Moolenaard1f56e62006-02-22 21:25:37 +00002639#endif
2640
Bram Moolenaar071d4272004-06-13 20:20:40 +00002641/*
2642 * Set the value of a boolean option, and take care of side effects.
2643 * Returns NULL for success, or an error message for an error.
2644 */
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002645 static char *
Bram Moolenaar9b578142016-01-30 19:39:49 +01002646set_bool_option(
2647 int opt_idx, /* index in options[] table */
2648 char_u *varp, /* pointer to the option variable */
2649 int value, /* new value */
2650 int opt_flags) /* OPT_LOCAL and/or OPT_GLOBAL */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002651{
2652 int old_value = *(int *)varp;
Bram Moolenaar983f2f12019-06-16 16:41:41 +02002653#if defined(FEAT_EVAL)
Bram Moolenaard7c96872019-06-15 17:12:48 +02002654 int old_global_value = 0;
Bram Moolenaar983f2f12019-06-16 16:41:41 +02002655#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00002656
Bram Moolenaar071d4272004-06-13 20:20:40 +00002657 /* Disallow changing some options from secure mode */
2658 if ((secure
2659#ifdef HAVE_SANDBOX
2660 || sandbox != 0
2661#endif
2662 ) && (options[opt_idx].flags & P_SECURE))
2663 return e_secure;
2664
Bram Moolenaar983f2f12019-06-16 16:41:41 +02002665#if defined(FEAT_EVAL)
Bram Moolenaard7c96872019-06-15 17:12:48 +02002666 // Save the global value before changing anything. This is needed as for
2667 // a global-only option setting the "local value" in fact sets the global
2668 // value (since there is only one value).
2669 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
2670 old_global_value = *(int *)get_varp_scope(&(options[opt_idx]),
2671 OPT_GLOBAL);
Bram Moolenaar983f2f12019-06-16 16:41:41 +02002672#endif
Bram Moolenaard7c96872019-06-15 17:12:48 +02002673
Bram Moolenaar071d4272004-06-13 20:20:40 +00002674 *(int *)varp = value; /* set the new value */
2675#ifdef FEAT_EVAL
2676 /* Remember where the option was set. */
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02002677 set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002678#endif
2679
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00002680#ifdef FEAT_GUI
2681 need_mouse_correct = TRUE;
2682#endif
2683
Bram Moolenaar071d4272004-06-13 20:20:40 +00002684 /* May set global value for local option. */
2685 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
2686 *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = value;
2687
2688 /*
2689 * Handle side effects of changing a bool option.
2690 */
2691
2692 /* 'compatible' */
2693 if ((int *)varp == &p_cp)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002694 compatible_set();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002695
Bram Moolenaar920694c2016-08-21 17:45:02 +02002696#ifdef FEAT_LANGMAP
2697 if ((int *)varp == &p_lrm)
2698 /* 'langremap' -> !'langnoremap' */
2699 p_lnr = !p_lrm;
2700 else if ((int *)varp == &p_lnr)
2701 /* 'langnoremap' -> !'langremap' */
2702 p_lrm = !p_lnr;
2703#endif
2704
Bram Moolenaar8c63e0e2018-09-25 22:17:54 +02002705#ifdef FEAT_SYN_HL
2706 else if ((int *)varp == &curwin->w_p_cul && !value && old_value)
2707 reset_cursorline();
2708#endif
2709
Bram Moolenaar374d32d2012-01-04 19:34:37 +01002710#ifdef FEAT_PERSISTENT_UNDO
2711 /* 'undofile' */
2712 else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf)
2713 {
Bram Moolenaare8d8fd22012-10-21 03:46:05 +02002714 /* Only take action when the option was set. When reset we do not
2715 * delete the undo file, the option may be set again without making
2716 * any changes in between. */
2717 if (curbuf->b_p_udf || p_udf)
Bram Moolenaar374d32d2012-01-04 19:34:37 +01002718 {
Bram Moolenaare8d8fd22012-10-21 03:46:05 +02002719 char_u hash[UNDO_HASH_SIZE];
2720 buf_T *save_curbuf = curbuf;
2721
Bram Moolenaar29323592016-07-24 22:04:11 +02002722 FOR_ALL_BUFFERS(curbuf)
Bram Moolenaar374d32d2012-01-04 19:34:37 +01002723 {
Bram Moolenaare8d8fd22012-10-21 03:46:05 +02002724 /* When 'undofile' is set globally: for every buffer, otherwise
2725 * only for the current buffer: Try to read in the undofile,
2726 * if one exists, the buffer wasn't changed and the buffer was
2727 * loaded */
2728 if ((curbuf == save_curbuf
2729 || (opt_flags & OPT_GLOBAL) || opt_flags == 0)
2730 && !curbufIsChanged() && curbuf->b_ml.ml_mfp != NULL)
2731 {
2732 u_compute_hash(hash);
2733 u_read_undo(NULL, hash, curbuf->b_fname);
2734 }
Bram Moolenaar374d32d2012-01-04 19:34:37 +01002735 }
Bram Moolenaare8d8fd22012-10-21 03:46:05 +02002736 curbuf = save_curbuf;
Bram Moolenaar374d32d2012-01-04 19:34:37 +01002737 }
Bram Moolenaar374d32d2012-01-04 19:34:37 +01002738 }
2739#endif
2740
Bram Moolenaar071d4272004-06-13 20:20:40 +00002741 else if ((int *)varp == &curbuf->b_p_ro)
2742 {
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +00002743 /* when 'readonly' is reset globally, also reset readonlymode */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002744 if (!curbuf->b_p_ro && (opt_flags & OPT_LOCAL) == 0)
2745 readonlymode = FALSE;
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +00002746
2747 /* when 'readonly' is set may give W10 again */
2748 if (curbuf->b_p_ro)
2749 curbuf->b_did_warn = FALSE;
2750
Bram Moolenaar071d4272004-06-13 20:20:40 +00002751#ifdef FEAT_TITLE
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002752 redraw_titles();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002753#endif
2754 }
2755
Bram Moolenaar9c449722010-07-20 18:44:27 +02002756#ifdef FEAT_GUI
2757 else if ((int *)varp == &p_mh)
2758 {
2759 if (!p_mh)
2760 gui_mch_mousehide(FALSE);
2761 }
2762#endif
2763
Bram Moolenaara539df02010-08-01 14:35:05 +02002764 /* when 'modifiable' is changed, redraw the window title */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002765 else if ((int *)varp == &curbuf->b_p_ma)
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002766 {
Bram Moolenaar423802d2017-07-30 16:52:24 +02002767# ifdef FEAT_TERMINAL
2768 /* Cannot set 'modifiable' when in Terminal mode. */
Bram Moolenaard7db27b2018-03-07 23:02:33 +01002769 if (curbuf->b_p_ma && (term_in_normal_mode() || (bt_terminal(curbuf)
2770 && curbuf->b_term != NULL && !term_is_finished(curbuf))))
Bram Moolenaar423802d2017-07-30 16:52:24 +02002771 {
2772 curbuf->b_p_ma = FALSE;
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002773 return N_("E946: Cannot make a terminal with running job modifiable");
Bram Moolenaar423802d2017-07-30 16:52:24 +02002774 }
2775# endif
2776# ifdef FEAT_TITLE
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002777 redraw_titles();
Bram Moolenaar423802d2017-07-30 16:52:24 +02002778# endif
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002779 }
Bram Moolenaar423802d2017-07-30 16:52:24 +02002780#ifdef FEAT_TITLE
Bram Moolenaar071d4272004-06-13 20:20:40 +00002781 /* when 'endofline' is changed, redraw the window title */
2782 else if ((int *)varp == &curbuf->b_p_eol)
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002783 {
2784 redraw_titles();
2785 }
Bram Moolenaar34d72d42015-07-17 14:18:08 +02002786 /* when 'fixeol' is changed, redraw the window title */
2787 else if ((int *)varp == &curbuf->b_p_fixeol)
2788 {
2789 redraw_titles();
2790 }
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002791 /* when 'bomb' is changed, redraw the window title and tab page text */
Bram Moolenaar83eb8852007-08-12 13:51:26 +00002792 else if ((int *)varp == &curbuf->b_p_bomb)
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002793 {
2794 redraw_titles();
2795 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002796#endif
2797
2798 /* when 'bin' is set also set some other options */
2799 else if ((int *)varp == &curbuf->b_p_bin)
2800 {
2801 set_options_bin(old_value, curbuf->b_p_bin, opt_flags);
2802#ifdef FEAT_TITLE
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002803 redraw_titles();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002804#endif
2805 }
2806
Bram Moolenaar071d4272004-06-13 20:20:40 +00002807 /* when 'buflisted' changes, trigger autocommands */
2808 else if ((int *)varp == &curbuf->b_p_bl && old_value != curbuf->b_p_bl)
2809 {
2810 apply_autocmds(curbuf->b_p_bl ? EVENT_BUFADD : EVENT_BUFDELETE,
2811 NULL, NULL, TRUE, curbuf);
2812 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002813
2814 /* when 'swf' is set, create swapfile, when reset remove swapfile */
2815 else if ((int *)varp == &curbuf->b_p_swf)
2816 {
2817 if (curbuf->b_p_swf && p_uc)
2818 ml_open_file(curbuf); /* create the swap file */
2819 else
Bram Moolenaard55de222007-05-06 13:38:48 +00002820 /* no need to reset curbuf->b_may_swap, ml_open_file() will check
2821 * buf->b_p_swf */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002822 mf_close_file(curbuf, TRUE); /* remove the swap file */
2823 }
2824
2825 /* when 'terse' is set change 'shortmess' */
2826 else if ((int *)varp == &p_terse)
2827 {
2828 char_u *p;
2829
2830 p = vim_strchr(p_shm, SHM_SEARCH);
2831
2832 /* insert 's' in p_shm */
2833 if (p_terse && p == NULL)
2834 {
2835 STRCPY(IObuff, p_shm);
2836 STRCAT(IObuff, "s");
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002837 set_string_option_direct((char_u *)"shm", -1, IObuff, OPT_FREE, 0);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002838 }
2839 /* remove 's' from p_shm */
2840 else if (!p_terse && p != NULL)
Bram Moolenaarc1a11ed2008-06-24 22:09:24 +00002841 STRMOVE(p, p + 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002842 }
2843
2844 /* when 'paste' is set or reset also change other options */
2845 else if ((int *)varp == &p_paste)
2846 {
2847 paste_option_changed();
2848 }
2849
2850 /* when 'insertmode' is set from an autocommand need to do work here */
2851 else if ((int *)varp == &p_im)
2852 {
2853 if (p_im)
2854 {
2855 if ((State & INSERT) == 0)
2856 need_start_insertmode = TRUE;
2857 stop_insert_mode = FALSE;
2858 }
Bram Moolenaar00672e12016-06-26 18:38:13 +02002859 /* only reset if it was set previously */
2860 else if (old_value)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002861 {
2862 need_start_insertmode = FALSE;
2863 stop_insert_mode = TRUE;
Bram Moolenaard12f5c12006-01-25 22:10:52 +00002864 if (restart_edit != 0 && mode_displayed)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002865 clear_cmdline = TRUE; /* remove "(insert)" */
2866 restart_edit = 0;
2867 }
2868 }
2869
2870 /* when 'ignorecase' is set or reset and 'hlsearch' is set, redraw */
2871 else if ((int *)varp == &p_ic && p_hls)
2872 {
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00002873 redraw_all_later(SOME_VALID);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002874 }
2875
2876#ifdef FEAT_SEARCH_EXTRA
2877 /* when 'hlsearch' is set or reset: reset no_hlsearch */
2878 else if ((int *)varp == &p_hls)
2879 {
Bram Moolenaar451fc7b2018-04-27 22:53:07 +02002880 set_no_hlsearch(FALSE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002881 }
2882#endif
2883
Bram Moolenaar071d4272004-06-13 20:20:40 +00002884 /* when 'scrollbind' is set: snapshot the current position to avoid a jump
2885 * at the end of normal_cmd() */
2886 else if ((int *)varp == &curwin->w_p_scb)
2887 {
2888 if (curwin->w_p_scb)
Bram Moolenaar04c5c9e2013-07-09 13:44:59 +02002889 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00002890 do_check_scrollbind(FALSE);
Bram Moolenaar04c5c9e2013-07-09 13:44:59 +02002891 curwin->w_scbind_pos = curwin->w_topline;
2892 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002893 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002894
Bram Moolenaar4033c552017-09-16 20:54:51 +02002895#if defined(FEAT_QUICKFIX)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002896 /* There can be only one window with 'previewwindow' set. */
2897 else if ((int *)varp == &curwin->w_p_pvw)
2898 {
2899 if (curwin->w_p_pvw)
2900 {
2901 win_T *win;
2902
Bram Moolenaar29323592016-07-24 22:04:11 +02002903 FOR_ALL_WINDOWS(win)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002904 if (win->w_p_pvw && win != curwin)
2905 {
2906 curwin->w_p_pvw = FALSE;
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002907 return N_("E590: A preview window already exists");
Bram Moolenaar071d4272004-06-13 20:20:40 +00002908 }
2909 }
2910 }
2911#endif
2912
2913 /* when 'textmode' is set or reset also change 'fileformat' */
2914 else if ((int *)varp == &curbuf->b_p_tx)
2915 {
2916 set_fileformat(curbuf->b_p_tx ? EOL_DOS : EOL_UNIX, opt_flags);
2917 }
2918
2919 /* when 'textauto' is set or reset also change 'fileformats' */
2920 else if ((int *)varp == &p_ta)
Bram Moolenaarabab0b02019-03-30 18:47:01 +01002921 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00002922 set_string_option_direct((char_u *)"ffs", -1,
2923 p_ta ? (char_u *)DFLT_FFS_VIM : (char_u *)"",
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00002924 OPT_FREE | opt_flags, 0);
Bram Moolenaarabab0b02019-03-30 18:47:01 +01002925 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002926
2927 /*
2928 * When 'lisp' option changes include/exclude '-' in
2929 * keyword characters.
2930 */
2931#ifdef FEAT_LISP
2932 else if (varp == (char_u *)&(curbuf->b_p_lisp))
2933 {
2934 (void)buf_init_chartab(curbuf, FALSE); /* ignore errors */
2935 }
2936#endif
2937
2938#ifdef FEAT_TITLE
2939 /* when 'title' changed, may need to change the title; same for 'icon' */
Bram Moolenaar84a93082018-06-16 22:58:15 +02002940 else if ((int *)varp == &p_title || (int *)varp == &p_icon)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002941 {
Bram Moolenaar84a93082018-06-16 22:58:15 +02002942 did_set_title();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002943 }
2944#endif
2945
2946 else if ((int *)varp == &curbuf->b_changed)
2947 {
2948 if (!value)
2949 save_file_ff(curbuf); /* Buffer is unchanged */
2950#ifdef FEAT_TITLE
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00002951 redraw_titles();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002952#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00002953 modified_was_set = value;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002954 }
2955
2956#ifdef BACKSLASH_IN_FILENAME
2957 else if ((int *)varp == &p_ssl)
2958 {
2959 if (p_ssl)
2960 {
2961 psepc = '/';
2962 psepcN = '\\';
2963 pseps[0] = '/';
Bram Moolenaar071d4272004-06-13 20:20:40 +00002964 }
2965 else
2966 {
2967 psepc = '\\';
2968 psepcN = '/';
2969 pseps[0] = '\\';
Bram Moolenaar071d4272004-06-13 20:20:40 +00002970 }
2971
2972 /* need to adjust the file name arguments and buffer names. */
2973 buflist_slash_adjust();
2974 alist_slash_adjust();
2975# ifdef FEAT_EVAL
2976 scriptnames_slash_adjust();
2977# endif
2978 }
2979#endif
2980
2981 /* If 'wrap' is set, set w_leftcol to zero. */
2982 else if ((int *)varp == &curwin->w_p_wrap)
2983 {
2984 if (curwin->w_p_wrap)
2985 curwin->w_leftcol = 0;
2986 }
2987
Bram Moolenaar071d4272004-06-13 20:20:40 +00002988 else if ((int *)varp == &p_ea)
2989 {
2990 if (p_ea && !old_value)
2991 win_equal(curwin, FALSE, 0);
2992 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002993
2994 else if ((int *)varp == &p_wiv)
2995 {
2996 /*
2997 * When 'weirdinvert' changed, set/reset 't_xs'.
2998 * Then set 'weirdinvert' according to value of 't_xs'.
2999 */
3000 if (p_wiv && !old_value)
3001 T_XS = (char_u *)"y";
3002 else if (!p_wiv && old_value)
3003 T_XS = empty_option;
3004 p_wiv = (*T_XS != NUL);
3005 }
3006
Bram Moolenaarc3719bd2017-11-18 22:13:31 +01003007#ifdef FEAT_BEVAL_GUI
Bram Moolenaar071d4272004-06-13 20:20:40 +00003008 else if ((int *)varp == &p_beval)
3009 {
Bram Moolenaar51b0f372017-11-18 18:52:04 +01003010 if (!balloonEvalForTerm)
3011 {
3012 if (p_beval && !old_value)
3013 gui_mch_enable_beval_area(balloonEval);
3014 else if (!p_beval && old_value)
3015 gui_mch_disable_beval_area(balloonEval);
3016 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003017 }
Bram Moolenaar8dff8182006-04-06 20:18:50 +00003018#endif
Bram Moolenaarc3719bd2017-11-18 22:13:31 +01003019#ifdef FEAT_BEVAL_TERM
Bram Moolenaar51b0f372017-11-18 18:52:04 +01003020 else if ((int *)varp == &p_bevalterm)
3021 {
3022 mch_bevalterm_changed();
3023 }
Bram Moolenaarc3719bd2017-11-18 22:13:31 +01003024#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003025
Bram Moolenaar8dff8182006-04-06 20:18:50 +00003026#ifdef FEAT_AUTOCHDIR
Bram Moolenaar071d4272004-06-13 20:20:40 +00003027 else if ((int *)varp == &p_acd)
3028 {
Bram Moolenaar498efdb2006-09-05 14:31:54 +00003029 /* Change directories when the 'acd' option is set now. */
Bram Moolenaar6f470022018-04-10 18:47:20 +02003030 DO_AUTOCHDIR;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003031 }
3032#endif
3033
3034#ifdef FEAT_DIFF
3035 /* 'diff' */
3036 else if ((int *)varp == &curwin->w_p_diff)
3037 {
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00003038 /* May add or remove the buffer from the list of diff buffers. */
3039 diff_buf_adjust(curwin);
3040# ifdef FEAT_FOLDING
Bram Moolenaar071d4272004-06-13 20:20:40 +00003041 if (foldmethodIsDiff(curwin))
3042 foldUpdateAll(curwin);
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00003043# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003044 }
3045#endif
3046
Bram Moolenaarf2bd8ef2018-03-04 18:08:14 +01003047#ifdef HAVE_INPUT_METHOD
Bram Moolenaar071d4272004-06-13 20:20:40 +00003048 /* 'imdisable' */
3049 else if ((int *)varp == &p_imdisable)
3050 {
3051 /* Only de-activate it here, it will be enabled when changing mode. */
3052 if (p_imdisable)
3053 im_set_active(FALSE);
Bram Moolenaar725a9622011-10-12 16:57:13 +02003054 else if (State & INSERT)
3055 /* When the option is set from an autocommand, it may need to take
3056 * effect right away. */
3057 im_set_active(curbuf->b_p_iminsert == B_IMODE_IM);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003058 }
3059#endif
3060
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00003061#ifdef FEAT_SPELL
Bram Moolenaar0cb032e2005-04-23 20:52:00 +00003062 /* 'spell' */
3063 else if ((int *)varp == &curwin->w_p_spell)
3064 {
3065 if (curwin->w_p_spell)
3066 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003067 char *errmsg = did_set_spelllang(curwin);
3068
Bram Moolenaar0cb032e2005-04-23 20:52:00 +00003069 if (errmsg != NULL)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003070 emsg(_(errmsg));
Bram Moolenaar0cb032e2005-04-23 20:52:00 +00003071 }
3072 }
3073#endif
3074
Bram Moolenaar071d4272004-06-13 20:20:40 +00003075#ifdef FEAT_ARABIC
3076 if ((int *)varp == &curwin->w_p_arab)
3077 {
3078 if (curwin->w_p_arab)
3079 {
3080 /*
3081 * 'arabic' is set, handle various sub-settings.
3082 */
3083 if (!p_tbidi)
3084 {
3085 /* set rightleft mode */
3086 if (!curwin->w_p_rl)
3087 {
3088 curwin->w_p_rl = TRUE;
3089 changed_window_setting();
3090 }
3091
3092 /* Enable Arabic shaping (major part of what Arabic requires) */
3093 if (!p_arshape)
3094 {
3095 p_arshape = TRUE;
3096 redraw_later_clear();
3097 }
3098 }
3099
3100 /* Arabic requires a utf-8 encoding, inform the user if its not
3101 * set. */
3102 if (STRCMP(p_enc, "utf-8") != 0)
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00003103 {
Bram Moolenaar496c5262009-03-18 14:42:00 +00003104 static char *w_arabic = N_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'");
3105
Bram Moolenaar8820b482017-03-16 17:23:31 +01003106 msg_source(HL_ATTR(HLF_W));
Bram Moolenaar32526b32019-01-19 17:43:09 +01003107 msg_attr(_(w_arabic), HL_ATTR(HLF_W));
Bram Moolenaar496c5262009-03-18 14:42:00 +00003108#ifdef FEAT_EVAL
3109 set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_arabic), -1);
3110#endif
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00003111 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003112
Bram Moolenaar071d4272004-06-13 20:20:40 +00003113 /* set 'delcombine' */
3114 p_deco = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003115
3116# ifdef FEAT_KEYMAP
3117 /* Force-set the necessary keymap for arabic */
3118 set_option_value((char_u *)"keymap", 0L, (char_u *)"arabic",
3119 OPT_LOCAL);
3120# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003121 }
3122 else
3123 {
3124 /*
3125 * 'arabic' is reset, handle various sub-settings.
3126 */
3127 if (!p_tbidi)
3128 {
3129 /* reset rightleft mode */
3130 if (curwin->w_p_rl)
3131 {
3132 curwin->w_p_rl = FALSE;
3133 changed_window_setting();
3134 }
3135
3136 /* 'arabicshape' isn't reset, it is a global option and
3137 * another window may still need it "on". */
3138 }
3139
3140 /* 'delcombine' isn't reset, it is a global option and another
3141 * window may still want it "on". */
3142
3143# ifdef FEAT_KEYMAP
3144 /* Revert to the default keymap */
3145 curbuf->b_p_iminsert = B_IMODE_NONE;
3146 curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
3147# endif
3148 }
Bram Moolenaar801f8b82009-07-29 13:42:05 +00003149 }
3150
Bram Moolenaar319bdbd2009-09-11 13:20:33 +00003151#endif
3152
Bram Moolenaar44826212019-08-22 21:23:20 +02003153#if defined(FEAT_SIGNS) && defined(FEAT_GUI)
3154 else if (((int *)varp == &curwin->w_p_nu
3155 || (int *)varp == &curwin->w_p_rnu)
3156 && gui.in_use
3157 && (*curwin->w_p_scl == 'n' && *(curwin->w_p_scl + 1) == 'u')
3158 && curbuf->b_signlist != NULL)
3159 {
3160 // If the 'number' or 'relativenumber' options are modified and
3161 // 'signcolumn' is set to 'number', then clear the screen for a full
3162 // refresh. Otherwise the sign icons are not displayed properly in the
3163 // number column. If the 'number' option is set and only the
3164 // 'relativenumber' option is toggled, then don't refresh the screen
3165 // (optimization).
3166 if (!(curwin->w_p_nu && ((int *)varp == &curwin->w_p_rnu)))
3167 redraw_all_later(CLEAR);
3168 }
3169#endif
3170
Bram Moolenaar61be73b2016-04-29 22:59:22 +02003171#ifdef FEAT_TERMGUICOLORS
3172 /* 'termguicolors' */
3173 else if ((int *)varp == &p_tgc)
Bram Moolenaar8a633e32016-04-21 21:10:14 +02003174 {
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003175# ifdef FEAT_VTP
3176 /* Do not turn on 'tgc' when 24-bit colors are not supported. */
Bram Moolenaarafde13b2019-04-28 19:46:49 +02003177 if (
3178# ifdef VIMDLL
3179 !gui.in_use && !gui.starting &&
3180# endif
3181 !has_vtp_working())
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003182 {
3183 p_tgc = 0;
Bram Moolenaaraa5df7e2019-02-03 14:53:10 +01003184 return N_("E954: 24-bit colors are not supported on this environment");
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003185 }
Bram Moolenaarc5cd8852018-05-01 15:47:38 +02003186 if (is_term_win32())
3187 swap_tcap();
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003188# endif
Bram Moolenaar8a633e32016-04-21 21:10:14 +02003189# ifdef FEAT_GUI
3190 if (!gui.in_use && !gui.starting)
3191# endif
3192 highlight_gui_started();
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003193# ifdef FEAT_VTP
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003194 /* reset t_Co */
Bram Moolenaarc5cd8852018-05-01 15:47:38 +02003195 if (is_term_win32())
Bram Moolenaarb0eb14f2018-06-28 15:29:52 +02003196 {
3197 control_console_color_rgb();
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003198 set_termname(T_NAME);
Bram Moolenaarb0eb14f2018-06-28 15:29:52 +02003199 init_highlight(TRUE, FALSE);
3200 }
Bram Moolenaarcafafb32018-02-22 21:07:09 +01003201# endif
Bram Moolenaar8a633e32016-04-21 21:10:14 +02003202 }
3203#endif
3204
Bram Moolenaar071d4272004-06-13 20:20:40 +00003205 /*
3206 * End of handling side effects for bool options.
3207 */
3208
Bram Moolenaar53744302015-07-17 17:38:22 +02003209 /* after handling side effects, call autocommand */
3210
Bram Moolenaar071d4272004-06-13 20:20:40 +00003211 options[opt_idx].flags |= P_WAS_SET;
3212
Bram Moolenaarf2bd8ef2018-03-04 18:08:14 +01003213#if defined(FEAT_EVAL)
Bram Moolenaar3f3fb0b2018-09-21 11:59:32 +02003214 // Don't do this while starting up or recursively.
3215 if (!starting && *get_vim_var_str(VV_OPTION_TYPE) == NUL)
Bram Moolenaar53744302015-07-17 17:38:22 +02003216 {
Bram Moolenaard7c96872019-06-15 17:12:48 +02003217 char_u buf_old[2], buf_old_global[2], buf_new[2], buf_type[7];
Bram Moolenaar3f3fb0b2018-09-21 11:59:32 +02003218
Bram Moolenaarfb9bc482015-07-17 22:04:48 +02003219 vim_snprintf((char *)buf_old, 2, "%d", old_value ? TRUE: FALSE);
Bram Moolenaard7c96872019-06-15 17:12:48 +02003220 vim_snprintf((char *)buf_old_global, 2, "%d",
3221 old_global_value ? TRUE: FALSE);
Bram Moolenaarfb9bc482015-07-17 22:04:48 +02003222 vim_snprintf((char *)buf_new, 2, "%d", value ? TRUE: FALSE);
Bram Moolenaard7c96872019-06-15 17:12:48 +02003223 vim_snprintf((char *)buf_type, 7, "%s",
3224 (opt_flags & OPT_LOCAL) ? "local" : "global");
Bram Moolenaar53744302015-07-17 17:38:22 +02003225 set_vim_var_string(VV_OPTION_NEW, buf_new, -1);
3226 set_vim_var_string(VV_OPTION_OLD, buf_old, -1);
3227 set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
Bram Moolenaard7c96872019-06-15 17:12:48 +02003228 if (opt_flags & OPT_LOCAL)
3229 {
3230 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setlocal", -1);
3231 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
3232 }
3233 if (opt_flags & OPT_GLOBAL)
3234 {
3235 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setglobal", -1);
3236 set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old, -1);
3237 }
3238 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
3239 {
3240 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"set", -1);
3241 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
3242 set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old_global, -1);
3243 }
3244 if (opt_flags & OPT_MODELINE)
3245 {
3246 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"modeline", -1);
3247 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
3248 }
3249 apply_autocmds(EVENT_OPTIONSET, (char_u *)options[opt_idx].fullname,
3250 NULL, FALSE, NULL);
Bram Moolenaar53744302015-07-17 17:38:22 +02003251 reset_v_option_vars();
3252 }
3253#endif
3254
Bram Moolenaar071d4272004-06-13 20:20:40 +00003255 comp_col(); /* in case 'ruler' or 'showcmd' changed */
Bram Moolenaar913077c2012-03-28 19:59:04 +02003256 if (curwin->w_curswant != MAXCOL
Bram Moolenaar488eb262015-03-13 11:23:50 +01003257 && (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0)
Bram Moolenaar913077c2012-03-28 19:59:04 +02003258 curwin->w_set_curswant = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003259 check_redraw(options[opt_idx].flags);
3260
3261 return NULL;
3262}
3263
3264/*
3265 * Set the value of a number option, and take care of side effects.
3266 * Returns NULL for success, or an error message for an error.
3267 */
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003268 static char *
Bram Moolenaar9b578142016-01-30 19:39:49 +01003269set_num_option(
3270 int opt_idx, /* index in options[] table */
3271 char_u *varp, /* pointer to the option variable */
3272 long value, /* new value */
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003273 char *errbuf, /* buffer for error messages */
Bram Moolenaar9b578142016-01-30 19:39:49 +01003274 size_t errbuflen, /* length of "errbuf" */
3275 int opt_flags) /* OPT_LOCAL, OPT_GLOBAL and
Bram Moolenaar071d4272004-06-13 20:20:40 +00003276 OPT_MODELINE */
3277{
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01003278 char *errmsg = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003279 long old_value = *(long *)varp;
Bram Moolenaar983f2f12019-06-16 16:41:41 +02003280#if defined(FEAT_EVAL)
Bram Moolenaard7c96872019-06-15 17:12:48 +02003281 long old_global_value = 0; // only used when setting a local and
3282 // global option
Bram Moolenaar983f2f12019-06-16 16:41:41 +02003283#endif
Bram Moolenaard7c96872019-06-15 17:12:48 +02003284 long old_Rows = Rows; // remember old Rows
3285 long old_Columns = Columns; // remember old Columns
Bram Moolenaar071d4272004-06-13 20:20:40 +00003286 long *pp = (long *)varp;
3287
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00003288 /* Disallow changing some options from secure mode. */
3289 if ((secure
3290#ifdef HAVE_SANDBOX
3291 || sandbox != 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00003292#endif
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00003293 ) && (options[opt_idx].flags & P_SECURE))
3294 return e_secure;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003295
Bram Moolenaar983f2f12019-06-16 16:41:41 +02003296#if defined(FEAT_EVAL)
Bram Moolenaard7c96872019-06-15 17:12:48 +02003297 // Save the global value before changing anything. This is needed as for
3298 // a global-only option setting the "local value" infact sets the global
3299 // value (since there is only one value).
3300 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
Bram Moolenaar983f2f12019-06-16 16:41:41 +02003301 old_global_value = *(long *)get_varp_scope(&(options[opt_idx]),
3302 OPT_GLOBAL);
3303#endif
Bram Moolenaard7c96872019-06-15 17:12:48 +02003304
Bram Moolenaar071d4272004-06-13 20:20:40 +00003305 *pp = value;
3306#ifdef FEAT_EVAL
3307 /* Remember where the option was set. */
Bram Moolenaarf29c1c62018-09-10 21:05:02 +02003308 set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003309#endif
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00003310#ifdef FEAT_GUI
3311 need_mouse_correct = TRUE;
3312#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003313
Bram Moolenaar14f24742012-08-08 18:01:05 +02003314 if (curbuf->b_p_sw < 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003315 {
3316 errmsg = e_positive;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02003317#ifdef FEAT_VARTABS
3318 // Use the first 'vartabstop' value, or 'tabstop' if vts isn't in use.
3319 curbuf->b_p_sw = tabstop_count(curbuf->b_p_vts_array) > 0
3320 ? tabstop_first(curbuf->b_p_vts_array)
3321 : curbuf->b_p_ts;
3322#else
Bram Moolenaar071d4272004-06-13 20:20:40 +00003323 curbuf->b_p_sw = curbuf->b_p_ts;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02003324#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003325 }
3326
3327 /*
3328 * Number options that need some action when changed
3329 */
Bram Moolenaar071d4272004-06-13 20:20:40 +00003330 if (pp == &p_wh || pp == &p_hh)
3331 {
Bram Moolenaar1c3c1042018-06-12 16:49:30 +02003332 // 'winheight' and 'helpheight'
Bram Moolenaar071d4272004-06-13 20:20:40 +00003333 if (p_wh < 1)
3334 {
3335 errmsg = e_positive;
3336 p_wh = 1;
3337 }
3338 if (p_wmh > p_wh)
3339 {
3340 errmsg = e_winheight;
3341 p_wh = p_wmh;
3342 }
3343 if (p_hh < 0)
3344 {
3345 errmsg = e_positive;
3346 p_hh = 0;
3347 }
3348
3349 /* Change window height NOW */
Bram Moolenaar459ca562016-11-10 18:16:33 +01003350 if (!ONE_WINDOW)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003351 {
3352 if (pp == &p_wh && curwin->w_height < p_wh)
3353 win_setheight((int)p_wh);
3354 if (pp == &p_hh && curbuf->b_help && curwin->w_height < p_hh)
3355 win_setheight((int)p_hh);
3356 }
3357 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003358 else if (pp == &p_wmh)
3359 {
Bram Moolenaar1c3c1042018-06-12 16:49:30 +02003360 // 'winminheight'
Bram Moolenaar071d4272004-06-13 20:20:40 +00003361 if (p_wmh < 0)
3362 {
3363 errmsg = e_positive;
3364 p_wmh = 0;
3365 }
3366 if (p_wmh > p_wh)
3367 {
3368 errmsg = e_winheight;
3369 p_wmh = p_wh;
3370 }
3371 win_setminheight();
3372 }
Bram Moolenaar592e0a22004-07-03 16:05:59 +00003373 else if (pp == &p_wiw)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003374 {
Bram Moolenaar1c3c1042018-06-12 16:49:30 +02003375 // 'winwidth'
Bram Moolenaar071d4272004-06-13 20:20:40 +00003376 if (p_wiw < 1)
3377 {
3378 errmsg = e_positive;
3379 p_wiw = 1;
3380 }
3381 if (p_wmw > p_wiw)
3382 {
3383 errmsg = e_winwidth;
3384 p_wiw = p_wmw;
3385 }
3386
3387 /* Change window width NOW */
Bram Moolenaar459ca562016-11-10 18:16:33 +01003388 if (!ONE_WINDOW && curwin->w_width < p_wiw)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003389 win_setwidth((int)p_wiw);
3390 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003391 else if (pp == &p_wmw)
3392 {
Bram Moolenaar1c3c1042018-06-12 16:49:30 +02003393 // 'winminwidth'
Bram Moolenaar071d4272004-06-13 20:20:40 +00003394 if (p_wmw < 0)
3395 {
3396 errmsg = e_positive;
3397 p_wmw = 0;
3398 }
3399 if (p_wmw > p_wiw)
3400 {
3401 errmsg = e_winwidth;
3402 p_wmw = p_wiw;
3403 }
Bram Moolenaar1c3c1042018-06-12 16:49:30 +02003404 win_setminwidth();
Bram Moolenaar071d4272004-06-13 20:20:40 +00003405 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003406
Bram Moolenaar071d4272004-06-13 20:20:40 +00003407 /* (re)set last window status line */
3408 else if (pp == &p_ls)
3409 {
3410 last_status(FALSE);
3411 }
Bram Moolenaar4c7ed462006-02-15 22:18:42 +00003412
3413 /* (re)set tab page line */
Bram Moolenaarfaa959a2006-02-20 21:37:40 +00003414 else if (pp == &p_stal)
Bram Moolenaar4c7ed462006-02-15 22:18:42 +00003415 {
3416 shell_new_rows(); /* recompute window positions and heights */
3417 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003418
3419#ifdef FEAT_GUI
3420 else if (pp == &p_linespace)
3421 {
Bram Moolenaar02743632005-07-25 20:42:36 +00003422 /* Recompute gui.char_height and resize the Vim window to keep the
3423 * same number of lines. */
3424 if (gui.in_use && gui_mch_adjust_charheight() == OK)
Bram Moolenaar3964b7e2006-03-27 20:59:33 +00003425 gui_set_shellsize(FALSE, FALSE, RESIZE_VERT);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003426 }
3427#endif
3428
3429#ifdef FEAT_FOLDING
3430 /* 'foldlevel' */
3431 else if (pp == &curwin->w_p_fdl)
3432 {
3433 if (curwin->w_p_fdl < 0)
3434 curwin->w_p_fdl = 0;
3435 newFoldLevel();
3436 }
3437
Bram Moolenaar1f26d2f2009-02-11 10:35:36 +00003438 /* 'foldminlines' */
Bram Moolenaar071d4272004-06-13 20:20:40 +00003439 else if (pp == &curwin->w_p_fml)
3440 {
3441 foldUpdateAll(curwin);
3442 }
3443
3444 /* 'foldnestmax' */
3445 else if (pp == &curwin->w_p_fdn)
3446 {
3447 if (foldmethodIsSyntax(curwin) || foldmethodIsIndent(curwin))
3448 foldUpdateAll(curwin);
3449 }
3450
3451 /* 'foldcolumn' */
3452 else if (pp == &curwin->w_p_fdc)
3453 {
3454 if (curwin->w_p_fdc < 0)
3455 {
3456 errmsg = e_positive;
3457 curwin->w_p_fdc = 0;
3458 }
3459 else if (curwin->w_p_fdc > 12)
3460 {
3461 errmsg = e_invarg;
3462 curwin->w_p_fdc = 12;
3463 }
3464 }
Bram Moolenaar6bcbcc52013-11-05 07:13:41 +01003465#endif /* FEAT_FOLDING */
Bram Moolenaar071d4272004-06-13 20:20:40 +00003466
Bram Moolenaar6bcbcc52013-11-05 07:13:41 +01003467#if defined(FEAT_FOLDING) || defined(FEAT_CINDENT)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003468 /* 'shiftwidth' or 'tabstop' */
3469 else if (pp == &curbuf->b_p_sw || pp == &curbuf->b_p_ts)
3470 {
Bram Moolenaar6bcbcc52013-11-05 07:13:41 +01003471# ifdef FEAT_FOLDING
Bram Moolenaar071d4272004-06-13 20:20:40 +00003472 if (foldmethodIsIndent(curwin))
3473 foldUpdateAll(curwin);
Bram Moolenaar6bcbcc52013-11-05 07:13:41 +01003474# endif
3475# ifdef FEAT_CINDENT
3476 /* When 'shiftwidth' changes, or it's zero and 'tabstop' changes:
3477 * parse 'cinoptions'. */
3478 if (pp == &curbuf->b_p_sw || curbuf->b_p_sw == 0)
3479 parse_cino(curbuf);
3480# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003481 }
Bram Moolenaar6bcbcc52013-11-05 07:13:41 +01003482#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003483
Bram Moolenaar362e1a32006-03-06 23:29:24 +00003484 /* 'maxcombine' */
3485 else if (pp == &p_mco)
3486 {
3487 if (p_mco > MAX_MCO)
3488 p_mco = MAX_MCO;
3489 else if (p_mco < 0)
3490 p_mco = 0;
3491 screenclear(); /* will re-allocate the screen */
3492 }
Bram Moolenaar362e1a32006-03-06 23:29:24 +00003493
Bram Moolenaar071d4272004-06-13 20:20:40 +00003494 else if (pp == &curbuf->b_p_iminsert)
3495 {
3496 if (curbuf->b_p_iminsert < 0 || curbuf->b_p_iminsert > B_IMODE_LAST)
3497 {
3498 errmsg = e_invarg;
3499 curbuf->b_p_iminsert = B_IMODE_NONE;
3500 }
3501 p_iminsert = curbuf->b_p_iminsert;
3502 if (termcap_active) /* don't do this in the alternate screen */
3503 showmode();
Bram Moolenaar4033c552017-09-16 20:54:51 +02003504#if defined(FEAT_KEYMAP)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003505 /* Show/unshow value of 'keymap' in status lines. */
3506 status_redraw_curbuf();
3507#endif
3508 }
3509
Bram Moolenaar5c6dbcb2017-08-30 22:00:20 +02003510#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
3511 /* 'imstyle' */
3512 else if (pp == &p_imst)
3513 {
3514 if (p_imst != IM_ON_THE_SPOT && p_imst != IM_OVER_THE_SPOT)
3515 errmsg = e_invarg;
3516 }
3517#endif
3518
Bram Moolenaar4399ef42005-02-12 14:29:27 +00003519 else if (pp == &p_window)
3520 {
3521 if (p_window < 1)
3522 p_window = 1;
3523 else if (p_window >= Rows)
3524 p_window = Rows - 1;
3525 }
3526
Bram Moolenaar071d4272004-06-13 20:20:40 +00003527 else if (pp == &curbuf->b_p_imsearch)
3528 {
3529 if (curbuf->b_p_imsearch < -1 || curbuf->b_p_imsearch > B_IMODE_LAST)
3530 {
3531 errmsg = e_invarg;
3532 curbuf->b_p_imsearch = B_IMODE_NONE;
3533 }
3534 p_imsearch = curbuf->b_p_imsearch;
3535 }
3536
3537#ifdef FEAT_TITLE
3538 /* if 'titlelen' has changed, redraw the title */
3539 else if (pp == &p_titlelen)
3540 {
3541 if (p_titlelen < 0)
3542 {
3543 errmsg = e_positive;
3544 p_titlelen = 85;
3545 }
3546 if (starting != NO_SCREEN && old_value != p_titlelen)
3547 need_maketitle = TRUE;
3548 }
3549#endif
3550
3551 /* if p_ch changed value, change the command line height */
3552 else if (pp == &p_ch)
3553 {
3554 if (p_ch < 1)
3555 {
3556 errmsg = e_positive;
3557 p_ch = 1;
3558 }
Bram Moolenaar719939c2007-09-25 12:51:28 +00003559 if (p_ch > Rows - min_rows() + 1)
3560 p_ch = Rows - min_rows() + 1;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003561
3562 /* Only compute the new window layout when startup has been
3563 * completed. Otherwise the frame sizes may be wrong. */
3564 if (p_ch != old_value && full_screen
3565#ifdef FEAT_GUI
3566 && !gui.starting
3567#endif
3568 )
Bram Moolenaarc6fe9192006-04-09 21:54:49 +00003569 command_height();
Bram Moolenaar071d4272004-06-13 20:20:40 +00003570 }
3571
3572 /* when 'updatecount' changes from zero to non-zero, open swap files */
3573 else if (pp == &p_uc)
3574 {
3575 if (p_uc < 0)
3576 {
3577 errmsg = e_positive;
3578 p_uc = 100;
3579 }
3580 if (p_uc && !old_value)
3581 ml_open_files();
3582 }
Bram Moolenaar860cae12010-06-05 23:22:07 +02003583#ifdef FEAT_CONCEAL
Bram Moolenaarf5963f72010-07-23 22:10:27 +02003584 else if (pp == &curwin->w_p_cole)
Bram Moolenaar860cae12010-06-05 23:22:07 +02003585 {
Bram Moolenaarf5963f72010-07-23 22:10:27 +02003586 if (curwin->w_p_cole < 0)
Bram Moolenaar860cae12010-06-05 23:22:07 +02003587 {
3588 errmsg = e_positive;
Bram Moolenaarf5963f72010-07-23 22:10:27 +02003589 curwin->w_p_cole = 0;
Bram Moolenaar860cae12010-06-05 23:22:07 +02003590 }
Bram Moolenaarf5963f72010-07-23 22:10:27 +02003591 else if (curwin->w_p_cole > 3)
Bram Moolenaar860cae12010-06-05 23:22:07 +02003592 {
3593 errmsg = e_invarg;
Bram Moolenaarf5963f72010-07-23 22:10:27 +02003594 curwin->w_p_cole = 3;
Bram Moolenaar860cae12010-06-05 23:22:07 +02003595 }
3596 }
3597#endif
Bram Moolenaar2df6dcc2004-07-12 15:53:54 +00003598#ifdef MZSCHEME_GUI_THREADS
Bram Moolenaar325b7a22004-07-05 15:58:32 +00003599 else if (pp == &p_mzq)
3600 mzvim_reset_timer();
3601#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00003602
Bram Moolenaarf42dd3c2017-01-28 16:06:38 +01003603#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
3604 /* 'pyxversion' */
3605 else if (pp == &p_pyx)
3606 {
3607 if (p_pyx != 0 && p_pyx != 2 && p_pyx != 3)
3608 errmsg = e_invarg;
3609 }
3610#endif
3611
Bram Moolenaar071d4272004-06-13 20:20:40 +00003612 /* sync undo before 'undolevels' changes */
3613 else if (pp == &p_ul)
3614 {
3615 /* use the old value, otherwise u_sync() may not work properly */
3616 p_ul = old_value;
Bram Moolenaar779b74b2006-04-10 14:55:34 +00003617 u_sync(TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003618 p_ul = value;
3619 }
Bram Moolenaarf5a2fd82013-11-06 05:26:15 +01003620 else if (pp == &curbuf->b_p_ul)
3621 {
3622 /* use the old value, otherwise u_sync() may not work properly */
3623 curbuf->b_p_ul = old_value;
3624 u_sync(TRUE);
3625 curbuf->b_p_ul = value;
3626 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003627
Bram Moolenaar592e0a22004-07-03 16:05:59 +00003628#ifdef FEAT_LINEBREAK
3629 /* 'numberwidth' must be positive */
3630 else if (pp == &curwin->w_p_nuw)
3631 {
3632 if (curwin->w_p_nuw < 1)
3633 {
3634 errmsg = e_positive;
3635 curwin->w_p_nuw = 1;
3636 }
Bram Moolenaarf8a07122019-07-01 22:06:07 +02003637 if (curwin->w_p_nuw > 20)
Bram Moolenaar592e0a22004-07-03 16:05:59 +00003638 {
3639 errmsg = e_invarg;
Bram Moolenaarf8a07122019-07-01 22:06:07 +02003640 curwin->w_p_nuw = 20;
Bram Moolenaar592e0a22004-07-03 16:05:59 +00003641 }
Bram Moolenaar1e7813a2015-03-31 18:31:03 +02003642 curwin->w_nrwidth_line_count = 0; /* trigger a redraw */
Bram Moolenaar592e0a22004-07-03 16:05:59 +00003643 }
3644#endif
3645
Bram Moolenaar1a384422010-07-14 19:53:30 +02003646 else if (pp == &curbuf->b_p_tw)
3647 {
3648 if (curbuf->b_p_tw < 0)
3649 {
3650 errmsg = e_positive;
3651 curbuf->b_p_tw = 0;
3652 }
3653#ifdef FEAT_SYN_HL
Bram Moolenaar1a384422010-07-14 19:53:30 +02003654 {
3655 win_T *wp;
3656 tabpage_T *tp;
3657
3658 FOR_ALL_TAB_WINDOWS(tp, wp)
3659 check_colorcolumn(wp);
3660 }
Bram Moolenaar1a384422010-07-14 19:53:30 +02003661#endif
3662 }
3663
Bram Moolenaar071d4272004-06-13 20:20:40 +00003664 /*
3665 * Check the bounds for numeric options here
3666 */
3667 if (Rows < min_rows() && full_screen)
3668 {
3669 if (errbuf != NULL)
3670 {
Bram Moolenaar555b2802005-05-19 21:08:39 +00003671 vim_snprintf((char *)errbuf, errbuflen,
3672 _("E593: Need at least %d lines"), min_rows());
Bram Moolenaar071d4272004-06-13 20:20:40 +00003673 errmsg = errbuf;
3674 }
3675 Rows = min_rows();
3676 }
3677 if (Columns < MIN_COLUMNS && full_screen)
3678 {
3679 if (errbuf != NULL)
3680 {
Bram Moolenaar555b2802005-05-19 21:08:39 +00003681 vim_snprintf((char *)errbuf, errbuflen,
3682 _("E594: Need at least %d columns"), MIN_COLUMNS);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003683 errmsg = errbuf;
3684 }
3685 Columns = MIN_COLUMNS;
3686 }
Bram Moolenaare057d402013-06-30 17:51:51 +02003687 limit_screen_size();
Bram Moolenaar071d4272004-06-13 20:20:40 +00003688
Bram Moolenaar071d4272004-06-13 20:20:40 +00003689 /*
3690 * If the screen (shell) height has been changed, assume it is the
3691 * physical screenheight.
3692 */
3693 if (old_Rows != Rows || old_Columns != Columns)
3694 {
3695 /* Changing the screen size is not allowed while updating the screen. */
3696 if (updating_screen)
3697 *pp = old_value;
3698 else if (full_screen
3699#ifdef FEAT_GUI
3700 && !gui.starting
3701#endif
3702 )
3703 set_shellsize((int)Columns, (int)Rows, TRUE);
3704 else
3705 {
3706 /* Postpone the resizing; check the size and cmdline position for
3707 * messages. */
3708 check_shellsize();
3709 if (cmdline_row > Rows - p_ch && Rows > p_ch)
3710 cmdline_row = Rows - p_ch;
3711 }
Bram Moolenaard68071d2006-05-02 22:08:30 +00003712 if (p_window >= Rows || !option_was_set((char_u *)"window"))
Bram Moolenaar4399ef42005-02-12 14:29:27 +00003713 p_window = Rows - 1;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003714 }
3715
Bram Moolenaar071d4272004-06-13 20:20:40 +00003716 if (curbuf->b_p_ts <= 0)
3717 {
3718 errmsg = e_positive;
3719 curbuf->b_p_ts = 8;
3720 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003721 if (p_tm < 0)
3722 {
3723 errmsg = e_positive;
3724 p_tm = 0;
3725 }
3726 if ((curwin->w_p_scr <= 0
3727 || (curwin->w_p_scr > curwin->w_height
3728 && curwin->w_height > 0))
3729 && full_screen)
3730 {
3731 if (pp == &(curwin->w_p_scr))
3732 {
3733 if (curwin->w_p_scr != 0)
3734 errmsg = e_scroll;
3735 win_comp_scroll(curwin);
3736 }
3737 /* If 'scroll' became invalid because of a side effect silently adjust
3738 * it. */
3739 else if (curwin->w_p_scr <= 0)
3740 curwin->w_p_scr = 1;
3741 else /* curwin->w_p_scr > curwin->w_height */
3742 curwin->w_p_scr = curwin->w_height;
3743 }
Bram Moolenaar991e10f2008-10-02 20:48:41 +00003744 if (p_hi < 0)
3745 {
3746 errmsg = e_positive;
3747 p_hi = 0;
3748 }
Bram Moolenaar78159bb2014-06-25 11:48:54 +02003749 else if (p_hi > 10000)
3750 {
3751 errmsg = e_invarg;
3752 p_hi = 10000;
3753 }
Bram Moolenaarfbc0d2e2013-05-19 19:40:29 +02003754 if (p_re < 0 || p_re > 2)
3755 {
3756 errmsg = e_invarg;
3757 p_re = 0;
3758 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00003759 if (p_report < 0)
3760 {
3761 errmsg = e_positive;
3762 p_report = 1;
3763 }
Bram Moolenaar1e015462005-09-25 22:16:38 +00003764 if ((p_sj < -100 || p_sj >= Rows) && full_screen)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003765 {
3766 if (Rows != old_Rows) /* Rows changed, just adjust p_sj */
3767 p_sj = Rows / 2;
3768 else
3769 {
3770 errmsg = e_scroll;
3771 p_sj = 1;
3772 }
3773 }
3774 if (p_so < 0 && full_screen)
3775 {
Bram Moolenaar375e3392019-01-31 18:26:10 +01003776 errmsg = e_positive;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003777 p_so = 0;
3778 }
3779 if (p_siso < 0 && full_screen)
3780 {
3781 errmsg = e_positive;
3782 p_siso = 0;
3783 }
3784#ifdef FEAT_CMDWIN
3785 if (p_cwh < 1)
3786 {
3787 errmsg = e_positive;
3788 p_cwh = 1;
3789 }
3790#endif
3791 if (p_ut < 0)
3792 {
3793 errmsg = e_positive;
3794 p_ut = 2000;
3795 }
3796 if (p_ss < 0)
3797 {
3798 errmsg = e_positive;
3799 p_ss = 0;
3800 }
3801
3802 /* May set global value for local option. */
3803 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
3804 *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = *pp;
3805
3806 options[opt_idx].flags |= P_WAS_SET;
3807
Bram Moolenaarf2bd8ef2018-03-04 18:08:14 +01003808#if defined(FEAT_EVAL)
Bram Moolenaar3f3fb0b2018-09-21 11:59:32 +02003809 // Don't do this while starting up, failure or recursively.
3810 if (!starting && errmsg == NULL && *get_vim_var_str(VV_OPTION_TYPE) == NUL)
Bram Moolenaar53744302015-07-17 17:38:22 +02003811 {
Bram Moolenaard7c96872019-06-15 17:12:48 +02003812 char_u buf_old[11], buf_old_global[11], buf_new[11], buf_type[7];
Bram Moolenaarfb9bc482015-07-17 22:04:48 +02003813 vim_snprintf((char *)buf_old, 10, "%ld", old_value);
Bram Moolenaard7c96872019-06-15 17:12:48 +02003814 vim_snprintf((char *)buf_old_global, 10, "%ld", old_global_value);
Bram Moolenaarfb9bc482015-07-17 22:04:48 +02003815 vim_snprintf((char *)buf_new, 10, "%ld", value);
3816 vim_snprintf((char *)buf_type, 7, "%s", (opt_flags & OPT_LOCAL) ? "local" : "global");
Bram Moolenaar53744302015-07-17 17:38:22 +02003817 set_vim_var_string(VV_OPTION_NEW, buf_new, -1);
3818 set_vim_var_string(VV_OPTION_OLD, buf_old, -1);
3819 set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
Bram Moolenaard7c96872019-06-15 17:12:48 +02003820 if (opt_flags & OPT_LOCAL)
3821 {
3822 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setlocal", -1);
3823 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
3824 }
3825 if (opt_flags & OPT_GLOBAL)
3826 {
3827 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"setglobal", -1);
3828 set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old, -1);
3829 }
3830 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
3831 {
3832 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"set", -1);
3833 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
3834 set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old_global, -1);
3835 }
3836 if (opt_flags & OPT_MODELINE)
3837 {
3838 set_vim_var_string(VV_OPTION_COMMAND, (char_u *)"modeline", -1);
3839 set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
3840 }
3841 apply_autocmds(EVENT_OPTIONSET, (char_u *)options[opt_idx].fullname,
3842 NULL, FALSE, NULL);
Bram Moolenaar53744302015-07-17 17:38:22 +02003843 reset_v_option_vars();
3844 }
3845#endif
3846
Bram Moolenaar071d4272004-06-13 20:20:40 +00003847 comp_col(); /* in case 'columns' or 'ls' changed */
Bram Moolenaar913077c2012-03-28 19:59:04 +02003848 if (curwin->w_curswant != MAXCOL
Bram Moolenaar488eb262015-03-13 11:23:50 +01003849 && (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0)
Bram Moolenaar913077c2012-03-28 19:59:04 +02003850 curwin->w_set_curswant = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00003851 check_redraw(options[opt_idx].flags);
3852
3853 return errmsg;
3854}
3855
3856/*
3857 * Called after an option changed: check if something needs to be redrawn.
3858 */
Bram Moolenaardac13472019-09-16 21:06:21 +02003859 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01003860check_redraw(long_u flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003861{
3862 /* Careful: P_RCLR and P_RALL are a combination of other P_ flags */
Bram Moolenaar70b2a562012-01-10 22:26:17 +01003863 int doclear = (flags & P_RCLR) == P_RCLR;
3864 int all = ((flags & P_RALL) == P_RALL || doclear);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003865
Bram Moolenaar071d4272004-06-13 20:20:40 +00003866 if ((flags & P_RSTAT) || all) /* mark all status lines dirty */
3867 status_redraw_all();
Bram Moolenaar071d4272004-06-13 20:20:40 +00003868
3869 if ((flags & P_RBUF) || (flags & P_RWIN) || all)
3870 changed_window_setting();
3871 if (flags & P_RBUF)
3872 redraw_curbuf_later(NOT_VALID);
Bram Moolenaara2477fd2016-12-03 15:13:20 +01003873 if (flags & P_RWINONLY)
3874 redraw_later(NOT_VALID);
Bram Moolenaar70b2a562012-01-10 22:26:17 +01003875 if (doclear)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003876 redraw_all_later(CLEAR);
3877 else if (all)
3878 redraw_all_later(NOT_VALID);
3879}
3880
3881/*
3882 * Find index for option 'arg'.
3883 * Return -1 if not found.
3884 */
Bram Moolenaardac13472019-09-16 21:06:21 +02003885 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01003886findoption(char_u *arg)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003887{
3888 int opt_idx;
3889 char *s, *p;
3890 static short quick_tab[27] = {0, 0}; /* quick access table */
3891 int is_term_opt;
3892
3893 /*
3894 * For first call: Initialize the quick-access table.
3895 * It contains the index for the first option that starts with a certain
3896 * letter. There are 26 letters, plus the first "t_" option.
3897 */
3898 if (quick_tab[1] == 0)
3899 {
3900 p = options[0].fullname;
3901 for (opt_idx = 1; (s = options[opt_idx].fullname) != NULL; opt_idx++)
3902 {
3903 if (s[0] != p[0])
3904 {
3905 if (s[0] == 't' && s[1] == '_')
3906 quick_tab[26] = opt_idx;
3907 else
3908 quick_tab[CharOrdLow(s[0])] = opt_idx;
3909 }
3910 p = s;
3911 }
3912 }
3913
3914 /*
3915 * Check for name starting with an illegal character.
3916 */
3917#ifdef EBCDIC
3918 if (!islower(arg[0]))
3919#else
3920 if (arg[0] < 'a' || arg[0] > 'z')
3921#endif
3922 return -1;
3923
3924 is_term_opt = (arg[0] == 't' && arg[1] == '_');
3925 if (is_term_opt)
3926 opt_idx = quick_tab[26];
3927 else
3928 opt_idx = quick_tab[CharOrdLow(arg[0])];
3929 for ( ; (s = options[opt_idx].fullname) != NULL; opt_idx++)
3930 {
3931 if (STRCMP(arg, s) == 0) /* match full name */
3932 break;
3933 }
3934 if (s == NULL && !is_term_opt)
3935 {
3936 opt_idx = quick_tab[CharOrdLow(arg[0])];
3937 for ( ; options[opt_idx].fullname != NULL; opt_idx++)
3938 {
3939 s = options[opt_idx].shortname;
3940 if (s != NULL && STRCMP(arg, s) == 0) /* match short name */
3941 break;
3942 s = NULL;
3943 }
3944 }
3945 if (s == NULL)
3946 opt_idx = -1;
3947 return opt_idx;
3948}
3949
Bram Moolenaar325b7a22004-07-05 15:58:32 +00003950#if defined(FEAT_EVAL) || defined(FEAT_TCL) || defined(FEAT_MZSCHEME)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003951/*
3952 * Get the value for an option.
3953 *
3954 * Returns:
3955 * Number or Toggle option: 1, *numval gets value.
3956 * String option: 0, *stringval gets allocated string.
3957 * Hidden Number or Toggle option: -1.
3958 * hidden String option: -2.
3959 * unknown option: -3.
3960 */
3961 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01003962get_option_value(
3963 char_u *name,
3964 long *numval,
3965 char_u **stringval, /* NULL when only checking existence */
3966 int opt_flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003967{
3968 int opt_idx;
3969 char_u *varp;
3970
3971 opt_idx = findoption(name);
3972 if (opt_idx < 0) /* unknown option */
Bram Moolenaare353c402017-02-04 19:49:16 +01003973 {
3974 int key;
3975
3976 if (STRLEN(name) == 4 && name[0] == 't' && name[1] == '_'
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02003977 && (key = find_key_option(name, FALSE)) != 0)
Bram Moolenaare353c402017-02-04 19:49:16 +01003978 {
3979 char_u key_name[2];
3980 char_u *p;
3981
3982 if (key < 0)
3983 {
3984 key_name[0] = KEY2TERMCAP0(key);
3985 key_name[1] = KEY2TERMCAP1(key);
3986 }
3987 else
3988 {
3989 key_name[0] = KS_KEY;
3990 key_name[1] = (key & 0xff);
3991 }
3992 p = find_termcode(key_name);
3993 if (p != NULL)
3994 {
3995 if (stringval != NULL)
3996 *stringval = vim_strsave(p);
3997 return 0;
3998 }
3999 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004000 return -3;
Bram Moolenaare353c402017-02-04 19:49:16 +01004001 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004002
4003 varp = get_varp_scope(&(options[opt_idx]), opt_flags);
4004
4005 if (options[opt_idx].flags & P_STRING)
4006 {
4007 if (varp == NULL) /* hidden option */
4008 return -2;
4009 if (stringval != NULL)
4010 {
4011#ifdef FEAT_CRYPT
4012 /* never return the value of the crypt key */
Bram Moolenaarc1a11ed2008-06-24 22:09:24 +00004013 if ((char_u **)varp == &curbuf->b_p_key
4014 && **(char_u **)(varp) != NUL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004015 *stringval = vim_strsave((char_u *)"*****");
4016 else
4017#endif
4018 *stringval = vim_strsave(*(char_u **)(varp));
4019 }
4020 return 0;
4021 }
4022
4023 if (varp == NULL) /* hidden option */
4024 return -1;
4025 if (options[opt_idx].flags & P_NUM)
4026 *numval = *(long *)varp;
4027 else
4028 {
4029 /* Special case: 'modified' is b_changed, but we also want to consider
4030 * it set when 'ff' or 'fenc' changed. */
4031 if ((int *)varp == &curbuf->b_changed)
4032 *numval = curbufIsChanged();
4033 else
Bram Moolenaar2acfbed2016-07-01 23:14:02 +02004034 *numval = (long) *(int *)varp;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004035 }
4036 return 1;
4037}
4038#endif
4039
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004040#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) || defined(PROTO)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004041/*
4042 * Returns the option attributes and its value. Unlike the above function it
4043 * will return either global value or local value of the option depending on
4044 * what was requested, but it will never return global value if it was
4045 * requested to return local one and vice versa. Neither it will return
4046 * buffer-local value if it was requested to return window-local one.
4047 *
4048 * Pretends that option is absent if it is not present in the requested scope
4049 * (i.e. has no global, window-local or buffer-local value depending on
4050 * opt_type). Uses
4051 *
4052 * Returned flags:
Bram Moolenaar75a8d742014-05-07 15:10:21 +02004053 * 0 hidden or unknown option, also option that does not have requested
4054 * type (see SREQ_* in vim.h)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004055 * see SOPT_* in vim.h for other flags
4056 *
4057 * Possible opt_type values: see SREQ_* in vim.h
4058 */
4059 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01004060get_option_value_strict(
4061 char_u *name,
4062 long *numval,
4063 char_u **stringval, /* NULL when only obtaining attributes */
4064 int opt_type,
4065 void *from)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004066{
4067 int opt_idx;
Bram Moolenaar68001862013-05-11 13:45:05 +02004068 char_u *varp = NULL;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004069 struct vimoption *p;
4070 int r = 0;
4071
4072 opt_idx = findoption(name);
4073 if (opt_idx < 0)
4074 return 0;
4075
4076 p = &(options[opt_idx]);
4077
4078 /* Hidden option */
4079 if (p->var == NULL)
4080 return 0;
4081
4082 if (p->flags & P_BOOL)
4083 r |= SOPT_BOOL;
4084 else if (p->flags & P_NUM)
4085 r |= SOPT_NUM;
4086 else if (p->flags & P_STRING)
4087 r |= SOPT_STRING;
4088
4089 if (p->indir == PV_NONE)
4090 {
4091 if (opt_type == SREQ_GLOBAL)
4092 r |= SOPT_GLOBAL;
4093 else
4094 return 0; /* Did not request global-only option */
4095 }
4096 else
4097 {
4098 if (p->indir & PV_BOTH)
4099 r |= SOPT_GLOBAL;
4100 else if (opt_type == SREQ_GLOBAL)
4101 return 0; /* Requested global option */
4102
4103 if (p->indir & PV_WIN)
4104 {
4105 if (opt_type == SREQ_BUF)
4106 return 0; /* Did not request window-local option */
4107 else
4108 r |= SOPT_WIN;
4109 }
4110 else if (p->indir & PV_BUF)
4111 {
4112 if (opt_type == SREQ_WIN)
4113 return 0; /* Did not request buffer-local option */
4114 else
4115 r |= SOPT_BUF;
4116 }
4117 }
4118
4119 if (stringval == NULL)
4120 return r;
4121
4122 if (opt_type == SREQ_GLOBAL)
4123 varp = p->var;
4124 else
4125 {
4126 if (opt_type == SREQ_BUF)
4127 {
4128 /* Special case: 'modified' is b_changed, but we also want to
4129 * consider it set when 'ff' or 'fenc' changed. */
4130 if (p->indir == PV_MOD)
4131 {
Bram Moolenaardefe6422018-06-24 15:14:07 +02004132 *numval = bufIsChanged((buf_T *)from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004133 varp = NULL;
4134 }
4135#ifdef FEAT_CRYPT
4136 else if (p->indir == PV_KEY)
4137 {
4138 /* never return the value of the crypt key */
4139 *stringval = NULL;
4140 varp = NULL;
4141 }
4142#endif
4143 else
4144 {
Bram Moolenaardefe6422018-06-24 15:14:07 +02004145 buf_T *save_curbuf = curbuf;
4146
4147 // only getting a pointer, no need to use aucmd_prepbuf()
4148 curbuf = (buf_T *)from;
4149 curwin->w_buffer = curbuf;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004150 varp = get_varp(p);
Bram Moolenaardefe6422018-06-24 15:14:07 +02004151 curbuf = save_curbuf;
4152 curwin->w_buffer = curbuf;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004153 }
4154 }
4155 else if (opt_type == SREQ_WIN)
4156 {
Bram Moolenaardefe6422018-06-24 15:14:07 +02004157 win_T *save_curwin = curwin;
4158
4159 curwin = (win_T *)from;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004160 curbuf = curwin->w_buffer;
4161 varp = get_varp(p);
4162 curwin = save_curwin;
4163 curbuf = curwin->w_buffer;
4164 }
4165 if (varp == p->var)
4166 return (r | SOPT_UNSET);
4167 }
4168
4169 if (varp != NULL)
4170 {
4171 if (p->flags & P_STRING)
4172 *stringval = vim_strsave(*(char_u **)(varp));
4173 else if (p->flags & P_NUM)
4174 *numval = *(long *) varp;
4175 else
4176 *numval = *(int *)varp;
4177 }
4178
4179 return r;
4180}
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004181
4182/*
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02004183 * Iterate over options. First argument is a pointer to a pointer to a
4184 * structure inside options[] array, second is option type like in the above
4185 * function.
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004186 *
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02004187 * If first argument points to NULL it is assumed that iteration just started
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004188 * and caller needs the very first value.
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02004189 * If first argument points to the end marker function returns NULL and sets
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004190 * first argument to NULL.
4191 *
4192 * Returns full option name for current option on each call.
4193 */
4194 char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01004195option_iter_next(void **option, int opt_type)
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004196{
4197 struct vimoption *ret = NULL;
4198 do
4199 {
4200 if (*option == NULL)
4201 *option = (void *) options;
4202 else if (((struct vimoption *) (*option))->fullname == NULL)
4203 {
4204 *option = NULL;
4205 return NULL;
4206 }
4207 else
4208 *option = (void *) (((struct vimoption *) (*option)) + 1);
4209
4210 ret = ((struct vimoption *) (*option));
4211
4212 /* Hidden option */
4213 if (ret->var == NULL)
4214 {
4215 ret = NULL;
4216 continue;
4217 }
4218
4219 switch (opt_type)
4220 {
4221 case SREQ_GLOBAL:
4222 if (!(ret->indir == PV_NONE || ret->indir & PV_BOTH))
4223 ret = NULL;
4224 break;
4225 case SREQ_BUF:
4226 if (!(ret->indir & PV_BUF))
4227 ret = NULL;
4228 break;
4229 case SREQ_WIN:
4230 if (!(ret->indir & PV_WIN))
4231 ret = NULL;
4232 break;
4233 default:
Bram Moolenaar95f09602016-11-10 20:01:45 +01004234 internal_error("option_iter_next()");
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01004235 return NULL;
4236 }
4237 }
4238 while (ret == NULL);
4239
4240 return (char_u *)ret->fullname;
4241}
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004242#endif
4243
Bram Moolenaar071d4272004-06-13 20:20:40 +00004244/*
Bram Moolenaardac13472019-09-16 21:06:21 +02004245 * Return the flags for the option at 'opt_idx'.
4246 */
4247 long_u
4248get_option_flags(int opt_idx)
4249{
4250 return options[opt_idx].flags;
4251}
4252
4253/*
4254 * Set a flag for the option at 'opt_idx'.
4255 */
4256 void
4257set_option_flag(int opt_idx, long_u flag)
4258{
4259 options[opt_idx].flags |= flag;
4260}
4261
4262/*
4263 * Clear a flag for the option at 'opt_idx'.
4264 */
4265 void
4266clear_option_flag(int opt_idx, long_u flag)
4267{
4268 options[opt_idx].flags &= ~flag;
4269}
4270
4271/*
4272 * Returns TRUE if the option at 'opt_idx' is a global option
4273 */
4274 int
4275is_global_option(int opt_idx)
4276{
4277 return options[opt_idx].indir == PV_NONE;
4278}
4279
4280/*
4281 * Returns TRUE if the option at 'opt_idx' is a global option which also has a
4282 * local value.
4283 */
4284 int
4285is_global_local_option(int opt_idx)
4286{
4287 return options[opt_idx].indir & PV_BOTH;
4288}
4289
4290/*
4291 * Returns TRUE if the option at 'opt_idx' is a window-local option
4292 */
4293 int
4294is_window_local_option(int opt_idx)
4295{
4296 return options[opt_idx].var == VAR_WIN;
4297}
4298
4299/*
4300 * Returns TRUE if the option at 'opt_idx' is a hidden option
4301 */
4302 int
4303is_hidden_option(int opt_idx)
4304{
4305 return options[opt_idx].var == NULL;
4306}
4307
4308#if defined(FEAT_CRYPT) || defined(PROTO)
4309/*
4310 * Returns TRUE if the option at 'opt_idx' is a crypt key option
4311 */
4312 int
4313is_crypt_key_option(int opt_idx)
4314{
4315 return options[opt_idx].indir == PV_KEY;
4316}
4317#endif
4318
4319/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00004320 * Set the value of option "name".
4321 * Use "string" for string options, use "number" for other options.
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004322 *
4323 * Returns NULL on success or error message on error.
Bram Moolenaar071d4272004-06-13 20:20:40 +00004324 */
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004325 char *
Bram Moolenaar9b578142016-01-30 19:39:49 +01004326set_option_value(
4327 char_u *name,
4328 long number,
4329 char_u *string,
4330 int opt_flags) /* OPT_LOCAL or 0 (both) */
Bram Moolenaar071d4272004-06-13 20:20:40 +00004331{
4332 int opt_idx;
4333 char_u *varp;
Bram Moolenaara93fa7e2006-04-17 22:14:47 +00004334 long_u flags;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004335
4336 opt_idx = findoption(name);
Bram Moolenaarfc1421e2006-04-20 22:17:20 +00004337 if (opt_idx < 0)
Bram Moolenaare353c402017-02-04 19:49:16 +01004338 {
4339 int key;
4340
4341 if (STRLEN(name) == 4 && name[0] == 't' && name[1] == '_'
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02004342 && (key = find_key_option(name, FALSE)) != 0)
Bram Moolenaare353c402017-02-04 19:49:16 +01004343 {
4344 char_u key_name[2];
4345
4346 if (key < 0)
4347 {
4348 key_name[0] = KEY2TERMCAP0(key);
4349 key_name[1] = KEY2TERMCAP1(key);
4350 }
4351 else
4352 {
4353 key_name[0] = KS_KEY;
4354 key_name[1] = (key & 0xff);
4355 }
4356 add_termcode(key_name, string, FALSE);
4357 if (full_screen)
4358 ttest(FALSE);
4359 redraw_all_later(CLEAR);
4360 return NULL;
4361 }
4362
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004363 semsg(_("E355: Unknown option: %s"), name);
Bram Moolenaare353c402017-02-04 19:49:16 +01004364 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004365 else
4366 {
4367 flags = options[opt_idx].flags;
4368#ifdef HAVE_SANDBOX
4369 /* Disallow changing some options in the sandbox */
4370 if (sandbox > 0 && (flags & P_SECURE))
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00004371 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004372 emsg(_(e_sandbox));
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004373 return NULL;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00004374 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004375#endif
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00004376 if (flags & P_STRING)
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004377 return set_string_option(opt_idx, string, opt_flags);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004378 else
4379 {
Bram Moolenaarb3163762008-07-08 15:15:08 +00004380 varp = get_varp_scope(&(options[opt_idx]), opt_flags);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004381 if (varp != NULL) /* hidden option is not changed */
4382 {
Bram Moolenaar96bb6212007-06-19 18:52:53 +00004383 if (number == 0 && string != NULL)
4384 {
Bram Moolenaarfe86f2d2008-11-28 20:29:07 +00004385 int idx;
Bram Moolenaar96bb6212007-06-19 18:52:53 +00004386
4387 /* Either we are given a string or we are setting option
4388 * to zero. */
Bram Moolenaarfe86f2d2008-11-28 20:29:07 +00004389 for (idx = 0; string[idx] == '0'; ++idx)
Bram Moolenaar96bb6212007-06-19 18:52:53 +00004390 ;
Bram Moolenaarfe86f2d2008-11-28 20:29:07 +00004391 if (string[idx] != NUL || idx == 0)
Bram Moolenaar96bb6212007-06-19 18:52:53 +00004392 {
4393 /* There's another character after zeros or the string
4394 * is empty. In both cases, we are trying to set a
4395 * num option using a string. */
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01004396 semsg(_("E521: Number required: &%s = '%s'"),
Bram Moolenaar96bb6212007-06-19 18:52:53 +00004397 name, string);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004398 return NULL; /* do nothing as we hit an error */
Bram Moolenaar96bb6212007-06-19 18:52:53 +00004399
4400 }
4401 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004402 if (flags & P_NUM)
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004403 return set_num_option(opt_idx, varp, number,
Bram Moolenaar555b2802005-05-19 21:08:39 +00004404 NULL, 0, opt_flags);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004405 else
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004406 return set_bool_option(opt_idx, varp, (int)number,
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00004407 opt_flags);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004408 }
4409 }
4410 }
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02004411 return NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004412}
4413
4414/*
4415 * Get the terminal code for a terminal option.
4416 * Returns NULL when not found.
4417 */
4418 char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01004419get_term_code(char_u *tname)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004420{
4421 int opt_idx;
4422 char_u *varp;
4423
4424 if (tname[0] != 't' || tname[1] != '_' ||
4425 tname[2] == NUL || tname[3] == NUL)
4426 return NULL;
4427 if ((opt_idx = findoption(tname)) >= 0)
4428 {
4429 varp = get_varp(&(options[opt_idx]));
4430 if (varp != NULL)
4431 varp = *(char_u **)(varp);
4432 return varp;
4433 }
4434 return find_termcode(tname + 2);
4435}
4436
4437 char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01004438get_highlight_default(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004439{
4440 int i;
4441
4442 i = findoption((char_u *)"hl");
4443 if (i >= 0)
4444 return options[i].def_val[VI_DEFAULT];
4445 return (char_u *)NULL;
4446}
4447
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00004448 char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01004449get_encoding_default(void)
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00004450{
4451 int i;
4452
4453 i = findoption((char_u *)"enc");
4454 if (i >= 0)
4455 return options[i].def_val[VI_DEFAULT];
4456 return (char_u *)NULL;
4457}
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00004458
Bram Moolenaar071d4272004-06-13 20:20:40 +00004459/*
4460 * Translate a string like "t_xx", "<t_xx>" or "<S-Tab>" to a key number.
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02004461 * When "has_lt" is true there is a '<' before "*arg_arg".
4462 * Returns 0 when the key is not recognized.
Bram Moolenaar071d4272004-06-13 20:20:40 +00004463 */
4464 static int
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02004465find_key_option(char_u *arg_arg, int has_lt)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004466{
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02004467 int key = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004468 int modifiers;
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02004469 char_u *arg = arg_arg;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004470
4471 /*
4472 * Don't use get_special_key_code() for t_xx, we don't want it to call
4473 * add_termcap_entry().
4474 */
4475 if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
4476 key = TERMCAP2KEY(arg[2], arg[3]);
Bram Moolenaar9cf4b502018-07-23 04:12:03 +02004477 else if (has_lt)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004478 {
4479 --arg; /* put arg at the '<' */
4480 modifiers = 0;
Bram Moolenaar35a4cfa2016-08-14 16:07:48 +02004481 key = find_special_key(&arg, &modifiers, TRUE, TRUE, FALSE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004482 if (modifiers) /* can't handle modifiers here */
4483 key = 0;
4484 }
4485 return key;
4486}
4487
4488/*
4489 * if 'all' == 0: show changed options
4490 * if 'all' == 1: show all normal options
4491 * if 'all' == 2: show all terminal options
4492 */
4493 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01004494showoptions(
4495 int all,
4496 int opt_flags) /* OPT_LOCAL and/or OPT_GLOBAL */
Bram Moolenaar071d4272004-06-13 20:20:40 +00004497{
4498 struct vimoption *p;
4499 int col;
4500 int isterm;
4501 char_u *varp;
4502 struct vimoption **items;
4503 int item_count;
4504 int run;
4505 int row, rows;
4506 int cols;
4507 int i;
4508 int len;
4509
4510#define INC 20
4511#define GAP 3
4512
Bram Moolenaarc799fe22019-05-28 23:08:19 +02004513 items = ALLOC_MULT(struct vimoption *, PARAM_COUNT);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004514 if (items == NULL)
4515 return;
4516
4517 /* Highlight title */
4518 if (all == 2)
Bram Moolenaar32526b32019-01-19 17:43:09 +01004519 msg_puts_title(_("\n--- Terminal codes ---"));
Bram Moolenaar071d4272004-06-13 20:20:40 +00004520 else if (opt_flags & OPT_GLOBAL)
Bram Moolenaar32526b32019-01-19 17:43:09 +01004521 msg_puts_title(_("\n--- Global option values ---"));
Bram Moolenaar071d4272004-06-13 20:20:40 +00004522 else if (opt_flags & OPT_LOCAL)
Bram Moolenaar32526b32019-01-19 17:43:09 +01004523 msg_puts_title(_("\n--- Local option values ---"));
Bram Moolenaar071d4272004-06-13 20:20:40 +00004524 else
Bram Moolenaar32526b32019-01-19 17:43:09 +01004525 msg_puts_title(_("\n--- Options ---"));
Bram Moolenaar071d4272004-06-13 20:20:40 +00004526
4527 /*
4528 * do the loop two times:
4529 * 1. display the short items
4530 * 2. display the long items (only strings and numbers)
4531 */
4532 for (run = 1; run <= 2 && !got_int; ++run)
4533 {
4534 /*
4535 * collect the items in items[]
4536 */
4537 item_count = 0;
4538 for (p = &options[0]; p->fullname != NULL; p++)
4539 {
Bram Moolenaarf86db782018-10-25 13:31:37 +02004540 // apply :filter /pat/
4541 if (message_filtered((char_u *) p->fullname))
4542 continue;
4543
Bram Moolenaar071d4272004-06-13 20:20:40 +00004544 varp = NULL;
4545 isterm = istermoption(p);
4546 if (opt_flags != 0)
4547 {
4548 if (p->indir != PV_NONE && !isterm)
4549 varp = get_varp_scope(p, opt_flags);
4550 }
4551 else
4552 varp = get_varp(p);
4553 if (varp != NULL
4554 && ((all == 2 && isterm)
4555 || (all == 1 && !isterm)
Bram Moolenaarcacc6a52019-05-30 15:22:43 +02004556 || (all == 0 && !optval_default(p, varp, p_cp))))
Bram Moolenaar071d4272004-06-13 20:20:40 +00004557 {
4558 if (p->flags & P_BOOL)
4559 len = 1; /* a toggle option fits always */
4560 else
4561 {
4562 option_value2string(p, opt_flags);
4563 len = (int)STRLEN(p->fullname) + vim_strsize(NameBuff) + 1;
4564 }
4565 if ((len <= INC - GAP && run == 1) ||
4566 (len > INC - GAP && run == 2))
4567 items[item_count++] = p;
4568 }
4569 }
4570
4571 /*
4572 * display the items
4573 */
4574 if (run == 1)
4575 {
4576 cols = (Columns + GAP - 3) / INC;
4577 if (cols == 0)
4578 cols = 1;
4579 rows = (item_count + cols - 1) / cols;
4580 }
4581 else /* run == 2 */
4582 rows = item_count;
4583 for (row = 0; row < rows && !got_int; ++row)
4584 {
4585 msg_putchar('\n'); /* go to next line */
4586 if (got_int) /* 'q' typed in more */
4587 break;
4588 col = 0;
4589 for (i = row; i < item_count; i += rows)
4590 {
4591 msg_col = col; /* make columns */
4592 showoneopt(items[i], opt_flags);
4593 col += INC;
4594 }
4595 out_flush();
4596 ui_breakcheck();
4597 }
4598 }
4599 vim_free(items);
4600}
4601
4602/*
4603 * Return TRUE if option "p" has its default value.
4604 */
4605 static int
Bram Moolenaarcacc6a52019-05-30 15:22:43 +02004606optval_default(struct vimoption *p, char_u *varp, int compatible)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004607{
4608 int dvi;
4609
4610 if (varp == NULL)
4611 return TRUE; /* hidden option is always at default */
Bram Moolenaarcacc6a52019-05-30 15:22:43 +02004612 dvi = ((p->flags & P_VI_DEF) || compatible) ? VI_DEFAULT : VIM_DEFAULT;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004613 if (p->flags & P_NUM)
Bram Moolenaareb3593b2006-04-22 22:33:57 +00004614 return (*(long *)varp == (long)(long_i)p->def_val[dvi]);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004615 if (p->flags & P_BOOL)
Bram Moolenaareb3593b2006-04-22 22:33:57 +00004616 /* the cast to long is required for Manx C, long_i is
4617 * needed for MSVC */
4618 return (*(int *)varp == (int)(long)(long_i)p->def_val[dvi]);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004619 /* P_STRING */
4620 return (STRCMP(*(char_u **)varp, p->def_val[dvi]) == 0);
4621}
4622
4623/*
4624 * showoneopt: show the value of one option
4625 * must not be called with a hidden option!
4626 */
4627 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01004628showoneopt(
4629 struct vimoption *p,
4630 int opt_flags) /* OPT_LOCAL or OPT_GLOBAL */
Bram Moolenaar071d4272004-06-13 20:20:40 +00004631{
Bram Moolenaar26a60b42005-02-22 08:49:11 +00004632 char_u *varp;
4633 int save_silent = silent_mode;
4634
4635 silent_mode = FALSE;
4636 info_message = TRUE; /* use mch_msg(), not mch_errmsg() */
Bram Moolenaar071d4272004-06-13 20:20:40 +00004637
4638 varp = get_varp_scope(p, opt_flags);
4639
4640 /* for 'modified' we also need to check if 'ff' or 'fenc' changed. */
4641 if ((p->flags & P_BOOL) && ((int *)varp == &curbuf->b_changed
4642 ? !curbufIsChanged() : !*(int *)varp))
Bram Moolenaar32526b32019-01-19 17:43:09 +01004643 msg_puts("no");
Bram Moolenaar071d4272004-06-13 20:20:40 +00004644 else if ((p->flags & P_BOOL) && *(int *)varp < 0)
Bram Moolenaar32526b32019-01-19 17:43:09 +01004645 msg_puts("--");
Bram Moolenaar071d4272004-06-13 20:20:40 +00004646 else
Bram Moolenaar32526b32019-01-19 17:43:09 +01004647 msg_puts(" ");
4648 msg_puts(p->fullname);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004649 if (!(p->flags & P_BOOL))
4650 {
4651 msg_putchar('=');
4652 /* put value string in NameBuff */
4653 option_value2string(p, opt_flags);
4654 msg_outtrans(NameBuff);
4655 }
Bram Moolenaar26a60b42005-02-22 08:49:11 +00004656
4657 silent_mode = save_silent;
4658 info_message = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004659}
4660
4661/*
4662 * Write modified options as ":set" commands to a file.
4663 *
4664 * There are three values for "opt_flags":
4665 * OPT_GLOBAL: Write global option values and fresh values of
4666 * buffer-local options (used for start of a session
4667 * file).
4668 * OPT_GLOBAL + OPT_LOCAL: Idem, add fresh values of window-local options for
4669 * curwin (used for a vimrc file).
4670 * OPT_LOCAL: Write buffer-local option values for curbuf, fresh
4671 * and local values for window-local options of
4672 * curwin. Local values are also written when at the
4673 * default value, because a modeline or autocommand
4674 * may have set them when doing ":edit file" and the
4675 * user has set them back at the default or fresh
4676 * value.
4677 * When "local_only" is TRUE, don't write fresh
4678 * values, only local values (for ":mkview").
4679 * (fresh value = value used for a new buffer or window for a local option).
4680 *
4681 * Return FAIL on error, OK otherwise.
4682 */
4683 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01004684makeset(FILE *fd, int opt_flags, int local_only)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004685{
4686 struct vimoption *p;
4687 char_u *varp; /* currently used value */
4688 char_u *varp_fresh; /* local value */
4689 char_u *varp_local = NULL; /* fresh value */
4690 char *cmd;
4691 int round;
Bram Moolenaar7fd16022007-09-06 14:35:35 +00004692 int pri;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004693
4694 /*
4695 * The options that don't have a default (terminal name, columns, lines)
4696 * are never written. Terminal options are also not written.
Bram Moolenaar7fd16022007-09-06 14:35:35 +00004697 * Do the loop over "options[]" twice: once for options with the
4698 * P_PRI_MKRC flag and once without.
Bram Moolenaar071d4272004-06-13 20:20:40 +00004699 */
Bram Moolenaar7fd16022007-09-06 14:35:35 +00004700 for (pri = 1; pri >= 0; --pri)
4701 {
4702 for (p = &options[0]; !istermoption(p); p++)
4703 if (!(p->flags & P_NO_MKRC)
4704 && !istermoption(p)
4705 && ((pri == 1) == ((p->flags & P_PRI_MKRC) != 0)))
Bram Moolenaar071d4272004-06-13 20:20:40 +00004706 {
4707 /* skip global option when only doing locals */
4708 if (p->indir == PV_NONE && !(opt_flags & OPT_GLOBAL))
4709 continue;
4710
4711 /* Do not store options like 'bufhidden' and 'syntax' in a vimrc
4712 * file, they are always buffer-specific. */
4713 if ((opt_flags & OPT_GLOBAL) && (p->flags & P_NOGLOB))
4714 continue;
4715
4716 /* Global values are only written when not at the default value. */
4717 varp = get_varp_scope(p, opt_flags);
Bram Moolenaarcacc6a52019-05-30 15:22:43 +02004718 if ((opt_flags & OPT_GLOBAL) && optval_default(p, varp, p_cp))
Bram Moolenaar071d4272004-06-13 20:20:40 +00004719 continue;
4720
4721 round = 2;
4722 if (p->indir != PV_NONE)
4723 {
4724 if (p->var == VAR_WIN)
4725 {
4726 /* skip window-local option when only doing globals */
4727 if (!(opt_flags & OPT_LOCAL))
4728 continue;
4729 /* When fresh value of window-local option is not at the
4730 * default, need to write it too. */
4731 if (!(opt_flags & OPT_GLOBAL) && !local_only)
4732 {
4733 varp_fresh = get_varp_scope(p, OPT_GLOBAL);
Bram Moolenaarcacc6a52019-05-30 15:22:43 +02004734 if (!optval_default(p, varp_fresh, p_cp))
Bram Moolenaar071d4272004-06-13 20:20:40 +00004735 {
4736 round = 1;
4737 varp_local = varp;
4738 varp = varp_fresh;
4739 }
4740 }
4741 }
4742 }
4743
4744 /* Round 1: fresh value for window-local options.
4745 * Round 2: other values */
4746 for ( ; round <= 2; varp = varp_local, ++round)
4747 {
4748 if (round == 1 || (opt_flags & OPT_GLOBAL))
4749 cmd = "set";
4750 else
4751 cmd = "setlocal";
4752
4753 if (p->flags & P_BOOL)
4754 {
4755 if (put_setbool(fd, cmd, p->fullname, *(int *)varp) == FAIL)
4756 return FAIL;
4757 }
4758 else if (p->flags & P_NUM)
4759 {
4760 if (put_setnum(fd, cmd, p->fullname, (long *)varp) == FAIL)
4761 return FAIL;
4762 }
4763 else /* P_STRING */
4764 {
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00004765 int do_endif = FALSE;
4766
Bram Moolenaar071d4272004-06-13 20:20:40 +00004767 /* Don't set 'syntax' and 'filetype' again if the value is
4768 * already right, avoids reloading the syntax file. */
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00004769 if (
Bram Moolenaarf2bd8ef2018-03-04 18:08:14 +01004770#if defined(FEAT_SYN_HL)
4771 p->indir == PV_SYN ||
4772#endif
4773 p->indir == PV_FT)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004774 {
4775 if (fprintf(fd, "if &%s != '%s'", p->fullname,
4776 *(char_u **)(varp)) < 0
4777 || put_eol(fd) < 0)
4778 return FAIL;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00004779 do_endif = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004780 }
4781 if (put_setstring(fd, cmd, p->fullname, (char_u **)varp,
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004782 p->flags) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004783 return FAIL;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00004784 if (do_endif)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004785 {
4786 if (put_line(fd, "endif") == FAIL)
4787 return FAIL;
4788 }
4789 }
4790 }
4791 }
Bram Moolenaar7fd16022007-09-06 14:35:35 +00004792 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004793 return OK;
4794}
4795
4796#if defined(FEAT_FOLDING) || defined(PROTO)
4797/*
4798 * Generate set commands for the local fold options only. Used when
4799 * 'sessionoptions' or 'viewoptions' contains "folds" but not "options".
4800 */
4801 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01004802makefoldset(FILE *fd)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004803{
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004804 if (put_setstring(fd, "setlocal", "fdm", &curwin->w_p_fdm, 0) == FAIL
Bram Moolenaar071d4272004-06-13 20:20:40 +00004805# ifdef FEAT_EVAL
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004806 || put_setstring(fd, "setlocal", "fde", &curwin->w_p_fde, 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004807 == FAIL
4808# endif
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004809 || put_setstring(fd, "setlocal", "fmr", &curwin->w_p_fmr, 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004810 == FAIL
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004811 || put_setstring(fd, "setlocal", "fdi", &curwin->w_p_fdi, 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004812 == FAIL
4813 || put_setnum(fd, "setlocal", "fdl", &curwin->w_p_fdl) == FAIL
4814 || put_setnum(fd, "setlocal", "fml", &curwin->w_p_fml) == FAIL
4815 || put_setnum(fd, "setlocal", "fdn", &curwin->w_p_fdn) == FAIL
4816 || put_setbool(fd, "setlocal", "fen", curwin->w_p_fen) == FAIL
4817 )
4818 return FAIL;
4819
4820 return OK;
4821}
4822#endif
4823
4824 static int
Bram Moolenaar9b578142016-01-30 19:39:49 +01004825put_setstring(
4826 FILE *fd,
4827 char *cmd,
4828 char *name,
4829 char_u **valuep,
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004830 long_u flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004831{
4832 char_u *s;
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004833 char_u *buf = NULL;
4834 char_u *part = NULL;
4835 char_u *p;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004836
4837 if (fprintf(fd, "%s %s=", cmd, name) < 0)
4838 return FAIL;
4839 if (*valuep != NULL)
4840 {
4841 /* Output 'pastetoggle' as key names. For other
4842 * options some characters have to be escaped with
4843 * CTRL-V or backslash */
4844 if (valuep == &p_pt)
4845 {
4846 s = *valuep;
4847 while (*s != NUL)
Bram Moolenaar7d96acd2008-06-09 15:07:54 +00004848 if (put_escstr(fd, str2special(&s, FALSE), 2) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004849 return FAIL;
4850 }
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004851 // expand the option value, replace $HOME by ~
4852 else if ((flags & P_EXPAND) != 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004853 {
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004854 int size = (int)STRLEN(*valuep) + 1;
4855
4856 // replace home directory in the whole option value into "buf"
4857 buf = alloc(size);
Bram Moolenaarf8441472011-04-28 17:24:58 +02004858 if (buf == NULL)
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004859 goto fail;
4860 home_replace(NULL, *valuep, buf, size, FALSE);
4861
4862 // If the option value is longer than MAXPATHL, we need to append
4863 // earch comma separated part of the option separately, so that it
4864 // can be expanded when read back.
4865 if (size >= MAXPATHL && (flags & P_COMMA) != 0
4866 && vim_strchr(*valuep, ',') != NULL)
4867 {
4868 part = alloc(size);
4869 if (part == NULL)
4870 goto fail;
4871
4872 // write line break to clear the option, e.g. ':set rtp='
4873 if (put_eol(fd) == FAIL)
4874 goto fail;
4875
4876 p = buf;
4877 while (*p != NUL)
4878 {
4879 // for each comma separated option part, append value to
4880 // the option, :set rtp+=value
4881 if (fprintf(fd, "%s %s+=", cmd, name) < 0)
4882 goto fail;
4883 (void)copy_option_part(&p, part, size, ",");
4884 if (put_escstr(fd, part, 2) == FAIL || put_eol(fd) == FAIL)
4885 goto fail;
4886 }
4887 vim_free(buf);
4888 vim_free(part);
4889 return OK;
4890 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004891 if (put_escstr(fd, buf, 2) == FAIL)
Bram Moolenaarf8441472011-04-28 17:24:58 +02004892 {
4893 vim_free(buf);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004894 return FAIL;
Bram Moolenaarf8441472011-04-28 17:24:58 +02004895 }
4896 vim_free(buf);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004897 }
4898 else if (put_escstr(fd, *valuep, 2) == FAIL)
4899 return FAIL;
4900 }
4901 if (put_eol(fd) < 0)
4902 return FAIL;
4903 return OK;
Bram Moolenaared18f2c2019-01-24 20:30:52 +01004904fail:
4905 vim_free(buf);
4906 vim_free(part);
4907 return FAIL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004908}
4909
4910 static int
Bram Moolenaar9b578142016-01-30 19:39:49 +01004911put_setnum(
4912 FILE *fd,
4913 char *cmd,
4914 char *name,
4915 long *valuep)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004916{
4917 long wc;
4918
4919 if (fprintf(fd, "%s %s=", cmd, name) < 0)
4920 return FAIL;
4921 if (wc_use_keyname((char_u *)valuep, &wc))
4922 {
4923 /* print 'wildchar' and 'wildcharm' as a key name */
4924 if (fputs((char *)get_special_key_name((int)wc, 0), fd) < 0)
4925 return FAIL;
4926 }
4927 else if (fprintf(fd, "%ld", *valuep) < 0)
4928 return FAIL;
4929 if (put_eol(fd) < 0)
4930 return FAIL;
4931 return OK;
4932}
4933
4934 static int
Bram Moolenaar9b578142016-01-30 19:39:49 +01004935put_setbool(
4936 FILE *fd,
4937 char *cmd,
4938 char *name,
4939 int value)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004940{
Bram Moolenaar893de922007-10-02 18:40:57 +00004941 if (value < 0) /* global/local option using global value */
4942 return OK;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004943 if (fprintf(fd, "%s %s%s", cmd, value ? "" : "no", name) < 0
4944 || put_eol(fd) < 0)
4945 return FAIL;
4946 return OK;
4947}
4948
4949/*
4950 * Clear all the terminal options.
4951 * If the option has been allocated, free the memory.
4952 * Terminal options are never hidden or indirect.
4953 */
4954 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01004955clear_termoptions(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004956{
Bram Moolenaar071d4272004-06-13 20:20:40 +00004957 /*
4958 * Reset a few things before clearing the old options. This may cause
4959 * outputting a few things that the terminal doesn't understand, but the
4960 * screen will be cleared later, so this is OK.
4961 */
4962#ifdef FEAT_MOUSE_TTY
4963 mch_setmouse(FALSE); /* switch mouse off */
4964#endif
4965#ifdef FEAT_TITLE
Bram Moolenaar40385db2018-08-07 22:31:44 +02004966 mch_restore_title(SAVE_RESTORE_BOTH); /* restore window titles */
Bram Moolenaar071d4272004-06-13 20:20:40 +00004967#endif
4968#if defined(FEAT_XCLIPBOARD) && defined(FEAT_GUI)
4969 /* When starting the GUI close the display opened for the clipboard.
4970 * After restoring the title, because that will need the display. */
4971 if (gui.starting)
4972 clear_xterm_clip();
4973#endif
Bram Moolenaarcea912a2016-10-12 14:20:24 +02004974 stoptermcap(); /* stop termcap mode */
Bram Moolenaar071d4272004-06-13 20:20:40 +00004975
Bram Moolenaarf461c8e2005-06-25 23:04:51 +00004976 free_termoptions();
4977}
4978
4979 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01004980free_termoptions(void)
Bram Moolenaarf461c8e2005-06-25 23:04:51 +00004981{
4982 struct vimoption *p;
4983
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02004984 for (p = options; p->fullname != NULL; p++)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004985 if (istermoption(p))
4986 {
4987 if (p->flags & P_ALLOCED)
4988 free_string_option(*(char_u **)(p->var));
4989 if (p->flags & P_DEF_ALLOCED)
4990 free_string_option(p->def_val[VI_DEFAULT]);
4991 *(char_u **)(p->var) = empty_option;
4992 p->def_val[VI_DEFAULT] = empty_option;
4993 p->flags &= ~(P_ALLOCED|P_DEF_ALLOCED);
Bram Moolenaar35bc7d62018-10-02 14:45:10 +02004994#ifdef FEAT_EVAL
4995 // remember where the option was cleared
4996 set_option_sctx_idx((int)(p - options), OPT_GLOBAL, current_sctx);
4997#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00004998 }
4999 clear_termcodes();
5000}
5001
5002/*
Bram Moolenaar363cb672009-07-22 12:28:17 +00005003 * Free the string for one term option, if it was allocated.
5004 * Set the string to empty_option and clear allocated flag.
5005 * "var" points to the option value.
5006 */
5007 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005008free_one_termoption(char_u *var)
Bram Moolenaar363cb672009-07-22 12:28:17 +00005009{
5010 struct vimoption *p;
5011
5012 for (p = &options[0]; p->fullname != NULL; p++)
5013 if (p->var == var)
5014 {
5015 if (p->flags & P_ALLOCED)
5016 free_string_option(*(char_u **)(p->var));
5017 *(char_u **)(p->var) = empty_option;
5018 p->flags &= ~P_ALLOCED;
5019 break;
5020 }
5021}
5022
5023/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005024 * Set the terminal option defaults to the current value.
5025 * Used after setting the terminal name.
5026 */
5027 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005028set_term_defaults(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005029{
5030 struct vimoption *p;
5031
5032 for (p = &options[0]; p->fullname != NULL; p++)
5033 {
5034 if (istermoption(p) && p->def_val[VI_DEFAULT] != *(char_u **)(p->var))
5035 {
5036 if (p->flags & P_DEF_ALLOCED)
5037 {
5038 free_string_option(p->def_val[VI_DEFAULT]);
5039 p->flags &= ~P_DEF_ALLOCED;
5040 }
5041 p->def_val[VI_DEFAULT] = *(char_u **)(p->var);
5042 if (p->flags & P_ALLOCED)
5043 {
5044 p->flags |= P_DEF_ALLOCED;
5045 p->flags &= ~P_ALLOCED; /* don't free the value now */
5046 }
5047 }
5048 }
5049}
5050
5051/*
5052 * return TRUE if 'p' starts with 't_'
5053 */
5054 static int
Bram Moolenaar9b578142016-01-30 19:39:49 +01005055istermoption(struct vimoption *p)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005056{
5057 return (p->fullname[0] == 't' && p->fullname[1] == '_');
5058}
5059
Bram Moolenaardac13472019-09-16 21:06:21 +02005060/*
5061 * Returns TRUE if the option at 'opt_idx' starts with 't_'
5062 */
5063 int
5064istermoption_idx(int opt_idx)
5065{
5066 return istermoption(&options[opt_idx]);
5067}
5068
Bram Moolenaar113e1072019-01-20 15:30:40 +01005069#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005070/*
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005071 * Unset local option value, similar to ":set opt<".
5072 */
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005073 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005074unset_global_local_option(char_u *name, void *from)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005075{
5076 struct vimoption *p;
5077 int opt_idx;
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005078 buf_T *buf = (buf_T *)from;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005079
5080 opt_idx = findoption(name);
Bram Moolenaarbd8539a2015-08-11 18:53:03 +02005081 if (opt_idx < 0)
5082 return;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005083 p = &(options[opt_idx]);
5084
5085 switch ((int)p->indir)
5086 {
5087 /* global option with local value: use local value if it's been set */
5088 case PV_EP:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005089 clear_string_option(&buf->b_p_ep);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005090 break;
5091 case PV_KP:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005092 clear_string_option(&buf->b_p_kp);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005093 break;
5094 case PV_PATH:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005095 clear_string_option(&buf->b_p_path);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005096 break;
5097 case PV_AR:
5098 buf->b_p_ar = -1;
5099 break;
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02005100 case PV_BKC:
5101 clear_string_option(&buf->b_p_bkc);
5102 buf->b_bkc_flags = 0;
5103 break;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005104 case PV_TAGS:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005105 clear_string_option(&buf->b_p_tags);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005106 break;
Bram Moolenaar0f6562e2015-11-24 18:48:14 +01005107 case PV_TC:
5108 clear_string_option(&buf->b_p_tc);
5109 buf->b_tc_flags = 0;
5110 break;
Bram Moolenaar375e3392019-01-31 18:26:10 +01005111 case PV_SISO:
5112 curwin->w_p_siso = -1;
5113 break;
5114 case PV_SO:
5115 curwin->w_p_so = -1;
5116 break;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005117#ifdef FEAT_FIND_ID
5118 case PV_DEF:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005119 clear_string_option(&buf->b_p_def);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005120 break;
5121 case PV_INC:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005122 clear_string_option(&buf->b_p_inc);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005123 break;
5124#endif
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005125 case PV_DICT:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005126 clear_string_option(&buf->b_p_dict);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005127 break;
5128 case PV_TSR:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005129 clear_string_option(&buf->b_p_tsr);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005130 break;
Bram Moolenaar9be7c042017-01-14 14:28:30 +01005131 case PV_FP:
5132 clear_string_option(&buf->b_p_fp);
5133 break;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005134#ifdef FEAT_QUICKFIX
5135 case PV_EFM:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005136 clear_string_option(&buf->b_p_efm);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005137 break;
5138 case PV_GP:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005139 clear_string_option(&buf->b_p_gp);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005140 break;
5141 case PV_MP:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005142 clear_string_option(&buf->b_p_mp);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005143 break;
5144#endif
5145#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
5146 case PV_BEXPR:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005147 clear_string_option(&buf->b_p_bexpr);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005148 break;
5149#endif
5150#if defined(FEAT_CRYPT)
5151 case PV_CM:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005152 clear_string_option(&buf->b_p_cm);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005153 break;
5154#endif
5155#ifdef FEAT_STL_OPT
5156 case PV_STL:
Bram Moolenaar51ac8a22013-05-06 06:45:47 +02005157 clear_string_option(&((win_T *)from)->w_p_stl);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005158 break;
5159#endif
Bram Moolenaarf5a2fd82013-11-06 05:26:15 +01005160 case PV_UL:
5161 buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
5162 break;
Bram Moolenaaraf6c1312014-03-12 18:55:58 +01005163#ifdef FEAT_LISP
5164 case PV_LW:
5165 clear_string_option(&buf->b_p_lw);
5166 break;
5167#endif
Bram Moolenaar2c7292d2017-03-05 17:43:31 +01005168 case PV_MENC:
5169 clear_string_option(&buf->b_p_menc);
5170 break;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005171 }
5172}
Bram Moolenaar113e1072019-01-20 15:30:40 +01005173#endif
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005174
5175/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005176 * Get pointer to option variable, depending on local or global scope.
5177 */
5178 static char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01005179get_varp_scope(struct vimoption *p, int opt_flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005180{
5181 if ((opt_flags & OPT_GLOBAL) && p->indir != PV_NONE)
5182 {
5183 if (p->var == VAR_WIN)
5184 return (char_u *)GLOBAL_WO(get_varp(p));
5185 return p->var;
5186 }
Bram Moolenaara23ccb82006-02-27 00:08:02 +00005187 if ((opt_flags & OPT_LOCAL) && ((int)p->indir & PV_BOTH))
Bram Moolenaar071d4272004-06-13 20:20:40 +00005188 {
5189 switch ((int)p->indir)
5190 {
Bram Moolenaar9be7c042017-01-14 14:28:30 +01005191 case PV_FP: return (char_u *)&(curbuf->b_p_fp);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005192#ifdef FEAT_QUICKFIX
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005193 case PV_EFM: return (char_u *)&(curbuf->b_p_efm);
5194 case PV_GP: return (char_u *)&(curbuf->b_p_gp);
5195 case PV_MP: return (char_u *)&(curbuf->b_p_mp);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005196#endif
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005197 case PV_EP: return (char_u *)&(curbuf->b_p_ep);
5198 case PV_KP: return (char_u *)&(curbuf->b_p_kp);
5199 case PV_PATH: return (char_u *)&(curbuf->b_p_path);
Bram Moolenaara23ccb82006-02-27 00:08:02 +00005200 case PV_AR: return (char_u *)&(curbuf->b_p_ar);
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005201 case PV_TAGS: return (char_u *)&(curbuf->b_p_tags);
Bram Moolenaar0f6562e2015-11-24 18:48:14 +01005202 case PV_TC: return (char_u *)&(curbuf->b_p_tc);
Bram Moolenaar375e3392019-01-31 18:26:10 +01005203 case PV_SISO: return (char_u *)&(curwin->w_p_siso);
5204 case PV_SO: return (char_u *)&(curwin->w_p_so);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005205#ifdef FEAT_FIND_ID
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005206 case PV_DEF: return (char_u *)&(curbuf->b_p_def);
5207 case PV_INC: return (char_u *)&(curbuf->b_p_inc);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005208#endif
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005209 case PV_DICT: return (char_u *)&(curbuf->b_p_dict);
5210 case PV_TSR: return (char_u *)&(curbuf->b_p_tsr);
Bram Moolenaar9b2200a2006-03-20 21:55:45 +00005211#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
5212 case PV_BEXPR: return (char_u *)&(curbuf->b_p_bexpr);
5213#endif
Bram Moolenaar49771f42010-07-20 17:32:38 +02005214#if defined(FEAT_CRYPT)
5215 case PV_CM: return (char_u *)&(curbuf->b_p_cm);
5216#endif
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005217#ifdef FEAT_STL_OPT
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005218 case PV_STL: return (char_u *)&(curwin->w_p_stl);
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005219#endif
Bram Moolenaarf5a2fd82013-11-06 05:26:15 +01005220 case PV_UL: return (char_u *)&(curbuf->b_p_ul);
Bram Moolenaaraf6c1312014-03-12 18:55:58 +01005221#ifdef FEAT_LISP
5222 case PV_LW: return (char_u *)&(curbuf->b_p_lw);
5223#endif
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02005224 case PV_BKC: return (char_u *)&(curbuf->b_p_bkc);
Bram Moolenaar2c7292d2017-03-05 17:43:31 +01005225 case PV_MENC: return (char_u *)&(curbuf->b_p_menc);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005226 }
5227 return NULL; /* "cannot happen" */
5228 }
5229 return get_varp(p);
5230}
5231
5232/*
Bram Moolenaardac13472019-09-16 21:06:21 +02005233 * Get pointer to option variable at 'opt_idx', depending on local or global
5234 * scope.
5235 */
5236 char_u *
5237get_option_varp_scope(int opt_idx, int opt_flags)
5238{
5239 return get_varp_scope(&(options[opt_idx]), opt_flags);
5240}
5241
5242/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005243 * Get pointer to option variable.
5244 */
5245 static char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01005246get_varp(struct vimoption *p)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005247{
5248 /* hidden option, always return NULL */
5249 if (p->var == NULL)
5250 return NULL;
5251
5252 switch ((int)p->indir)
5253 {
5254 case PV_NONE: return p->var;
5255
5256 /* global option with local value: use local value if it's been set */
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005257 case PV_EP: return *curbuf->b_p_ep != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005258 ? (char_u *)&curbuf->b_p_ep : p->var;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005259 case PV_KP: return *curbuf->b_p_kp != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005260 ? (char_u *)&curbuf->b_p_kp : p->var;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005261 case PV_PATH: return *curbuf->b_p_path != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005262 ? (char_u *)&(curbuf->b_p_path) : p->var;
Bram Moolenaara23ccb82006-02-27 00:08:02 +00005263 case PV_AR: return curbuf->b_p_ar >= 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00005264 ? (char_u *)&(curbuf->b_p_ar) : p->var;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005265 case PV_TAGS: return *curbuf->b_p_tags != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005266 ? (char_u *)&(curbuf->b_p_tags) : p->var;
Bram Moolenaar0f6562e2015-11-24 18:48:14 +01005267 case PV_TC: return *curbuf->b_p_tc != NUL
5268 ? (char_u *)&(curbuf->b_p_tc) : p->var;
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02005269 case PV_BKC: return *curbuf->b_p_bkc != NUL
5270 ? (char_u *)&(curbuf->b_p_bkc) : p->var;
Bram Moolenaar375e3392019-01-31 18:26:10 +01005271 case PV_SISO: return curwin->w_p_siso >= 0
5272 ? (char_u *)&(curwin->w_p_siso) : p->var;
5273 case PV_SO: return curwin->w_p_so >= 0
5274 ? (char_u *)&(curwin->w_p_so) : p->var;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005275#ifdef FEAT_FIND_ID
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005276 case PV_DEF: return *curbuf->b_p_def != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005277 ? (char_u *)&(curbuf->b_p_def) : p->var;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005278 case PV_INC: return *curbuf->b_p_inc != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005279 ? (char_u *)&(curbuf->b_p_inc) : p->var;
5280#endif
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005281 case PV_DICT: return *curbuf->b_p_dict != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005282 ? (char_u *)&(curbuf->b_p_dict) : p->var;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005283 case PV_TSR: return *curbuf->b_p_tsr != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005284 ? (char_u *)&(curbuf->b_p_tsr) : p->var;
Bram Moolenaar9be7c042017-01-14 14:28:30 +01005285 case PV_FP: return *curbuf->b_p_fp != NUL
5286 ? (char_u *)&(curbuf->b_p_fp) : p->var;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005287#ifdef FEAT_QUICKFIX
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005288 case PV_EFM: return *curbuf->b_p_efm != NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +00005289 ? (char_u *)&(curbuf->b_p_efm) : p->var;
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005290 case PV_GP: return *curbuf->b_p_gp != NUL
5291 ? (char_u *)&(curbuf->b_p_gp) : p->var;
5292 case PV_MP: return *curbuf->b_p_mp != NUL
5293 ? (char_u *)&(curbuf->b_p_mp) : p->var;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005294#endif
Bram Moolenaar9b2200a2006-03-20 21:55:45 +00005295#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
5296 case PV_BEXPR: return *curbuf->b_p_bexpr != NUL
5297 ? (char_u *)&(curbuf->b_p_bexpr) : p->var;
5298#endif
Bram Moolenaar49771f42010-07-20 17:32:38 +02005299#if defined(FEAT_CRYPT)
5300 case PV_CM: return *curbuf->b_p_cm != NUL
5301 ? (char_u *)&(curbuf->b_p_cm) : p->var;
5302#endif
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005303#ifdef FEAT_STL_OPT
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005304 case PV_STL: return *curwin->w_p_stl != NUL
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005305 ? (char_u *)&(curwin->w_p_stl) : p->var;
5306#endif
Bram Moolenaarf5a2fd82013-11-06 05:26:15 +01005307 case PV_UL: return curbuf->b_p_ul != NO_LOCAL_UNDOLEVEL
5308 ? (char_u *)&(curbuf->b_p_ul) : p->var;
Bram Moolenaaraf6c1312014-03-12 18:55:58 +01005309#ifdef FEAT_LISP
5310 case PV_LW: return *curbuf->b_p_lw != NUL
5311 ? (char_u *)&(curbuf->b_p_lw) : p->var;
5312#endif
Bram Moolenaar2c7292d2017-03-05 17:43:31 +01005313 case PV_MENC: return *curbuf->b_p_menc != NUL
5314 ? (char_u *)&(curbuf->b_p_menc) : p->var;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005315#ifdef FEAT_ARABIC
5316 case PV_ARAB: return (char_u *)&(curwin->w_p_arab);
5317#endif
5318 case PV_LIST: return (char_u *)&(curwin->w_p_list);
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005319#ifdef FEAT_SPELL
Bram Moolenaar217ad922005-03-20 22:37:15 +00005320 case PV_SPELL: return (char_u *)&(curwin->w_p_spell);
5321#endif
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005322#ifdef FEAT_SYN_HL
5323 case PV_CUC: return (char_u *)&(curwin->w_p_cuc);
5324 case PV_CUL: return (char_u *)&(curwin->w_p_cul);
Bram Moolenaar410e98a2019-09-09 22:05:49 +02005325 case PV_CULOPT: return (char_u *)&(curwin->w_p_culopt);
Bram Moolenaar1a384422010-07-14 19:53:30 +02005326 case PV_CC: return (char_u *)&(curwin->w_p_cc);
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005327#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005328#ifdef FEAT_DIFF
5329 case PV_DIFF: return (char_u *)&(curwin->w_p_diff);
5330#endif
5331#ifdef FEAT_FOLDING
5332 case PV_FDC: return (char_u *)&(curwin->w_p_fdc);
5333 case PV_FEN: return (char_u *)&(curwin->w_p_fen);
5334 case PV_FDI: return (char_u *)&(curwin->w_p_fdi);
5335 case PV_FDL: return (char_u *)&(curwin->w_p_fdl);
5336 case PV_FDM: return (char_u *)&(curwin->w_p_fdm);
5337 case PV_FML: return (char_u *)&(curwin->w_p_fml);
5338 case PV_FDN: return (char_u *)&(curwin->w_p_fdn);
5339# ifdef FEAT_EVAL
5340 case PV_FDE: return (char_u *)&(curwin->w_p_fde);
5341 case PV_FDT: return (char_u *)&(curwin->w_p_fdt);
5342# endif
5343 case PV_FMR: return (char_u *)&(curwin->w_p_fmr);
5344#endif
5345 case PV_NU: return (char_u *)&(curwin->w_p_nu);
Bram Moolenaar64486672010-05-16 15:46:46 +02005346 case PV_RNU: return (char_u *)&(curwin->w_p_rnu);
Bram Moolenaar592e0a22004-07-03 16:05:59 +00005347#ifdef FEAT_LINEBREAK
5348 case PV_NUW: return (char_u *)&(curwin->w_p_nuw);
5349#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005350 case PV_WFH: return (char_u *)&(curwin->w_p_wfh);
Bram Moolenaar97b2ad32006-03-18 21:40:56 +00005351 case PV_WFW: return (char_u *)&(curwin->w_p_wfw);
Bram Moolenaar4033c552017-09-16 20:54:51 +02005352#if defined(FEAT_QUICKFIX)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005353 case PV_PVW: return (char_u *)&(curwin->w_p_pvw);
5354#endif
5355#ifdef FEAT_RIGHTLEFT
5356 case PV_RL: return (char_u *)&(curwin->w_p_rl);
5357 case PV_RLC: return (char_u *)&(curwin->w_p_rlc);
5358#endif
5359 case PV_SCROLL: return (char_u *)&(curwin->w_p_scr);
5360 case PV_WRAP: return (char_u *)&(curwin->w_p_wrap);
5361#ifdef FEAT_LINEBREAK
5362 case PV_LBR: return (char_u *)&(curwin->w_p_lbr);
Bram Moolenaar597a4222014-06-25 14:39:50 +02005363 case PV_BRI: return (char_u *)&(curwin->w_p_bri);
5364 case PV_BRIOPT: return (char_u *)&(curwin->w_p_briopt);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005365#endif
Bram Moolenaar4d784b22019-05-25 19:51:39 +02005366 case PV_WCR: return (char_u *)&(curwin->w_p_wcr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005367 case PV_SCBIND: return (char_u *)&(curwin->w_p_scb);
Bram Moolenaar860cae12010-06-05 23:22:07 +02005368 case PV_CRBIND: return (char_u *)&(curwin->w_p_crb);
Bram Moolenaar860cae12010-06-05 23:22:07 +02005369#ifdef FEAT_CONCEAL
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005370 case PV_COCU: return (char_u *)&(curwin->w_p_cocu);
5371 case PV_COLE: return (char_u *)&(curwin->w_p_cole);
5372#endif
5373#ifdef FEAT_TERMINAL
Bram Moolenaar6d150f72018-04-21 20:03:20 +02005374 case PV_TWK: return (char_u *)&(curwin->w_p_twk);
5375 case PV_TWS: return (char_u *)&(curwin->w_p_tws);
5376 case PV_TWSL: return (char_u *)&(curbuf->b_p_twsl);
Bram Moolenaar860cae12010-06-05 23:22:07 +02005377#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005378
5379 case PV_AI: return (char_u *)&(curbuf->b_p_ai);
5380 case PV_BIN: return (char_u *)&(curbuf->b_p_bin);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005381 case PV_BOMB: return (char_u *)&(curbuf->b_p_bomb);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005382 case PV_BH: return (char_u *)&(curbuf->b_p_bh);
5383 case PV_BT: return (char_u *)&(curbuf->b_p_bt);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005384 case PV_BL: return (char_u *)&(curbuf->b_p_bl);
5385 case PV_CI: return (char_u *)&(curbuf->b_p_ci);
5386#ifdef FEAT_CINDENT
5387 case PV_CIN: return (char_u *)&(curbuf->b_p_cin);
5388 case PV_CINK: return (char_u *)&(curbuf->b_p_cink);
5389 case PV_CINO: return (char_u *)&(curbuf->b_p_cino);
5390#endif
5391#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
5392 case PV_CINW: return (char_u *)&(curbuf->b_p_cinw);
5393#endif
5394#ifdef FEAT_COMMENTS
5395 case PV_COM: return (char_u *)&(curbuf->b_p_com);
5396#endif
5397#ifdef FEAT_FOLDING
5398 case PV_CMS: return (char_u *)&(curbuf->b_p_cms);
5399#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005400 case PV_CPT: return (char_u *)&(curbuf->b_p_cpt);
Bram Moolenaare2c453d2019-08-21 14:37:09 +02005401#ifdef BACKSLASH_IN_FILENAME
Bram Moolenaarac3150d2019-07-28 16:36:39 +02005402 case PV_CSL: return (char_u *)&(curbuf->b_p_csl);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005403#endif
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00005404#ifdef FEAT_COMPL_FUNC
5405 case PV_CFU: return (char_u *)&(curbuf->b_p_cfu);
Bram Moolenaare344bea2005-09-01 20:46:49 +00005406 case PV_OFU: return (char_u *)&(curbuf->b_p_ofu);
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00005407#endif
Bram Moolenaar45e18cb2019-04-28 18:05:35 +02005408#ifdef FEAT_EVAL
5409 case PV_TFU: return (char_u *)&(curbuf->b_p_tfu);
5410#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005411 case PV_EOL: return (char_u *)&(curbuf->b_p_eol);
Bram Moolenaar34d72d42015-07-17 14:18:08 +02005412 case PV_FIXEOL: return (char_u *)&(curbuf->b_p_fixeol);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005413 case PV_ET: return (char_u *)&(curbuf->b_p_et);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005414 case PV_FENC: return (char_u *)&(curbuf->b_p_fenc);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005415 case PV_FF: return (char_u *)&(curbuf->b_p_ff);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005416 case PV_FT: return (char_u *)&(curbuf->b_p_ft);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005417 case PV_FO: return (char_u *)&(curbuf->b_p_fo);
Bram Moolenaar86b68352004-12-27 21:59:20 +00005418 case PV_FLP: return (char_u *)&(curbuf->b_p_flp);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005419 case PV_IMI: return (char_u *)&(curbuf->b_p_iminsert);
5420 case PV_IMS: return (char_u *)&(curbuf->b_p_imsearch);
5421 case PV_INF: return (char_u *)&(curbuf->b_p_inf);
5422 case PV_ISK: return (char_u *)&(curbuf->b_p_isk);
5423#ifdef FEAT_FIND_ID
5424# ifdef FEAT_EVAL
5425 case PV_INEX: return (char_u *)&(curbuf->b_p_inex);
5426# endif
5427#endif
5428#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
5429 case PV_INDE: return (char_u *)&(curbuf->b_p_inde);
5430 case PV_INDK: return (char_u *)&(curbuf->b_p_indk);
5431#endif
Bram Moolenaar5e3cb7e2006-02-27 23:58:35 +00005432#ifdef FEAT_EVAL
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +00005433 case PV_FEX: return (char_u *)&(curbuf->b_p_fex);
5434#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005435#ifdef FEAT_CRYPT
5436 case PV_KEY: return (char_u *)&(curbuf->b_p_key);
5437#endif
5438#ifdef FEAT_LISP
5439 case PV_LISP: return (char_u *)&(curbuf->b_p_lisp);
5440#endif
5441 case PV_ML: return (char_u *)&(curbuf->b_p_ml);
5442 case PV_MPS: return (char_u *)&(curbuf->b_p_mps);
5443 case PV_MA: return (char_u *)&(curbuf->b_p_ma);
5444 case PV_MOD: return (char_u *)&(curbuf->b_changed);
5445 case PV_NF: return (char_u *)&(curbuf->b_p_nf);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005446 case PV_PI: return (char_u *)&(curbuf->b_p_pi);
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00005447#ifdef FEAT_TEXTOBJ
5448 case PV_QE: return (char_u *)&(curbuf->b_p_qe);
5449#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005450 case PV_RO: return (char_u *)&(curbuf->b_p_ro);
5451#ifdef FEAT_SMARTINDENT
5452 case PV_SI: return (char_u *)&(curbuf->b_p_si);
5453#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005454 case PV_SN: return (char_u *)&(curbuf->b_p_sn);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005455 case PV_STS: return (char_u *)&(curbuf->b_p_sts);
5456#ifdef FEAT_SEARCHPATH
5457 case PV_SUA: return (char_u *)&(curbuf->b_p_sua);
5458#endif
5459 case PV_SWF: return (char_u *)&(curbuf->b_p_swf);
5460#ifdef FEAT_SYN_HL
Bram Moolenaar3b56eb32005-07-11 22:40:32 +00005461 case PV_SMC: return (char_u *)&(curbuf->b_p_smc);
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005462 case PV_SYN: return (char_u *)&(curbuf->b_p_syn);
5463#endif
5464#ifdef FEAT_SPELL
Bram Moolenaar860cae12010-06-05 23:22:07 +02005465 case PV_SPC: return (char_u *)&(curwin->w_s->b_p_spc);
5466 case PV_SPF: return (char_u *)&(curwin->w_s->b_p_spf);
5467 case PV_SPL: return (char_u *)&(curwin->w_s->b_p_spl);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005468#endif
5469 case PV_SW: return (char_u *)&(curbuf->b_p_sw);
5470 case PV_TS: return (char_u *)&(curbuf->b_p_ts);
5471 case PV_TW: return (char_u *)&(curbuf->b_p_tw);
5472 case PV_TX: return (char_u *)&(curbuf->b_p_tx);
Bram Moolenaar55debbe2010-05-23 23:34:36 +02005473#ifdef FEAT_PERSISTENT_UNDO
5474 case PV_UDF: return (char_u *)&(curbuf->b_p_udf);
5475#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005476 case PV_WM: return (char_u *)&(curbuf->b_p_wm);
5477#ifdef FEAT_KEYMAP
5478 case PV_KMAP: return (char_u *)&(curbuf->b_p_keymap);
5479#endif
Bram Moolenaar95ec9d62016-08-12 18:29:59 +02005480#ifdef FEAT_SIGNS
5481 case PV_SCL: return (char_u *)&(curwin->w_p_scl);
5482#endif
Bram Moolenaar04958cb2018-06-23 19:23:02 +02005483#ifdef FEAT_VARTABS
5484 case PV_VSTS: return (char_u *)&(curbuf->b_p_vsts);
5485 case PV_VTS: return (char_u *)&(curbuf->b_p_vts);
5486#endif
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01005487 default: iemsg(_("E356: get_varp ERROR"));
Bram Moolenaar071d4272004-06-13 20:20:40 +00005488 }
5489 /* always return a valid pointer to avoid a crash! */
5490 return (char_u *)&(curbuf->b_p_wm);
5491}
5492
5493/*
Bram Moolenaardac13472019-09-16 21:06:21 +02005494 * Return a pointer to the variable for option at 'opt_idx'
5495 */
5496 char_u *
5497get_option_var(int opt_idx)
5498{
5499 return options[opt_idx].var;
5500}
5501
5502/*
5503 * Return the full name of the option at 'opt_idx'
5504 */
5505 char_u *
5506get_option_fullname(int opt_idx)
5507{
5508 return (char_u *)options[opt_idx].fullname;
5509}
5510
5511/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005512 * Get the value of 'equalprg', either the buffer-local one or the global one.
5513 */
5514 char_u *
Bram Moolenaar9b578142016-01-30 19:39:49 +01005515get_equalprg(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005516{
5517 if (*curbuf->b_p_ep == NUL)
5518 return p_ep;
5519 return curbuf->b_p_ep;
5520}
5521
Bram Moolenaar071d4272004-06-13 20:20:40 +00005522/*
5523 * Copy options from one window to another.
5524 * Used when splitting a window.
5525 */
5526 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005527win_copy_options(win_T *wp_from, win_T *wp_to)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005528{
5529 copy_winopt(&wp_from->w_onebuf_opt, &wp_to->w_onebuf_opt);
5530 copy_winopt(&wp_from->w_allbuf_opt, &wp_to->w_allbuf_opt);
Bram Moolenaar285ed7e2014-08-24 21:39:49 +02005531#if defined(FEAT_LINEBREAK)
5532 briopt_check(wp_to);
5533#endif
Bram Moolenaar017ba072019-09-14 21:01:23 +02005534#ifdef FEAT_SYN_HL
5535 fill_culopt_flags(NULL, wp_to);
5536#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005537}
Bram Moolenaar071d4272004-06-13 20:20:40 +00005538
5539/*
5540 * Copy the options from one winopt_T to another.
5541 * Doesn't free the old option values in "to", use clear_winopt() for that.
5542 * The 'scroll' option is not copied, because it depends on the window height.
5543 * The 'previewwindow' option is reset, there can be only one preview window.
5544 */
5545 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005546copy_winopt(winopt_T *from, winopt_T *to)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005547{
5548#ifdef FEAT_ARABIC
5549 to->wo_arab = from->wo_arab;
5550#endif
5551 to->wo_list = from->wo_list;
5552 to->wo_nu = from->wo_nu;
Bram Moolenaar64486672010-05-16 15:46:46 +02005553 to->wo_rnu = from->wo_rnu;
Bram Moolenaar592e0a22004-07-03 16:05:59 +00005554#ifdef FEAT_LINEBREAK
5555 to->wo_nuw = from->wo_nuw;
5556#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005557#ifdef FEAT_RIGHTLEFT
5558 to->wo_rl = from->wo_rl;
5559 to->wo_rlc = vim_strsave(from->wo_rlc);
5560#endif
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005561#ifdef FEAT_STL_OPT
5562 to->wo_stl = vim_strsave(from->wo_stl);
5563#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005564 to->wo_wrap = from->wo_wrap;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005565#ifdef FEAT_DIFF
5566 to->wo_wrap_save = from->wo_wrap_save;
5567#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005568#ifdef FEAT_LINEBREAK
5569 to->wo_lbr = from->wo_lbr;
Bram Moolenaar597a4222014-06-25 14:39:50 +02005570 to->wo_bri = from->wo_bri;
5571 to->wo_briopt = vim_strsave(from->wo_briopt);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005572#endif
Bram Moolenaar4d784b22019-05-25 19:51:39 +02005573 to->wo_wcr = vim_strsave(from->wo_wcr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005574 to->wo_scb = from->wo_scb;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005575 to->wo_scb_save = from->wo_scb_save;
Bram Moolenaar4161dcc2010-12-02 15:33:21 +01005576 to->wo_crb = from->wo_crb;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005577 to->wo_crb_save = from->wo_crb_save;
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005578#ifdef FEAT_SPELL
Bram Moolenaar217ad922005-03-20 22:37:15 +00005579 to->wo_spell = from->wo_spell;
5580#endif
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005581#ifdef FEAT_SYN_HL
5582 to->wo_cuc = from->wo_cuc;
5583 to->wo_cul = from->wo_cul;
Bram Moolenaar410e98a2019-09-09 22:05:49 +02005584 to->wo_culopt = vim_strsave(from->wo_culopt);
Bram Moolenaar1a384422010-07-14 19:53:30 +02005585 to->wo_cc = vim_strsave(from->wo_cc);
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005586#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005587#ifdef FEAT_DIFF
5588 to->wo_diff = from->wo_diff;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005589 to->wo_diff_saved = from->wo_diff_saved;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005590#endif
Bram Moolenaarf5963f72010-07-23 22:10:27 +02005591#ifdef FEAT_CONCEAL
5592 to->wo_cocu = vim_strsave(from->wo_cocu);
Bram Moolenaard497a302010-07-23 22:27:03 +02005593 to->wo_cole = from->wo_cole;
Bram Moolenaarf5963f72010-07-23 22:10:27 +02005594#endif
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005595#ifdef FEAT_TERMINAL
Bram Moolenaar6d150f72018-04-21 20:03:20 +02005596 to->wo_twk = vim_strsave(from->wo_twk);
5597 to->wo_tws = vim_strsave(from->wo_tws);
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005598#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005599#ifdef FEAT_FOLDING
5600 to->wo_fdc = from->wo_fdc;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005601 to->wo_fdc_save = from->wo_fdc_save;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005602 to->wo_fen = from->wo_fen;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005603 to->wo_fen_save = from->wo_fen_save;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005604 to->wo_fdi = vim_strsave(from->wo_fdi);
5605 to->wo_fml = from->wo_fml;
5606 to->wo_fdl = from->wo_fdl;
Bram Moolenaara87aa802013-07-03 15:47:03 +02005607 to->wo_fdl_save = from->wo_fdl_save;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005608 to->wo_fdm = vim_strsave(from->wo_fdm);
Bram Moolenaara87aa802013-07-03 15:47:03 +02005609 to->wo_fdm_save = from->wo_diff_saved
5610 ? vim_strsave(from->wo_fdm_save) : empty_option;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005611 to->wo_fdn = from->wo_fdn;
5612# ifdef FEAT_EVAL
5613 to->wo_fde = vim_strsave(from->wo_fde);
5614 to->wo_fdt = vim_strsave(from->wo_fdt);
5615# endif
5616 to->wo_fmr = vim_strsave(from->wo_fmr);
5617#endif
Bram Moolenaar95ec9d62016-08-12 18:29:59 +02005618#ifdef FEAT_SIGNS
5619 to->wo_scl = vim_strsave(from->wo_scl);
5620#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005621 check_winopt(to); /* don't want NULL pointers */
5622}
5623
5624/*
5625 * Check string options in a window for a NULL value.
5626 */
Bram Moolenaar5843f5f2019-08-20 20:13:45 +02005627 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005628check_win_options(win_T *win)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005629{
5630 check_winopt(&win->w_onebuf_opt);
5631 check_winopt(&win->w_allbuf_opt);
5632}
5633
5634/*
5635 * Check for NULL pointers in a winopt_T and replace them with empty_option.
5636 */
Bram Moolenaar8dc907d2014-06-25 14:44:10 +02005637 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005638check_winopt(winopt_T *wop UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005639{
5640#ifdef FEAT_FOLDING
5641 check_string_option(&wop->wo_fdi);
5642 check_string_option(&wop->wo_fdm);
Bram Moolenaara87aa802013-07-03 15:47:03 +02005643 check_string_option(&wop->wo_fdm_save);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005644# ifdef FEAT_EVAL
5645 check_string_option(&wop->wo_fde);
5646 check_string_option(&wop->wo_fdt);
5647# endif
5648 check_string_option(&wop->wo_fmr);
5649#endif
Bram Moolenaar95ec9d62016-08-12 18:29:59 +02005650#ifdef FEAT_SIGNS
5651 check_string_option(&wop->wo_scl);
5652#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005653#ifdef FEAT_RIGHTLEFT
5654 check_string_option(&wop->wo_rlc);
5655#endif
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005656#ifdef FEAT_STL_OPT
5657 check_string_option(&wop->wo_stl);
5658#endif
Bram Moolenaar1a384422010-07-14 19:53:30 +02005659#ifdef FEAT_SYN_HL
Bram Moolenaar410e98a2019-09-09 22:05:49 +02005660 check_string_option(&wop->wo_culopt);
Bram Moolenaar1a384422010-07-14 19:53:30 +02005661 check_string_option(&wop->wo_cc);
5662#endif
Bram Moolenaarf5963f72010-07-23 22:10:27 +02005663#ifdef FEAT_CONCEAL
5664 check_string_option(&wop->wo_cocu);
5665#endif
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005666#ifdef FEAT_TERMINAL
Bram Moolenaar6d150f72018-04-21 20:03:20 +02005667 check_string_option(&wop->wo_twk);
5668 check_string_option(&wop->wo_tws);
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005669#endif
Bram Moolenaar597a4222014-06-25 14:39:50 +02005670#ifdef FEAT_LINEBREAK
5671 check_string_option(&wop->wo_briopt);
5672#endif
Bram Moolenaar4d784b22019-05-25 19:51:39 +02005673 check_string_option(&wop->wo_wcr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005674}
5675
5676/*
5677 * Free the allocated memory inside a winopt_T.
5678 */
Bram Moolenaar071d4272004-06-13 20:20:40 +00005679 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005680clear_winopt(winopt_T *wop UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005681{
5682#ifdef FEAT_FOLDING
5683 clear_string_option(&wop->wo_fdi);
5684 clear_string_option(&wop->wo_fdm);
Bram Moolenaara87aa802013-07-03 15:47:03 +02005685 clear_string_option(&wop->wo_fdm_save);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005686# ifdef FEAT_EVAL
5687 clear_string_option(&wop->wo_fde);
5688 clear_string_option(&wop->wo_fdt);
5689# endif
5690 clear_string_option(&wop->wo_fmr);
5691#endif
Bram Moolenaar95ec9d62016-08-12 18:29:59 +02005692#ifdef FEAT_SIGNS
5693 clear_string_option(&wop->wo_scl);
5694#endif
Bram Moolenaar597a4222014-06-25 14:39:50 +02005695#ifdef FEAT_LINEBREAK
5696 clear_string_option(&wop->wo_briopt);
5697#endif
Bram Moolenaar4d784b22019-05-25 19:51:39 +02005698 clear_string_option(&wop->wo_wcr);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005699#ifdef FEAT_RIGHTLEFT
5700 clear_string_option(&wop->wo_rlc);
5701#endif
Bram Moolenaarb5bf5b82004-12-24 14:35:23 +00005702#ifdef FEAT_STL_OPT
5703 clear_string_option(&wop->wo_stl);
5704#endif
Bram Moolenaar1a384422010-07-14 19:53:30 +02005705#ifdef FEAT_SYN_HL
Bram Moolenaar410e98a2019-09-09 22:05:49 +02005706 clear_string_option(&wop->wo_culopt);
Bram Moolenaar1a384422010-07-14 19:53:30 +02005707 clear_string_option(&wop->wo_cc);
5708#endif
Bram Moolenaarf5963f72010-07-23 22:10:27 +02005709#ifdef FEAT_CONCEAL
5710 clear_string_option(&wop->wo_cocu);
5711#endif
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005712#ifdef FEAT_TERMINAL
Bram Moolenaar6d150f72018-04-21 20:03:20 +02005713 clear_string_option(&wop->wo_twk);
5714 clear_string_option(&wop->wo_tws);
Bram Moolenaare4f25e42017-07-07 11:54:15 +02005715#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005716}
5717
5718/*
5719 * Copy global option values to local options for one buffer.
5720 * Used when creating a new buffer and sometimes when entering a buffer.
5721 * flags:
5722 * BCO_ENTER We will enter the buf buffer.
5723 * BCO_ALWAYS Always copy the options, but only set b_p_initialized when
5724 * appropriate.
5725 * BCO_NOHELP Don't copy the values to a help buffer.
5726 */
5727 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01005728buf_copy_options(buf_T *buf, int flags)
Bram Moolenaar071d4272004-06-13 20:20:40 +00005729{
5730 int should_copy = TRUE;
5731 char_u *save_p_isk = NULL; /* init for GCC */
5732 int dont_do_help;
5733 int did_isk = FALSE;
5734
5735 /*
Bram Moolenaar071d4272004-06-13 20:20:40 +00005736 * Skip this when the option defaults have not been set yet. Happens when
5737 * main() allocates the first buffer.
5738 */
5739 if (p_cpo != NULL)
5740 {
5741 /*
5742 * Always copy when entering and 'cpo' contains 'S'.
5743 * Don't copy when already initialized.
5744 * Don't copy when 'cpo' contains 's' and not entering.
5745 * 'S' BCO_ENTER initialized 's' should_copy
5746 * yes yes X X TRUE
5747 * yes no yes X FALSE
5748 * no X yes X FALSE
5749 * X no no yes FALSE
5750 * X no no no TRUE
5751 * no yes no X TRUE
5752 */
5753 if ((vim_strchr(p_cpo, CPO_BUFOPTGLOB) == NULL || !(flags & BCO_ENTER))
5754 && (buf->b_p_initialized
5755 || (!(flags & BCO_ENTER)
5756 && vim_strchr(p_cpo, CPO_BUFOPT) != NULL)))
5757 should_copy = FALSE;
5758
5759 if (should_copy || (flags & BCO_ALWAYS))
5760 {
5761 /* Don't copy the options specific to a help buffer when
5762 * BCO_NOHELP is given or the options were initialized already
5763 * (jumping back to a help file with CTRL-T or CTRL-O) */
5764 dont_do_help = ((flags & BCO_NOHELP) && buf->b_help)
5765 || buf->b_p_initialized;
5766 if (dont_do_help) /* don't free b_p_isk */
5767 {
5768 save_p_isk = buf->b_p_isk;
5769 buf->b_p_isk = NULL;
5770 }
5771 /*
Bram Moolenaar40385db2018-08-07 22:31:44 +02005772 * Always free the allocated strings. If not already initialized,
5773 * reset 'readonly' and copy 'fileformat'.
Bram Moolenaar071d4272004-06-13 20:20:40 +00005774 */
5775 if (!buf->b_p_initialized)
5776 {
5777 free_buf_options(buf, TRUE);
5778 buf->b_p_ro = FALSE; /* don't copy readonly */
5779 buf->b_p_tx = p_tx;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005780 buf->b_p_fenc = vim_strsave(p_fenc);
Bram Moolenaare8ef3a02016-10-12 17:45:29 +02005781 switch (*p_ffs)
5782 {
5783 case 'm':
5784 buf->b_p_ff = vim_strsave((char_u *)FF_MAC); break;
5785 case 'd':
5786 buf->b_p_ff = vim_strsave((char_u *)FF_DOS); break;
5787 case 'u':
5788 buf->b_p_ff = vim_strsave((char_u *)FF_UNIX); break;
5789 default:
5790 buf->b_p_ff = vim_strsave(p_ff);
5791 }
5792 if (buf->b_p_ff != NULL)
5793 buf->b_start_ffc = *buf->b_p_ff;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005794 buf->b_p_bh = empty_option;
5795 buf->b_p_bt = empty_option;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005796 }
5797 else
5798 free_buf_options(buf, FALSE);
5799
5800 buf->b_p_ai = p_ai;
5801 buf->b_p_ai_nopaste = p_ai_nopaste;
5802 buf->b_p_sw = p_sw;
5803 buf->b_p_tw = p_tw;
5804 buf->b_p_tw_nopaste = p_tw_nopaste;
5805 buf->b_p_tw_nobin = p_tw_nobin;
5806 buf->b_p_wm = p_wm;
5807 buf->b_p_wm_nopaste = p_wm_nopaste;
5808 buf->b_p_wm_nobin = p_wm_nobin;
5809 buf->b_p_bin = p_bin;
Bram Moolenaare8bb2552005-07-08 22:26:47 +00005810 buf->b_p_bomb = p_bomb;
Bram Moolenaarb388be02015-07-22 22:19:38 +02005811 buf->b_p_fixeol = p_fixeol;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005812 buf->b_p_et = p_et;
5813 buf->b_p_et_nobin = p_et_nobin;
Bram Moolenaar54f018c2015-09-15 17:30:40 +02005814 buf->b_p_et_nopaste = p_et_nopaste;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005815 buf->b_p_ml = p_ml;
5816 buf->b_p_ml_nobin = p_ml_nobin;
5817 buf->b_p_inf = p_inf;
Bram Moolenaar3bab9392017-04-07 15:42:25 +02005818 buf->b_p_swf = cmdmod.noswapfile ? FALSE : p_swf;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005819 buf->b_p_cpt = vim_strsave(p_cpt);
Bram Moolenaare2c453d2019-08-21 14:37:09 +02005820#ifdef BACKSLASH_IN_FILENAME
Bram Moolenaarac3150d2019-07-28 16:36:39 +02005821 buf->b_p_csl = vim_strsave(p_csl);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005822#endif
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00005823#ifdef FEAT_COMPL_FUNC
5824 buf->b_p_cfu = vim_strsave(p_cfu);
Bram Moolenaare344bea2005-09-01 20:46:49 +00005825 buf->b_p_ofu = vim_strsave(p_ofu);
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00005826#endif
Bram Moolenaar45e18cb2019-04-28 18:05:35 +02005827#ifdef FEAT_EVAL
5828 buf->b_p_tfu = vim_strsave(p_tfu);
5829#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005830 buf->b_p_sts = p_sts;
5831 buf->b_p_sts_nopaste = p_sts_nopaste;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02005832#ifdef FEAT_VARTABS
5833 buf->b_p_vsts = vim_strsave(p_vsts);
5834 if (p_vsts && p_vsts != empty_option)
5835 tabstop_set(p_vsts, &buf->b_p_vsts_array);
5836 else
5837 buf->b_p_vsts_array = 0;
5838 buf->b_p_vsts_nopaste = p_vsts_nopaste
5839 ? vim_strsave(p_vsts_nopaste) : NULL;
5840#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005841 buf->b_p_sn = p_sn;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005842#ifdef FEAT_COMMENTS
5843 buf->b_p_com = vim_strsave(p_com);
5844#endif
5845#ifdef FEAT_FOLDING
5846 buf->b_p_cms = vim_strsave(p_cms);
5847#endif
5848 buf->b_p_fo = vim_strsave(p_fo);
Bram Moolenaar86b68352004-12-27 21:59:20 +00005849 buf->b_p_flp = vim_strsave(p_flp);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005850 buf->b_p_nf = vim_strsave(p_nf);
5851 buf->b_p_mps = vim_strsave(p_mps);
5852#ifdef FEAT_SMARTINDENT
5853 buf->b_p_si = p_si;
5854#endif
5855 buf->b_p_ci = p_ci;
5856#ifdef FEAT_CINDENT
5857 buf->b_p_cin = p_cin;
5858 buf->b_p_cink = vim_strsave(p_cink);
5859 buf->b_p_cino = vim_strsave(p_cino);
5860#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005861 /* Don't copy 'filetype', it must be detected */
5862 buf->b_p_ft = empty_option;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005863 buf->b_p_pi = p_pi;
5864#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
5865 buf->b_p_cinw = vim_strsave(p_cinw);
5866#endif
5867#ifdef FEAT_LISP
5868 buf->b_p_lisp = p_lisp;
5869#endif
5870#ifdef FEAT_SYN_HL
5871 /* Don't copy 'syntax', it must be set */
5872 buf->b_p_syn = empty_option;
Bram Moolenaar3b56eb32005-07-11 22:40:32 +00005873 buf->b_p_smc = p_smc;
Bram Moolenaarb8060fe2016-01-19 22:29:28 +01005874 buf->b_s.b_syn_isk = empty_option;
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00005875#endif
5876#ifdef FEAT_SPELL
Bram Moolenaard5784f92010-10-13 14:05:35 +02005877 buf->b_s.b_p_spc = vim_strsave(p_spc);
Bram Moolenaar860cae12010-06-05 23:22:07 +02005878 (void)compile_cap_prog(&buf->b_s);
5879 buf->b_s.b_p_spf = vim_strsave(p_spf);
5880 buf->b_s.b_p_spl = vim_strsave(p_spl);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005881#endif
5882#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
5883 buf->b_p_inde = vim_strsave(p_inde);
5884 buf->b_p_indk = vim_strsave(p_indk);
5885#endif
Bram Moolenaar9be7c042017-01-14 14:28:30 +01005886 buf->b_p_fp = empty_option;
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +00005887#if defined(FEAT_EVAL)
5888 buf->b_p_fex = vim_strsave(p_fex);
5889#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005890#ifdef FEAT_CRYPT
5891 buf->b_p_key = vim_strsave(p_key);
5892#endif
5893#ifdef FEAT_SEARCHPATH
5894 buf->b_p_sua = vim_strsave(p_sua);
5895#endif
5896#ifdef FEAT_KEYMAP
5897 buf->b_p_keymap = vim_strsave(p_keymap);
5898 buf->b_kmap_state |= KEYMAP_INIT;
5899#endif
Bram Moolenaar6d150f72018-04-21 20:03:20 +02005900#ifdef FEAT_TERMINAL
5901 buf->b_p_twsl = p_twsl;
5902#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005903 /* This isn't really an option, but copying the langmap and IME
5904 * state from the current buffer is better than resetting it. */
5905 buf->b_p_iminsert = p_iminsert;
5906 buf->b_p_imsearch = p_imsearch;
5907
5908 /* options that are normally global but also have a local value
5909 * are not copied, start using the global value */
5910 buf->b_p_ar = -1;
Bram Moolenaarf5a2fd82013-11-06 05:26:15 +01005911 buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02005912 buf->b_p_bkc = empty_option;
5913 buf->b_bkc_flags = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005914#ifdef FEAT_QUICKFIX
5915 buf->b_p_gp = empty_option;
5916 buf->b_p_mp = empty_option;
5917 buf->b_p_efm = empty_option;
5918#endif
5919 buf->b_p_ep = empty_option;
5920 buf->b_p_kp = empty_option;
5921 buf->b_p_path = empty_option;
5922 buf->b_p_tags = empty_option;
Bram Moolenaar0f6562e2015-11-24 18:48:14 +01005923 buf->b_p_tc = empty_option;
5924 buf->b_tc_flags = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005925#ifdef FEAT_FIND_ID
5926 buf->b_p_def = empty_option;
5927 buf->b_p_inc = empty_option;
5928# ifdef FEAT_EVAL
5929 buf->b_p_inex = vim_strsave(p_inex);
5930# endif
5931#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005932 buf->b_p_dict = empty_option;
5933 buf->b_p_tsr = empty_option;
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00005934#ifdef FEAT_TEXTOBJ
5935 buf->b_p_qe = vim_strsave(p_qe);
5936#endif
Bram Moolenaar9b2200a2006-03-20 21:55:45 +00005937#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
5938 buf->b_p_bexpr = empty_option;
5939#endif
Bram Moolenaar49771f42010-07-20 17:32:38 +02005940#if defined(FEAT_CRYPT)
5941 buf->b_p_cm = empty_option;
5942#endif
Bram Moolenaar55debbe2010-05-23 23:34:36 +02005943#ifdef FEAT_PERSISTENT_UNDO
5944 buf->b_p_udf = p_udf;
5945#endif
Bram Moolenaaraf6c1312014-03-12 18:55:58 +01005946#ifdef FEAT_LISP
5947 buf->b_p_lw = empty_option;
5948#endif
Bram Moolenaar2c7292d2017-03-05 17:43:31 +01005949 buf->b_p_menc = empty_option;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005950
5951 /*
5952 * Don't copy the options set by ex_help(), use the saved values,
5953 * when going from a help buffer to a non-help buffer.
5954 * Don't touch these at all when BCO_NOHELP is used and going from
5955 * or to a help buffer.
5956 */
5957 if (dont_do_help)
Bram Moolenaar04958cb2018-06-23 19:23:02 +02005958 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00005959 buf->b_p_isk = save_p_isk;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02005960#ifdef FEAT_VARTABS
5961 if (p_vts && p_vts != empty_option && !buf->b_p_vts_array)
5962 tabstop_set(p_vts, &buf->b_p_vts_array);
5963 else
5964 buf->b_p_vts_array = NULL;
5965#endif
5966 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00005967 else
5968 {
5969 buf->b_p_isk = vim_strsave(p_isk);
5970 did_isk = TRUE;
5971 buf->b_p_ts = p_ts;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02005972#ifdef FEAT_VARTABS
5973 buf->b_p_vts = vim_strsave(p_vts);
5974 if (p_vts && p_vts != empty_option && !buf->b_p_vts_array)
5975 tabstop_set(p_vts, &buf->b_p_vts_array);
5976 else
5977 buf->b_p_vts_array = NULL;
5978#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00005979 buf->b_help = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00005980 if (buf->b_p_bt[0] == 'h')
5981 clear_string_option(&buf->b_p_bt);
Bram Moolenaar071d4272004-06-13 20:20:40 +00005982 buf->b_p_ma = p_ma;
5983 }
5984 }
5985
5986 /*
5987 * When the options should be copied (ignoring BCO_ALWAYS), set the
5988 * flag that indicates that the options have been initialized.
5989 */
5990 if (should_copy)
5991 buf->b_p_initialized = TRUE;
5992 }
5993
5994 check_buf_options(buf); /* make sure we don't have NULLs */
5995 if (did_isk)
5996 (void)buf_init_chartab(buf, FALSE);
5997}
5998
5999/*
6000 * Reset the 'modifiable' option and its default value.
6001 */
6002 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006003reset_modifiable(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006004{
6005 int opt_idx;
6006
6007 curbuf->b_p_ma = FALSE;
6008 p_ma = FALSE;
6009 opt_idx = findoption((char_u *)"ma");
Bram Moolenaarfc1421e2006-04-20 22:17:20 +00006010 if (opt_idx >= 0)
6011 options[opt_idx].def_val[VI_DEFAULT] = FALSE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006012}
6013
6014/*
6015 * Set the global value for 'iminsert' to the local value.
6016 */
6017 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006018set_iminsert_global(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006019{
6020 p_iminsert = curbuf->b_p_iminsert;
6021}
6022
6023/*
6024 * Set the global value for 'imsearch' to the local value.
6025 */
6026 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006027set_imsearch_global(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006028{
6029 p_imsearch = curbuf->b_p_imsearch;
6030}
6031
Bram Moolenaar071d4272004-06-13 20:20:40 +00006032static int expand_option_idx = -1;
6033static char_u expand_option_name[5] = {'t', '_', NUL, NUL, NUL};
6034static int expand_option_flags = 0;
6035
6036 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006037set_context_in_set_cmd(
6038 expand_T *xp,
6039 char_u *arg,
6040 int opt_flags) /* OPT_GLOBAL and/or OPT_LOCAL */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006041{
6042 int nextchar;
6043 long_u flags = 0; /* init for GCC */
6044 int opt_idx = 0; /* init for GCC */
6045 char_u *p;
6046 char_u *s;
6047 int is_term_option = FALSE;
6048 int key;
6049
6050 expand_option_flags = opt_flags;
6051
6052 xp->xp_context = EXPAND_SETTINGS;
6053 if (*arg == NUL)
6054 {
6055 xp->xp_pattern = arg;
6056 return;
6057 }
6058 p = arg + STRLEN(arg) - 1;
6059 if (*p == ' ' && *(p - 1) != '\\')
6060 {
6061 xp->xp_pattern = p + 1;
6062 return;
6063 }
6064 while (p > arg)
6065 {
6066 s = p;
6067 /* count number of backslashes before ' ' or ',' */
6068 if (*p == ' ' || *p == ',')
6069 {
6070 while (s > arg && *(s - 1) == '\\')
6071 --s;
6072 }
6073 /* break at a space with an even number of backslashes */
6074 if (*p == ' ' && ((p - s) & 1) == 0)
6075 {
6076 ++p;
6077 break;
6078 }
6079 --p;
6080 }
Bram Moolenaar2a7b9ee2009-06-16 15:50:33 +00006081 if (STRNCMP(p, "no", 2) == 0 && STRNCMP(p, "novice", 6) != 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006082 {
6083 xp->xp_context = EXPAND_BOOL_SETTINGS;
6084 p += 2;
6085 }
6086 if (STRNCMP(p, "inv", 3) == 0)
6087 {
6088 xp->xp_context = EXPAND_BOOL_SETTINGS;
6089 p += 3;
6090 }
6091 xp->xp_pattern = arg = p;
6092 if (*arg == '<')
6093 {
6094 while (*p != '>')
6095 if (*p++ == NUL) /* expand terminal option name */
6096 return;
6097 key = get_special_key_code(arg + 1);
6098 if (key == 0) /* unknown name */
6099 {
6100 xp->xp_context = EXPAND_NOTHING;
6101 return;
6102 }
6103 nextchar = *++p;
6104 is_term_option = TRUE;
6105 expand_option_name[2] = KEY2TERMCAP0(key);
6106 expand_option_name[3] = KEY2TERMCAP1(key);
6107 }
6108 else
6109 {
6110 if (p[0] == 't' && p[1] == '_')
6111 {
6112 p += 2;
6113 if (*p != NUL)
6114 ++p;
6115 if (*p == NUL)
6116 return; /* expand option name */
6117 nextchar = *++p;
6118 is_term_option = TRUE;
6119 expand_option_name[2] = p[-2];
6120 expand_option_name[3] = p[-1];
6121 }
6122 else
6123 {
6124 /* Allow * wildcard */
6125 while (ASCII_ISALNUM(*p) || *p == '_' || *p == '*')
6126 p++;
6127 if (*p == NUL)
6128 return;
6129 nextchar = *p;
6130 *p = NUL;
6131 opt_idx = findoption(arg);
6132 *p = nextchar;
6133 if (opt_idx == -1 || options[opt_idx].var == NULL)
6134 {
6135 xp->xp_context = EXPAND_NOTHING;
6136 return;
6137 }
6138 flags = options[opt_idx].flags;
6139 if (flags & P_BOOL)
6140 {
6141 xp->xp_context = EXPAND_NOTHING;
6142 return;
6143 }
6144 }
6145 }
6146 /* handle "-=" and "+=" */
6147 if ((nextchar == '-' || nextchar == '+' || nextchar == '^') && p[1] == '=')
6148 {
6149 ++p;
6150 nextchar = '=';
6151 }
6152 if ((nextchar != '=' && nextchar != ':')
6153 || xp->xp_context == EXPAND_BOOL_SETTINGS)
6154 {
6155 xp->xp_context = EXPAND_UNSUCCESSFUL;
6156 return;
6157 }
6158 if (xp->xp_context != EXPAND_BOOL_SETTINGS && p[1] == NUL)
6159 {
6160 xp->xp_context = EXPAND_OLD_SETTING;
6161 if (is_term_option)
6162 expand_option_idx = -1;
6163 else
6164 expand_option_idx = opt_idx;
6165 xp->xp_pattern = p + 1;
6166 return;
6167 }
6168 xp->xp_context = EXPAND_NOTHING;
6169 if (is_term_option || (flags & P_NUM))
6170 return;
6171
6172 xp->xp_pattern = p + 1;
6173
6174 if (flags & P_EXPAND)
6175 {
6176 p = options[opt_idx].var;
6177 if (p == (char_u *)&p_bdir
6178 || p == (char_u *)&p_dir
6179 || p == (char_u *)&p_path
Bram Moolenaarf6fee0e2016-02-21 23:02:49 +01006180 || p == (char_u *)&p_pp
Bram Moolenaar071d4272004-06-13 20:20:40 +00006181 || p == (char_u *)&p_rtp
6182#ifdef FEAT_SEARCHPATH
6183 || p == (char_u *)&p_cdpath
6184#endif
6185#ifdef FEAT_SESSION
6186 || p == (char_u *)&p_vdir
6187#endif
6188 )
6189 {
6190 xp->xp_context = EXPAND_DIRECTORIES;
6191 if (p == (char_u *)&p_path
6192#ifdef FEAT_SEARCHPATH
6193 || p == (char_u *)&p_cdpath
6194#endif
6195 )
6196 xp->xp_backslash = XP_BS_THREE;
6197 else
6198 xp->xp_backslash = XP_BS_ONE;
6199 }
6200 else
6201 {
6202 xp->xp_context = EXPAND_FILES;
6203 /* for 'tags' need three backslashes for a space */
6204 if (p == (char_u *)&p_tags)
6205 xp->xp_backslash = XP_BS_THREE;
6206 else
6207 xp->xp_backslash = XP_BS_ONE;
6208 }
6209 }
6210
6211 /* For an option that is a list of file names, find the start of the
6212 * last file name. */
6213 for (p = arg + STRLEN(arg) - 1; p > xp->xp_pattern; --p)
6214 {
6215 /* count number of backslashes before ' ' or ',' */
6216 if (*p == ' ' || *p == ',')
6217 {
6218 s = p;
6219 while (s > xp->xp_pattern && *(s - 1) == '\\')
6220 --s;
6221 if ((*p == ' ' && (xp->xp_backslash == XP_BS_THREE && (p - s) < 3))
6222 || (*p == ',' && (flags & P_COMMA) && ((p - s) & 1) == 0))
6223 {
6224 xp->xp_pattern = p + 1;
6225 break;
6226 }
6227 }
Bram Moolenaar24bbcfe2005-06-28 23:32:02 +00006228
Bram Moolenaarb9a02fc2006-03-12 22:08:12 +00006229#ifdef FEAT_SPELL
Bram Moolenaar24bbcfe2005-06-28 23:32:02 +00006230 /* for 'spellsuggest' start at "file:" */
6231 if (options[opt_idx].var == (char_u *)&p_sps
6232 && STRNCMP(p, "file:", 5) == 0)
6233 {
6234 xp->xp_pattern = p + 5;
6235 break;
6236 }
6237#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006238 }
6239
6240 return;
6241}
6242
6243 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006244ExpandSettings(
6245 expand_T *xp,
6246 regmatch_T *regmatch,
6247 int *num_file,
6248 char_u ***file)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006249{
6250 int num_normal = 0; /* Nr of matching non-term-code settings */
6251 int num_term = 0; /* Nr of matching terminal code settings */
6252 int opt_idx;
6253 int match;
6254 int count = 0;
6255 char_u *str;
6256 int loop;
6257 int is_term_opt;
6258 char_u name_buf[MAX_KEY_NAME_LEN];
6259 static char *(names[]) = {"all", "termcap"};
6260 int ic = regmatch->rm_ic; /* remember the ignore-case flag */
6261
6262 /* do this loop twice:
6263 * loop == 0: count the number of matching options
6264 * loop == 1: copy the matching options into allocated memory
6265 */
6266 for (loop = 0; loop <= 1; ++loop)
6267 {
6268 regmatch->rm_ic = ic;
6269 if (xp->xp_context != EXPAND_BOOL_SETTINGS)
6270 {
Bram Moolenaar2c4278f2009-05-17 11:33:22 +00006271 for (match = 0; match < (int)(sizeof(names) / sizeof(char *));
6272 ++match)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006273 if (vim_regexec(regmatch, (char_u *)names[match], (colnr_T)0))
6274 {
6275 if (loop == 0)
6276 num_normal++;
6277 else
6278 (*file)[count++] = vim_strsave((char_u *)names[match]);
6279 }
6280 }
6281 for (opt_idx = 0; (str = (char_u *)options[opt_idx].fullname) != NULL;
6282 opt_idx++)
6283 {
6284 if (options[opt_idx].var == NULL)
6285 continue;
6286 if (xp->xp_context == EXPAND_BOOL_SETTINGS
6287 && !(options[opt_idx].flags & P_BOOL))
6288 continue;
Bram Moolenaardac13472019-09-16 21:06:21 +02006289 is_term_opt = istermoption_idx(opt_idx);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006290 if (is_term_opt && num_normal > 0)
6291 continue;
6292 match = FALSE;
6293 if (vim_regexec(regmatch, str, (colnr_T)0)
6294 || (options[opt_idx].shortname != NULL
6295 && vim_regexec(regmatch,
6296 (char_u *)options[opt_idx].shortname, (colnr_T)0)))
6297 match = TRUE;
6298 else if (is_term_opt)
6299 {
6300 name_buf[0] = '<';
6301 name_buf[1] = 't';
6302 name_buf[2] = '_';
6303 name_buf[3] = str[2];
6304 name_buf[4] = str[3];
6305 name_buf[5] = '>';
6306 name_buf[6] = NUL;
6307 if (vim_regexec(regmatch, name_buf, (colnr_T)0))
6308 {
6309 match = TRUE;
6310 str = name_buf;
6311 }
6312 }
6313 if (match)
6314 {
6315 if (loop == 0)
6316 {
6317 if (is_term_opt)
6318 num_term++;
6319 else
6320 num_normal++;
6321 }
6322 else
6323 (*file)[count++] = vim_strsave(str);
6324 }
6325 }
6326 /*
6327 * Check terminal key codes, these are not in the option table
6328 */
6329 if (xp->xp_context != EXPAND_BOOL_SETTINGS && num_normal == 0)
6330 {
6331 for (opt_idx = 0; (str = get_termcode(opt_idx)) != NULL; opt_idx++)
6332 {
6333 if (!isprint(str[0]) || !isprint(str[1]))
6334 continue;
6335
6336 name_buf[0] = 't';
6337 name_buf[1] = '_';
6338 name_buf[2] = str[0];
6339 name_buf[3] = str[1];
6340 name_buf[4] = NUL;
6341
6342 match = FALSE;
6343 if (vim_regexec(regmatch, name_buf, (colnr_T)0))
6344 match = TRUE;
6345 else
6346 {
6347 name_buf[0] = '<';
6348 name_buf[1] = 't';
6349 name_buf[2] = '_';
6350 name_buf[3] = str[0];
6351 name_buf[4] = str[1];
6352 name_buf[5] = '>';
6353 name_buf[6] = NUL;
6354
6355 if (vim_regexec(regmatch, name_buf, (colnr_T)0))
6356 match = TRUE;
6357 }
6358 if (match)
6359 {
6360 if (loop == 0)
6361 num_term++;
6362 else
6363 (*file)[count++] = vim_strsave(name_buf);
6364 }
6365 }
6366
6367 /*
6368 * Check special key names.
6369 */
6370 regmatch->rm_ic = TRUE; /* ignore case here */
6371 for (opt_idx = 0; (str = get_key_name(opt_idx)) != NULL; opt_idx++)
6372 {
6373 name_buf[0] = '<';
6374 STRCPY(name_buf + 1, str);
6375 STRCAT(name_buf, ">");
6376
6377 if (vim_regexec(regmatch, name_buf, (colnr_T)0))
6378 {
6379 if (loop == 0)
6380 num_term++;
6381 else
6382 (*file)[count++] = vim_strsave(name_buf);
6383 }
6384 }
6385 }
6386 if (loop == 0)
6387 {
6388 if (num_normal > 0)
6389 *num_file = num_normal;
6390 else if (num_term > 0)
6391 *num_file = num_term;
6392 else
6393 return OK;
Bram Moolenaarc799fe22019-05-28 23:08:19 +02006394 *file = ALLOC_MULT(char_u *, *num_file);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006395 if (*file == NULL)
6396 {
6397 *file = (char_u **)"";
6398 return FAIL;
6399 }
6400 }
6401 }
6402 return OK;
6403}
6404
6405 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006406ExpandOldSetting(int *num_file, char_u ***file)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006407{
6408 char_u *var = NULL; /* init for GCC */
6409 char_u *buf;
6410
6411 *num_file = 0;
Bram Moolenaarc799fe22019-05-28 23:08:19 +02006412 *file = ALLOC_ONE(char_u *);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006413 if (*file == NULL)
6414 return FAIL;
6415
6416 /*
6417 * For a terminal key code expand_option_idx is < 0.
6418 */
6419 if (expand_option_idx < 0)
6420 {
6421 var = find_termcode(expand_option_name + 2);
6422 if (var == NULL)
6423 expand_option_idx = findoption(expand_option_name);
6424 }
6425
6426 if (expand_option_idx >= 0)
6427 {
6428 /* put string of option value in NameBuff */
6429 option_value2string(&options[expand_option_idx], expand_option_flags);
6430 var = NameBuff;
6431 }
6432 else if (var == NULL)
6433 var = (char_u *)"";
6434
6435 /* A backslash is required before some characters. This is the reverse of
6436 * what happens in do_set(). */
6437 buf = vim_strsave_escaped(var, escape_chars);
6438
6439 if (buf == NULL)
6440 {
Bram Moolenaard23a8232018-02-10 18:45:26 +01006441 VIM_CLEAR(*file);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006442 return FAIL;
6443 }
6444
6445#ifdef BACKSLASH_IN_FILENAME
6446 /* For MS-Windows et al. we don't double backslashes at the start and
6447 * before a file name character. */
Bram Moolenaar91acfff2017-03-12 19:22:36 +01006448 for (var = buf; *var != NUL; MB_PTR_ADV(var))
Bram Moolenaar071d4272004-06-13 20:20:40 +00006449 if (var[0] == '\\' && var[1] == '\\'
6450 && expand_option_idx >= 0
6451 && (options[expand_option_idx].flags & P_EXPAND)
6452 && vim_isfilec(var[2])
6453 && (var[2] != '\\' || (var == buf && var[4] != '\\')))
Bram Moolenaarc1a11ed2008-06-24 22:09:24 +00006454 STRMOVE(var, var + 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006455#endif
6456
6457 *file[0] = buf;
6458 *num_file = 1;
6459 return OK;
6460}
Bram Moolenaar071d4272004-06-13 20:20:40 +00006461
6462/*
6463 * Get the value for the numeric or string option *opp in a nice format into
6464 * NameBuff[]. Must not be called with a hidden option!
6465 */
6466 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006467option_value2string(
6468 struct vimoption *opp,
6469 int opt_flags) /* OPT_GLOBAL and/or OPT_LOCAL */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006470{
6471 char_u *varp;
6472
6473 varp = get_varp_scope(opp, opt_flags);
6474
6475 if (opp->flags & P_NUM)
6476 {
6477 long wc = 0;
6478
6479 if (wc_use_keyname(varp, &wc))
6480 STRCPY(NameBuff, get_special_key_name((int)wc, 0));
6481 else if (wc != 0)
6482 STRCPY(NameBuff, transchar((int)wc));
6483 else
6484 sprintf((char *)NameBuff, "%ld", *(long *)varp);
6485 }
6486 else /* P_STRING */
6487 {
6488 varp = *(char_u **)(varp);
6489 if (varp == NULL) /* just in case */
6490 NameBuff[0] = NUL;
6491#ifdef FEAT_CRYPT
6492 /* don't show the actual value of 'key', only that it's set */
Bram Moolenaareb3593b2006-04-22 22:33:57 +00006493 else if (opp->var == (char_u *)&p_key && *varp)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006494 STRCPY(NameBuff, "*****");
6495#endif
6496 else if (opp->flags & P_EXPAND)
6497 home_replace(NULL, varp, NameBuff, MAXPATHL, FALSE);
6498 /* Translate 'pastetoggle' into special key names */
6499 else if ((char_u **)opp->var == &p_pt)
6500 str2specialbuf(p_pt, NameBuff, MAXPATHL);
6501 else
Bram Moolenaarce0842a2005-07-18 21:58:11 +00006502 vim_strncpy(NameBuff, varp, MAXPATHL - 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006503 }
6504}
6505
6506/*
6507 * Return TRUE if "varp" points to 'wildchar' or 'wildcharm' and it can be
6508 * printed as a keyname.
6509 * "*wcp" is set to the value of the option if it's 'wildchar' or 'wildcharm'.
6510 */
6511 static int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006512wc_use_keyname(char_u *varp, long *wcp)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006513{
6514 if (((long *)varp == &p_wc) || ((long *)varp == &p_wcm))
6515 {
6516 *wcp = *(long *)varp;
6517 if (IS_SPECIAL(*wcp) || find_special_key_in_table((int)*wcp) >= 0)
6518 return TRUE;
6519 }
6520 return FALSE;
6521}
6522
Bram Moolenaar071d4272004-06-13 20:20:40 +00006523/*
6524 * Return TRUE if format option 'x' is in effect.
6525 * Take care of no formatting when 'paste' is set.
6526 */
6527 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006528has_format_option(int x)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006529{
6530 if (p_paste)
6531 return FALSE;
6532 return (vim_strchr(curbuf->b_p_fo, x) != NULL);
6533}
6534
6535/*
6536 * Return TRUE if "x" is present in 'shortmess' option, or
6537 * 'shortmess' contains 'a' and "x" is present in SHM_A.
6538 */
6539 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006540shortmess(int x)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006541{
Bram Moolenaar7f29f7a2012-02-29 13:51:37 +01006542 return p_shm != NULL &&
6543 ( vim_strchr(p_shm, x) != NULL
Bram Moolenaar071d4272004-06-13 20:20:40 +00006544 || (vim_strchr(p_shm, 'a') != NULL
6545 && vim_strchr((char_u *)SHM_A, x) != NULL));
6546}
6547
6548/*
6549 * paste_option_changed() - Called after p_paste was set or reset.
6550 */
6551 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006552paste_option_changed(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006553{
6554 static int old_p_paste = FALSE;
6555 static int save_sm = 0;
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006556 static int save_sta = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006557#ifdef FEAT_CMDL_INFO
6558 static int save_ru = 0;
6559#endif
6560#ifdef FEAT_RIGHTLEFT
6561 static int save_ri = 0;
6562 static int save_hkmap = 0;
6563#endif
6564 buf_T *buf;
6565
6566 if (p_paste)
6567 {
6568 /*
6569 * Paste switched from off to on.
6570 * Save the current values, so they can be restored later.
6571 */
6572 if (!old_p_paste)
6573 {
6574 /* save options for each buffer */
Bram Moolenaar29323592016-07-24 22:04:11 +02006575 FOR_ALL_BUFFERS(buf)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006576 {
6577 buf->b_p_tw_nopaste = buf->b_p_tw;
6578 buf->b_p_wm_nopaste = buf->b_p_wm;
6579 buf->b_p_sts_nopaste = buf->b_p_sts;
6580 buf->b_p_ai_nopaste = buf->b_p_ai;
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006581 buf->b_p_et_nopaste = buf->b_p_et;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02006582#ifdef FEAT_VARTABS
6583 if (buf->b_p_vsts_nopaste)
6584 vim_free(buf->b_p_vsts_nopaste);
6585 buf->b_p_vsts_nopaste = buf->b_p_vsts && buf->b_p_vsts != empty_option
6586 ? vim_strsave(buf->b_p_vsts) : NULL;
6587#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006588 }
6589
6590 /* save global options */
6591 save_sm = p_sm;
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006592 save_sta = p_sta;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006593#ifdef FEAT_CMDL_INFO
6594 save_ru = p_ru;
6595#endif
6596#ifdef FEAT_RIGHTLEFT
6597 save_ri = p_ri;
6598 save_hkmap = p_hkmap;
6599#endif
6600 /* save global values for local buffer options */
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006601 p_ai_nopaste = p_ai;
6602 p_et_nopaste = p_et;
6603 p_sts_nopaste = p_sts;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006604 p_tw_nopaste = p_tw;
6605 p_wm_nopaste = p_wm;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02006606#ifdef FEAT_VARTABS
6607 if (p_vsts_nopaste)
6608 vim_free(p_vsts_nopaste);
6609 p_vsts_nopaste = p_vsts && p_vsts != empty_option ? vim_strsave(p_vsts) : NULL;
6610#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006611 }
6612
6613 /*
6614 * Always set the option values, also when 'paste' is set when it is
6615 * already on.
6616 */
6617 /* set options for each buffer */
Bram Moolenaar29323592016-07-24 22:04:11 +02006618 FOR_ALL_BUFFERS(buf)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006619 {
6620 buf->b_p_tw = 0; /* textwidth is 0 */
6621 buf->b_p_wm = 0; /* wrapmargin is 0 */
6622 buf->b_p_sts = 0; /* softtabstop is 0 */
6623 buf->b_p_ai = 0; /* no auto-indent */
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006624 buf->b_p_et = 0; /* no expandtab */
Bram Moolenaar04958cb2018-06-23 19:23:02 +02006625#ifdef FEAT_VARTABS
6626 if (buf->b_p_vsts)
6627 free_string_option(buf->b_p_vsts);
6628 buf->b_p_vsts = empty_option;
6629 if (buf->b_p_vsts_array)
6630 vim_free(buf->b_p_vsts_array);
6631 buf->b_p_vsts_array = 0;
6632#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006633 }
6634
6635 /* set global options */
6636 p_sm = 0; /* no showmatch */
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006637 p_sta = 0; /* no smarttab */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006638#ifdef FEAT_CMDL_INFO
Bram Moolenaar071d4272004-06-13 20:20:40 +00006639 if (p_ru)
6640 status_redraw_all(); /* redraw to remove the ruler */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006641 p_ru = 0; /* no ruler */
6642#endif
6643#ifdef FEAT_RIGHTLEFT
6644 p_ri = 0; /* no reverse insert */
6645 p_hkmap = 0; /* no Hebrew keyboard */
6646#endif
6647 /* set global values for local buffer options */
6648 p_tw = 0;
6649 p_wm = 0;
6650 p_sts = 0;
6651 p_ai = 0;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02006652#ifdef FEAT_VARTABS
6653 if (p_vsts)
6654 free_string_option(p_vsts);
6655 p_vsts = empty_option;
6656#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006657 }
6658
6659 /*
6660 * Paste switched from on to off: Restore saved values.
6661 */
6662 else if (old_p_paste)
6663 {
6664 /* restore options for each buffer */
Bram Moolenaar29323592016-07-24 22:04:11 +02006665 FOR_ALL_BUFFERS(buf)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006666 {
6667 buf->b_p_tw = buf->b_p_tw_nopaste;
6668 buf->b_p_wm = buf->b_p_wm_nopaste;
6669 buf->b_p_sts = buf->b_p_sts_nopaste;
6670 buf->b_p_ai = buf->b_p_ai_nopaste;
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006671 buf->b_p_et = buf->b_p_et_nopaste;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02006672#ifdef FEAT_VARTABS
6673 if (buf->b_p_vsts)
6674 free_string_option(buf->b_p_vsts);
6675 buf->b_p_vsts = buf->b_p_vsts_nopaste
6676 ? vim_strsave(buf->b_p_vsts_nopaste) : empty_option;
6677 if (buf->b_p_vsts_array)
6678 vim_free(buf->b_p_vsts_array);
6679 if (buf->b_p_vsts && buf->b_p_vsts != empty_option)
6680 tabstop_set(buf->b_p_vsts, &buf->b_p_vsts_array);
6681 else
6682 buf->b_p_vsts_array = 0;
6683#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006684 }
6685
6686 /* restore global options */
6687 p_sm = save_sm;
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006688 p_sta = save_sta;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006689#ifdef FEAT_CMDL_INFO
Bram Moolenaar071d4272004-06-13 20:20:40 +00006690 if (p_ru != save_ru)
6691 status_redraw_all(); /* redraw to draw the ruler */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006692 p_ru = save_ru;
6693#endif
6694#ifdef FEAT_RIGHTLEFT
6695 p_ri = save_ri;
6696 p_hkmap = save_hkmap;
6697#endif
6698 /* set global values for local buffer options */
Bram Moolenaar54f018c2015-09-15 17:30:40 +02006699 p_ai = p_ai_nopaste;
6700 p_et = p_et_nopaste;
6701 p_sts = p_sts_nopaste;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006702 p_tw = p_tw_nopaste;
6703 p_wm = p_wm_nopaste;
Bram Moolenaar04958cb2018-06-23 19:23:02 +02006704#ifdef FEAT_VARTABS
6705 if (p_vsts)
6706 free_string_option(p_vsts);
6707 p_vsts = p_vsts_nopaste ? vim_strsave(p_vsts_nopaste) : empty_option;
6708#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006709 }
6710
6711 old_p_paste = p_paste;
6712}
6713
6714/*
6715 * vimrc_found() - Called when a ".vimrc" or "VIMINIT" has been found.
6716 *
6717 * Reset 'compatible' and set the values for options that didn't get set yet
6718 * to the Vim defaults.
6719 * Don't do this if the 'compatible' option has been set or reset before.
Bram Moolenaar910f66f2006-04-05 20:41:53 +00006720 * When "fname" is not NULL, use it to set $"envname" when it wasn't set yet.
Bram Moolenaar071d4272004-06-13 20:20:40 +00006721 */
6722 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006723vimrc_found(char_u *fname, char_u *envname)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006724{
Bram Moolenaar910f66f2006-04-05 20:41:53 +00006725 int opt_idx;
Bram Moolenaar4c3f5362006-04-11 21:38:50 +00006726 int dofree = FALSE;
Bram Moolenaar910f66f2006-04-05 20:41:53 +00006727 char_u *p;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006728
6729 if (!option_was_set((char_u *)"cp"))
6730 {
6731 p_cp = FALSE;
Bram Moolenaardac13472019-09-16 21:06:21 +02006732 for (opt_idx = 0; !istermoption_idx(opt_idx); opt_idx++)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006733 if (!(options[opt_idx].flags & (P_WAS_SET|P_VI_DEF)))
6734 set_option_default(opt_idx, OPT_FREE, FALSE);
6735 didset_options();
Bram Moolenaare68c25c2015-08-25 15:39:55 +02006736 didset_options2();
Bram Moolenaar071d4272004-06-13 20:20:40 +00006737 }
Bram Moolenaar910f66f2006-04-05 20:41:53 +00006738
6739 if (fname != NULL)
6740 {
6741 p = vim_getenv(envname, &dofree);
6742 if (p == NULL)
6743 {
6744 /* Set $MYVIMRC to the first vimrc file found. */
6745 p = FullName_save(fname, FALSE);
6746 if (p != NULL)
6747 {
6748 vim_setenv(envname, p);
6749 vim_free(p);
6750 }
6751 }
6752 else if (dofree)
6753 vim_free(p);
6754 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00006755}
6756
6757/*
6758 * Set 'compatible' on or off. Called for "-C" and "-N" command line arg.
6759 */
6760 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006761change_compatible(int on)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006762{
Bram Moolenaarfc1421e2006-04-20 22:17:20 +00006763 int opt_idx;
6764
Bram Moolenaar071d4272004-06-13 20:20:40 +00006765 if (p_cp != on)
6766 {
6767 p_cp = on;
6768 compatible_set();
6769 }
Bram Moolenaarfc1421e2006-04-20 22:17:20 +00006770 opt_idx = findoption((char_u *)"cp");
6771 if (opt_idx >= 0)
6772 options[opt_idx].flags |= P_WAS_SET;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006773}
6774
6775/*
6776 * Return TRUE when option "name" has been set.
Bram Moolenaar1a4a75c2013-07-28 16:03:06 +02006777 * Only works correctly for global options.
Bram Moolenaar071d4272004-06-13 20:20:40 +00006778 */
6779 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006780option_was_set(char_u *name)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006781{
6782 int idx;
6783
6784 idx = findoption(name);
6785 if (idx < 0) /* unknown option */
6786 return FALSE;
6787 if (options[idx].flags & P_WAS_SET)
6788 return TRUE;
6789 return FALSE;
6790}
6791
6792/*
Bram Moolenaar15d55de2012-12-05 14:43:02 +01006793 * Reset the flag indicating option "name" was set.
6794 */
Bram Moolenaarfe8ef982018-09-13 20:31:54 +02006795 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006796reset_option_was_set(char_u *name)
Bram Moolenaar15d55de2012-12-05 14:43:02 +01006797{
6798 int idx = findoption(name);
6799
6800 if (idx >= 0)
Bram Moolenaarfe8ef982018-09-13 20:31:54 +02006801 {
Bram Moolenaar15d55de2012-12-05 14:43:02 +01006802 options[idx].flags &= ~P_WAS_SET;
Bram Moolenaarfe8ef982018-09-13 20:31:54 +02006803 return OK;
6804 }
6805 return FAIL;
Bram Moolenaar15d55de2012-12-05 14:43:02 +01006806}
6807
6808/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00006809 * compatible_set() - Called when 'compatible' has been set or unset.
6810 *
6811 * When 'compatible' set: Set all relevant options (those that have the P_VIM)
6812 * flag) to a Vi compatible value.
6813 * When 'compatible' is unset: Set all options that have a different default
6814 * for Vim (without the P_VI_DEF flag) to that default.
6815 */
6816 static void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006817compatible_set(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006818{
6819 int opt_idx;
6820
Bram Moolenaardac13472019-09-16 21:06:21 +02006821 for (opt_idx = 0; !istermoption_idx(opt_idx); opt_idx++)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006822 if ( ((options[opt_idx].flags & P_VIM) && p_cp)
6823 || (!(options[opt_idx].flags & P_VI_DEF) && !p_cp))
6824 set_option_default(opt_idx, OPT_FREE, p_cp);
6825 didset_options();
Bram Moolenaare68c25c2015-08-25 15:39:55 +02006826 didset_options2();
Bram Moolenaar071d4272004-06-13 20:20:40 +00006827}
6828
Bram Moolenaardac13472019-09-16 21:06:21 +02006829#if defined(FEAT_LINEBREAK) || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006830
Bram Moolenaar071d4272004-06-13 20:20:40 +00006831/*
6832 * fill_breakat_flags() -- called when 'breakat' changes value.
6833 */
Bram Moolenaardac13472019-09-16 21:06:21 +02006834 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006835fill_breakat_flags(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006836{
Bram Moolenaarac6e65f2005-08-29 22:25:38 +00006837 char_u *p;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006838 int i;
6839
6840 for (i = 0; i < 256; i++)
6841 breakat_flags[i] = FALSE;
6842
6843 if (p_breakat != NULL)
Bram Moolenaarac6e65f2005-08-29 22:25:38 +00006844 for (p = p_breakat; *p; p++)
6845 breakat_flags[*p] = TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006846}
Bram Moolenaar071d4272004-06-13 20:20:40 +00006847#endif
6848
6849/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00006850 * Read the 'wildmode' option, fill wim_flags[].
6851 */
Bram Moolenaardac13472019-09-16 21:06:21 +02006852 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006853check_opt_wim(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006854{
6855 char_u new_wim_flags[4];
6856 char_u *p;
6857 int i;
6858 int idx = 0;
6859
6860 for (i = 0; i < 4; ++i)
6861 new_wim_flags[i] = 0;
6862
6863 for (p = p_wim; *p; ++p)
6864 {
6865 for (i = 0; ASCII_ISALPHA(p[i]); ++i)
6866 ;
6867 if (p[i] != NUL && p[i] != ',' && p[i] != ':')
6868 return FAIL;
6869 if (i == 7 && STRNCMP(p, "longest", 7) == 0)
6870 new_wim_flags[idx] |= WIM_LONGEST;
6871 else if (i == 4 && STRNCMP(p, "full", 4) == 0)
6872 new_wim_flags[idx] |= WIM_FULL;
6873 else if (i == 4 && STRNCMP(p, "list", 4) == 0)
6874 new_wim_flags[idx] |= WIM_LIST;
6875 else
6876 return FAIL;
6877 p += i;
6878 if (*p == NUL)
6879 break;
6880 if (*p == ',')
6881 {
6882 if (idx == 3)
6883 return FAIL;
6884 ++idx;
6885 }
6886 }
6887
6888 /* fill remaining entries with last flag */
6889 while (idx < 3)
6890 {
6891 new_wim_flags[idx + 1] = new_wim_flags[idx];
6892 ++idx;
6893 }
6894
6895 /* only when there are no errors, wim_flags[] is changed */
6896 for (i = 0; i < 4; ++i)
6897 wim_flags[i] = new_wim_flags[i];
6898 return OK;
6899}
6900
6901/*
6902 * Check if backspacing over something is allowed.
6903 */
6904 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006905can_bs(
6906 int what) /* BS_INDENT, BS_EOL or BS_START */
Bram Moolenaar071d4272004-06-13 20:20:40 +00006907{
Bram Moolenaar6b810d92018-06-04 17:28:44 +02006908#ifdef FEAT_JOB_CHANNEL
6909 if (what == BS_START && bt_prompt(curbuf))
6910 return FALSE;
6911#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00006912 switch (*p_bs)
6913 {
6914 case '2': return TRUE;
6915 case '1': return (what != BS_START);
6916 case '0': return FALSE;
6917 }
6918 return vim_strchr(p_bs, what) != NULL;
6919}
6920
6921/*
6922 * Save the current values of 'fileformat' and 'fileencoding', so that we know
6923 * the file must be considered changed when the value is different.
6924 */
6925 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006926save_file_ff(buf_T *buf)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006927{
6928 buf->b_start_ffc = *buf->b_p_ff;
6929 buf->b_start_eol = buf->b_p_eol;
Bram Moolenaar83eb8852007-08-12 13:51:26 +00006930 buf->b_start_bomb = buf->b_p_bomb;
6931
Bram Moolenaar071d4272004-06-13 20:20:40 +00006932 /* Only use free/alloc when necessary, they take time. */
6933 if (buf->b_start_fenc == NULL
6934 || STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0)
6935 {
6936 vim_free(buf->b_start_fenc);
6937 buf->b_start_fenc = vim_strsave(buf->b_p_fenc);
6938 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00006939}
6940
6941/*
6942 * Return TRUE if 'fileformat' and/or 'fileencoding' has a different value
6943 * from when editing started (save_file_ff() called).
Bram Moolenaar83eb8852007-08-12 13:51:26 +00006944 * Also when 'endofline' was changed and 'binary' is set, or when 'bomb' was
6945 * changed and 'binary' is not set.
Bram Moolenaar34d72d42015-07-17 14:18:08 +02006946 * Also when 'endofline' was changed and 'fixeol' is not set.
Bram Moolenaar164c60f2011-01-22 00:11:50 +01006947 * When "ignore_empty" is true don't consider a new, empty buffer to be
6948 * changed.
Bram Moolenaar071d4272004-06-13 20:20:40 +00006949 */
6950 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01006951file_ff_differs(buf_T *buf, int ignore_empty)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006952{
Bram Moolenaar9cffde92007-07-24 07:51:18 +00006953 /* In a buffer that was never loaded the options are not valid. */
6954 if (buf->b_flags & BF_NEVERLOADED)
6955 return FALSE;
Bram Moolenaar164c60f2011-01-22 00:11:50 +01006956 if (ignore_empty
6957 && (buf->b_flags & BF_NEW)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006958 && buf->b_ml.ml_line_count == 1
6959 && *ml_get_buf(buf, (linenr_T)1, FALSE) == NUL)
6960 return FALSE;
6961 if (buf->b_start_ffc != *buf->b_p_ff)
6962 return TRUE;
Bram Moolenaar34d72d42015-07-17 14:18:08 +02006963 if ((buf->b_p_bin || !buf->b_p_fixeol) && buf->b_start_eol != buf->b_p_eol)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006964 return TRUE;
Bram Moolenaar83eb8852007-08-12 13:51:26 +00006965 if (!buf->b_p_bin && buf->b_start_bomb != buf->b_p_bomb)
6966 return TRUE;
Bram Moolenaar071d4272004-06-13 20:20:40 +00006967 if (buf->b_start_fenc == NULL)
6968 return (*buf->b_p_fenc != NUL);
6969 return (STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0);
Bram Moolenaar071d4272004-06-13 20:20:40 +00006970}
6971
6972/*
Bram Moolenaar375e3392019-01-31 18:26:10 +01006973 * Return the effective 'scrolloff' value for the current window, using the
6974 * global value when appropriate.
6975 */
6976 long
6977get_scrolloff_value(void)
6978{
6979 return curwin->w_p_so < 0 ? p_so : curwin->w_p_so;
6980}
6981
6982/*
6983 * Return the effective 'sidescrolloff' value for the current window, using the
6984 * global value when appropriate.
6985 */
6986 long
6987get_sidescrolloff_value(void)
6988{
6989 return curwin->w_p_siso < 0 ? p_siso : curwin->w_p_siso;
6990}
6991
6992/*
Bram Moolenaar8c7694a2013-01-17 17:02:05 +01006993 * Check matchpairs option for "*initc".
6994 * If there is a match set "*initc" to the matching character and "*findc" to
6995 * the opposite character. Set "*backwards" to the direction.
6996 * When "switchit" is TRUE swap the direction.
6997 */
6998 void
Bram Moolenaar9b578142016-01-30 19:39:49 +01006999find_mps_values(
7000 int *initc,
7001 int *findc,
7002 int *backwards,
7003 int switchit)
Bram Moolenaar8c7694a2013-01-17 17:02:05 +01007004{
7005 char_u *ptr;
7006
7007 ptr = curbuf->b_p_mps;
7008 while (*ptr != NUL)
7009 {
Bram Moolenaar8c7694a2013-01-17 17:02:05 +01007010 if (has_mbyte)
7011 {
7012 char_u *prev;
7013
7014 if (mb_ptr2char(ptr) == *initc)
7015 {
7016 if (switchit)
7017 {
7018 *findc = *initc;
7019 *initc = mb_ptr2char(ptr + mb_ptr2len(ptr) + 1);
7020 *backwards = TRUE;
7021 }
7022 else
7023 {
7024 *findc = mb_ptr2char(ptr + mb_ptr2len(ptr) + 1);
7025 *backwards = FALSE;
7026 }
7027 return;
7028 }
7029 prev = ptr;
7030 ptr += mb_ptr2len(ptr) + 1;
7031 if (mb_ptr2char(ptr) == *initc)
7032 {
7033 if (switchit)
7034 {
7035 *findc = *initc;
7036 *initc = mb_ptr2char(prev);
7037 *backwards = FALSE;
7038 }
7039 else
7040 {
7041 *findc = mb_ptr2char(prev);
7042 *backwards = TRUE;
7043 }
7044 return;
7045 }
7046 ptr += mb_ptr2len(ptr);
7047 }
7048 else
Bram Moolenaar8c7694a2013-01-17 17:02:05 +01007049 {
7050 if (*ptr == *initc)
7051 {
7052 if (switchit)
7053 {
7054 *backwards = TRUE;
7055 *findc = *initc;
7056 *initc = ptr[2];
7057 }
7058 else
7059 {
7060 *backwards = FALSE;
7061 *findc = ptr[2];
7062 }
7063 return;
7064 }
7065 ptr += 2;
7066 if (*ptr == *initc)
7067 {
7068 if (switchit)
7069 {
7070 *backwards = FALSE;
7071 *findc = *initc;
7072 *initc = ptr[-2];
7073 }
7074 else
7075 {
7076 *backwards = TRUE;
7077 *findc = ptr[-2];
7078 }
7079 return;
7080 }
7081 ++ptr;
7082 }
7083 if (*ptr == ',')
7084 ++ptr;
7085 }
7086}
Bram Moolenaar597a4222014-06-25 14:39:50 +02007087
7088#if defined(FEAT_LINEBREAK) || defined(PROTO)
7089/*
7090 * This is called when 'breakindentopt' is changed and when a window is
7091 * initialized.
7092 */
Bram Moolenaardac13472019-09-16 21:06:21 +02007093 int
Bram Moolenaar9b578142016-01-30 19:39:49 +01007094briopt_check(win_T *wp)
Bram Moolenaar597a4222014-06-25 14:39:50 +02007095{
7096 char_u *p;
7097 int bri_shift = 0;
7098 long bri_min = 20;
7099 int bri_sbr = FALSE;
7100
Bram Moolenaar285ed7e2014-08-24 21:39:49 +02007101 p = wp->w_p_briopt;
Bram Moolenaar597a4222014-06-25 14:39:50 +02007102 while (*p != NUL)
7103 {
7104 if (STRNCMP(p, "shift:", 6) == 0
7105 && ((p[6] == '-' && VIM_ISDIGIT(p[7])) || VIM_ISDIGIT(p[6])))
7106 {
7107 p += 6;
7108 bri_shift = getdigits(&p);
7109 }
7110 else if (STRNCMP(p, "min:", 4) == 0 && VIM_ISDIGIT(p[4]))
7111 {
7112 p += 4;
7113 bri_min = getdigits(&p);
7114 }
7115 else if (STRNCMP(p, "sbr", 3) == 0)
7116 {
7117 p += 3;
7118 bri_sbr = TRUE;
7119 }
7120 if (*p != ',' && *p != NUL)
7121 return FAIL;
7122 if (*p == ',')
7123 ++p;
7124 }
7125
Bram Moolenaar285ed7e2014-08-24 21:39:49 +02007126 wp->w_p_brishift = bri_shift;
7127 wp->w_p_brimin = bri_min;
7128 wp->w_p_brisbr = bri_sbr;
Bram Moolenaar597a4222014-06-25 14:39:50 +02007129
7130 return OK;
7131}
7132#endif
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02007133
7134/*
7135 * Get the local or global value of 'backupcopy'.
7136 */
7137 unsigned int
Bram Moolenaar9b578142016-01-30 19:39:49 +01007138get_bkc_value(buf_T *buf)
Bram Moolenaarb8ee25a2014-09-23 15:45:08 +02007139{
7140 return buf->b_bkc_flags ? buf->b_bkc_flags : bkc_flags;
7141}
Bram Moolenaar95ec9d62016-08-12 18:29:59 +02007142
7143#if defined(FEAT_SIGNS) || defined(PROTO)
7144/*
7145 * Return TRUE when window "wp" has a column to draw signs in.
7146 */
7147 int
7148signcolumn_on(win_T *wp)
7149{
Bram Moolenaar394c5d82019-06-17 21:48:05 +02007150 // If 'signcolumn' is set to 'number', signs are displayed in the 'number'
7151 // column (if present). Otherwise signs are to be displayed in the sign
7152 // column.
7153 if (*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u')
7154 return wp->w_buffer->b_signlist != NULL && !wp->w_p_nu && !wp->w_p_rnu;
7155
Bram Moolenaar95ec9d62016-08-12 18:29:59 +02007156 if (*wp->w_p_scl == 'n')
7157 return FALSE;
7158 if (*wp->w_p_scl == 'y')
7159 return TRUE;
7160 return (wp->w_buffer->b_signlist != NULL
7161# ifdef FEAT_NETBEANS_INTG
7162 || wp->w_buffer->b_has_sign_column
7163# endif
7164 );
7165}
7166#endif
Bram Moolenaarb5ae48e2016-08-12 22:23:25 +02007167
7168#if defined(FEAT_EVAL) || defined(PROTO)
7169/*
7170 * Get window or buffer local options.
7171 */
7172 dict_T *
7173get_winbuf_options(int bufopt)
7174{
7175 dict_T *d;
7176 int opt_idx;
7177
7178 d = dict_alloc();
7179 if (d == NULL)
7180 return NULL;
7181
Bram Moolenaardac13472019-09-16 21:06:21 +02007182 for (opt_idx = 0; !istermoption_idx(opt_idx); opt_idx++)
Bram Moolenaarb5ae48e2016-08-12 22:23:25 +02007183 {
7184 struct vimoption *opt = &options[opt_idx];
7185
7186 if ((bufopt && (opt->indir & PV_BUF))
7187 || (!bufopt && (opt->indir & PV_WIN)))
7188 {
7189 char_u *varp = get_varp(opt);
7190
7191 if (varp != NULL)
7192 {
7193 if (opt->flags & P_STRING)
Bram Moolenaare0be1672018-07-08 16:50:37 +02007194 dict_add_string(d, opt->fullname, *(char_u **)varp);
Bram Moolenaar789a5c02016-09-12 19:51:11 +02007195 else if (opt->flags & P_NUM)
Bram Moolenaare0be1672018-07-08 16:50:37 +02007196 dict_add_number(d, opt->fullname, *(long *)varp);
Bram Moolenaarb5ae48e2016-08-12 22:23:25 +02007197 else
Bram Moolenaare0be1672018-07-08 16:50:37 +02007198 dict_add_number(d, opt->fullname, *(int *)varp);
Bram Moolenaarb5ae48e2016-08-12 22:23:25 +02007199 }
7200 }
7201 }
7202
7203 return d;
7204}
7205#endif
Bram Moolenaar017ba072019-09-14 21:01:23 +02007206
Bram Moolenaardac13472019-09-16 21:06:21 +02007207#if defined(FEAT_SYN_HL) || defined(PROTO)
Bram Moolenaar017ba072019-09-14 21:01:23 +02007208/*
7209 * This is called when 'culopt' is changed
7210 */
Bram Moolenaardac13472019-09-16 21:06:21 +02007211 int
Bram Moolenaar017ba072019-09-14 21:01:23 +02007212fill_culopt_flags(char_u *val, win_T *wp)
7213{
7214 char_u *p;
7215 char_u culopt_flags_new = 0;
7216
7217 if (val == NULL)
7218 p = wp->w_p_culopt;
7219 else
7220 p = val;
7221 while (*p != NUL)
7222 {
7223 if (STRNCMP(p, "line", 4) == 0)
7224 {
7225 p += 4;
7226 culopt_flags_new |= CULOPT_LINE;
7227 }
7228 else if (STRNCMP(p, "both", 4) == 0)
7229 {
7230 p += 4;
7231 culopt_flags_new |= CULOPT_LINE | CULOPT_NBR;
7232 }
7233 else if (STRNCMP(p, "number", 6) == 0)
7234 {
7235 p += 6;
7236 culopt_flags_new |= CULOPT_NBR;
7237 }
7238 else if (STRNCMP(p, "screenline", 10) == 0)
7239 {
7240 p += 10;
7241 culopt_flags_new |= CULOPT_SCRLINE;
7242 }
7243
7244 if (*p != ',' && *p != NUL)
7245 return FAIL;
7246 if (*p == ',')
7247 ++p;
7248 }
7249
7250 // Can't have both "line" and "screenline".
7251 if ((culopt_flags_new & CULOPT_LINE) && (culopt_flags_new & CULOPT_SCRLINE))
7252 return FAIL;
7253 wp->w_p_culopt_flags = culopt_flags_new;
7254
7255 return OK;
7256}
7257#endif