1/* vi:set ts=8 sts=4 sw=4:
2 *
3 * VIM - Vi IMproved	by Bram Moolenaar
4 *
5 * Do ":help uganda"  in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9
10/*
11 * Code to handle user-settable options. This is all pretty much table-
12 * driven. Checklist for adding a new option:
13 * - Put it in the options array below (copy an existing entry).
14 * - For a global option: Add a variable for it in option.h.
15 * - For a buffer or window local option:
16 *   - Add a PV_XX entry to the enum below.
17 *   - Add a variable to the window or buffer struct in structs.h.
18 *   - For a window option, add some code to copy_winopt().
19 *   - For a buffer option, add some code to buf_copy_options().
20 *   - For a buffer string option, add code to check_buf_options().
21 * - If it's a numeric option, add any necessary bounds checks to do_set().
22 * - If it's a list of flags, add some code in do_set(), search for WW_ALL.
23 * - When adding an option with expansion (P_EXPAND), but with a different
24 *   default for Vi and Vim (no P_VI_DEF), add some code at VIMEXP.
25 * - Add documentation!  One line in doc/help.txt, full description in
26 *   options.txt, and any other related places.
27 * - Add an entry in runtime/optwin.vim.
28 * When making changes:
29 * - Adjust the help for the option in doc/option.txt.
30 * - When an entry has the P_VIM flag, or is lacking the P_VI_DEF flag, add a
31 *   comment at the help for the 'compatible' option.
32 */
33
34#define IN_OPTION_C
35#include "vim.h"
36
37/*
38 * The options that are local to a window or buffer have "indir" set to one of
39 * these values.  Special values:
40 * PV_NONE: global option.
41 * PV_WIN is added: window-local option
42 * PV_BUF is added: buffer-local option
43 * PV_BOTH is added: global option which also has a local value.
44 */
45#define PV_BOTH 0x1000
46#define PV_WIN  0x2000
47#define PV_BUF  0x4000
48#define PV_MASK 0x0fff
49#define OPT_WIN(x)  (idopt_T)(PV_WIN + (int)(x))
50#define OPT_BUF(x)  (idopt_T)(PV_BUF + (int)(x))
51#define OPT_BOTH(x) (idopt_T)(PV_BOTH + (int)(x))
52
53/*
54 * Definition of the PV_ values for buffer-local options.
55 * The BV_ values are defined in option.h.
56 */
57#define PV_AI		OPT_BUF(BV_AI)
58#define PV_AR		OPT_BOTH(OPT_BUF(BV_AR))
59#ifdef FEAT_QUICKFIX
60# define PV_BH		OPT_BUF(BV_BH)
61# define PV_BT		OPT_BUF(BV_BT)
62# define PV_EFM		OPT_BOTH(OPT_BUF(BV_EFM))
63# define PV_GP		OPT_BOTH(OPT_BUF(BV_GP))
64# define PV_MP		OPT_BOTH(OPT_BUF(BV_MP))
65#endif
66#define PV_BIN		OPT_BUF(BV_BIN)
67#define PV_BL		OPT_BUF(BV_BL)
68#ifdef FEAT_MBYTE
69# define PV_BOMB	OPT_BUF(BV_BOMB)
70#endif
71#define PV_CI		OPT_BUF(BV_CI)
72#ifdef FEAT_CINDENT
73# define PV_CIN		OPT_BUF(BV_CIN)
74# define PV_CINK	OPT_BUF(BV_CINK)
75# define PV_CINO	OPT_BUF(BV_CINO)
76#endif
77#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
78# define PV_CINW	OPT_BUF(BV_CINW)
79#endif
80#define PV_CM		OPT_BOTH(OPT_BUF(BV_CM))
81#ifdef FEAT_FOLDING
82# define PV_CMS		OPT_BUF(BV_CMS)
83#endif
84#ifdef FEAT_COMMENTS
85# define PV_COM		OPT_BUF(BV_COM)
86#endif
87#ifdef FEAT_INS_EXPAND
88# define PV_CPT		OPT_BUF(BV_CPT)
89# define PV_DICT	OPT_BOTH(OPT_BUF(BV_DICT))
90# define PV_TSR		OPT_BOTH(OPT_BUF(BV_TSR))
91#endif
92#ifdef FEAT_COMPL_FUNC
93# define PV_CFU		OPT_BUF(BV_CFU)
94#endif
95#ifdef FEAT_FIND_ID
96# define PV_DEF		OPT_BOTH(OPT_BUF(BV_DEF))
97# define PV_INC		OPT_BOTH(OPT_BUF(BV_INC))
98#endif
99#define PV_EOL		OPT_BUF(BV_EOL)
100#define PV_EP		OPT_BOTH(OPT_BUF(BV_EP))
101#define PV_ET		OPT_BUF(BV_ET)
102#ifdef FEAT_MBYTE
103# define PV_FENC	OPT_BUF(BV_FENC)
104#endif
105#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
106# define PV_BEXPR	OPT_BOTH(OPT_BUF(BV_BEXPR))
107#endif
108#ifdef FEAT_EVAL
109# define PV_FEX		OPT_BUF(BV_FEX)
110#endif
111#define PV_FF		OPT_BUF(BV_FF)
112#define PV_FLP		OPT_BUF(BV_FLP)
113#define PV_FO		OPT_BUF(BV_FO)
114#ifdef FEAT_AUTOCMD
115# define PV_FT		OPT_BUF(BV_FT)
116#endif
117#define PV_IMI		OPT_BUF(BV_IMI)
118#define PV_IMS		OPT_BUF(BV_IMS)
119#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
120# define PV_INDE	OPT_BUF(BV_INDE)
121# define PV_INDK	OPT_BUF(BV_INDK)
122#endif
123#if defined(FEAT_FIND_ID) && defined(FEAT_EVAL)
124# define PV_INEX	OPT_BUF(BV_INEX)
125#endif
126#define PV_INF		OPT_BUF(BV_INF)
127#define PV_ISK		OPT_BUF(BV_ISK)
128#ifdef FEAT_CRYPT
129# define PV_KEY		OPT_BUF(BV_KEY)
130#endif
131#ifdef FEAT_KEYMAP
132# define PV_KMAP	OPT_BUF(BV_KMAP)
133#endif
134#define PV_KP		OPT_BOTH(OPT_BUF(BV_KP))
135#ifdef FEAT_LISP
136# define PV_LISP	OPT_BUF(BV_LISP)
137#endif
138#define PV_MA		OPT_BUF(BV_MA)
139#define PV_ML		OPT_BUF(BV_ML)
140#define PV_MOD		OPT_BUF(BV_MOD)
141#define PV_MPS		OPT_BUF(BV_MPS)
142#define PV_NF		OPT_BUF(BV_NF)
143#ifdef FEAT_OSFILETYPE
144# define PV_OFT		OPT_BUF(BV_OFT)
145#endif
146#ifdef FEAT_COMPL_FUNC
147# define PV_OFU		OPT_BUF(BV_OFU)
148#endif
149#define PV_PATH		OPT_BOTH(OPT_BUF(BV_PATH))
150#define PV_PI		OPT_BUF(BV_PI)
151#ifdef FEAT_TEXTOBJ
152# define PV_QE		OPT_BUF(BV_QE)
153#endif
154#define PV_RO		OPT_BUF(BV_RO)
155#ifdef FEAT_SMARTINDENT
156# define PV_SI		OPT_BUF(BV_SI)
157#endif
158#ifndef SHORT_FNAME
159# define PV_SN		OPT_BUF(BV_SN)
160#endif
161#ifdef FEAT_SYN_HL
162# define PV_SMC		OPT_BUF(BV_SMC)
163# define PV_SYN		OPT_BUF(BV_SYN)
164#endif
165#ifdef FEAT_SPELL
166# define PV_SPC		OPT_BUF(BV_SPC)
167# define PV_SPF		OPT_BUF(BV_SPF)
168# define PV_SPL		OPT_BUF(BV_SPL)
169#endif
170#define PV_STS		OPT_BUF(BV_STS)
171#ifdef FEAT_SEARCHPATH
172# define PV_SUA		OPT_BUF(BV_SUA)
173#endif
174#define PV_SW		OPT_BUF(BV_SW)
175#define PV_SWF		OPT_BUF(BV_SWF)
176#define PV_TAGS		OPT_BOTH(OPT_BUF(BV_TAGS))
177#define PV_TS		OPT_BUF(BV_TS)
178#define PV_TW		OPT_BUF(BV_TW)
179#define PV_TX		OPT_BUF(BV_TX)
180#ifdef FEAT_PERSISTENT_UNDO
181# define PV_UDF		OPT_BUF(BV_UDF)
182#endif
183#define PV_WM		OPT_BUF(BV_WM)
184
185/*
186 * Definition of the PV_ values for window-local options.
187 * The WV_ values are defined in option.h.
188 */
189#define PV_LIST		OPT_WIN(WV_LIST)
190#ifdef FEAT_ARABIC
191# define PV_ARAB	OPT_WIN(WV_ARAB)
192#endif
193#ifdef FEAT_DIFF
194# define PV_DIFF	OPT_WIN(WV_DIFF)
195#endif
196#ifdef FEAT_FOLDING
197# define PV_FDC		OPT_WIN(WV_FDC)
198# define PV_FEN		OPT_WIN(WV_FEN)
199# define PV_FDI		OPT_WIN(WV_FDI)
200# define PV_FDL		OPT_WIN(WV_FDL)
201# define PV_FDM		OPT_WIN(WV_FDM)
202# define PV_FML		OPT_WIN(WV_FML)
203# define PV_FDN		OPT_WIN(WV_FDN)
204# ifdef FEAT_EVAL
205#  define PV_FDE	OPT_WIN(WV_FDE)
206#  define PV_FDT	OPT_WIN(WV_FDT)
207# endif
208# define PV_FMR		OPT_WIN(WV_FMR)
209#endif
210#ifdef FEAT_LINEBREAK
211# define PV_LBR		OPT_WIN(WV_LBR)
212#endif
213#define PV_NU		OPT_WIN(WV_NU)
214#define PV_RNU		OPT_WIN(WV_RNU)
215#ifdef FEAT_LINEBREAK
216# define PV_NUW		OPT_WIN(WV_NUW)
217#endif
218#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
219# define PV_PVW		OPT_WIN(WV_PVW)
220#endif
221#ifdef FEAT_RIGHTLEFT
222# define PV_RL		OPT_WIN(WV_RL)
223# define PV_RLC		OPT_WIN(WV_RLC)
224#endif
225#ifdef FEAT_SCROLLBIND
226# define PV_SCBIND	OPT_WIN(WV_SCBIND)
227#endif
228#define PV_SCROLL	OPT_WIN(WV_SCROLL)
229#ifdef FEAT_SPELL
230# define PV_SPELL	OPT_WIN(WV_SPELL)
231#endif
232#ifdef FEAT_SYN_HL
233# define PV_CUC		OPT_WIN(WV_CUC)
234# define PV_CUL		OPT_WIN(WV_CUL)
235# define PV_CC		OPT_WIN(WV_CC)
236#endif
237#ifdef FEAT_STL_OPT
238# define PV_STL		OPT_BOTH(OPT_WIN(WV_STL))
239#endif
240#ifdef FEAT_WINDOWS
241# define PV_WFH		OPT_WIN(WV_WFH)
242#endif
243#ifdef FEAT_VERTSPLIT
244# define PV_WFW		OPT_WIN(WV_WFW)
245#endif
246#define PV_WRAP		OPT_WIN(WV_WRAP)
247#ifdef FEAT_CURSORBIND
248# define PV_CRBIND	OPT_WIN(WV_CRBIND)
249#endif
250#ifdef FEAT_CONCEAL
251# define PV_COCU	OPT_WIN(WV_COCU)
252# define PV_COLE	OPT_WIN(WV_COLE)
253#endif
254
255/* WV_ and BV_ values get typecasted to this for the "indir" field */
256typedef enum
257{
258    PV_NONE = 0,
259    PV_MAXVAL = 0xffff    /* to avoid warnings for value out of range */
260} idopt_T;
261
262/*
263 * Options local to a window have a value local to a buffer and global to all
264 * buffers.  Indicate this by setting "var" to VAR_WIN.
265 */
266#define VAR_WIN ((char_u *)-1)
267
268/*
269 * These are the global values for options which are also local to a buffer.
270 * Only to be used in option.c!
271 */
272static int	p_ai;
273static int	p_bin;
274#ifdef FEAT_MBYTE
275static int	p_bomb;
276#endif
277#if defined(FEAT_QUICKFIX)
278static char_u	*p_bh;
279static char_u	*p_bt;
280#endif
281static int	p_bl;
282static int	p_ci;
283#ifdef FEAT_CINDENT
284static int	p_cin;
285static char_u	*p_cink;
286static char_u	*p_cino;
287#endif
288#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
289static char_u	*p_cinw;
290#endif
291#ifdef FEAT_COMMENTS
292static char_u	*p_com;
293#endif
294#ifdef FEAT_FOLDING
295static char_u	*p_cms;
296#endif
297#ifdef FEAT_INS_EXPAND
298static char_u	*p_cpt;
299#endif
300#ifdef FEAT_COMPL_FUNC
301static char_u	*p_cfu;
302static char_u	*p_ofu;
303#endif
304static int	p_eol;
305static int	p_et;
306#ifdef FEAT_MBYTE
307static char_u	*p_fenc;
308#endif
309static char_u	*p_ff;
310static char_u	*p_fo;
311static char_u	*p_flp;
312#ifdef FEAT_AUTOCMD
313static char_u	*p_ft;
314#endif
315static long	p_iminsert;
316static long	p_imsearch;
317#if defined(FEAT_FIND_ID) && defined(FEAT_EVAL)
318static char_u	*p_inex;
319#endif
320#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
321static char_u	*p_inde;
322static char_u	*p_indk;
323#endif
324#if defined(FEAT_EVAL)
325static char_u	*p_fex;
326#endif
327static int	p_inf;
328static char_u	*p_isk;
329#ifdef FEAT_CRYPT
330static char_u	*p_key;
331#endif
332#ifdef FEAT_LISP
333static int	p_lisp;
334#endif
335static int	p_ml;
336static int	p_ma;
337static int	p_mod;
338static char_u	*p_mps;
339static char_u	*p_nf;
340#ifdef FEAT_OSFILETYPE
341static char_u	*p_oft;
342#endif
343static int	p_pi;
344#ifdef FEAT_TEXTOBJ
345static char_u	*p_qe;
346#endif
347static int	p_ro;
348#ifdef FEAT_SMARTINDENT
349static int	p_si;
350#endif
351#ifndef SHORT_FNAME
352static int	p_sn;
353#endif
354static long	p_sts;
355#if defined(FEAT_SEARCHPATH)
356static char_u	*p_sua;
357#endif
358static long	p_sw;
359static int	p_swf;
360#ifdef FEAT_SYN_HL
361static long	p_smc;
362static char_u	*p_syn;
363#endif
364#ifdef FEAT_SPELL
365static char_u	*p_spc;
366static char_u	*p_spf;
367static char_u	*p_spl;
368#endif
369static long	p_ts;
370static long	p_tw;
371static int	p_tx;
372#ifdef FEAT_PERSISTENT_UNDO
373static int	p_udf;
374#endif
375static long	p_wm;
376#ifdef FEAT_KEYMAP
377static char_u	*p_keymap;
378#endif
379
380/* Saved values for when 'bin' is set. */
381static int	p_et_nobin;
382static int	p_ml_nobin;
383static long	p_tw_nobin;
384static long	p_wm_nobin;
385
386/* Saved values for when 'paste' is set */
387static long	p_tw_nopaste;
388static long	p_wm_nopaste;
389static long	p_sts_nopaste;
390static int	p_ai_nopaste;
391
392struct vimoption
393{
394    char	*fullname;	/* full option name */
395    char	*shortname;	/* permissible abbreviation */
396    long_u	flags;		/* see below */
397    char_u	*var;		/* global option: pointer to variable;
398				 * window-local option: VAR_WIN;
399				 * buffer-local option: global value */
400    idopt_T	indir;		/* global option: PV_NONE;
401				 * local option: indirect option index */
402    char_u	*def_val[2];	/* default values for variable (vi and vim) */
403#ifdef FEAT_EVAL
404    scid_T	scriptID;	/* script in which the option was last set */
405# define SCRIPTID_INIT , 0
406#else
407# define SCRIPTID_INIT
408#endif
409};
410
411#define VI_DEFAULT  0	    /* def_val[VI_DEFAULT] is Vi default value */
412#define VIM_DEFAULT 1	    /* def_val[VIM_DEFAULT] is Vim default value */
413
414/*
415 * Flags
416 */
417#define P_BOOL		0x01	/* the option is boolean */
418#define P_NUM		0x02	/* the option is numeric */
419#define P_STRING	0x04	/* the option is a string */
420#define P_ALLOCED	0x08	/* the string option is in allocated memory,
421				   must use free_string_option() when
422				   assigning new value. Not set if default is
423				   the same. */
424#define P_EXPAND	0x10	/* environment expansion.  NOTE: P_EXPAND can
425				   never be used for local or hidden options! */
426#define P_NODEFAULT	0x40	/* don't set to default value */
427#define P_DEF_ALLOCED	0x80	/* default value is in allocated memory, must
428				    use vim_free() when assigning new value */
429#define P_WAS_SET	0x100	/* option has been set/reset */
430#define P_NO_MKRC	0x200	/* don't include in :mkvimrc output */
431#define P_VI_DEF	0x400	/* Use Vi default for Vim */
432#define P_VIM		0x800	/* Vim option, reset when 'cp' set */
433
434				/* when option changed, what to display: */
435#define P_RSTAT		0x1000	/* redraw status lines */
436#define P_RWIN		0x2000	/* redraw current window */
437#define P_RBUF		0x4000	/* redraw current buffer */
438#define P_RALL		0x6000	/* redraw all windows */
439#define P_RCLR		0x7000	/* clear and redraw all */
440
441#define P_COMMA		0x8000	/* comma separated list */
442#define P_NODUP		0x10000L/* don't allow duplicate strings */
443#define P_FLAGLIST	0x20000L/* list of single-char flags */
444
445#define P_SECURE	0x40000L/* cannot change in modeline or secure mode */
446#define P_GETTEXT	0x80000L/* expand default value with _() */
447#define P_NOGLOB       0x100000L/* do not use local value for global vimrc */
448#define P_NFNAME       0x200000L/* only normal file name chars allowed */
449#define P_INSECURE     0x400000L/* option was set from a modeline */
450#define P_PRI_MKRC     0x800000L/* priority for :mkvimrc (setting option has
451				   side effects) */
452#define P_NO_ML       0x1000000L/* not allowed in modeline */
453
454#define ISK_LATIN1  (char_u *)"@,48-57,_,192-255"
455
456/* 'isprint' for latin1 is also used for MS-Windows cp1252, where 0x80 is used
457 * for the currency sign. */
458#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
459# define ISP_LATIN1 (char_u *)"@,~-255"
460#else
461# define ISP_LATIN1 (char_u *)"@,161-255"
462#endif
463
464/* The 16 bit MS-DOS version is low on space, make the string as short as
465 * possible when compiling with few features. */
466#if defined(FEAT_DIFF) || defined(FEAT_FOLDING) || defined(FEAT_SPELL) \
467	|| defined(FEAT_VERTSPLIT) || defined(FEAT_CLIPBOARD) \
468	|| defined(FEAT_INS_EXPAND) || defined(FEAT_SYN_HL) || defined(FEAT_CONCEAL)
469# define HIGHLIGHT_INIT "8:SpecialKey,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn"
470#else
471# define HIGHLIGHT_INIT "8:SpecialKey,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,r:Question,s:StatusLine,S:StatusLineNC,t:Title,v:Visual,w:WarningMsg,W:WildMenu,>:SignColumn,*:TabLine,#:TabLineSel,_:TabLineFill"
472#endif
473
474/*
475 * options[] is initialized here.
476 * The order of the options MUST be alphabetic for ":set all" and findoption().
477 * All option names MUST start with a lowercase letter (for findoption()).
478 * Exception: "t_" options are at the end.
479 * The options with a NULL variable are 'hidden': a set command for them is
480 * ignored and they are not printed.
481 */
482static struct vimoption
483#ifdef FEAT_GUI_W16
484	_far
485#endif
486	options[] =
487{
488    {"aleph",	    "al",   P_NUM|P_VI_DEF,
489#ifdef FEAT_RIGHTLEFT
490			    (char_u *)&p_aleph, PV_NONE,
491#else
492			    (char_u *)NULL, PV_NONE,
493#endif
494			    {
495#if (defined(MSDOS) || defined(WIN3264) || defined(OS2)) && !defined(FEAT_GUI_W32)
496			    (char_u *)128L,
497#else
498			    (char_u *)224L,
499#endif
500					    (char_u *)0L} SCRIPTID_INIT},
501    {"antialias",   "anti", P_BOOL|P_VI_DEF|P_VIM|P_RCLR,
502#if defined(FEAT_GUI) && defined(MACOS_X)
503			    (char_u *)&p_antialias, PV_NONE,
504			    {(char_u *)FALSE, (char_u *)FALSE}
505#else
506			    (char_u *)NULL, PV_NONE,
507			    {(char_u *)FALSE, (char_u *)FALSE}
508#endif
509			    SCRIPTID_INIT},
510    {"arabic",	    "arab", P_BOOL|P_VI_DEF|P_VIM,
511#ifdef FEAT_ARABIC
512			    (char_u *)VAR_WIN, PV_ARAB,
513#else
514			    (char_u *)NULL, PV_NONE,
515#endif
516			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
517    {"arabicshape", "arshape", P_BOOL|P_VI_DEF|P_VIM|P_RCLR,
518#ifdef FEAT_ARABIC
519			    (char_u *)&p_arshape, PV_NONE,
520#else
521			    (char_u *)NULL, PV_NONE,
522#endif
523			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
524    {"allowrevins", "ari",  P_BOOL|P_VI_DEF|P_VIM,
525#ifdef FEAT_RIGHTLEFT
526			    (char_u *)&p_ari, PV_NONE,
527#else
528			    (char_u *)NULL, PV_NONE,
529#endif
530			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
531    {"altkeymap",   "akm",  P_BOOL|P_VI_DEF,
532#ifdef FEAT_FKMAP
533			    (char_u *)&p_altkeymap, PV_NONE,
534#else
535			    (char_u *)NULL, PV_NONE,
536#endif
537			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
538    {"ambiwidth",  "ambw",  P_STRING|P_VI_DEF|P_RCLR,
539#if defined(FEAT_MBYTE)
540			    (char_u *)&p_ambw, PV_NONE,
541			    {(char_u *)"single", (char_u *)0L}
542#else
543			    (char_u *)NULL, PV_NONE,
544			    {(char_u *)0L, (char_u *)0L}
545#endif
546			    SCRIPTID_INIT},
547#ifdef FEAT_AUTOCHDIR
548    {"autochdir",  "acd",   P_BOOL|P_VI_DEF,
549			    (char_u *)&p_acd, PV_NONE,
550			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
551#endif
552    {"autoindent",  "ai",   P_BOOL|P_VI_DEF,
553			    (char_u *)&p_ai, PV_AI,
554			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
555    {"autoprint",   "ap",   P_BOOL|P_VI_DEF,
556			    (char_u *)&p_ap, PV_NONE,
557			    {(char_u *)TRUE, (char_u *)1L} SCRIPTID_INIT},
558    {"autoread",    "ar",   P_BOOL|P_VI_DEF,
559			    (char_u *)&p_ar, PV_AR,
560			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
561    {"autowrite",   "aw",   P_BOOL|P_VI_DEF,
562			    (char_u *)&p_aw, PV_NONE,
563			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
564    {"autowriteall","awa",  P_BOOL|P_VI_DEF,
565			    (char_u *)&p_awa, PV_NONE,
566			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
567    {"background",  "bg",   P_STRING|P_VI_DEF|P_RCLR,
568			    (char_u *)&p_bg, PV_NONE,
569			    {
570#if (defined(MSDOS) || defined(OS2) || defined(WIN3264)) && !defined(FEAT_GUI)
571			    (char_u *)"dark",
572#else
573			    (char_u *)"light",
574#endif
575					    (char_u *)0L} SCRIPTID_INIT},
576    {"backspace",   "bs",   P_STRING|P_VI_DEF|P_VIM|P_COMMA|P_NODUP,
577			    (char_u *)&p_bs, PV_NONE,
578			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
579    {"backup",	    "bk",   P_BOOL|P_VI_DEF|P_VIM,
580			    (char_u *)&p_bk, PV_NONE,
581			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
582    {"backupcopy",  "bkc",  P_STRING|P_VIM|P_COMMA|P_NODUP,
583			    (char_u *)&p_bkc, PV_NONE,
584#ifdef UNIX
585			    {(char_u *)"yes", (char_u *)"auto"}
586#else
587			    {(char_u *)"auto", (char_u *)"auto"}
588#endif
589			    SCRIPTID_INIT},
590    {"backupdir",   "bdir", P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP|P_SECURE,
591			    (char_u *)&p_bdir, PV_NONE,
592			    {(char_u *)DFLT_BDIR, (char_u *)0L} SCRIPTID_INIT},
593    {"backupext",   "bex",  P_STRING|P_VI_DEF|P_NFNAME,
594			    (char_u *)&p_bex, PV_NONE,
595			    {
596#ifdef VMS
597			    (char_u *)"_",
598#else
599			    (char_u *)"~",
600#endif
601					    (char_u *)0L} SCRIPTID_INIT},
602    {"backupskip",  "bsk",  P_STRING|P_VI_DEF|P_COMMA,
603#ifdef FEAT_WILDIGN
604			    (char_u *)&p_bsk, PV_NONE,
605			    {(char_u *)"", (char_u *)0L}
606#else
607			    (char_u *)NULL, PV_NONE,
608			    {(char_u *)0L, (char_u *)0L}
609#endif
610			    SCRIPTID_INIT},
611#ifdef FEAT_BEVAL
612    {"balloondelay","bdlay",P_NUM|P_VI_DEF,
613			    (char_u *)&p_bdlay, PV_NONE,
614			    {(char_u *)600L, (char_u *)0L} SCRIPTID_INIT},
615    {"ballooneval", "beval",P_BOOL|P_VI_DEF|P_NO_MKRC,
616			    (char_u *)&p_beval, PV_NONE,
617			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
618# ifdef FEAT_EVAL
619    {"balloonexpr", "bexpr", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM,
620			    (char_u *)&p_bexpr, PV_BEXPR,
621			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
622# endif
623#endif
624    {"beautify",    "bf",   P_BOOL|P_VI_DEF,
625			    (char_u *)&p_bf, PV_NONE,
626			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
627    {"binary",	    "bin",  P_BOOL|P_VI_DEF|P_RSTAT,
628			    (char_u *)&p_bin, PV_BIN,
629			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
630    {"bioskey",	    "biosk",P_BOOL|P_VI_DEF,
631#ifdef MSDOS
632			    (char_u *)&p_biosk, PV_NONE,
633#else
634			    (char_u *)NULL, PV_NONE,
635#endif
636			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
637    {"bomb",	    NULL,   P_BOOL|P_NO_MKRC|P_VI_DEF|P_RSTAT,
638#ifdef FEAT_MBYTE
639			    (char_u *)&p_bomb, PV_BOMB,
640#else
641			    (char_u *)NULL, PV_NONE,
642#endif
643			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
644    {"breakat",	    "brk",  P_STRING|P_VI_DEF|P_RALL|P_FLAGLIST,
645#ifdef FEAT_LINEBREAK
646			    (char_u *)&p_breakat, PV_NONE,
647			    {(char_u *)" \t!@*-+;:,./?", (char_u *)0L}
648#else
649			    (char_u *)NULL, PV_NONE,
650			    {(char_u *)0L, (char_u *)0L}
651#endif
652			    SCRIPTID_INIT},
653    {"browsedir",   "bsdir",P_STRING|P_VI_DEF,
654#ifdef FEAT_BROWSE
655			    (char_u *)&p_bsdir, PV_NONE,
656			    {(char_u *)"last", (char_u *)0L}
657#else
658			    (char_u *)NULL, PV_NONE,
659			    {(char_u *)0L, (char_u *)0L}
660#endif
661			    SCRIPTID_INIT},
662    {"bufhidden",   "bh",   P_STRING|P_ALLOCED|P_VI_DEF|P_NOGLOB,
663#if defined(FEAT_QUICKFIX)
664			    (char_u *)&p_bh, PV_BH,
665			    {(char_u *)"", (char_u *)0L}
666#else
667			    (char_u *)NULL, PV_NONE,
668			    {(char_u *)0L, (char_u *)0L}
669#endif
670			    SCRIPTID_INIT},
671    {"buflisted",   "bl",   P_BOOL|P_VI_DEF|P_NOGLOB,
672			    (char_u *)&p_bl, PV_BL,
673			    {(char_u *)1L, (char_u *)0L}
674			    SCRIPTID_INIT},
675    {"buftype",	    "bt",   P_STRING|P_ALLOCED|P_VI_DEF|P_NOGLOB,
676#if defined(FEAT_QUICKFIX)
677			    (char_u *)&p_bt, PV_BT,
678			    {(char_u *)"", (char_u *)0L}
679#else
680			    (char_u *)NULL, PV_NONE,
681			    {(char_u *)0L, (char_u *)0L}
682#endif
683			    SCRIPTID_INIT},
684    {"casemap",	    "cmp",   P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
685#ifdef FEAT_MBYTE
686			    (char_u *)&p_cmp, PV_NONE,
687			    {(char_u *)"internal,keepascii", (char_u *)0L}
688#else
689			    (char_u *)NULL, PV_NONE,
690			    {(char_u *)0L, (char_u *)0L}
691#endif
692			    SCRIPTID_INIT},
693    {"cdpath",	    "cd",   P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP,
694#ifdef FEAT_SEARCHPATH
695			    (char_u *)&p_cdpath, PV_NONE,
696			    {(char_u *)",,", (char_u *)0L}
697#else
698			    (char_u *)NULL, PV_NONE,
699			    {(char_u *)0L, (char_u *)0L}
700#endif
701			    SCRIPTID_INIT},
702    {"cedit",	    NULL,   P_STRING,
703#ifdef FEAT_CMDWIN
704			    (char_u *)&p_cedit, PV_NONE,
705			    {(char_u *)"", (char_u *)CTRL_F_STR}
706#else
707			    (char_u *)NULL, PV_NONE,
708			    {(char_u *)0L, (char_u *)0L}
709#endif
710			    SCRIPTID_INIT},
711    {"charconvert",  "ccv", P_STRING|P_VI_DEF|P_SECURE,
712#if defined(FEAT_MBYTE) && defined(FEAT_EVAL)
713			    (char_u *)&p_ccv, PV_NONE,
714			    {(char_u *)"", (char_u *)0L}
715#else
716			    (char_u *)NULL, PV_NONE,
717			    {(char_u *)0L, (char_u *)0L}
718#endif
719			    SCRIPTID_INIT},
720    {"cindent",	    "cin",  P_BOOL|P_VI_DEF|P_VIM,
721#ifdef FEAT_CINDENT
722			    (char_u *)&p_cin, PV_CIN,
723#else
724			    (char_u *)NULL, PV_NONE,
725#endif
726			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
727    {"cinkeys",	    "cink", P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
728#ifdef FEAT_CINDENT
729			    (char_u *)&p_cink, PV_CINK,
730			    {(char_u *)"0{,0},0),:,0#,!^F,o,O,e", (char_u *)0L}
731#else
732			    (char_u *)NULL, PV_NONE,
733			    {(char_u *)0L, (char_u *)0L}
734#endif
735			    SCRIPTID_INIT},
736    {"cinoptions",  "cino", P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
737#ifdef FEAT_CINDENT
738			    (char_u *)&p_cino, PV_CINO,
739#else
740			    (char_u *)NULL, PV_NONE,
741#endif
742			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
743    {"cinwords",    "cinw", P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
744#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
745			    (char_u *)&p_cinw, PV_CINW,
746			    {(char_u *)"if,else,while,do,for,switch",
747				(char_u *)0L}
748#else
749			    (char_u *)NULL, PV_NONE,
750			    {(char_u *)0L, (char_u *)0L}
751#endif
752			    SCRIPTID_INIT},
753    {"clipboard",   "cb",   P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
754#ifdef FEAT_CLIPBOARD
755			    (char_u *)&p_cb, PV_NONE,
756# ifdef FEAT_XCLIPBOARD
757			    {(char_u *)"autoselect,exclude:cons\\|linux",
758							       (char_u *)0L}
759# else
760			    {(char_u *)"", (char_u *)0L}
761# endif
762#else
763			    (char_u *)NULL, PV_NONE,
764			    {(char_u *)"", (char_u *)0L}
765#endif
766			    SCRIPTID_INIT},
767    {"cmdheight",   "ch",   P_NUM|P_VI_DEF|P_RALL,
768			    (char_u *)&p_ch, PV_NONE,
769			    {(char_u *)1L, (char_u *)0L} SCRIPTID_INIT},
770    {"cmdwinheight", "cwh", P_NUM|P_VI_DEF,
771#ifdef FEAT_CMDWIN
772			    (char_u *)&p_cwh, PV_NONE,
773#else
774			    (char_u *)NULL, PV_NONE,
775#endif
776			    {(char_u *)7L, (char_u *)0L} SCRIPTID_INIT},
777    {"colorcolumn", "cc",   P_STRING|P_VI_DEF|P_COMMA|P_NODUP|P_RWIN,
778#ifdef FEAT_SYN_HL
779			    (char_u *)VAR_WIN, PV_CC,
780#else
781			    (char_u *)NULL, PV_NONE,
782#endif
783			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
784    {"columns",	    "co",   P_NUM|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RCLR,
785			    (char_u *)&Columns, PV_NONE,
786			    {(char_u *)80L, (char_u *)0L} SCRIPTID_INIT},
787    {"comments",    "com",  P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
788#ifdef FEAT_COMMENTS
789			    (char_u *)&p_com, PV_COM,
790			    {(char_u *)"s1:/*,mb:*,ex:*/,://,b:#,:%,:XCOMM,n:>,fb:-",
791				(char_u *)0L}
792#else
793			    (char_u *)NULL, PV_NONE,
794			    {(char_u *)0L, (char_u *)0L}
795#endif
796			    SCRIPTID_INIT},
797    {"commentstring", "cms", P_STRING|P_ALLOCED|P_VI_DEF,
798#ifdef FEAT_FOLDING
799			    (char_u *)&p_cms, PV_CMS,
800			    {(char_u *)"/*%s*/", (char_u *)0L}
801#else
802			    (char_u *)NULL, PV_NONE,
803			    {(char_u *)0L, (char_u *)0L}
804#endif
805			    SCRIPTID_INIT},
806			    /* P_PRI_MKRC isn't needed here, optval_default()
807			     * always returns TRUE for 'compatible' */
808    {"compatible",  "cp",   P_BOOL|P_RALL,
809			    (char_u *)&p_cp, PV_NONE,
810			    {(char_u *)TRUE, (char_u *)FALSE} SCRIPTID_INIT},
811    {"complete",    "cpt",  P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
812#ifdef FEAT_INS_EXPAND
813			    (char_u *)&p_cpt, PV_CPT,
814			    {(char_u *)".,w,b,u,t,i", (char_u *)0L}
815#else
816			    (char_u *)NULL, PV_NONE,
817			    {(char_u *)0L, (char_u *)0L}
818#endif
819			    SCRIPTID_INIT},
820    {"concealcursor","cocu", P_STRING|P_ALLOCED|P_RWIN|P_VI_DEF,
821#ifdef FEAT_CONCEAL
822			    (char_u *)VAR_WIN, PV_COCU,
823			    {(char_u *)"", (char_u *)NULL}
824#else
825			    (char_u *)NULL, PV_NONE,
826			    {(char_u *)NULL, (char_u *)0L}
827#endif
828			    SCRIPTID_INIT},
829    {"conceallevel","cole", P_NUM|P_RWIN|P_VI_DEF,
830#ifdef FEAT_CONCEAL
831			    (char_u *)VAR_WIN, PV_COLE,
832#else
833			    (char_u *)NULL, PV_NONE,
834#endif
835			    {(char_u *)0L, (char_u *)0L}
836			    SCRIPTID_INIT},
837    {"completefunc", "cfu", P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE,
838#ifdef FEAT_COMPL_FUNC
839			    (char_u *)&p_cfu, PV_CFU,
840			    {(char_u *)"", (char_u *)0L}
841#else
842			    (char_u *)NULL, PV_NONE,
843			    {(char_u *)0L, (char_u *)0L}
844#endif
845			    SCRIPTID_INIT},
846    {"completeopt",   "cot",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
847#ifdef FEAT_INS_EXPAND
848			    (char_u *)&p_cot, PV_NONE,
849			    {(char_u *)"menu,preview", (char_u *)0L}
850#else
851			    (char_u *)NULL, PV_NONE,
852			    {(char_u *)0L, (char_u *)0L}
853#endif
854			    SCRIPTID_INIT},
855    {"confirm",     "cf",   P_BOOL|P_VI_DEF,
856#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
857			    (char_u *)&p_confirm, PV_NONE,
858#else
859			    (char_u *)NULL, PV_NONE,
860#endif
861			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
862    {"conskey",	    "consk",P_BOOL|P_VI_DEF,
863#ifdef MSDOS
864			    (char_u *)&p_consk, PV_NONE,
865#else
866			    (char_u *)NULL, PV_NONE,
867#endif
868			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
869    {"copyindent",  "ci",   P_BOOL|P_VI_DEF|P_VIM,
870			    (char_u *)&p_ci, PV_CI,
871			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
872    {"cpoptions",   "cpo",  P_STRING|P_VIM|P_RALL|P_FLAGLIST,
873			    (char_u *)&p_cpo, PV_NONE,
874			    {(char_u *)CPO_VI, (char_u *)CPO_VIM}
875			    SCRIPTID_INIT},
876    {"cryptmethod", "cm",   P_STRING|P_ALLOCED|P_VI_DEF,
877#ifdef FEAT_CRYPT
878			    (char_u *)&p_cm, PV_CM,
879			    {(char_u *)"zip", (char_u *)0L}
880#else
881			    (char_u *)NULL, PV_NONE,
882			    {(char_u *)0L, (char_u *)0L}
883#endif
884			    SCRIPTID_INIT},
885    {"cscopepathcomp", "cspc", P_NUM|P_VI_DEF|P_VIM,
886#ifdef FEAT_CSCOPE
887			    (char_u *)&p_cspc, PV_NONE,
888#else
889			    (char_u *)NULL, PV_NONE,
890#endif
891			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
892    {"cscopeprg",   "csprg", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
893#ifdef FEAT_CSCOPE
894			    (char_u *)&p_csprg, PV_NONE,
895			    {(char_u *)"cscope", (char_u *)0L}
896#else
897			    (char_u *)NULL, PV_NONE,
898			    {(char_u *)0L, (char_u *)0L}
899#endif
900			    SCRIPTID_INIT},
901    {"cscopequickfix", "csqf", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
902#if defined(FEAT_CSCOPE) && defined(FEAT_QUICKFIX)
903			    (char_u *)&p_csqf, PV_NONE,
904			    {(char_u *)"", (char_u *)0L}
905#else
906			    (char_u *)NULL, PV_NONE,
907			    {(char_u *)0L, (char_u *)0L}
908#endif
909			    SCRIPTID_INIT},
910    {"cscopetag",   "cst",  P_BOOL|P_VI_DEF|P_VIM,
911#ifdef FEAT_CSCOPE
912			    (char_u *)&p_cst, PV_NONE,
913#else
914			    (char_u *)NULL, PV_NONE,
915#endif
916			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
917    {"cscopetagorder", "csto", P_NUM|P_VI_DEF|P_VIM,
918#ifdef FEAT_CSCOPE
919			    (char_u *)&p_csto, PV_NONE,
920#else
921			    (char_u *)NULL, PV_NONE,
922#endif
923			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
924    {"cscopeverbose", "csverb", P_BOOL|P_VI_DEF|P_VIM,
925#ifdef FEAT_CSCOPE
926			    (char_u *)&p_csverbose, PV_NONE,
927#else
928			    (char_u *)NULL, PV_NONE,
929#endif
930			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
931    {"cursorbind",  "crb",  P_BOOL|P_VI_DEF,
932#ifdef FEAT_CURSORBIND
933			    (char_u *)VAR_WIN, PV_CRBIND,
934#else
935			    (char_u *)NULL, PV_NONE,
936#endif
937			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
938    {"cursorcolumn", "cuc", P_BOOL|P_VI_DEF|P_RWIN,
939#ifdef FEAT_SYN_HL
940			    (char_u *)VAR_WIN, PV_CUC,
941#else
942			    (char_u *)NULL, PV_NONE,
943#endif
944			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
945    {"cursorline",   "cul", P_BOOL|P_VI_DEF|P_RWIN,
946#ifdef FEAT_SYN_HL
947			    (char_u *)VAR_WIN, PV_CUL,
948#else
949			    (char_u *)NULL, PV_NONE,
950#endif
951			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
952    {"debug",	    NULL,   P_STRING|P_VI_DEF,
953			    (char_u *)&p_debug, PV_NONE,
954			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
955    {"define",	    "def",  P_STRING|P_ALLOCED|P_VI_DEF,
956#ifdef FEAT_FIND_ID
957			    (char_u *)&p_def, PV_DEF,
958			    {(char_u *)"^\\s*#\\s*define", (char_u *)0L}
959#else
960			    (char_u *)NULL, PV_NONE,
961			    {(char_u *)NULL, (char_u *)0L}
962#endif
963			    SCRIPTID_INIT},
964    {"delcombine", "deco",  P_BOOL|P_VI_DEF|P_VIM,
965#ifdef FEAT_MBYTE
966			    (char_u *)&p_deco, PV_NONE,
967#else
968			    (char_u *)NULL, PV_NONE,
969#endif
970			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
971    {"dictionary",  "dict", P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP,
972#ifdef FEAT_INS_EXPAND
973			    (char_u *)&p_dict, PV_DICT,
974#else
975			    (char_u *)NULL, PV_NONE,
976#endif
977			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
978    {"diff",	    NULL,   P_BOOL|P_VI_DEF|P_RWIN|P_NOGLOB,
979#ifdef FEAT_DIFF
980			    (char_u *)VAR_WIN, PV_DIFF,
981#else
982			    (char_u *)NULL, PV_NONE,
983#endif
984			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
985    {"diffexpr",    "dex",  P_STRING|P_VI_DEF|P_SECURE,
986#if defined(FEAT_DIFF) && defined(FEAT_EVAL)
987			    (char_u *)&p_dex, PV_NONE,
988			    {(char_u *)"", (char_u *)0L}
989#else
990			    (char_u *)NULL, PV_NONE,
991			    {(char_u *)0L, (char_u *)0L}
992#endif
993			    SCRIPTID_INIT},
994    {"diffopt",	    "dip",  P_STRING|P_ALLOCED|P_VI_DEF|P_RWIN|P_COMMA|P_NODUP,
995#ifdef FEAT_DIFF
996			    (char_u *)&p_dip, PV_NONE,
997			    {(char_u *)"filler", (char_u *)NULL}
998#else
999			    (char_u *)NULL, PV_NONE,
1000			    {(char_u *)"", (char_u *)NULL}
1001#endif
1002			    SCRIPTID_INIT},
1003    {"digraph",	    "dg",   P_BOOL|P_VI_DEF|P_VIM,
1004#ifdef FEAT_DIGRAPHS
1005			    (char_u *)&p_dg, PV_NONE,
1006#else
1007			    (char_u *)NULL, PV_NONE,
1008#endif
1009			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1010    {"directory",   "dir",  P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP|P_SECURE,
1011			    (char_u *)&p_dir, PV_NONE,
1012			    {(char_u *)DFLT_DIR, (char_u *)0L} SCRIPTID_INIT},
1013    {"display",	    "dy",   P_STRING|P_VI_DEF|P_COMMA|P_RALL|P_NODUP,
1014			    (char_u *)&p_dy, PV_NONE,
1015			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
1016    {"eadirection", "ead",  P_STRING|P_VI_DEF,
1017#ifdef FEAT_VERTSPLIT
1018			    (char_u *)&p_ead, PV_NONE,
1019			    {(char_u *)"both", (char_u *)0L}
1020#else
1021			    (char_u *)NULL, PV_NONE,
1022			    {(char_u *)NULL, (char_u *)0L}
1023#endif
1024			    SCRIPTID_INIT},
1025    {"edcompatible","ed",   P_BOOL|P_VI_DEF,
1026			    (char_u *)&p_ed, PV_NONE,
1027			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1028    {"encoding",    "enc",  P_STRING|P_VI_DEF|P_RCLR|P_NO_ML,
1029#ifdef FEAT_MBYTE
1030			    (char_u *)&p_enc, PV_NONE,
1031			    {(char_u *)ENC_DFLT, (char_u *)0L}
1032#else
1033			    (char_u *)NULL, PV_NONE,
1034			    {(char_u *)0L, (char_u *)0L}
1035#endif
1036			    SCRIPTID_INIT},
1037    {"endofline",   "eol",  P_BOOL|P_NO_MKRC|P_VI_DEF|P_RSTAT,
1038			    (char_u *)&p_eol, PV_EOL,
1039			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
1040    {"equalalways", "ea",   P_BOOL|P_VI_DEF|P_RALL,
1041			    (char_u *)&p_ea, PV_NONE,
1042			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
1043    {"equalprg",    "ep",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
1044			    (char_u *)&p_ep, PV_EP,
1045			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
1046    {"errorbells",  "eb",   P_BOOL|P_VI_DEF,
1047			    (char_u *)&p_eb, PV_NONE,
1048			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1049    {"errorfile",   "ef",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
1050#ifdef FEAT_QUICKFIX
1051			    (char_u *)&p_ef, PV_NONE,
1052			    {(char_u *)DFLT_ERRORFILE, (char_u *)0L}
1053#else
1054			    (char_u *)NULL, PV_NONE,
1055			    {(char_u *)NULL, (char_u *)0L}
1056#endif
1057			    SCRIPTID_INIT},
1058    {"errorformat", "efm",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
1059#ifdef FEAT_QUICKFIX
1060			    (char_u *)&p_efm, PV_EFM,
1061			    {(char_u *)DFLT_EFM, (char_u *)0L}
1062#else
1063			    (char_u *)NULL, PV_NONE,
1064			    {(char_u *)NULL, (char_u *)0L}
1065#endif
1066			    SCRIPTID_INIT},
1067    {"esckeys",	    "ek",   P_BOOL|P_VIM,
1068			    (char_u *)&p_ek, PV_NONE,
1069			    {(char_u *)FALSE, (char_u *)TRUE} SCRIPTID_INIT},
1070    {"eventignore", "ei",   P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
1071#ifdef FEAT_AUTOCMD
1072			    (char_u *)&p_ei, PV_NONE,
1073#else
1074			    (char_u *)NULL, PV_NONE,
1075#endif
1076			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
1077    {"expandtab",   "et",   P_BOOL|P_VI_DEF|P_VIM,
1078			    (char_u *)&p_et, PV_ET,
1079			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1080    {"exrc",	    "ex",   P_BOOL|P_VI_DEF|P_SECURE,
1081			    (char_u *)&p_exrc, PV_NONE,
1082			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1083    {"fileencoding","fenc", P_STRING|P_ALLOCED|P_VI_DEF|P_RSTAT|P_RBUF|P_NO_MKRC,
1084#ifdef FEAT_MBYTE
1085			    (char_u *)&p_fenc, PV_FENC,
1086			    {(char_u *)"", (char_u *)0L}
1087#else
1088			    (char_u *)NULL, PV_NONE,
1089			    {(char_u *)0L, (char_u *)0L}
1090#endif
1091			    SCRIPTID_INIT},
1092    {"fileencodings","fencs", P_STRING|P_VI_DEF|P_COMMA,
1093#ifdef FEAT_MBYTE
1094			    (char_u *)&p_fencs, PV_NONE,
1095			    {(char_u *)"ucs-bom", (char_u *)0L}
1096#else
1097			    (char_u *)NULL, PV_NONE,
1098			    {(char_u *)0L, (char_u *)0L}
1099#endif
1100			    SCRIPTID_INIT},
1101    {"fileformat",  "ff",   P_STRING|P_ALLOCED|P_VI_DEF|P_RSTAT|P_NO_MKRC,
1102			    (char_u *)&p_ff, PV_FF,
1103			    {(char_u *)DFLT_FF, (char_u *)0L} SCRIPTID_INIT},
1104    {"fileformats", "ffs",  P_STRING|P_VIM|P_COMMA|P_NODUP,
1105			    (char_u *)&p_ffs, PV_NONE,
1106			    {(char_u *)DFLT_FFS_VI, (char_u *)DFLT_FFS_VIM}
1107			    SCRIPTID_INIT},
1108    {"filetype",    "ft",   P_STRING|P_ALLOCED|P_VI_DEF|P_NOGLOB|P_NFNAME,
1109#ifdef FEAT_AUTOCMD
1110			    (char_u *)&p_ft, PV_FT,
1111			    {(char_u *)"", (char_u *)0L}
1112#else
1113			    (char_u *)NULL, PV_NONE,
1114			    {(char_u *)0L, (char_u *)0L}
1115#endif
1116			    SCRIPTID_INIT},
1117    {"fillchars",   "fcs",  P_STRING|P_VI_DEF|P_RALL|P_COMMA|P_NODUP,
1118#if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)
1119			    (char_u *)&p_fcs, PV_NONE,
1120			    {(char_u *)"vert:|,fold:-", (char_u *)0L}
1121#else
1122			    (char_u *)NULL, PV_NONE,
1123			    {(char_u *)"", (char_u *)0L}
1124#endif
1125			    SCRIPTID_INIT},
1126    {"fkmap",	    "fk",   P_BOOL|P_VI_DEF,
1127#ifdef FEAT_FKMAP
1128			    (char_u *)&p_fkmap, PV_NONE,
1129#else
1130			    (char_u *)NULL, PV_NONE,
1131#endif
1132			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1133    {"flash",	    "fl",   P_BOOL|P_VI_DEF,
1134			    (char_u *)NULL, PV_NONE,
1135			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1136#ifdef FEAT_FOLDING
1137    {"foldclose",   "fcl",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP|P_RWIN,
1138			    (char_u *)&p_fcl, PV_NONE,
1139			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
1140    {"foldcolumn",  "fdc",  P_NUM|P_VI_DEF|P_RWIN,
1141			    (char_u *)VAR_WIN, PV_FDC,
1142			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1143    {"foldenable",  "fen",  P_BOOL|P_VI_DEF|P_RWIN,
1144			    (char_u *)VAR_WIN, PV_FEN,
1145			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
1146    {"foldexpr",    "fde",  P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN,
1147# ifdef FEAT_EVAL
1148			    (char_u *)VAR_WIN, PV_FDE,
1149			    {(char_u *)"0", (char_u *)NULL}
1150# else
1151			    (char_u *)NULL, PV_NONE,
1152			    {(char_u *)NULL, (char_u *)0L}
1153# endif
1154			    SCRIPTID_INIT},
1155    {"foldignore",  "fdi",  P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN,
1156			    (char_u *)VAR_WIN, PV_FDI,
1157			    {(char_u *)"#", (char_u *)NULL} SCRIPTID_INIT},
1158    {"foldlevel",   "fdl",  P_NUM|P_VI_DEF|P_RWIN,
1159			    (char_u *)VAR_WIN, PV_FDL,
1160			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
1161    {"foldlevelstart","fdls", P_NUM|P_VI_DEF,
1162			    (char_u *)&p_fdls, PV_NONE,
1163			    {(char_u *)-1L, (char_u *)0L} SCRIPTID_INIT},
1164    {"foldmarker",  "fmr",  P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|
1165						       P_RWIN|P_COMMA|P_NODUP,
1166			    (char_u *)VAR_WIN, PV_FMR,
1167			    {(char_u *)"{{{,}}}", (char_u *)NULL}
1168			    SCRIPTID_INIT},
1169    {"foldmethod",  "fdm",  P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN,
1170			    (char_u *)VAR_WIN, PV_FDM,
1171			    {(char_u *)"manual", (char_u *)NULL} SCRIPTID_INIT},
1172    {"foldminlines","fml",  P_NUM|P_VI_DEF|P_RWIN,
1173			    (char_u *)VAR_WIN, PV_FML,
1174			    {(char_u *)1L, (char_u *)0L} SCRIPTID_INIT},
1175    {"foldnestmax", "fdn",  P_NUM|P_VI_DEF|P_RWIN,
1176			    (char_u *)VAR_WIN, PV_FDN,
1177			    {(char_u *)20L, (char_u *)0L} SCRIPTID_INIT},
1178    {"foldopen",    "fdo",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
1179			    (char_u *)&p_fdo, PV_NONE,
1180		 {(char_u *)"block,hor,mark,percent,quickfix,search,tag,undo",
1181						 (char_u *)0L} SCRIPTID_INIT},
1182    {"foldtext",    "fdt",  P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN,
1183# ifdef FEAT_EVAL
1184			    (char_u *)VAR_WIN, PV_FDT,
1185			    {(char_u *)"foldtext()", (char_u *)NULL}
1186# else
1187			    (char_u *)NULL, PV_NONE,
1188			    {(char_u *)NULL, (char_u *)0L}
1189# endif
1190			    SCRIPTID_INIT},
1191#endif
1192    {"formatexpr", "fex",   P_STRING|P_ALLOCED|P_VI_DEF|P_VIM,
1193#ifdef FEAT_EVAL
1194			    (char_u *)&p_fex, PV_FEX,
1195			    {(char_u *)"", (char_u *)0L}
1196#else
1197			    (char_u *)NULL, PV_NONE,
1198			    {(char_u *)0L, (char_u *)0L}
1199#endif
1200			    SCRIPTID_INIT},
1201    {"formatoptions","fo",  P_STRING|P_ALLOCED|P_VIM|P_FLAGLIST,
1202			    (char_u *)&p_fo, PV_FO,
1203			    {(char_u *)DFLT_FO_VI, (char_u *)DFLT_FO_VIM}
1204			    SCRIPTID_INIT},
1205    {"formatlistpat","flp", P_STRING|P_ALLOCED|P_VI_DEF,
1206			    (char_u *)&p_flp, PV_FLP,
1207			    {(char_u *)"^\\s*\\d\\+[\\]:.)}\\t ]\\s*",
1208						 (char_u *)0L} SCRIPTID_INIT},
1209    {"formatprg",   "fp",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
1210			    (char_u *)&p_fp, PV_NONE,
1211			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
1212    {"fsync",       "fs",   P_BOOL|P_SECURE|P_VI_DEF,
1213#ifdef HAVE_FSYNC
1214			    (char_u *)&p_fs, PV_NONE,
1215			    {(char_u *)TRUE, (char_u *)0L}
1216#else
1217			    (char_u *)NULL, PV_NONE,
1218			    {(char_u *)FALSE, (char_u *)0L}
1219#endif
1220			    SCRIPTID_INIT},
1221    {"gdefault",    "gd",   P_BOOL|P_VI_DEF|P_VIM,
1222			    (char_u *)&p_gd, PV_NONE,
1223			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1224    {"graphic",	    "gr",   P_BOOL|P_VI_DEF,
1225			    (char_u *)NULL, PV_NONE,
1226			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1227    {"grepformat",  "gfm",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
1228#ifdef FEAT_QUICKFIX
1229			    (char_u *)&p_gefm, PV_NONE,
1230			    {(char_u *)DFLT_GREPFORMAT, (char_u *)0L}
1231#else
1232			    (char_u *)NULL, PV_NONE,
1233			    {(char_u *)NULL, (char_u *)0L}
1234#endif
1235			    SCRIPTID_INIT},
1236    {"grepprg",	    "gp",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
1237#ifdef FEAT_QUICKFIX
1238			    (char_u *)&p_gp, PV_GP,
1239			    {
1240# ifdef WIN3264
1241			    /* may be changed to "grep -n" in os_win32.c */
1242			    (char_u *)"findstr /n",
1243# else
1244#  ifdef UNIX
1245			    /* Add an extra file name so that grep will always
1246			     * insert a file name in the match line. */
1247			    (char_u *)"grep -n $* /dev/null",
1248#  else
1249#   ifdef VMS
1250			    (char_u *)"SEARCH/NUMBERS ",
1251#   else
1252			    (char_u *)"grep -n ",
1253#   endif
1254#  endif
1255# endif
1256			    (char_u *)0L}
1257#else
1258			    (char_u *)NULL, PV_NONE,
1259			    {(char_u *)NULL, (char_u *)0L}
1260#endif
1261			    SCRIPTID_INIT},
1262    {"guicursor",    "gcr",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
1263#ifdef CURSOR_SHAPE
1264			    (char_u *)&p_guicursor, PV_NONE,
1265			    {
1266# ifdef FEAT_GUI
1267				(char_u *)"n-v-c:block-Cursor/lCursor,ve:ver35-Cursor,o:hor50-Cursor,i-ci:ver25-Cursor/lCursor,r-cr:hor20-Cursor/lCursor,sm:block-Cursor-blinkwait175-blinkoff150-blinkon175",
1268# else	/* MSDOS or Win32 console */
1269				(char_u *)"n-v-c:block,o:hor50,i-ci:hor15,r-cr:hor30,sm:block",
1270# endif
1271				    (char_u *)0L}
1272#else
1273			    (char_u *)NULL, PV_NONE,
1274			    {(char_u *)NULL, (char_u *)0L}
1275#endif
1276			    SCRIPTID_INIT},
1277    {"guifont",	    "gfn",  P_STRING|P_VI_DEF|P_RCLR|P_COMMA|P_NODUP,
1278#ifdef FEAT_GUI
1279			    (char_u *)&p_guifont, PV_NONE,
1280			    {(char_u *)"", (char_u *)0L}
1281#else
1282			    (char_u *)NULL, PV_NONE,
1283			    {(char_u *)NULL, (char_u *)0L}
1284#endif
1285			    SCRIPTID_INIT},
1286    {"guifontset",  "gfs",  P_STRING|P_VI_DEF|P_RCLR|P_COMMA,
1287#if defined(FEAT_GUI) && defined(FEAT_XFONTSET)
1288			    (char_u *)&p_guifontset, PV_NONE,
1289			    {(char_u *)"", (char_u *)0L}
1290#else
1291			    (char_u *)NULL, PV_NONE,
1292			    {(char_u *)NULL, (char_u *)0L}
1293#endif
1294			    SCRIPTID_INIT},
1295    {"guifontwide", "gfw",  P_STRING|P_VI_DEF|P_RCLR|P_COMMA|P_NODUP,
1296#if defined(FEAT_GUI) && defined(FEAT_MBYTE)
1297			    (char_u *)&p_guifontwide, PV_NONE,
1298			    {(char_u *)"", (char_u *)0L}
1299#else
1300			    (char_u *)NULL, PV_NONE,
1301			    {(char_u *)NULL, (char_u *)0L}
1302#endif
1303			    SCRIPTID_INIT},
1304    {"guiheadroom", "ghr",  P_NUM|P_VI_DEF,
1305#if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_X11)
1306			    (char_u *)&p_ghr, PV_NONE,
1307#else
1308			    (char_u *)NULL, PV_NONE,
1309#endif
1310			    {(char_u *)50L, (char_u *)0L} SCRIPTID_INIT},
1311    {"guioptions",  "go",   P_STRING|P_VI_DEF|P_RALL|P_FLAGLIST,
1312#if defined(FEAT_GUI)
1313			    (char_u *)&p_go, PV_NONE,
1314# if defined(UNIX) && !defined(MACOS)
1315			    {(char_u *)"aegimrLtT", (char_u *)0L}
1316# else
1317			    {(char_u *)"egmrLtT", (char_u *)0L}
1318# endif
1319#else
1320			    (char_u *)NULL, PV_NONE,
1321			    {(char_u *)NULL, (char_u *)0L}
1322#endif
1323			    SCRIPTID_INIT},
1324    {"guipty",	    NULL,   P_BOOL|P_VI_DEF,
1325#if defined(FEAT_GUI)
1326			    (char_u *)&p_guipty, PV_NONE,
1327#else
1328			    (char_u *)NULL, PV_NONE,
1329#endif
1330			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
1331    {"guitablabel",  "gtl", P_STRING|P_VI_DEF|P_RWIN,
1332#if defined(FEAT_GUI_TABLINE)
1333			    (char_u *)&p_gtl, PV_NONE,
1334			    {(char_u *)"", (char_u *)0L}
1335#else
1336			    (char_u *)NULL, PV_NONE,
1337			    {(char_u *)NULL, (char_u *)0L}
1338#endif
1339			    SCRIPTID_INIT},
1340    {"guitabtooltip",  "gtt", P_STRING|P_VI_DEF|P_RWIN,
1341#if defined(FEAT_GUI_TABLINE)
1342			    (char_u *)&p_gtt, PV_NONE,
1343			    {(char_u *)"", (char_u *)0L}
1344#else
1345			    (char_u *)NULL, PV_NONE,
1346			    {(char_u *)NULL, (char_u *)0L}
1347#endif
1348			    SCRIPTID_INIT},
1349    {"hardtabs",    "ht",   P_NUM|P_VI_DEF,
1350			    (char_u *)NULL, PV_NONE,
1351			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
1352    {"helpfile",    "hf",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
1353			    (char_u *)&p_hf, PV_NONE,
1354			    {(char_u *)DFLT_HELPFILE, (char_u *)0L}
1355			    SCRIPTID_INIT},
1356    {"helpheight",  "hh",   P_NUM|P_VI_DEF,
1357#ifdef FEAT_WINDOWS
1358			    (char_u *)&p_hh, PV_NONE,
1359#else
1360			    (char_u *)NULL, PV_NONE,
1361#endif
1362			    {(char_u *)20L, (char_u *)0L} SCRIPTID_INIT},
1363    {"helplang",    "hlg",  P_STRING|P_VI_DEF|P_COMMA,
1364#ifdef FEAT_MULTI_LANG
1365			    (char_u *)&p_hlg, PV_NONE,
1366			    {(char_u *)"", (char_u *)0L}
1367#else
1368			    (char_u *)NULL, PV_NONE,
1369			    {(char_u *)0L, (char_u *)0L}
1370#endif
1371			    SCRIPTID_INIT},
1372    {"hidden",	    "hid",  P_BOOL|P_VI_DEF,
1373			    (char_u *)&p_hid, PV_NONE,
1374			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1375    {"highlight",   "hl",   P_STRING|P_VI_DEF|P_RCLR|P_COMMA|P_NODUP,
1376			    (char_u *)&p_hl, PV_NONE,
1377			    {(char_u *)HIGHLIGHT_INIT, (char_u *)0L}
1378			    SCRIPTID_INIT},
1379    {"history",	    "hi",   P_NUM|P_VIM,
1380			    (char_u *)&p_hi, PV_NONE,
1381			    {(char_u *)0L, (char_u *)20L} SCRIPTID_INIT},
1382    {"hkmap",	    "hk",   P_BOOL|P_VI_DEF|P_VIM,
1383#ifdef FEAT_RIGHTLEFT
1384			    (char_u *)&p_hkmap, PV_NONE,
1385#else
1386			    (char_u *)NULL, PV_NONE,
1387#endif
1388			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1389    {"hkmapp",	    "hkp",  P_BOOL|P_VI_DEF|P_VIM,
1390#ifdef FEAT_RIGHTLEFT
1391			    (char_u *)&p_hkmapp, PV_NONE,
1392#else
1393			    (char_u *)NULL, PV_NONE,
1394#endif
1395			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1396    {"hlsearch",    "hls",  P_BOOL|P_VI_DEF|P_VIM|P_RALL,
1397			    (char_u *)&p_hls, PV_NONE,
1398			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1399    {"icon",	    NULL,   P_BOOL|P_VI_DEF,
1400#ifdef FEAT_TITLE
1401			    (char_u *)&p_icon, PV_NONE,
1402#else
1403			    (char_u *)NULL, PV_NONE,
1404#endif
1405			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1406    {"iconstring",  NULL,   P_STRING|P_VI_DEF,
1407#ifdef FEAT_TITLE
1408			    (char_u *)&p_iconstring, PV_NONE,
1409#else
1410			    (char_u *)NULL, PV_NONE,
1411#endif
1412			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
1413    {"ignorecase",  "ic",   P_BOOL|P_VI_DEF,
1414			    (char_u *)&p_ic, PV_NONE,
1415			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1416    {"imactivatekey","imak",P_STRING|P_VI_DEF,
1417#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
1418			    (char_u *)&p_imak, PV_NONE,
1419#else
1420			    (char_u *)NULL, PV_NONE,
1421#endif
1422			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
1423    {"imcmdline",   "imc",  P_BOOL|P_VI_DEF,
1424#ifdef USE_IM_CONTROL
1425			    (char_u *)&p_imcmdline, PV_NONE,
1426#else
1427			    (char_u *)NULL, PV_NONE,
1428#endif
1429			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1430    {"imdisable",   "imd",  P_BOOL|P_VI_DEF,
1431#ifdef USE_IM_CONTROL
1432			    (char_u *)&p_imdisable, PV_NONE,
1433#else
1434			    (char_u *)NULL, PV_NONE,
1435#endif
1436#ifdef __sgi
1437			    {(char_u *)TRUE, (char_u *)0L}
1438#else
1439			    {(char_u *)FALSE, (char_u *)0L}
1440#endif
1441			    SCRIPTID_INIT},
1442    {"iminsert",    "imi",  P_NUM|P_VI_DEF,
1443			    (char_u *)&p_iminsert, PV_IMI,
1444#ifdef B_IMODE_IM
1445			    {(char_u *)B_IMODE_IM, (char_u *)0L}
1446#else
1447			    {(char_u *)B_IMODE_NONE, (char_u *)0L}
1448#endif
1449			    SCRIPTID_INIT},
1450    {"imsearch",    "ims",  P_NUM|P_VI_DEF,
1451			    (char_u *)&p_imsearch, PV_IMS,
1452#ifdef B_IMODE_IM
1453			    {(char_u *)B_IMODE_IM, (char_u *)0L}
1454#else
1455			    {(char_u *)B_IMODE_NONE, (char_u *)0L}
1456#endif
1457			    SCRIPTID_INIT},
1458    {"include",	    "inc",  P_STRING|P_ALLOCED|P_VI_DEF,
1459#ifdef FEAT_FIND_ID
1460			    (char_u *)&p_inc, PV_INC,
1461			    {(char_u *)"^\\s*#\\s*include", (char_u *)0L}
1462#else
1463			    (char_u *)NULL, PV_NONE,
1464			    {(char_u *)0L, (char_u *)0L}
1465#endif
1466			    SCRIPTID_INIT},
1467    {"includeexpr", "inex", P_STRING|P_ALLOCED|P_VI_DEF,
1468#if defined(FEAT_FIND_ID) && defined(FEAT_EVAL)
1469			    (char_u *)&p_inex, PV_INEX,
1470			    {(char_u *)"", (char_u *)0L}
1471#else
1472			    (char_u *)NULL, PV_NONE,
1473			    {(char_u *)0L, (char_u *)0L}
1474#endif
1475			    SCRIPTID_INIT},
1476    {"incsearch",   "is",   P_BOOL|P_VI_DEF|P_VIM,
1477			    (char_u *)&p_is, PV_NONE,
1478			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1479    {"indentexpr", "inde",  P_STRING|P_ALLOCED|P_VI_DEF|P_VIM,
1480#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
1481			    (char_u *)&p_inde, PV_INDE,
1482			    {(char_u *)"", (char_u *)0L}
1483#else
1484			    (char_u *)NULL, PV_NONE,
1485			    {(char_u *)0L, (char_u *)0L}
1486#endif
1487			    SCRIPTID_INIT},
1488    {"indentkeys", "indk",  P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
1489#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
1490			    (char_u *)&p_indk, PV_INDK,
1491			    {(char_u *)"0{,0},:,0#,!^F,o,O,e", (char_u *)0L}
1492#else
1493			    (char_u *)NULL, PV_NONE,
1494			    {(char_u *)0L, (char_u *)0L}
1495#endif
1496			    SCRIPTID_INIT},
1497    {"infercase",   "inf",  P_BOOL|P_VI_DEF,
1498			    (char_u *)&p_inf, PV_INF,
1499			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1500    {"insertmode",  "im",   P_BOOL|P_VI_DEF|P_VIM,
1501			    (char_u *)&p_im, PV_NONE,
1502			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1503    {"isfname",	    "isf",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
1504			    (char_u *)&p_isf, PV_NONE,
1505			    {
1506#ifdef BACKSLASH_IN_FILENAME
1507				/* Excluded are: & and ^ are special in cmd.exe
1508				 * ( and ) are used in text separating fnames */
1509			    (char_u *)"@,48-57,/,\\,.,-,_,+,,,#,$,%,{,},[,],:,@-@,!,~,=",
1510#else
1511# ifdef AMIGA
1512			    (char_u *)"@,48-57,/,.,-,_,+,,,$,:",
1513# else
1514#  ifdef VMS
1515			    (char_u *)"@,48-57,/,.,-,_,+,,,#,$,%,<,>,[,],:,;,~",
1516#  else /* UNIX et al. */
1517#   ifdef EBCDIC
1518			    (char_u *)"@,240-249,/,.,-,_,+,,,#,$,%,~,=",
1519#   else
1520			    (char_u *)"@,48-57,/,.,-,_,+,,,#,$,%,~,=",
1521#   endif
1522#  endif
1523# endif
1524#endif
1525				(char_u *)0L} SCRIPTID_INIT},
1526    {"isident",	    "isi",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
1527			    (char_u *)&p_isi, PV_NONE,
1528			    {
1529#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
1530			    (char_u *)"@,48-57,_,128-167,224-235",
1531#else
1532# ifdef EBCDIC
1533			    /* TODO: EBCDIC Check this! @ == isalpha()*/
1534			    (char_u *)"@,240-249,_,66-73,81-89,98-105,"
1535				    "112-120,128,140-142,156,158,172,"
1536				    "174,186,191,203-207,219-225,235-239,"
1537				    "251-254",
1538# else
1539			    (char_u *)"@,48-57,_,192-255",
1540# endif
1541#endif
1542				(char_u *)0L} SCRIPTID_INIT},
1543    {"iskeyword",   "isk",  P_STRING|P_ALLOCED|P_VIM|P_COMMA|P_NODUP,
1544			    (char_u *)&p_isk, PV_ISK,
1545			    {
1546#ifdef EBCDIC
1547			     (char_u *)"@,240-249,_",
1548			     /* TODO: EBCDIC Check this! @ == isalpha()*/
1549			     (char_u *)"@,240-249,_,66-73,81-89,98-105,"
1550				    "112-120,128,140-142,156,158,172,"
1551				    "174,186,191,203-207,219-225,235-239,"
1552				    "251-254",
1553#else
1554				(char_u *)"@,48-57,_",
1555# if defined(MSDOS) || defined(MSWIN) || defined(OS2)
1556				(char_u *)"@,48-57,_,128-167,224-235"
1557# else
1558				ISK_LATIN1
1559# endif
1560#endif
1561			    } SCRIPTID_INIT},
1562    {"isprint",	    "isp",  P_STRING|P_VI_DEF|P_RALL|P_COMMA|P_NODUP,
1563			    (char_u *)&p_isp, PV_NONE,
1564			    {
1565#if defined(MSDOS) || defined(MSWIN) || defined(OS2) \
1566		|| (defined(MACOS) && !defined(MACOS_X)) \
1567		|| defined(VMS)
1568			    (char_u *)"@,~-255",
1569#else
1570# ifdef EBCDIC
1571			    /* all chars above 63 are printable */
1572			    (char_u *)"63-255",
1573# else
1574			    ISP_LATIN1,
1575# endif
1576#endif
1577				(char_u *)0L} SCRIPTID_INIT},
1578    {"joinspaces",  "js",   P_BOOL|P_VI_DEF|P_VIM,
1579			    (char_u *)&p_js, PV_NONE,
1580			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
1581    {"key",	    NULL,   P_STRING|P_ALLOCED|P_VI_DEF|P_NO_MKRC,
1582#ifdef FEAT_CRYPT
1583			    (char_u *)&p_key, PV_KEY,
1584			    {(char_u *)"", (char_u *)0L}
1585#else
1586			    (char_u *)NULL, PV_NONE,
1587			    {(char_u *)0L, (char_u *)0L}
1588#endif
1589			    SCRIPTID_INIT},
1590    {"keymap",	    "kmp",  P_STRING|P_ALLOCED|P_VI_DEF|P_RBUF|P_RSTAT|P_NFNAME|P_PRI_MKRC,
1591#ifdef FEAT_KEYMAP
1592			    (char_u *)&p_keymap, PV_KMAP,
1593			    {(char_u *)"", (char_u *)0L}
1594#else
1595			    (char_u *)NULL, PV_NONE,
1596			    {(char_u *)"", (char_u *)0L}
1597#endif
1598			    SCRIPTID_INIT},
1599    {"keymodel",    "km",   P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
1600#ifdef FEAT_VISUAL
1601			    (char_u *)&p_km, PV_NONE,
1602#else
1603			    (char_u *)NULL, PV_NONE,
1604#endif
1605			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
1606    {"keywordprg",  "kp",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
1607			    (char_u *)&p_kp, PV_KP,
1608			    {
1609#if defined(MSDOS) || defined(MSWIN)
1610			    (char_u *)":help",
1611#else
1612#ifdef VMS
1613			    (char_u *)"help",
1614#else
1615# if defined(OS2)
1616			    (char_u *)"view /",
1617# else
1618#  ifdef USEMAN_S
1619			    (char_u *)"man -s",
1620#  else
1621			    (char_u *)"man",
1622#  endif
1623# endif
1624#endif
1625#endif
1626				(char_u *)0L} SCRIPTID_INIT},
1627    {"langmap",     "lmap", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
1628#ifdef FEAT_LANGMAP
1629			    (char_u *)&p_langmap, PV_NONE,
1630			    {(char_u *)"",	/* unmatched } */
1631#else
1632			    (char_u *)NULL, PV_NONE,
1633			    {(char_u *)NULL,
1634#endif
1635				(char_u *)0L} SCRIPTID_INIT},
1636    {"langmenu",    "lm",   P_STRING|P_VI_DEF|P_NFNAME,
1637#if defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)
1638			    (char_u *)&p_lm, PV_NONE,
1639#else
1640			    (char_u *)NULL, PV_NONE,
1641#endif
1642			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
1643    {"laststatus",  "ls",   P_NUM|P_VI_DEF|P_RALL,
1644#ifdef FEAT_WINDOWS
1645			    (char_u *)&p_ls, PV_NONE,
1646#else
1647			    (char_u *)NULL, PV_NONE,
1648#endif
1649			    {(char_u *)1L, (char_u *)0L} SCRIPTID_INIT},
1650    {"lazyredraw",  "lz",   P_BOOL|P_VI_DEF,
1651			    (char_u *)&p_lz, PV_NONE,
1652			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1653    {"linebreak",   "lbr",  P_BOOL|P_VI_DEF|P_RWIN,
1654#ifdef FEAT_LINEBREAK
1655			    (char_u *)VAR_WIN, PV_LBR,
1656#else
1657			    (char_u *)NULL, PV_NONE,
1658#endif
1659			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1660    {"lines",	    NULL,   P_NUM|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RCLR,
1661			    (char_u *)&Rows, PV_NONE,
1662			    {
1663#if defined(MSDOS) || defined(WIN3264) || defined(OS2)
1664			    (char_u *)25L,
1665#else
1666			    (char_u *)24L,
1667#endif
1668					    (char_u *)0L} SCRIPTID_INIT},
1669    {"linespace",   "lsp",  P_NUM|P_VI_DEF|P_RCLR,
1670#ifdef FEAT_GUI
1671			    (char_u *)&p_linespace, PV_NONE,
1672#else
1673			    (char_u *)NULL, PV_NONE,
1674#endif
1675#ifdef FEAT_GUI_W32
1676			    {(char_u *)1L, (char_u *)0L}
1677#else
1678			    {(char_u *)0L, (char_u *)0L}
1679#endif
1680			    SCRIPTID_INIT},
1681    {"lisp",	    NULL,   P_BOOL|P_VI_DEF,
1682#ifdef FEAT_LISP
1683			    (char_u *)&p_lisp, PV_LISP,
1684#else
1685			    (char_u *)NULL, PV_NONE,
1686#endif
1687			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1688    {"lispwords",   "lw",   P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
1689#ifdef FEAT_LISP
1690			    (char_u *)&p_lispwords, PV_NONE,
1691			    {(char_u *)LISPWORD_VALUE, (char_u *)0L}
1692#else
1693			    (char_u *)NULL, PV_NONE,
1694			    {(char_u *)"", (char_u *)0L}
1695#endif
1696			    SCRIPTID_INIT},
1697    {"list",	    NULL,   P_BOOL|P_VI_DEF|P_RWIN,
1698			    (char_u *)VAR_WIN, PV_LIST,
1699			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1700    {"listchars",   "lcs",  P_STRING|P_VI_DEF|P_RALL|P_COMMA|P_NODUP,
1701			    (char_u *)&p_lcs, PV_NONE,
1702			    {(char_u *)"eol:$", (char_u *)0L} SCRIPTID_INIT},
1703    {"loadplugins", "lpl",  P_BOOL|P_VI_DEF,
1704			    (char_u *)&p_lpl, PV_NONE,
1705			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
1706#ifdef FEAT_GUI_MAC
1707    {"macatsui",    NULL,   P_BOOL|P_VI_DEF|P_RCLR,
1708			    (char_u *)&p_macatsui, PV_NONE,
1709			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
1710#endif
1711    {"magic",	    NULL,   P_BOOL|P_VI_DEF,
1712			    (char_u *)&p_magic, PV_NONE,
1713			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
1714    {"makeef",	    "mef",  P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
1715#ifdef FEAT_QUICKFIX
1716			    (char_u *)&p_mef, PV_NONE,
1717			    {(char_u *)"", (char_u *)0L}
1718#else
1719			    (char_u *)NULL, PV_NONE,
1720			    {(char_u *)NULL, (char_u *)0L}
1721#endif
1722			    SCRIPTID_INIT},
1723    {"makeprg",	    "mp",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
1724#ifdef FEAT_QUICKFIX
1725			    (char_u *)&p_mp, PV_MP,
1726# ifdef VMS
1727			    {(char_u *)"MMS", (char_u *)0L}
1728# else
1729			    {(char_u *)"make", (char_u *)0L}
1730# endif
1731#else
1732			    (char_u *)NULL, PV_NONE,
1733			    {(char_u *)NULL, (char_u *)0L}
1734#endif
1735			    SCRIPTID_INIT},
1736    {"matchpairs",  "mps",  P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
1737			    (char_u *)&p_mps, PV_MPS,
1738			    {(char_u *)"(:),{:},[:]", (char_u *)0L}
1739			    SCRIPTID_INIT},
1740    {"matchtime",   "mat",  P_NUM|P_VI_DEF,
1741			    (char_u *)&p_mat, PV_NONE,
1742			    {(char_u *)5L, (char_u *)0L} SCRIPTID_INIT},
1743    {"maxcombine",  "mco",  P_NUM|P_VI_DEF,
1744#ifdef FEAT_MBYTE
1745			    (char_u *)&p_mco, PV_NONE,
1746#else
1747			    (char_u *)NULL, PV_NONE,
1748#endif
1749			    {(char_u *)2, (char_u *)0L} SCRIPTID_INIT},
1750    {"maxfuncdepth", "mfd", P_NUM|P_VI_DEF,
1751#ifdef FEAT_EVAL
1752			    (char_u *)&p_mfd, PV_NONE,
1753#else
1754			    (char_u *)NULL, PV_NONE,
1755#endif
1756			    {(char_u *)100L, (char_u *)0L} SCRIPTID_INIT},
1757    {"maxmapdepth", "mmd",  P_NUM|P_VI_DEF,
1758			    (char_u *)&p_mmd, PV_NONE,
1759			    {(char_u *)1000L, (char_u *)0L} SCRIPTID_INIT},
1760    {"maxmem",	    "mm",   P_NUM|P_VI_DEF,
1761			    (char_u *)&p_mm, PV_NONE,
1762			    {(char_u *)DFLT_MAXMEM, (char_u *)0L}
1763			    SCRIPTID_INIT},
1764    {"maxmempattern","mmp", P_NUM|P_VI_DEF,
1765			    (char_u *)&p_mmp, PV_NONE,
1766			    {(char_u *)1000L, (char_u *)0L} SCRIPTID_INIT},
1767    {"maxmemtot",   "mmt",  P_NUM|P_VI_DEF,
1768			    (char_u *)&p_mmt, PV_NONE,
1769			    {(char_u *)DFLT_MAXMEMTOT, (char_u *)0L}
1770			    SCRIPTID_INIT},
1771    {"menuitems",   "mis",  P_NUM|P_VI_DEF,
1772#ifdef FEAT_MENU
1773			    (char_u *)&p_mis, PV_NONE,
1774#else
1775			    (char_u *)NULL, PV_NONE,
1776#endif
1777			    {(char_u *)25L, (char_u *)0L} SCRIPTID_INIT},
1778    {"mesg",	    NULL,   P_BOOL|P_VI_DEF,
1779			    (char_u *)NULL, PV_NONE,
1780			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1781    {"mkspellmem",  "msm",  P_STRING|P_VI_DEF|P_EXPAND|P_SECURE,
1782#ifdef FEAT_SPELL
1783			    (char_u *)&p_msm, PV_NONE,
1784			    {(char_u *)"460000,2000,500", (char_u *)0L}
1785#else
1786			    (char_u *)NULL, PV_NONE,
1787			    {(char_u *)0L, (char_u *)0L}
1788#endif
1789			    SCRIPTID_INIT},
1790    {"modeline",    "ml",   P_BOOL|P_VIM,
1791			    (char_u *)&p_ml, PV_ML,
1792			    {(char_u *)FALSE, (char_u *)TRUE} SCRIPTID_INIT},
1793    {"modelines",   "mls",  P_NUM|P_VI_DEF,
1794			    (char_u *)&p_mls, PV_NONE,
1795			    {(char_u *)5L, (char_u *)0L} SCRIPTID_INIT},
1796    {"modifiable",  "ma",   P_BOOL|P_VI_DEF|P_NOGLOB,
1797			    (char_u *)&p_ma, PV_MA,
1798			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
1799    {"modified",    "mod",  P_BOOL|P_NO_MKRC|P_VI_DEF|P_RSTAT,
1800			    (char_u *)&p_mod, PV_MOD,
1801			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1802    {"more",	    NULL,   P_BOOL|P_VIM,
1803			    (char_u *)&p_more, PV_NONE,
1804			    {(char_u *)FALSE, (char_u *)TRUE} SCRIPTID_INIT},
1805    {"mouse",	    NULL,   P_STRING|P_VI_DEF|P_FLAGLIST,
1806			    (char_u *)&p_mouse, PV_NONE,
1807			    {
1808#if defined(MSDOS) || defined(WIN3264)
1809				(char_u *)"a",
1810#else
1811				(char_u *)"",
1812#endif
1813				(char_u *)0L} SCRIPTID_INIT},
1814    {"mousefocus",   "mousef", P_BOOL|P_VI_DEF,
1815#ifdef FEAT_GUI
1816			    (char_u *)&p_mousef, PV_NONE,
1817#else
1818			    (char_u *)NULL, PV_NONE,
1819#endif
1820			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1821    {"mousehide",   "mh",   P_BOOL|P_VI_DEF,
1822#ifdef FEAT_GUI
1823			    (char_u *)&p_mh, PV_NONE,
1824#else
1825			    (char_u *)NULL, PV_NONE,
1826#endif
1827			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
1828    {"mousemodel",  "mousem", P_STRING|P_VI_DEF,
1829			    (char_u *)&p_mousem, PV_NONE,
1830			    {
1831#if defined(MSDOS) || defined(MSWIN)
1832				(char_u *)"popup",
1833#else
1834# if defined(MACOS)
1835				(char_u *)"popup_setpos",
1836# else
1837				(char_u *)"extend",
1838# endif
1839#endif
1840				(char_u *)0L} SCRIPTID_INIT},
1841    {"mouseshape",  "mouses",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
1842#ifdef FEAT_MOUSESHAPE
1843			    (char_u *)&p_mouseshape, PV_NONE,
1844			    {(char_u *)"i-r:beam,s:updown,sd:udsizing,vs:leftright,vd:lrsizing,m:no,ml:up-arrow,v:rightup-arrow", (char_u *)0L}
1845#else
1846			    (char_u *)NULL, PV_NONE,
1847			    {(char_u *)NULL, (char_u *)0L}
1848#endif
1849			    SCRIPTID_INIT},
1850    {"mousetime",   "mouset",	P_NUM|P_VI_DEF,
1851			    (char_u *)&p_mouset, PV_NONE,
1852			    {(char_u *)500L, (char_u *)0L} SCRIPTID_INIT},
1853    {"mzquantum",  "mzq",   P_NUM,
1854#ifdef FEAT_MZSCHEME
1855			    (char_u *)&p_mzq, PV_NONE,
1856#else
1857			    (char_u *)NULL, PV_NONE,
1858#endif
1859			    {(char_u *)100L, (char_u *)100L} SCRIPTID_INIT},
1860    {"novice",	    NULL,   P_BOOL|P_VI_DEF,
1861			    (char_u *)NULL, PV_NONE,
1862			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1863    {"nrformats",   "nf",   P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
1864			    (char_u *)&p_nf, PV_NF,
1865			    {(char_u *)"octal,hex", (char_u *)0L}
1866			    SCRIPTID_INIT},
1867    {"number",	    "nu",   P_BOOL|P_VI_DEF|P_RWIN,
1868			    (char_u *)VAR_WIN, PV_NU,
1869			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1870    {"numberwidth", "nuw",  P_NUM|P_RWIN|P_VIM,
1871#ifdef FEAT_LINEBREAK
1872			    (char_u *)VAR_WIN, PV_NUW,
1873#else
1874			    (char_u *)NULL, PV_NONE,
1875#endif
1876			    {(char_u *)8L, (char_u *)4L} SCRIPTID_INIT},
1877    {"omnifunc",    "ofu",  P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE,
1878#ifdef FEAT_COMPL_FUNC
1879			    (char_u *)&p_ofu, PV_OFU,
1880			    {(char_u *)"", (char_u *)0L}
1881#else
1882			    (char_u *)NULL, PV_NONE,
1883			    {(char_u *)0L, (char_u *)0L}
1884#endif
1885			    SCRIPTID_INIT},
1886    {"open",	    NULL,   P_BOOL|P_VI_DEF,
1887			    (char_u *)NULL, PV_NONE,
1888			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1889    {"opendevice",  "odev", P_BOOL|P_VI_DEF,
1890#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
1891			    (char_u *)&p_odev, PV_NONE,
1892#else
1893			    (char_u *)NULL, PV_NONE,
1894#endif
1895			    {(char_u *)FALSE, (char_u *)FALSE}
1896			    SCRIPTID_INIT},
1897    {"operatorfunc", "opfunc", P_STRING|P_VI_DEF|P_SECURE,
1898			    (char_u *)&p_opfunc, PV_NONE,
1899			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
1900    {"optimize",    "opt",  P_BOOL|P_VI_DEF,
1901			    (char_u *)NULL, PV_NONE,
1902			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1903    {"osfiletype",  "oft",  P_STRING|P_ALLOCED|P_VI_DEF,
1904#ifdef FEAT_OSFILETYPE
1905			    (char_u *)&p_oft, PV_OFT,
1906			    {(char_u *)DFLT_OFT, (char_u *)0L}
1907#else
1908			    (char_u *)NULL, PV_NONE,
1909			    {(char_u *)0L, (char_u *)0L}
1910#endif
1911			    SCRIPTID_INIT},
1912    {"paragraphs",  "para", P_STRING|P_VI_DEF,
1913			    (char_u *)&p_para, PV_NONE,
1914			    {(char_u *)"IPLPPPQPP TPHPLIPpLpItpplpipbp",
1915				(char_u *)0L} SCRIPTID_INIT},
1916    {"paste",	    NULL,   P_BOOL|P_VI_DEF|P_PRI_MKRC,
1917			    (char_u *)&p_paste, PV_NONE,
1918			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1919    {"pastetoggle", "pt",   P_STRING|P_VI_DEF,
1920			    (char_u *)&p_pt, PV_NONE,
1921			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
1922    {"patchexpr",   "pex",  P_STRING|P_VI_DEF|P_SECURE,
1923#if defined(FEAT_DIFF) && defined(FEAT_EVAL)
1924			    (char_u *)&p_pex, PV_NONE,
1925			    {(char_u *)"", (char_u *)0L}
1926#else
1927			    (char_u *)NULL, PV_NONE,
1928			    {(char_u *)0L, (char_u *)0L}
1929#endif
1930			    SCRIPTID_INIT},
1931    {"patchmode",   "pm",   P_STRING|P_VI_DEF|P_NFNAME,
1932			    (char_u *)&p_pm, PV_NONE,
1933			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
1934    {"path",	    "pa",   P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP,
1935			    (char_u *)&p_path, PV_PATH,
1936			    {
1937#if defined AMIGA || defined MSDOS || defined MSWIN
1938			    (char_u *)".,,",
1939#else
1940# if defined(__EMX__)
1941			    (char_u *)".,/emx/include,,",
1942# else /* Unix, probably */
1943			    (char_u *)".,/usr/include,,",
1944# endif
1945#endif
1946				(char_u *)0L} SCRIPTID_INIT},
1947    {"preserveindent", "pi", P_BOOL|P_VI_DEF|P_VIM,
1948			    (char_u *)&p_pi, PV_PI,
1949			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1950    {"previewheight", "pvh", P_NUM|P_VI_DEF,
1951#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
1952			    (char_u *)&p_pvh, PV_NONE,
1953#else
1954			    (char_u *)NULL, PV_NONE,
1955#endif
1956			    {(char_u *)12L, (char_u *)0L} SCRIPTID_INIT},
1957    {"previewwindow", "pvw", P_BOOL|P_VI_DEF|P_RSTAT|P_NOGLOB,
1958#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
1959			    (char_u *)VAR_WIN, PV_PVW,
1960#else
1961			    (char_u *)NULL, PV_NONE,
1962#endif
1963			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
1964    {"printdevice", "pdev", P_STRING|P_VI_DEF|P_SECURE,
1965#ifdef FEAT_PRINTER
1966			    (char_u *)&p_pdev, PV_NONE,
1967			    {(char_u *)"", (char_u *)0L}
1968#else
1969			    (char_u *)NULL, PV_NONE,
1970			    {(char_u *)NULL, (char_u *)0L}
1971#endif
1972			    SCRIPTID_INIT},
1973    {"printencoding", "penc", P_STRING|P_VI_DEF,
1974#ifdef FEAT_POSTSCRIPT
1975			    (char_u *)&p_penc, PV_NONE,
1976			    {(char_u *)"", (char_u *)0L}
1977#else
1978			    (char_u *)NULL, PV_NONE,
1979			    {(char_u *)NULL, (char_u *)0L}
1980#endif
1981			    SCRIPTID_INIT},
1982    {"printexpr", "pexpr",  P_STRING|P_VI_DEF,
1983#ifdef FEAT_POSTSCRIPT
1984			    (char_u *)&p_pexpr, PV_NONE,
1985			    {(char_u *)"", (char_u *)0L}
1986#else
1987			    (char_u *)NULL, PV_NONE,
1988			    {(char_u *)NULL, (char_u *)0L}
1989#endif
1990			    SCRIPTID_INIT},
1991    {"printfont", "pfn",    P_STRING|P_VI_DEF,
1992#ifdef FEAT_PRINTER
1993			    (char_u *)&p_pfn, PV_NONE,
1994			    {
1995# ifdef MSWIN
1996				(char_u *)"Courier_New:h10",
1997# else
1998				(char_u *)"courier",
1999# endif
2000				(char_u *)0L}
2001#else
2002			    (char_u *)NULL, PV_NONE,
2003			    {(char_u *)NULL, (char_u *)0L}
2004#endif
2005			    SCRIPTID_INIT},
2006    {"printheader", "pheader",  P_STRING|P_VI_DEF|P_GETTEXT,
2007#ifdef FEAT_PRINTER
2008			    (char_u *)&p_header, PV_NONE,
2009			    {(char_u *)N_("%<%f%h%m%=Page %N"), (char_u *)0L}
2010#else
2011			    (char_u *)NULL, PV_NONE,
2012			    {(char_u *)NULL, (char_u *)0L}
2013#endif
2014			    SCRIPTID_INIT},
2015   {"printmbcharset", "pmbcs",  P_STRING|P_VI_DEF,
2016#if defined(FEAT_POSTSCRIPT) && defined(FEAT_MBYTE)
2017			    (char_u *)&p_pmcs, PV_NONE,
2018			    {(char_u *)"", (char_u *)0L}
2019#else
2020			    (char_u *)NULL, PV_NONE,
2021			    {(char_u *)NULL, (char_u *)0L}
2022#endif
2023			    SCRIPTID_INIT},
2024    {"printmbfont", "pmbfn",  P_STRING|P_VI_DEF,
2025#if defined(FEAT_POSTSCRIPT) && defined(FEAT_MBYTE)
2026			    (char_u *)&p_pmfn, PV_NONE,
2027			    {(char_u *)"", (char_u *)0L}
2028#else
2029			    (char_u *)NULL, PV_NONE,
2030			    {(char_u *)NULL, (char_u *)0L}
2031#endif
2032			    SCRIPTID_INIT},
2033    {"printoptions", "popt", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
2034#ifdef FEAT_PRINTER
2035			    (char_u *)&p_popt, PV_NONE,
2036			    {(char_u *)"", (char_u *)0L}
2037#else
2038			    (char_u *)NULL, PV_NONE,
2039			    {(char_u *)NULL, (char_u *)0L}
2040#endif
2041			    SCRIPTID_INIT},
2042    {"prompt",	    NULL,   P_BOOL|P_VI_DEF,
2043			    (char_u *)&p_prompt, PV_NONE,
2044			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
2045    {"pumheight",   "ph",   P_NUM|P_VI_DEF,
2046#ifdef FEAT_INS_EXPAND
2047			    (char_u *)&p_ph, PV_NONE,
2048#else
2049			    (char_u *)NULL, PV_NONE,
2050#endif
2051			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
2052    {"quoteescape", "qe",   P_STRING|P_ALLOCED|P_VI_DEF,
2053#ifdef FEAT_TEXTOBJ
2054			    (char_u *)&p_qe, PV_QE,
2055			    {(char_u *)"\\", (char_u *)0L}
2056#else
2057			    (char_u *)NULL, PV_NONE,
2058			    {(char_u *)NULL, (char_u *)0L}
2059#endif
2060			    SCRIPTID_INIT},
2061    {"readonly",    "ro",   P_BOOL|P_VI_DEF|P_RSTAT|P_NOGLOB,
2062			    (char_u *)&readonlymode, PV_RO,
2063			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2064    {"redraw",	    NULL,   P_BOOL|P_VI_DEF,
2065			    (char_u *)NULL, PV_NONE,
2066			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2067    {"redrawtime",  "rdt",  P_NUM|P_VI_DEF,
2068#ifdef FEAT_RELTIME
2069			    (char_u *)&p_rdt, PV_NONE,
2070#else
2071			    (char_u *)NULL, PV_NONE,
2072#endif
2073			    {(char_u *)2000L, (char_u *)0L} SCRIPTID_INIT},
2074    {"relativenumber", "rnu", P_BOOL|P_VI_DEF|P_RWIN,
2075			    (char_u *)VAR_WIN, PV_RNU,
2076			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2077    {"remap",	    NULL,   P_BOOL|P_VI_DEF,
2078			    (char_u *)&p_remap, PV_NONE,
2079			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
2080    {"report",	    NULL,   P_NUM|P_VI_DEF,
2081			    (char_u *)&p_report, PV_NONE,
2082			    {(char_u *)2L, (char_u *)0L} SCRIPTID_INIT},
2083    {"restorescreen", "rs", P_BOOL|P_VI_DEF,
2084#ifdef WIN3264
2085			    (char_u *)&p_rs, PV_NONE,
2086#else
2087			    (char_u *)NULL, PV_NONE,
2088#endif
2089			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
2090    {"revins",	    "ri",   P_BOOL|P_VI_DEF|P_VIM,
2091#ifdef FEAT_RIGHTLEFT
2092			    (char_u *)&p_ri, PV_NONE,
2093#else
2094			    (char_u *)NULL, PV_NONE,
2095#endif
2096			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2097    {"rightleft",   "rl",   P_BOOL|P_VI_DEF|P_RWIN,
2098#ifdef FEAT_RIGHTLEFT
2099			    (char_u *)VAR_WIN, PV_RL,
2100#else
2101			    (char_u *)NULL, PV_NONE,
2102#endif
2103			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2104    {"rightleftcmd", "rlc", P_STRING|P_ALLOCED|P_VI_DEF|P_RWIN,
2105#ifdef FEAT_RIGHTLEFT
2106			    (char_u *)VAR_WIN, PV_RLC,
2107			    {(char_u *)"search", (char_u *)NULL}
2108#else
2109			    (char_u *)NULL, PV_NONE,
2110			    {(char_u *)NULL, (char_u *)0L}
2111#endif
2112			    SCRIPTID_INIT},
2113    {"ruler",	    "ru",   P_BOOL|P_VI_DEF|P_VIM|P_RSTAT,
2114#ifdef FEAT_CMDL_INFO
2115			    (char_u *)&p_ru, PV_NONE,
2116#else
2117			    (char_u *)NULL, PV_NONE,
2118#endif
2119			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2120    {"rulerformat", "ruf",  P_STRING|P_VI_DEF|P_ALLOCED|P_RSTAT,
2121#ifdef FEAT_STL_OPT
2122			    (char_u *)&p_ruf, PV_NONE,
2123#else
2124			    (char_u *)NULL, PV_NONE,
2125#endif
2126			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
2127    {"runtimepath", "rtp",  P_STRING|P_VI_DEF|P_EXPAND|P_COMMA|P_NODUP|P_SECURE,
2128			    (char_u *)&p_rtp, PV_NONE,
2129			    {(char_u *)DFLT_RUNTIMEPATH, (char_u *)0L}
2130			    SCRIPTID_INIT},
2131    {"scroll",	    "scr",  P_NUM|P_NO_MKRC|P_VI_DEF,
2132			    (char_u *)VAR_WIN, PV_SCROLL,
2133			    {(char_u *)12L, (char_u *)0L} SCRIPTID_INIT},
2134    {"scrollbind",  "scb",  P_BOOL|P_VI_DEF,
2135#ifdef FEAT_SCROLLBIND
2136			    (char_u *)VAR_WIN, PV_SCBIND,
2137#else
2138			    (char_u *)NULL, PV_NONE,
2139#endif
2140			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2141    {"scrolljump",  "sj",   P_NUM|P_VI_DEF|P_VIM,
2142			    (char_u *)&p_sj, PV_NONE,
2143			    {(char_u *)1L, (char_u *)0L} SCRIPTID_INIT},
2144    {"scrolloff",   "so",   P_NUM|P_VI_DEF|P_VIM|P_RALL,
2145			    (char_u *)&p_so, PV_NONE,
2146			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
2147    {"scrollopt",   "sbo",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
2148#ifdef FEAT_SCROLLBIND
2149			    (char_u *)&p_sbo, PV_NONE,
2150			    {(char_u *)"ver,jump", (char_u *)0L}
2151#else
2152			    (char_u *)NULL, PV_NONE,
2153			    {(char_u *)0L, (char_u *)0L}
2154#endif
2155			    SCRIPTID_INIT},
2156    {"sections",    "sect", P_STRING|P_VI_DEF,
2157			    (char_u *)&p_sections, PV_NONE,
2158			    {(char_u *)"SHNHH HUnhsh", (char_u *)0L}
2159			    SCRIPTID_INIT},
2160    {"secure",	    NULL,   P_BOOL|P_VI_DEF|P_SECURE,
2161			    (char_u *)&p_secure, PV_NONE,
2162			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2163    {"selection",   "sel",  P_STRING|P_VI_DEF,
2164#ifdef FEAT_VISUAL
2165			    (char_u *)&p_sel, PV_NONE,
2166#else
2167			    (char_u *)NULL, PV_NONE,
2168#endif
2169			    {(char_u *)"inclusive", (char_u *)0L}
2170			    SCRIPTID_INIT},
2171    {"selectmode",  "slm",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
2172#ifdef FEAT_VISUAL
2173			    (char_u *)&p_slm, PV_NONE,
2174#else
2175			    (char_u *)NULL, PV_NONE,
2176#endif
2177			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
2178    {"sessionoptions", "ssop", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
2179#ifdef FEAT_SESSION
2180			    (char_u *)&p_ssop, PV_NONE,
2181	 {(char_u *)"blank,buffers,curdir,folds,help,options,tabpages,winsize",
2182							       (char_u *)0L}
2183#else
2184			    (char_u *)NULL, PV_NONE,
2185			    {(char_u *)0L, (char_u *)0L}
2186#endif
2187			    SCRIPTID_INIT},
2188    {"shell",	    "sh",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
2189			    (char_u *)&p_sh, PV_NONE,
2190			    {
2191#ifdef VMS
2192			    (char_u *)"-",
2193#else
2194# if defined(MSDOS)
2195			    (char_u *)"command",
2196# else
2197#  if defined(WIN16)
2198			    (char_u *)"command.com",
2199#  else
2200#   if defined(WIN3264)
2201			    (char_u *)"",	/* set in set_init_1() */
2202#   else
2203#    if defined(OS2)
2204			    (char_u *)"cmd.exe",
2205#    else
2206#     if defined(ARCHIE)
2207			    (char_u *)"gos",
2208#     else
2209			    (char_u *)"sh",
2210#     endif
2211#    endif
2212#   endif
2213#  endif
2214# endif
2215#endif /* VMS */
2216				(char_u *)0L} SCRIPTID_INIT},
2217    {"shellcmdflag","shcf", P_STRING|P_VI_DEF|P_SECURE,
2218			    (char_u *)&p_shcf, PV_NONE,
2219			    {
2220#if defined(MSDOS) || defined(MSWIN)
2221			    (char_u *)"/c",
2222#else
2223# if defined(OS2)
2224			    (char_u *)"/c",
2225# else
2226			    (char_u *)"-c",
2227# endif
2228#endif
2229				(char_u *)0L} SCRIPTID_INIT},
2230    {"shellpipe",   "sp",   P_STRING|P_VI_DEF|P_SECURE,
2231#ifdef FEAT_QUICKFIX
2232			    (char_u *)&p_sp, PV_NONE,
2233			    {
2234#if defined(UNIX) || defined(OS2)
2235# ifdef ARCHIE
2236			    (char_u *)"2>",
2237# else
2238			    (char_u *)"| tee",
2239# endif
2240#else
2241			    (char_u *)">",
2242#endif
2243				(char_u *)0L}
2244#else
2245			    (char_u *)NULL, PV_NONE,
2246			    {(char_u *)0L, (char_u *)0L}
2247#endif
2248			    SCRIPTID_INIT},
2249    {"shellquote",  "shq",  P_STRING|P_VI_DEF|P_SECURE,
2250			    (char_u *)&p_shq, PV_NONE,
2251			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
2252    {"shellredir",  "srr",  P_STRING|P_VI_DEF|P_SECURE,
2253			    (char_u *)&p_srr, PV_NONE,
2254			    {(char_u *)">", (char_u *)0L} SCRIPTID_INIT},
2255    {"shellslash",  "ssl",   P_BOOL|P_VI_DEF,
2256#ifdef BACKSLASH_IN_FILENAME
2257			    (char_u *)&p_ssl, PV_NONE,
2258#else
2259			    (char_u *)NULL, PV_NONE,
2260#endif
2261			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2262    {"shelltemp",   "stmp", P_BOOL,
2263			    (char_u *)&p_stmp, PV_NONE,
2264			    {(char_u *)FALSE, (char_u *)TRUE} SCRIPTID_INIT},
2265    {"shelltype",   "st",   P_NUM|P_VI_DEF,
2266#ifdef AMIGA
2267			    (char_u *)&p_st, PV_NONE,
2268#else
2269			    (char_u *)NULL, PV_NONE,
2270#endif
2271			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
2272    {"shellxquote", "sxq",  P_STRING|P_VI_DEF|P_SECURE,
2273			    (char_u *)&p_sxq, PV_NONE,
2274			    {
2275#if defined(UNIX) && defined(USE_SYSTEM) && !defined(__EMX__)
2276			    (char_u *)"\"",
2277#else
2278			    (char_u *)"",
2279#endif
2280				(char_u *)0L} SCRIPTID_INIT},
2281    {"shiftround",  "sr",   P_BOOL|P_VI_DEF|P_VIM,
2282			    (char_u *)&p_sr, PV_NONE,
2283			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2284    {"shiftwidth",  "sw",   P_NUM|P_VI_DEF,
2285			    (char_u *)&p_sw, PV_SW,
2286			    {(char_u *)8L, (char_u *)0L} SCRIPTID_INIT},
2287    {"shortmess",   "shm",  P_STRING|P_VIM|P_FLAGLIST,
2288			    (char_u *)&p_shm, PV_NONE,
2289			    {(char_u *)"", (char_u *)"filnxtToO"}
2290			    SCRIPTID_INIT},
2291    {"shortname",   "sn",   P_BOOL|P_VI_DEF,
2292#ifdef SHORT_FNAME
2293			    (char_u *)NULL, PV_NONE,
2294#else
2295			    (char_u *)&p_sn, PV_SN,
2296#endif
2297			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2298    {"showbreak",   "sbr",  P_STRING|P_VI_DEF|P_RALL,
2299#ifdef FEAT_LINEBREAK
2300			    (char_u *)&p_sbr, PV_NONE,
2301#else
2302			    (char_u *)NULL, PV_NONE,
2303#endif
2304			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
2305    {"showcmd",	    "sc",   P_BOOL|P_VIM,
2306#ifdef FEAT_CMDL_INFO
2307			    (char_u *)&p_sc, PV_NONE,
2308#else
2309			    (char_u *)NULL, PV_NONE,
2310#endif
2311			    {(char_u *)FALSE,
2312#ifdef UNIX
2313				(char_u *)FALSE
2314#else
2315				(char_u *)TRUE
2316#endif
2317				} SCRIPTID_INIT},
2318    {"showfulltag", "sft",  P_BOOL|P_VI_DEF,
2319			    (char_u *)&p_sft, PV_NONE,
2320			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2321    {"showmatch",   "sm",   P_BOOL|P_VI_DEF,
2322			    (char_u *)&p_sm, PV_NONE,
2323			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2324    {"showmode",    "smd",  P_BOOL|P_VIM,
2325			    (char_u *)&p_smd, PV_NONE,
2326			    {(char_u *)FALSE, (char_u *)TRUE} SCRIPTID_INIT},
2327    {"showtabline", "stal", P_NUM|P_VI_DEF|P_RALL,
2328#ifdef FEAT_WINDOWS
2329			    (char_u *)&p_stal, PV_NONE,
2330#else
2331			    (char_u *)NULL, PV_NONE,
2332#endif
2333			    {(char_u *)1L, (char_u *)0L} SCRIPTID_INIT},
2334    {"sidescroll",  "ss",   P_NUM|P_VI_DEF,
2335			    (char_u *)&p_ss, PV_NONE,
2336			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
2337    {"sidescrolloff", "siso", P_NUM|P_VI_DEF|P_VIM|P_RBUF,
2338			    (char_u *)&p_siso, PV_NONE,
2339			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
2340    {"slowopen",    "slow", P_BOOL|P_VI_DEF,
2341			    (char_u *)NULL, PV_NONE,
2342			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2343    {"smartcase",   "scs",  P_BOOL|P_VI_DEF|P_VIM,
2344			    (char_u *)&p_scs, PV_NONE,
2345			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2346    {"smartindent", "si",   P_BOOL|P_VI_DEF|P_VIM,
2347#ifdef FEAT_SMARTINDENT
2348			    (char_u *)&p_si, PV_SI,
2349#else
2350			    (char_u *)NULL, PV_NONE,
2351#endif
2352			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2353    {"smarttab",    "sta",  P_BOOL|P_VI_DEF|P_VIM,
2354			    (char_u *)&p_sta, PV_NONE,
2355			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2356    {"softtabstop", "sts",  P_NUM|P_VI_DEF|P_VIM,
2357			    (char_u *)&p_sts, PV_STS,
2358			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
2359    {"sourceany",   NULL,   P_BOOL|P_VI_DEF,
2360			    (char_u *)NULL, PV_NONE,
2361			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2362    {"spell",	    NULL,   P_BOOL|P_VI_DEF|P_RWIN,
2363#ifdef FEAT_SPELL
2364			    (char_u *)VAR_WIN, PV_SPELL,
2365#else
2366			    (char_u *)NULL, PV_NONE,
2367#endif
2368			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2369    {"spellcapcheck", "spc", P_STRING|P_ALLOCED|P_VI_DEF|P_RBUF,
2370#ifdef FEAT_SPELL
2371			    (char_u *)&p_spc, PV_SPC,
2372			    {(char_u *)"[.?!]\\_[\\])'\"	 ]\\+", (char_u *)0L}
2373#else
2374			    (char_u *)NULL, PV_NONE,
2375			    {(char_u *)0L, (char_u *)0L}
2376#endif
2377			    SCRIPTID_INIT},
2378    {"spellfile",   "spf",  P_STRING|P_EXPAND|P_ALLOCED|P_VI_DEF|P_SECURE|P_COMMA,
2379#ifdef FEAT_SPELL
2380			    (char_u *)&p_spf, PV_SPF,
2381			    {(char_u *)"", (char_u *)0L}
2382#else
2383			    (char_u *)NULL, PV_NONE,
2384			    {(char_u *)0L, (char_u *)0L}
2385#endif
2386			    SCRIPTID_INIT},
2387    {"spelllang",   "spl",  P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_RBUF|P_EXPAND,
2388#ifdef FEAT_SPELL
2389			    (char_u *)&p_spl, PV_SPL,
2390			    {(char_u *)"en", (char_u *)0L}
2391#else
2392			    (char_u *)NULL, PV_NONE,
2393			    {(char_u *)0L, (char_u *)0L}
2394#endif
2395			    SCRIPTID_INIT},
2396    {"spellsuggest", "sps", P_STRING|P_VI_DEF|P_EXPAND|P_SECURE|P_COMMA,
2397#ifdef FEAT_SPELL
2398			    (char_u *)&p_sps, PV_NONE,
2399			    {(char_u *)"best", (char_u *)0L}
2400#else
2401			    (char_u *)NULL, PV_NONE,
2402			    {(char_u *)0L, (char_u *)0L}
2403#endif
2404			    SCRIPTID_INIT},
2405    {"splitbelow",  "sb",   P_BOOL|P_VI_DEF,
2406#ifdef FEAT_WINDOWS
2407			    (char_u *)&p_sb, PV_NONE,
2408#else
2409			    (char_u *)NULL, PV_NONE,
2410#endif
2411			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2412    {"splitright",  "spr",  P_BOOL|P_VI_DEF,
2413#ifdef FEAT_VERTSPLIT
2414			    (char_u *)&p_spr, PV_NONE,
2415#else
2416			    (char_u *)NULL, PV_NONE,
2417#endif
2418			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2419    {"startofline", "sol",  P_BOOL|P_VI_DEF|P_VIM,
2420			    (char_u *)&p_sol, PV_NONE,
2421			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
2422    {"statusline"  ,"stl",  P_STRING|P_VI_DEF|P_ALLOCED|P_RSTAT,
2423#ifdef FEAT_STL_OPT
2424			    (char_u *)&p_stl, PV_STL,
2425#else
2426			    (char_u *)NULL, PV_NONE,
2427#endif
2428			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
2429    {"suffixes",    "su",   P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
2430			    (char_u *)&p_su, PV_NONE,
2431			    {(char_u *)".bak,~,.o,.h,.info,.swp,.obj",
2432				(char_u *)0L} SCRIPTID_INIT},
2433    {"suffixesadd", "sua",  P_STRING|P_VI_DEF|P_ALLOCED|P_COMMA|P_NODUP,
2434#ifdef FEAT_SEARCHPATH
2435			    (char_u *)&p_sua, PV_SUA,
2436			    {(char_u *)"", (char_u *)0L}
2437#else
2438			    (char_u *)NULL, PV_NONE,
2439			    {(char_u *)0L, (char_u *)0L}
2440#endif
2441			    SCRIPTID_INIT},
2442    {"swapfile",    "swf",  P_BOOL|P_VI_DEF|P_RSTAT,
2443			    (char_u *)&p_swf, PV_SWF,
2444			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
2445    {"swapsync",    "sws",  P_STRING|P_VI_DEF,
2446			    (char_u *)&p_sws, PV_NONE,
2447			    {(char_u *)"fsync", (char_u *)0L} SCRIPTID_INIT},
2448    {"switchbuf",   "swb",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
2449			    (char_u *)&p_swb, PV_NONE,
2450			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
2451    {"synmaxcol",   "smc",  P_NUM|P_VI_DEF|P_RBUF,
2452#ifdef FEAT_SYN_HL
2453			    (char_u *)&p_smc, PV_SMC,
2454			    {(char_u *)3000L, (char_u *)0L}
2455#else
2456			    (char_u *)NULL, PV_NONE,
2457			    {(char_u *)0L, (char_u *)0L}
2458#endif
2459			    SCRIPTID_INIT},
2460    {"syntax",	    "syn",  P_STRING|P_ALLOCED|P_VI_DEF|P_NOGLOB|P_NFNAME,
2461#ifdef FEAT_SYN_HL
2462			    (char_u *)&p_syn, PV_SYN,
2463			    {(char_u *)"", (char_u *)0L}
2464#else
2465			    (char_u *)NULL, PV_NONE,
2466			    {(char_u *)0L, (char_u *)0L}
2467#endif
2468			    SCRIPTID_INIT},
2469    {"tabline",	    "tal",  P_STRING|P_VI_DEF|P_RALL,
2470#ifdef FEAT_STL_OPT
2471			    (char_u *)&p_tal, PV_NONE,
2472#else
2473			    (char_u *)NULL, PV_NONE,
2474#endif
2475			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
2476    {"tabpagemax",  "tpm",  P_NUM|P_VI_DEF,
2477#ifdef FEAT_WINDOWS
2478			    (char_u *)&p_tpm, PV_NONE,
2479#else
2480			    (char_u *)NULL, PV_NONE,
2481#endif
2482			    {(char_u *)10L, (char_u *)0L} SCRIPTID_INIT},
2483    {"tabstop",	    "ts",   P_NUM|P_VI_DEF|P_RBUF,
2484			    (char_u *)&p_ts, PV_TS,
2485			    {(char_u *)8L, (char_u *)0L} SCRIPTID_INIT},
2486    {"tagbsearch",  "tbs",   P_BOOL|P_VI_DEF,
2487			    (char_u *)&p_tbs, PV_NONE,
2488#ifdef VMS	/* binary searching doesn't appear to work on VMS */
2489			    {(char_u *)0L, (char_u *)0L}
2490#else
2491			    {(char_u *)TRUE, (char_u *)0L}
2492#endif
2493			    SCRIPTID_INIT},
2494    {"taglength",   "tl",   P_NUM|P_VI_DEF,
2495			    (char_u *)&p_tl, PV_NONE,
2496			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
2497    {"tagrelative", "tr",   P_BOOL|P_VIM,
2498			    (char_u *)&p_tr, PV_NONE,
2499			    {(char_u *)FALSE, (char_u *)TRUE} SCRIPTID_INIT},
2500    {"tags",	    "tag",  P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP,
2501			    (char_u *)&p_tags, PV_TAGS,
2502			    {
2503#if defined(FEAT_EMACS_TAGS) && !defined(CASE_INSENSITIVE_FILENAME)
2504			    (char_u *)"./tags,./TAGS,tags,TAGS",
2505#else
2506			    (char_u *)"./tags,tags",
2507#endif
2508				(char_u *)0L} SCRIPTID_INIT},
2509    {"tagstack",    "tgst", P_BOOL|P_VI_DEF,
2510			    (char_u *)&p_tgst, PV_NONE,
2511			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
2512    {"term",	    NULL,   P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RALL,
2513			    (char_u *)&T_NAME, PV_NONE,
2514			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
2515    {"termbidi", "tbidi",   P_BOOL|P_VI_DEF,
2516#ifdef FEAT_ARABIC
2517			    (char_u *)&p_tbidi, PV_NONE,
2518#else
2519			    (char_u *)NULL, PV_NONE,
2520#endif
2521			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2522    {"termencoding", "tenc", P_STRING|P_VI_DEF|P_RCLR,
2523#ifdef FEAT_MBYTE
2524			    (char_u *)&p_tenc, PV_NONE,
2525			    {(char_u *)"", (char_u *)0L}
2526#else
2527			    (char_u *)NULL, PV_NONE,
2528			    {(char_u *)0L, (char_u *)0L}
2529#endif
2530			    SCRIPTID_INIT},
2531    {"terse",	    NULL,   P_BOOL|P_VI_DEF,
2532			    (char_u *)&p_terse, PV_NONE,
2533			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2534    {"textauto",    "ta",   P_BOOL|P_VIM,
2535			    (char_u *)&p_ta, PV_NONE,
2536			    {(char_u *)DFLT_TEXTAUTO, (char_u *)TRUE}
2537			    SCRIPTID_INIT},
2538    {"textmode",    "tx",   P_BOOL|P_VI_DEF|P_NO_MKRC,
2539			    (char_u *)&p_tx, PV_TX,
2540			    {
2541#ifdef USE_CRNL
2542			    (char_u *)TRUE,
2543#else
2544			    (char_u *)FALSE,
2545#endif
2546				(char_u *)0L} SCRIPTID_INIT},
2547    {"textwidth",   "tw",   P_NUM|P_VI_DEF|P_VIM|P_RBUF,
2548			    (char_u *)&p_tw, PV_TW,
2549			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
2550    {"thesaurus",   "tsr",  P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP,
2551#ifdef FEAT_INS_EXPAND
2552			    (char_u *)&p_tsr, PV_TSR,
2553#else
2554			    (char_u *)NULL, PV_NONE,
2555#endif
2556			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
2557    {"tildeop",	    "top",  P_BOOL|P_VI_DEF|P_VIM,
2558			    (char_u *)&p_to, PV_NONE,
2559			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2560    {"timeout",	    "to",   P_BOOL|P_VI_DEF,
2561			    (char_u *)&p_timeout, PV_NONE,
2562			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
2563    {"timeoutlen",  "tm",   P_NUM|P_VI_DEF,
2564			    (char_u *)&p_tm, PV_NONE,
2565			    {(char_u *)1000L, (char_u *)0L} SCRIPTID_INIT},
2566    {"title",	    NULL,   P_BOOL|P_VI_DEF,
2567#ifdef FEAT_TITLE
2568			    (char_u *)&p_title, PV_NONE,
2569#else
2570			    (char_u *)NULL, PV_NONE,
2571#endif
2572			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2573    {"titlelen",    NULL,   P_NUM|P_VI_DEF,
2574#ifdef FEAT_TITLE
2575			    (char_u *)&p_titlelen, PV_NONE,
2576#else
2577			    (char_u *)NULL, PV_NONE,
2578#endif
2579			    {(char_u *)85L, (char_u *)0L} SCRIPTID_INIT},
2580    {"titleold",    NULL,   P_STRING|P_VI_DEF|P_GETTEXT|P_SECURE|P_NO_MKRC,
2581#ifdef FEAT_TITLE
2582			    (char_u *)&p_titleold, PV_NONE,
2583			    {(char_u *)N_("Thanks for flying Vim"),
2584							       (char_u *)0L}
2585#else
2586			    (char_u *)NULL, PV_NONE,
2587			    {(char_u *)0L, (char_u *)0L}
2588#endif
2589			    SCRIPTID_INIT},
2590    {"titlestring", NULL,   P_STRING|P_VI_DEF,
2591#ifdef FEAT_TITLE
2592			    (char_u *)&p_titlestring, PV_NONE,
2593#else
2594			    (char_u *)NULL, PV_NONE,
2595#endif
2596			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
2597#if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32)
2598    {"toolbar",     "tb",   P_STRING|P_COMMA|P_VI_DEF|P_NODUP,
2599			    (char_u *)&p_toolbar, PV_NONE,
2600			    {(char_u *)"icons,tooltips", (char_u *)0L}
2601			    SCRIPTID_INIT},
2602#endif
2603#if defined(FEAT_TOOLBAR) && defined(FEAT_GUI_GTK)
2604    {"toolbariconsize",	"tbis", P_STRING|P_VI_DEF,
2605			    (char_u *)&p_tbis, PV_NONE,
2606			    {(char_u *)"small", (char_u *)0L} SCRIPTID_INIT},
2607#endif
2608    {"ttimeout",    NULL,   P_BOOL|P_VI_DEF|P_VIM,
2609			    (char_u *)&p_ttimeout, PV_NONE,
2610			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2611    {"ttimeoutlen", "ttm",  P_NUM|P_VI_DEF,
2612			    (char_u *)&p_ttm, PV_NONE,
2613			    {(char_u *)-1L, (char_u *)0L} SCRIPTID_INIT},
2614    {"ttybuiltin",  "tbi",  P_BOOL|P_VI_DEF,
2615			    (char_u *)&p_tbi, PV_NONE,
2616			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
2617    {"ttyfast",	    "tf",   P_BOOL|P_NO_MKRC|P_VI_DEF,
2618			    (char_u *)&p_tf, PV_NONE,
2619			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2620    {"ttymouse",    "ttym", P_STRING|P_NODEFAULT|P_NO_MKRC|P_VI_DEF,
2621#if defined(FEAT_MOUSE) && (defined(UNIX) || defined(VMS))
2622			    (char_u *)&p_ttym, PV_NONE,
2623#else
2624			    (char_u *)NULL, PV_NONE,
2625#endif
2626			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
2627    {"ttyscroll",   "tsl",  P_NUM|P_VI_DEF,
2628			    (char_u *)&p_ttyscroll, PV_NONE,
2629			    {(char_u *)999L, (char_u *)0L} SCRIPTID_INIT},
2630    {"ttytype",	    "tty",  P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RALL,
2631			    (char_u *)&T_NAME, PV_NONE,
2632			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
2633    {"undodir",     "udir", P_STRING|P_EXPAND|P_COMMA|P_NODUP|P_SECURE|P_VI_DEF,
2634#ifdef FEAT_PERSISTENT_UNDO
2635			    (char_u *)&p_udir, PV_NONE,
2636			    {(char_u *)".", (char_u *)0L}
2637#else
2638			    (char_u *)NULL, PV_NONE,
2639			    {(char_u *)0L, (char_u *)0L}
2640#endif
2641			    SCRIPTID_INIT},
2642    {"undofile",    "udf",  P_BOOL|P_VI_DEF|P_VIM,
2643#ifdef FEAT_PERSISTENT_UNDO
2644			    (char_u *)&p_udf, PV_UDF,
2645#else
2646			    (char_u *)NULL, PV_NONE,
2647#endif
2648			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2649    {"undolevels",  "ul",   P_NUM|P_VI_DEF,
2650			    (char_u *)&p_ul, PV_NONE,
2651			    {
2652#if defined(UNIX) || defined(WIN3264) || defined(OS2) || defined(VMS)
2653			    (char_u *)1000L,
2654#else
2655			    (char_u *)100L,
2656#endif
2657				(char_u *)0L} SCRIPTID_INIT},
2658    {"undoreload",  "ur",   P_NUM|P_VI_DEF,
2659			    (char_u *)&p_ur, PV_NONE,
2660			    { (char_u *)10000L, (char_u *)0L} SCRIPTID_INIT},
2661    {"updatecount", "uc",   P_NUM|P_VI_DEF,
2662			    (char_u *)&p_uc, PV_NONE,
2663			    {(char_u *)200L, (char_u *)0L} SCRIPTID_INIT},
2664    {"updatetime",  "ut",   P_NUM|P_VI_DEF,
2665			    (char_u *)&p_ut, PV_NONE,
2666			    {(char_u *)4000L, (char_u *)0L} SCRIPTID_INIT},
2667    {"verbose",	    "vbs",  P_NUM|P_VI_DEF,
2668			    (char_u *)&p_verbose, PV_NONE,
2669			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
2670    {"verbosefile", "vfile", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
2671			    (char_u *)&p_vfile, PV_NONE,
2672			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
2673    {"viewdir",     "vdir", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
2674#ifdef FEAT_SESSION
2675			    (char_u *)&p_vdir, PV_NONE,
2676			    {(char_u *)DFLT_VDIR, (char_u *)0L}
2677#else
2678			    (char_u *)NULL, PV_NONE,
2679			    {(char_u *)0L, (char_u *)0L}
2680#endif
2681			    SCRIPTID_INIT},
2682    {"viewoptions", "vop",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
2683#ifdef FEAT_SESSION
2684			    (char_u *)&p_vop, PV_NONE,
2685			    {(char_u *)"folds,options,cursor", (char_u *)0L}
2686#else
2687			    (char_u *)NULL, PV_NONE,
2688			    {(char_u *)0L, (char_u *)0L}
2689#endif
2690			    SCRIPTID_INIT},
2691    {"viminfo",	    "vi",   P_STRING|P_COMMA|P_NODUP|P_SECURE,
2692#ifdef FEAT_VIMINFO
2693			    (char_u *)&p_viminfo, PV_NONE,
2694#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
2695			    {(char_u *)"", (char_u *)"'100,<50,s10,h,rA:,rB:"}
2696#else
2697# ifdef AMIGA
2698			    {(char_u *)"",
2699				 (char_u *)"'100,<50,s10,h,rdf0:,rdf1:,rdf2:"}
2700# else
2701			    {(char_u *)"", (char_u *)"'100,<50,s10,h"}
2702# endif
2703#endif
2704#else
2705			    (char_u *)NULL, PV_NONE,
2706			    {(char_u *)0L, (char_u *)0L}
2707#endif
2708			    SCRIPTID_INIT},
2709    {"virtualedit", "ve",   P_STRING|P_COMMA|P_NODUP|P_VI_DEF|P_VIM,
2710#ifdef FEAT_VIRTUALEDIT
2711			    (char_u *)&p_ve, PV_NONE,
2712			    {(char_u *)"", (char_u *)""}
2713#else
2714			    (char_u *)NULL, PV_NONE,
2715			    {(char_u *)0L, (char_u *)0L}
2716#endif
2717			    SCRIPTID_INIT},
2718    {"visualbell",  "vb",   P_BOOL|P_VI_DEF,
2719			    (char_u *)&p_vb, PV_NONE,
2720			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2721    {"w300",	    NULL,   P_NUM|P_VI_DEF,
2722			    (char_u *)NULL, PV_NONE,
2723			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
2724    {"w1200",	    NULL,   P_NUM|P_VI_DEF,
2725			    (char_u *)NULL, PV_NONE,
2726			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
2727    {"w9600",	    NULL,   P_NUM|P_VI_DEF,
2728			    (char_u *)NULL, PV_NONE,
2729			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
2730    {"warn",	    NULL,   P_BOOL|P_VI_DEF,
2731			    (char_u *)&p_warn, PV_NONE,
2732			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
2733    {"weirdinvert", "wiv",  P_BOOL|P_VI_DEF|P_RCLR,
2734			    (char_u *)&p_wiv, PV_NONE,
2735			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2736    {"whichwrap",   "ww",   P_STRING|P_VIM|P_COMMA|P_FLAGLIST,
2737			    (char_u *)&p_ww, PV_NONE,
2738			    {(char_u *)"", (char_u *)"b,s"} SCRIPTID_INIT},
2739    {"wildchar",    "wc",   P_NUM|P_VIM,
2740			    (char_u *)&p_wc, PV_NONE,
2741			    {(char_u *)(long)Ctrl_E, (char_u *)(long)TAB}
2742			    SCRIPTID_INIT},
2743    {"wildcharm",   "wcm",   P_NUM|P_VI_DEF,
2744			    (char_u *)&p_wcm, PV_NONE,
2745			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
2746    {"wildignore",  "wig",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
2747#ifdef FEAT_WILDIGN
2748			    (char_u *)&p_wig, PV_NONE,
2749#else
2750			    (char_u *)NULL, PV_NONE,
2751#endif
2752			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
2753    {"wildmenu",    "wmnu", P_BOOL|P_VI_DEF,
2754#ifdef FEAT_WILDMENU
2755			    (char_u *)&p_wmnu, PV_NONE,
2756#else
2757			    (char_u *)NULL, PV_NONE,
2758#endif
2759			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2760    {"wildmode",    "wim",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
2761			    (char_u *)&p_wim, PV_NONE,
2762			    {(char_u *)"full", (char_u *)0L} SCRIPTID_INIT},
2763    {"wildoptions", "wop",  P_STRING|P_VI_DEF,
2764#ifdef FEAT_CMDL_COMPL
2765			    (char_u *)&p_wop, PV_NONE,
2766			    {(char_u *)"", (char_u *)0L}
2767#else
2768			    (char_u *)NULL, PV_NONE,
2769			    {(char_u *)NULL, (char_u *)0L}
2770#endif
2771			    SCRIPTID_INIT},
2772    {"winaltkeys",  "wak",  P_STRING|P_VI_DEF,
2773#ifdef FEAT_WAK
2774			    (char_u *)&p_wak, PV_NONE,
2775			    {(char_u *)"menu", (char_u *)0L}
2776#else
2777			    (char_u *)NULL, PV_NONE,
2778			    {(char_u *)NULL, (char_u *)0L}
2779#endif
2780			    SCRIPTID_INIT},
2781    {"window",	    "wi",   P_NUM|P_VI_DEF,
2782			    (char_u *)&p_window_unix2003, PV_NONE,
2783			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
2784    {"winheight",   "wh",   P_NUM|P_VI_DEF,
2785#ifdef FEAT_WINDOWS
2786			    (char_u *)&p_wh, PV_NONE,
2787#else
2788			    (char_u *)NULL, PV_NONE,
2789#endif
2790			    {(char_u *)1L, (char_u *)0L} SCRIPTID_INIT},
2791    {"winfixheight", "wfh", P_BOOL|P_VI_DEF|P_RSTAT,
2792#ifdef FEAT_WINDOWS
2793			    (char_u *)VAR_WIN, PV_WFH,
2794#else
2795			    (char_u *)NULL, PV_NONE,
2796#endif
2797			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2798    {"winfixwidth", "wfw", P_BOOL|P_VI_DEF|P_RSTAT,
2799#ifdef FEAT_VERTSPLIT
2800			    (char_u *)VAR_WIN, PV_WFW,
2801#else
2802			    (char_u *)NULL, PV_NONE,
2803#endif
2804			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2805    {"winminheight", "wmh", P_NUM|P_VI_DEF,
2806#ifdef FEAT_WINDOWS
2807			    (char_u *)&p_wmh, PV_NONE,
2808#else
2809			    (char_u *)NULL, PV_NONE,
2810#endif
2811			    {(char_u *)1L, (char_u *)0L} SCRIPTID_INIT},
2812    {"winminwidth", "wmw", P_NUM|P_VI_DEF,
2813#ifdef FEAT_VERTSPLIT
2814			    (char_u *)&p_wmw, PV_NONE,
2815#else
2816			    (char_u *)NULL, PV_NONE,
2817#endif
2818			    {(char_u *)1L, (char_u *)0L} SCRIPTID_INIT},
2819    {"winwidth",   "wiw",   P_NUM|P_VI_DEF,
2820#ifdef FEAT_VERTSPLIT
2821			    (char_u *)&p_wiw, PV_NONE,
2822#else
2823			    (char_u *)NULL, PV_NONE,
2824#endif
2825			    {(char_u *)20L, (char_u *)0L} SCRIPTID_INIT},
2826    {"wrap",	    NULL,   P_BOOL|P_VI_DEF|P_RWIN,
2827			    (char_u *)VAR_WIN, PV_WRAP,
2828			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
2829    {"wrapmargin",  "wm",   P_NUM|P_VI_DEF,
2830			    (char_u *)&p_wm, PV_WM,
2831			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
2832    {"wrapscan",    "ws",   P_BOOL|P_VI_DEF,
2833			    (char_u *)&p_ws, PV_NONE,
2834			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
2835    {"write",	    NULL,   P_BOOL|P_VI_DEF,
2836			    (char_u *)&p_write, PV_NONE,
2837			    {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
2838    {"writeany",    "wa",   P_BOOL|P_VI_DEF,
2839			    (char_u *)&p_wa, PV_NONE,
2840			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
2841    {"writebackup", "wb",   P_BOOL|P_VI_DEF|P_VIM,
2842			    (char_u *)&p_wb, PV_NONE,
2843			    {
2844#ifdef FEAT_WRITEBACKUP
2845			    (char_u *)TRUE,
2846#else
2847			    (char_u *)FALSE,
2848#endif
2849				(char_u *)0L} SCRIPTID_INIT},
2850    {"writedelay",  "wd",   P_NUM|P_VI_DEF,
2851			    (char_u *)&p_wd, PV_NONE,
2852			    {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
2853
2854/* terminal output codes */
2855#define p_term(sss, vvv)   {sss, NULL, P_STRING|P_VI_DEF|P_RALL|P_SECURE, \
2856			    (char_u *)&vvv, PV_NONE, \
2857			    {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
2858
2859    p_term("t_AB", T_CAB)
2860    p_term("t_AF", T_CAF)
2861    p_term("t_AL", T_CAL)
2862    p_term("t_al", T_AL)
2863    p_term("t_bc", T_BC)
2864    p_term("t_cd", T_CD)
2865    p_term("t_ce", T_CE)
2866    p_term("t_cl", T_CL)
2867    p_term("t_cm", T_CM)
2868    p_term("t_Co", T_CCO)
2869    p_term("t_CS", T_CCS)
2870    p_term("t_cs", T_CS)
2871#ifdef FEAT_VERTSPLIT
2872    p_term("t_CV", T_CSV)
2873#endif
2874    p_term("t_ut", T_UT)
2875    p_term("t_da", T_DA)
2876    p_term("t_db", T_DB)
2877    p_term("t_DL", T_CDL)
2878    p_term("t_dl", T_DL)
2879    p_term("t_fs", T_FS)
2880    p_term("t_IE", T_CIE)
2881    p_term("t_IS", T_CIS)
2882    p_term("t_ke", T_KE)
2883    p_term("t_ks", T_KS)
2884    p_term("t_le", T_LE)
2885    p_term("t_mb", T_MB)
2886    p_term("t_md", T_MD)
2887    p_term("t_me", T_ME)
2888    p_term("t_mr", T_MR)
2889    p_term("t_ms", T_MS)
2890    p_term("t_nd", T_ND)
2891    p_term("t_op", T_OP)
2892    p_term("t_RI", T_CRI)
2893    p_term("t_RV", T_CRV)
2894    p_term("t_Sb", T_CSB)
2895    p_term("t_Sf", T_CSF)
2896    p_term("t_se", T_SE)
2897    p_term("t_so", T_SO)
2898    p_term("t_sr", T_SR)
2899    p_term("t_ts", T_TS)
2900    p_term("t_te", T_TE)
2901    p_term("t_ti", T_TI)
2902    p_term("t_ue", T_UE)
2903    p_term("t_us", T_US)
2904    p_term("t_vb", T_VB)
2905    p_term("t_ve", T_VE)
2906    p_term("t_vi", T_VI)
2907    p_term("t_vs", T_VS)
2908    p_term("t_WP", T_CWP)
2909    p_term("t_WS", T_CWS)
2910    p_term("t_SI", T_CSI)
2911    p_term("t_EI", T_CEI)
2912    p_term("t_xs", T_XS)
2913    p_term("t_ZH", T_CZH)
2914    p_term("t_ZR", T_CZR)
2915
2916/* terminal key codes are not in here */
2917
2918    /* end marker */
2919    {NULL, NULL, 0, NULL, PV_NONE, {NULL, NULL} SCRIPTID_INIT}
2920};
2921
2922#define PARAM_COUNT (sizeof(options) / sizeof(struct vimoption))
2923
2924#ifdef FEAT_MBYTE
2925static char *(p_ambw_values[]) = {"single", "double", NULL};
2926#endif
2927static char *(p_bg_values[]) = {"light", "dark", NULL};
2928static char *(p_nf_values[]) = {"octal", "hex", "alpha", NULL};
2929static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL};
2930#ifdef FEAT_CRYPT
2931static char *(p_cm_values[]) = {"zip", "blowfish", NULL};
2932#endif
2933#ifdef FEAT_CMDL_COMPL
2934static char *(p_wop_values[]) = {"tagfile", NULL};
2935#endif
2936#ifdef FEAT_WAK
2937static char *(p_wak_values[]) = {"yes", "menu", "no", NULL};
2938#endif
2939static char *(p_mousem_values[]) = {"extend", "popup", "popup_setpos", "mac", NULL};
2940#ifdef FEAT_VISUAL
2941static char *(p_sel_values[]) = {"inclusive", "exclusive", "old", NULL};
2942static char *(p_slm_values[]) = {"mouse", "key", "cmd", NULL};
2943#endif
2944#ifdef FEAT_VISUAL
2945static char *(p_km_values[]) = {"startsel", "stopsel", NULL};
2946#endif
2947#ifdef FEAT_BROWSE
2948static char *(p_bsdir_values[]) = {"current", "last", "buffer", NULL};
2949#endif
2950#ifdef FEAT_SCROLLBIND
2951static char *(p_scbopt_values[]) = {"ver", "hor", "jump", NULL};
2952#endif
2953static char *(p_debug_values[]) = {"msg", "throw", "beep", NULL};
2954#ifdef FEAT_VERTSPLIT
2955static char *(p_ead_values[]) = {"both", "ver", "hor", NULL};
2956#endif
2957#if defined(FEAT_QUICKFIX)
2958# ifdef FEAT_AUTOCMD
2959static char *(p_buftype_values[]) = {"nofile", "nowrite", "quickfix", "help", "acwrite", NULL};
2960# else
2961static char *(p_buftype_values[]) = {"nofile", "nowrite", "quickfix", "help", NULL};
2962# endif
2963static char *(p_bufhidden_values[]) = {"hide", "unload", "delete", "wipe", NULL};
2964#endif
2965static char *(p_bs_values[]) = {"indent", "eol", "start", NULL};
2966#ifdef FEAT_FOLDING
2967static char *(p_fdm_values[]) = {"manual", "expr", "marker", "indent", "syntax",
2968# ifdef FEAT_DIFF
2969				"diff",
2970# endif
2971				NULL};
2972static char *(p_fcl_values[]) = {"all", NULL};
2973#endif
2974#ifdef FEAT_INS_EXPAND
2975static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", NULL};
2976#endif
2977
2978static void set_option_default __ARGS((int, int opt_flags, int compatible));
2979static void set_options_default __ARGS((int opt_flags));
2980static char_u *term_bg_default __ARGS((void));
2981static void did_set_option __ARGS((int opt_idx, int opt_flags, int new_value));
2982static char_u *illegal_char __ARGS((char_u *, int));
2983static int string_to_key __ARGS((char_u *arg));
2984#ifdef FEAT_CMDWIN
2985static char_u *check_cedit __ARGS((void));
2986#endif
2987#ifdef FEAT_TITLE
2988static void did_set_title __ARGS((int icon));
2989#endif
2990static char_u *option_expand __ARGS((int opt_idx, char_u *val));
2991static void didset_options __ARGS((void));
2992static void check_string_option __ARGS((char_u **pp));
2993#if defined(FEAT_EVAL) || defined(PROTO)
2994static long_u *insecure_flag __ARGS((int opt_idx, int opt_flags));
2995#else
2996# define insecure_flag(opt_idx, opt_flags) (&options[opt_idx].flags)
2997#endif
2998static void set_string_option_global __ARGS((int opt_idx, char_u **varp));
2999static void set_string_option __ARGS((int opt_idx, char_u *value, int opt_flags));
3000static char_u *did_set_string_option __ARGS((int opt_idx, char_u **varp, int new_value_alloced, char_u *oldval, char_u *errbuf, int opt_flags));
3001static char_u *set_chars_option __ARGS((char_u **varp));
3002#ifdef FEAT_SYN_HL
3003static int int_cmp __ARGS((const void *a, const void *b));
3004#endif
3005#ifdef FEAT_CLIPBOARD
3006static char_u *check_clipboard_option __ARGS((void));
3007#endif
3008#ifdef FEAT_SPELL
3009static char_u *compile_cap_prog __ARGS((synblock_T *synblock));
3010#endif
3011#ifdef FEAT_EVAL
3012static void set_option_scriptID_idx __ARGS((int opt_idx, int opt_flags, int id));
3013#endif
3014static char_u *set_bool_option __ARGS((int opt_idx, char_u *varp, int value, int opt_flags));
3015static char_u *set_num_option __ARGS((int opt_idx, char_u *varp, long value, char_u *errbuf, size_t errbuflen, int opt_flags));
3016static void check_redraw __ARGS((long_u flags));
3017static int findoption __ARGS((char_u *));
3018static int find_key_option __ARGS((char_u *));
3019static void showoptions __ARGS((int all, int opt_flags));
3020static int optval_default __ARGS((struct vimoption *, char_u *varp));
3021static void showoneopt __ARGS((struct vimoption *, int opt_flags));
3022static int put_setstring __ARGS((FILE *fd, char *cmd, char *name, char_u **valuep, int expand));
3023static int put_setnum __ARGS((FILE *fd, char *cmd, char *name, long *valuep));
3024static int put_setbool __ARGS((FILE *fd, char *cmd, char *name, int value));
3025static int  istermoption __ARGS((struct vimoption *));
3026static char_u *get_varp_scope __ARGS((struct vimoption *p, int opt_flags));
3027static char_u *get_varp __ARGS((struct vimoption *));
3028static void option_value2string __ARGS((struct vimoption *, int opt_flags));
3029static int wc_use_keyname __ARGS((char_u *varp, long *wcp));
3030#ifdef FEAT_LANGMAP
3031static void langmap_init __ARGS((void));
3032static void langmap_set __ARGS((void));
3033#endif
3034static void paste_option_changed __ARGS((void));
3035static void compatible_set __ARGS((void));
3036#ifdef FEAT_LINEBREAK
3037static void fill_breakat_flags __ARGS((void));
3038#endif
3039static int opt_strings_flags __ARGS((char_u *val, char **values, unsigned *flagp, int list));
3040static int check_opt_strings __ARGS((char_u *val, char **values, int));
3041static int check_opt_wim __ARGS((void));
3042
3043/*
3044 * Initialize the options, first part.
3045 *
3046 * Called only once from main(), just after creating the first buffer.
3047 */
3048    void
3049set_init_1()
3050{
3051    char_u	*p;
3052    int		opt_idx;
3053    long_u	n;
3054
3055#ifdef FEAT_LANGMAP
3056    langmap_init();
3057#endif
3058
3059    /* Be Vi compatible by default */
3060    p_cp = TRUE;
3061
3062    /* Use POSIX compatibility when $VIM_POSIX is set. */
3063    if (mch_getenv((char_u *)"VIM_POSIX") != NULL)
3064    {
3065	set_string_default("cpo", (char_u *)CPO_ALL);
3066	set_string_default("shm", (char_u *)"A");
3067    }
3068
3069    /*
3070     * Find default value for 'shell' option.
3071     * Don't use it if it is empty.
3072     */
3073    if (((p = mch_getenv((char_u *)"SHELL")) != NULL && *p != NUL)
3074#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
3075# ifdef __EMX__
3076	    || ((p = mch_getenv((char_u *)"EMXSHELL")) != NULL && *p != NUL)
3077# endif
3078	    || ((p = mch_getenv((char_u *)"COMSPEC")) != NULL && *p != NUL)
3079# ifdef WIN3264
3080	    || ((p = default_shell()) != NULL && *p != NUL)
3081# endif
3082#endif
3083	    )
3084	set_string_default("sh", p);
3085
3086#ifdef FEAT_WILDIGN
3087    /*
3088     * Set the default for 'backupskip' to include environment variables for
3089     * temp files.
3090     */
3091    {
3092# ifdef UNIX
3093	static char	*(names[4]) = {"", "TMPDIR", "TEMP", "TMP"};
3094# else
3095	static char	*(names[3]) = {"TMPDIR", "TEMP", "TMP"};
3096# endif
3097	int		len;
3098	garray_T	ga;
3099	int		mustfree;
3100
3101	ga_init2(&ga, 1, 100);
3102	for (n = 0; n < (long)(sizeof(names) / sizeof(char *)); ++n)
3103	{
3104	    mustfree = FALSE;
3105# ifdef UNIX
3106	    if (*names[n] == NUL)
3107		p = (char_u *)"/tmp";
3108	    else
3109# endif
3110		p = vim_getenv((char_u *)names[n], &mustfree);
3111	    if (p != NULL && *p != NUL)
3112	    {
3113		/* First time count the NUL, otherwise count the ','. */
3114		len = (int)STRLEN(p) + 3;
3115		if (ga_grow(&ga, len) == OK)
3116		{
3117		    if (ga.ga_len > 0)
3118			STRCAT(ga.ga_data, ",");
3119		    STRCAT(ga.ga_data, p);
3120		    add_pathsep(ga.ga_data);
3121		    STRCAT(ga.ga_data, "*");
3122		    ga.ga_len += len;
3123		}
3124	    }
3125	    if (mustfree)
3126		vim_free(p);
3127	}
3128	if (ga.ga_data != NULL)
3129	{
3130	    set_string_default("bsk", ga.ga_data);
3131	    vim_free(ga.ga_data);
3132	}
3133    }
3134#endif
3135
3136    /*
3137     * 'maxmemtot' and 'maxmem' may have to be adjusted for available memory
3138     */
3139    opt_idx = findoption((char_u *)"maxmemtot");
3140    if (opt_idx >= 0)
3141    {
3142#if !defined(HAVE_AVAIL_MEM) && !defined(HAVE_TOTAL_MEM)
3143	if (options[opt_idx].def_val[VI_DEFAULT] == (char_u *)0L)
3144#endif
3145	{
3146#ifdef HAVE_AVAIL_MEM
3147	    /* Use amount of memory available at this moment. */
3148	    n = (mch_avail_mem(FALSE) >> 11);
3149#else
3150# ifdef HAVE_TOTAL_MEM
3151	    /* Use amount of memory available to Vim. */
3152	    n = (mch_total_mem(FALSE) >> 1);
3153# else
3154	    n = (0x7fffffff >> 11);
3155# endif
3156#endif
3157	    options[opt_idx].def_val[VI_DEFAULT] = (char_u *)n;
3158	    opt_idx = findoption((char_u *)"maxmem");
3159	    if (opt_idx >= 0)
3160	    {
3161#if !defined(HAVE_AVAIL_MEM) && !defined(HAVE_TOTAL_MEM)
3162		if ((long)options[opt_idx].def_val[VI_DEFAULT] > n
3163			|| (long)options[opt_idx].def_val[VI_DEFAULT] == 0L)
3164#endif
3165		    options[opt_idx].def_val[VI_DEFAULT] = (char_u *)n;
3166	    }
3167	}
3168    }
3169
3170#ifdef FEAT_GUI_W32
3171    /* force 'shortname' for Win32s */
3172    if (gui_is_win32s())
3173    {
3174	opt_idx = findoption((char_u *)"shortname");
3175	if (opt_idx >= 0)
3176	    options[opt_idx].def_val[VI_DEFAULT] = (char_u *)TRUE;
3177    }
3178#endif
3179
3180#ifdef FEAT_SEARCHPATH
3181    {
3182	char_u	*cdpath;
3183	char_u	*buf;
3184	int	i;
3185	int	j;
3186	int	mustfree = FALSE;
3187
3188	/* Initialize the 'cdpath' option's default value. */
3189	cdpath = vim_getenv((char_u *)"CDPATH", &mustfree);
3190	if (cdpath != NULL)
3191	{
3192	    buf = alloc((unsigned)((STRLEN(cdpath) << 1) + 2));
3193	    if (buf != NULL)
3194	    {
3195		buf[0] = ',';	    /* start with ",", current dir first */
3196		j = 1;
3197		for (i = 0; cdpath[i] != NUL; ++i)
3198		{
3199		    if (vim_ispathlistsep(cdpath[i]))
3200			buf[j++] = ',';
3201		    else
3202		    {
3203			if (cdpath[i] == ' ' || cdpath[i] == ',')
3204			    buf[j++] = '\\';
3205			buf[j++] = cdpath[i];
3206		    }
3207		}
3208		buf[j] = NUL;
3209		opt_idx = findoption((char_u *)"cdpath");
3210		if (opt_idx >= 0)
3211		{
3212		    options[opt_idx].def_val[VI_DEFAULT] = buf;
3213		    options[opt_idx].flags |= P_DEF_ALLOCED;
3214		}
3215		else
3216		    vim_free(buf); /* cannot happen */
3217	    }
3218	    if (mustfree)
3219		vim_free(cdpath);
3220	}
3221    }
3222#endif
3223
3224#if defined(FEAT_POSTSCRIPT) && (defined(MSWIN) || defined(OS2) || defined(VMS) || defined(EBCDIC) || defined(MAC) || defined(hpux))
3225    /* Set print encoding on platforms that don't default to latin1 */
3226    set_string_default("penc",
3227# if defined(MSWIN) || defined(OS2)
3228		       (char_u *)"cp1252"
3229# else
3230#  ifdef VMS
3231		       (char_u *)"dec-mcs"
3232#  else
3233#   ifdef EBCDIC
3234		       (char_u *)"ebcdic-uk"
3235#   else
3236#    ifdef MAC
3237		       (char_u *)"mac-roman"
3238#    else /* HPUX */
3239		       (char_u *)"hp-roman8"
3240#    endif
3241#   endif
3242#  endif
3243# endif
3244		       );
3245#endif
3246
3247#ifdef FEAT_POSTSCRIPT
3248    /* 'printexpr' must be allocated to be able to evaluate it. */
3249    set_string_default("pexpr",
3250# if defined(MSWIN) || defined(MSDOS) || defined(OS2)
3251	    (char_u *)"system('copy' . ' ' . v:fname_in . (&printdevice == '' ? ' LPT1:' : (' \"' . &printdevice . '\"'))) . delete(v:fname_in)"
3252# else
3253#  ifdef VMS
3254	    (char_u *)"system('print/delete' . (&printdevice == '' ? '' : ' /queue=' . &printdevice) . ' ' . v:fname_in)"
3255
3256#  else
3257	    (char_u *)"system('lpr' . (&printdevice == '' ? '' : ' -P' . &printdevice) . ' ' . v:fname_in) . delete(v:fname_in) + v:shell_error"
3258#  endif
3259# endif
3260	    );
3261#endif
3262
3263    /*
3264     * Set all the options (except the terminal options) to their default
3265     * value.  Also set the global value for local options.
3266     */
3267    set_options_default(0);
3268
3269#ifdef FEAT_GUI
3270    if (found_reverse_arg)
3271	set_option_value((char_u *)"bg", 0L, (char_u *)"dark", 0);
3272#endif
3273
3274    curbuf->b_p_initialized = TRUE;
3275    curbuf->b_p_ar = -1;	/* no local 'autoread' value */
3276    check_buf_options(curbuf);
3277    check_win_options(curwin);
3278    check_options();
3279
3280    /* Must be before option_expand(), because that one needs vim_isIDc() */
3281    didset_options();
3282
3283#ifdef FEAT_SPELL
3284    /* Use the current chartab for the generic chartab. */
3285    init_spell_chartab();
3286#endif
3287
3288#ifdef FEAT_LINEBREAK
3289    /*
3290     * initialize the table for 'breakat'.
3291     */
3292    fill_breakat_flags();
3293#endif
3294
3295    /*
3296     * Expand environment variables and things like "~" for the defaults.
3297     * If option_expand() returns non-NULL the variable is expanded.  This can
3298     * only happen for non-indirect options.
3299     * Also set the default to the expanded value, so ":set" does not list
3300     * them.
3301     * Don't set the P_ALLOCED flag, because we don't want to free the
3302     * default.
3303     */
3304    for (opt_idx = 0; !istermoption(&options[opt_idx]); opt_idx++)
3305    {
3306	if ((options[opt_idx].flags & P_GETTEXT)
3307					      && options[opt_idx].var != NULL)
3308	    p = (char_u *)_(*(char **)options[opt_idx].var);
3309	else
3310	    p = option_expand(opt_idx, NULL);
3311	if (p != NULL && (p = vim_strsave(p)) != NULL)
3312	{
3313	    *(char_u **)options[opt_idx].var = p;
3314	    /* VIMEXP
3315	     * Defaults for all expanded options are currently the same for Vi
3316	     * and Vim.  When this changes, add some code here!  Also need to
3317	     * split P_DEF_ALLOCED in two.
3318	     */
3319	    if (options[opt_idx].flags & P_DEF_ALLOCED)
3320		vim_free(options[opt_idx].def_val[VI_DEFAULT]);
3321	    options[opt_idx].def_val[VI_DEFAULT] = p;
3322	    options[opt_idx].flags |= P_DEF_ALLOCED;
3323	}
3324    }
3325
3326    /* Initialize the highlight_attr[] table. */
3327    highlight_changed();
3328
3329    save_file_ff(curbuf);	/* Buffer is unchanged */
3330
3331    /* Parse default for 'wildmode'  */
3332    check_opt_wim();
3333
3334#if defined(FEAT_ARABIC)
3335    /* Detect use of mlterm.
3336     * Mlterm is a terminal emulator akin to xterm that has some special
3337     * abilities (bidi namely).
3338     * NOTE: mlterm's author is being asked to 'set' a variable
3339     *       instead of an environment variable due to inheritance.
3340     */
3341    if (mch_getenv((char_u *)"MLTERM") != NULL)
3342	set_option_value((char_u *)"tbidi", 1L, NULL, 0);
3343#endif
3344
3345#if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)
3346    /* Parse default for 'fillchars'. */
3347    (void)set_chars_option(&p_fcs);
3348#endif
3349
3350#ifdef FEAT_CLIPBOARD
3351    /* Parse default for 'clipboard' */
3352    (void)check_clipboard_option();
3353#endif
3354
3355#ifdef FEAT_MBYTE
3356# if defined(WIN3264) && defined(FEAT_GETTEXT)
3357    /*
3358     * If $LANG isn't set, try to get a good value for it.  This makes the
3359     * right language be used automatically.  Don't do this for English.
3360     */
3361    if (mch_getenv((char_u *)"LANG") == NULL)
3362    {
3363	char	buf[20];
3364
3365	/* Could use LOCALE_SISO639LANGNAME, but it's not in Win95.
3366	 * LOCALE_SABBREVLANGNAME gives us three letters, like "enu", we use
3367	 * only the first two. */
3368	n = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SABBREVLANGNAME,
3369							     (LPTSTR)buf, 20);
3370	if (n >= 2 && STRNICMP(buf, "en", 2) != 0)
3371	{
3372	    /* There are a few exceptions (probably more) */
3373	    if (STRNICMP(buf, "cht", 3) == 0 || STRNICMP(buf, "zht", 3) == 0)
3374		STRCPY(buf, "zh_TW");
3375	    else if (STRNICMP(buf, "chs", 3) == 0
3376					      || STRNICMP(buf, "zhc", 3) == 0)
3377		STRCPY(buf, "zh_CN");
3378	    else if (STRNICMP(buf, "jp", 2) == 0)
3379		STRCPY(buf, "ja");
3380	    else
3381		buf[2] = NUL;		/* truncate to two-letter code */
3382	    vim_setenv("LANG", buf);
3383	}
3384    }
3385# else
3386#  ifdef MACOS_CONVERT
3387    /* Moved to os_mac_conv.c to avoid dependency problems. */
3388    mac_lang_init();
3389#  endif
3390# endif
3391
3392    /* enc_locale() will try to find the encoding of the current locale. */
3393    p = enc_locale();
3394    if (p != NULL)
3395    {
3396	char_u *save_enc;
3397
3398	/* Try setting 'encoding' and check if the value is valid.
3399	 * If not, go back to the default "latin1". */
3400	save_enc = p_enc;
3401	p_enc = p;
3402	if (STRCMP(p_enc, "gb18030") == 0)
3403	{
3404	    /* We don't support "gb18030", but "cp936" is a good substitute
3405	     * for practical purposes, thus use that.  It's not an alias to
3406	     * still support conversion between gb18030 and utf-8. */
3407	    p_enc = vim_strsave((char_u *)"cp936");
3408	    vim_free(p);
3409	}
3410	if (mb_init() == NULL)
3411	{
3412	    opt_idx = findoption((char_u *)"encoding");
3413	    if (opt_idx >= 0)
3414	    {
3415		options[opt_idx].def_val[VI_DEFAULT] = p_enc;
3416		options[opt_idx].flags |= P_DEF_ALLOCED;
3417	    }
3418
3419#if defined(MSDOS) || defined(MSWIN) || defined(OS2) || defined(MACOS) \
3420		|| defined(VMS)
3421	    if (STRCMP(p_enc, "latin1") == 0
3422# ifdef FEAT_MBYTE
3423		    || enc_utf8
3424# endif
3425		    )
3426	    {
3427		/* Adjust the default for 'isprint' and 'iskeyword' to match
3428		 * latin1.  Also set the defaults for when 'nocompatible' is
3429		 * set. */
3430		set_string_option_direct((char_u *)"isp", -1,
3431					      ISP_LATIN1, OPT_FREE, SID_NONE);
3432		set_string_option_direct((char_u *)"isk", -1,
3433					      ISK_LATIN1, OPT_FREE, SID_NONE);
3434		opt_idx = findoption((char_u *)"isp");
3435		if (opt_idx >= 0)
3436		    options[opt_idx].def_val[VIM_DEFAULT] = ISP_LATIN1;
3437		opt_idx = findoption((char_u *)"isk");
3438		if (opt_idx >= 0)
3439		    options[opt_idx].def_val[VIM_DEFAULT] = ISK_LATIN1;
3440		(void)init_chartab();
3441	    }
3442#endif
3443
3444# if defined(WIN3264) && !defined(FEAT_GUI)
3445	    /* Win32 console: When GetACP() returns a different value from
3446	     * GetConsoleCP() set 'termencoding'. */
3447	    if (GetACP() != GetConsoleCP())
3448	    {
3449		char	buf[50];
3450
3451		sprintf(buf, "cp%ld", (long)GetConsoleCP());
3452		p_tenc = vim_strsave((char_u *)buf);
3453		if (p_tenc != NULL)
3454		{
3455		    opt_idx = findoption((char_u *)"termencoding");
3456		    if (opt_idx >= 0)
3457		    {
3458			options[opt_idx].def_val[VI_DEFAULT] = p_tenc;
3459			options[opt_idx].flags |= P_DEF_ALLOCED;
3460		    }
3461		    convert_setup(&input_conv, p_tenc, p_enc);
3462		    convert_setup(&output_conv, p_enc, p_tenc);
3463		}
3464		else
3465		    p_tenc = empty_option;
3466	    }
3467# endif
3468# if defined(WIN3264) && defined(FEAT_MBYTE)
3469	    /* $HOME may have characters in active code page. */
3470	    init_homedir();
3471# endif
3472	}
3473	else
3474	{
3475	    vim_free(p_enc);
3476	    p_enc = save_enc;
3477	}
3478    }
3479#endif
3480
3481#ifdef FEAT_MULTI_LANG
3482    /* Set the default for 'helplang'. */
3483    set_helplang_default(get_mess_lang());
3484#endif
3485}
3486
3487/*
3488 * Set an option to its default value.
3489 * This does not take care of side effects!
3490 */
3491    static void
3492set_option_default(opt_idx, opt_flags, compatible)
3493    int		opt_idx;
3494    int		opt_flags;	/* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
3495    int		compatible;	/* use Vi default value */
3496{
3497    char_u	*varp;		/* pointer to variable for current option */
3498    int		dvi;		/* index in def_val[] */
3499    long_u	flags;
3500    long_u	*flagsp;
3501    int		both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
3502
3503    varp = get_varp_scope(&(options[opt_idx]), both ? OPT_LOCAL : opt_flags);
3504    flags = options[opt_idx].flags;
3505    if (varp != NULL)	    /* skip hidden option, nothing to do for it */
3506    {
3507	dvi = ((flags & P_VI_DEF) || compatible) ? VI_DEFAULT : VIM_DEFAULT;
3508	if (flags & P_STRING)
3509	{
3510	    /* Use set_string_option_direct() for local options to handle
3511	     * freeing and allocating the value. */
3512	    if (options[opt_idx].indir != PV_NONE)
3513		set_string_option_direct(NULL, opt_idx,
3514				 options[opt_idx].def_val[dvi], opt_flags, 0);
3515	    else
3516	    {
3517		if ((opt_flags & OPT_FREE) && (flags & P_ALLOCED))
3518		    free_string_option(*(char_u **)(varp));
3519		*(char_u **)varp = options[opt_idx].def_val[dvi];
3520		options[opt_idx].flags &= ~P_ALLOCED;
3521	    }
3522	}
3523	else if (flags & P_NUM)
3524	{
3525	    if (options[opt_idx].indir == PV_SCROLL)
3526		win_comp_scroll(curwin);
3527	    else
3528	    {
3529		*(long *)varp = (long)(long_i)options[opt_idx].def_val[dvi];
3530		/* May also set global value for local option. */
3531		if (both)
3532		    *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) =
3533								*(long *)varp;
3534	    }
3535	}
3536	else	/* P_BOOL */
3537	{
3538	    /* the cast to long is required for Manx C, long_i is needed for
3539	     * MSVC */
3540	    *(int *)varp = (int)(long)(long_i)options[opt_idx].def_val[dvi];
3541#ifdef UNIX
3542	    /* 'modeline' defaults to off for root */
3543	    if (options[opt_idx].indir == PV_ML && getuid() == ROOT_UID)
3544		*(int *)varp = FALSE;
3545#endif
3546	    /* May also set global value for local option. */
3547	    if (both)
3548		*(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) =
3549								*(int *)varp;
3550	}
3551
3552	/* The default value is not insecure. */
3553	flagsp = insecure_flag(opt_idx, opt_flags);
3554	*flagsp = *flagsp & ~P_INSECURE;
3555    }
3556
3557#ifdef FEAT_EVAL
3558    set_option_scriptID_idx(opt_idx, opt_flags, current_SID);
3559#endif
3560}
3561
3562/*
3563 * Set all options (except terminal options) to their default value.
3564 */
3565    static void
3566set_options_default(opt_flags)
3567    int		opt_flags;	/* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
3568{
3569    int		i;
3570#ifdef FEAT_WINDOWS
3571    win_T	*wp;
3572    tabpage_T	*tp;
3573#endif
3574
3575    for (i = 0; !istermoption(&options[i]); i++)
3576	if (!(options[i].flags & P_NODEFAULT))
3577	    set_option_default(i, opt_flags, p_cp);
3578
3579#ifdef FEAT_WINDOWS
3580    /* The 'scroll' option must be computed for all windows. */
3581    FOR_ALL_TAB_WINDOWS(tp, wp)
3582	win_comp_scroll(wp);
3583#else
3584	win_comp_scroll(curwin);
3585#endif
3586}
3587
3588/*
3589 * Set the Vi-default value of a string option.
3590 * Used for 'sh', 'backupskip' and 'term'.
3591 */
3592    void
3593set_string_default(name, val)
3594    char	*name;
3595    char_u	*val;
3596{
3597    char_u	*p;
3598    int		opt_idx;
3599
3600    p = vim_strsave(val);
3601    if (p != NULL)		/* we don't want a NULL */
3602    {
3603	opt_idx = findoption((char_u *)name);
3604	if (opt_idx >= 0)
3605	{
3606	    if (options[opt_idx].flags & P_DEF_ALLOCED)
3607		vim_free(options[opt_idx].def_val[VI_DEFAULT]);
3608	    options[opt_idx].def_val[VI_DEFAULT] = p;
3609	    options[opt_idx].flags |= P_DEF_ALLOCED;
3610	}
3611    }
3612}
3613
3614/*
3615 * Set the Vi-default value of a number option.
3616 * Used for 'lines' and 'columns'.
3617 */
3618    void
3619set_number_default(name, val)
3620    char	*name;
3621    long	val;
3622{
3623    int		opt_idx;
3624
3625    opt_idx = findoption((char_u *)name);
3626    if (opt_idx >= 0)
3627	options[opt_idx].def_val[VI_DEFAULT] = (char_u *)(long_i)val;
3628}
3629
3630#if defined(EXITFREE) || defined(PROTO)
3631/*
3632 * Free all options.
3633 */
3634    void
3635free_all_options()
3636{
3637    int		i;
3638
3639    for (i = 0; !istermoption(&options[i]); i++)
3640    {
3641	if (options[i].indir == PV_NONE)
3642	{
3643	    /* global option: free value and default value. */
3644	    if (options[i].flags & P_ALLOCED && options[i].var != NULL)
3645		free_string_option(*(char_u **)options[i].var);
3646	    if (options[i].flags & P_DEF_ALLOCED)
3647		free_string_option(options[i].def_val[VI_DEFAULT]);
3648	}
3649	else if (options[i].var != VAR_WIN
3650		&& (options[i].flags & P_STRING))
3651	    /* buffer-local option: free global value */
3652	    free_string_option(*(char_u **)options[i].var);
3653    }
3654}
3655#endif
3656
3657
3658/*
3659 * Initialize the options, part two: After getting Rows and Columns and
3660 * setting 'term'.
3661 */
3662    void
3663set_init_2()
3664{
3665    int		idx;
3666
3667    /*
3668     * 'scroll' defaults to half the window height. Note that this default is
3669     * wrong when the window height changes.
3670     */
3671    set_number_default("scroll", (long)((long_u)Rows >> 1));
3672    idx = findoption((char_u *)"scroll");
3673    if (idx >= 0 && !(options[idx].flags & P_WAS_SET))
3674	set_option_default(idx, OPT_LOCAL, p_cp);
3675    comp_col();
3676
3677    /*
3678     * 'window' is only for backwards compatibility with Vi.
3679     * Default is Rows - 1.
3680     */
3681    if (!option_was_set((char_u *)"window"))
3682	p_window = Rows - 1;
3683    set_number_default("window", p_window);
3684
3685    /* For DOS console the default is always black. */
3686#if !((defined(MSDOS) || defined(OS2) || defined(WIN3264)) && !defined(FEAT_GUI))
3687    /*
3688     * If 'background' wasn't set by the user, try guessing the value,
3689     * depending on the terminal name.  Only need to check for terminals
3690     * with a dark background, that can handle color.
3691     */
3692    idx = findoption((char_u *)"bg");
3693    if (idx >= 0 && !(options[idx].flags & P_WAS_SET)
3694						 && *term_bg_default() == 'd')
3695    {
3696	set_string_option_direct(NULL, idx, (char_u *)"dark", OPT_FREE, 0);
3697	/* don't mark it as set, when starting the GUI it may be
3698	 * changed again */
3699	options[idx].flags &= ~P_WAS_SET;
3700    }
3701#endif
3702
3703#ifdef CURSOR_SHAPE
3704    parse_shape_opt(SHAPE_CURSOR); /* set cursor shapes from 'guicursor' */
3705#endif
3706#ifdef FEAT_MOUSESHAPE
3707    parse_shape_opt(SHAPE_MOUSE);  /* set mouse shapes from 'mouseshape' */
3708#endif
3709#ifdef FEAT_PRINTER
3710    (void)parse_printoptions();	    /* parse 'printoptions' default value */
3711#endif
3712}
3713
3714/*
3715 * Return "dark" or "light" depending on the kind of terminal.
3716 * This is just guessing!  Recognized are:
3717 * "linux"	    Linux console
3718 * "screen.linux"   Linux console with screen
3719 * "cygwin"	    Cygwin shell
3720 * "putty"	    Putty program
3721 * We also check the COLORFGBG environment variable, which is set by
3722 * rxvt and derivatives. This variable contains either two or three
3723 * values separated by semicolons; we want the last value in either
3724 * case. If this value is 0-6 or 8, our background is dark.
3725 */
3726    static char_u *
3727term_bg_default()
3728{
3729#if defined(MSDOS) || defined(OS2) || defined(WIN3264)
3730    /* DOS console nearly always black */
3731    return (char_u *)"dark";
3732#else
3733    char_u	*p;
3734
3735    if (STRCMP(T_NAME, "linux") == 0
3736	    || STRCMP(T_NAME, "screen.linux") == 0
3737	    || STRCMP(T_NAME, "cygwin") == 0
3738	    || STRCMP(T_NAME, "putty") == 0
3739	    || ((p = mch_getenv((char_u *)"COLORFGBG")) != NULL
3740		&& (p = vim_strrchr(p, ';')) != NULL
3741		&& ((p[1] >= '0' && p[1] <= '6') || p[1] == '8')
3742		&& p[2] == NUL))
3743	return (char_u *)"dark";
3744    return (char_u *)"light";
3745#endif
3746}
3747
3748/*
3749 * Initialize the options, part three: After reading the .vimrc
3750 */
3751    void
3752set_init_3()
3753{
3754#if defined(UNIX) || defined(OS2) || defined(WIN3264)
3755/*
3756 * Set 'shellpipe' and 'shellredir', depending on the 'shell' option.
3757 * This is done after other initializations, where 'shell' might have been
3758 * set, but only if they have not been set before.
3759 */
3760    char_u  *p;
3761    int	    idx_srr;
3762    int	    do_srr;
3763#ifdef FEAT_QUICKFIX
3764    int	    idx_sp;
3765    int	    do_sp;
3766#endif
3767
3768    idx_srr = findoption((char_u *)"srr");
3769    if (idx_srr < 0)
3770	do_srr = FALSE;
3771    else
3772	do_srr = !(options[idx_srr].flags & P_WAS_SET);
3773#ifdef FEAT_QUICKFIX
3774    idx_sp = findoption((char_u *)"sp");
3775    if (idx_sp < 0)
3776	do_sp = FALSE;
3777    else
3778	do_sp = !(options[idx_sp].flags & P_WAS_SET);
3779#endif
3780
3781    /*
3782     * Isolate the name of the shell:
3783     * - Skip beyond any path.  E.g., "/usr/bin/csh -f" -> "csh -f".
3784     * - Remove any argument.  E.g., "csh -f" -> "csh".
3785     * But don't allow a space in the path, so that this works:
3786     *   "/usr/bin/csh --rcfile ~/.cshrc"
3787     * But don't do that for Windows, it's common to have a space in the path.
3788     */
3789#ifdef WIN3264
3790    p = gettail(p_sh);
3791    p = vim_strnsave(p, (int)(skiptowhite(p) - p));
3792#else
3793    p = skiptowhite(p_sh);
3794    if (*p == NUL)
3795    {
3796	/* No white space, use the tail. */
3797	p = vim_strsave(gettail(p_sh));
3798    }
3799    else
3800    {
3801	char_u  *p1, *p2;
3802
3803	/* Find the last path separator before the space. */
3804	p1 = p_sh;
3805	for (p2 = p_sh; p2 < p; mb_ptr_adv(p2))
3806	    if (vim_ispathsep(*p2))
3807		p1 = p2 + 1;
3808	p = vim_strnsave(p1, (int)(p - p1));
3809    }
3810#endif
3811    if (p != NULL)
3812    {
3813	/*
3814	 * Default for p_sp is "| tee", for p_srr is ">".
3815	 * For known shells it is changed here to include stderr.
3816	 */
3817	if (	   fnamecmp(p, "csh") == 0
3818		|| fnamecmp(p, "tcsh") == 0
3819# if defined(OS2) || defined(WIN3264)	/* also check with .exe extension */
3820		|| fnamecmp(p, "csh.exe") == 0
3821		|| fnamecmp(p, "tcsh.exe") == 0
3822# endif
3823	   )
3824	{
3825#if defined(FEAT_QUICKFIX)
3826	    if (do_sp)
3827	    {
3828# ifdef WIN3264
3829		p_sp = (char_u *)">&";
3830# else
3831		p_sp = (char_u *)"|& tee";
3832# endif
3833		options[idx_sp].def_val[VI_DEFAULT] = p_sp;
3834	    }
3835#endif
3836	    if (do_srr)
3837	    {
3838		p_srr = (char_u *)">&";
3839		options[idx_srr].def_val[VI_DEFAULT] = p_srr;
3840	    }
3841	}
3842	else
3843# ifndef OS2	/* Always use bourne shell style redirection if we reach this */
3844	    if (       fnamecmp(p, "sh") == 0
3845		    || fnamecmp(p, "ksh") == 0
3846		    || fnamecmp(p, "zsh") == 0
3847		    || fnamecmp(p, "zsh-beta") == 0
3848		    || fnamecmp(p, "bash") == 0
3849#  ifdef WIN3264
3850		    || fnamecmp(p, "cmd") == 0
3851		    || fnamecmp(p, "sh.exe") == 0
3852		    || fnamecmp(p, "ksh.exe") == 0
3853		    || fnamecmp(p, "zsh.exe") == 0
3854		    || fnamecmp(p, "zsh-beta.exe") == 0
3855		    || fnamecmp(p, "bash.exe") == 0
3856		    || fnamecmp(p, "cmd.exe") == 0
3857#  endif
3858		    )
3859# endif
3860	    {
3861#if defined(FEAT_QUICKFIX)
3862		if (do_sp)
3863		{
3864# ifdef WIN3264
3865		    p_sp = (char_u *)">%s 2>&1";
3866# else
3867		    p_sp = (char_u *)"2>&1| tee";
3868# endif
3869		    options[idx_sp].def_val[VI_DEFAULT] = p_sp;
3870		}
3871#endif
3872		if (do_srr)
3873		{
3874		    p_srr = (char_u *)">%s 2>&1";
3875		    options[idx_srr].def_val[VI_DEFAULT] = p_srr;
3876		}
3877	    }
3878	vim_free(p);
3879    }
3880#endif
3881
3882#if defined(MSDOS) || defined(WIN3264) || defined(OS2)
3883    /*
3884     * Set 'shellcmdflag and 'shellquote' depending on the 'shell' option.
3885     * This is done after other initializations, where 'shell' might have been
3886     * set, but only if they have not been set before.  Default for p_shcf is
3887     * "/c", for p_shq is "".  For "sh" like  shells it is changed here to
3888     * "-c" and "\"", but not for DJGPP, because it starts the shell without
3889     * command.com.  And for Win32 we need to set p_sxq instead.
3890     */
3891    if (strstr((char *)gettail(p_sh), "sh") != NULL)
3892    {
3893	int	idx3;
3894
3895	idx3 = findoption((char_u *)"shcf");
3896	if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET))
3897	{
3898	    p_shcf = (char_u *)"-c";
3899	    options[idx3].def_val[VI_DEFAULT] = p_shcf;
3900	}
3901
3902# ifndef DJGPP
3903#  ifdef WIN3264
3904	/* Somehow Win32 requires the quotes around the redirection too */
3905	idx3 = findoption((char_u *)"sxq");
3906	if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET))
3907	{
3908	    p_sxq = (char_u *)"\"";
3909	    options[idx3].def_val[VI_DEFAULT] = p_sxq;
3910	}
3911#  else
3912	idx3 = findoption((char_u *)"shq");
3913	if (idx3 >= 0 && !(options[idx3].flags & P_WAS_SET))
3914	{
3915	    p_shq = (char_u *)"\"";
3916	    options[idx3].def_val[VI_DEFAULT] = p_shq;
3917	}
3918#  endif
3919# endif
3920    }
3921#endif
3922
3923#ifdef FEAT_TITLE
3924    set_title_defaults();
3925#endif
3926}
3927
3928#if defined(FEAT_MULTI_LANG) || defined(PROTO)
3929/*
3930 * When 'helplang' is still at its default value, set it to "lang".
3931 * Only the first two characters of "lang" are used.
3932 */
3933    void
3934set_helplang_default(lang)
3935    char_u	*lang;
3936{
3937    int		idx;
3938
3939    if (lang == NULL || STRLEN(lang) < 2)	/* safety check */
3940	return;
3941    idx = findoption((char_u *)"hlg");
3942    if (idx >= 0 && !(options[idx].flags & P_WAS_SET))
3943    {
3944	if (options[idx].flags & P_ALLOCED)
3945	    free_string_option(p_hlg);
3946	p_hlg = vim_strsave(lang);
3947	if (p_hlg == NULL)
3948	    p_hlg = empty_option;
3949	else
3950	{
3951	    /* zh_CN becomes "cn", zh_TW becomes "tw". */
3952	    if (STRNICMP(p_hlg, "zh_", 3) == 0 && STRLEN(p_hlg) >= 5)
3953	    {
3954		p_hlg[0] = TOLOWER_ASC(p_hlg[3]);
3955		p_hlg[1] = TOLOWER_ASC(p_hlg[4]);
3956	    }
3957	    p_hlg[2] = NUL;
3958	}
3959	options[idx].flags |= P_ALLOCED;
3960    }
3961}
3962#endif
3963
3964#ifdef FEAT_GUI
3965static char_u *gui_bg_default __ARGS((void));
3966
3967    static char_u *
3968gui_bg_default()
3969{
3970    if (gui_get_lightness(gui.back_pixel) < 127)
3971	return (char_u *)"dark";
3972    return (char_u *)"light";
3973}
3974
3975/*
3976 * Option initializations that can only be done after opening the GUI window.
3977 */
3978    void
3979init_gui_options()
3980{
3981    /* Set the 'background' option according to the lightness of the
3982     * background color, unless the user has set it already. */
3983    if (!option_was_set((char_u *)"bg") && STRCMP(p_bg, gui_bg_default()) != 0)
3984    {
3985	set_option_value((char_u *)"bg", 0L, gui_bg_default(), 0);
3986	highlight_changed();
3987    }
3988}
3989#endif
3990
3991#ifdef FEAT_TITLE
3992/*
3993 * 'title' and 'icon' only default to true if they have not been set or reset
3994 * in .vimrc and we can read the old value.
3995 * When 'title' and 'icon' have been reset in .vimrc, we won't even check if
3996 * they can be reset.  This reduces startup time when using X on a remote
3997 * machine.
3998 */
3999    void
4000set_title_defaults()
4001{
4002    int	    idx1;
4003    long    val;
4004
4005    /*
4006     * If GUI is (going to be) used, we can always set the window title and
4007     * icon name.  Saves a bit of time, because the X11 display server does
4008     * not need to be contacted.
4009     */
4010    idx1 = findoption((char_u *)"title");
4011    if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET))
4012    {
4013#ifdef FEAT_GUI
4014	if (gui.starting || gui.in_use)
4015	    val = TRUE;
4016	else
4017#endif
4018	    val = mch_can_restore_title();
4019	options[idx1].def_val[VI_DEFAULT] = (char_u *)(long_i)val;
4020	p_title = val;
4021    }
4022    idx1 = findoption((char_u *)"icon");
4023    if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET))
4024    {
4025#ifdef FEAT_GUI
4026	if (gui.starting || gui.in_use)
4027	    val = TRUE;
4028	else
4029#endif
4030	    val = mch_can_restore_icon();
4031	options[idx1].def_val[VI_DEFAULT] = (char_u *)(long_i)val;
4032	p_icon = val;
4033    }
4034}
4035#endif
4036
4037/*
4038 * Parse 'arg' for option settings.
4039 *
4040 * 'arg' may be IObuff, but only when no errors can be present and option
4041 * does not need to be expanded with option_expand().
4042 * "opt_flags":
4043 * 0 for ":set"
4044 * OPT_GLOBAL   for ":setglobal"
4045 * OPT_LOCAL    for ":setlocal" and a modeline
4046 * OPT_MODELINE for a modeline
4047 * OPT_WINONLY  to only set window-local options
4048 * OPT_NOWIN	to skip setting window-local options
4049 *
4050 * returns FAIL if an error is detected, OK otherwise
4051 */
4052    int
4053do_set(arg, opt_flags)
4054    char_u	*arg;		/* option string (may be written to!) */
4055    int		opt_flags;
4056{
4057    int		opt_idx;
4058    char_u	*errmsg;
4059    char_u	errbuf[80];
4060    char_u	*startarg;
4061    int		prefix;	/* 1: nothing, 0: "no", 2: "inv" in front of name */
4062    int		nextchar;	    /* next non-white char after option name */
4063    int		afterchar;	    /* character just after option name */
4064    int		len;
4065    int		i;
4066    long	value;
4067    int		key;
4068    long_u	flags;		    /* flags for current option */
4069    char_u	*varp = NULL;	    /* pointer to variable for current option */
4070    int		did_show = FALSE;   /* already showed one value */
4071    int		adding;		    /* "opt+=arg" */
4072    int		prepending;	    /* "opt^=arg" */
4073    int		removing;	    /* "opt-=arg" */
4074    int		cp_val = 0;
4075    char_u	key_name[2];
4076
4077    if (*arg == NUL)
4078    {
4079	showoptions(0, opt_flags);
4080	did_show = TRUE;
4081	goto theend;
4082    }
4083
4084    while (*arg != NUL)		/* loop to process all options */
4085    {
4086	errmsg = NULL;
4087	startarg = arg;		/* remember for error message */
4088
4089	if (STRNCMP(arg, "all", 3) == 0 && !isalpha(arg[3])
4090						&& !(opt_flags & OPT_MODELINE))
4091	{
4092	    /*
4093	     * ":set all"  show all options.
4094	     * ":set all&" set all options to their default value.
4095	     */
4096	    arg += 3;
4097	    if (*arg == '&')
4098	    {
4099		++arg;
4100		/* Only for :set command set global value of local options. */
4101		set_options_default(OPT_FREE | opt_flags);
4102	    }
4103	    else
4104	    {
4105		showoptions(1, opt_flags);
4106		did_show = TRUE;
4107	    }
4108	}
4109	else if (STRNCMP(arg, "termcap", 7) == 0 && !(opt_flags & OPT_MODELINE))
4110	{
4111	    showoptions(2, opt_flags);
4112	    show_termcodes();
4113	    did_show = TRUE;
4114	    arg += 7;
4115	}
4116	else
4117	{
4118	    prefix = 1;
4119	    if (STRNCMP(arg, "no", 2) == 0 && STRNCMP(arg, "novice", 6) != 0)
4120	    {
4121		prefix = 0;
4122		arg += 2;
4123	    }
4124	    else if (STRNCMP(arg, "inv", 3) == 0)
4125	    {
4126		prefix = 2;
4127		arg += 3;
4128	    }
4129
4130	    /* find end of name */
4131	    key = 0;
4132	    if (*arg == '<')
4133	    {
4134		nextchar = 0;
4135		opt_idx = -1;
4136		/* look out for <t_>;> */
4137		if (arg[1] == 't' && arg[2] == '_' && arg[3] && arg[4])
4138		    len = 5;
4139		else
4140		{
4141		    len = 1;
4142		    while (arg[len] != NUL && arg[len] != '>')
4143			++len;
4144		}
4145		if (arg[len] != '>')
4146		{
4147		    errmsg = e_invarg;
4148		    goto skip;
4149		}
4150		arg[len] = NUL;			    /* put NUL after name */
4151		if (arg[1] == 't' && arg[2] == '_') /* could be term code */
4152		    opt_idx = findoption(arg + 1);
4153		arg[len++] = '>';		    /* restore '>' */
4154		if (opt_idx == -1)
4155		    key = find_key_option(arg + 1);
4156	    }
4157	    else
4158	    {
4159		len = 0;
4160		/*
4161		 * The two characters after "t_" may not be alphanumeric.
4162		 */
4163		if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
4164		    len = 4;
4165		else
4166		    while (ASCII_ISALNUM(arg[len]) || arg[len] == '_')
4167			++len;
4168		nextchar = arg[len];
4169		arg[len] = NUL;			    /* put NUL after name */
4170		opt_idx = findoption(arg);
4171		arg[len] = nextchar;		    /* restore nextchar */
4172		if (opt_idx == -1)
4173		    key = find_key_option(arg);
4174	    }
4175
4176	    /* remember character after option name */
4177	    afterchar = arg[len];
4178
4179	    /* skip white space, allow ":set ai  ?" */
4180	    while (vim_iswhite(arg[len]))
4181		++len;
4182
4183	    adding = FALSE;
4184	    prepending = FALSE;
4185	    removing = FALSE;
4186	    if (arg[len] != NUL && arg[len + 1] == '=')
4187	    {
4188		if (arg[len] == '+')
4189		{
4190		    adding = TRUE;		/* "+=" */
4191		    ++len;
4192		}
4193		else if (arg[len] == '^')
4194		{
4195		    prepending = TRUE;		/* "^=" */
4196		    ++len;
4197		}
4198		else if (arg[len] == '-')
4199		{
4200		    removing = TRUE;		/* "-=" */
4201		    ++len;
4202		}
4203	    }
4204	    nextchar = arg[len];
4205
4206	    if (opt_idx == -1 && key == 0)	/* found a mismatch: skip */
4207	    {
4208		errmsg = (char_u *)N_("E518: Unknown option");
4209		goto skip;
4210	    }
4211
4212	    if (opt_idx >= 0)
4213	    {
4214		if (options[opt_idx].var == NULL)   /* hidden option: skip */
4215		{
4216		    /* Only give an error message when requesting the value of
4217		     * a hidden option, ignore setting it. */
4218		    if (vim_strchr((char_u *)"=:!&<", nextchar) == NULL
4219			    && (!(options[opt_idx].flags & P_BOOL)
4220				|| nextchar == '?'))
4221			errmsg = (char_u *)N_("E519: Option not supported");
4222		    goto skip;
4223		}
4224
4225		flags = options[opt_idx].flags;
4226		varp = get_varp_scope(&(options[opt_idx]), opt_flags);
4227	    }
4228	    else
4229	    {
4230		flags = P_STRING;
4231		if (key < 0)
4232		{
4233		    key_name[0] = KEY2TERMCAP0(key);
4234		    key_name[1] = KEY2TERMCAP1(key);
4235		}
4236		else
4237		{
4238		    key_name[0] = KS_KEY;
4239		    key_name[1] = (key & 0xff);
4240		}
4241	    }
4242
4243	    /* Skip all options that are not window-local (used when showing
4244	     * an already loaded buffer in a window). */
4245	    if ((opt_flags & OPT_WINONLY)
4246			  && (opt_idx < 0 || options[opt_idx].var != VAR_WIN))
4247		goto skip;
4248
4249	    /* Skip all options that are window-local (used for :vimgrep). */
4250	    if ((opt_flags & OPT_NOWIN) && opt_idx >= 0
4251					   && options[opt_idx].var == VAR_WIN)
4252		goto skip;
4253
4254	    /* Disallow changing some options from modelines. */
4255	    if (opt_flags & OPT_MODELINE)
4256	    {
4257		if (flags & (P_SECURE | P_NO_ML))
4258		{
4259		    errmsg = (char_u *)_("E520: Not allowed in a modeline");
4260		    goto skip;
4261		}
4262#ifdef FEAT_DIFF
4263		/* In diff mode some options are overruled.  This avoids that
4264		 * 'foldmethod' becomes "marker" instead of "diff" and that
4265		 * "wrap" gets set. */
4266		if (curwin->w_p_diff
4267			&& opt_idx >= 0  /* shut up coverity warning */
4268			&& (options[opt_idx].indir == PV_FDM
4269			    || options[opt_idx].indir == PV_WRAP))
4270		    goto skip;
4271#endif
4272	    }
4273
4274#ifdef HAVE_SANDBOX
4275	    /* Disallow changing some options in the sandbox */
4276	    if (sandbox != 0 && (flags & P_SECURE))
4277	    {
4278		errmsg = (char_u *)_(e_sandbox);
4279		goto skip;
4280	    }
4281#endif
4282
4283	    if (vim_strchr((char_u *)"?=:!&<", nextchar) != NULL)
4284	    {
4285		arg += len;
4286		cp_val = p_cp;
4287		if (nextchar == '&' && arg[1] == 'v' && arg[2] == 'i')
4288		{
4289		    if (arg[3] == 'm')	/* "opt&vim": set to Vim default */
4290		    {
4291			cp_val = FALSE;
4292			arg += 3;
4293		    }
4294		    else		/* "opt&vi": set to Vi default */
4295		    {
4296			cp_val = TRUE;
4297			arg += 2;
4298		    }
4299		}
4300		if (vim_strchr((char_u *)"?!&<", nextchar) != NULL
4301			&& arg[1] != NUL && !vim_iswhite(arg[1]))
4302		{
4303		    errmsg = e_trailing;
4304		    goto skip;
4305		}
4306	    }
4307
4308	    /*
4309	     * allow '=' and ':' as MSDOS command.com allows only one
4310	     * '=' character per "set" command line. grrr. (jw)
4311	     */
4312	    if (nextchar == '?'
4313		    || (prefix == 1
4314			&& vim_strchr((char_u *)"=:&<", nextchar) == NULL
4315			&& !(flags & P_BOOL)))
4316	    {
4317		/*
4318		 * print value
4319		 */
4320		if (did_show)
4321		    msg_putchar('\n');	    /* cursor below last one */
4322		else
4323		{
4324		    gotocmdline(TRUE);	    /* cursor at status line */
4325		    did_show = TRUE;	    /* remember that we did a line */
4326		}
4327		if (opt_idx >= 0)
4328		{
4329		    showoneopt(&options[opt_idx], opt_flags);
4330#ifdef FEAT_EVAL
4331		    if (p_verbose > 0)
4332		    {
4333			/* Mention where the option was last set. */
4334			if (varp == options[opt_idx].var)
4335			    last_set_msg(options[opt_idx].scriptID);
4336			else if ((int)options[opt_idx].indir & PV_WIN)
4337			    last_set_msg(curwin->w_p_scriptID[
4338				      (int)options[opt_idx].indir & PV_MASK]);
4339			else if ((int)options[opt_idx].indir & PV_BUF)
4340			    last_set_msg(curbuf->b_p_scriptID[
4341				      (int)options[opt_idx].indir & PV_MASK]);
4342		    }
4343#endif
4344		}
4345		else
4346		{
4347		    char_u	    *p;
4348
4349		    p = find_termcode(key_name);
4350		    if (p == NULL)
4351		    {
4352			errmsg = (char_u *)N_("E518: Unknown option");
4353			goto skip;
4354		    }
4355		    else
4356			(void)show_one_termcode(key_name, p, TRUE);
4357		}
4358		if (nextchar != '?'
4359			&& nextchar != NUL && !vim_iswhite(afterchar))
4360		    errmsg = e_trailing;
4361	    }
4362	    else
4363	    {
4364		if (flags & P_BOOL)		    /* boolean */
4365		{
4366		    if (nextchar == '=' || nextchar == ':')
4367		    {
4368			errmsg = e_invarg;
4369			goto skip;
4370		    }
4371
4372		    /*
4373		     * ":set opt!": invert
4374		     * ":set opt&": reset to default value
4375		     * ":set opt<": reset to global value
4376		     */
4377		    if (nextchar == '!')
4378			value = *(int *)(varp) ^ 1;
4379		    else if (nextchar == '&')
4380			value = (int)(long)(long_i)options[opt_idx].def_val[
4381						((flags & P_VI_DEF) || cp_val)
4382						 ?  VI_DEFAULT : VIM_DEFAULT];
4383		    else if (nextchar == '<')
4384		    {
4385			/* For 'autoread' -1 means to use global value. */
4386			if ((int *)varp == &curbuf->b_p_ar
4387						    && opt_flags == OPT_LOCAL)
4388			    value = -1;
4389			else
4390			    value = *(int *)get_varp_scope(&(options[opt_idx]),
4391								  OPT_GLOBAL);
4392		    }
4393		    else
4394		    {
4395			/*
4396			 * ":set invopt": invert
4397			 * ":set opt" or ":set noopt": set or reset
4398			 */
4399			if (nextchar != NUL && !vim_iswhite(afterchar))
4400			{
4401			    errmsg = e_trailing;
4402			    goto skip;
4403			}
4404			if (prefix == 2)	/* inv */
4405			    value = *(int *)(varp) ^ 1;
4406			else
4407			    value = prefix;
4408		    }
4409
4410		    errmsg = set_bool_option(opt_idx, varp, (int)value,
4411								   opt_flags);
4412		}
4413		else				    /* numeric or string */
4414		{
4415		    if (vim_strchr((char_u *)"=:&<", nextchar) == NULL
4416							       || prefix != 1)
4417		    {
4418			errmsg = e_invarg;
4419			goto skip;
4420		    }
4421
4422		    if (flags & P_NUM)		    /* numeric */
4423		    {
4424			/*
4425			 * Different ways to set a number option:
4426			 * &	    set to default value
4427			 * <	    set to global value
4428			 * <xx>	    accept special key codes for 'wildchar'
4429			 * c	    accept any non-digit for 'wildchar'
4430			 * [-]0-9   set number
4431			 * other    error
4432			 */
4433			++arg;
4434			if (nextchar == '&')
4435			    value = (long)(long_i)options[opt_idx].def_val[
4436						((flags & P_VI_DEF) || cp_val)
4437						 ?  VI_DEFAULT : VIM_DEFAULT];
4438			else if (nextchar == '<')
4439			    value = *(long *)get_varp_scope(&(options[opt_idx]),
4440								  OPT_GLOBAL);
4441			else if (((long *)varp == &p_wc
4442				    || (long *)varp == &p_wcm)
4443				&& (*arg == '<'
4444				    || *arg == '^'
4445				    || ((!arg[1] || vim_iswhite(arg[1]))
4446					&& !VIM_ISDIGIT(*arg))))
4447			{
4448			    value = string_to_key(arg);
4449			    if (value == 0 && (long *)varp != &p_wcm)
4450			    {
4451				errmsg = e_invarg;
4452				goto skip;
4453			    }
4454			}
4455				/* allow negative numbers (for 'undolevels') */
4456			else if (*arg == '-' || VIM_ISDIGIT(*arg))
4457			{
4458			    i = 0;
4459			    if (*arg == '-')
4460				i = 1;
4461#ifdef HAVE_STRTOL
4462			    value = strtol((char *)arg, NULL, 0);
4463			    if (arg[i] == '0' && TOLOWER_ASC(arg[i + 1]) == 'x')
4464				i += 2;
4465#else
4466			    value = atol((char *)arg);
4467#endif
4468			    while (VIM_ISDIGIT(arg[i]))
4469				++i;
4470			    if (arg[i] != NUL && !vim_iswhite(arg[i]))
4471			    {
4472				errmsg = e_invarg;
4473				goto skip;
4474			    }
4475			}
4476			else
4477			{
4478			    errmsg = (char_u *)N_("E521: Number required after =");
4479			    goto skip;
4480			}
4481
4482			if (adding)
4483			    value = *(long *)varp + value;
4484			if (prepending)
4485			    value = *(long *)varp * value;
4486			if (removing)
4487			    value = *(long *)varp - value;
4488			errmsg = set_num_option(opt_idx, varp, value,
4489					   errbuf, sizeof(errbuf), opt_flags);
4490		    }
4491		    else if (opt_idx >= 0)		    /* string */
4492		    {
4493			char_u	    *save_arg = NULL;
4494			char_u	    *s = NULL;
4495			char_u	    *oldval;	/* previous value if *varp */
4496			char_u	    *newval;
4497			char_u	    *origval;
4498			unsigned    newlen;
4499			int	    comma;
4500			int	    bs;
4501			int	    new_value_alloced;	/* new string option
4502							   was allocated */
4503
4504			/* When using ":set opt=val" for a global option
4505			 * with a local value the local value will be
4506			 * reset, use the global value here. */
4507			if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
4508				&& ((int)options[opt_idx].indir & PV_BOTH))
4509			    varp = options[opt_idx].var;
4510
4511			/* The old value is kept until we are sure that the
4512			 * new value is valid. */
4513			oldval = *(char_u **)varp;
4514			if (nextchar == '&')	/* set to default val */
4515			{
4516			    newval = options[opt_idx].def_val[
4517						((flags & P_VI_DEF) || cp_val)
4518						 ?  VI_DEFAULT : VIM_DEFAULT];
4519			    if ((char_u **)varp == &p_bg)
4520			    {
4521				/* guess the value of 'background' */
4522#ifdef FEAT_GUI
4523				if (gui.in_use)
4524				    newval = gui_bg_default();
4525				else
4526#endif
4527				    newval = term_bg_default();
4528			    }
4529
4530			    /* expand environment variables and ~ (since the
4531			     * default value was already expanded, only
4532			     * required when an environment variable was set
4533			     * later */
4534			    if (newval == NULL)
4535				newval = empty_option;
4536			    else
4537			    {
4538				s = option_expand(opt_idx, newval);
4539				if (s == NULL)
4540				    s = newval;
4541				newval = vim_strsave(s);
4542			    }
4543			    new_value_alloced = TRUE;
4544			}
4545			else if (nextchar == '<')	/* set to global val */
4546			{
4547			    newval = vim_strsave(*(char_u **)get_varp_scope(
4548					     &(options[opt_idx]), OPT_GLOBAL));
4549			    new_value_alloced = TRUE;
4550			}
4551			else
4552			{
4553			    ++arg;	/* jump to after the '=' or ':' */
4554
4555			    /*
4556			     * Set 'keywordprg' to ":help" if an empty
4557			     * value was passed to :set by the user.
4558			     * Misuse errbuf[] for the resulting string.
4559			     */
4560			    if (varp == (char_u *)&p_kp
4561					      && (*arg == NUL || *arg == ' '))
4562			    {
4563				STRCPY(errbuf, ":help");
4564				save_arg = arg;
4565				arg = errbuf;
4566			    }
4567			    /*
4568			     * Convert 'whichwrap' number to string, for
4569			     * backwards compatibility with Vim 3.0.
4570			     * Misuse errbuf[] for the resulting string.
4571			     */
4572			    else if (varp == (char_u *)&p_ww
4573							 && VIM_ISDIGIT(*arg))
4574			    {
4575				*errbuf = NUL;
4576				i = getdigits(&arg);
4577				if (i & 1)
4578				    STRCAT(errbuf, "b,");
4579				if (i & 2)
4580				    STRCAT(errbuf, "s,");
4581				if (i & 4)
4582				    STRCAT(errbuf, "h,l,");
4583				if (i & 8)
4584				    STRCAT(errbuf, "<,>,");
4585				if (i & 16)
4586				    STRCAT(errbuf, "[,],");
4587				if (*errbuf != NUL)	/* remove trailing , */
4588				    errbuf[STRLEN(errbuf) - 1] = NUL;
4589				save_arg = arg;
4590				arg = errbuf;
4591			    }
4592			    /*
4593			     * Remove '>' before 'dir' and 'bdir', for
4594			     * backwards compatibility with version 3.0
4595			     */
4596			    else if (  *arg == '>'
4597				    && (varp == (char_u *)&p_dir
4598					    || varp == (char_u *)&p_bdir))
4599			    {
4600				++arg;
4601			    }
4602
4603			    /* When setting the local value of a global
4604			     * option, the old value may be the global value. */
4605			    if (((int)options[opt_idx].indir & PV_BOTH)
4606						   && (opt_flags & OPT_LOCAL))
4607				origval = *(char_u **)get_varp(
4608							   &options[opt_idx]);
4609			    else
4610				origval = oldval;
4611
4612			    /*
4613			     * Copy the new string into allocated memory.
4614			     * Can't use set_string_option_direct(), because
4615			     * we need to remove the backslashes.
4616			     */
4617			    /* get a bit too much */
4618			    newlen = (unsigned)STRLEN(arg) + 1;
4619			    if (adding || prepending || removing)
4620				newlen += (unsigned)STRLEN(origval) + 1;
4621			    newval = alloc(newlen);
4622			    if (newval == NULL)  /* out of mem, don't change */
4623				break;
4624			    s = newval;
4625
4626			    /*
4627			     * Copy the string, skip over escaped chars.
4628			     * For MS-DOS and WIN32 backslashes before normal
4629			     * file name characters are not removed, and keep
4630			     * backslash at start, for "\\machine\path", but
4631			     * do remove it for "\\\\machine\\path".
4632			     * The reverse is found in ExpandOldSetting().
4633			     */
4634			    while (*arg && !vim_iswhite(*arg))
4635			    {
4636				if (*arg == '\\' && arg[1] != NUL
4637#ifdef BACKSLASH_IN_FILENAME
4638					&& !((flags & P_EXPAND)
4639						&& vim_isfilec(arg[1])
4640						&& (arg[1] != '\\'
4641						    || (s == newval
4642							&& arg[2] != '\\')))
4643#endif
4644								    )
4645				    ++arg;	/* remove backslash */
4646#ifdef FEAT_MBYTE
4647				if (has_mbyte
4648					&& (i = (*mb_ptr2len)(arg)) > 1)
4649				{
4650				    /* copy multibyte char */
4651				    mch_memmove(s, arg, (size_t)i);
4652				    arg += i;
4653				    s += i;
4654				}
4655				else
4656#endif
4657				    *s++ = *arg++;
4658			    }
4659			    *s = NUL;
4660
4661			    /*
4662			     * Expand environment variables and ~.
4663			     * Don't do it when adding without inserting a
4664			     * comma.
4665			     */
4666			    if (!(adding || prepending || removing)
4667							 || (flags & P_COMMA))
4668			    {
4669				s = option_expand(opt_idx, newval);
4670				if (s != NULL)
4671				{
4672				    vim_free(newval);
4673				    newlen = (unsigned)STRLEN(s) + 1;
4674				    if (adding || prepending || removing)
4675					newlen += (unsigned)STRLEN(origval) + 1;
4676				    newval = alloc(newlen);
4677				    if (newval == NULL)
4678					break;
4679				    STRCPY(newval, s);
4680				}
4681			    }
4682
4683			    /* locate newval[] in origval[] when removing it
4684			     * and when adding to avoid duplicates */
4685			    i = 0;	/* init for GCC */
4686			    if (removing || (flags & P_NODUP))
4687			    {
4688				i = (int)STRLEN(newval);
4689				bs = 0;
4690				for (s = origval; *s; ++s)
4691				{
4692				    if ((!(flags & P_COMMA)
4693						|| s == origval
4694						|| (s[-1] == ',' && !(bs & 1)))
4695					    && STRNCMP(s, newval, i) == 0
4696					    && (!(flags & P_COMMA)
4697						|| s[i] == ','
4698						|| s[i] == NUL))
4699					break;
4700				    /* Count backspaces.  Only a comma with an
4701				     * even number of backspaces before it is
4702				     * recognized as a separator */
4703				    if (s > origval && s[-1] == '\\')
4704					++bs;
4705				    else
4706					bs = 0;
4707				}
4708
4709				/* do not add if already there */
4710				if ((adding || prepending) && *s)
4711				{
4712				    prepending = FALSE;
4713				    adding = FALSE;
4714				    STRCPY(newval, origval);
4715				}
4716			    }
4717
4718			    /* concatenate the two strings; add a ',' if
4719			     * needed */
4720			    if (adding || prepending)
4721			    {
4722				comma = ((flags & P_COMMA) && *origval != NUL
4723							   && *newval != NUL);
4724				if (adding)
4725				{
4726				    i = (int)STRLEN(origval);
4727				    mch_memmove(newval + i + comma, newval,
4728							  STRLEN(newval) + 1);
4729				    mch_memmove(newval, origval, (size_t)i);
4730				}
4731				else
4732				{
4733				    i = (int)STRLEN(newval);
4734				    STRMOVE(newval + i + comma, origval);
4735				}
4736				if (comma)
4737				    newval[i] = ',';
4738			    }
4739
4740			    /* Remove newval[] from origval[]. (Note: "i" has
4741			     * been set above and is used here). */
4742			    if (removing)
4743			    {
4744				STRCPY(newval, origval);
4745				if (*s)
4746				{
4747				    /* may need to remove a comma */
4748				    if (flags & P_COMMA)
4749				    {
4750					if (s == origval)
4751					{
4752					    /* include comma after string */
4753					    if (s[i] == ',')
4754						++i;
4755					}
4756					else
4757					{
4758					    /* include comma before string */
4759					    --s;
4760					    ++i;
4761					}
4762				    }
4763				    STRMOVE(newval + (s - origval), s + i);
4764				}
4765			    }
4766
4767			    if (flags & P_FLAGLIST)
4768			    {
4769				/* Remove flags that appear twice. */
4770				for (s = newval; *s; ++s)
4771				    if ((!(flags & P_COMMA) || *s != ',')
4772					    && vim_strchr(s + 1, *s) != NULL)
4773				    {
4774					STRMOVE(s, s + 1);
4775					--s;
4776				    }
4777			    }
4778
4779			    if (save_arg != NULL)   /* number for 'whichwrap' */
4780				arg = save_arg;
4781			    new_value_alloced = TRUE;
4782			}
4783
4784			/* Set the new value. */
4785			*(char_u **)(varp) = newval;
4786
4787			/* Handle side effects, and set the global value for
4788			 * ":set" on local options. */
4789			errmsg = did_set_string_option(opt_idx, (char_u **)varp,
4790				new_value_alloced, oldval, errbuf, opt_flags);
4791
4792			/* If error detected, print the error message. */
4793			if (errmsg != NULL)
4794			    goto skip;
4795		    }
4796		    else	    /* key code option */
4797		    {
4798			char_u	    *p;
4799
4800			if (nextchar == '&')
4801			{
4802			    if (add_termcap_entry(key_name, TRUE) == FAIL)
4803				errmsg = (char_u *)N_("E522: Not found in termcap");
4804			}
4805			else
4806			{
4807			    ++arg; /* jump to after the '=' or ':' */
4808			    for (p = arg; *p && !vim_iswhite(*p); ++p)
4809				if (*p == '\\' && p[1] != NUL)
4810				    ++p;
4811			    nextchar = *p;
4812			    *p = NUL;
4813			    add_termcode(key_name, arg, FALSE);
4814			    *p = nextchar;
4815			}
4816			if (full_screen)
4817			    ttest(FALSE);
4818			redraw_all_later(CLEAR);
4819		    }
4820		}
4821
4822		if (opt_idx >= 0)
4823		    did_set_option(opt_idx, opt_flags,
4824					 !prepending && !adding && !removing);
4825	    }
4826
4827skip:
4828	    /*
4829	     * Advance to next argument.
4830	     * - skip until a blank found, taking care of backslashes
4831	     * - skip blanks
4832	     * - skip one "=val" argument (for hidden options ":set gfn =xx")
4833	     */
4834	    for (i = 0; i < 2 ; ++i)
4835	    {
4836		while (*arg != NUL && !vim_iswhite(*arg))
4837		    if (*arg++ == '\\' && *arg != NUL)
4838			++arg;
4839		arg = skipwhite(arg);
4840		if (*arg != '=')
4841		    break;
4842	    }
4843	}
4844
4845	if (errmsg != NULL)
4846	{
4847	    vim_strncpy(IObuff, (char_u *)_(errmsg), IOSIZE - 1);
4848	    i = (int)STRLEN(IObuff) + 2;
4849	    if (i + (arg - startarg) < IOSIZE)
4850	    {
4851		/* append the argument with the error */
4852		STRCAT(IObuff, ": ");
4853		mch_memmove(IObuff + i, startarg, (arg - startarg));
4854		IObuff[i + (arg - startarg)] = NUL;
4855	    }
4856	    /* make sure all characters are printable */
4857	    trans_characters(IObuff, IOSIZE);
4858
4859	    ++no_wait_return;	/* wait_return done later */
4860	    emsg(IObuff);	/* show error highlighted */
4861	    --no_wait_return;
4862
4863	    return FAIL;
4864	}
4865
4866	arg = skipwhite(arg);
4867    }
4868
4869theend:
4870    if (silent_mode && did_show)
4871    {
4872	/* After displaying option values in silent mode. */
4873	silent_mode = FALSE;
4874	info_message = TRUE;	/* use mch_msg(), not mch_errmsg() */
4875	msg_putchar('\n');
4876	cursor_on();		/* msg_start() switches it off */
4877	out_flush();
4878	silent_mode = TRUE;
4879	info_message = FALSE;	/* use mch_msg(), not mch_errmsg() */
4880    }
4881
4882    return OK;
4883}
4884
4885/*
4886 * Call this when an option has been given a new value through a user command.
4887 * Sets the P_WAS_SET flag and takes care of the P_INSECURE flag.
4888 */
4889    static void
4890did_set_option(opt_idx, opt_flags, new_value)
4891    int	    opt_idx;
4892    int	    opt_flags;	    /* possibly with OPT_MODELINE */
4893    int	    new_value;	    /* value was replaced completely */
4894{
4895    long_u	*p;
4896
4897    options[opt_idx].flags |= P_WAS_SET;
4898
4899    /* When an option is set in the sandbox, from a modeline or in secure mode
4900     * set the P_INSECURE flag.  Otherwise, if a new value is stored reset the
4901     * flag. */
4902    p = insecure_flag(opt_idx, opt_flags);
4903    if (secure
4904#ifdef HAVE_SANDBOX
4905	    || sandbox != 0
4906#endif
4907	    || (opt_flags & OPT_MODELINE))
4908	*p = *p | P_INSECURE;
4909    else if (new_value)
4910	*p = *p & ~P_INSECURE;
4911}
4912
4913    static char_u *
4914illegal_char(errbuf, c)
4915    char_u	*errbuf;
4916    int		c;
4917{
4918    if (errbuf == NULL)
4919	return (char_u *)"";
4920    sprintf((char *)errbuf, _("E539: Illegal character <%s>"),
4921							(char *)transchar(c));
4922    return errbuf;
4923}
4924
4925/*
4926 * Convert a key name or string into a key value.
4927 * Used for 'wildchar' and 'cedit' options.
4928 */
4929    static int
4930string_to_key(arg)
4931    char_u	*arg;
4932{
4933    if (*arg == '<')
4934	return find_key_option(arg + 1);
4935    if (*arg == '^')
4936	return Ctrl_chr(arg[1]);
4937    return *arg;
4938}
4939
4940#ifdef FEAT_CMDWIN
4941/*
4942 * Check value of 'cedit' and set cedit_key.
4943 * Returns NULL if value is OK, error message otherwise.
4944 */
4945    static char_u *
4946check_cedit()
4947{
4948    int n;
4949
4950    if (*p_cedit == NUL)
4951	cedit_key = -1;
4952    else
4953    {
4954	n = string_to_key(p_cedit);
4955	if (vim_isprintc(n))
4956	    return e_invarg;
4957	cedit_key = n;
4958    }
4959    return NULL;
4960}
4961#endif
4962
4963#ifdef FEAT_TITLE
4964/*
4965 * When changing 'title', 'titlestring', 'icon' or 'iconstring', call
4966 * maketitle() to create and display it.
4967 * When switching the title or icon off, call mch_restore_title() to get
4968 * the old value back.
4969 */
4970    static void
4971did_set_title(icon)
4972    int	    icon;	    /* Did set icon instead of title */
4973{
4974    if (starting != NO_SCREEN
4975#ifdef FEAT_GUI
4976	    && !gui.starting
4977#endif
4978				)
4979    {
4980	maketitle();
4981	if (icon)
4982	{
4983	    if (!p_icon)
4984		mch_restore_title(2);
4985	}
4986	else
4987	{
4988	    if (!p_title)
4989		mch_restore_title(1);
4990	}
4991    }
4992}
4993#endif
4994
4995/*
4996 * set_options_bin -  called when 'bin' changes value.
4997 */
4998    void
4999set_options_bin(oldval, newval, opt_flags)
5000    int		oldval;
5001    int		newval;
5002    int		opt_flags;	/* OPT_LOCAL and/or OPT_GLOBAL */
5003{
5004    /*
5005     * The option values that are changed when 'bin' changes are
5006     * copied when 'bin is set and restored when 'bin' is reset.
5007     */
5008    if (newval)
5009    {
5010	if (!oldval)		/* switched on */
5011	{
5012	    if (!(opt_flags & OPT_GLOBAL))
5013	    {
5014		curbuf->b_p_tw_nobin = curbuf->b_p_tw;
5015		curbuf->b_p_wm_nobin = curbuf->b_p_wm;
5016		curbuf->b_p_ml_nobin = curbuf->b_p_ml;
5017		curbuf->b_p_et_nobin = curbuf->b_p_et;
5018	    }
5019	    if (!(opt_flags & OPT_LOCAL))
5020	    {
5021		p_tw_nobin = p_tw;
5022		p_wm_nobin = p_wm;
5023		p_ml_nobin = p_ml;
5024		p_et_nobin = p_et;
5025	    }
5026	}
5027
5028	if (!(opt_flags & OPT_GLOBAL))
5029	{
5030	    curbuf->b_p_tw = 0;	/* no automatic line wrap */
5031	    curbuf->b_p_wm = 0;	/* no automatic line wrap */
5032	    curbuf->b_p_ml = 0;	/* no modelines */
5033	    curbuf->b_p_et = 0;	/* no expandtab */
5034	}
5035	if (!(opt_flags & OPT_LOCAL))
5036	{
5037	    p_tw = 0;
5038	    p_wm = 0;
5039	    p_ml = FALSE;
5040	    p_et = FALSE;
5041	    p_bin = TRUE;	/* needed when called for the "-b" argument */
5042	}
5043    }
5044    else if (oldval)		/* switched off */
5045    {
5046	if (!(opt_flags & OPT_GLOBAL))
5047	{
5048	    curbuf->b_p_tw = curbuf->b_p_tw_nobin;
5049	    curbuf->b_p_wm = curbuf->b_p_wm_nobin;
5050	    curbuf->b_p_ml = curbuf->b_p_ml_nobin;
5051	    curbuf->b_p_et = curbuf->b_p_et_nobin;
5052	}
5053	if (!(opt_flags & OPT_LOCAL))
5054	{
5055	    p_tw = p_tw_nobin;
5056	    p_wm = p_wm_nobin;
5057	    p_ml = p_ml_nobin;
5058	    p_et = p_et_nobin;
5059	}
5060    }
5061}
5062
5063#ifdef FEAT_VIMINFO
5064/*
5065 * Find the parameter represented by the given character (eg ', :, ", or /),
5066 * and return its associated value in the 'viminfo' string.
5067 * Only works for number parameters, not for 'r' or 'n'.
5068 * If the parameter is not specified in the string or there is no following
5069 * number, return -1.
5070 */
5071    int
5072get_viminfo_parameter(type)
5073    int	    type;
5074{
5075    char_u  *p;
5076
5077    p = find_viminfo_parameter(type);
5078    if (p != NULL && VIM_ISDIGIT(*p))
5079	return atoi((char *)p);
5080    return -1;
5081}
5082
5083/*
5084 * Find the parameter represented by the given character (eg ''', ':', '"', or
5085 * '/') in the 'viminfo' option and return a pointer to the string after it.
5086 * Return NULL if the parameter is not specified in the string.
5087 */
5088    char_u *
5089find_viminfo_parameter(type)
5090    int	    type;
5091{
5092    char_u  *p;
5093
5094    for (p = p_viminfo; *p; ++p)
5095    {
5096	if (*p == type)
5097	    return p + 1;
5098	if (*p == 'n')		    /* 'n' is always the last one */
5099	    break;
5100	p = vim_strchr(p, ',');	    /* skip until next ',' */
5101	if (p == NULL)		    /* hit the end without finding parameter */
5102	    break;
5103    }
5104    return NULL;
5105}
5106#endif
5107
5108/*
5109 * Expand environment variables for some string options.
5110 * These string options cannot be indirect!
5111 * If "val" is NULL expand the current value of the option.
5112 * Return pointer to NameBuff, or NULL when not expanded.
5113 */
5114    static char_u *
5115option_expand(opt_idx, val)
5116    int		opt_idx;
5117    char_u	*val;
5118{
5119    /* if option doesn't need expansion nothing to do */
5120    if (!(options[opt_idx].flags & P_EXPAND) || options[opt_idx].var == NULL)
5121	return NULL;
5122
5123    /* If val is longer than MAXPATHL no meaningful expansion can be done,
5124     * expand_env() would truncate the string. */
5125    if (val != NULL && STRLEN(val) > MAXPATHL)
5126	return NULL;
5127
5128    if (val == NULL)
5129	val = *(char_u **)options[opt_idx].var;
5130
5131    /*
5132     * Expanding this with NameBuff, expand_env() must not be passed IObuff.
5133     * Escape spaces when expanding 'tags', they are used to separate file
5134     * names.
5135     * For 'spellsuggest' expand after "file:".
5136     */
5137    expand_env_esc(val, NameBuff, MAXPATHL,
5138	    (char_u **)options[opt_idx].var == &p_tags, FALSE,
5139#ifdef FEAT_SPELL
5140	    (char_u **)options[opt_idx].var == &p_sps ? (char_u *)"file:" :
5141#endif
5142				  NULL);
5143    if (STRCMP(NameBuff, val) == 0)   /* they are the same */
5144	return NULL;
5145
5146    return NameBuff;
5147}
5148
5149/*
5150 * After setting various option values: recompute variables that depend on
5151 * option values.
5152 */
5153    static void
5154didset_options()
5155{
5156    /* initialize the table for 'iskeyword' et.al. */
5157    (void)init_chartab();
5158
5159#ifdef FEAT_MBYTE
5160    (void)opt_strings_flags(p_cmp, p_cmp_values, &cmp_flags, TRUE);
5161#endif
5162    (void)opt_strings_flags(p_bkc, p_bkc_values, &bkc_flags, TRUE);
5163#ifdef FEAT_SESSION
5164    (void)opt_strings_flags(p_ssop, p_ssop_values, &ssop_flags, TRUE);
5165    (void)opt_strings_flags(p_vop, p_ssop_values, &vop_flags, TRUE);
5166#endif
5167#ifdef FEAT_FOLDING
5168    (void)opt_strings_flags(p_fdo, p_fdo_values, &fdo_flags, TRUE);
5169#endif
5170    (void)opt_strings_flags(p_dy, p_dy_values, &dy_flags, TRUE);
5171#ifdef FEAT_VIRTUALEDIT
5172    (void)opt_strings_flags(p_ve, p_ve_values, &ve_flags, TRUE);
5173#endif
5174#if defined(FEAT_MOUSE) && (defined(UNIX) || defined(VMS))
5175    (void)opt_strings_flags(p_ttym, p_ttym_values, &ttym_flags, FALSE);
5176#endif
5177#ifdef FEAT_SPELL
5178    (void)spell_check_msm();
5179    (void)spell_check_sps();
5180    (void)compile_cap_prog(curwin->w_s);
5181#endif
5182#if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32)
5183    (void)opt_strings_flags(p_toolbar, p_toolbar_values, &toolbar_flags, TRUE);
5184#endif
5185#if defined(FEAT_TOOLBAR) && defined(FEAT_GUI_GTK)
5186    (void)opt_strings_flags(p_tbis, p_tbis_values, &tbis_flags, FALSE);
5187#endif
5188#ifdef FEAT_CMDWIN
5189    /* set cedit_key */
5190    (void)check_cedit();
5191#endif
5192}
5193
5194/*
5195 * Check for string options that are NULL (normally only termcap options).
5196 */
5197    void
5198check_options()
5199{
5200    int		opt_idx;
5201
5202    for (opt_idx = 0; options[opt_idx].fullname != NULL; opt_idx++)
5203	if ((options[opt_idx].flags & P_STRING) && options[opt_idx].var != NULL)
5204	    check_string_option((char_u **)get_varp(&(options[opt_idx])));
5205}
5206
5207/*
5208 * Check string options in a buffer for NULL value.
5209 */
5210    void
5211check_buf_options(buf)
5212    buf_T	*buf;
5213{
5214#if defined(FEAT_QUICKFIX)
5215    check_string_option(&buf->b_p_bh);
5216    check_string_option(&buf->b_p_bt);
5217#endif
5218#ifdef FEAT_MBYTE
5219    check_string_option(&buf->b_p_fenc);
5220#endif
5221    check_string_option(&buf->b_p_ff);
5222#ifdef FEAT_FIND_ID
5223    check_string_option(&buf->b_p_def);
5224    check_string_option(&buf->b_p_inc);
5225# ifdef FEAT_EVAL
5226    check_string_option(&buf->b_p_inex);
5227# endif
5228#endif
5229#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
5230    check_string_option(&buf->b_p_inde);
5231    check_string_option(&buf->b_p_indk);
5232#endif
5233#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
5234    check_string_option(&buf->b_p_bexpr);
5235#endif
5236#if defined(FEAT_CRYPT)
5237    check_string_option(&buf->b_p_cm);
5238#endif
5239#if defined(FEAT_EVAL)
5240    check_string_option(&buf->b_p_fex);
5241#endif
5242#ifdef FEAT_CRYPT
5243    check_string_option(&buf->b_p_key);
5244#endif
5245    check_string_option(&buf->b_p_kp);
5246    check_string_option(&buf->b_p_mps);
5247    check_string_option(&buf->b_p_fo);
5248    check_string_option(&buf->b_p_flp);
5249    check_string_option(&buf->b_p_isk);
5250#ifdef FEAT_COMMENTS
5251    check_string_option(&buf->b_p_com);
5252#endif
5253#ifdef FEAT_FOLDING
5254    check_string_option(&buf->b_p_cms);
5255#endif
5256    check_string_option(&buf->b_p_nf);
5257#ifdef FEAT_TEXTOBJ
5258    check_string_option(&buf->b_p_qe);
5259#endif
5260#ifdef FEAT_SYN_HL
5261    check_string_option(&buf->b_p_syn);
5262#endif
5263#ifdef FEAT_SPELL
5264    check_string_option(&buf->b_s.b_p_spc);
5265    check_string_option(&buf->b_s.b_p_spf);
5266    check_string_option(&buf->b_s.b_p_spl);
5267#endif
5268#ifdef FEAT_SEARCHPATH
5269    check_string_option(&buf->b_p_sua);
5270#endif
5271#ifdef FEAT_CINDENT
5272    check_string_option(&buf->b_p_cink);
5273    check_string_option(&buf->b_p_cino);
5274#endif
5275#ifdef FEAT_AUTOCMD
5276    check_string_option(&buf->b_p_ft);
5277#endif
5278#ifdef FEAT_OSFILETYPE
5279    check_string_option(&buf->b_p_oft);
5280#endif
5281#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
5282    check_string_option(&buf->b_p_cinw);
5283#endif
5284#ifdef FEAT_INS_EXPAND
5285    check_string_option(&buf->b_p_cpt);
5286#endif
5287#ifdef FEAT_COMPL_FUNC
5288    check_string_option(&buf->b_p_cfu);
5289    check_string_option(&buf->b_p_ofu);
5290#endif
5291#ifdef FEAT_KEYMAP
5292    check_string_option(&buf->b_p_keymap);
5293#endif
5294#ifdef FEAT_QUICKFIX
5295    check_string_option(&buf->b_p_gp);
5296    check_string_option(&buf->b_p_mp);
5297    check_string_option(&buf->b_p_efm);
5298#endif
5299    check_string_option(&buf->b_p_ep);
5300    check_string_option(&buf->b_p_path);
5301    check_string_option(&buf->b_p_tags);
5302#ifdef FEAT_INS_EXPAND
5303    check_string_option(&buf->b_p_dict);
5304    check_string_option(&buf->b_p_tsr);
5305#endif
5306}
5307
5308/*
5309 * Free the string allocated for an option.
5310 * Checks for the string being empty_option. This may happen if we're out of
5311 * memory, vim_strsave() returned NULL, which was replaced by empty_option by
5312 * check_options().
5313 * Does NOT check for P_ALLOCED flag!
5314 */
5315    void
5316free_string_option(p)
5317    char_u	*p;
5318{
5319    if (p != empty_option)
5320	vim_free(p);
5321}
5322
5323    void
5324clear_string_option(pp)
5325    char_u	**pp;
5326{
5327    if (*pp != empty_option)
5328	vim_free(*pp);
5329    *pp = empty_option;
5330}
5331
5332    static void
5333check_string_option(pp)
5334    char_u	**pp;
5335{
5336    if (*pp == NULL)
5337	*pp = empty_option;
5338}
5339
5340/*
5341 * Mark a terminal option as allocated, found by a pointer into term_strings[].
5342 */
5343    void
5344set_term_option_alloced(p)
5345    char_u **p;
5346{
5347    int		opt_idx;
5348
5349    for (opt_idx = 1; options[opt_idx].fullname != NULL; opt_idx++)
5350	if (options[opt_idx].var == (char_u *)p)
5351	{
5352	    options[opt_idx].flags |= P_ALLOCED;
5353	    return;
5354	}
5355    return; /* cannot happen: didn't find it! */
5356}
5357
5358#if defined(FEAT_EVAL) || defined(PROTO)
5359/*
5360 * Return TRUE when option "opt" was set from a modeline or in secure mode.
5361 * Return FALSE when it wasn't.
5362 * Return -1 for an unknown option.
5363 */
5364    int
5365was_set_insecurely(opt, opt_flags)
5366    char_u  *opt;
5367    int	    opt_flags;
5368{
5369    int	    idx = findoption(opt);
5370    long_u  *flagp;
5371
5372    if (idx >= 0)
5373    {
5374	flagp = insecure_flag(idx, opt_flags);
5375	return (*flagp & P_INSECURE) != 0;
5376    }
5377    EMSG2(_(e_intern2), "was_set_insecurely()");
5378    return -1;
5379}
5380
5381/*
5382 * Get a pointer to the flags used for the P_INSECURE flag of option
5383 * "opt_idx".  For some local options a local flags field is used.
5384 */
5385    static long_u *
5386insecure_flag(opt_idx, opt_flags)
5387    int		opt_idx;
5388    int		opt_flags;
5389{
5390    if (opt_flags & OPT_LOCAL)
5391	switch ((int)options[opt_idx].indir)
5392	{
5393#ifdef FEAT_STL_OPT
5394	    case PV_STL:	return &curwin->w_p_stl_flags;
5395#endif
5396#ifdef FEAT_EVAL
5397# ifdef FEAT_FOLDING
5398	    case PV_FDE:	return &curwin->w_p_fde_flags;
5399	    case PV_FDT:	return &curwin->w_p_fdt_flags;
5400# endif
5401# ifdef FEAT_BEVAL
5402	    case PV_BEXPR:	return &curbuf->b_p_bexpr_flags;
5403# endif
5404# if defined(FEAT_CINDENT)
5405	    case PV_INDE:	return &curbuf->b_p_inde_flags;
5406# endif
5407	    case PV_FEX:	return &curbuf->b_p_fex_flags;
5408# ifdef FEAT_FIND_ID
5409	    case PV_INEX:	return &curbuf->b_p_inex_flags;
5410# endif
5411#endif
5412	}
5413
5414    /* Nothing special, return global flags field. */
5415    return &options[opt_idx].flags;
5416}
5417#endif
5418
5419#ifdef FEAT_TITLE
5420static void redraw_titles __ARGS((void));
5421
5422/*
5423 * Redraw the window title and/or tab page text later.
5424 */
5425static void redraw_titles()
5426{
5427    need_maketitle = TRUE;
5428# ifdef FEAT_WINDOWS
5429    redraw_tabline = TRUE;
5430# endif
5431}
5432#endif
5433
5434/*
5435 * Set a string option to a new value (without checking the effect).
5436 * The string is copied into allocated memory.
5437 * if ("opt_idx" == -1) "name" is used, otherwise "opt_idx" is used.
5438 * When "set_sid" is zero set the scriptID to current_SID.  When "set_sid" is
5439 * SID_NONE don't set the scriptID.  Otherwise set the scriptID to "set_sid".
5440 */
5441    void
5442set_string_option_direct(name, opt_idx, val, opt_flags, set_sid)
5443    char_u	*name;
5444    int		opt_idx;
5445    char_u	*val;
5446    int		opt_flags;	/* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
5447    int		set_sid UNUSED;
5448{
5449    char_u	*s;
5450    char_u	**varp;
5451    int		both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
5452    int		idx = opt_idx;
5453
5454    if (idx == -1)		/* use name */
5455    {
5456	idx = findoption(name);
5457	if (idx < 0)	/* not found (should not happen) */
5458	{
5459	    EMSG2(_(e_intern2), "set_string_option_direct()");
5460	    return;
5461	}
5462    }
5463
5464    if (options[idx].var == NULL)	/* can't set hidden option */
5465	return;
5466
5467    s = vim_strsave(val);
5468    if (s != NULL)
5469    {
5470	varp = (char_u **)get_varp_scope(&(options[idx]),
5471					       both ? OPT_LOCAL : opt_flags);
5472	if ((opt_flags & OPT_FREE) && (options[idx].flags & P_ALLOCED))
5473	    free_string_option(*varp);
5474	*varp = s;
5475
5476	/* For buffer/window local option may also set the global value. */
5477	if (both)
5478	    set_string_option_global(idx, varp);
5479
5480	options[idx].flags |= P_ALLOCED;
5481
5482	/* When setting both values of a global option with a local value,
5483	 * make the local value empty, so that the global value is used. */
5484	if (((int)options[idx].indir & PV_BOTH) && both)
5485	{
5486	    free_string_option(*varp);
5487	    *varp = empty_option;
5488	}
5489# ifdef FEAT_EVAL
5490	if (set_sid != SID_NONE)
5491	    set_option_scriptID_idx(idx, opt_flags,
5492					set_sid == 0 ? current_SID : set_sid);
5493# endif
5494    }
5495}
5496
5497/*
5498 * Set global value for string option when it's a local option.
5499 */
5500    static void
5501set_string_option_global(opt_idx, varp)
5502    int		opt_idx;	/* option index */
5503    char_u	**varp;		/* pointer to option variable */
5504{
5505    char_u	**p, *s;
5506
5507    /* the global value is always allocated */
5508    if (options[opt_idx].var == VAR_WIN)
5509	p = (char_u **)GLOBAL_WO(varp);
5510    else
5511	p = (char_u **)options[opt_idx].var;
5512    if (options[opt_idx].indir != PV_NONE
5513	    && p != varp
5514	    && (s = vim_strsave(*varp)) != NULL)
5515    {
5516	free_string_option(*p);
5517	*p = s;
5518    }
5519}
5520
5521/*
5522 * Set a string option to a new value, and handle the effects.
5523 */
5524    static void
5525set_string_option(opt_idx, value, opt_flags)
5526    int		opt_idx;
5527    char_u	*value;
5528    int		opt_flags;	/* OPT_LOCAL and/or OPT_GLOBAL */
5529{
5530    char_u	*s;
5531    char_u	**varp;
5532    char_u	*oldval;
5533
5534    if (options[opt_idx].var == NULL)	/* don't set hidden option */
5535	return;
5536
5537    s = vim_strsave(value);
5538    if (s != NULL)
5539    {
5540	varp = (char_u **)get_varp_scope(&(options[opt_idx]),
5541		(opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
5542		    ? (((int)options[opt_idx].indir & PV_BOTH)
5543			? OPT_GLOBAL : OPT_LOCAL)
5544		    : opt_flags);
5545	oldval = *varp;
5546	*varp = s;
5547	if (did_set_string_option(opt_idx, varp, TRUE, oldval, NULL,
5548							   opt_flags) == NULL)
5549	    did_set_option(opt_idx, opt_flags, TRUE);
5550    }
5551}
5552
5553/*
5554 * Handle string options that need some action to perform when changed.
5555 * Returns NULL for success, or an error message for an error.
5556 */
5557    static char_u *
5558did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
5559								    opt_flags)
5560    int		opt_idx;		/* index in options[] table */
5561    char_u	**varp;			/* pointer to the option variable */
5562    int		new_value_alloced;	/* new value was allocated */
5563    char_u	*oldval;		/* previous value of the option */
5564    char_u	*errbuf;		/* buffer for errors, or NULL */
5565    int		opt_flags;		/* OPT_LOCAL and/or OPT_GLOBAL */
5566{
5567    char_u	*errmsg = NULL;
5568    char_u	*s, *p;
5569    int		did_chartab = FALSE;
5570    char_u	**gvarp;
5571    long_u	free_oldval = (options[opt_idx].flags & P_ALLOCED);
5572#ifdef FEAT_GUI
5573    /* set when changing an option that only requires a redraw in the GUI */
5574    int		redraw_gui_only = FALSE;
5575#endif
5576
5577    /* Get the global option to compare with, otherwise we would have to check
5578     * two values for all local options. */
5579    gvarp = (char_u **)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL);
5580
5581    /* Disallow changing some options from secure mode */
5582    if ((secure
5583#ifdef HAVE_SANDBOX
5584		|| sandbox != 0
5585#endif
5586		) && (options[opt_idx].flags & P_SECURE))
5587    {
5588	errmsg = e_secure;
5589    }
5590
5591    /* Check for a "normal" file name in some options.  Disallow a path
5592     * separator (slash and/or backslash), wildcards and characters that are
5593     * often illegal in a file name. */
5594    else if ((options[opt_idx].flags & P_NFNAME)
5595			 && vim_strpbrk(*varp, (char_u *)"/\\*?[|<>") != NULL)
5596    {
5597	errmsg = e_invarg;
5598    }
5599
5600    /* 'term' */
5601    else if (varp == &T_NAME)
5602    {
5603	if (T_NAME[0] == NUL)
5604	    errmsg = (char_u *)N_("E529: Cannot set 'term' to empty string");
5605#ifdef FEAT_GUI
5606	if (gui.in_use)
5607	    errmsg = (char_u *)N_("E530: Cannot change term in GUI");
5608	else if (term_is_gui(T_NAME))
5609	    errmsg = (char_u *)N_("E531: Use \":gui\" to start the GUI");
5610#endif
5611	else if (set_termname(T_NAME) == FAIL)
5612	    errmsg = (char_u *)N_("E522: Not found in termcap");
5613	else
5614	    /* Screen colors may have changed. */
5615	    redraw_later_clear();
5616    }
5617
5618    /* 'backupcopy' */
5619    else if (varp == &p_bkc)
5620    {
5621	if (opt_strings_flags(p_bkc, p_bkc_values, &bkc_flags, TRUE) != OK)
5622	    errmsg = e_invarg;
5623	if (((bkc_flags & BKC_AUTO) != 0)
5624		+ ((bkc_flags & BKC_YES) != 0)
5625		+ ((bkc_flags & BKC_NO) != 0) != 1)
5626	{
5627	    /* Must have exactly one of "auto", "yes"  and "no". */
5628	    (void)opt_strings_flags(oldval, p_bkc_values, &bkc_flags, TRUE);
5629	    errmsg = e_invarg;
5630	}
5631    }
5632
5633    /* 'backupext' and 'patchmode' */
5634    else if (varp == &p_bex || varp == &p_pm)
5635    {
5636	if (STRCMP(*p_bex == '.' ? p_bex + 1 : p_bex,
5637		     *p_pm == '.' ? p_pm + 1 : p_pm) == 0)
5638	    errmsg = (char_u *)N_("E589: 'backupext' and 'patchmode' are equal");
5639    }
5640
5641    /*
5642     * 'isident', 'iskeyword', 'isprint or 'isfname' option: refill chartab[]
5643     * If the new option is invalid, use old value.  'lisp' option: refill
5644     * chartab[] for '-' char
5645     */
5646    else if (  varp == &p_isi
5647	    || varp == &(curbuf->b_p_isk)
5648	    || varp == &p_isp
5649	    || varp == &p_isf)
5650    {
5651	if (init_chartab() == FAIL)
5652	{
5653	    did_chartab = TRUE;	    /* need to restore it below */
5654	    errmsg = e_invarg;	    /* error in value */
5655	}
5656    }
5657
5658    /* 'helpfile' */
5659    else if (varp == &p_hf)
5660    {
5661	/* May compute new values for $VIM and $VIMRUNTIME */
5662	if (didset_vim)
5663	{
5664	    vim_setenv((char_u *)"VIM", (char_u *)"");
5665	    didset_vim = FALSE;
5666	}
5667	if (didset_vimruntime)
5668	{
5669	    vim_setenv((char_u *)"VIMRUNTIME", (char_u *)"");
5670	    didset_vimruntime = FALSE;
5671	}
5672    }
5673
5674#ifdef FEAT_SYN_HL
5675    /* 'colorcolumn' */
5676    else if (varp == &curwin->w_p_cc)
5677	errmsg = check_colorcolumn(curwin);
5678#endif
5679
5680#ifdef FEAT_MULTI_LANG
5681    /* 'helplang' */
5682    else if (varp == &p_hlg)
5683    {
5684	/* Check for "", "ab", "ab,cd", etc. */
5685	for (s = p_hlg; *s != NUL; s += 3)
5686	{
5687	    if (s[1] == NUL || ((s[2] != ',' || s[3] == NUL) && s[2] != NUL))
5688	    {
5689		errmsg = e_invarg;
5690		break;
5691	    }
5692	    if (s[2] == NUL)
5693		break;
5694	}
5695    }
5696#endif
5697
5698    /* 'highlight' */
5699    else if (varp == &p_hl)
5700    {
5701	if (highlight_changed() == FAIL)
5702	    errmsg = e_invarg;	/* invalid flags */
5703    }
5704
5705    /* 'nrformats' */
5706    else if (gvarp == &p_nf)
5707    {
5708	if (check_opt_strings(*varp, p_nf_values, TRUE) != OK)
5709	    errmsg = e_invarg;
5710    }
5711
5712#ifdef FEAT_SESSION
5713    /* 'sessionoptions' */
5714    else if (varp == &p_ssop)
5715    {
5716	if (opt_strings_flags(p_ssop, p_ssop_values, &ssop_flags, TRUE) != OK)
5717	    errmsg = e_invarg;
5718	if ((ssop_flags & SSOP_CURDIR) && (ssop_flags & SSOP_SESDIR))
5719	{
5720	    /* Don't allow both "sesdir" and "curdir". */
5721	    (void)opt_strings_flags(oldval, p_ssop_values, &ssop_flags, TRUE);
5722	    errmsg = e_invarg;
5723	}
5724    }
5725    /* 'viewoptions' */
5726    else if (varp == &p_vop)
5727    {
5728	if (opt_strings_flags(p_vop, p_ssop_values, &vop_flags, TRUE) != OK)
5729	    errmsg = e_invarg;
5730    }
5731#endif
5732
5733    /* 'scrollopt' */
5734#ifdef FEAT_SCROLLBIND
5735    else if (varp == &p_sbo)
5736    {
5737	if (check_opt_strings(p_sbo, p_scbopt_values, TRUE) != OK)
5738	    errmsg = e_invarg;
5739    }
5740#endif
5741
5742    /* 'ambiwidth' */
5743#ifdef FEAT_MBYTE
5744    else if (varp == &p_ambw)
5745    {
5746	if (check_opt_strings(p_ambw, p_ambw_values, FALSE) != OK)
5747	    errmsg = e_invarg;
5748	else if (set_chars_option(&p_lcs) != NULL)
5749	    errmsg = (char_u *)_("E834: Conflicts with value of 'listchars'");
5750# if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)
5751	else if (set_chars_option(&p_fcs) != NULL)
5752	    errmsg = (char_u *)_("E835: Conflicts with value of 'fillchars'");
5753# endif
5754    }
5755#endif
5756
5757    /* 'background' */
5758    else if (varp == &p_bg)
5759    {
5760	if (check_opt_strings(p_bg, p_bg_values, FALSE) == OK)
5761	{
5762#ifdef FEAT_EVAL
5763	    int dark = (*p_bg == 'd');
5764#endif
5765
5766	    init_highlight(FALSE, FALSE);
5767
5768#ifdef FEAT_EVAL
5769	    if (dark != (*p_bg == 'd')
5770			  && get_var_value((char_u *)"g:colors_name") != NULL)
5771	    {
5772		/* The color scheme must have set 'background' back to another
5773		 * value, that's not what we want here.  Disable the color
5774		 * scheme and set the colors again. */
5775		do_unlet((char_u *)"g:colors_name", TRUE);
5776		free_string_option(p_bg);
5777		p_bg = vim_strsave((char_u *)(dark ? "dark" : "light"));
5778		check_string_option(&p_bg);
5779		init_highlight(FALSE, FALSE);
5780	    }
5781#endif
5782	}
5783	else
5784	    errmsg = e_invarg;
5785    }
5786
5787    /* 'wildmode' */
5788    else if (varp == &p_wim)
5789    {
5790	if (check_opt_wim() == FAIL)
5791	    errmsg = e_invarg;
5792    }
5793
5794#ifdef FEAT_CMDL_COMPL
5795    /* 'wildoptions' */
5796    else if (varp == &p_wop)
5797    {
5798	if (check_opt_strings(p_wop, p_wop_values, TRUE) != OK)
5799	    errmsg = e_invarg;
5800    }
5801#endif
5802
5803#ifdef FEAT_WAK
5804    /* 'winaltkeys' */
5805    else if (varp == &p_wak)
5806    {
5807	if (*p_wak == NUL
5808		|| check_opt_strings(p_wak, p_wak_values, FALSE) != OK)
5809	    errmsg = e_invarg;
5810# ifdef FEAT_MENU
5811#  ifdef FEAT_GUI_MOTIF
5812	else if (gui.in_use)
5813	    gui_motif_set_mnemonics(p_wak[0] == 'y' || p_wak[0] == 'm');
5814#  else
5815#   ifdef FEAT_GUI_GTK
5816	else if (gui.in_use)
5817	    gui_gtk_set_mnemonics(p_wak[0] == 'y' || p_wak[0] == 'm');
5818#   endif
5819#  endif
5820# endif
5821    }
5822#endif
5823
5824#ifdef FEAT_AUTOCMD
5825    /* 'eventignore' */
5826    else if (varp == &p_ei)
5827    {
5828	if (check_ei() == FAIL)
5829	    errmsg = e_invarg;
5830    }
5831#endif
5832
5833#ifdef FEAT_MBYTE
5834    /* 'encoding' and 'fileencoding' */
5835    else if (varp == &p_enc || gvarp == &p_fenc || varp == &p_tenc)
5836    {
5837	if (gvarp == &p_fenc)
5838	{
5839	    if (!curbuf->b_p_ma && opt_flags != OPT_GLOBAL)
5840		errmsg = e_modifiable;
5841	    else if (vim_strchr(*varp, ',') != NULL)
5842		/* No comma allowed in 'fileencoding'; catches confusing it
5843		 * with 'fileencodings'. */
5844		errmsg = e_invarg;
5845	    else
5846	    {
5847# ifdef FEAT_TITLE
5848		/* May show a "+" in the title now. */
5849		redraw_titles();
5850# endif
5851		/* Add 'fileencoding' to the swap file. */
5852		ml_setflags(curbuf);
5853	    }
5854	}
5855	if (errmsg == NULL)
5856	{
5857	    /* canonize the value, so that STRCMP() can be used on it */
5858	    p = enc_canonize(*varp);
5859	    if (p != NULL)
5860	    {
5861		vim_free(*varp);
5862		*varp = p;
5863	    }
5864	    if (varp == &p_enc)
5865	    {
5866		errmsg = mb_init();
5867# ifdef FEAT_TITLE
5868		redraw_titles();
5869# endif
5870	    }
5871	}
5872
5873# if defined(FEAT_GUI_GTK)
5874	if (errmsg == NULL && varp == &p_tenc && gui.in_use)
5875	{
5876	    /* GTK+ 2 uses only a single encoding, and that is UTF-8. */
5877	    if (STRCMP(p_tenc, "utf-8") != 0)
5878		errmsg = (char_u *)N_("E617: Cannot be changed in the GTK+ 2 GUI");
5879	}
5880# endif
5881
5882	if (errmsg == NULL)
5883	{
5884# ifdef FEAT_KEYMAP
5885	    /* When 'keymap' is used and 'encoding' changes, reload the keymap
5886	     * (with another encoding). */
5887	    if (varp == &p_enc && *curbuf->b_p_keymap != NUL)
5888		(void)keymap_init();
5889# endif
5890
5891	    /* When 'termencoding' is not empty and 'encoding' changes or when
5892	     * 'termencoding' changes, need to setup for keyboard input and
5893	     * display output conversion. */
5894	    if (((varp == &p_enc && *p_tenc != NUL) || varp == &p_tenc))
5895	    {
5896		convert_setup(&input_conv, p_tenc, p_enc);
5897		convert_setup(&output_conv, p_enc, p_tenc);
5898	    }
5899
5900# if defined(WIN3264) && defined(FEAT_MBYTE)
5901	    /* $HOME may have characters in active code page. */
5902	    if (varp == &p_enc)
5903		init_homedir();
5904# endif
5905	}
5906    }
5907#endif
5908
5909#if defined(FEAT_POSTSCRIPT)
5910    else if (varp == &p_penc)
5911    {
5912	/* Canonize printencoding if VIM standard one */
5913	p = enc_canonize(p_penc);
5914	if (p != NULL)
5915	{
5916	    vim_free(p_penc);
5917	    p_penc = p;
5918	}
5919	else
5920	{
5921	    /* Ensure lower case and '-' for '_' */
5922	    for (s = p_penc; *s != NUL; s++)
5923	    {
5924		if (*s == '_')
5925		    *s = '-';
5926		else
5927		    *s = TOLOWER_ASC(*s);
5928	    }
5929	}
5930    }
5931#endif
5932
5933#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
5934    else if (varp == &p_imak)
5935    {
5936	if (gui.in_use && !im_xim_isvalid_imactivate())
5937	    errmsg = e_invarg;
5938    }
5939#endif
5940
5941#ifdef FEAT_KEYMAP
5942    else if (varp == &curbuf->b_p_keymap)
5943    {
5944	/* load or unload key mapping tables */
5945	errmsg = keymap_init();
5946
5947	if (errmsg == NULL)
5948	{
5949	    if (*curbuf->b_p_keymap != NUL)
5950	    {
5951		/* Installed a new keymap, switch on using it. */
5952		curbuf->b_p_iminsert = B_IMODE_LMAP;
5953		if (curbuf->b_p_imsearch != B_IMODE_USE_INSERT)
5954		    curbuf->b_p_imsearch = B_IMODE_LMAP;
5955	    }
5956	    else
5957	    {
5958		/* Cleared the keymap, may reset 'iminsert' and 'imsearch'. */
5959		if (curbuf->b_p_iminsert == B_IMODE_LMAP)
5960		    curbuf->b_p_iminsert = B_IMODE_NONE;
5961		if (curbuf->b_p_imsearch == B_IMODE_LMAP)
5962		    curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
5963	    }
5964	    if ((opt_flags & OPT_LOCAL) == 0)
5965	    {
5966		set_iminsert_global();
5967		set_imsearch_global();
5968	    }
5969# ifdef FEAT_WINDOWS
5970	    status_redraw_curbuf();
5971# endif
5972	}
5973    }
5974#endif
5975
5976    /* 'fileformat' */
5977    else if (gvarp == &p_ff)
5978    {
5979	if (!curbuf->b_p_ma && !(opt_flags & OPT_GLOBAL))
5980	    errmsg = e_modifiable;
5981	else if (check_opt_strings(*varp, p_ff_values, FALSE) != OK)
5982	    errmsg = e_invarg;
5983	else
5984	{
5985	    /* may also change 'textmode' */
5986	    if (get_fileformat(curbuf) == EOL_DOS)
5987		curbuf->b_p_tx = TRUE;
5988	    else
5989		curbuf->b_p_tx = FALSE;
5990#ifdef FEAT_TITLE
5991	    redraw_titles();
5992#endif
5993	    /* update flag in swap file */
5994	    ml_setflags(curbuf);
5995	    /* Redraw needed when switching to/from "mac": a CR in the text
5996	     * will be displayed differently. */
5997	    if (get_fileformat(curbuf) == EOL_MAC || *oldval == 'm')
5998		redraw_curbuf_later(NOT_VALID);
5999	}
6000    }
6001
6002    /* 'fileformats' */
6003    else if (varp == &p_ffs)
6004    {
6005	if (check_opt_strings(p_ffs, p_ff_values, TRUE) != OK)
6006	    errmsg = e_invarg;
6007	else
6008	{
6009	    /* also change 'textauto' */
6010	    if (*p_ffs == NUL)
6011		p_ta = FALSE;
6012	    else
6013		p_ta = TRUE;
6014	}
6015    }
6016
6017#if defined(FEAT_CRYPT)
6018    /* 'cryptkey' */
6019    else if (gvarp == &p_key)
6020    {
6021# if defined(FEAT_CMDHIST)
6022	/* Make sure the ":set" command doesn't show the new value in the
6023	 * history. */
6024	remove_key_from_history();
6025# endif
6026	if (STRCMP(curbuf->b_p_key, oldval) != 0)
6027	    /* Need to update the swapfile. */
6028	    ml_set_crypt_key(curbuf, oldval, get_crypt_method(curbuf));
6029    }
6030
6031    else if (gvarp == &p_cm)
6032    {
6033	if (opt_flags & OPT_LOCAL)
6034	    p = curbuf->b_p_cm;
6035	else
6036	    p = p_cm;
6037	if (check_opt_strings(p, p_cm_values, TRUE) != OK)
6038	    errmsg = e_invarg;
6039	else if (get_crypt_method(curbuf) > 0 && blowfish_self_test() == FAIL)
6040	    errmsg = e_invarg;
6041	else
6042	{
6043	    /* When setting the global value to empty, make it "zip". */
6044	    if (*p_cm == NUL)
6045	    {
6046		if (new_value_alloced)
6047		    free_string_option(p_cm);
6048		p_cm = vim_strsave((char_u *)"zip");
6049		new_value_alloced = TRUE;
6050	    }
6051
6052	    /* Need to update the swapfile when the effective method changed.
6053	     * Set "s" to the effective old value, "p" to the effective new
6054	     * method and compare. */
6055	    if ((opt_flags & OPT_LOCAL) && *oldval == NUL)
6056		s = p_cm;  /* was previously using the global value */
6057	    else
6058		s = oldval;
6059	    if (*curbuf->b_p_cm == NUL)
6060		p = p_cm;  /* is now using the global value */
6061	    else
6062		p = curbuf->b_p_cm;
6063	    if (STRCMP(s, p) != 0)
6064		ml_set_crypt_key(curbuf, curbuf->b_p_key,
6065						 crypt_method_from_string(s));
6066
6067	    /* If the global value changes need to update the swapfile for all
6068	     * buffers using that value. */
6069	    if ((opt_flags & OPT_GLOBAL) && STRCMP(p_cm, oldval) != 0)
6070	    {
6071		buf_T	*buf;
6072
6073		for (buf = firstbuf; buf != NULL; buf = buf->b_next)
6074		    if (buf != curbuf && *buf->b_p_cm == NUL)
6075			ml_set_crypt_key(buf, buf->b_p_key,
6076					    crypt_method_from_string(oldval));
6077	    }
6078	}
6079    }
6080#endif
6081
6082    /* 'matchpairs' */
6083    else if (gvarp == &p_mps)
6084    {
6085	/* Check for "x:y,x:y" */
6086	for (p = *varp; *p != NUL; p += 4)
6087	{
6088	    if (p[1] != ':' || p[2] == NUL || (p[3] != NUL && p[3] != ','))
6089	    {
6090		errmsg = e_invarg;
6091		break;
6092	    }
6093	    if (p[3] == NUL)
6094		break;
6095	}
6096    }
6097
6098#ifdef FEAT_COMMENTS
6099    /* 'comments' */
6100    else if (gvarp == &p_com)
6101    {
6102	for (s = *varp; *s; )
6103	{
6104	    while (*s && *s != ':')
6105	    {
6106		if (vim_strchr((char_u *)COM_ALL, *s) == NULL
6107					     && !VIM_ISDIGIT(*s) && *s != '-')
6108		{
6109		    errmsg = illegal_char(errbuf, *s);
6110		    break;
6111		}
6112		++s;
6113	    }
6114	    if (*s++ == NUL)
6115		errmsg = (char_u *)N_("E524: Missing colon");
6116	    else if (*s == ',' || *s == NUL)
6117		errmsg = (char_u *)N_("E525: Zero length string");
6118	    if (errmsg != NULL)
6119		break;
6120	    while (*s && *s != ',')
6121	    {
6122		if (*s == '\\' && s[1] != NUL)
6123		    ++s;
6124		++s;
6125	    }
6126	    s = skip_to_option_part(s);
6127	}
6128    }
6129#endif
6130
6131    /* 'listchars' */
6132    else if (varp == &p_lcs)
6133    {
6134	errmsg = set_chars_option(varp);
6135    }
6136
6137#if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)
6138    /* 'fillchars' */
6139    else if (varp == &p_fcs)
6140    {
6141	errmsg = set_chars_option(varp);
6142    }
6143#endif
6144
6145#ifdef FEAT_CMDWIN
6146    /* 'cedit' */
6147    else if (varp == &p_cedit)
6148    {
6149	errmsg = check_cedit();
6150    }
6151#endif
6152
6153    /* 'verbosefile' */
6154    else if (varp == &p_vfile)
6155    {
6156	verbose_stop();
6157	if (*p_vfile != NUL && verbose_open() == FAIL)
6158	    errmsg = e_invarg;
6159    }
6160
6161#ifdef FEAT_VIMINFO
6162    /* 'viminfo' */
6163    else if (varp == &p_viminfo)
6164    {
6165	for (s = p_viminfo; *s;)
6166	{
6167	    /* Check it's a valid character */
6168	    if (vim_strchr((char_u *)"!\"%'/:<@cfhnrs", *s) == NULL)
6169	    {
6170		errmsg = illegal_char(errbuf, *s);
6171		break;
6172	    }
6173	    if (*s == 'n')	/* name is always last one */
6174	    {
6175		break;
6176	    }
6177	    else if (*s == 'r') /* skip until next ',' */
6178	    {
6179		while (*++s && *s != ',')
6180		    ;
6181	    }
6182	    else if (*s == '%')
6183	    {
6184		/* optional number */
6185		while (vim_isdigit(*++s))
6186		    ;
6187	    }
6188	    else if (*s == '!' || *s == 'h' || *s == 'c')
6189		++s;		/* no extra chars */
6190	    else		/* must have a number */
6191	    {
6192		while (vim_isdigit(*++s))
6193		    ;
6194
6195		if (!VIM_ISDIGIT(*(s - 1)))
6196		{
6197		    if (errbuf != NULL)
6198		    {
6199			sprintf((char *)errbuf,
6200					 _("E526: Missing number after <%s>"),
6201						    transchar_byte(*(s - 1)));
6202			errmsg = errbuf;
6203		    }
6204		    else
6205			errmsg = (char_u *)"";
6206		    break;
6207		}
6208	    }
6209	    if (*s == ',')
6210		++s;
6211	    else if (*s)
6212	    {
6213		if (errbuf != NULL)
6214		    errmsg = (char_u *)N_("E527: Missing comma");
6215		else
6216		    errmsg = (char_u *)"";
6217		break;
6218	    }
6219	}
6220	if (*p_viminfo && errmsg == NULL && get_viminfo_parameter('\'') < 0)
6221	    errmsg = (char_u *)N_("E528: Must specify a ' value");
6222    }
6223#endif /* FEAT_VIMINFO */
6224
6225    /* terminal options */
6226    else if (istermoption(&options[opt_idx]) && full_screen)
6227    {
6228	/* ":set t_Co=0" and ":set t_Co=1" do ":set t_Co=" */
6229	if (varp == &T_CCO)
6230	{
6231	    int colors = atoi((char *)T_CCO);
6232
6233	    /* Only reinitialize colors if t_Co value has really changed to
6234	     * avoid expensive reload of colorscheme if t_Co is set to the
6235	     * same value multiple times. */
6236	    if (colors != t_colors)
6237	    {
6238		t_colors = colors;
6239		if (t_colors <= 1)
6240		{
6241		    if (new_value_alloced)
6242			vim_free(T_CCO);
6243		    T_CCO = empty_option;
6244		}
6245		/* We now have a different color setup, initialize it again. */
6246		init_highlight(TRUE, FALSE);
6247	    }
6248	}
6249	ttest(FALSE);
6250	if (varp == &T_ME)
6251	{
6252	    out_str(T_ME);
6253	    redraw_later(CLEAR);
6254#if defined(MSDOS) || (defined(WIN3264) && !defined(FEAT_GUI_W32))
6255	    /* Since t_me has been set, this probably means that the user
6256	     * wants to use this as default colors.  Need to reset default
6257	     * background/foreground colors. */
6258	    mch_set_normal_colors();
6259#endif
6260	}
6261    }
6262
6263#ifdef FEAT_LINEBREAK
6264    /* 'showbreak' */
6265    else if (varp == &p_sbr)
6266    {
6267	for (s = p_sbr; *s; )
6268	{
6269	    if (ptr2cells(s) != 1)
6270		errmsg = (char_u *)N_("E595: contains unprintable or wide character");
6271	    mb_ptr_adv(s);
6272	}
6273    }
6274#endif
6275
6276#ifdef FEAT_GUI
6277    /* 'guifont' */
6278    else if (varp == &p_guifont)
6279    {
6280	if (gui.in_use)
6281	{
6282	    p = p_guifont;
6283# if defined(FEAT_GUI_GTK)
6284	    /*
6285	     * Put up a font dialog and let the user select a new value.
6286	     * If this is cancelled go back to the old value but don't
6287	     * give an error message.
6288	     */
6289	    if (STRCMP(p, "*") == 0)
6290	    {
6291		p = gui_mch_font_dialog(oldval);
6292
6293		if (new_value_alloced)
6294		    free_string_option(p_guifont);
6295
6296		p_guifont = (p != NULL) ? p : vim_strsave(oldval);
6297		new_value_alloced = TRUE;
6298	    }
6299# endif
6300	    if (p != NULL && gui_init_font(p_guifont, FALSE) != OK)
6301	    {
6302# if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_PHOTON)
6303		if (STRCMP(p_guifont, "*") == 0)
6304		{
6305		    /* Dialog was cancelled: Keep the old value without giving
6306		     * an error message. */
6307		    if (new_value_alloced)
6308			free_string_option(p_guifont);
6309		    p_guifont = vim_strsave(oldval);
6310		    new_value_alloced = TRUE;
6311		}
6312		else
6313# endif
6314		    errmsg = (char_u *)N_("E596: Invalid font(s)");
6315	    }
6316	}
6317	redraw_gui_only = TRUE;
6318    }
6319# ifdef FEAT_XFONTSET
6320    else if (varp == &p_guifontset)
6321    {
6322	if (STRCMP(p_guifontset, "*") == 0)
6323	    errmsg = (char_u *)N_("E597: can't select fontset");
6324	else if (gui.in_use && gui_init_font(p_guifontset, TRUE) != OK)
6325	    errmsg = (char_u *)N_("E598: Invalid fontset");
6326	redraw_gui_only = TRUE;
6327    }
6328# endif
6329# ifdef FEAT_MBYTE
6330    else if (varp == &p_guifontwide)
6331    {
6332	if (STRCMP(p_guifontwide, "*") == 0)
6333	    errmsg = (char_u *)N_("E533: can't select wide font");
6334	else if (gui_get_wide_font() == FAIL)
6335	    errmsg = (char_u *)N_("E534: Invalid wide font");
6336	redraw_gui_only = TRUE;
6337    }
6338# endif
6339#endif
6340
6341#ifdef CURSOR_SHAPE
6342    /* 'guicursor' */
6343    else if (varp == &p_guicursor)
6344	errmsg = parse_shape_opt(SHAPE_CURSOR);
6345#endif
6346
6347#ifdef FEAT_MOUSESHAPE
6348    /* 'mouseshape' */
6349    else if (varp == &p_mouseshape)
6350    {
6351	errmsg = parse_shape_opt(SHAPE_MOUSE);
6352	update_mouseshape(-1);
6353    }
6354#endif
6355
6356#ifdef FEAT_PRINTER
6357    else if (varp == &p_popt)
6358	errmsg = parse_printoptions();
6359# if defined(FEAT_MBYTE) && defined(FEAT_POSTSCRIPT)
6360    else if (varp == &p_pmfn)
6361	errmsg = parse_printmbfont();
6362# endif
6363#endif
6364
6365#ifdef FEAT_LANGMAP
6366    /* 'langmap' */
6367    else if (varp == &p_langmap)
6368	langmap_set();
6369#endif
6370
6371#ifdef FEAT_LINEBREAK
6372    /* 'breakat' */
6373    else if (varp == &p_breakat)
6374	fill_breakat_flags();
6375#endif
6376
6377#ifdef FEAT_TITLE
6378    /* 'titlestring' and 'iconstring' */
6379    else if (varp == &p_titlestring || varp == &p_iconstring)
6380    {
6381# ifdef FEAT_STL_OPT
6382	int	flagval = (varp == &p_titlestring) ? STL_IN_TITLE : STL_IN_ICON;
6383
6384	/* NULL => statusline syntax */
6385	if (vim_strchr(*varp, '%') && check_stl_option(*varp) == NULL)
6386	    stl_syntax |= flagval;
6387	else
6388	    stl_syntax &= ~flagval;
6389# endif
6390	did_set_title(varp == &p_iconstring);
6391
6392    }
6393#endif
6394
6395#ifdef FEAT_GUI
6396    /* 'guioptions' */
6397    else if (varp == &p_go)
6398    {
6399	gui_init_which_components(oldval);
6400	redraw_gui_only = TRUE;
6401    }
6402#endif
6403
6404#if defined(FEAT_GUI_TABLINE)
6405    /* 'guitablabel' */
6406    else if (varp == &p_gtl)
6407    {
6408	redraw_tabline = TRUE;
6409	redraw_gui_only = TRUE;
6410    }
6411    /* 'guitabtooltip' */
6412    else if (varp == &p_gtt)
6413    {
6414	redraw_gui_only = TRUE;
6415    }
6416#endif
6417
6418#if defined(FEAT_MOUSE_TTY) && (defined(UNIX) || defined(VMS))
6419    /* 'ttymouse' */
6420    else if (varp == &p_ttym)
6421    {
6422	/* Switch the mouse off before changing the escape sequences used for
6423	 * that. */
6424	mch_setmouse(FALSE);
6425	if (opt_strings_flags(p_ttym, p_ttym_values, &ttym_flags, FALSE) != OK)
6426	    errmsg = e_invarg;
6427	else
6428	    check_mouse_termcode();
6429	if (termcap_active)
6430	    setmouse();		/* may switch it on again */
6431    }
6432#endif
6433
6434#ifdef FEAT_VISUAL
6435    /* 'selection' */
6436    else if (varp == &p_sel)
6437    {
6438	if (*p_sel == NUL
6439		|| check_opt_strings(p_sel, p_sel_values, FALSE) != OK)
6440	    errmsg = e_invarg;
6441    }
6442
6443    /* 'selectmode' */
6444    else if (varp == &p_slm)
6445    {
6446	if (check_opt_strings(p_slm, p_slm_values, TRUE) != OK)
6447	    errmsg = e_invarg;
6448    }
6449#endif
6450
6451#ifdef FEAT_BROWSE
6452    /* 'browsedir' */
6453    else if (varp == &p_bsdir)
6454    {
6455	if (check_opt_strings(p_bsdir, p_bsdir_values, FALSE) != OK
6456		&& !mch_isdir(p_bsdir))
6457	    errmsg = e_invarg;
6458    }
6459#endif
6460
6461#ifdef FEAT_VISUAL
6462    /* 'keymodel' */
6463    else if (varp == &p_km)
6464    {
6465	if (check_opt_strings(p_km, p_km_values, TRUE) != OK)
6466	    errmsg = e_invarg;
6467	else
6468	{
6469	    km_stopsel = (vim_strchr(p_km, 'o') != NULL);
6470	    km_startsel = (vim_strchr(p_km, 'a') != NULL);
6471	}
6472    }
6473#endif
6474
6475    /* 'mousemodel' */
6476    else if (varp == &p_mousem)
6477    {
6478	if (check_opt_strings(p_mousem, p_mousem_values, FALSE) != OK)
6479	    errmsg = e_invarg;
6480#if defined(FEAT_GUI_MOTIF) && defined(FEAT_MENU) && (XmVersion <= 1002)
6481	else if (*p_mousem != *oldval)
6482	    /* Changed from "extend" to "popup" or "popup_setpos" or vv: need
6483	     * to create or delete the popup menus. */
6484	    gui_motif_update_mousemodel(root_menu);
6485#endif
6486    }
6487
6488    /* 'switchbuf' */
6489    else if (varp == &p_swb)
6490    {
6491	if (opt_strings_flags(p_swb, p_swb_values, &swb_flags, TRUE) != OK)
6492	    errmsg = e_invarg;
6493    }
6494
6495    /* 'debug' */
6496    else if (varp == &p_debug)
6497    {
6498	if (check_opt_strings(p_debug, p_debug_values, TRUE) != OK)
6499	    errmsg = e_invarg;
6500    }
6501
6502    /* 'display' */
6503    else if (varp == &p_dy)
6504    {
6505	if (opt_strings_flags(p_dy, p_dy_values, &dy_flags, TRUE) != OK)
6506	    errmsg = e_invarg;
6507	else
6508	    (void)init_chartab();
6509
6510    }
6511
6512#ifdef FEAT_VERTSPLIT
6513    /* 'eadirection' */
6514    else if (varp == &p_ead)
6515    {
6516	if (check_opt_strings(p_ead, p_ead_values, FALSE) != OK)
6517	    errmsg = e_invarg;
6518    }
6519#endif
6520
6521#ifdef FEAT_CLIPBOARD
6522    /* 'clipboard' */
6523    else if (varp == &p_cb)
6524	errmsg = check_clipboard_option();
6525#endif
6526
6527#ifdef FEAT_SPELL
6528    /* When 'spelllang' or 'spellfile' is set and there is a window for this
6529     * buffer in which 'spell' is set load the wordlists. */
6530    else if (varp == &(curbuf->b_s.b_p_spl) || varp == &(curbuf->b_s.b_p_spf))
6531    {
6532	win_T	    *wp;
6533	int	    l;
6534
6535	if (varp == &(curbuf->b_s.b_p_spf))
6536	{
6537	    l = (int)STRLEN(curbuf->b_s.b_p_spf);
6538	    if (l > 0 && (l < 4 || STRCMP(curbuf->b_s.b_p_spf + l - 4,
6539								".add") != 0))
6540		errmsg = e_invarg;
6541	}
6542
6543	if (errmsg == NULL)
6544	{
6545	    FOR_ALL_WINDOWS(wp)
6546		if (wp->w_buffer == curbuf && wp->w_p_spell)
6547		{
6548		    errmsg = did_set_spelllang(wp);
6549# ifdef FEAT_WINDOWS
6550		    break;
6551# endif
6552		}
6553	}
6554    }
6555    /* When 'spellcapcheck' is set compile the regexp program. */
6556    else if (varp == &(curwin->w_s->b_p_spc))
6557    {
6558	errmsg = compile_cap_prog(curwin->w_s);
6559    }
6560    /* 'spellsuggest' */
6561    else if (varp == &p_sps)
6562    {
6563	if (spell_check_sps() != OK)
6564	    errmsg = e_invarg;
6565    }
6566    /* 'mkspellmem' */
6567    else if (varp == &p_msm)
6568    {
6569	if (spell_check_msm() != OK)
6570	    errmsg = e_invarg;
6571    }
6572#endif
6573
6574#ifdef FEAT_QUICKFIX
6575    /* When 'bufhidden' is set, check for valid value. */
6576    else if (gvarp == &p_bh)
6577    {
6578	if (check_opt_strings(curbuf->b_p_bh, p_bufhidden_values, FALSE) != OK)
6579	    errmsg = e_invarg;
6580    }
6581
6582    /* When 'buftype' is set, check for valid value. */
6583    else if (gvarp == &p_bt)
6584    {
6585	if (check_opt_strings(curbuf->b_p_bt, p_buftype_values, FALSE) != OK)
6586	    errmsg = e_invarg;
6587	else
6588	{
6589# ifdef FEAT_WINDOWS
6590	    if (curwin->w_status_height)
6591	    {
6592		curwin->w_redr_status = TRUE;
6593		redraw_later(VALID);
6594	    }
6595# endif
6596	    curbuf->b_help = (curbuf->b_p_bt[0] == 'h');
6597# ifdef FEAT_TITLE
6598	    redraw_titles();
6599# endif
6600	}
6601    }
6602#endif
6603
6604#ifdef FEAT_STL_OPT
6605    /* 'statusline' or 'rulerformat' */
6606    else if (gvarp == &p_stl || varp == &p_ruf)
6607    {
6608	int wid;
6609
6610	if (varp == &p_ruf)	/* reset ru_wid first */
6611	    ru_wid = 0;
6612	s = *varp;
6613	if (varp == &p_ruf && *s == '%')
6614	{
6615	    /* set ru_wid if 'ruf' starts with "%99(" */
6616	    if (*++s == '-')	/* ignore a '-' */
6617		s++;
6618	    wid = getdigits(&s);
6619	    if (wid && *s == '(' && (errmsg = check_stl_option(p_ruf)) == NULL)
6620		ru_wid = wid;
6621	    else
6622		errmsg = check_stl_option(p_ruf);
6623	}
6624	/* check 'statusline' only if it doesn't start with "%!" */
6625	else if (varp == &p_ruf || s[0] != '%' || s[1] != '!')
6626	    errmsg = check_stl_option(s);
6627	if (varp == &p_ruf && errmsg == NULL)
6628	    comp_col();
6629    }
6630#endif
6631
6632#ifdef FEAT_INS_EXPAND
6633    /* check if it is a valid value for 'complete' -- Acevedo */
6634    else if (gvarp == &p_cpt)
6635    {
6636	for (s = *varp; *s;)
6637	{
6638	    while(*s == ',' || *s == ' ')
6639		s++;
6640	    if (!*s)
6641		break;
6642	    if (vim_strchr((char_u *)".wbuksid]tU", *s) == NULL)
6643	    {
6644		errmsg = illegal_char(errbuf, *s);
6645		break;
6646	    }
6647	    if (*++s != NUL && *s != ',' && *s != ' ')
6648	    {
6649		if (s[-1] == 'k' || s[-1] == 's')
6650		{
6651		    /* skip optional filename after 'k' and 's' */
6652		    while (*s && *s != ',' && *s != ' ')
6653		    {
6654			if (*s == '\\')
6655			    ++s;
6656			++s;
6657		    }
6658		}
6659		else
6660		{
6661		    if (errbuf != NULL)
6662		    {
6663			sprintf((char *)errbuf,
6664				     _("E535: Illegal character after <%c>"),
6665				     *--s);
6666			errmsg = errbuf;
6667		    }
6668		    else
6669			errmsg = (char_u *)"";
6670		    break;
6671		}
6672	    }
6673	}
6674    }
6675
6676    /* 'completeopt' */
6677    else if (varp == &p_cot)
6678    {
6679	if (check_opt_strings(p_cot, p_cot_values, TRUE) != OK)
6680	    errmsg = e_invarg;
6681    }
6682#endif /* FEAT_INS_EXPAND */
6683
6684
6685#if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32)
6686    else if (varp == &p_toolbar)
6687    {
6688	if (opt_strings_flags(p_toolbar, p_toolbar_values,
6689			      &toolbar_flags, TRUE) != OK)
6690	    errmsg = e_invarg;
6691	else
6692	{
6693	    out_flush();
6694	    gui_mch_show_toolbar((toolbar_flags &
6695				  (TOOLBAR_TEXT | TOOLBAR_ICONS)) != 0);
6696	}
6697    }
6698#endif
6699
6700#if defined(FEAT_TOOLBAR) && defined(FEAT_GUI_GTK)
6701    /* 'toolbariconsize': GTK+ 2 only */
6702    else if (varp == &p_tbis)
6703    {
6704	if (opt_strings_flags(p_tbis, p_tbis_values, &tbis_flags, FALSE) != OK)
6705	    errmsg = e_invarg;
6706	else
6707	{
6708	    out_flush();
6709	    gui_mch_show_toolbar((toolbar_flags &
6710				  (TOOLBAR_TEXT | TOOLBAR_ICONS)) != 0);
6711	}
6712    }
6713#endif
6714
6715    /* 'pastetoggle': translate key codes like in a mapping */
6716    else if (varp == &p_pt)
6717    {
6718	if (*p_pt)
6719	{
6720	    (void)replace_termcodes(p_pt, &p, TRUE, TRUE, FALSE);
6721	    if (p != NULL)
6722	    {
6723		if (new_value_alloced)
6724		    free_string_option(p_pt);
6725		p_pt = p;
6726		new_value_alloced = TRUE;
6727	    }
6728	}
6729    }
6730
6731    /* 'backspace' */
6732    else if (varp == &p_bs)
6733    {
6734	if (VIM_ISDIGIT(*p_bs))
6735	{
6736	    if (*p_bs >'2' || p_bs[1] != NUL)
6737		errmsg = e_invarg;
6738	}
6739	else if (check_opt_strings(p_bs, p_bs_values, TRUE) != OK)
6740	    errmsg = e_invarg;
6741    }
6742
6743#ifdef FEAT_MBYTE
6744    /* 'casemap' */
6745    else if (varp == &p_cmp)
6746    {
6747	if (opt_strings_flags(p_cmp, p_cmp_values, &cmp_flags, TRUE) != OK)
6748	    errmsg = e_invarg;
6749    }
6750#endif
6751
6752#ifdef FEAT_DIFF
6753    /* 'diffopt' */
6754    else if (varp == &p_dip)
6755    {
6756	if (diffopt_changed() == FAIL)
6757	    errmsg = e_invarg;
6758    }
6759#endif
6760
6761#ifdef FEAT_FOLDING
6762    /* 'foldmethod' */
6763    else if (gvarp == &curwin->w_allbuf_opt.wo_fdm)
6764    {
6765	if (check_opt_strings(*varp, p_fdm_values, FALSE) != OK
6766		|| *curwin->w_p_fdm == NUL)
6767	    errmsg = e_invarg;
6768	else
6769	{
6770	    foldUpdateAll(curwin);
6771	    if (foldmethodIsDiff(curwin))
6772		newFoldLevel();
6773	}
6774    }
6775# ifdef FEAT_EVAL
6776    /* 'foldexpr' */
6777    else if (varp == &curwin->w_p_fde)
6778    {
6779	if (foldmethodIsExpr(curwin))
6780	    foldUpdateAll(curwin);
6781    }
6782# endif
6783    /* 'foldmarker' */
6784    else if (gvarp == &curwin->w_allbuf_opt.wo_fmr)
6785    {
6786	p = vim_strchr(*varp, ',');
6787	if (p == NULL)
6788	    errmsg = (char_u *)N_("E536: comma required");
6789	else if (p == *varp || p[1] == NUL)
6790	    errmsg = e_invarg;
6791	else if (foldmethodIsMarker(curwin))
6792	    foldUpdateAll(curwin);
6793    }
6794    /* 'commentstring' */
6795    else if (gvarp == &p_cms)
6796    {
6797	if (**varp != NUL && strstr((char *)*varp, "%s") == NULL)
6798	    errmsg = (char_u *)N_("E537: 'commentstring' must be empty or contain %s");
6799    }
6800    /* 'foldopen' */
6801    else if (varp == &p_fdo)
6802    {
6803	if (opt_strings_flags(p_fdo, p_fdo_values, &fdo_flags, TRUE) != OK)
6804	    errmsg = e_invarg;
6805    }
6806    /* 'foldclose' */
6807    else if (varp == &p_fcl)
6808    {
6809	if (check_opt_strings(p_fcl, p_fcl_values, TRUE) != OK)
6810	    errmsg = e_invarg;
6811    }
6812    /* 'foldignore' */
6813    else if (gvarp == &curwin->w_allbuf_opt.wo_fdi)
6814    {
6815	if (foldmethodIsIndent(curwin))
6816	    foldUpdateAll(curwin);
6817    }
6818#endif
6819
6820#ifdef FEAT_VIRTUALEDIT
6821    /* 'virtualedit' */
6822    else if (varp == &p_ve)
6823    {
6824	if (opt_strings_flags(p_ve, p_ve_values, &ve_flags, TRUE) != OK)
6825	    errmsg = e_invarg;
6826	else if (STRCMP(p_ve, oldval) != 0)
6827	{
6828	    /* Recompute cursor position in case the new 've' setting
6829	     * changes something. */
6830	    validate_virtcol();
6831	    coladvance(curwin->w_virtcol);
6832	}
6833    }
6834#endif
6835
6836#if defined(FEAT_CSCOPE) && defined(FEAT_QUICKFIX)
6837    else if (varp == &p_csqf)
6838    {
6839	if (p_csqf != NULL)
6840	{
6841	    p = p_csqf;
6842	    while (*p != NUL)
6843	    {
6844		if (vim_strchr((char_u *)CSQF_CMDS, *p) == NULL
6845			|| p[1] == NUL
6846			|| vim_strchr((char_u *)CSQF_FLAGS, p[1]) == NULL
6847			|| (p[2] != NUL && p[2] != ','))
6848		{
6849		    errmsg = e_invarg;
6850		    break;
6851		}
6852		else if (p[2] == NUL)
6853		    break;
6854		else
6855		    p += 3;
6856	    }
6857	}
6858    }
6859#endif
6860
6861    /* Options that are a list of flags. */
6862    else
6863    {
6864	p = NULL;
6865	if (varp == &p_ww)
6866	    p = (char_u *)WW_ALL;
6867	if (varp == &p_shm)
6868	    p = (char_u *)SHM_ALL;
6869	else if (varp == &(p_cpo))
6870	    p = (char_u *)CPO_ALL;
6871	else if (varp == &(curbuf->b_p_fo))
6872	    p = (char_u *)FO_ALL;
6873#ifdef FEAT_CONCEAL
6874	else if (varp == &curwin->w_p_cocu)
6875	    p = (char_u *)COCU_ALL;
6876#endif
6877	else if (varp == &p_mouse)
6878	{
6879#ifdef FEAT_MOUSE
6880	    p = (char_u *)MOUSE_ALL;
6881#else
6882	    if (*p_mouse != NUL)
6883		errmsg = (char_u *)N_("E538: No mouse support");
6884#endif
6885	}
6886#if defined(FEAT_GUI)
6887	else if (varp == &p_go)
6888	    p = (char_u *)GO_ALL;
6889#endif
6890	if (p != NULL)
6891	{
6892	    for (s = *varp; *s; ++s)
6893		if (vim_strchr(p, *s) == NULL)
6894		{
6895		    errmsg = illegal_char(errbuf, *s);
6896		    break;
6897		}
6898	}
6899    }
6900
6901    /*
6902     * If error detected, restore the previous value.
6903     */
6904    if (errmsg != NULL)
6905    {
6906	if (new_value_alloced)
6907	    free_string_option(*varp);
6908	*varp = oldval;
6909	/*
6910	 * When resetting some values, need to act on it.
6911	 */
6912	if (did_chartab)
6913	    (void)init_chartab();
6914	if (varp == &p_hl)
6915	    (void)highlight_changed();
6916    }
6917    else
6918    {
6919#ifdef FEAT_EVAL
6920	/* Remember where the option was set. */
6921	set_option_scriptID_idx(opt_idx, opt_flags, current_SID);
6922#endif
6923	/*
6924	 * Free string options that are in allocated memory.
6925	 * Use "free_oldval", because recursiveness may change the flags under
6926	 * our fingers (esp. init_highlight()).
6927	 */
6928	if (free_oldval)
6929	    free_string_option(oldval);
6930	if (new_value_alloced)
6931	    options[opt_idx].flags |= P_ALLOCED;
6932	else
6933	    options[opt_idx].flags &= ~P_ALLOCED;
6934
6935	if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
6936		&& ((int)options[opt_idx].indir & PV_BOTH))
6937	{
6938	    /* global option with local value set to use global value; free
6939	     * the local value and make it empty */
6940	    p = get_varp_scope(&(options[opt_idx]), OPT_LOCAL);
6941	    free_string_option(*(char_u **)p);
6942	    *(char_u **)p = empty_option;
6943	}
6944
6945	/* May set global value for local option. */
6946	else if (!(opt_flags & OPT_LOCAL) && opt_flags != OPT_GLOBAL)
6947	    set_string_option_global(opt_idx, varp);
6948
6949#ifdef FEAT_AUTOCMD
6950	/*
6951	 * Trigger the autocommand only after setting the flags.
6952	 */
6953# ifdef FEAT_SYN_HL
6954	/* When 'syntax' is set, load the syntax of that name */
6955	if (varp == &(curbuf->b_p_syn))
6956	{
6957	    apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn,
6958					       curbuf->b_fname, TRUE, curbuf);
6959	}
6960# endif
6961	else if (varp == &(curbuf->b_p_ft))
6962	{
6963	    /* 'filetype' is set, trigger the FileType autocommand */
6964	    did_filetype = TRUE;
6965	    apply_autocmds(EVENT_FILETYPE, curbuf->b_p_ft,
6966					       curbuf->b_fname, TRUE, curbuf);
6967	}
6968#endif
6969#ifdef FEAT_SPELL
6970	if (varp == &(curwin->w_s->b_p_spl))
6971	{
6972	    char_u	fname[200];
6973
6974	    /*
6975	     * Source the spell/LANG.vim in 'runtimepath'.
6976	     * They could set 'spellcapcheck' depending on the language.
6977	     * Use the first name in 'spelllang' up to '_region' or
6978	     * '.encoding'.
6979	     */
6980	    for (p = curwin->w_s->b_p_spl; *p != NUL; ++p)
6981		if (vim_strchr((char_u *)"_.,", *p) != NULL)
6982		    break;
6983	    vim_snprintf((char *)fname, 200, "spell/%.*s.vim",
6984				 (int)(p - curwin->w_s->b_p_spl), curwin->w_s->b_p_spl);
6985	    source_runtime(fname, TRUE);
6986	}
6987#endif
6988    }
6989
6990#ifdef FEAT_MOUSE
6991    if (varp == &p_mouse)
6992    {
6993# ifdef FEAT_MOUSE_TTY
6994	if (*p_mouse == NUL)
6995	    mch_setmouse(FALSE);    /* switch mouse off */
6996	else
6997# endif
6998	    setmouse();		    /* in case 'mouse' changed */
6999    }
7000#endif
7001
7002    if (curwin->w_curswant != MAXCOL)
7003	curwin->w_set_curswant = TRUE;  /* in case 'showbreak' changed */
7004#ifdef FEAT_GUI
7005    /* check redraw when it's not a GUI option or the GUI is active. */
7006    if (!redraw_gui_only || gui.in_use)
7007#endif
7008	check_redraw(options[opt_idx].flags);
7009
7010    return errmsg;
7011}
7012
7013#ifdef FEAT_SYN_HL
7014/*
7015 * Simple int comparison function for use with qsort()
7016 */
7017    static int
7018int_cmp(a, b)
7019    const void *a;
7020    const void *b;
7021{
7022    return *(const int *)a - *(const int *)b;
7023}
7024
7025/*
7026 * Handle setting 'colorcolumn' or 'textwidth' in window "wp".
7027 * Returns error message, NULL if it's OK.
7028 */
7029    char_u *
7030check_colorcolumn(wp)
7031    win_T	*wp;
7032{
7033    char_u	*s;
7034    int		col;
7035    int		count = 0;
7036    int		color_cols[256];
7037    int		i;
7038    int		j = 0;
7039
7040    for (s = wp->w_p_cc; *s != NUL && count < 255;)
7041    {
7042	if (*s == '-' || *s == '+')
7043	{
7044	    /* -N and +N: add to 'textwidth' */
7045	    col = (*s == '-') ? -1 : 1;
7046	    ++s;
7047	    if (!VIM_ISDIGIT(*s))
7048		return e_invarg;
7049	    col = col * getdigits(&s);
7050	    if (wp->w_buffer->b_p_tw == 0)
7051		goto skip;  /* 'textwidth' not set, skip this item */
7052	    col += wp->w_buffer->b_p_tw;
7053	    if (col < 0)
7054		goto skip;
7055	}
7056	else if (VIM_ISDIGIT(*s))
7057	    col = getdigits(&s);
7058	else
7059	    return e_invarg;
7060	color_cols[count++] = col - 1;  /* 1-based to 0-based */
7061skip:
7062	if (*s == NUL)
7063	    break;
7064	if (*s != ',')
7065	    return e_invarg;
7066	if (*++s == NUL)
7067	    return e_invarg;  /* illegal trailing comma as in "set cc=80," */
7068    }
7069
7070    vim_free(wp->w_p_cc_cols);
7071    if (count == 0)
7072	wp->w_p_cc_cols = NULL;
7073    else
7074    {
7075	wp->w_p_cc_cols = (int *)alloc((unsigned)sizeof(int) * (count + 1));
7076	if (wp->w_p_cc_cols != NULL)
7077	{
7078	    /* sort the columns for faster usage on screen redraw inside
7079	     * win_line() */
7080	    qsort(color_cols, count, sizeof(int), int_cmp);
7081
7082	    for (i = 0; i < count; ++i)
7083		/* skip duplicates */
7084		if (j == 0 || wp->w_p_cc_cols[j - 1] != color_cols[i])
7085		    wp->w_p_cc_cols[j++] = color_cols[i];
7086	    wp->w_p_cc_cols[j] = -1;  /* end marker */
7087	}
7088    }
7089
7090    return NULL;  /* no error */
7091}
7092#endif
7093
7094/*
7095 * Handle setting 'listchars' or 'fillchars'.
7096 * Returns error message, NULL if it's OK.
7097 */
7098    static char_u *
7099set_chars_option(varp)
7100    char_u	**varp;
7101{
7102    int		round, i, len, entries;
7103    char_u	*p, *s;
7104    int		c1, c2 = 0;
7105    struct charstab
7106    {
7107	int	*cp;
7108	char	*name;
7109    };
7110#if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)
7111    static struct charstab filltab[] =
7112    {
7113	{&fill_stl,	"stl"},
7114	{&fill_stlnc,	"stlnc"},
7115	{&fill_vert,	"vert"},
7116	{&fill_fold,	"fold"},
7117	{&fill_diff,	"diff"},
7118    };
7119#endif
7120    static struct charstab lcstab[] =
7121    {
7122	{&lcs_eol,	"eol"},
7123	{&lcs_ext,	"extends"},
7124	{&lcs_nbsp,	"nbsp"},
7125	{&lcs_prec,	"precedes"},
7126	{&lcs_tab2,	"tab"},
7127	{&lcs_trail,	"trail"},
7128#ifdef FEAT_CONCEAL
7129	{&lcs_conceal,	"conceal"},
7130#else
7131	{NULL,		"conceal"},
7132#endif
7133    };
7134    struct charstab *tab;
7135
7136#if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)
7137    if (varp == &p_lcs)
7138#endif
7139    {
7140	tab = lcstab;
7141	entries = sizeof(lcstab) / sizeof(struct charstab);
7142    }
7143#if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)
7144    else
7145    {
7146	tab = filltab;
7147	entries = sizeof(filltab) / sizeof(struct charstab);
7148    }
7149#endif
7150
7151    /* first round: check for valid value, second round: assign values */
7152    for (round = 0; round <= 1; ++round)
7153    {
7154	if (round > 0)
7155	{
7156	    /* After checking that the value is valid: set defaults: space for
7157	     * 'fillchars', NUL for 'listchars' */
7158	    for (i = 0; i < entries; ++i)
7159		if (tab[i].cp != NULL)
7160		    *(tab[i].cp) = (varp == &p_lcs ? NUL : ' ');
7161	    if (varp == &p_lcs)
7162		lcs_tab1 = NUL;
7163#if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)
7164	    else
7165		fill_diff = '-';
7166#endif
7167	}
7168	p = *varp;
7169	while (*p)
7170	{
7171	    for (i = 0; i < entries; ++i)
7172	    {
7173		len = (int)STRLEN(tab[i].name);
7174		if (STRNCMP(p, tab[i].name, len) == 0
7175			&& p[len] == ':'
7176			&& p[len + 1] != NUL)
7177		{
7178		    s = p + len + 1;
7179#ifdef FEAT_MBYTE
7180		    c1 = mb_ptr2char_adv(&s);
7181		    if (mb_char2cells(c1) > 1)
7182			continue;
7183#else
7184		    c1 = *s++;
7185#endif
7186		    if (tab[i].cp == &lcs_tab2)
7187		    {
7188			if (*s == NUL)
7189			    continue;
7190#ifdef FEAT_MBYTE
7191			c2 = mb_ptr2char_adv(&s);
7192			if (mb_char2cells(c2) > 1)
7193			    continue;
7194#else
7195			c2 = *s++;
7196#endif
7197		    }
7198		    if (*s == ',' || *s == NUL)
7199		    {
7200			if (round)
7201			{
7202			    if (tab[i].cp == &lcs_tab2)
7203			    {
7204				lcs_tab1 = c1;
7205				lcs_tab2 = c2;
7206			    }
7207			    else if (tab[i].cp != NULL)
7208				*(tab[i].cp) = c1;
7209
7210			}
7211			p = s;
7212			break;
7213		    }
7214		}
7215	    }
7216
7217	    if (i == entries)
7218		return e_invarg;
7219	    if (*p == ',')
7220		++p;
7221	}
7222    }
7223
7224    return NULL;	/* no error */
7225}
7226
7227#ifdef FEAT_STL_OPT
7228/*
7229 * Check validity of options with the 'statusline' format.
7230 * Return error message or NULL.
7231 */
7232    char_u *
7233check_stl_option(s)
7234    char_u	*s;
7235{
7236    int		itemcnt = 0;
7237    int		groupdepth = 0;
7238    static char_u   errbuf[80];
7239
7240    while (*s && itemcnt < STL_MAX_ITEM)
7241    {
7242	/* Check for valid keys after % sequences */
7243	while (*s && *s != '%')
7244	    s++;
7245	if (!*s)
7246	    break;
7247	s++;
7248	if (*s != '%' && *s != ')')
7249	    ++itemcnt;
7250	if (*s == '%' || *s == STL_TRUNCMARK || *s == STL_MIDDLEMARK)
7251	{
7252	    s++;
7253	    continue;
7254	}
7255	if (*s == ')')
7256	{
7257	    s++;
7258	    if (--groupdepth < 0)
7259		break;
7260	    continue;
7261	}
7262	if (*s == '-')
7263	    s++;
7264	while (VIM_ISDIGIT(*s))
7265	    s++;
7266	if (*s == STL_USER_HL)
7267	    continue;
7268	if (*s == '.')
7269	{
7270	    s++;
7271	    while (*s && VIM_ISDIGIT(*s))
7272		s++;
7273	}
7274	if (*s == '(')
7275	{
7276	    groupdepth++;
7277	    continue;
7278	}
7279	if (vim_strchr(STL_ALL, *s) == NULL)
7280	{
7281	    return illegal_char(errbuf, *s);
7282	}
7283	if (*s == '{')
7284	{
7285	    s++;
7286	    while (*s != '}' && *s)
7287		s++;
7288	    if (*s != '}')
7289		return (char_u *)N_("E540: Unclosed expression sequence");
7290	}
7291    }
7292    if (itemcnt >= STL_MAX_ITEM)
7293	return (char_u *)N_("E541: too many items");
7294    if (groupdepth != 0)
7295	return (char_u *)N_("E542: unbalanced groups");
7296    return NULL;
7297}
7298#endif
7299
7300#ifdef FEAT_CLIPBOARD
7301/*
7302 * Extract the items in the 'clipboard' option and set global values.
7303 */
7304    static char_u *
7305check_clipboard_option()
7306{
7307    int		new_unnamed = FALSE;
7308    int		new_autoselect = FALSE;
7309    int		new_autoselectml = FALSE;
7310    int		new_html = FALSE;
7311    regprog_T	*new_exclude_prog = NULL;
7312    char_u	*errmsg = NULL;
7313    char_u	*p;
7314
7315    for (p = p_cb; *p != NUL; )
7316    {
7317	if (STRNCMP(p, "unnamed", 7) == 0 && (p[7] == ',' || p[7] == NUL))
7318	{
7319	    new_unnamed = TRUE;
7320	    p += 7;
7321	}
7322	else if (STRNCMP(p, "autoselect", 10) == 0
7323					&& (p[10] == ',' || p[10] == NUL))
7324	{
7325	    new_autoselect = TRUE;
7326	    p += 10;
7327	}
7328	else if (STRNCMP(p, "autoselectml", 12) == 0
7329					&& (p[12] == ',' || p[12] == NUL))
7330	{
7331	    new_autoselectml = TRUE;
7332	    p += 12;
7333	}
7334	else if (STRNCMP(p, "html", 4) == 0 && (p[4] == ',' || p[4] == NUL))
7335	{
7336	    new_html = TRUE;
7337	    p += 4;
7338	}
7339	else if (STRNCMP(p, "exclude:", 8) == 0 && new_exclude_prog == NULL)
7340	{
7341	    p += 8;
7342	    new_exclude_prog = vim_regcomp(p, RE_MAGIC);
7343	    if (new_exclude_prog == NULL)
7344		errmsg = e_invarg;
7345	    break;
7346	}
7347	else
7348	{
7349	    errmsg = e_invarg;
7350	    break;
7351	}
7352	if (*p == ',')
7353	    ++p;
7354    }
7355    if (errmsg == NULL)
7356    {
7357	clip_unnamed = new_unnamed;
7358	clip_autoselect = new_autoselect;
7359	clip_autoselectml = new_autoselectml;
7360	clip_html = new_html;
7361	vim_free(clip_exclude_prog);
7362	clip_exclude_prog = new_exclude_prog;
7363#ifdef FEAT_GUI_GTK
7364	if (gui.in_use)
7365	{
7366	    gui_gtk_set_selection_targets();
7367	    gui_gtk_set_dnd_targets();
7368	}
7369#endif
7370    }
7371    else
7372	vim_free(new_exclude_prog);
7373
7374    return errmsg;
7375}
7376#endif
7377
7378#ifdef FEAT_SPELL
7379/*
7380 * Set curbuf->b_cap_prog to the regexp program for 'spellcapcheck'.
7381 * Return error message when failed, NULL when OK.
7382 */
7383    static char_u *
7384compile_cap_prog(synblock)
7385    synblock_T *synblock;
7386{
7387    regprog_T   *rp = synblock->b_cap_prog;
7388    char_u	*re;
7389
7390    if (*synblock->b_p_spc == NUL)
7391	synblock->b_cap_prog = NULL;
7392    else
7393    {
7394	/* Prepend a ^ so that we only match at one column */
7395	re = concat_str((char_u *)"^", synblock->b_p_spc);
7396	if (re != NULL)
7397	{
7398	    synblock->b_cap_prog = vim_regcomp(re, RE_MAGIC);
7399	    if (synblock->b_cap_prog == NULL)
7400	    {
7401		synblock->b_cap_prog = rp; /* restore the previous program */
7402		return e_invarg;
7403	    }
7404	    vim_free(re);
7405	}
7406    }
7407
7408    vim_free(rp);
7409    return NULL;
7410}
7411#endif
7412
7413#if defined(FEAT_EVAL) || defined(PROTO)
7414/*
7415 * Set the scriptID for an option, taking care of setting the buffer- or
7416 * window-local value.
7417 */
7418    static void
7419set_option_scriptID_idx(opt_idx, opt_flags, id)
7420    int	    opt_idx;
7421    int	    opt_flags;
7422    int	    id;
7423{
7424    int		both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
7425    int		indir = (int)options[opt_idx].indir;
7426
7427    /* Remember where the option was set.  For local options need to do that
7428     * in the buffer or window structure. */
7429    if (both || (opt_flags & OPT_GLOBAL) || (indir & (PV_BUF|PV_WIN)) == 0)
7430	options[opt_idx].scriptID = id;
7431    if (both || (opt_flags & OPT_LOCAL))
7432    {
7433	if (indir & PV_BUF)
7434	    curbuf->b_p_scriptID[indir & PV_MASK] = id;
7435	else if (indir & PV_WIN)
7436	    curwin->w_p_scriptID[indir & PV_MASK] = id;
7437    }
7438}
7439#endif
7440
7441/*
7442 * Set the value of a boolean option, and take care of side effects.
7443 * Returns NULL for success, or an error message for an error.
7444 */
7445    static char_u *
7446set_bool_option(opt_idx, varp, value, opt_flags)
7447    int		opt_idx;		/* index in options[] table */
7448    char_u	*varp;			/* pointer to the option variable */
7449    int		value;			/* new value */
7450    int		opt_flags;		/* OPT_LOCAL and/or OPT_GLOBAL */
7451{
7452    int		old_value = *(int *)varp;
7453
7454    /* Disallow changing some options from secure mode */
7455    if ((secure
7456#ifdef HAVE_SANDBOX
7457		|| sandbox != 0
7458#endif
7459		) && (options[opt_idx].flags & P_SECURE))
7460	return e_secure;
7461
7462    *(int *)varp = value;	    /* set the new value */
7463#ifdef FEAT_EVAL
7464    /* Remember where the option was set. */
7465    set_option_scriptID_idx(opt_idx, opt_flags, current_SID);
7466#endif
7467
7468#ifdef FEAT_GUI
7469    need_mouse_correct = TRUE;
7470#endif
7471
7472    /* May set global value for local option. */
7473    if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
7474	*(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = value;
7475
7476    /*
7477     * Handle side effects of changing a bool option.
7478     */
7479
7480    /* 'compatible' */
7481    if ((int *)varp == &p_cp)
7482    {
7483	compatible_set();
7484    }
7485
7486    /* 'list', 'number' */
7487    else if ((int *)varp == &curwin->w_p_list
7488	  || (int *)varp == &curwin->w_p_nu
7489	  || (int *)varp == &curwin->w_p_rnu)
7490    {
7491	if (curwin->w_curswant != MAXCOL)
7492	    curwin->w_set_curswant = TRUE;
7493
7494	/* If 'number' is set, reset 'relativenumber'. */
7495	/* If 'relativenumber' is set, reset 'number'. */
7496	if ((int *)varp == &curwin->w_p_nu && curwin->w_p_nu)
7497	    curwin->w_p_rnu = FALSE;
7498	if ((int *)varp == &curwin->w_p_rnu && curwin->w_p_rnu)
7499	    curwin->w_p_nu = FALSE;
7500    }
7501
7502    else if ((int *)varp == &curbuf->b_p_ro)
7503    {
7504	/* when 'readonly' is reset globally, also reset readonlymode */
7505	if (!curbuf->b_p_ro && (opt_flags & OPT_LOCAL) == 0)
7506	    readonlymode = FALSE;
7507
7508	/* when 'readonly' is set may give W10 again */
7509	if (curbuf->b_p_ro)
7510	    curbuf->b_did_warn = FALSE;
7511
7512#ifdef FEAT_TITLE
7513	redraw_titles();
7514#endif
7515    }
7516
7517#ifdef FEAT_GUI
7518    else if ((int *)varp == &p_mh)
7519    {
7520	if (!p_mh)
7521	    gui_mch_mousehide(FALSE);
7522    }
7523#endif
7524
7525#ifdef FEAT_TITLE
7526    /* when 'modifiable' is changed, redraw the window title */
7527    else if ((int *)varp == &curbuf->b_p_ma)
7528    {
7529	redraw_titles();
7530    }
7531    /* when 'endofline' is changed, redraw the window title */
7532    else if ((int *)varp == &curbuf->b_p_eol)
7533    {
7534	redraw_titles();
7535    }
7536# ifdef FEAT_MBYTE
7537    /* when 'bomb' is changed, redraw the window title and tab page text */
7538    else if ((int *)varp == &curbuf->b_p_bomb)
7539    {
7540	redraw_titles();
7541    }
7542# endif
7543#endif
7544
7545    /* when 'bin' is set also set some other options */
7546    else if ((int *)varp == &curbuf->b_p_bin)
7547    {
7548	set_options_bin(old_value, curbuf->b_p_bin, opt_flags);
7549#ifdef FEAT_TITLE
7550	redraw_titles();
7551#endif
7552    }
7553
7554#ifdef FEAT_AUTOCMD
7555    /* when 'buflisted' changes, trigger autocommands */
7556    else if ((int *)varp == &curbuf->b_p_bl && old_value != curbuf->b_p_bl)
7557    {
7558	apply_autocmds(curbuf->b_p_bl ? EVENT_BUFADD : EVENT_BUFDELETE,
7559						    NULL, NULL, TRUE, curbuf);
7560    }
7561#endif
7562
7563    /* when 'swf' is set, create swapfile, when reset remove swapfile */
7564    else if ((int *)varp == &curbuf->b_p_swf)
7565    {
7566	if (curbuf->b_p_swf && p_uc)
7567	    ml_open_file(curbuf);		/* create the swap file */
7568	else
7569	    /* no need to reset curbuf->b_may_swap, ml_open_file() will check
7570	     * buf->b_p_swf */
7571	    mf_close_file(curbuf, TRUE);	/* remove the swap file */
7572    }
7573
7574    /* when 'terse' is set change 'shortmess' */
7575    else if ((int *)varp == &p_terse)
7576    {
7577	char_u	*p;
7578
7579	p = vim_strchr(p_shm, SHM_SEARCH);
7580
7581	/* insert 's' in p_shm */
7582	if (p_terse && p == NULL)
7583	{
7584	    STRCPY(IObuff, p_shm);
7585	    STRCAT(IObuff, "s");
7586	    set_string_option_direct((char_u *)"shm", -1, IObuff, OPT_FREE, 0);
7587	}
7588	/* remove 's' from p_shm */
7589	else if (!p_terse && p != NULL)
7590	    STRMOVE(p, p + 1);
7591    }
7592
7593    /* when 'paste' is set or reset also change other options */
7594    else if ((int *)varp == &p_paste)
7595    {
7596	paste_option_changed();
7597    }
7598
7599    /* when 'insertmode' is set from an autocommand need to do work here */
7600    else if ((int *)varp == &p_im)
7601    {
7602	if (p_im)
7603	{
7604	    if ((State & INSERT) == 0)
7605		need_start_insertmode = TRUE;
7606	    stop_insert_mode = FALSE;
7607	}
7608	else
7609	{
7610	    need_start_insertmode = FALSE;
7611	    stop_insert_mode = TRUE;
7612	    if (restart_edit != 0 && mode_displayed)
7613		clear_cmdline = TRUE;	/* remove "(insert)" */
7614	    restart_edit = 0;
7615	}
7616    }
7617
7618    /* when 'ignorecase' is set or reset and 'hlsearch' is set, redraw */
7619    else if ((int *)varp == &p_ic && p_hls)
7620    {
7621	redraw_all_later(SOME_VALID);
7622    }
7623
7624#ifdef FEAT_SEARCH_EXTRA
7625    /* when 'hlsearch' is set or reset: reset no_hlsearch */
7626    else if ((int *)varp == &p_hls)
7627    {
7628	no_hlsearch = FALSE;
7629    }
7630#endif
7631
7632#ifdef FEAT_SCROLLBIND
7633    /* when 'scrollbind' is set: snapshot the current position to avoid a jump
7634     * at the end of normal_cmd() */
7635    else if ((int *)varp == &curwin->w_p_scb)
7636    {
7637	if (curwin->w_p_scb)
7638	    do_check_scrollbind(FALSE);
7639    }
7640#endif
7641
7642#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
7643    /* There can be only one window with 'previewwindow' set. */
7644    else if ((int *)varp == &curwin->w_p_pvw)
7645    {
7646	if (curwin->w_p_pvw)
7647	{
7648	    win_T	*win;
7649
7650	    for (win = firstwin; win != NULL; win = win->w_next)
7651		if (win->w_p_pvw && win != curwin)
7652		{
7653		    curwin->w_p_pvw = FALSE;
7654		    return (char_u *)N_("E590: A preview window already exists");
7655		}
7656	}
7657    }
7658#endif
7659
7660    /* when 'textmode' is set or reset also change 'fileformat' */
7661    else if ((int *)varp == &curbuf->b_p_tx)
7662    {
7663	set_fileformat(curbuf->b_p_tx ? EOL_DOS : EOL_UNIX, opt_flags);
7664    }
7665
7666    /* when 'textauto' is set or reset also change 'fileformats' */
7667    else if ((int *)varp == &p_ta)
7668	set_string_option_direct((char_u *)"ffs", -1,
7669				 p_ta ? (char_u *)DFLT_FFS_VIM : (char_u *)"",
7670						     OPT_FREE | opt_flags, 0);
7671
7672    /*
7673     * When 'lisp' option changes include/exclude '-' in
7674     * keyword characters.
7675     */
7676#ifdef FEAT_LISP
7677    else if (varp == (char_u *)&(curbuf->b_p_lisp))
7678    {
7679	(void)buf_init_chartab(curbuf, FALSE);	    /* ignore errors */
7680    }
7681#endif
7682
7683#ifdef FEAT_TITLE
7684    /* when 'title' changed, may need to change the title; same for 'icon' */
7685    else if ((int *)varp == &p_title)
7686    {
7687	did_set_title(FALSE);
7688    }
7689
7690    else if ((int *)varp == &p_icon)
7691    {
7692	did_set_title(TRUE);
7693    }
7694#endif
7695
7696    else if ((int *)varp == &curbuf->b_changed)
7697    {
7698	if (!value)
7699	    save_file_ff(curbuf);	/* Buffer is unchanged */
7700#ifdef FEAT_TITLE
7701	redraw_titles();
7702#endif
7703#ifdef FEAT_AUTOCMD
7704	modified_was_set = value;
7705#endif
7706    }
7707
7708#ifdef BACKSLASH_IN_FILENAME
7709    else if ((int *)varp == &p_ssl)
7710    {
7711	if (p_ssl)
7712	{
7713	    psepc = '/';
7714	    psepcN = '\\';
7715	    pseps[0] = '/';
7716	}
7717	else
7718	{
7719	    psepc = '\\';
7720	    psepcN = '/';
7721	    pseps[0] = '\\';
7722	}
7723
7724	/* need to adjust the file name arguments and buffer names. */
7725	buflist_slash_adjust();
7726	alist_slash_adjust();
7727# ifdef FEAT_EVAL
7728	scriptnames_slash_adjust();
7729# endif
7730    }
7731#endif
7732
7733    /* If 'wrap' is set, set w_leftcol to zero. */
7734    else if ((int *)varp == &curwin->w_p_wrap)
7735    {
7736	if (curwin->w_p_wrap)
7737	    curwin->w_leftcol = 0;
7738	if (curwin->w_curswant != MAXCOL)
7739	    curwin->w_set_curswant = TRUE;
7740    }
7741
7742#ifdef FEAT_WINDOWS
7743    else if ((int *)varp == &p_ea)
7744    {
7745	if (p_ea && !old_value)
7746	    win_equal(curwin, FALSE, 0);
7747    }
7748#endif
7749
7750    else if ((int *)varp == &p_wiv)
7751    {
7752	/*
7753	 * When 'weirdinvert' changed, set/reset 't_xs'.
7754	 * Then set 'weirdinvert' according to value of 't_xs'.
7755	 */
7756	if (p_wiv && !old_value)
7757	    T_XS = (char_u *)"y";
7758	else if (!p_wiv && old_value)
7759	    T_XS = empty_option;
7760	p_wiv = (*T_XS != NUL);
7761    }
7762
7763#ifdef FEAT_BEVAL
7764    else if ((int *)varp == &p_beval)
7765    {
7766	if (p_beval == TRUE)
7767	    gui_mch_enable_beval_area(balloonEval);
7768	else
7769	    gui_mch_disable_beval_area(balloonEval);
7770    }
7771#endif
7772
7773#ifdef FEAT_AUTOCHDIR
7774    else if ((int *)varp == &p_acd)
7775    {
7776	/* Change directories when the 'acd' option is set now. */
7777	DO_AUTOCHDIR
7778    }
7779#endif
7780
7781#ifdef FEAT_DIFF
7782    /* 'diff' */
7783    else if ((int *)varp == &curwin->w_p_diff)
7784    {
7785	/* May add or remove the buffer from the list of diff buffers. */
7786	diff_buf_adjust(curwin);
7787# ifdef FEAT_FOLDING
7788	if (foldmethodIsDiff(curwin))
7789	    foldUpdateAll(curwin);
7790# endif
7791    }
7792#endif
7793
7794#ifdef USE_IM_CONTROL
7795    /* 'imdisable' */
7796    else if ((int *)varp == &p_imdisable)
7797    {
7798	/* Only de-activate it here, it will be enabled when changing mode. */
7799	if (p_imdisable)
7800	    im_set_active(FALSE);
7801    }
7802#endif
7803
7804#ifdef FEAT_SPELL
7805    /* 'spell' */
7806    else if ((int *)varp == &curwin->w_p_spell)
7807    {
7808	if (curwin->w_p_spell)
7809	{
7810	    char_u	*errmsg = did_set_spelllang(curwin);
7811	    if (errmsg != NULL)
7812		EMSG(_(errmsg));
7813	}
7814    }
7815#endif
7816
7817#ifdef FEAT_FKMAP
7818    else if ((int *)varp == &p_altkeymap)
7819    {
7820	if (old_value != p_altkeymap)
7821	{
7822	    if (!p_altkeymap)
7823	    {
7824		p_hkmap = p_fkmap;
7825		p_fkmap = 0;
7826	    }
7827	    else
7828	    {
7829		p_fkmap = p_hkmap;
7830		p_hkmap = 0;
7831	    }
7832	    (void)init_chartab();
7833	}
7834    }
7835
7836    /*
7837     * In case some second language keymapping options have changed, check
7838     * and correct the setting in a consistent way.
7839     */
7840
7841    /*
7842     * If hkmap or fkmap are set, reset Arabic keymapping.
7843     */
7844    if ((p_hkmap || p_fkmap) && p_altkeymap)
7845    {
7846	p_altkeymap = p_fkmap;
7847# ifdef FEAT_ARABIC
7848	curwin->w_p_arab = FALSE;
7849# endif
7850	(void)init_chartab();
7851    }
7852
7853    /*
7854     * If hkmap set, reset Farsi keymapping.
7855     */
7856    if (p_hkmap && p_altkeymap)
7857    {
7858	p_altkeymap = 0;
7859	p_fkmap = 0;
7860# ifdef FEAT_ARABIC
7861	curwin->w_p_arab = FALSE;
7862# endif
7863	(void)init_chartab();
7864    }
7865
7866    /*
7867     * If fkmap set, reset Hebrew keymapping.
7868     */
7869    if (p_fkmap && !p_altkeymap)
7870    {
7871	p_altkeymap = 1;
7872	p_hkmap = 0;
7873# ifdef FEAT_ARABIC
7874	curwin->w_p_arab = FALSE;
7875# endif
7876	(void)init_chartab();
7877    }
7878#endif
7879
7880#ifdef FEAT_ARABIC
7881    if ((int *)varp == &curwin->w_p_arab)
7882    {
7883	if (curwin->w_p_arab)
7884	{
7885	    /*
7886	     * 'arabic' is set, handle various sub-settings.
7887	     */
7888	    if (!p_tbidi)
7889	    {
7890		/* set rightleft mode */
7891		if (!curwin->w_p_rl)
7892		{
7893		    curwin->w_p_rl = TRUE;
7894		    changed_window_setting();
7895		}
7896
7897		/* Enable Arabic shaping (major part of what Arabic requires) */
7898		if (!p_arshape)
7899		{
7900		    p_arshape = TRUE;
7901		    redraw_later_clear();
7902		}
7903	    }
7904
7905	    /* Arabic requires a utf-8 encoding, inform the user if its not
7906	     * set. */
7907	    if (STRCMP(p_enc, "utf-8") != 0)
7908	    {
7909		static char *w_arabic = N_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'");
7910
7911		msg_source(hl_attr(HLF_W));
7912		MSG_ATTR(_(w_arabic), hl_attr(HLF_W));
7913#ifdef FEAT_EVAL
7914		set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_arabic), -1);
7915#endif
7916	    }
7917
7918# ifdef FEAT_MBYTE
7919	    /* set 'delcombine' */
7920	    p_deco = TRUE;
7921# endif
7922
7923# ifdef FEAT_KEYMAP
7924	    /* Force-set the necessary keymap for arabic */
7925	    set_option_value((char_u *)"keymap", 0L, (char_u *)"arabic",
7926								   OPT_LOCAL);
7927# endif
7928# ifdef FEAT_FKMAP
7929	    p_altkeymap = 0;
7930	    p_hkmap = 0;
7931	    p_fkmap = 0;
7932	    (void)init_chartab();
7933# endif
7934	}
7935	else
7936	{
7937	    /*
7938	     * 'arabic' is reset, handle various sub-settings.
7939	     */
7940	    if (!p_tbidi)
7941	    {
7942		/* reset rightleft mode */
7943		if (curwin->w_p_rl)
7944		{
7945		    curwin->w_p_rl = FALSE;
7946		    changed_window_setting();
7947		}
7948
7949		/* 'arabicshape' isn't reset, it is a global option and
7950		 * another window may still need it "on". */
7951	    }
7952
7953	    /* 'delcombine' isn't reset, it is a global option and another
7954	     * window may still want it "on". */
7955
7956# ifdef FEAT_KEYMAP
7957	    /* Revert to the default keymap */
7958	    curbuf->b_p_iminsert = B_IMODE_NONE;
7959	    curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
7960# endif
7961	}
7962	if (curwin->w_curswant != MAXCOL)
7963	    curwin->w_set_curswant = TRUE;
7964    }
7965
7966    else if ((int *)varp == &p_arshape)
7967    {
7968	if (curwin->w_curswant != MAXCOL)
7969	    curwin->w_set_curswant = TRUE;
7970    }
7971#endif
7972
7973#ifdef FEAT_LINEBREAK
7974    if ((int *)varp == &curwin->w_p_lbr)
7975    {
7976	if (curwin->w_curswant != MAXCOL)
7977	    curwin->w_set_curswant = TRUE;
7978    }
7979#endif
7980
7981#ifdef FEAT_RIGHTLEFT
7982    if ((int *)varp == &curwin->w_p_rl)
7983    {
7984	if (curwin->w_curswant != MAXCOL)
7985	    curwin->w_set_curswant = TRUE;
7986    }
7987#endif
7988
7989    /*
7990     * End of handling side effects for bool options.
7991     */
7992
7993    options[opt_idx].flags |= P_WAS_SET;
7994
7995    comp_col();			    /* in case 'ruler' or 'showcmd' changed */
7996
7997    check_redraw(options[opt_idx].flags);
7998
7999    return NULL;
8000}
8001
8002/*
8003 * Set the value of a number option, and take care of side effects.
8004 * Returns NULL for success, or an error message for an error.
8005 */
8006    static char_u *
8007set_num_option(opt_idx, varp, value, errbuf, errbuflen, opt_flags)
8008    int		opt_idx;		/* index in options[] table */
8009    char_u	*varp;			/* pointer to the option variable */
8010    long	value;			/* new value */
8011    char_u	*errbuf;		/* buffer for error messages */
8012    size_t	errbuflen;		/* length of "errbuf" */
8013    int		opt_flags;		/* OPT_LOCAL, OPT_GLOBAL and
8014					   OPT_MODELINE */
8015{
8016    char_u	*errmsg = NULL;
8017    long	old_value = *(long *)varp;
8018    long	old_Rows = Rows;	/* remember old Rows */
8019    long	old_Columns = Columns;	/* remember old Columns */
8020    long	*pp = (long *)varp;
8021
8022    /* Disallow changing some options from secure mode. */
8023    if ((secure
8024#ifdef HAVE_SANDBOX
8025		|| sandbox != 0
8026#endif
8027		) && (options[opt_idx].flags & P_SECURE))
8028	return e_secure;
8029
8030    *pp = value;
8031#ifdef FEAT_EVAL
8032    /* Remember where the option was set. */
8033    set_option_scriptID_idx(opt_idx, opt_flags, current_SID);
8034#endif
8035#ifdef FEAT_GUI
8036    need_mouse_correct = TRUE;
8037#endif
8038
8039    if (curbuf->b_p_sw <= 0)
8040    {
8041	errmsg = e_positive;
8042	curbuf->b_p_sw = curbuf->b_p_ts;
8043    }
8044
8045    /*
8046     * Number options that need some action when changed
8047     */
8048#ifdef FEAT_WINDOWS
8049    if (pp == &p_wh || pp == &p_hh)
8050    {
8051	if (p_wh < 1)
8052	{
8053	    errmsg = e_positive;
8054	    p_wh = 1;
8055	}
8056	if (p_wmh > p_wh)
8057	{
8058	    errmsg = e_winheight;
8059	    p_wh = p_wmh;
8060	}
8061	if (p_hh < 0)
8062	{
8063	    errmsg = e_positive;
8064	    p_hh = 0;
8065	}
8066
8067	/* Change window height NOW */
8068	if (lastwin != firstwin)
8069	{
8070	    if (pp == &p_wh && curwin->w_height < p_wh)
8071		win_setheight((int)p_wh);
8072	    if (pp == &p_hh && curbuf->b_help && curwin->w_height < p_hh)
8073		win_setheight((int)p_hh);
8074	}
8075    }
8076
8077    /* 'winminheight' */
8078    else if (pp == &p_wmh)
8079    {
8080	if (p_wmh < 0)
8081	{
8082	    errmsg = e_positive;
8083	    p_wmh = 0;
8084	}
8085	if (p_wmh > p_wh)
8086	{
8087	    errmsg = e_winheight;
8088	    p_wmh = p_wh;
8089	}
8090	win_setminheight();
8091    }
8092
8093# ifdef FEAT_VERTSPLIT
8094    else if (pp == &p_wiw)
8095    {
8096	if (p_wiw < 1)
8097	{
8098	    errmsg = e_positive;
8099	    p_wiw = 1;
8100	}
8101	if (p_wmw > p_wiw)
8102	{
8103	    errmsg = e_winwidth;
8104	    p_wiw = p_wmw;
8105	}
8106
8107	/* Change window width NOW */
8108	if (lastwin != firstwin && curwin->w_width < p_wiw)
8109	    win_setwidth((int)p_wiw);
8110    }
8111
8112    /* 'winminwidth' */
8113    else if (pp == &p_wmw)
8114    {
8115	if (p_wmw < 0)
8116	{
8117	    errmsg = e_positive;
8118	    p_wmw = 0;
8119	}
8120	if (p_wmw > p_wiw)
8121	{
8122	    errmsg = e_winwidth;
8123	    p_wmw = p_wiw;
8124	}
8125	win_setminheight();
8126    }
8127# endif
8128
8129#endif
8130
8131#ifdef FEAT_WINDOWS
8132    /* (re)set last window status line */
8133    else if (pp == &p_ls)
8134    {
8135	last_status(FALSE);
8136    }
8137
8138    /* (re)set tab page line */
8139    else if (pp == &p_stal)
8140    {
8141	shell_new_rows();	/* recompute window positions and heights */
8142    }
8143#endif
8144
8145#ifdef FEAT_GUI
8146    else if (pp == &p_linespace)
8147    {
8148	/* Recompute gui.char_height and resize the Vim window to keep the
8149	 * same number of lines. */
8150	if (gui.in_use && gui_mch_adjust_charheight() == OK)
8151	    gui_set_shellsize(FALSE, FALSE, RESIZE_VERT);
8152    }
8153#endif
8154
8155#ifdef FEAT_FOLDING
8156    /* 'foldlevel' */
8157    else if (pp == &curwin->w_p_fdl)
8158    {
8159	if (curwin->w_p_fdl < 0)
8160	    curwin->w_p_fdl = 0;
8161	newFoldLevel();
8162    }
8163
8164    /* 'foldminlines' */
8165    else if (pp == &curwin->w_p_fml)
8166    {
8167	foldUpdateAll(curwin);
8168    }
8169
8170    /* 'foldnestmax' */
8171    else if (pp == &curwin->w_p_fdn)
8172    {
8173	if (foldmethodIsSyntax(curwin) || foldmethodIsIndent(curwin))
8174	    foldUpdateAll(curwin);
8175    }
8176
8177    /* 'foldcolumn' */
8178    else if (pp == &curwin->w_p_fdc)
8179    {
8180	if (curwin->w_p_fdc < 0)
8181	{
8182	    errmsg = e_positive;
8183	    curwin->w_p_fdc = 0;
8184	}
8185	else if (curwin->w_p_fdc > 12)
8186	{
8187	    errmsg = e_invarg;
8188	    curwin->w_p_fdc = 12;
8189	}
8190    }
8191
8192    /* 'shiftwidth' or 'tabstop' */
8193    else if (pp == &curbuf->b_p_sw || pp == &curbuf->b_p_ts)
8194    {
8195	if (foldmethodIsIndent(curwin))
8196	    foldUpdateAll(curwin);
8197    }
8198#endif /* FEAT_FOLDING */
8199
8200#ifdef FEAT_MBYTE
8201    /* 'maxcombine' */
8202    else if (pp == &p_mco)
8203    {
8204	if (p_mco > MAX_MCO)
8205	    p_mco = MAX_MCO;
8206	else if (p_mco < 0)
8207	    p_mco = 0;
8208	screenclear();	    /* will re-allocate the screen */
8209    }
8210#endif
8211
8212    else if (pp == &curbuf->b_p_iminsert)
8213    {
8214	if (curbuf->b_p_iminsert < 0 || curbuf->b_p_iminsert > B_IMODE_LAST)
8215	{
8216	    errmsg = e_invarg;
8217	    curbuf->b_p_iminsert = B_IMODE_NONE;
8218	}
8219	p_iminsert = curbuf->b_p_iminsert;
8220	if (termcap_active)	/* don't do this in the alternate screen */
8221	    showmode();
8222#if defined(FEAT_WINDOWS) && defined(FEAT_KEYMAP)
8223	/* Show/unshow value of 'keymap' in status lines. */
8224	status_redraw_curbuf();
8225#endif
8226    }
8227
8228    else if (pp == &p_window)
8229    {
8230	if (p_window < 1)
8231	    p_window = 1;
8232	else if (p_window >= Rows)
8233	    p_window = Rows - 1;
8234    }
8235
8236    else if (pp == &curbuf->b_p_imsearch)
8237    {
8238	if (curbuf->b_p_imsearch < -1 || curbuf->b_p_imsearch > B_IMODE_LAST)
8239	{
8240	    errmsg = e_invarg;
8241	    curbuf->b_p_imsearch = B_IMODE_NONE;
8242	}
8243	p_imsearch = curbuf->b_p_imsearch;
8244    }
8245
8246#ifdef FEAT_TITLE
8247    /* if 'titlelen' has changed, redraw the title */
8248    else if (pp == &p_titlelen)
8249    {
8250	if (p_titlelen < 0)
8251	{
8252	    errmsg = e_positive;
8253	    p_titlelen = 85;
8254	}
8255	if (starting != NO_SCREEN && old_value != p_titlelen)
8256	    need_maketitle = TRUE;
8257    }
8258#endif
8259
8260    /* if p_ch changed value, change the command line height */
8261    else if (pp == &p_ch)
8262    {
8263	if (p_ch < 1)
8264	{
8265	    errmsg = e_positive;
8266	    p_ch = 1;
8267	}
8268	if (p_ch > Rows - min_rows() + 1)
8269	    p_ch = Rows - min_rows() + 1;
8270
8271	/* Only compute the new window layout when startup has been
8272	 * completed. Otherwise the frame sizes may be wrong. */
8273	if (p_ch != old_value && full_screen
8274#ifdef FEAT_GUI
8275		&& !gui.starting
8276#endif
8277	   )
8278	    command_height();
8279    }
8280
8281    /* when 'updatecount' changes from zero to non-zero, open swap files */
8282    else if (pp == &p_uc)
8283    {
8284	if (p_uc < 0)
8285	{
8286	    errmsg = e_positive;
8287	    p_uc = 100;
8288	}
8289	if (p_uc && !old_value)
8290	    ml_open_files();
8291    }
8292#ifdef FEAT_CONCEAL
8293    else if (pp == &curwin->w_p_cole)
8294    {
8295	if (curwin->w_p_cole < 0)
8296	{
8297	    errmsg = e_positive;
8298	    curwin->w_p_cole = 0;
8299	}
8300	else if (curwin->w_p_cole > 3)
8301	{
8302	    errmsg = e_invarg;
8303	    curwin->w_p_cole = 3;
8304	}
8305    }
8306#endif
8307#ifdef MZSCHEME_GUI_THREADS
8308    else if (pp == &p_mzq)
8309	mzvim_reset_timer();
8310#endif
8311
8312    /* sync undo before 'undolevels' changes */
8313    else if (pp == &p_ul)
8314    {
8315	/* use the old value, otherwise u_sync() may not work properly */
8316	p_ul = old_value;
8317	u_sync(TRUE);
8318	p_ul = value;
8319    }
8320
8321#ifdef FEAT_LINEBREAK
8322    /* 'numberwidth' must be positive */
8323    else if (pp == &curwin->w_p_nuw)
8324    {
8325	if (curwin->w_p_nuw < 1)
8326	{
8327	    errmsg = e_positive;
8328	    curwin->w_p_nuw = 1;
8329	}
8330	if (curwin->w_p_nuw > 10)
8331	{
8332	    errmsg = e_invarg;
8333	    curwin->w_p_nuw = 10;
8334	}
8335	curwin->w_nrwidth_line_count = 0;
8336    }
8337#endif
8338
8339    else if (pp == &curbuf->b_p_tw)
8340    {
8341	if (curbuf->b_p_tw < 0)
8342	{
8343	    errmsg = e_positive;
8344	    curbuf->b_p_tw = 0;
8345	}
8346#ifdef FEAT_SYN_HL
8347# ifdef FEAT_WINDOWS
8348	{
8349	    win_T	*wp;
8350	    tabpage_T	*tp;
8351
8352	    FOR_ALL_TAB_WINDOWS(tp, wp)
8353		check_colorcolumn(wp);
8354	}
8355# else
8356	check_colorcolumn(curwin);
8357# endif
8358#endif
8359    }
8360
8361    /*
8362     * Check the bounds for numeric options here
8363     */
8364    if (Rows < min_rows() && full_screen)
8365    {
8366	if (errbuf != NULL)
8367	{
8368	    vim_snprintf((char *)errbuf, errbuflen,
8369			       _("E593: Need at least %d lines"), min_rows());
8370	    errmsg = errbuf;
8371	}
8372	Rows = min_rows();
8373    }
8374    if (Columns < MIN_COLUMNS && full_screen)
8375    {
8376	if (errbuf != NULL)
8377	{
8378	    vim_snprintf((char *)errbuf, errbuflen,
8379			    _("E594: Need at least %d columns"), MIN_COLUMNS);
8380	    errmsg = errbuf;
8381	}
8382	Columns = MIN_COLUMNS;
8383    }
8384    /* Limit the values to avoid an overflow in Rows * Columns. */
8385    if (Columns > 10000)
8386	Columns = 10000;
8387    if (Rows > 1000)
8388	Rows = 1000;
8389
8390#ifdef DJGPP
8391    /* avoid a crash by checking for a too large value of 'columns' */
8392    if (old_Columns != Columns && full_screen && term_console)
8393	mch_check_columns();
8394#endif
8395
8396    /*
8397     * If the screen (shell) height has been changed, assume it is the
8398     * physical screenheight.
8399     */
8400    if (old_Rows != Rows || old_Columns != Columns)
8401    {
8402	/* Changing the screen size is not allowed while updating the screen. */
8403	if (updating_screen)
8404	    *pp = old_value;
8405	else if (full_screen
8406#ifdef FEAT_GUI
8407		&& !gui.starting
8408#endif
8409	    )
8410	    set_shellsize((int)Columns, (int)Rows, TRUE);
8411	else
8412	{
8413	    /* Postpone the resizing; check the size and cmdline position for
8414	     * messages. */
8415	    check_shellsize();
8416	    if (cmdline_row > Rows - p_ch && Rows > p_ch)
8417		cmdline_row = Rows - p_ch;
8418	}
8419	if (p_window >= Rows || !option_was_set((char_u *)"window"))
8420	    p_window = Rows - 1;
8421    }
8422
8423    if (curbuf->b_p_sts < 0)
8424    {
8425	errmsg = e_positive;
8426	curbuf->b_p_sts = 0;
8427    }
8428    if (curbuf->b_p_ts <= 0)
8429    {
8430	errmsg = e_positive;
8431	curbuf->b_p_ts = 8;
8432    }
8433    if (p_tm < 0)
8434    {
8435	errmsg = e_positive;
8436	p_tm = 0;
8437    }
8438    if ((curwin->w_p_scr <= 0
8439		|| (curwin->w_p_scr > curwin->w_height
8440		    && curwin->w_height > 0))
8441	    && full_screen)
8442    {
8443	if (pp == &(curwin->w_p_scr))
8444	{
8445	    if (curwin->w_p_scr != 0)
8446		errmsg = e_scroll;
8447	    win_comp_scroll(curwin);
8448	}
8449	/* If 'scroll' became invalid because of a side effect silently adjust
8450	 * it. */
8451	else if (curwin->w_p_scr <= 0)
8452	    curwin->w_p_scr = 1;
8453	else /* curwin->w_p_scr > curwin->w_height */
8454	    curwin->w_p_scr = curwin->w_height;
8455    }
8456    if (p_hi < 0)
8457    {
8458	errmsg = e_positive;
8459	p_hi = 0;
8460    }
8461    if (p_report < 0)
8462    {
8463	errmsg = e_positive;
8464	p_report = 1;
8465    }
8466    if ((p_sj < -100 || p_sj >= Rows) && full_screen)
8467    {
8468	if (Rows != old_Rows)	/* Rows changed, just adjust p_sj */
8469	    p_sj = Rows / 2;
8470	else
8471	{
8472	    errmsg = e_scroll;
8473	    p_sj = 1;
8474	}
8475    }
8476    if (p_so < 0 && full_screen)
8477    {
8478	errmsg = e_scroll;
8479	p_so = 0;
8480    }
8481    if (p_siso < 0 && full_screen)
8482    {
8483	errmsg = e_positive;
8484	p_siso = 0;
8485    }
8486#ifdef FEAT_CMDWIN
8487    if (p_cwh < 1)
8488    {
8489	errmsg = e_positive;
8490	p_cwh = 1;
8491    }
8492#endif
8493    if (p_ut < 0)
8494    {
8495	errmsg = e_positive;
8496	p_ut = 2000;
8497    }
8498    if (p_ss < 0)
8499    {
8500	errmsg = e_positive;
8501	p_ss = 0;
8502    }
8503
8504    /* May set global value for local option. */
8505    if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
8506	*(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = *pp;
8507
8508    options[opt_idx].flags |= P_WAS_SET;
8509
8510    comp_col();			    /* in case 'columns' or 'ls' changed */
8511    if (curwin->w_curswant != MAXCOL)
8512	curwin->w_set_curswant = TRUE;  /* in case 'tabstop' changed */
8513    check_redraw(options[opt_idx].flags);
8514
8515    return errmsg;
8516}
8517
8518/*
8519 * Called after an option changed: check if something needs to be redrawn.
8520 */
8521    static void
8522check_redraw(flags)
8523    long_u	flags;
8524{
8525    /* Careful: P_RCLR and P_RALL are a combination of other P_ flags */
8526    int		clear = (flags & P_RCLR) == P_RCLR;
8527    int		all = ((flags & P_RALL) == P_RALL || clear);
8528
8529#ifdef FEAT_WINDOWS
8530    if ((flags & P_RSTAT) || all)	/* mark all status lines dirty */
8531	status_redraw_all();
8532#endif
8533
8534    if ((flags & P_RBUF) || (flags & P_RWIN) || all)
8535	changed_window_setting();
8536    if (flags & P_RBUF)
8537	redraw_curbuf_later(NOT_VALID);
8538    if (clear)
8539	redraw_all_later(CLEAR);
8540    else if (all)
8541	redraw_all_later(NOT_VALID);
8542}
8543
8544/*
8545 * Find index for option 'arg'.
8546 * Return -1 if not found.
8547 */
8548    static int
8549findoption(arg)
8550    char_u *arg;
8551{
8552    int		    opt_idx;
8553    char	    *s, *p;
8554    static short    quick_tab[27] = {0, 0};	/* quick access table */
8555    int		    is_term_opt;
8556
8557    /*
8558     * For first call: Initialize the quick-access table.
8559     * It contains the index for the first option that starts with a certain
8560     * letter.  There are 26 letters, plus the first "t_" option.
8561     */
8562    if (quick_tab[1] == 0)
8563    {
8564	p = options[0].fullname;
8565	for (opt_idx = 1; (s = options[opt_idx].fullname) != NULL; opt_idx++)
8566	{
8567	    if (s[0] != p[0])
8568	    {
8569		if (s[0] == 't' && s[1] == '_')
8570		    quick_tab[26] = opt_idx;
8571		else
8572		    quick_tab[CharOrdLow(s[0])] = opt_idx;
8573	    }
8574	    p = s;
8575	}
8576    }
8577
8578    /*
8579     * Check for name starting with an illegal character.
8580     */
8581#ifdef EBCDIC
8582    if (!islower(arg[0]))
8583#else
8584    if (arg[0] < 'a' || arg[0] > 'z')
8585#endif
8586	return -1;
8587
8588    is_term_opt = (arg[0] == 't' && arg[1] == '_');
8589    if (is_term_opt)
8590	opt_idx = quick_tab[26];
8591    else
8592	opt_idx = quick_tab[CharOrdLow(arg[0])];
8593    for ( ; (s = options[opt_idx].fullname) != NULL; opt_idx++)
8594    {
8595	if (STRCMP(arg, s) == 0)		    /* match full name */
8596	    break;
8597    }
8598    if (s == NULL && !is_term_opt)
8599    {
8600	opt_idx = quick_tab[CharOrdLow(arg[0])];
8601	for ( ; options[opt_idx].fullname != NULL; opt_idx++)
8602	{
8603	    s = options[opt_idx].shortname;
8604	    if (s != NULL && STRCMP(arg, s) == 0)   /* match short name */
8605		break;
8606	    s = NULL;
8607	}
8608    }
8609    if (s == NULL)
8610	opt_idx = -1;
8611    return opt_idx;
8612}
8613
8614#if defined(FEAT_EVAL) || defined(FEAT_TCL) || defined(FEAT_MZSCHEME)
8615/*
8616 * Get the value for an option.
8617 *
8618 * Returns:
8619 * Number or Toggle option: 1, *numval gets value.
8620 *	     String option: 0, *stringval gets allocated string.
8621 * Hidden Number or Toggle option: -1.
8622 *	     hidden String option: -2.
8623 *		   unknown option: -3.
8624 */
8625    int
8626get_option_value(name, numval, stringval, opt_flags)
8627    char_u	*name;
8628    long	*numval;
8629    char_u	**stringval;	    /* NULL when only checking existence */
8630    int		opt_flags;
8631{
8632    int		opt_idx;
8633    char_u	*varp;
8634
8635    opt_idx = findoption(name);
8636    if (opt_idx < 0)		    /* unknown option */
8637	return -3;
8638
8639    varp = get_varp_scope(&(options[opt_idx]), opt_flags);
8640
8641    if (options[opt_idx].flags & P_STRING)
8642    {
8643	if (varp == NULL)		    /* hidden option */
8644	    return -2;
8645	if (stringval != NULL)
8646	{
8647#ifdef FEAT_CRYPT
8648	    /* never return the value of the crypt key */
8649	    if ((char_u **)varp == &curbuf->b_p_key
8650						&& **(char_u **)(varp) != NUL)
8651		*stringval = vim_strsave((char_u *)"*****");
8652	    else
8653#endif
8654		*stringval = vim_strsave(*(char_u **)(varp));
8655	}
8656	return 0;
8657    }
8658
8659    if (varp == NULL)		    /* hidden option */
8660	return -1;
8661    if (options[opt_idx].flags & P_NUM)
8662	*numval = *(long *)varp;
8663    else
8664    {
8665	/* Special case: 'modified' is b_changed, but we also want to consider
8666	 * it set when 'ff' or 'fenc' changed. */
8667	if ((int *)varp == &curbuf->b_changed)
8668	    *numval = curbufIsChanged();
8669	else
8670	    *numval = *(int *)varp;
8671    }
8672    return 1;
8673}
8674#endif
8675
8676/*
8677 * Set the value of option "name".
8678 * Use "string" for string options, use "number" for other options.
8679 */
8680    void
8681set_option_value(name, number, string, opt_flags)
8682    char_u	*name;
8683    long	number;
8684    char_u	*string;
8685    int		opt_flags;	/* OPT_LOCAL or 0 (both) */
8686{
8687    int		opt_idx;
8688    char_u	*varp;
8689    long_u	flags;
8690
8691    opt_idx = findoption(name);
8692    if (opt_idx < 0)
8693	EMSG2(_("E355: Unknown option: %s"), name);
8694    else
8695    {
8696	flags = options[opt_idx].flags;
8697#ifdef HAVE_SANDBOX
8698	/* Disallow changing some options in the sandbox */
8699	if (sandbox > 0 && (flags & P_SECURE))
8700	{
8701	    EMSG(_(e_sandbox));
8702	    return;
8703	}
8704#endif
8705	if (flags & P_STRING)
8706	    set_string_option(opt_idx, string, opt_flags);
8707	else
8708	{
8709	    varp = get_varp_scope(&(options[opt_idx]), opt_flags);
8710	    if (varp != NULL)	/* hidden option is not changed */
8711	    {
8712		if (number == 0 && string != NULL)
8713		{
8714		    int idx;
8715
8716		    /* Either we are given a string or we are setting option
8717		     * to zero. */
8718		    for (idx = 0; string[idx] == '0'; ++idx)
8719			;
8720		    if (string[idx] != NUL || idx == 0)
8721		    {
8722			/* There's another character after zeros or the string
8723			 * is empty.  In both cases, we are trying to set a
8724			 * num option using a string. */
8725			EMSG3(_("E521: Number required: &%s = '%s'"),
8726								name, string);
8727			return;     /* do nothing as we hit an error */
8728
8729		    }
8730		}
8731		if (flags & P_NUM)
8732		    (void)set_num_option(opt_idx, varp, number,
8733							  NULL, 0, opt_flags);
8734		else
8735		    (void)set_bool_option(opt_idx, varp, (int)number,
8736								   opt_flags);
8737	    }
8738	}
8739    }
8740}
8741
8742/*
8743 * Get the terminal code for a terminal option.
8744 * Returns NULL when not found.
8745 */
8746    char_u *
8747get_term_code(tname)
8748    char_u	*tname;
8749{
8750    int	    opt_idx;
8751    char_u  *varp;
8752
8753    if (tname[0] != 't' || tname[1] != '_' ||
8754	    tname[2] == NUL || tname[3] == NUL)
8755	return NULL;
8756    if ((opt_idx = findoption(tname)) >= 0)
8757    {
8758	varp = get_varp(&(options[opt_idx]));
8759	if (varp != NULL)
8760	    varp = *(char_u **)(varp);
8761	return varp;
8762    }
8763    return find_termcode(tname + 2);
8764}
8765
8766    char_u *
8767get_highlight_default()
8768{
8769    int i;
8770
8771    i = findoption((char_u *)"hl");
8772    if (i >= 0)
8773	return options[i].def_val[VI_DEFAULT];
8774    return (char_u *)NULL;
8775}
8776
8777#if defined(FEAT_MBYTE) || defined(PROTO)
8778    char_u *
8779get_encoding_default()
8780{
8781    int i;
8782
8783    i = findoption((char_u *)"enc");
8784    if (i >= 0)
8785	return options[i].def_val[VI_DEFAULT];
8786    return (char_u *)NULL;
8787}
8788#endif
8789
8790/*
8791 * Translate a string like "t_xx", "<t_xx>" or "<S-Tab>" to a key number.
8792 */
8793    static int
8794find_key_option(arg)
8795    char_u *arg;
8796{
8797    int		key;
8798    int		modifiers;
8799
8800    /*
8801     * Don't use get_special_key_code() for t_xx, we don't want it to call
8802     * add_termcap_entry().
8803     */
8804    if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
8805	key = TERMCAP2KEY(arg[2], arg[3]);
8806    else
8807    {
8808	--arg;			    /* put arg at the '<' */
8809	modifiers = 0;
8810	key = find_special_key(&arg, &modifiers, TRUE, TRUE);
8811	if (modifiers)		    /* can't handle modifiers here */
8812	    key = 0;
8813    }
8814    return key;
8815}
8816
8817/*
8818 * if 'all' == 0: show changed options
8819 * if 'all' == 1: show all normal options
8820 * if 'all' == 2: show all terminal options
8821 */
8822    static void
8823showoptions(all, opt_flags)
8824    int		all;
8825    int		opt_flags;	/* OPT_LOCAL and/or OPT_GLOBAL */
8826{
8827    struct vimoption	*p;
8828    int			col;
8829    int			isterm;
8830    char_u		*varp;
8831    struct vimoption	**items;
8832    int			item_count;
8833    int			run;
8834    int			row, rows;
8835    int			cols;
8836    int			i;
8837    int			len;
8838
8839#define INC 20
8840#define GAP 3
8841
8842    items = (struct vimoption **)alloc((unsigned)(sizeof(struct vimoption *) *
8843								PARAM_COUNT));
8844    if (items == NULL)
8845	return;
8846
8847    /* Highlight title */
8848    if (all == 2)
8849	MSG_PUTS_TITLE(_("\n--- Terminal codes ---"));
8850    else if (opt_flags & OPT_GLOBAL)
8851	MSG_PUTS_TITLE(_("\n--- Global option values ---"));
8852    else if (opt_flags & OPT_LOCAL)
8853	MSG_PUTS_TITLE(_("\n--- Local option values ---"));
8854    else
8855	MSG_PUTS_TITLE(_("\n--- Options ---"));
8856
8857    /*
8858     * do the loop two times:
8859     * 1. display the short items
8860     * 2. display the long items (only strings and numbers)
8861     */
8862    for (run = 1; run <= 2 && !got_int; ++run)
8863    {
8864	/*
8865	 * collect the items in items[]
8866	 */
8867	item_count = 0;
8868	for (p = &options[0]; p->fullname != NULL; p++)
8869	{
8870	    varp = NULL;
8871	    isterm = istermoption(p);
8872	    if (opt_flags != 0)
8873	    {
8874		if (p->indir != PV_NONE && !isterm)
8875		    varp = get_varp_scope(p, opt_flags);
8876	    }
8877	    else
8878		varp = get_varp(p);
8879	    if (varp != NULL
8880		    && ((all == 2 && isterm)
8881			|| (all == 1 && !isterm)
8882			|| (all == 0 && !optval_default(p, varp))))
8883	    {
8884		if (p->flags & P_BOOL)
8885		    len = 1;		/* a toggle option fits always */
8886		else
8887		{
8888		    option_value2string(p, opt_flags);
8889		    len = (int)STRLEN(p->fullname) + vim_strsize(NameBuff) + 1;
8890		}
8891		if ((len <= INC - GAP && run == 1) ||
8892						(len > INC - GAP && run == 2))
8893		    items[item_count++] = p;
8894	    }
8895	}
8896
8897	/*
8898	 * display the items
8899	 */
8900	if (run == 1)
8901	{
8902	    cols = (Columns + GAP - 3) / INC;
8903	    if (cols == 0)
8904		cols = 1;
8905	    rows = (item_count + cols - 1) / cols;
8906	}
8907	else	/* run == 2 */
8908	    rows = item_count;
8909	for (row = 0; row < rows && !got_int; ++row)
8910	{
8911	    msg_putchar('\n');			/* go to next line */
8912	    if (got_int)			/* 'q' typed in more */
8913		break;
8914	    col = 0;
8915	    for (i = row; i < item_count; i += rows)
8916	    {
8917		msg_col = col;			/* make columns */
8918		showoneopt(items[i], opt_flags);
8919		col += INC;
8920	    }
8921	    out_flush();
8922	    ui_breakcheck();
8923	}
8924    }
8925    vim_free(items);
8926}
8927
8928/*
8929 * Return TRUE if option "p" has its default value.
8930 */
8931    static int
8932optval_default(p, varp)
8933    struct vimoption	*p;
8934    char_u		*varp;
8935{
8936    int		dvi;
8937
8938    if (varp == NULL)
8939	return TRUE;	    /* hidden option is always at default */
8940    dvi = ((p->flags & P_VI_DEF) || p_cp) ? VI_DEFAULT : VIM_DEFAULT;
8941    if (p->flags & P_NUM)
8942	return (*(long *)varp == (long)(long_i)p->def_val[dvi]);
8943    if (p->flags & P_BOOL)
8944			/* the cast to long is required for Manx C, long_i is
8945			 * needed for MSVC */
8946	return (*(int *)varp == (int)(long)(long_i)p->def_val[dvi]);
8947    /* P_STRING */
8948    return (STRCMP(*(char_u **)varp, p->def_val[dvi]) == 0);
8949}
8950
8951/*
8952 * showoneopt: show the value of one option
8953 * must not be called with a hidden option!
8954 */
8955    static void
8956showoneopt(p, opt_flags)
8957    struct vimoption	*p;
8958    int			opt_flags;	/* OPT_LOCAL or OPT_GLOBAL */
8959{
8960    char_u	*varp;
8961    int		save_silent = silent_mode;
8962
8963    silent_mode = FALSE;
8964    info_message = TRUE;	/* use mch_msg(), not mch_errmsg() */
8965
8966    varp = get_varp_scope(p, opt_flags);
8967
8968    /* for 'modified' we also need to check if 'ff' or 'fenc' changed. */
8969    if ((p->flags & P_BOOL) && ((int *)varp == &curbuf->b_changed
8970					? !curbufIsChanged() : !*(int *)varp))
8971	MSG_PUTS("no");
8972    else if ((p->flags & P_BOOL) && *(int *)varp < 0)
8973	MSG_PUTS("--");
8974    else
8975	MSG_PUTS("  ");
8976    MSG_PUTS(p->fullname);
8977    if (!(p->flags & P_BOOL))
8978    {
8979	msg_putchar('=');
8980	/* put value string in NameBuff */
8981	option_value2string(p, opt_flags);
8982	msg_outtrans(NameBuff);
8983    }
8984
8985    silent_mode = save_silent;
8986    info_message = FALSE;
8987}
8988
8989/*
8990 * Write modified options as ":set" commands to a file.
8991 *
8992 * There are three values for "opt_flags":
8993 * OPT_GLOBAL:		   Write global option values and fresh values of
8994 *			   buffer-local options (used for start of a session
8995 *			   file).
8996 * OPT_GLOBAL + OPT_LOCAL: Idem, add fresh values of window-local options for
8997 *			   curwin (used for a vimrc file).
8998 * OPT_LOCAL:		   Write buffer-local option values for curbuf, fresh
8999 *			   and local values for window-local options of
9000 *			   curwin.  Local values are also written when at the
9001 *			   default value, because a modeline or autocommand
9002 *			   may have set them when doing ":edit file" and the
9003 *			   user has set them back at the default or fresh
9004 *			   value.
9005 *			   When "local_only" is TRUE, don't write fresh
9006 *			   values, only local values (for ":mkview").
9007 * (fresh value = value used for a new buffer or window for a local option).
9008 *
9009 * Return FAIL on error, OK otherwise.
9010 */
9011    int
9012makeset(fd, opt_flags, local_only)
9013    FILE	*fd;
9014    int		opt_flags;
9015    int		local_only;
9016{
9017    struct vimoption	*p;
9018    char_u		*varp;			/* currently used value */
9019    char_u		*varp_fresh;		/* local value */
9020    char_u		*varp_local = NULL;	/* fresh value */
9021    char		*cmd;
9022    int			round;
9023    int			pri;
9024
9025    /*
9026     * The options that don't have a default (terminal name, columns, lines)
9027     * are never written.  Terminal options are also not written.
9028     * Do the loop over "options[]" twice: once for options with the
9029     * P_PRI_MKRC flag and once without.
9030     */
9031    for (pri = 1; pri >= 0; --pri)
9032    {
9033      for (p = &options[0]; !istermoption(p); p++)
9034	if (!(p->flags & P_NO_MKRC)
9035		&& !istermoption(p)
9036		&& ((pri == 1) == ((p->flags & P_PRI_MKRC) != 0)))
9037	{
9038	    /* skip global option when only doing locals */
9039	    if (p->indir == PV_NONE && !(opt_flags & OPT_GLOBAL))
9040		continue;
9041
9042	    /* Do not store options like 'bufhidden' and 'syntax' in a vimrc
9043	     * file, they are always buffer-specific. */
9044	    if ((opt_flags & OPT_GLOBAL) && (p->flags & P_NOGLOB))
9045		continue;
9046
9047	    /* Global values are only written when not at the default value. */
9048	    varp = get_varp_scope(p, opt_flags);
9049	    if ((opt_flags & OPT_GLOBAL) && optval_default(p, varp))
9050		continue;
9051
9052	    round = 2;
9053	    if (p->indir != PV_NONE)
9054	    {
9055		if (p->var == VAR_WIN)
9056		{
9057		    /* skip window-local option when only doing globals */
9058		    if (!(opt_flags & OPT_LOCAL))
9059			continue;
9060		    /* When fresh value of window-local option is not at the
9061		     * default, need to write it too. */
9062		    if (!(opt_flags & OPT_GLOBAL) && !local_only)
9063		    {
9064			varp_fresh = get_varp_scope(p, OPT_GLOBAL);
9065			if (!optval_default(p, varp_fresh))
9066			{
9067			    round = 1;
9068			    varp_local = varp;
9069			    varp = varp_fresh;
9070			}
9071		    }
9072		}
9073	    }
9074
9075	    /* Round 1: fresh value for window-local options.
9076	     * Round 2: other values */
9077	    for ( ; round <= 2; varp = varp_local, ++round)
9078	    {
9079		if (round == 1 || (opt_flags & OPT_GLOBAL))
9080		    cmd = "set";
9081		else
9082		    cmd = "setlocal";
9083
9084		if (p->flags & P_BOOL)
9085		{
9086		    if (put_setbool(fd, cmd, p->fullname, *(int *)varp) == FAIL)
9087			return FAIL;
9088		}
9089		else if (p->flags & P_NUM)
9090		{
9091		    if (put_setnum(fd, cmd, p->fullname, (long *)varp) == FAIL)
9092			return FAIL;
9093		}
9094		else    /* P_STRING */
9095		{
9096#if defined(FEAT_SYN_HL) || defined(FEAT_AUTOCMD)
9097		    int		do_endif = FALSE;
9098
9099		    /* Don't set 'syntax' and 'filetype' again if the value is
9100		     * already right, avoids reloading the syntax file. */
9101		    if (
9102# if defined(FEAT_SYN_HL)
9103			    p->indir == PV_SYN
9104#  if defined(FEAT_AUTOCMD)
9105			    ||
9106#  endif
9107# endif
9108# if defined(FEAT_AUTOCMD)
9109			    p->indir == PV_FT
9110# endif
9111			    )
9112		    {
9113			if (fprintf(fd, "if &%s != '%s'", p->fullname,
9114						       *(char_u **)(varp)) < 0
9115				|| put_eol(fd) < 0)
9116			    return FAIL;
9117			do_endif = TRUE;
9118		    }
9119#endif
9120		    if (put_setstring(fd, cmd, p->fullname, (char_u **)varp,
9121					  (p->flags & P_EXPAND) != 0) == FAIL)
9122			return FAIL;
9123#if defined(FEAT_SYN_HL) || defined(FEAT_AUTOCMD)
9124		    if (do_endif)
9125		    {
9126			if (put_line(fd, "endif") == FAIL)
9127			    return FAIL;
9128		    }
9129#endif
9130		}
9131	    }
9132	}
9133    }
9134    return OK;
9135}
9136
9137#if defined(FEAT_FOLDING) || defined(PROTO)
9138/*
9139 * Generate set commands for the local fold options only.  Used when
9140 * 'sessionoptions' or 'viewoptions' contains "folds" but not "options".
9141 */
9142    int
9143makefoldset(fd)
9144    FILE	*fd;
9145{
9146    if (put_setstring(fd, "setlocal", "fdm", &curwin->w_p_fdm, FALSE) == FAIL
9147# ifdef FEAT_EVAL
9148	    || put_setstring(fd, "setlocal", "fde", &curwin->w_p_fde, FALSE)
9149								       == FAIL
9150# endif
9151	    || put_setstring(fd, "setlocal", "fmr", &curwin->w_p_fmr, FALSE)
9152								       == FAIL
9153	    || put_setstring(fd, "setlocal", "fdi", &curwin->w_p_fdi, FALSE)
9154								       == FAIL
9155	    || put_setnum(fd, "setlocal", "fdl", &curwin->w_p_fdl) == FAIL
9156	    || put_setnum(fd, "setlocal", "fml", &curwin->w_p_fml) == FAIL
9157	    || put_setnum(fd, "setlocal", "fdn", &curwin->w_p_fdn) == FAIL
9158	    || put_setbool(fd, "setlocal", "fen", curwin->w_p_fen) == FAIL
9159	    )
9160	return FAIL;
9161
9162    return OK;
9163}
9164#endif
9165
9166    static int
9167put_setstring(fd, cmd, name, valuep, expand)
9168    FILE	*fd;
9169    char	*cmd;
9170    char	*name;
9171    char_u	**valuep;
9172    int		expand;
9173{
9174    char_u	*s;
9175    char_u	buf[MAXPATHL];
9176
9177    if (fprintf(fd, "%s %s=", cmd, name) < 0)
9178	return FAIL;
9179    if (*valuep != NULL)
9180    {
9181	/* Output 'pastetoggle' as key names.  For other
9182	 * options some characters have to be escaped with
9183	 * CTRL-V or backslash */
9184	if (valuep == &p_pt)
9185	{
9186	    s = *valuep;
9187	    while (*s != NUL)
9188		if (put_escstr(fd, str2special(&s, FALSE), 2) == FAIL)
9189		    return FAIL;
9190	}
9191	else if (expand)
9192	{
9193	    home_replace(NULL, *valuep, buf, MAXPATHL, FALSE);
9194	    if (put_escstr(fd, buf, 2) == FAIL)
9195		return FAIL;
9196	}
9197	else if (put_escstr(fd, *valuep, 2) == FAIL)
9198	    return FAIL;
9199    }
9200    if (put_eol(fd) < 0)
9201	return FAIL;
9202    return OK;
9203}
9204
9205    static int
9206put_setnum(fd, cmd, name, valuep)
9207    FILE	*fd;
9208    char	*cmd;
9209    char	*name;
9210    long	*valuep;
9211{
9212    long	wc;
9213
9214    if (fprintf(fd, "%s %s=", cmd, name) < 0)
9215	return FAIL;
9216    if (wc_use_keyname((char_u *)valuep, &wc))
9217    {
9218	/* print 'wildchar' and 'wildcharm' as a key name */
9219	if (fputs((char *)get_special_key_name((int)wc, 0), fd) < 0)
9220	    return FAIL;
9221    }
9222    else if (fprintf(fd, "%ld", *valuep) < 0)
9223	return FAIL;
9224    if (put_eol(fd) < 0)
9225	return FAIL;
9226    return OK;
9227}
9228
9229    static int
9230put_setbool(fd, cmd, name, value)
9231    FILE	*fd;
9232    char	*cmd;
9233    char	*name;
9234    int		value;
9235{
9236    if (value < 0)	/* global/local option using global value */
9237	return OK;
9238    if (fprintf(fd, "%s %s%s", cmd, value ? "" : "no", name) < 0
9239	    || put_eol(fd) < 0)
9240	return FAIL;
9241    return OK;
9242}
9243
9244/*
9245 * Clear all the terminal options.
9246 * If the option has been allocated, free the memory.
9247 * Terminal options are never hidden or indirect.
9248 */
9249    void
9250clear_termoptions()
9251{
9252    /*
9253     * Reset a few things before clearing the old options. This may cause
9254     * outputting a few things that the terminal doesn't understand, but the
9255     * screen will be cleared later, so this is OK.
9256     */
9257#ifdef FEAT_MOUSE_TTY
9258    mch_setmouse(FALSE);	    /* switch mouse off */
9259#endif
9260#ifdef FEAT_TITLE
9261    mch_restore_title(3);	    /* restore window titles */
9262#endif
9263#if defined(FEAT_XCLIPBOARD) && defined(FEAT_GUI)
9264    /* When starting the GUI close the display opened for the clipboard.
9265     * After restoring the title, because that will need the display. */
9266    if (gui.starting)
9267	clear_xterm_clip();
9268#endif
9269#ifdef WIN3264
9270    /*
9271     * Check if this is allowed now.
9272     */
9273    if (can_end_termcap_mode(FALSE) == TRUE)
9274#endif
9275	stoptermcap();			/* stop termcap mode */
9276
9277    free_termoptions();
9278}
9279
9280    void
9281free_termoptions()
9282{
9283    struct vimoption   *p;
9284
9285    for (p = &options[0]; p->fullname != NULL; p++)
9286	if (istermoption(p))
9287	{
9288	    if (p->flags & P_ALLOCED)
9289		free_string_option(*(char_u **)(p->var));
9290	    if (p->flags & P_DEF_ALLOCED)
9291		free_string_option(p->def_val[VI_DEFAULT]);
9292	    *(char_u **)(p->var) = empty_option;
9293	    p->def_val[VI_DEFAULT] = empty_option;
9294	    p->flags &= ~(P_ALLOCED|P_DEF_ALLOCED);
9295	}
9296    clear_termcodes();
9297}
9298
9299/*
9300 * Free the string for one term option, if it was allocated.
9301 * Set the string to empty_option and clear allocated flag.
9302 * "var" points to the option value.
9303 */
9304    void
9305free_one_termoption(var)
9306    char_u *var;
9307{
9308    struct vimoption   *p;
9309
9310    for (p = &options[0]; p->fullname != NULL; p++)
9311	if (p->var == var)
9312	{
9313	    if (p->flags & P_ALLOCED)
9314		free_string_option(*(char_u **)(p->var));
9315	    *(char_u **)(p->var) = empty_option;
9316	    p->flags &= ~P_ALLOCED;
9317	    break;
9318	}
9319}
9320
9321/*
9322 * Set the terminal option defaults to the current value.
9323 * Used after setting the terminal name.
9324 */
9325    void
9326set_term_defaults()
9327{
9328    struct vimoption   *p;
9329
9330    for (p = &options[0]; p->fullname != NULL; p++)
9331    {
9332	if (istermoption(p) && p->def_val[VI_DEFAULT] != *(char_u **)(p->var))
9333	{
9334	    if (p->flags & P_DEF_ALLOCED)
9335	    {
9336		free_string_option(p->def_val[VI_DEFAULT]);
9337		p->flags &= ~P_DEF_ALLOCED;
9338	    }
9339	    p->def_val[VI_DEFAULT] = *(char_u **)(p->var);
9340	    if (p->flags & P_ALLOCED)
9341	    {
9342		p->flags |= P_DEF_ALLOCED;
9343		p->flags &= ~P_ALLOCED;	 /* don't free the value now */
9344	    }
9345	}
9346    }
9347}
9348
9349/*
9350 * return TRUE if 'p' starts with 't_'
9351 */
9352    static int
9353istermoption(p)
9354    struct vimoption *p;
9355{
9356    return (p->fullname[0] == 't' && p->fullname[1] == '_');
9357}
9358
9359/*
9360 * Compute columns for ruler and shown command. 'sc_col' is also used to
9361 * decide what the maximum length of a message on the status line can be.
9362 * If there is a status line for the last window, 'sc_col' is independent
9363 * of 'ru_col'.
9364 */
9365
9366#define COL_RULER 17	    /* columns needed by standard ruler */
9367
9368    void
9369comp_col()
9370{
9371#if defined(FEAT_CMDL_INFO) && defined(FEAT_WINDOWS)
9372    int last_has_status = (p_ls == 2 || (p_ls == 1 && firstwin != lastwin));
9373
9374    sc_col = 0;
9375    ru_col = 0;
9376    if (p_ru)
9377    {
9378#ifdef FEAT_STL_OPT
9379	ru_col = (ru_wid ? ru_wid : COL_RULER) + 1;
9380#else
9381	ru_col = COL_RULER + 1;
9382#endif
9383	/* no last status line, adjust sc_col */
9384	if (!last_has_status)
9385	    sc_col = ru_col;
9386    }
9387    if (p_sc)
9388    {
9389	sc_col += SHOWCMD_COLS;
9390	if (!p_ru || last_has_status)	    /* no need for separating space */
9391	    ++sc_col;
9392    }
9393    sc_col = Columns - sc_col;
9394    ru_col = Columns - ru_col;
9395    if (sc_col <= 0)		/* screen too narrow, will become a mess */
9396	sc_col = 1;
9397    if (ru_col <= 0)
9398	ru_col = 1;
9399#else
9400    sc_col = Columns;
9401    ru_col = Columns;
9402#endif
9403}
9404
9405/*
9406 * Get pointer to option variable, depending on local or global scope.
9407 */
9408    static char_u *
9409get_varp_scope(p, opt_flags)
9410    struct vimoption	*p;
9411    int			opt_flags;
9412{
9413    if ((opt_flags & OPT_GLOBAL) && p->indir != PV_NONE)
9414    {
9415	if (p->var == VAR_WIN)
9416	    return (char_u *)GLOBAL_WO(get_varp(p));
9417	return p->var;
9418    }
9419    if ((opt_flags & OPT_LOCAL) && ((int)p->indir & PV_BOTH))
9420    {
9421	switch ((int)p->indir)
9422	{
9423#ifdef FEAT_QUICKFIX
9424	    case PV_EFM:  return (char_u *)&(curbuf->b_p_efm);
9425	    case PV_GP:   return (char_u *)&(curbuf->b_p_gp);
9426	    case PV_MP:   return (char_u *)&(curbuf->b_p_mp);
9427#endif
9428	    case PV_EP:   return (char_u *)&(curbuf->b_p_ep);
9429	    case PV_KP:   return (char_u *)&(curbuf->b_p_kp);
9430	    case PV_PATH: return (char_u *)&(curbuf->b_p_path);
9431	    case PV_AR:   return (char_u *)&(curbuf->b_p_ar);
9432	    case PV_TAGS: return (char_u *)&(curbuf->b_p_tags);
9433#ifdef FEAT_FIND_ID
9434	    case PV_DEF:  return (char_u *)&(curbuf->b_p_def);
9435	    case PV_INC:  return (char_u *)&(curbuf->b_p_inc);
9436#endif
9437#ifdef FEAT_INS_EXPAND
9438	    case PV_DICT: return (char_u *)&(curbuf->b_p_dict);
9439	    case PV_TSR:  return (char_u *)&(curbuf->b_p_tsr);
9440#endif
9441#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
9442	    case PV_BEXPR: return (char_u *)&(curbuf->b_p_bexpr);
9443#endif
9444#if defined(FEAT_CRYPT)
9445	    case PV_CM:	  return (char_u *)&(curbuf->b_p_cm);
9446#endif
9447#ifdef FEAT_STL_OPT
9448	    case PV_STL:  return (char_u *)&(curwin->w_p_stl);
9449#endif
9450	}
9451	return NULL; /* "cannot happen" */
9452    }
9453    return get_varp(p);
9454}
9455
9456/*
9457 * Get pointer to option variable.
9458 */
9459    static char_u *
9460get_varp(p)
9461    struct vimoption	*p;
9462{
9463    /* hidden option, always return NULL */
9464    if (p->var == NULL)
9465	return NULL;
9466
9467    switch ((int)p->indir)
9468    {
9469	case PV_NONE:	return p->var;
9470
9471	/* global option with local value: use local value if it's been set */
9472	case PV_EP:	return *curbuf->b_p_ep != NUL
9473				    ? (char_u *)&curbuf->b_p_ep : p->var;
9474	case PV_KP:	return *curbuf->b_p_kp != NUL
9475				    ? (char_u *)&curbuf->b_p_kp : p->var;
9476	case PV_PATH:	return *curbuf->b_p_path != NUL
9477				    ? (char_u *)&(curbuf->b_p_path) : p->var;
9478	case PV_AR:	return curbuf->b_p_ar >= 0
9479				    ? (char_u *)&(curbuf->b_p_ar) : p->var;
9480	case PV_TAGS:	return *curbuf->b_p_tags != NUL
9481				    ? (char_u *)&(curbuf->b_p_tags) : p->var;
9482#ifdef FEAT_FIND_ID
9483	case PV_DEF:	return *curbuf->b_p_def != NUL
9484				    ? (char_u *)&(curbuf->b_p_def) : p->var;
9485	case PV_INC:	return *curbuf->b_p_inc != NUL
9486				    ? (char_u *)&(curbuf->b_p_inc) : p->var;
9487#endif
9488#ifdef FEAT_INS_EXPAND
9489	case PV_DICT:	return *curbuf->b_p_dict != NUL
9490				    ? (char_u *)&(curbuf->b_p_dict) : p->var;
9491	case PV_TSR:	return *curbuf->b_p_tsr != NUL
9492				    ? (char_u *)&(curbuf->b_p_tsr) : p->var;
9493#endif
9494#ifdef FEAT_QUICKFIX
9495	case PV_EFM:	return *curbuf->b_p_efm != NUL
9496				    ? (char_u *)&(curbuf->b_p_efm) : p->var;
9497	case PV_GP:	return *curbuf->b_p_gp != NUL
9498				    ? (char_u *)&(curbuf->b_p_gp) : p->var;
9499	case PV_MP:	return *curbuf->b_p_mp != NUL
9500				    ? (char_u *)&(curbuf->b_p_mp) : p->var;
9501#endif
9502#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
9503	case PV_BEXPR:	return *curbuf->b_p_bexpr != NUL
9504				    ? (char_u *)&(curbuf->b_p_bexpr) : p->var;
9505#endif
9506#if defined(FEAT_CRYPT)
9507	case PV_CM:	return *curbuf->b_p_cm != NUL
9508				    ? (char_u *)&(curbuf->b_p_cm) : p->var;
9509#endif
9510#ifdef FEAT_STL_OPT
9511	case PV_STL:	return *curwin->w_p_stl != NUL
9512				    ? (char_u *)&(curwin->w_p_stl) : p->var;
9513#endif
9514
9515#ifdef FEAT_ARABIC
9516	case PV_ARAB:	return (char_u *)&(curwin->w_p_arab);
9517#endif
9518	case PV_LIST:	return (char_u *)&(curwin->w_p_list);
9519#ifdef FEAT_SPELL
9520	case PV_SPELL:	return (char_u *)&(curwin->w_p_spell);
9521#endif
9522#ifdef FEAT_SYN_HL
9523	case PV_CUC:	return (char_u *)&(curwin->w_p_cuc);
9524	case PV_CUL:	return (char_u *)&(curwin->w_p_cul);
9525	case PV_CC:	return (char_u *)&(curwin->w_p_cc);
9526#endif
9527#ifdef FEAT_DIFF
9528	case PV_DIFF:	return (char_u *)&(curwin->w_p_diff);
9529#endif
9530#ifdef FEAT_FOLDING
9531	case PV_FDC:	return (char_u *)&(curwin->w_p_fdc);
9532	case PV_FEN:	return (char_u *)&(curwin->w_p_fen);
9533	case PV_FDI:	return (char_u *)&(curwin->w_p_fdi);
9534	case PV_FDL:	return (char_u *)&(curwin->w_p_fdl);
9535	case PV_FDM:	return (char_u *)&(curwin->w_p_fdm);
9536	case PV_FML:	return (char_u *)&(curwin->w_p_fml);
9537	case PV_FDN:	return (char_u *)&(curwin->w_p_fdn);
9538# ifdef FEAT_EVAL
9539	case PV_FDE:	return (char_u *)&(curwin->w_p_fde);
9540	case PV_FDT:	return (char_u *)&(curwin->w_p_fdt);
9541# endif
9542	case PV_FMR:	return (char_u *)&(curwin->w_p_fmr);
9543#endif
9544	case PV_NU:	return (char_u *)&(curwin->w_p_nu);
9545	case PV_RNU:	return (char_u *)&(curwin->w_p_rnu);
9546#ifdef FEAT_LINEBREAK
9547	case PV_NUW:	return (char_u *)&(curwin->w_p_nuw);
9548#endif
9549#ifdef FEAT_WINDOWS
9550	case PV_WFH:	return (char_u *)&(curwin->w_p_wfh);
9551#endif
9552#ifdef FEAT_VERTSPLIT
9553	case PV_WFW:	return (char_u *)&(curwin->w_p_wfw);
9554#endif
9555#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
9556	case PV_PVW:	return (char_u *)&(curwin->w_p_pvw);
9557#endif
9558#ifdef FEAT_RIGHTLEFT
9559	case PV_RL:	return (char_u *)&(curwin->w_p_rl);
9560	case PV_RLC:	return (char_u *)&(curwin->w_p_rlc);
9561#endif
9562	case PV_SCROLL:	return (char_u *)&(curwin->w_p_scr);
9563	case PV_WRAP:	return (char_u *)&(curwin->w_p_wrap);
9564#ifdef FEAT_LINEBREAK
9565	case PV_LBR:	return (char_u *)&(curwin->w_p_lbr);
9566#endif
9567#ifdef FEAT_SCROLLBIND
9568	case PV_SCBIND: return (char_u *)&(curwin->w_p_scb);
9569#endif
9570#ifdef FEAT_CURSORBIND
9571	case PV_CRBIND: return (char_u *)&(curwin->w_p_crb);
9572#endif
9573#ifdef FEAT_CONCEAL
9574	case PV_COCU:    return (char_u *)&(curwin->w_p_cocu);
9575	case PV_COLE:    return (char_u *)&(curwin->w_p_cole);
9576#endif
9577
9578	case PV_AI:	return (char_u *)&(curbuf->b_p_ai);
9579	case PV_BIN:	return (char_u *)&(curbuf->b_p_bin);
9580#ifdef FEAT_MBYTE
9581	case PV_BOMB:	return (char_u *)&(curbuf->b_p_bomb);
9582#endif
9583#if defined(FEAT_QUICKFIX)
9584	case PV_BH:	return (char_u *)&(curbuf->b_p_bh);
9585	case PV_BT:	return (char_u *)&(curbuf->b_p_bt);
9586#endif
9587	case PV_BL:	return (char_u *)&(curbuf->b_p_bl);
9588	case PV_CI:	return (char_u *)&(curbuf->b_p_ci);
9589#ifdef FEAT_CINDENT
9590	case PV_CIN:	return (char_u *)&(curbuf->b_p_cin);
9591	case PV_CINK:	return (char_u *)&(curbuf->b_p_cink);
9592	case PV_CINO:	return (char_u *)&(curbuf->b_p_cino);
9593#endif
9594#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
9595	case PV_CINW:	return (char_u *)&(curbuf->b_p_cinw);
9596#endif
9597#ifdef FEAT_COMMENTS
9598	case PV_COM:	return (char_u *)&(curbuf->b_p_com);
9599#endif
9600#ifdef FEAT_FOLDING
9601	case PV_CMS:	return (char_u *)&(curbuf->b_p_cms);
9602#endif
9603#ifdef FEAT_INS_EXPAND
9604	case PV_CPT:	return (char_u *)&(curbuf->b_p_cpt);
9605#endif
9606#ifdef FEAT_COMPL_FUNC
9607	case PV_CFU:	return (char_u *)&(curbuf->b_p_cfu);
9608	case PV_OFU:	return (char_u *)&(curbuf->b_p_ofu);
9609#endif
9610	case PV_EOL:	return (char_u *)&(curbuf->b_p_eol);
9611	case PV_ET:	return (char_u *)&(curbuf->b_p_et);
9612#ifdef FEAT_MBYTE
9613	case PV_FENC:	return (char_u *)&(curbuf->b_p_fenc);
9614#endif
9615	case PV_FF:	return (char_u *)&(curbuf->b_p_ff);
9616#ifdef FEAT_AUTOCMD
9617	case PV_FT:	return (char_u *)&(curbuf->b_p_ft);
9618#endif
9619	case PV_FO:	return (char_u *)&(curbuf->b_p_fo);
9620	case PV_FLP:	return (char_u *)&(curbuf->b_p_flp);
9621	case PV_IMI:	return (char_u *)&(curbuf->b_p_iminsert);
9622	case PV_IMS:	return (char_u *)&(curbuf->b_p_imsearch);
9623	case PV_INF:	return (char_u *)&(curbuf->b_p_inf);
9624	case PV_ISK:	return (char_u *)&(curbuf->b_p_isk);
9625#ifdef FEAT_FIND_ID
9626# ifdef FEAT_EVAL
9627	case PV_INEX:	return (char_u *)&(curbuf->b_p_inex);
9628# endif
9629#endif
9630#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
9631	case PV_INDE:	return (char_u *)&(curbuf->b_p_inde);
9632	case PV_INDK:	return (char_u *)&(curbuf->b_p_indk);
9633#endif
9634#ifdef FEAT_EVAL
9635	case PV_FEX:	return (char_u *)&(curbuf->b_p_fex);
9636#endif
9637#ifdef FEAT_CRYPT
9638	case PV_KEY:	return (char_u *)&(curbuf->b_p_key);
9639#endif
9640#ifdef FEAT_LISP
9641	case PV_LISP:	return (char_u *)&(curbuf->b_p_lisp);
9642#endif
9643	case PV_ML:	return (char_u *)&(curbuf->b_p_ml);
9644	case PV_MPS:	return (char_u *)&(curbuf->b_p_mps);
9645	case PV_MA:	return (char_u *)&(curbuf->b_p_ma);
9646	case PV_MOD:	return (char_u *)&(curbuf->b_changed);
9647	case PV_NF:	return (char_u *)&(curbuf->b_p_nf);
9648#ifdef FEAT_OSFILETYPE
9649	case PV_OFT:	return (char_u *)&(curbuf->b_p_oft);
9650#endif
9651	case PV_PI:	return (char_u *)&(curbuf->b_p_pi);
9652#ifdef FEAT_TEXTOBJ
9653	case PV_QE:	return (char_u *)&(curbuf->b_p_qe);
9654#endif
9655	case PV_RO:	return (char_u *)&(curbuf->b_p_ro);
9656#ifdef FEAT_SMARTINDENT
9657	case PV_SI:	return (char_u *)&(curbuf->b_p_si);
9658#endif
9659#ifndef SHORT_FNAME
9660	case PV_SN:	return (char_u *)&(curbuf->b_p_sn);
9661#endif
9662	case PV_STS:	return (char_u *)&(curbuf->b_p_sts);
9663#ifdef FEAT_SEARCHPATH
9664	case PV_SUA:	return (char_u *)&(curbuf->b_p_sua);
9665#endif
9666	case PV_SWF:	return (char_u *)&(curbuf->b_p_swf);
9667#ifdef FEAT_SYN_HL
9668	case PV_SMC:	return (char_u *)&(curbuf->b_p_smc);
9669	case PV_SYN:	return (char_u *)&(curbuf->b_p_syn);
9670#endif
9671#ifdef FEAT_SPELL
9672	case PV_SPC:	return (char_u *)&(curwin->w_s->b_p_spc);
9673	case PV_SPF:	return (char_u *)&(curwin->w_s->b_p_spf);
9674	case PV_SPL:	return (char_u *)&(curwin->w_s->b_p_spl);
9675#endif
9676	case PV_SW:	return (char_u *)&(curbuf->b_p_sw);
9677	case PV_TS:	return (char_u *)&(curbuf->b_p_ts);
9678	case PV_TW:	return (char_u *)&(curbuf->b_p_tw);
9679	case PV_TX:	return (char_u *)&(curbuf->b_p_tx);
9680#ifdef FEAT_PERSISTENT_UNDO
9681	case PV_UDF:	return (char_u *)&(curbuf->b_p_udf);
9682#endif
9683	case PV_WM:	return (char_u *)&(curbuf->b_p_wm);
9684#ifdef FEAT_KEYMAP
9685	case PV_KMAP:	return (char_u *)&(curbuf->b_p_keymap);
9686#endif
9687	default:	EMSG(_("E356: get_varp ERROR"));
9688    }
9689    /* always return a valid pointer to avoid a crash! */
9690    return (char_u *)&(curbuf->b_p_wm);
9691}
9692
9693/*
9694 * Get the value of 'equalprg', either the buffer-local one or the global one.
9695 */
9696    char_u *
9697get_equalprg()
9698{
9699    if (*curbuf->b_p_ep == NUL)
9700	return p_ep;
9701    return curbuf->b_p_ep;
9702}
9703
9704#if defined(FEAT_WINDOWS) || defined(PROTO)
9705/*
9706 * Copy options from one window to another.
9707 * Used when splitting a window.
9708 */
9709    void
9710win_copy_options(wp_from, wp_to)
9711    win_T	*wp_from;
9712    win_T	*wp_to;
9713{
9714    copy_winopt(&wp_from->w_onebuf_opt, &wp_to->w_onebuf_opt);
9715    copy_winopt(&wp_from->w_allbuf_opt, &wp_to->w_allbuf_opt);
9716# ifdef FEAT_RIGHTLEFT
9717#  ifdef FEAT_FKMAP
9718    /* Is this right? */
9719    wp_to->w_farsi = wp_from->w_farsi;
9720#  endif
9721# endif
9722}
9723#endif
9724
9725/*
9726 * Copy the options from one winopt_T to another.
9727 * Doesn't free the old option values in "to", use clear_winopt() for that.
9728 * The 'scroll' option is not copied, because it depends on the window height.
9729 * The 'previewwindow' option is reset, there can be only one preview window.
9730 */
9731    void
9732copy_winopt(from, to)
9733    winopt_T	*from;
9734    winopt_T	*to;
9735{
9736#ifdef FEAT_ARABIC
9737    to->wo_arab = from->wo_arab;
9738#endif
9739    to->wo_list = from->wo_list;
9740    to->wo_nu = from->wo_nu;
9741    to->wo_rnu = from->wo_rnu;
9742#ifdef FEAT_LINEBREAK
9743    to->wo_nuw = from->wo_nuw;
9744#endif
9745#ifdef FEAT_RIGHTLEFT
9746    to->wo_rl  = from->wo_rl;
9747    to->wo_rlc = vim_strsave(from->wo_rlc);
9748#endif
9749#ifdef FEAT_STL_OPT
9750    to->wo_stl = vim_strsave(from->wo_stl);
9751#endif
9752    to->wo_wrap = from->wo_wrap;
9753#ifdef FEAT_LINEBREAK
9754    to->wo_lbr = from->wo_lbr;
9755#endif
9756#ifdef FEAT_SCROLLBIND
9757    to->wo_scb = from->wo_scb;
9758#endif
9759#ifdef FEAT_SPELL
9760    to->wo_spell = from->wo_spell;
9761#endif
9762#ifdef FEAT_SYN_HL
9763    to->wo_cuc = from->wo_cuc;
9764    to->wo_cul = from->wo_cul;
9765    to->wo_cc = vim_strsave(from->wo_cc);
9766#endif
9767#ifdef FEAT_DIFF
9768    to->wo_diff = from->wo_diff;
9769#endif
9770#ifdef FEAT_CONCEAL
9771    to->wo_cocu = vim_strsave(from->wo_cocu);
9772    to->wo_cole = from->wo_cole;
9773#endif
9774#ifdef FEAT_FOLDING
9775    to->wo_fdc = from->wo_fdc;
9776    to->wo_fen = from->wo_fen;
9777    to->wo_fdi = vim_strsave(from->wo_fdi);
9778    to->wo_fml = from->wo_fml;
9779    to->wo_fdl = from->wo_fdl;
9780    to->wo_fdm = vim_strsave(from->wo_fdm);
9781    to->wo_fdn = from->wo_fdn;
9782# ifdef FEAT_EVAL
9783    to->wo_fde = vim_strsave(from->wo_fde);
9784    to->wo_fdt = vim_strsave(from->wo_fdt);
9785# endif
9786    to->wo_fmr = vim_strsave(from->wo_fmr);
9787#endif
9788    check_winopt(to);		/* don't want NULL pointers */
9789}
9790
9791/*
9792 * Check string options in a window for a NULL value.
9793 */
9794    void
9795check_win_options(win)
9796    win_T	*win;
9797{
9798    check_winopt(&win->w_onebuf_opt);
9799    check_winopt(&win->w_allbuf_opt);
9800}
9801
9802/*
9803 * Check for NULL pointers in a winopt_T and replace them with empty_option.
9804 */
9805    void
9806check_winopt(wop)
9807    winopt_T	*wop UNUSED;
9808{
9809#ifdef FEAT_FOLDING
9810    check_string_option(&wop->wo_fdi);
9811    check_string_option(&wop->wo_fdm);
9812# ifdef FEAT_EVAL
9813    check_string_option(&wop->wo_fde);
9814    check_string_option(&wop->wo_fdt);
9815# endif
9816    check_string_option(&wop->wo_fmr);
9817#endif
9818#ifdef FEAT_RIGHTLEFT
9819    check_string_option(&wop->wo_rlc);
9820#endif
9821#ifdef FEAT_STL_OPT
9822    check_string_option(&wop->wo_stl);
9823#endif
9824#ifdef FEAT_SYN_HL
9825    check_string_option(&wop->wo_cc);
9826#endif
9827#ifdef FEAT_CONCEAL
9828    check_string_option(&wop->wo_cocu);
9829#endif
9830}
9831
9832/*
9833 * Free the allocated memory inside a winopt_T.
9834 */
9835    void
9836clear_winopt(wop)
9837    winopt_T	*wop UNUSED;
9838{
9839#ifdef FEAT_FOLDING
9840    clear_string_option(&wop->wo_fdi);
9841    clear_string_option(&wop->wo_fdm);
9842# ifdef FEAT_EVAL
9843    clear_string_option(&wop->wo_fde);
9844    clear_string_option(&wop->wo_fdt);
9845# endif
9846    clear_string_option(&wop->wo_fmr);
9847#endif
9848#ifdef FEAT_RIGHTLEFT
9849    clear_string_option(&wop->wo_rlc);
9850#endif
9851#ifdef FEAT_STL_OPT
9852    clear_string_option(&wop->wo_stl);
9853#endif
9854#ifdef FEAT_SYN_HL
9855    clear_string_option(&wop->wo_cc);
9856#endif
9857#ifdef FEAT_CONCEAL
9858    clear_string_option(&wop->wo_cocu);
9859#endif
9860}
9861
9862/*
9863 * Copy global option values to local options for one buffer.
9864 * Used when creating a new buffer and sometimes when entering a buffer.
9865 * flags:
9866 * BCO_ENTER	We will enter the buf buffer.
9867 * BCO_ALWAYS	Always copy the options, but only set b_p_initialized when
9868 *		appropriate.
9869 * BCO_NOHELP	Don't copy the values to a help buffer.
9870 */
9871    void
9872buf_copy_options(buf, flags)
9873    buf_T	*buf;
9874    int		flags;
9875{
9876    int		should_copy = TRUE;
9877    char_u	*save_p_isk = NULL;	    /* init for GCC */
9878    int		dont_do_help;
9879    int		did_isk = FALSE;
9880
9881    /*
9882     * Don't do anything if the buffer is invalid.
9883     */
9884    if (buf == NULL || !buf_valid(buf))
9885	return;
9886
9887    /*
9888     * Skip this when the option defaults have not been set yet.  Happens when
9889     * main() allocates the first buffer.
9890     */
9891    if (p_cpo != NULL)
9892    {
9893	/*
9894	 * Always copy when entering and 'cpo' contains 'S'.
9895	 * Don't copy when already initialized.
9896	 * Don't copy when 'cpo' contains 's' and not entering.
9897	 * 'S'	BCO_ENTER  initialized	's'  should_copy
9898	 * yes	  yes	       X	 X	TRUE
9899	 * yes	  no	      yes	 X	FALSE
9900	 * no	   X	      yes	 X	FALSE
9901	 *  X	  no	      no	yes	FALSE
9902	 *  X	  no	      no	no	TRUE
9903	 * no	  yes	      no	 X	TRUE
9904	 */
9905	if ((vim_strchr(p_cpo, CPO_BUFOPTGLOB) == NULL || !(flags & BCO_ENTER))
9906		&& (buf->b_p_initialized
9907		    || (!(flags & BCO_ENTER)
9908			&& vim_strchr(p_cpo, CPO_BUFOPT) != NULL)))
9909	    should_copy = FALSE;
9910
9911	if (should_copy || (flags & BCO_ALWAYS))
9912	{
9913	    /* Don't copy the options specific to a help buffer when
9914	     * BCO_NOHELP is given or the options were initialized already
9915	     * (jumping back to a help file with CTRL-T or CTRL-O) */
9916	    dont_do_help = ((flags & BCO_NOHELP) && buf->b_help)
9917						       || buf->b_p_initialized;
9918	    if (dont_do_help)		/* don't free b_p_isk */
9919	    {
9920		save_p_isk = buf->b_p_isk;
9921		buf->b_p_isk = NULL;
9922	    }
9923	    /*
9924	     * Always free the allocated strings.
9925	     * If not already initialized, set 'readonly' and copy 'fileformat'.
9926	     */
9927	    if (!buf->b_p_initialized)
9928	    {
9929		free_buf_options(buf, TRUE);
9930		buf->b_p_ro = FALSE;		/* don't copy readonly */
9931		buf->b_p_tx = p_tx;
9932#ifdef FEAT_MBYTE
9933		buf->b_p_fenc = vim_strsave(p_fenc);
9934#endif
9935		buf->b_p_ff = vim_strsave(p_ff);
9936#if defined(FEAT_QUICKFIX)
9937		buf->b_p_bh = empty_option;
9938		buf->b_p_bt = empty_option;
9939#endif
9940	    }
9941	    else
9942		free_buf_options(buf, FALSE);
9943
9944	    buf->b_p_ai = p_ai;
9945	    buf->b_p_ai_nopaste = p_ai_nopaste;
9946	    buf->b_p_sw = p_sw;
9947	    buf->b_p_tw = p_tw;
9948	    buf->b_p_tw_nopaste = p_tw_nopaste;
9949	    buf->b_p_tw_nobin = p_tw_nobin;
9950	    buf->b_p_wm = p_wm;
9951	    buf->b_p_wm_nopaste = p_wm_nopaste;
9952	    buf->b_p_wm_nobin = p_wm_nobin;
9953	    buf->b_p_bin = p_bin;
9954#ifdef FEAT_MBYTE
9955	    buf->b_p_bomb = p_bomb;
9956#endif
9957	    buf->b_p_et = p_et;
9958	    buf->b_p_et_nobin = p_et_nobin;
9959	    buf->b_p_ml = p_ml;
9960	    buf->b_p_ml_nobin = p_ml_nobin;
9961	    buf->b_p_inf = p_inf;
9962	    buf->b_p_swf = p_swf;
9963#ifdef FEAT_INS_EXPAND
9964	    buf->b_p_cpt = vim_strsave(p_cpt);
9965#endif
9966#ifdef FEAT_COMPL_FUNC
9967	    buf->b_p_cfu = vim_strsave(p_cfu);
9968	    buf->b_p_ofu = vim_strsave(p_ofu);
9969#endif
9970	    buf->b_p_sts = p_sts;
9971	    buf->b_p_sts_nopaste = p_sts_nopaste;
9972#ifndef SHORT_FNAME
9973	    buf->b_p_sn = p_sn;
9974#endif
9975#ifdef FEAT_COMMENTS
9976	    buf->b_p_com = vim_strsave(p_com);
9977#endif
9978#ifdef FEAT_FOLDING
9979	    buf->b_p_cms = vim_strsave(p_cms);
9980#endif
9981	    buf->b_p_fo = vim_strsave(p_fo);
9982	    buf->b_p_flp = vim_strsave(p_flp);
9983	    buf->b_p_nf = vim_strsave(p_nf);
9984	    buf->b_p_mps = vim_strsave(p_mps);
9985#ifdef FEAT_SMARTINDENT
9986	    buf->b_p_si = p_si;
9987#endif
9988	    buf->b_p_ci = p_ci;
9989#ifdef FEAT_CINDENT
9990	    buf->b_p_cin = p_cin;
9991	    buf->b_p_cink = vim_strsave(p_cink);
9992	    buf->b_p_cino = vim_strsave(p_cino);
9993#endif
9994#ifdef FEAT_AUTOCMD
9995	    /* Don't copy 'filetype', it must be detected */
9996	    buf->b_p_ft = empty_option;
9997#endif
9998#ifdef FEAT_OSFILETYPE
9999	    buf->b_p_oft = vim_strsave(p_oft);
10000#endif
10001	    buf->b_p_pi = p_pi;
10002#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
10003	    buf->b_p_cinw = vim_strsave(p_cinw);
10004#endif
10005#ifdef FEAT_LISP
10006	    buf->b_p_lisp = p_lisp;
10007#endif
10008#ifdef FEAT_SYN_HL
10009	    /* Don't copy 'syntax', it must be set */
10010	    buf->b_p_syn = empty_option;
10011	    buf->b_p_smc = p_smc;
10012#endif
10013#ifdef FEAT_SPELL
10014	    buf->b_s.b_p_spc = vim_strsave(p_spf);
10015	    (void)compile_cap_prog(&buf->b_s);
10016	    buf->b_s.b_p_spf = vim_strsave(p_spf);
10017	    buf->b_s.b_p_spl = vim_strsave(p_spl);
10018#endif
10019#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
10020	    buf->b_p_inde = vim_strsave(p_inde);
10021	    buf->b_p_indk = vim_strsave(p_indk);
10022#endif
10023#if defined(FEAT_EVAL)
10024	    buf->b_p_fex = vim_strsave(p_fex);
10025#endif
10026#ifdef FEAT_CRYPT
10027	    buf->b_p_key = vim_strsave(p_key);
10028#endif
10029#ifdef FEAT_SEARCHPATH
10030	    buf->b_p_sua = vim_strsave(p_sua);
10031#endif
10032#ifdef FEAT_KEYMAP
10033	    buf->b_p_keymap = vim_strsave(p_keymap);
10034	    buf->b_kmap_state |= KEYMAP_INIT;
10035#endif
10036	    /* This isn't really an option, but copying the langmap and IME
10037	     * state from the current buffer is better than resetting it. */
10038	    buf->b_p_iminsert = p_iminsert;
10039	    buf->b_p_imsearch = p_imsearch;
10040
10041	    /* options that are normally global but also have a local value
10042	     * are not copied, start using the global value */
10043	    buf->b_p_ar = -1;
10044#ifdef FEAT_QUICKFIX
10045	    buf->b_p_gp = empty_option;
10046	    buf->b_p_mp = empty_option;
10047	    buf->b_p_efm = empty_option;
10048#endif
10049	    buf->b_p_ep = empty_option;
10050	    buf->b_p_kp = empty_option;
10051	    buf->b_p_path = empty_option;
10052	    buf->b_p_tags = empty_option;
10053#ifdef FEAT_FIND_ID
10054	    buf->b_p_def = empty_option;
10055	    buf->b_p_inc = empty_option;
10056# ifdef FEAT_EVAL
10057	    buf->b_p_inex = vim_strsave(p_inex);
10058# endif
10059#endif
10060#ifdef FEAT_INS_EXPAND
10061	    buf->b_p_dict = empty_option;
10062	    buf->b_p_tsr = empty_option;
10063#endif
10064#ifdef FEAT_TEXTOBJ
10065	    buf->b_p_qe = vim_strsave(p_qe);
10066#endif
10067#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
10068	    buf->b_p_bexpr = empty_option;
10069#endif
10070#if defined(FEAT_CRYPT)
10071	    buf->b_p_cm = empty_option;
10072#endif
10073#ifdef FEAT_PERSISTENT_UNDO
10074	    buf->b_p_udf = p_udf;
10075#endif
10076
10077	    /*
10078	     * Don't copy the options set by ex_help(), use the saved values,
10079	     * when going from a help buffer to a non-help buffer.
10080	     * Don't touch these at all when BCO_NOHELP is used and going from
10081	     * or to a help buffer.
10082	     */
10083	    if (dont_do_help)
10084		buf->b_p_isk = save_p_isk;
10085	    else
10086	    {
10087		buf->b_p_isk = vim_strsave(p_isk);
10088		did_isk = TRUE;
10089		buf->b_p_ts = p_ts;
10090		buf->b_help = FALSE;
10091#ifdef FEAT_QUICKFIX
10092		if (buf->b_p_bt[0] == 'h')
10093		    clear_string_option(&buf->b_p_bt);
10094#endif
10095		buf->b_p_ma = p_ma;
10096	    }
10097	}
10098
10099	/*
10100	 * When the options should be copied (ignoring BCO_ALWAYS), set the
10101	 * flag that indicates that the options have been initialized.
10102	 */
10103	if (should_copy)
10104	    buf->b_p_initialized = TRUE;
10105    }
10106
10107    check_buf_options(buf);	    /* make sure we don't have NULLs */
10108    if (did_isk)
10109	(void)buf_init_chartab(buf, FALSE);
10110}
10111
10112/*
10113 * Reset the 'modifiable' option and its default value.
10114 */
10115    void
10116reset_modifiable()
10117{
10118    int		opt_idx;
10119
10120    curbuf->b_p_ma = FALSE;
10121    p_ma = FALSE;
10122    opt_idx = findoption((char_u *)"ma");
10123    if (opt_idx >= 0)
10124	options[opt_idx].def_val[VI_DEFAULT] = FALSE;
10125}
10126
10127/*
10128 * Set the global value for 'iminsert' to the local value.
10129 */
10130    void
10131set_iminsert_global()
10132{
10133    p_iminsert = curbuf->b_p_iminsert;
10134}
10135
10136/*
10137 * Set the global value for 'imsearch' to the local value.
10138 */
10139    void
10140set_imsearch_global()
10141{
10142    p_imsearch = curbuf->b_p_imsearch;
10143}
10144
10145#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
10146static int expand_option_idx = -1;
10147static char_u expand_option_name[5] = {'t', '_', NUL, NUL, NUL};
10148static int expand_option_flags = 0;
10149
10150    void
10151set_context_in_set_cmd(xp, arg, opt_flags)
10152    expand_T	*xp;
10153    char_u	*arg;
10154    int		opt_flags;	/* OPT_GLOBAL and/or OPT_LOCAL */
10155{
10156    int		nextchar;
10157    long_u	flags = 0;	/* init for GCC */
10158    int		opt_idx = 0;	/* init for GCC */
10159    char_u	*p;
10160    char_u	*s;
10161    int		is_term_option = FALSE;
10162    int		key;
10163
10164    expand_option_flags = opt_flags;
10165
10166    xp->xp_context = EXPAND_SETTINGS;
10167    if (*arg == NUL)
10168    {
10169	xp->xp_pattern = arg;
10170	return;
10171    }
10172    p = arg + STRLEN(arg) - 1;
10173    if (*p == ' ' && *(p - 1) != '\\')
10174    {
10175	xp->xp_pattern = p + 1;
10176	return;
10177    }
10178    while (p > arg)
10179    {
10180	s = p;
10181	/* count number of backslashes before ' ' or ',' */
10182	if (*p == ' ' || *p == ',')
10183	{
10184	    while (s > arg && *(s - 1) == '\\')
10185		--s;
10186	}
10187	/* break at a space with an even number of backslashes */
10188	if (*p == ' ' && ((p - s) & 1) == 0)
10189	{
10190	    ++p;
10191	    break;
10192	}
10193	--p;
10194    }
10195    if (STRNCMP(p, "no", 2) == 0 && STRNCMP(p, "novice", 6) != 0)
10196    {
10197	xp->xp_context = EXPAND_BOOL_SETTINGS;
10198	p += 2;
10199    }
10200    if (STRNCMP(p, "inv", 3) == 0)
10201    {
10202	xp->xp_context = EXPAND_BOOL_SETTINGS;
10203	p += 3;
10204    }
10205    xp->xp_pattern = arg = p;
10206    if (*arg == '<')
10207    {
10208	while (*p != '>')
10209	    if (*p++ == NUL)	    /* expand terminal option name */
10210		return;
10211	key = get_special_key_code(arg + 1);
10212	if (key == 0)		    /* unknown name */
10213	{
10214	    xp->xp_context = EXPAND_NOTHING;
10215	    return;
10216	}
10217	nextchar = *++p;
10218	is_term_option = TRUE;
10219	expand_option_name[2] = KEY2TERMCAP0(key);
10220	expand_option_name[3] = KEY2TERMCAP1(key);
10221    }
10222    else
10223    {
10224	if (p[0] == 't' && p[1] == '_')
10225	{
10226	    p += 2;
10227	    if (*p != NUL)
10228		++p;
10229	    if (*p == NUL)
10230		return;		/* expand option name */
10231	    nextchar = *++p;
10232	    is_term_option = TRUE;
10233	    expand_option_name[2] = p[-2];
10234	    expand_option_name[3] = p[-1];
10235	}
10236	else
10237	{
10238		/* Allow * wildcard */
10239	    while (ASCII_ISALNUM(*p) || *p == '_' || *p == '*')
10240		p++;
10241	    if (*p == NUL)
10242		return;
10243	    nextchar = *p;
10244	    *p = NUL;
10245	    opt_idx = findoption(arg);
10246	    *p = nextchar;
10247	    if (opt_idx == -1 || options[opt_idx].var == NULL)
10248	    {
10249		xp->xp_context = EXPAND_NOTHING;
10250		return;
10251	    }
10252	    flags = options[opt_idx].flags;
10253	    if (flags & P_BOOL)
10254	    {
10255		xp->xp_context = EXPAND_NOTHING;
10256		return;
10257	    }
10258	}
10259    }
10260    /* handle "-=" and "+=" */
10261    if ((nextchar == '-' || nextchar == '+' || nextchar == '^') && p[1] == '=')
10262    {
10263	++p;
10264	nextchar = '=';
10265    }
10266    if ((nextchar != '=' && nextchar != ':')
10267				    || xp->xp_context == EXPAND_BOOL_SETTINGS)
10268    {
10269	xp->xp_context = EXPAND_UNSUCCESSFUL;
10270	return;
10271    }
10272    if (xp->xp_context != EXPAND_BOOL_SETTINGS && p[1] == NUL)
10273    {
10274	xp->xp_context = EXPAND_OLD_SETTING;
10275	if (is_term_option)
10276	    expand_option_idx = -1;
10277	else
10278	    expand_option_idx = opt_idx;
10279	xp->xp_pattern = p + 1;
10280	return;
10281    }
10282    xp->xp_context = EXPAND_NOTHING;
10283    if (is_term_option || (flags & P_NUM))
10284	return;
10285
10286    xp->xp_pattern = p + 1;
10287
10288    if (flags & P_EXPAND)
10289    {
10290	p = options[opt_idx].var;
10291	if (p == (char_u *)&p_bdir
10292		|| p == (char_u *)&p_dir
10293		|| p == (char_u *)&p_path
10294		|| p == (char_u *)&p_rtp
10295#ifdef FEAT_SEARCHPATH
10296		|| p == (char_u *)&p_cdpath
10297#endif
10298#ifdef FEAT_SESSION
10299		|| p == (char_u *)&p_vdir
10300#endif
10301		)
10302	{
10303	    xp->xp_context = EXPAND_DIRECTORIES;
10304	    if (p == (char_u *)&p_path
10305#ifdef FEAT_SEARCHPATH
10306		    || p == (char_u *)&p_cdpath
10307#endif
10308		   )
10309		xp->xp_backslash = XP_BS_THREE;
10310	    else
10311		xp->xp_backslash = XP_BS_ONE;
10312	}
10313	else
10314	{
10315	    xp->xp_context = EXPAND_FILES;
10316	    /* for 'tags' need three backslashes for a space */
10317	    if (p == (char_u *)&p_tags)
10318		xp->xp_backslash = XP_BS_THREE;
10319	    else
10320		xp->xp_backslash = XP_BS_ONE;
10321	}
10322    }
10323
10324    /* For an option that is a list of file names, find the start of the
10325     * last file name. */
10326    for (p = arg + STRLEN(arg) - 1; p > xp->xp_pattern; --p)
10327    {
10328	/* count number of backslashes before ' ' or ',' */
10329	if (*p == ' ' || *p == ',')
10330	{
10331	    s = p;
10332	    while (s > xp->xp_pattern && *(s - 1) == '\\')
10333		--s;
10334	    if ((*p == ' ' && (xp->xp_backslash == XP_BS_THREE && (p - s) < 3))
10335		    || (*p == ',' && (flags & P_COMMA) && ((p - s) & 1) == 0))
10336	    {
10337		xp->xp_pattern = p + 1;
10338		break;
10339	    }
10340	}
10341
10342#ifdef FEAT_SPELL
10343	/* for 'spellsuggest' start at "file:" */
10344	if (options[opt_idx].var == (char_u *)&p_sps
10345					       && STRNCMP(p, "file:", 5) == 0)
10346	{
10347	    xp->xp_pattern = p + 5;
10348	    break;
10349	}
10350#endif
10351    }
10352
10353    return;
10354}
10355
10356    int
10357ExpandSettings(xp, regmatch, num_file, file)
10358    expand_T	*xp;
10359    regmatch_T	*regmatch;
10360    int		*num_file;
10361    char_u	***file;
10362{
10363    int		num_normal = 0;	    /* Nr of matching non-term-code settings */
10364    int		num_term = 0;	    /* Nr of matching terminal code settings */
10365    int		opt_idx;
10366    int		match;
10367    int		count = 0;
10368    char_u	*str;
10369    int		loop;
10370    int		is_term_opt;
10371    char_u	name_buf[MAX_KEY_NAME_LEN];
10372    static char *(names[]) = {"all", "termcap"};
10373    int		ic = regmatch->rm_ic;	/* remember the ignore-case flag */
10374
10375    /* do this loop twice:
10376     * loop == 0: count the number of matching options
10377     * loop == 1: copy the matching options into allocated memory
10378     */
10379    for (loop = 0; loop <= 1; ++loop)
10380    {
10381	regmatch->rm_ic = ic;
10382	if (xp->xp_context != EXPAND_BOOL_SETTINGS)
10383	{
10384	    for (match = 0; match < (int)(sizeof(names) / sizeof(char *));
10385								      ++match)
10386		if (vim_regexec(regmatch, (char_u *)names[match], (colnr_T)0))
10387		{
10388		    if (loop == 0)
10389			num_normal++;
10390		    else
10391			(*file)[count++] = vim_strsave((char_u *)names[match]);
10392		}
10393	}
10394	for (opt_idx = 0; (str = (char_u *)options[opt_idx].fullname) != NULL;
10395								    opt_idx++)
10396	{
10397	    if (options[opt_idx].var == NULL)
10398		continue;
10399	    if (xp->xp_context == EXPAND_BOOL_SETTINGS
10400	      && !(options[opt_idx].flags & P_BOOL))
10401		continue;
10402	    is_term_opt = istermoption(&options[opt_idx]);
10403	    if (is_term_opt && num_normal > 0)
10404		continue;
10405	    match = FALSE;
10406	    if (vim_regexec(regmatch, str, (colnr_T)0)
10407		    || (options[opt_idx].shortname != NULL
10408			&& vim_regexec(regmatch,
10409			   (char_u *)options[opt_idx].shortname, (colnr_T)0)))
10410		match = TRUE;
10411	    else if (is_term_opt)
10412	    {
10413		name_buf[0] = '<';
10414		name_buf[1] = 't';
10415		name_buf[2] = '_';
10416		name_buf[3] = str[2];
10417		name_buf[4] = str[3];
10418		name_buf[5] = '>';
10419		name_buf[6] = NUL;
10420		if (vim_regexec(regmatch, name_buf, (colnr_T)0))
10421		{
10422		    match = TRUE;
10423		    str = name_buf;
10424		}
10425	    }
10426	    if (match)
10427	    {
10428		if (loop == 0)
10429		{
10430		    if (is_term_opt)
10431			num_term++;
10432		    else
10433			num_normal++;
10434		}
10435		else
10436		    (*file)[count++] = vim_strsave(str);
10437	    }
10438	}
10439	/*
10440	 * Check terminal key codes, these are not in the option table
10441	 */
10442	if (xp->xp_context != EXPAND_BOOL_SETTINGS  && num_normal == 0)
10443	{
10444	    for (opt_idx = 0; (str = get_termcode(opt_idx)) != NULL; opt_idx++)
10445	    {
10446		if (!isprint(str[0]) || !isprint(str[1]))
10447		    continue;
10448
10449		name_buf[0] = 't';
10450		name_buf[1] = '_';
10451		name_buf[2] = str[0];
10452		name_buf[3] = str[1];
10453		name_buf[4] = NUL;
10454
10455		match = FALSE;
10456		if (vim_regexec(regmatch, name_buf, (colnr_T)0))
10457		    match = TRUE;
10458		else
10459		{
10460		    name_buf[0] = '<';
10461		    name_buf[1] = 't';
10462		    name_buf[2] = '_';
10463		    name_buf[3] = str[0];
10464		    name_buf[4] = str[1];
10465		    name_buf[5] = '>';
10466		    name_buf[6] = NUL;
10467
10468		    if (vim_regexec(regmatch, name_buf, (colnr_T)0))
10469			match = TRUE;
10470		}
10471		if (match)
10472		{
10473		    if (loop == 0)
10474			num_term++;
10475		    else
10476			(*file)[count++] = vim_strsave(name_buf);
10477		}
10478	    }
10479
10480	    /*
10481	     * Check special key names.
10482	     */
10483	    regmatch->rm_ic = TRUE;		/* ignore case here */
10484	    for (opt_idx = 0; (str = get_key_name(opt_idx)) != NULL; opt_idx++)
10485	    {
10486		name_buf[0] = '<';
10487		STRCPY(name_buf + 1, str);
10488		STRCAT(name_buf, ">");
10489
10490		if (vim_regexec(regmatch, name_buf, (colnr_T)0))
10491		{
10492		    if (loop == 0)
10493			num_term++;
10494		    else
10495			(*file)[count++] = vim_strsave(name_buf);
10496		}
10497	    }
10498	}
10499	if (loop == 0)
10500	{
10501	    if (num_normal > 0)
10502		*num_file = num_normal;
10503	    else if (num_term > 0)
10504		*num_file = num_term;
10505	    else
10506		return OK;
10507	    *file = (char_u **)alloc((unsigned)(*num_file * sizeof(char_u *)));
10508	    if (*file == NULL)
10509	    {
10510		*file = (char_u **)"";
10511		return FAIL;
10512	    }
10513	}
10514    }
10515    return OK;
10516}
10517
10518    int
10519ExpandOldSetting(num_file, file)
10520    int	    *num_file;
10521    char_u  ***file;
10522{
10523    char_u  *var = NULL;	/* init for GCC */
10524    char_u  *buf;
10525
10526    *num_file = 0;
10527    *file = (char_u **)alloc((unsigned)sizeof(char_u *));
10528    if (*file == NULL)
10529	return FAIL;
10530
10531    /*
10532     * For a terminal key code expand_option_idx is < 0.
10533     */
10534    if (expand_option_idx < 0)
10535    {
10536	var = find_termcode(expand_option_name + 2);
10537	if (var == NULL)
10538	    expand_option_idx = findoption(expand_option_name);
10539    }
10540
10541    if (expand_option_idx >= 0)
10542    {
10543	/* put string of option value in NameBuff */
10544	option_value2string(&options[expand_option_idx], expand_option_flags);
10545	var = NameBuff;
10546    }
10547    else if (var == NULL)
10548	var = (char_u *)"";
10549
10550    /* A backslash is required before some characters.  This is the reverse of
10551     * what happens in do_set(). */
10552    buf = vim_strsave_escaped(var, escape_chars);
10553
10554    if (buf == NULL)
10555    {
10556	vim_free(*file);
10557	*file = NULL;
10558	return FAIL;
10559    }
10560
10561#ifdef BACKSLASH_IN_FILENAME
10562    /* For MS-Windows et al. we don't double backslashes at the start and
10563     * before a file name character. */
10564    for (var = buf; *var != NUL; mb_ptr_adv(var))
10565	if (var[0] == '\\' && var[1] == '\\'
10566		&& expand_option_idx >= 0
10567		&& (options[expand_option_idx].flags & P_EXPAND)
10568		&& vim_isfilec(var[2])
10569		&& (var[2] != '\\' || (var == buf && var[4] != '\\')))
10570	    STRMOVE(var, var + 1);
10571#endif
10572
10573    *file[0] = buf;
10574    *num_file = 1;
10575    return OK;
10576}
10577#endif
10578
10579/*
10580 * Get the value for the numeric or string option *opp in a nice format into
10581 * NameBuff[].  Must not be called with a hidden option!
10582 */
10583    static void
10584option_value2string(opp, opt_flags)
10585    struct vimoption	*opp;
10586    int			opt_flags;	/* OPT_GLOBAL and/or OPT_LOCAL */
10587{
10588    char_u	*varp;
10589
10590    varp = get_varp_scope(opp, opt_flags);
10591
10592    if (opp->flags & P_NUM)
10593    {
10594	long wc = 0;
10595
10596	if (wc_use_keyname(varp, &wc))
10597	    STRCPY(NameBuff, get_special_key_name((int)wc, 0));
10598	else if (wc != 0)
10599	    STRCPY(NameBuff, transchar((int)wc));
10600	else
10601	    sprintf((char *)NameBuff, "%ld", *(long *)varp);
10602    }
10603    else    /* P_STRING */
10604    {
10605	varp = *(char_u **)(varp);
10606	if (varp == NULL)		    /* just in case */
10607	    NameBuff[0] = NUL;
10608#ifdef FEAT_CRYPT
10609	/* don't show the actual value of 'key', only that it's set */
10610	else if (opp->var == (char_u *)&p_key && *varp)
10611	    STRCPY(NameBuff, "*****");
10612#endif
10613	else if (opp->flags & P_EXPAND)
10614	    home_replace(NULL, varp, NameBuff, MAXPATHL, FALSE);
10615	/* Translate 'pastetoggle' into special key names */
10616	else if ((char_u **)opp->var == &p_pt)
10617	    str2specialbuf(p_pt, NameBuff, MAXPATHL);
10618	else
10619	    vim_strncpy(NameBuff, varp, MAXPATHL - 1);
10620    }
10621}
10622
10623/*
10624 * Return TRUE if "varp" points to 'wildchar' or 'wildcharm' and it can be
10625 * printed as a keyname.
10626 * "*wcp" is set to the value of the option if it's 'wildchar' or 'wildcharm'.
10627 */
10628    static int
10629wc_use_keyname(varp, wcp)
10630    char_u	*varp;
10631    long	*wcp;
10632{
10633    if (((long *)varp == &p_wc) || ((long *)varp == &p_wcm))
10634    {
10635	*wcp = *(long *)varp;
10636	if (IS_SPECIAL(*wcp) || find_special_key_in_table((int)*wcp) >= 0)
10637	    return TRUE;
10638    }
10639    return FALSE;
10640}
10641
10642#ifdef FEAT_LANGMAP
10643/*
10644 * Any character has an equivalent 'langmap' character.  This is used for
10645 * keyboards that have a special language mode that sends characters above
10646 * 128 (although other characters can be translated too).  The "to" field is a
10647 * Vim command character.  This avoids having to switch the keyboard back to
10648 * ASCII mode when leaving Insert mode.
10649 *
10650 * langmap_mapchar[] maps any of 256 chars to an ASCII char used for Vim
10651 * commands.
10652 * When FEAT_MBYTE is defined langmap_mapga.ga_data is a sorted table of
10653 * langmap_entry_T.  This does the same as langmap_mapchar[] for characters >=
10654 * 256.
10655 */
10656# ifdef FEAT_MBYTE
10657/*
10658 * With multi-byte support use growarray for 'langmap' chars >= 256
10659 */
10660typedef struct
10661{
10662    int	    from;
10663    int     to;
10664} langmap_entry_T;
10665
10666static garray_T langmap_mapga;
10667static void langmap_set_entry __ARGS((int from, int to));
10668
10669/*
10670 * Search for an entry in "langmap_mapga" for "from".  If found set the "to"
10671 * field.  If not found insert a new entry at the appropriate location.
10672 */
10673    static void
10674langmap_set_entry(from, to)
10675    int    from;
10676    int    to;
10677{
10678    langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data);
10679    int		    a = 0;
10680    int		    b = langmap_mapga.ga_len;
10681
10682    /* Do a binary search for an existing entry. */
10683    while (a != b)
10684    {
10685	int i = (a + b) / 2;
10686	int d = entries[i].from - from;
10687
10688	if (d == 0)
10689	{
10690	    entries[i].to = to;
10691	    return;
10692	}
10693	if (d < 0)
10694	    a = i + 1;
10695	else
10696	    b = i;
10697    }
10698
10699    if (ga_grow(&langmap_mapga, 1) != OK)
10700	return;  /* out of memory */
10701
10702    /* insert new entry at position "a" */
10703    entries = (langmap_entry_T *)(langmap_mapga.ga_data) + a;
10704    mch_memmove(entries + 1, entries,
10705			(langmap_mapga.ga_len - a) * sizeof(langmap_entry_T));
10706    ++langmap_mapga.ga_len;
10707    entries[0].from = from;
10708    entries[0].to = to;
10709}
10710
10711/*
10712 * Apply 'langmap' to multi-byte character "c" and return the result.
10713 */
10714    int
10715langmap_adjust_mb(c)
10716    int c;
10717{
10718    langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data);
10719    int a = 0;
10720    int b = langmap_mapga.ga_len;
10721
10722    while (a != b)
10723    {
10724	int i = (a + b) / 2;
10725	int d = entries[i].from - c;
10726
10727	if (d == 0)
10728	    return entries[i].to;  /* found matching entry */
10729	if (d < 0)
10730	    a = i + 1;
10731	else
10732	    b = i;
10733    }
10734    return c;  /* no entry found, return "c" unmodified */
10735}
10736# endif
10737
10738    static void
10739langmap_init()
10740{
10741    int i;
10742
10743    for (i = 0; i < 256; i++)
10744	langmap_mapchar[i] = i;	 /* we init with a one-to-one map */
10745# ifdef FEAT_MBYTE
10746    ga_init2(&langmap_mapga, sizeof(langmap_entry_T), 8);
10747# endif
10748}
10749
10750/*
10751 * Called when langmap option is set; the language map can be
10752 * changed at any time!
10753 */
10754    static void
10755langmap_set()
10756{
10757    char_u  *p;
10758    char_u  *p2;
10759    int	    from, to;
10760
10761#ifdef FEAT_MBYTE
10762    ga_clear(&langmap_mapga);		    /* clear the previous map first */
10763#endif
10764    langmap_init();			    /* back to one-to-one map */
10765
10766    for (p = p_langmap; p[0] != NUL; )
10767    {
10768	for (p2 = p; p2[0] != NUL && p2[0] != ',' && p2[0] != ';';
10769							       mb_ptr_adv(p2))
10770	{
10771	    if (p2[0] == '\\' && p2[1] != NUL)
10772		++p2;
10773	}
10774	if (p2[0] == ';')
10775	    ++p2;	    /* abcd;ABCD form, p2 points to A */
10776	else
10777	    p2 = NULL;	    /* aAbBcCdD form, p2 is NULL */
10778	while (p[0])
10779	{
10780	    if (p[0] == ',')
10781	    {
10782		++p;
10783		break;
10784	    }
10785	    if (p[0] == '\\' && p[1] != NUL)
10786		++p;
10787#ifdef FEAT_MBYTE
10788	    from = (*mb_ptr2char)(p);
10789#else
10790	    from = p[0];
10791#endif
10792	    to = NUL;
10793	    if (p2 == NULL)
10794	    {
10795		mb_ptr_adv(p);
10796		if (p[0] != ',')
10797		{
10798		    if (p[0] == '\\')
10799			++p;
10800#ifdef FEAT_MBYTE
10801		    to = (*mb_ptr2char)(p);
10802#else
10803		    to = p[0];
10804#endif
10805		}
10806	    }
10807	    else
10808	    {
10809		if (p2[0] != ',')
10810		{
10811		    if (p2[0] == '\\')
10812			++p2;
10813#ifdef FEAT_MBYTE
10814		    to = (*mb_ptr2char)(p2);
10815#else
10816		    to = p2[0];
10817#endif
10818		}
10819	    }
10820	    if (to == NUL)
10821	    {
10822		EMSG2(_("E357: 'langmap': Matching character missing for %s"),
10823							     transchar(from));
10824		return;
10825	    }
10826
10827#ifdef FEAT_MBYTE
10828	    if (from >= 256)
10829		langmap_set_entry(from, to);
10830	    else
10831#endif
10832		langmap_mapchar[from & 255] = to;
10833
10834	    /* Advance to next pair */
10835	    mb_ptr_adv(p);
10836	    if (p2 != NULL)
10837	    {
10838		mb_ptr_adv(p2);
10839		if (*p == ';')
10840		{
10841		    p = p2;
10842		    if (p[0] != NUL)
10843		    {
10844			if (p[0] != ',')
10845			{
10846			    EMSG2(_("E358: 'langmap': Extra characters after semicolon: %s"), p);
10847			    return;
10848			}
10849			++p;
10850		    }
10851		    break;
10852		}
10853	    }
10854	}
10855    }
10856}
10857#endif
10858
10859/*
10860 * Return TRUE if format option 'x' is in effect.
10861 * Take care of no formatting when 'paste' is set.
10862 */
10863    int
10864has_format_option(x)
10865    int		x;
10866{
10867    if (p_paste)
10868	return FALSE;
10869    return (vim_strchr(curbuf->b_p_fo, x) != NULL);
10870}
10871
10872/*
10873 * Return TRUE if "x" is present in 'shortmess' option, or
10874 * 'shortmess' contains 'a' and "x" is present in SHM_A.
10875 */
10876    int
10877shortmess(x)
10878    int	    x;
10879{
10880    return (   vim_strchr(p_shm, x) != NULL
10881	    || (vim_strchr(p_shm, 'a') != NULL
10882		&& vim_strchr((char_u *)SHM_A, x) != NULL));
10883}
10884
10885/*
10886 * paste_option_changed() - Called after p_paste was set or reset.
10887 */
10888    static void
10889paste_option_changed()
10890{
10891    static int	old_p_paste = FALSE;
10892    static int	save_sm = 0;
10893#ifdef FEAT_CMDL_INFO
10894    static int	save_ru = 0;
10895#endif
10896#ifdef FEAT_RIGHTLEFT
10897    static int	save_ri = 0;
10898    static int	save_hkmap = 0;
10899#endif
10900    buf_T	*buf;
10901
10902    if (p_paste)
10903    {
10904	/*
10905	 * Paste switched from off to on.
10906	 * Save the current values, so they can be restored later.
10907	 */
10908	if (!old_p_paste)
10909	{
10910	    /* save options for each buffer */
10911	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
10912	    {
10913		buf->b_p_tw_nopaste = buf->b_p_tw;
10914		buf->b_p_wm_nopaste = buf->b_p_wm;
10915		buf->b_p_sts_nopaste = buf->b_p_sts;
10916		buf->b_p_ai_nopaste = buf->b_p_ai;
10917	    }
10918
10919	    /* save global options */
10920	    save_sm = p_sm;
10921#ifdef FEAT_CMDL_INFO
10922	    save_ru = p_ru;
10923#endif
10924#ifdef FEAT_RIGHTLEFT
10925	    save_ri = p_ri;
10926	    save_hkmap = p_hkmap;
10927#endif
10928	    /* save global values for local buffer options */
10929	    p_tw_nopaste = p_tw;
10930	    p_wm_nopaste = p_wm;
10931	    p_sts_nopaste = p_sts;
10932	    p_ai_nopaste = p_ai;
10933	}
10934
10935	/*
10936	 * Always set the option values, also when 'paste' is set when it is
10937	 * already on.
10938	 */
10939	/* set options for each buffer */
10940	for (buf = firstbuf; buf != NULL; buf = buf->b_next)
10941	{
10942	    buf->b_p_tw = 0;	    /* textwidth is 0 */
10943	    buf->b_p_wm = 0;	    /* wrapmargin is 0 */
10944	    buf->b_p_sts = 0;	    /* softtabstop is 0 */
10945	    buf->b_p_ai = 0;	    /* no auto-indent */
10946	}
10947
10948	/* set global options */
10949	p_sm = 0;		    /* no showmatch */
10950#ifdef FEAT_CMDL_INFO
10951# ifdef FEAT_WINDOWS
10952	if (p_ru)
10953	    status_redraw_all();    /* redraw to remove the ruler */
10954# endif
10955	p_ru = 0;		    /* no ruler */
10956#endif
10957#ifdef FEAT_RIGHTLEFT
10958	p_ri = 0;		    /* no reverse insert */
10959	p_hkmap = 0;		    /* no Hebrew keyboard */
10960#endif
10961	/* set global values for local buffer options */
10962	p_tw = 0;
10963	p_wm = 0;
10964	p_sts = 0;
10965	p_ai = 0;
10966    }
10967
10968    /*
10969     * Paste switched from on to off: Restore saved values.
10970     */
10971    else if (old_p_paste)
10972    {
10973	/* restore options for each buffer */
10974	for (buf = firstbuf; buf != NULL; buf = buf->b_next)
10975	{
10976	    buf->b_p_tw = buf->b_p_tw_nopaste;
10977	    buf->b_p_wm = buf->b_p_wm_nopaste;
10978	    buf->b_p_sts = buf->b_p_sts_nopaste;
10979	    buf->b_p_ai = buf->b_p_ai_nopaste;
10980	}
10981
10982	/* restore global options */
10983	p_sm = save_sm;
10984#ifdef FEAT_CMDL_INFO
10985# ifdef FEAT_WINDOWS
10986	if (p_ru != save_ru)
10987	    status_redraw_all();    /* redraw to draw the ruler */
10988# endif
10989	p_ru = save_ru;
10990#endif
10991#ifdef FEAT_RIGHTLEFT
10992	p_ri = save_ri;
10993	p_hkmap = save_hkmap;
10994#endif
10995	/* set global values for local buffer options */
10996	p_tw = p_tw_nopaste;
10997	p_wm = p_wm_nopaste;
10998	p_sts = p_sts_nopaste;
10999	p_ai = p_ai_nopaste;
11000    }
11001
11002    old_p_paste = p_paste;
11003}
11004
11005/*
11006 * vimrc_found() - Called when a ".vimrc" or "VIMINIT" has been found.
11007 *
11008 * Reset 'compatible' and set the values for options that didn't get set yet
11009 * to the Vim defaults.
11010 * Don't do this if the 'compatible' option has been set or reset before.
11011 * When "fname" is not NULL, use it to set $"envname" when it wasn't set yet.
11012 */
11013    void
11014vimrc_found(fname, envname)
11015    char_u	*fname;
11016    char_u	*envname;
11017{
11018    int		opt_idx;
11019    int		dofree = FALSE;
11020    char_u	*p;
11021
11022    if (!option_was_set((char_u *)"cp"))
11023    {
11024	p_cp = FALSE;
11025	for (opt_idx = 0; !istermoption(&options[opt_idx]); opt_idx++)
11026	    if (!(options[opt_idx].flags & (P_WAS_SET|P_VI_DEF)))
11027		set_option_default(opt_idx, OPT_FREE, FALSE);
11028	didset_options();
11029    }
11030
11031    if (fname != NULL)
11032    {
11033	p = vim_getenv(envname, &dofree);
11034	if (p == NULL)
11035	{
11036	    /* Set $MYVIMRC to the first vimrc file found. */
11037	    p = FullName_save(fname, FALSE);
11038	    if (p != NULL)
11039	    {
11040		vim_setenv(envname, p);
11041		vim_free(p);
11042	    }
11043	}
11044	else if (dofree)
11045	    vim_free(p);
11046    }
11047}
11048
11049/*
11050 * Set 'compatible' on or off.  Called for "-C" and "-N" command line arg.
11051 */
11052    void
11053change_compatible(on)
11054    int	    on;
11055{
11056    int	    opt_idx;
11057
11058    if (p_cp != on)
11059    {
11060	p_cp = on;
11061	compatible_set();
11062    }
11063    opt_idx = findoption((char_u *)"cp");
11064    if (opt_idx >= 0)
11065	options[opt_idx].flags |= P_WAS_SET;
11066}
11067
11068/*
11069 * Return TRUE when option "name" has been set.
11070 */
11071    int
11072option_was_set(name)
11073    char_u	*name;
11074{
11075    int idx;
11076
11077    idx = findoption(name);
11078    if (idx < 0)	/* unknown option */
11079	return FALSE;
11080    if (options[idx].flags & P_WAS_SET)
11081	return TRUE;
11082    return FALSE;
11083}
11084
11085/*
11086 * compatible_set() - Called when 'compatible' has been set or unset.
11087 *
11088 * When 'compatible' set: Set all relevant options (those that have the P_VIM)
11089 * flag) to a Vi compatible value.
11090 * When 'compatible' is unset: Set all options that have a different default
11091 * for Vim (without the P_VI_DEF flag) to that default.
11092 */
11093    static void
11094compatible_set()
11095{
11096    int	    opt_idx;
11097
11098    for (opt_idx = 0; !istermoption(&options[opt_idx]); opt_idx++)
11099	if (	   ((options[opt_idx].flags & P_VIM) && p_cp)
11100		|| (!(options[opt_idx].flags & P_VI_DEF) && !p_cp))
11101	    set_option_default(opt_idx, OPT_FREE, p_cp);
11102    didset_options();
11103}
11104
11105#ifdef FEAT_LINEBREAK
11106
11107# if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
11108   /* Borland C++ screws up loop optimisation here (negri) */
11109  #pragma option -O-l
11110# endif
11111
11112/*
11113 * fill_breakat_flags() -- called when 'breakat' changes value.
11114 */
11115    static void
11116fill_breakat_flags()
11117{
11118    char_u	*p;
11119    int		i;
11120
11121    for (i = 0; i < 256; i++)
11122	breakat_flags[i] = FALSE;
11123
11124    if (p_breakat != NULL)
11125	for (p = p_breakat; *p; p++)
11126	    breakat_flags[*p] = TRUE;
11127}
11128
11129# if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
11130  #pragma option -O.l
11131# endif
11132
11133#endif
11134
11135/*
11136 * Check an option that can be a range of string values.
11137 *
11138 * Return OK for correct value, FAIL otherwise.
11139 * Empty is always OK.
11140 */
11141    static int
11142check_opt_strings(val, values, list)
11143    char_u	*val;
11144    char	**values;
11145    int		list;	    /* when TRUE: accept a list of values */
11146{
11147    return opt_strings_flags(val, values, NULL, list);
11148}
11149
11150/*
11151 * Handle an option that can be a range of string values.
11152 * Set a flag in "*flagp" for each string present.
11153 *
11154 * Return OK for correct value, FAIL otherwise.
11155 * Empty is always OK.
11156 */
11157    static int
11158opt_strings_flags(val, values, flagp, list)
11159    char_u	*val;		/* new value */
11160    char	**values;	/* array of valid string values */
11161    unsigned	*flagp;
11162    int		list;		/* when TRUE: accept a list of values */
11163{
11164    int		i;
11165    int		len;
11166    unsigned	new_flags = 0;
11167
11168    while (*val)
11169    {
11170	for (i = 0; ; ++i)
11171	{
11172	    if (values[i] == NULL)	/* val not found in values[] */
11173		return FAIL;
11174
11175	    len = (int)STRLEN(values[i]);
11176	    if (STRNCMP(values[i], val, len) == 0
11177		    && ((list && val[len] == ',') || val[len] == NUL))
11178	    {
11179		val += len + (val[len] == ',');
11180		new_flags |= (1 << i);
11181		break;		/* check next item in val list */
11182	    }
11183	}
11184    }
11185    if (flagp != NULL)
11186	*flagp = new_flags;
11187
11188    return OK;
11189}
11190
11191/*
11192 * Read the 'wildmode' option, fill wim_flags[].
11193 */
11194    static int
11195check_opt_wim()
11196{
11197    char_u	new_wim_flags[4];
11198    char_u	*p;
11199    int		i;
11200    int		idx = 0;
11201
11202    for (i = 0; i < 4; ++i)
11203	new_wim_flags[i] = 0;
11204
11205    for (p = p_wim; *p; ++p)
11206    {
11207	for (i = 0; ASCII_ISALPHA(p[i]); ++i)
11208	    ;
11209	if (p[i] != NUL && p[i] != ',' && p[i] != ':')
11210	    return FAIL;
11211	if (i == 7 && STRNCMP(p, "longest", 7) == 0)
11212	    new_wim_flags[idx] |= WIM_LONGEST;
11213	else if (i == 4 && STRNCMP(p, "full", 4) == 0)
11214	    new_wim_flags[idx] |= WIM_FULL;
11215	else if (i == 4 && STRNCMP(p, "list", 4) == 0)
11216	    new_wim_flags[idx] |= WIM_LIST;
11217	else
11218	    return FAIL;
11219	p += i;
11220	if (*p == NUL)
11221	    break;
11222	if (*p == ',')
11223	{
11224	    if (idx == 3)
11225		return FAIL;
11226	    ++idx;
11227	}
11228    }
11229
11230    /* fill remaining entries with last flag */
11231    while (idx < 3)
11232    {
11233	new_wim_flags[idx + 1] = new_wim_flags[idx];
11234	++idx;
11235    }
11236
11237    /* only when there are no errors, wim_flags[] is changed */
11238    for (i = 0; i < 4; ++i)
11239	wim_flags[i] = new_wim_flags[i];
11240    return OK;
11241}
11242
11243/*
11244 * Check if backspacing over something is allowed.
11245 */
11246    int
11247can_bs(what)
11248    int		what;	    /* BS_INDENT, BS_EOL or BS_START */
11249{
11250    switch (*p_bs)
11251    {
11252	case '2':	return TRUE;
11253	case '1':	return (what != BS_START);
11254	case '0':	return FALSE;
11255    }
11256    return vim_strchr(p_bs, what) != NULL;
11257}
11258
11259/*
11260 * Save the current values of 'fileformat' and 'fileencoding', so that we know
11261 * the file must be considered changed when the value is different.
11262 */
11263    void
11264save_file_ff(buf)
11265    buf_T	*buf;
11266{
11267    buf->b_start_ffc = *buf->b_p_ff;
11268    buf->b_start_eol = buf->b_p_eol;
11269#ifdef FEAT_MBYTE
11270    buf->b_start_bomb = buf->b_p_bomb;
11271
11272    /* Only use free/alloc when necessary, they take time. */
11273    if (buf->b_start_fenc == NULL
11274			     || STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0)
11275    {
11276	vim_free(buf->b_start_fenc);
11277	buf->b_start_fenc = vim_strsave(buf->b_p_fenc);
11278    }
11279#endif
11280}
11281
11282/*
11283 * Return TRUE if 'fileformat' and/or 'fileencoding' has a different value
11284 * from when editing started (save_file_ff() called).
11285 * Also when 'endofline' was changed and 'binary' is set, or when 'bomb' was
11286 * changed and 'binary' is not set.
11287 * Don't consider a new, empty buffer to be changed.
11288 */
11289    int
11290file_ff_differs(buf)
11291    buf_T	*buf;
11292{
11293    /* In a buffer that was never loaded the options are not valid. */
11294    if (buf->b_flags & BF_NEVERLOADED)
11295	return FALSE;
11296    if ((buf->b_flags & BF_NEW)
11297	    && buf->b_ml.ml_line_count == 1
11298	    && *ml_get_buf(buf, (linenr_T)1, FALSE) == NUL)
11299	return FALSE;
11300    if (buf->b_start_ffc != *buf->b_p_ff)
11301	return TRUE;
11302    if (buf->b_p_bin && buf->b_start_eol != buf->b_p_eol)
11303	return TRUE;
11304#ifdef FEAT_MBYTE
11305    if (!buf->b_p_bin && buf->b_start_bomb != buf->b_p_bomb)
11306	return TRUE;
11307    if (buf->b_start_fenc == NULL)
11308	return (*buf->b_p_fenc != NUL);
11309    return (STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0);
11310#else
11311    return FALSE;
11312#endif
11313}
11314
11315/*
11316 * return OK if "p" is a valid fileformat name, FAIL otherwise.
11317 */
11318    int
11319check_ff_value(p)
11320    char_u	*p;
11321{
11322    return check_opt_strings(p, p_ff_values, FALSE);
11323}
11324