[BACK]Return to option.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / vim

Annotation of src/usr.bin/vim/option.c, Revision 1.1.1.1

1.1       downsj      1: /* $OpenBSD$   */
                      2: /* vi:set ts=4 sw=4:
                      3:  *
                      4:  * VIM - Vi IMproved       by Bram Moolenaar
                      5:  *
                      6:  * Do ":help uganda"  in Vim to read copying and usage conditions.
                      7:  * Do ":help credits" in Vim to see a list of people who contributed.
                      8:  */
                      9:
                     10: /*
                     11:  * Code to handle user-settable options. This is all pretty much table-
                     12:  * driven. To add a new option, put it in the options array, and add a
                     13:  * variable for it in option.h. If it's a numeric option, add any necessary
                     14:  * bounds checks to do_set().
                     15:  */
                     16:
                     17: #include "vim.h"
                     18: #include "globals.h"
                     19: #include "proto.h"
                     20: #include "option.h"
                     21:
                     22: struct option
                     23: {
                     24:    char        *fullname;      /* full option name */
                     25:    char        *shortname;     /* permissible abbreviation */
                     26:    short       flags;          /* see below */
                     27:    char_u      *var;           /* pointer to variable */
                     28:    char_u      *def_val;       /* default value for variable (can be the same
                     29:                                    as the actual value) */
                     30: };
                     31:
                     32: /*
                     33:  * Flags
                     34:  *
                     35:  * Note: P_EXPAND and P_IND can never be used at the same time.
                     36:  * Note: P_IND cannot be used for a terminal option.
                     37:  */
                     38: #define P_BOOL         0x01    /* the option is boolean */
                     39: #define P_NUM          0x02    /* the option is numeric */
                     40: #define P_STRING       0x04    /* the option is a string */
                     41: #define P_ALLOCED      0x08    /* the string option is in allocated memory,
                     42:                                    must use vim_free() when assigning new
                     43:                                    value. Not set if default is the same. */
                     44: #define P_EXPAND       0x10    /* environment expansion */
                     45: #define P_IND          0x20    /* indirect, is in curwin or curbuf */
                     46: #define P_NODEFAULT        0x40    /* has no default value */
                     47: #define P_DEF_ALLOCED  0x80    /* default value is in allocated memory, must
                     48:                                    use vim_free() when assigning new value */
                     49: #define P_WAS_SET      0x100   /* option has been set/reset */
                     50: #define P_NO_MKRC      0x200   /* don't include in :mkvimrc output */
                     51:
                     52: /*
                     53:  * The options that are in curwin or curbuf have P_IND set and a var field
                     54:  * that contains one of the values below.
                     55:  */
                     56: #define PV_LIST        1
                     57: #define PV_NU      2
                     58: #define PV_SCROLL  3
                     59: #define PV_WRAP        4
                     60: #define PV_LBR     5
                     61:
                     62: #define PV_AI      6
                     63: #define PV_BIN     7
                     64: #define PV_CIN     8
                     65: #define PV_CINK        9
                     66: #define PV_CINO        10
                     67: #define PV_CINW        11
                     68: #define PV_COM     12
                     69: #define PV_EOL     13
                     70: #define PV_ET      14
                     71: #define PV_FO      15
                     72: #define PV_LISP        16
                     73: #define PV_ML      17
                     74: #define PV_MOD     18
                     75: #define PV_RO      20
                     76: #define PV_SI      21
                     77: #define PV_SN      22
                     78: #define PV_SW      23
                     79: #define PV_TS      24
                     80: #define PV_TW      25
                     81: #define PV_TX      26
                     82: #define PV_WM      27
                     83: #define PV_ISK     28
                     84: #define PV_INF     29
                     85: #define PV_RL      30
                     86:
                     87: /*
                     88:  * The option structure is initialized here.
                     89:  * The order of the options should be alphabetic for ":set all".
                     90:  * The options with a NULL variable are 'hidden': a set command for
                     91:  * them is ignored and they are not printed.
                     92:  */
                     93: static struct option options[] =
                     94: {
                     95: #ifdef RIGHTLEFT
                     96:    {"aleph",       "al",   P_NUM,              (char_u *)&p_aleph,
                     97: # if defined(MSDOS) || defined(WIN32) || defined(OS2)
                     98:                            (char_u *)128L},
                     99: # else
                    100:                            (char_u *)224L},
                    101: # endif
                    102: #endif
                    103:    {"autoindent",  "ai",   P_BOOL|P_IND,       (char_u *)PV_AI,
                    104:                            (char_u *)FALSE},
                    105:    {"autoprint",   "ap",   P_BOOL,             (char_u *)NULL,
                    106:                            (char_u *)FALSE},
                    107:    {"autowrite",   "aw",   P_BOOL,             (char_u *)&p_aw,
                    108:                            (char_u *)FALSE},
                    109:    {"backspace",   "bs",   P_NUM,              (char_u *)&p_bs,
                    110:                            (char_u *)0L},
                    111:    {"backup",      "bk",   P_BOOL,             (char_u *)&p_bk,
                    112:                            (char_u *)FALSE},
                    113:    {"backupdir",   "bdir", P_STRING|P_EXPAND,
                    114:                                                (char_u *)&p_bdir,
                    115:                            (char_u *)DEF_BDIR},
                    116:    {"backupext",   "bex",  P_STRING,           (char_u *)&p_bex,
                    117: #ifdef VMS
                    118:                            (char_u *)"_"},
                    119: #else
                    120:                            (char_u *)"~"},
                    121: #endif
                    122:    {"beautify",    "bf",   P_BOOL,             (char_u *)NULL,
                    123:                            (char_u *)FALSE},
                    124:    {"binary",      "bin",  P_BOOL|P_IND,       (char_u *)PV_BIN,
                    125:                            (char_u *)FALSE},
                    126:    {"bioskey",     "biosk",P_BOOL,
                    127: #ifdef MSDOS
                    128:                                                (char_u *)&p_biosk,
                    129: #else
                    130:                                                (char_u *)NULL,
                    131: #endif
                    132:                            (char_u *)TRUE},
                    133:    {"breakat",     "brk",  P_STRING,           (char_u *)&p_breakat,
                    134:                            (char_u *)" \t!@*-+_;:,./?"},
                    135: #ifdef CINDENT
                    136:    {"cindent",     "cin",  P_BOOL|P_IND,       (char_u *)PV_CIN,
                    137:                            (char_u *)FALSE},
                    138:    {"cinkeys",     "cink", P_STRING|P_IND|P_ALLOCED,   (char_u *)PV_CINK,
                    139:                            (char_u *)"0{,0},:,0#,!^F,o,O,e"},
                    140:    {"cinoptions",  "cino", P_STRING|P_IND|P_ALLOCED,   (char_u *)PV_CINO,
                    141:                            (char_u *)""},
                    142: #endif /* CINDENT */
                    143: #if defined(SMARTINDENT) || defined(CINDENT)
                    144:    {"cinwords",    "cinw", P_STRING|P_IND|P_ALLOCED,   (char_u *)PV_CINW,
                    145:                            (char_u *)"if,else,while,do,for,switch"},
                    146: #endif
                    147:    {"cmdheight",   "ch",   P_NUM,              (char_u *)&p_ch,
                    148:                            (char_u *)1L},
                    149:    {"columns",     "co",   P_NUM|P_NODEFAULT|P_NO_MKRC, (char_u *)&Columns,
                    150:                            (char_u *)80L},
                    151:    {"comments",    "com",  P_STRING|P_IND|P_ALLOCED,   (char_u *)PV_COM,
                    152:                            (char_u *)"sr:/*,mb:*,el:*/,://,b:#,:%,:XCOMM,n:>,fb:-"},
                    153:    {"compatible",  "cp",   P_BOOL,             (char_u *)&p_cp,
                    154:                            (char_u *)FALSE},
                    155:    {"cpoptions",   "cpo",  P_STRING,           (char_u *)&p_cpo,
                    156: #ifdef COMPATIBLE
                    157:                            (char_u *)CPO_ALL},
                    158: #else
                    159:                            (char_u *)CPO_DEFAULT},
                    160: #endif
                    161:    {"define",      "def",  P_STRING,           (char_u *)&p_def,
                    162:                            (char_u *)"^#[ \\t]*define"},
                    163:    {"dictionary",  "dict", P_STRING|P_EXPAND,  (char_u *)&p_dict,
                    164:                            (char_u *)""},
                    165:    {"digraph",     "dg",   P_BOOL,
                    166: #ifdef DIGRAPHS
                    167:                                                (char_u *)&p_dg,
                    168: #else
                    169:                                                (char_u *)NULL,
                    170: #endif /* DIGRAPHS */
                    171:                            (char_u *)FALSE},
                    172:    {"directory",   "dir",  P_STRING|P_EXPAND,  (char_u *)&p_dir,
                    173:                            (char_u *)DEF_DIR},
                    174:    {"edcompatible","ed",   P_BOOL,             (char_u *)&p_ed,
                    175:                            (char_u *)FALSE},
                    176:    {"endofline",   "eol",  P_BOOL|P_IND|P_NO_MKRC, (char_u *)PV_EOL,
                    177:                            (char_u *)FALSE},
                    178:    {"equalalways", "ea",   P_BOOL,             (char_u *)&p_ea,
                    179:                            (char_u *)TRUE},
                    180:    {"equalprg",    "ep",   P_STRING|P_EXPAND,  (char_u *)&p_ep,
                    181:                            (char_u *)""},
                    182:    {"errorbells",  "eb",   P_BOOL,             (char_u *)&p_eb,
                    183:                            (char_u *)FALSE},
                    184:    {"errorfile",   "ef",   P_STRING|P_EXPAND,  (char_u *)&p_ef,
                    185: #ifdef AMIGA
                    186:                            (char_u *)"AztecC.Err"},
                    187: #else
                    188:                            (char_u *)"errors.vim"},
                    189: #endif
                    190:    {"errorformat", "efm",  P_STRING,           (char_u *)&p_efm,
                    191: #ifdef AMIGA
                    192:                        /* don't use [^0-9] here, Manx C can't handle it */
                    193:                            (char_u *)"%f>%l:%c:%t:%n:%m,%f:%l: %t%*[^0123456789]%n: %m,%f %l %t%*[^0123456789]%n: %m,%*[^\"]\"%f\"%*[^0123456789]%l: %m,%f:%l:%m"},
                    194: #else
                    195: # if defined MSDOS  ||  defined WIN32
                    196:                            (char_u *)"%*[^\"]\"%f\"%*[^0-9]%l: %m,%f(%l) : %m,%*[^ ] %f %l: %m,%f:%l:%m"},
                    197: # elif defined(__EMX__)    /* put most common here (i.e. gcc format) at front */
                    198:                            (char_u *)"%f:%l:%m,%*[^\"]\"%f\"%*[^0-9]%l: %m,\"%f\"%*[^0-9]%l: %m"},
                    199: # else
                    200:                            (char_u *)"%*[^\"]\"%f\"%*[^0-9]%l: %m,\"%f\"%*[^0-9]%l: %m,%f:%l:%m"},
                    201: # endif
                    202: #endif
                    203:    {"esckeys",     "ek",   P_BOOL,             (char_u *)&p_ek,
                    204: #ifdef COMPATIBLE
                    205:                            (char_u *)FALSE},
                    206: #else
                    207:                            (char_u *)TRUE},
                    208: #endif
                    209:    {"expandtab",   "et",   P_BOOL|P_IND,       (char_u *)PV_ET,
                    210:                            (char_u *)FALSE},
                    211:    {"exrc",        NULL,   P_BOOL,             (char_u *)&p_exrc,
                    212:                            (char_u *)FALSE},
                    213:    {"flash",       "fl",   P_BOOL,             (char_u *)NULL,
                    214:                            (char_u *)FALSE},
                    215:    {"formatoptions","fo",  P_STRING|P_IND|P_ALLOCED,   (char_u *)PV_FO,
                    216: #ifdef COMPATIBLE
                    217:                            (char_u *)FO_DFLT_VI},
                    218: #else
                    219:                            (char_u *)FO_DFLT},
                    220: #endif
                    221:    {"formatprg",   "fp",   P_STRING|P_EXPAND,  (char_u *)&p_fp,
                    222:                            (char_u *)""},
                    223:    {"gdefault",    "gd",   P_BOOL,             (char_u *)&p_gd,
                    224:                            (char_u *)FALSE},
                    225:    {"graphic",     "gr",   P_BOOL,             (char_u *)NULL,
                    226:                            (char_u *)FALSE},
                    227:    {"guifont",     "gfn",  P_STRING,
                    228: #ifdef USE_GUI
                    229:                                                (char_u *)&p_guifont,
                    230:                            (char_u *)""},
                    231: #else
                    232:                                                (char_u *)NULL,
                    233:                            (char_u *)NULL},
                    234: #endif
                    235:    {"guioptions",  "go",   P_STRING,
                    236: #ifdef USE_GUI
                    237:                                                (char_u *)&p_guioptions,
                    238: # ifdef UNIX
                    239:                            (char_u *)"aAgmr"},
                    240: # else
                    241:                            (char_u *)"Agmr"},
                    242: # endif
                    243: #else
                    244:                                                (char_u *)NULL,
                    245:                            (char_u *)NULL},
                    246: #endif
                    247: #if defined(USE_GUI)
                    248:    {"guipty",      NULL,   P_BOOL,             (char_u *)&p_guipty,
                    249:                            (char_u *)FALSE},
                    250: #endif
                    251:    {"hardtabs",    "ht",   P_NUM,              (char_u *)NULL,
                    252:                            (char_u *)0L},
                    253:    {"helpfile",    "hf",   P_STRING|P_EXPAND,  (char_u *)&p_hf,
                    254:                            (char_u *)""},
                    255:    {"helpheight",  "hh",   P_NUM,              (char_u *)&p_hh,
                    256:                            (char_u *)20L},
                    257:    {"hidden",      "hid",  P_BOOL,             (char_u *)&p_hid,
                    258:                            (char_u *)FALSE},
                    259:    {"highlight",   "hl",   P_STRING,           (char_u *)&p_hl,
                    260:                            (char_u *)"8b,db,es,hs,mb,Mn,nu,rs,sr,tb,vr,ws"},
                    261:    {"history",     "hi",   P_NUM,              (char_u *)&p_hi,
                    262: #ifdef COMPATIBLE
                    263:                            (char_u *)0L},
                    264: #else
                    265:                            (char_u *)20L},
                    266: #endif
                    267: #ifdef RIGHTLEFT
                    268:    {"hkmap",       "hk",   P_BOOL,             (char_u *)&p_hkmap,
                    269:                            (char_u *)FALSE},
                    270: #endif
                    271:    {"icon",        NULL,   P_BOOL,             (char_u *)&p_icon,
                    272:                            (char_u *)FALSE},
                    273:    {"ignorecase",  "ic",   P_BOOL,             (char_u *)&p_ic,
                    274:                            (char_u *)FALSE},
                    275:    {"include",     "inc",  P_STRING,           (char_u *)&p_inc,
                    276:                            (char_u *)"^#[ \\t]*include"},
                    277:    {"incsearch",   "is",   P_BOOL,             (char_u *)&p_is,
                    278:                            (char_u *)FALSE},
                    279:    {"infercase",   "inf",  P_BOOL|P_IND,       (char_u *)PV_INF,
                    280:                            (char_u *)FALSE},
                    281:    {"insertmode",  "im",   P_BOOL,             (char_u *)&p_im,
                    282:                            (char_u *)FALSE},
                    283:    {"isfname",     "isf",  P_STRING,           (char_u *)&p_isf,
                    284: #ifdef BACKSLASH_IN_FILENAME
                    285:                            (char_u *)"@,48-57,/,.,-,_,+,,,$,:,\\"},
                    286: #else
                    287: # ifdef AMIGA
                    288:                            (char_u *)"@,48-57,/,.,-,_,+,,,$,:"},
                    289: # else /* UNIX */
                    290:                            (char_u *)"@,48-57,/,.,-,_,+,,,$,:,~"},
                    291: # endif
                    292: #endif
                    293:    {"isident",     "isi",  P_STRING,           (char_u *)&p_isi,
                    294: #if defined(MSDOS) || defined(WIN32) || defined(OS2)
                    295:                            (char_u *)"@,48-57,_,128-167,224-235"},
                    296: #else
                    297:                            (char_u *)"@,48-57,_,192-255"},
                    298: #endif
                    299:    {"iskeyword",   "isk",  P_STRING|P_IND|P_ALLOCED,   (char_u *)PV_ISK,
                    300: #ifdef COMPATIBLE
                    301:                            (char_u *)"@,48-57,_"},
                    302: #else
                    303: # if defined MSDOS  ||  defined WIN32
                    304:                            (char_u *)"@,48-57,_,128-167,224-235"},
                    305: # else
                    306:                            (char_u *)"@,48-57,_,192-255"},
                    307: # endif
                    308: #endif
                    309:    {"isprint",     "isp",  P_STRING,           (char_u *)&p_isp,
                    310: #if defined MSDOS  ||  defined WIN32
                    311:                            (char_u *)"@,~-255"},
                    312: #else
                    313:                            (char_u *)"@,161-255"},
                    314: #endif
                    315:    {"joinspaces",  "js",   P_BOOL,             (char_u *)&p_js,
                    316:                            (char_u *)TRUE},
                    317:    {"keywordprg",  "kp",   P_STRING|P_EXPAND,  (char_u *)&p_kp,
                    318: #if defined(MSDOS) ||  defined(WIN32)
                    319:                            (char_u *)""},
                    320: #else
                    321:                            (char_u *)"man"},
                    322: #endif
                    323:    {"langmap",     "lmap", P_STRING,
                    324: #ifdef HAVE_LANGMAP
                    325:                                                (char_u *)&p_langmap,
                    326:                            (char_u *)""},
                    327: #else
                    328:                                                (char_u *)NULL,
                    329:                            (char_u *)NULL},
                    330: #endif
                    331:    {"laststatus",  "ls",   P_NUM,              (char_u *)&p_ls,
                    332:                            (char_u *)1L},
                    333:    {"linebreak",   "lbr",  P_BOOL|P_IND,       (char_u *)PV_LBR,
                    334:                            (char_u *)FALSE},
                    335:    {"lines",       NULL,   P_NUM|P_NODEFAULT|P_NO_MKRC, (char_u *)&Rows,
                    336: #if defined MSDOS  ||  defined WIN32
                    337:                            (char_u *)25L},
                    338: #else
                    339:                            (char_u *)24L},
                    340: #endif
                    341:    {"lisp",        NULL,   P_BOOL|P_IND,       (char_u *)PV_LISP,
                    342:                            (char_u *)FALSE},
                    343:    {"list",        NULL,   P_BOOL|P_IND,       (char_u *)PV_LIST,
                    344:                            (char_u *)FALSE},
                    345:    {"magic",       NULL,   P_BOOL,             (char_u *)&p_magic,
                    346:                            (char_u *)TRUE},
                    347:    {"makeprg",     "mp",   P_STRING|P_EXPAND,  (char_u *)&p_mp,
                    348:                            (char_u *)"make"},
                    349:    {"maxmapdepth", "mmd",  P_NUM,              (char_u *)&p_mmd,
                    350:                            (char_u *)1000L},
                    351:    {"maxmem",      "mm",   P_NUM,              (char_u *)&p_mm,
                    352:                            (char_u *)MAXMEM},
                    353:    {"maxmemtot",   "mmt",  P_NUM,              (char_u *)&p_mmt,
                    354:                            (char_u *)MAXMEMTOT},
                    355:    {"mesg",        NULL,   P_BOOL,             (char_u *)NULL,
                    356:                            (char_u *)FALSE},
                    357:    {"modeline",    "ml",   P_BOOL|P_IND,       (char_u *)PV_ML,
                    358: #ifdef COMPATIBLE
                    359:                            (char_u *)FALSE},
                    360: #else
                    361:                            (char_u *)TRUE},
                    362: #endif
                    363:    {"modelines",   "mls",  P_NUM,              (char_u *)&p_mls,
                    364:                            (char_u *)5L},
                    365:    {"modified",    "mod",  P_BOOL|P_IND|P_NO_MKRC, (char_u *)PV_MOD,
                    366:                            (char_u *)FALSE},
                    367:    {"more",        NULL,   P_BOOL,             (char_u *)&p_more,
                    368: #ifdef COMPATIBLE
                    369:                            (char_u *)FALSE},
                    370: #else
                    371:                            (char_u *)TRUE},
                    372: #endif
                    373:    {"mouse",       NULL,   P_STRING,           (char_u *)&p_mouse,
                    374: #if defined(MSDOS) || defined(WIN32)
                    375:                            (char_u *)"a"},
                    376: #else
                    377:                            (char_u *)""},
                    378: #endif
                    379:    {"mousetime",   "mouset",   P_NUM,          (char_u *)&p_mouset,
                    380:                            (char_u *)500L},
                    381:    {"novice",      NULL,   P_BOOL,             (char_u *)NULL,
                    382:                            (char_u *)FALSE},
                    383:    {"number",      "nu",   P_BOOL|P_IND,       (char_u *)PV_NU,
                    384:                            (char_u *)FALSE},
                    385:    {"open",        NULL,   P_BOOL,             (char_u *)NULL,
                    386:                            (char_u *)FALSE},
                    387:    {"optimize",    "opt",  P_BOOL,             (char_u *)NULL,
                    388:                            (char_u *)FALSE},
                    389:    {"paragraphs",  "para", P_STRING,           (char_u *)&p_para,
                    390:                            (char_u *)"IPLPPPQPP LIpplpipbp"},
                    391:    {"paste",       NULL,   P_BOOL,             (char_u *)&p_paste,
                    392:                            (char_u *)FALSE},
                    393:    {"patchmode",   "pm",   P_STRING,           (char_u *)&p_pm,
                    394:                            (char_u *)""},
                    395:    {"path",        "pa",   P_STRING|P_EXPAND,  (char_u *)&p_path,
                    396: #if defined AMIGA  ||  defined MSDOS  ||  defined WIN32
                    397:                            (char_u *)".,,"},
                    398: #elif defined(__EMX__)
                    399:                            (char_u *)".,/emx/include,,"},
                    400: #else
                    401:                            (char_u *)".,/usr/include,,"},
                    402: #endif
                    403:    {"prompt",      NULL,   P_BOOL,             (char_u *)NULL,
                    404:                            (char_u *)FALSE},
                    405:    {"readonly",    "ro",   P_BOOL|P_IND,       (char_u *)PV_RO,
                    406:                            (char_u *)FALSE},
                    407:    {"redraw",      NULL,   P_BOOL,             (char_u *)NULL,
                    408:                            (char_u *)FALSE},
                    409:    {"remap",       NULL,   P_BOOL,             (char_u *)&p_remap,
                    410:                            (char_u *)TRUE},
                    411:    {"report",      NULL,   P_NUM,              (char_u *)&p_report,
                    412:                            (char_u *)2L},
                    413: #ifdef WIN32
                    414:    {"restorescreen", "rs", P_BOOL,             (char_u *)&p_rs,
                    415:                            (char_u *)TRUE},
                    416: #endif
                    417: #ifdef RIGHTLEFT
                    418:    {"revins",      "ri",   P_BOOL,             (char_u *)&p_ri,
                    419:                            (char_u *)FALSE},
                    420:    {"rightleft",   "rl",   P_BOOL|P_IND,       (char_u *)PV_RL,
                    421:                            (char_u *)FALSE},
                    422: #endif
                    423:    {"ruler",       "ru",   P_BOOL,             (char_u *)&p_ru,
                    424:                            (char_u *)FALSE},
                    425:    {"scroll",      "scr",  P_NUM|P_IND|P_NO_MKRC, (char_u *)PV_SCROLL,
                    426:                            (char_u *)12L},
                    427:    {"scrolljump",  "sj",   P_NUM,              (char_u *)&p_sj,
                    428:                            (char_u *)1L},
                    429:    {"scrolloff",   "so",   P_NUM,              (char_u *)&p_so,
                    430:                            (char_u *)0L},
                    431:    {"sections",    "sect", P_STRING,           (char_u *)&p_sections,
                    432:                            (char_u *)"SHNHH HUnhsh"},
                    433:    {"secure",      NULL,   P_BOOL,             (char_u *)&p_secure,
                    434:                            (char_u *)FALSE},
                    435:    {"shell",       "sh",   P_STRING|P_EXPAND,  (char_u *)&p_sh,
                    436: #if   defined(MSDOS)
                    437:                            (char_u *)"command"},
                    438: #elif defined(WIN32)
                    439:                            (char_u *)""},      /* set in set_init_1() */
                    440: #elif defined(__EMX__)
                    441:                            (char_u *)"cmd.exe"},
                    442: #elif defined(ARCHIE)
                    443:                            (char_u *)"gos"},
                    444: #else
                    445:                            (char_u *)"sh"},
                    446: #endif
                    447:    {"shellpipe",   "sp",   P_STRING,           (char_u *)&p_sp,
                    448: #if defined(UNIX) || defined(OS2)
                    449: # ifdef ARCHIE
                    450:                            (char_u *)"2>"},
                    451: # else
                    452:                            (char_u *)"| tee"},
                    453: # endif
                    454: #else
                    455:                            (char_u *)">"},
                    456: #endif
                    457:    {"shellredir",  "srr",  P_STRING,           (char_u *)&p_srr,
                    458:                            (char_u *)">"},
                    459:    {"shelltype",   "st",   P_NUM,              (char_u *)&p_st,
                    460:                            (char_u *)0L},
                    461:    {"shiftround",  "sr",   P_BOOL,             (char_u *)&p_sr,
                    462:                            (char_u *)FALSE},
                    463:    {"shiftwidth",  "sw",   P_NUM|P_IND,        (char_u *)PV_SW,
                    464:                            (char_u *)8L},
                    465:    {"shortmess",   "shm",  P_STRING,           (char_u *)&p_shm,
                    466:                            (char_u *)""},
                    467:    {"shortname",   "sn",   P_BOOL|P_IND,
                    468: #ifdef SHORT_FNAME
                    469:                                                (char_u *)NULL,
                    470: #else
                    471:                                                (char_u *)PV_SN,
                    472: #endif
                    473:                            (char_u *)FALSE},
                    474:    {"showbreak",   "sbr",  P_STRING,           (char_u *)&p_sbr,
                    475:                            (char_u *)""},
                    476:    {"showcmd",     "sc",   P_BOOL,             (char_u *)&p_sc,
                    477: #if defined(COMPATIBLE) || defined(UNIX)
                    478:                            (char_u *)FALSE},
                    479: #else
                    480:                            (char_u *)TRUE},
                    481: #endif
                    482:    {"showmatch",   "sm",   P_BOOL,             (char_u *)&p_sm,
                    483:                            (char_u *)FALSE},
                    484:    {"showmode",    "smd",  P_BOOL,             (char_u *)&p_smd,
                    485: #if defined(COMPATIBLE)
                    486:                            (char_u *)FALSE},
                    487: #else
                    488:                            (char_u *)TRUE},
                    489: #endif
                    490:    {"sidescroll",  "ss",   P_NUM,              (char_u *)&p_ss,
                    491:                            (char_u *)0L},
                    492:    {"slowopen",    "slow", P_BOOL,             (char_u *)NULL,
                    493:                            (char_u *)FALSE},
                    494:    {"smartcase",   "scs",  P_BOOL,             (char_u *)&p_scs,
                    495:                            (char_u *)FALSE},
                    496: #ifdef SMARTINDENT
                    497:    {"smartindent", "si",   P_BOOL|P_IND,       (char_u *)PV_SI,
                    498:                            (char_u *)FALSE},
                    499: #endif
                    500:    {"smarttab",    "sta",  P_BOOL,             (char_u *)&p_sta,
                    501:                            (char_u *)FALSE},
                    502:    {"sourceany",   NULL,   P_BOOL,             (char_u *)NULL,
                    503:                            (char_u *)FALSE},
                    504:    {"splitbelow",  "sb",   P_BOOL,             (char_u *)&p_sb,
                    505:                            (char_u *)FALSE},
                    506:    {"startofline", "sol",  P_BOOL,             (char_u *)&p_sol,
                    507:                            (char_u *)TRUE},
                    508:    {"suffixes",    "su",   P_STRING,           (char_u *)&p_su,
                    509:                            (char_u *)".bak,~,.o,.h,.info,.swp"},
                    510:    {"swapsync",    "sws",  P_STRING,           (char_u *)&p_sws,
                    511:                            (char_u *)"fsync"},
                    512:    {"tabstop",     "ts",   P_NUM|P_IND,        (char_u *)PV_TS,
                    513:                            (char_u *)8L},
                    514:    {"taglength",   "tl",   P_NUM,              (char_u *)&p_tl,
                    515:                            (char_u *)0L},
                    516:    {"tagrelative", "tr",   P_BOOL,             (char_u *)&p_tr,
                    517: #if defined(COMPATIBLE)
                    518:                            (char_u *)FALSE},
                    519: #else
                    520:                            (char_u *)TRUE},
                    521: #endif
                    522:    {"tags",        "tag",  P_STRING|P_EXPAND,  (char_u *)&p_tags,
                    523: #ifdef EMACS_TAGS
                    524:                            (char_u *)"./tags,./TAGS,tags,TAGS"},
                    525: #else
                    526:                            (char_u *)"./tags,tags"},
                    527: #endif
                    528:    {"tagstack",    "tgst", P_BOOL,             (char_u *)NULL,
                    529:                            (char_u *)FALSE},
                    530:    {"term",        NULL,   P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC,
                    531:                                            (char_u *)&term_strings[KS_NAME],
                    532:                            (char_u *)""},
                    533:    {"terse",       NULL,   P_BOOL,             (char_u *)&p_terse,
                    534:                            (char_u *)FALSE},
                    535:    {"textauto",    "ta",   P_BOOL,             (char_u *)&p_ta,
                    536: #if defined(COMPATIBLE)
                    537:                            (char_u *)FALSE},
                    538: #else
                    539:                            (char_u *)TRUE},
                    540: #endif
                    541:    {"textmode",    "tx",   P_BOOL|P_IND,       (char_u *)PV_TX,
                    542: #ifdef USE_CRNL
                    543:                            (char_u *)TRUE},
                    544: #else
                    545:                            (char_u *)FALSE},
                    546: #endif
                    547:    {"textwidth",   "tw",   P_NUM|P_IND,        (char_u *)PV_TW,
                    548:                            (char_u *)0L},
                    549:    {"tildeop",     "top",  P_BOOL,             (char_u *)&p_to,
                    550:                            (char_u *)FALSE},
                    551:    {"timeout",     "to",   P_BOOL,             (char_u *)&p_timeout,
                    552:                            (char_u *)TRUE},
                    553:    {"timeoutlen",  "tm",   P_NUM,              (char_u *)&p_tm,
                    554:                            (char_u *)1000L},
                    555:    {"title",       NULL,   P_BOOL,             (char_u *)&p_title,
                    556:                            (char_u *)FALSE},
                    557:    {"ttimeout",    NULL,   P_BOOL,             (char_u *)&p_ttimeout,
                    558:                            (char_u *)FALSE},
                    559:    {"ttimeoutlen", "ttm",  P_NUM,              (char_u *)&p_ttm,
                    560:                            (char_u *)-1L},
                    561:    {"ttybuiltin",  "tbi",  P_BOOL,             (char_u *)&p_tbi,
                    562:                            (char_u *)TRUE},
                    563:    {"ttyfast",     "tf",   P_BOOL|P_NO_MKRC,   (char_u *)&p_tf,
                    564:                            (char_u *)FALSE},
                    565:    {"ttyscroll",   "tsl",  P_NUM,              (char_u *)&p_ttyscroll,
                    566:                            (char_u *)999L},
                    567:    {"ttytype",     "tty",  P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC,
                    568:                                            (char_u *)&term_strings[KS_NAME],
                    569:                            (char_u *)""},
                    570:    {"undolevels",  "ul",   P_NUM,              (char_u *)&p_ul,
                    571: #ifdef COMPATIBLE
                    572:                            (char_u *)0L},
                    573: #else
                    574: # if defined(UNIX) || defined(WIN32) || defined(OS2)
                    575:                            (char_u *)1000L},
                    576: # else
                    577:                            (char_u *)100L},
                    578: # endif
                    579: #endif
                    580:    {"updatecount", "uc",   P_NUM,              (char_u *)&p_uc,
                    581: #ifdef COMPATIBLE
                    582:                            (char_u *)0L},
                    583: #else
                    584:                            (char_u *)200L},
                    585: #endif
                    586:    {"updatetime",  "ut",   P_NUM,              (char_u *)&p_ut,
                    587:                            (char_u *)4000L},
                    588:    {"viminfo",     "vi",   P_STRING,
                    589: #ifdef VIMINFO
                    590:                                                (char_u *)&p_viminfo,
                    591: #else
                    592:                                                (char_u *)NULL,
                    593: #endif /* VIMINFO */
                    594:                            (char_u *)""},
                    595:    {"visualbell",  "vb",   P_BOOL,             (char_u *)&p_vb,
                    596:                            (char_u *)FALSE},
                    597:    {"w300",        NULL,   P_NUM,              (char_u *)NULL,
                    598:                            (char_u *)0L},
                    599:    {"w1200",       NULL,   P_NUM,              (char_u *)NULL,
                    600:                            (char_u *)0L},
                    601:    {"w9600",       NULL,   P_NUM,              (char_u *)NULL,
                    602:                            (char_u *)0L},
                    603:    {"warn",        NULL,   P_BOOL,             (char_u *)&p_warn,
                    604:                            (char_u *)TRUE},
                    605:    {"weirdinvert", "wiv",  P_BOOL,             (char_u *)&p_wiv,
                    606:                            (char_u *)FALSE},
                    607:    {"whichwrap",   "ww",   P_STRING,           (char_u *)&p_ww,
                    608: #ifdef COMPATIBLE
                    609:                            (char_u *)""},
                    610: #else
                    611:                            (char_u *)"b,s"},
                    612: #endif
                    613:    {"wildchar",    "wc",   P_NUM,              (char_u *)&p_wc,
                    614: #ifdef COMPATIBLE
                    615:                            (char_u *)(long)Ctrl('E')},
                    616: #else
                    617:                            (char_u *)(long)TAB},
                    618: #endif
                    619:    {"window",      "wi",   P_NUM,              (char_u *)NULL,
                    620:                            (char_u *)0L},
                    621:    {"winheight",   "wh",   P_NUM,              (char_u *)&p_wh,
                    622:                            (char_u *)0L},
                    623:    {"wrap",        NULL,   P_BOOL|P_IND,       (char_u *)PV_WRAP,
                    624:                            (char_u *)TRUE},
                    625:    {"wrapmargin",  "wm",   P_NUM|P_IND,        (char_u *)PV_WM,
                    626:                            (char_u *)0L},
                    627:    {"wrapscan",    "ws",   P_BOOL,             (char_u *)&p_ws,
                    628:                            (char_u *)TRUE},
                    629:    {"writeany",    "wa",   P_BOOL,             (char_u *)&p_wa,
                    630:                            (char_u *)FALSE},
                    631:    {"writebackup", "wb",   P_BOOL,             (char_u *)&p_wb,
                    632: #if defined(COMPATIBLE) && !defined(WRITEBACKUP)
                    633:                            (char_u *)FALSE},
                    634: #else
                    635:                            (char_u *)TRUE},
                    636: #endif
                    637:    {"writedelay",  "wd",   P_NUM,              (char_u *)&p_wd,
                    638:                            (char_u *)0L},
                    639:
                    640: /* terminal output codes */
                    641:    {"t_AL",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CAL],
                    642:                            (char_u *)""},
                    643:    {"t_al",        NULL,   P_STRING,   (char_u *)&term_strings[KS_AL],
                    644:                            (char_u *)""},
                    645:    {"t_cd",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CD],
                    646:                            (char_u *)""},
                    647:    {"t_ce",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CE],
                    648:                            (char_u *)""},
                    649:    {"t_cl",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CL],
                    650:                            (char_u *)""},
                    651:    {"t_cm",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CM],
                    652:                            (char_u *)""},
                    653:    {"t_CS",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CSC],
                    654:                            (char_u *)""},
                    655:    {"t_cs",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CS],
                    656:                            (char_u *)""},
                    657:    {"t_da",        NULL,   P_STRING,   (char_u *)&term_strings[KS_DA],
                    658:                            (char_u *)""},
                    659:    {"t_db",        NULL,   P_STRING,   (char_u *)&term_strings[KS_DB],
                    660:                            (char_u *)""},
                    661:    {"t_DL",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CDL],
                    662:                            (char_u *)""},
                    663:    {"t_dl",        NULL,   P_STRING,   (char_u *)&term_strings[KS_DL],
                    664:                            (char_u *)""},
                    665:    {"t_ke",        NULL,   P_STRING,   (char_u *)&term_strings[KS_KE],
                    666:                            (char_u *)""},
                    667:    {"t_ks",        NULL,   P_STRING,   (char_u *)&term_strings[KS_KS],
                    668:                            (char_u *)""},
                    669:    {"t_md",        NULL,   P_STRING,   (char_u *)&term_strings[KS_MD],
                    670:                            (char_u *)""},
                    671:    {"t_me",        NULL,   P_STRING,   (char_u *)&term_strings[KS_ME],
                    672:                            (char_u *)""},
                    673:    {"t_mr",        NULL,   P_STRING,   (char_u *)&term_strings[KS_MR],
                    674:                            (char_u *)""},
                    675:    {"t_ms",        NULL,   P_STRING,   (char_u *)&term_strings[KS_MS],
                    676:                            (char_u *)""},
                    677:    {"t_RI",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CRI],
                    678:                            (char_u *)""},
                    679:    {"t_se",        NULL,   P_STRING,   (char_u *)&term_strings[KS_SE],
                    680:                            (char_u *)""},
                    681:    {"t_so",        NULL,   P_STRING,   (char_u *)&term_strings[KS_SO],
                    682:                            (char_u *)""},
                    683:    {"t_sr",        NULL,   P_STRING,   (char_u *)&term_strings[KS_SR],
                    684:                            (char_u *)""},
                    685:    {"t_te",        NULL,   P_STRING,   (char_u *)&term_strings[KS_TE],
                    686:                            (char_u *)""},
                    687:    {"t_ti",        NULL,   P_STRING,   (char_u *)&term_strings[KS_TI],
                    688:                            (char_u *)""},
                    689:    {"t_ue",        NULL,   P_STRING,   (char_u *)&term_strings[KS_UE],
                    690:                            (char_u *)""},
                    691:    {"t_us",        NULL,   P_STRING,   (char_u *)&term_strings[KS_US],
                    692:                            (char_u *)""},
                    693:    {"t_vb",        NULL,   P_STRING,   (char_u *)&term_strings[KS_VB],
                    694:                            (char_u *)""},
                    695:    {"t_ve",        NULL,   P_STRING,   (char_u *)&term_strings[KS_VE],
                    696:                            (char_u *)""},
                    697:    {"t_vi",        NULL,   P_STRING,   (char_u *)&term_strings[KS_VI],
                    698:                            (char_u *)""},
                    699:    {"t_vs",        NULL,   P_STRING,   (char_u *)&term_strings[KS_VS],
                    700:                            (char_u *)""},
                    701:    {"t_ZH",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CZH],
                    702:                            (char_u *)""},
                    703:    {"t_ZR",        NULL,   P_STRING,   (char_u *)&term_strings[KS_CZR],
                    704:                            (char_u *)""},
                    705:
                    706: /* terminal key codes are not here */
                    707:
                    708:    {NULL, NULL, 0, NULL, NULL}         /* end marker */
                    709: };
                    710:
                    711: #define PARAM_COUNT (sizeof(options) / sizeof(struct option))
                    712:
                    713: #ifdef AUTOCMD
                    714: /*
                    715:  * structures for automatic commands
                    716:  */
                    717:
                    718: typedef struct AutoCmd
                    719: {
                    720:    char_u          *cmd;                   /* The command to be executed */
                    721:    struct AutoCmd  *next;                  /* Next AutoCmd in list */
                    722: } AutoCmd;
                    723:
                    724: typedef struct AutoPat
                    725: {
                    726:    char_u          *pat;                   /* pattern as typed */
                    727:    char_u          *reg_pat;               /* pattern converted to regexp */
                    728:    int             allow_directories;      /* Pattern may match whole path */
                    729:    AutoCmd         *cmds;                  /* list of commands to do */
                    730:    struct AutoPat  *next;                  /* next AutoPat in AutoPat list */
                    731: } AutoPat;
                    732:
                    733: static struct event_name
                    734: {
                    735:    char    *name;      /* event name */
                    736:    int     event;      /* event number */
                    737: } event_names[] =
                    738: {
                    739:    {"BufEnter",        EVENT_BUFENTER},
                    740:    {"BufLeave",        EVENT_BUFLEAVE},
                    741:    {"BufNewFile",      EVENT_BUFNEWFILE},
                    742:    {"BufReadPost",     EVENT_BUFREADPOST},
                    743:    {"BufReadPre",      EVENT_BUFREADPRE},
                    744:    {"BufRead",         EVENT_BUFREADPOST},
                    745:    {"BufWritePost",    EVENT_BUFWRITEPOST},
                    746:    {"BufWritePre",     EVENT_BUFWRITEPRE},
                    747:    {"BufWrite",        EVENT_BUFWRITEPRE},
                    748:    {"FileAppendPost",  EVENT_FILEAPPENDPOST},
                    749:    {"FileAppendPre",   EVENT_FILEAPPENDPRE},
                    750:    {"FileReadPost",    EVENT_FILEREADPOST},
                    751:    {"FileReadPre",     EVENT_FILEREADPRE},
                    752:    {"FileWritePost",   EVENT_FILEWRITEPOST},
                    753:    {"FileWritePre",    EVENT_FILEWRITEPRE},
                    754:    {"FilterReadPost",  EVENT_FILTERREADPOST},
                    755:    {"FilterReadPre",   EVENT_FILTERREADPRE},
                    756:    {"FilterWritePost", EVENT_FILTERWRITEPOST},
                    757:    {"FilterWritePre",  EVENT_FILTERWRITEPRE},
                    758:    {"VimLeave",        EVENT_VIMLEAVE},
                    759:    {"WinEnter",        EVENT_WINENTER},
                    760:    {"WinLeave",        EVENT_WINLEAVE},
                    761:    {NULL,          0}
                    762: };
                    763:
                    764: static AutoPat *first_autopat[NUM_EVENTS] =
                    765: {
                    766:    NULL, NULL, NULL, NULL, NULL,
                    767:    NULL, NULL, NULL, NULL, NULL,
                    768:    NULL, NULL, NULL, NULL, NULL,
                    769:    NULL, NULL, NULL, NULL, NULL
                    770: };
                    771: #endif
                    772:
                    773: static void set_option_default __ARGS((int, int));
                    774: static void illegal_char __ARGS((char_u *, int));
                    775: static char_u *option_expand __ARGS((int));
                    776: static int findoption __ARGS((char_u *));
                    777: static int find_key_option __ARGS((char_u *));
                    778: static void    showoptions __ARGS((int));
                    779: static int option_changed __ARGS((struct option *));
                    780: static void showoneopt __ARGS((struct option *));
                    781: static int  istermoption __ARGS((struct option *));
                    782: static char_u *get_varp __ARGS((struct option *));
                    783: static void option_value2string __ARGS((struct option *));
                    784: #ifdef HAVE_LANGMAP
                    785: static void langmap_init __ARGS((void));
                    786: static void langmap_set __ARGS((void));
                    787: #endif
                    788: static void paste_option_changed __ARGS((void));
                    789: static void p_compatible_set __ARGS((void));
                    790: static void fill_breakat_flags __ARGS((void));
                    791:
                    792: /*
                    793:  * Initialize the options, first part.
                    794:  *
                    795:  * Called only once from main(), just after creating the first buffer.
                    796:  */
                    797:    void
                    798: set_init_1()
                    799: {
                    800:    char_u  *p;
                    801:    int     opt_idx;
                    802:    long    n;
                    803:
                    804: #ifdef HAVE_LANGMAP
                    805:    langmap_init();
                    806: #endif
                    807:
                    808: /*
                    809:  * Find default value for 'shell' option.
                    810:  */
                    811:    if ((p = vim_getenv((char_u *)"SHELL")) != NULL
                    812: #if defined(MSDOS) || defined(WIN32) || defined(OS2)
                    813: # ifdef __EMX__
                    814:            || (p = vim_getenv((char_u *)"EMXSHELL")) != NULL
                    815: # endif
                    816:            || (p = vim_getenv((char_u *)"COMSPEC")) != NULL
                    817: # ifdef WIN32
                    818:            || (p = default_shell()) != NULL
                    819: # endif
                    820: #endif
                    821:                                                            )
                    822:    {
                    823:        p = strsave(p);
                    824:        if (p != NULL)          /* we don't want a NULL */
                    825:        {
                    826:            opt_idx = findoption((char_u *)"sh");
                    827:            options[opt_idx].def_val = p;
                    828:            options[opt_idx].flags |= P_DEF_ALLOCED;
                    829:        }
                    830:    }
                    831:
                    832: /*
                    833:  * Set default for 'helpfile' option. This cannot be done at compile time,
                    834:  * because for Unix it is an external variable.
                    835:  */
                    836:    opt_idx = findoption((char_u *)"hf");
                    837: #if defined(HAVE_CONFIG_H) || defined(OS2)
                    838:    options[opt_idx].def_val = help_fname;
                    839: #else
                    840:    options[opt_idx].def_val = (char_u *)VIM_HLP;
                    841: #endif
                    842:
                    843: /*
                    844:  * 'maxmemtot' and 'maxmem' may have to be adjusted for available memory
                    845:  */
                    846:    opt_idx = findoption((char_u *)"maxmemtot");
                    847:    if (options[opt_idx].def_val == (char_u *)0L)
                    848:    {
                    849:        n = (mch_avail_mem(FALSE) >> 11);
                    850:        options[opt_idx].def_val = (char_u *)n;
                    851:        opt_idx = findoption((char_u *)"maxmem");
                    852:        if ((long)options[opt_idx].def_val > n ||
                    853:                                         (long)options[opt_idx].def_val == 0L)
                    854:            options[opt_idx].def_val = (char_u *)n;
                    855:    }
                    856:
                    857: /*
                    858:  * set all the options (except the terminal options) to their default value
                    859:  */
                    860:    for (opt_idx = 0; !istermoption(&options[opt_idx]); opt_idx++)
                    861:        if (!(options[opt_idx].flags & P_NODEFAULT))
                    862:            set_option_default(opt_idx, FALSE);
                    863:
                    864:    curbuf->b_p_initialized = TRUE;
                    865:    check_buf_options(curbuf);
                    866:    check_options();
                    867:
                    868:    /*
                    869:     * initialize the table for 'iskeyword' et.al.
                    870:     * Must be before option_expand(), because that one needs isidchar()
                    871:     */
                    872:    init_chartab();
                    873:
                    874:    /*
                    875:     * initialize the table for 'breakat'.
                    876:     */
                    877:    fill_breakat_flags();
                    878:
                    879:    /*
                    880:     * Expand environment variables and things like "~" for the defaults.
                    881:     * If option_expand() returns non-NULL the variable is expanded. This can
                    882:     * only happen for non-indirect options.
                    883:     * Also set the default to the expanded value, so ":set" does not list
                    884:     * them. Don't set the P_ALLOCED flag, because we don't want to free the
                    885:     * default.
                    886:     */
                    887:    for (opt_idx = 0; !istermoption(&options[opt_idx]); opt_idx++)
                    888:    {
                    889:        p = option_expand(opt_idx);
                    890:        if (p != NULL)
                    891:        {
                    892:            *(char_u **)options[opt_idx].var = p;
                    893:            options[opt_idx].def_val = p;
                    894:            options[opt_idx].flags |= P_DEF_ALLOCED;
                    895:        }
                    896:    }
                    897: }
                    898:
                    899: /*
                    900:  * Set an option to its default value.
                    901:  */
                    902:    static void
                    903: set_option_default(opt_idx, dofree)
                    904:    int     opt_idx;
                    905:    int     dofree;     /* TRUE when old value may be freed */
                    906: {
                    907:    char_u      *varp;          /* pointer to variable for current option */
                    908:
                    909:    varp = get_varp(&(options[opt_idx]));
                    910:    if (varp != NULL)       /* nothing to do for hidden option */
                    911:    {
                    912:        if (options[opt_idx].flags & P_STRING)
                    913:        {
                    914:            /* indirect options are always in allocated memory */
                    915:            if (options[opt_idx].flags & P_IND)
                    916:                set_string_option(NULL, opt_idx,
                    917:                                            options[opt_idx].def_val, dofree);
                    918:            else
                    919:            {
                    920:                if (dofree && (options[opt_idx].flags & P_ALLOCED))
                    921:                    free_string_option(*(char_u **)(varp));
                    922:                *(char_u **)varp = options[opt_idx].def_val;
                    923:                options[opt_idx].flags &= ~P_ALLOCED;
                    924:            }
                    925:        }
                    926:        else if (options[opt_idx].flags & P_NUM)
                    927:            *(long *)varp = (long)options[opt_idx].def_val;
                    928:        else    /* P_BOOL */
                    929:                /* the cast to long is required for Manx C */
                    930:            *(int *)varp = (int)(long)options[opt_idx].def_val;
                    931:    }
                    932: }
                    933:
                    934: /*
                    935:  * Initialize the options, part two: After getting Rows and Columns
                    936:  */
                    937:    void
                    938: set_init_2()
                    939: {
                    940: /*
                    941:  * 'scroll' defaults to half the window height. Note that this default is
                    942:  * wrong when the window height changes.
                    943:  */
                    944:    options[findoption((char_u *)"scroll")].def_val = (char_u *)(Rows >> 1);
                    945:
                    946:    comp_col();
                    947: }
                    948:
                    949: /*
                    950:  * Initialize the options, part three: After reading the .vimrc
                    951:  */
                    952:    void
                    953: set_init_3()
                    954: {
                    955:    int     idx1;
                    956:
                    957: #if defined(UNIX) || defined(OS2)
                    958: /*
                    959:  * Set 'shellpipe' and 'shellredir', depending on the 'shell' option.
                    960:  * This is done after other initializations, where 'shell' might have been
                    961:  * set, but only if they have not been set before.
                    962:  */
                    963:    char_u  *p;
                    964:    int     idx2;
                    965:    int     do_sp;
                    966:    int     do_srr;
                    967:
                    968:    idx1 = findoption((char_u *)"sp");
                    969:    idx2 = findoption((char_u *)"srr");
                    970:    do_sp = !(options[idx1].flags & P_WAS_SET);
                    971:    do_srr = !(options[idx2].flags & P_WAS_SET);
                    972:
                    973:    /*
                    974:     * Default for p_sp is "| tee", for p_srr is ">".
                    975:     * For known shells it is changed here to include stderr.
                    976:     */
                    977:    p = gettail(p_sh);
                    978:    if (    fnamecmp(p, "csh") == 0 ||
                    979:            fnamecmp(p, "tcsh") == 0
                    980: # ifdef OS2            /* also check with .exe extension */
                    981:            || fnamecmp(p, "csh.exe") == 0
                    982:            || fnamecmp(p, "tcsh.exe") == 0
                    983: # endif
                    984:                                            )
                    985:    {
                    986:        if (do_sp)
                    987:        {
                    988:            p_sp = (char_u *)"|& tee";
                    989:            options[idx1].def_val = p_sp;
                    990:        }
                    991:        if (do_srr)
                    992:        {
                    993:            p_srr = (char_u *)">&";
                    994:            options[idx2].def_val = p_srr;
                    995:        }
                    996:    }
                    997:    else
                    998: # ifndef OS2   /* Always use bourne shell style redirection if we reach this */
                    999:        if (    STRCMP(p, "sh") == 0 ||
                   1000:                STRCMP(p, "ksh") == 0 ||
                   1001:                STRCMP(p, "zsh") == 0 ||
                   1002:                STRCMP(p, "bash") == 0)
                   1003: # endif
                   1004:    {
                   1005:        if (do_sp)
                   1006:        {
                   1007:            p_sp = (char_u *)"2>&1| tee";
                   1008:            options[idx1].def_val = p_sp;
                   1009:        }
                   1010:        if (do_srr)
                   1011:        {
                   1012:            p_srr = (char_u *)">%s 2>&1";
                   1013:            options[idx2].def_val = p_srr;
                   1014:        }
                   1015:    }
                   1016: #endif
                   1017:
                   1018: /*
                   1019:  * 'title' and 'icon' only default to true if they have not been set or reset
                   1020:  * in .vimrc and we can read the old value.
                   1021:  * When 'title' and 'icon' have been reset in .vimrc, we won't even check if
                   1022:  * they can be reset. this reduces startup time when using X on a remote
                   1023:  * machine.
                   1024:  */
                   1025:    idx1 = findoption((char_u *)"title");
                   1026:    if (!(options[idx1].flags & P_WAS_SET) && mch_can_restore_title())
                   1027:    {
                   1028:        options[idx1].def_val = (char_u *)TRUE;
                   1029:        p_title = TRUE;
                   1030:    }
                   1031:    idx1 = findoption((char_u *)"icon");
                   1032:    if (!(options[idx1].flags & P_WAS_SET) && mch_can_restore_icon())
                   1033:    {
                   1034:        options[idx1].def_val = (char_u *)TRUE;
                   1035:        p_icon = TRUE;
                   1036:    }
                   1037: }
                   1038:
                   1039: /*
                   1040:  * Parse 'arg' for option settings.
                   1041:  *
                   1042:  * 'arg' may be IObuff, but only when no errors can be present and option
                   1043:  * does not need to be expanded with option_expand().
                   1044:  *
                   1045:  * return FAIL if errors are detected, OK otherwise
                   1046:  */
                   1047:    int
                   1048: do_set(arg)
                   1049:    char_u      *arg;   /* option string (may be written to!) */
                   1050: {
                   1051:    register int opt_idx;
                   1052:    char_u      *errmsg;
                   1053:    char_u      errbuf[80];
                   1054:    char_u      *startarg;
                   1055:    int         prefix; /* 1: nothing, 0: "no", 2: "inv" in front of name */
                   1056:    int         nextchar;           /* next non-white char after option name */
                   1057:    int         afterchar;          /* character just after option name */
                   1058:    int         len;
                   1059:    int         i;
                   1060:    int         key;
                   1061:    int         flags;              /* flags for current option */
                   1062:    char_u      *varp = NULL;       /* pointer to variable for current option */
                   1063:    char_u      *oldval;            /* previous value if *varp */
                   1064:    int         errcnt = 0;         /* number of errornous entries */
                   1065:    long        oldRows = Rows;     /* remember old Rows */
                   1066:    long        oldColumns = Columns;   /* remember old Columns */
                   1067:    int         oldbin;             /* remember old bin option */
                   1068:    long        oldch = p_ch;       /* remember old command line height */
                   1069:    int         oldea = p_ea;       /* remember old 'equalalways' */
                   1070:    long        olduc = p_uc;       /* remember old 'updatecount' */
                   1071:    int         did_show = FALSE;   /* already showed one value */
                   1072:    WIN         *wp;
                   1073:
                   1074:    if (*arg == NUL)
                   1075:    {
                   1076:        showoptions(0);
                   1077:        return OK;
                   1078:    }
                   1079:
                   1080:    while (*arg)        /* loop to process all options */
                   1081:    {
                   1082:        errmsg = NULL;
                   1083:        startarg = arg;     /* remember for error message */
                   1084:
                   1085:        if (STRNCMP(arg, "all", (size_t)3) == 0)
                   1086:        {
                   1087:            showoptions(1);
                   1088:            arg += 3;
                   1089:        }
                   1090:        else if (STRNCMP(arg, "termcap", (size_t)7) == 0)
                   1091:        {
                   1092:            showoptions(2);
                   1093:            show_termcodes();
                   1094:            arg += 7;
                   1095:        }
                   1096:        else
                   1097:        {
                   1098:            prefix = 1;
                   1099:            if (STRNCMP(arg, "no", (size_t)2) == 0)
                   1100:            {
                   1101:                prefix = 0;
                   1102:                arg += 2;
                   1103:            }
                   1104:            else if (STRNCMP(arg, "inv", (size_t)3) == 0)
                   1105:            {
                   1106:                prefix = 2;
                   1107:                arg += 3;
                   1108:            }
                   1109:                /* find end of name */
                   1110:            if (*arg == '<')
                   1111:            {
                   1112:                opt_idx = -1;
                   1113:                /* check for <t_>;> */
                   1114:                if (arg[1] == 't' && arg[2] == '_' && arg[3] && arg[4])
                   1115:                    len = 5;
                   1116:                else
                   1117:                {
                   1118:                    len = 1;
                   1119:                    while (arg[len] != NUL && arg[len] != '>')
                   1120:                        ++len;
                   1121:                }
                   1122:                if (arg[len] != '>')
                   1123:                {
                   1124:                    errmsg = e_invarg;
                   1125:                    goto skip;
                   1126:                }
                   1127:                nextchar = arg[len];
                   1128:                arg[len] = NUL;                     /* put NUL after name */
                   1129:                if (arg[1] == 't' && arg[2] == '_') /* could be term code */
                   1130:                    opt_idx = findoption(arg + 1);
                   1131:                key = 0;
                   1132:                if (opt_idx == -1)
                   1133:                    key = find_key_option(arg + 1);
                   1134:                arg[len++] = nextchar;              /* restore nextchar */
                   1135:                nextchar = arg[len];
                   1136:            }
                   1137:            else
                   1138:            {
                   1139:                len = 0;
                   1140:                /*
                   1141:                 * The two characters after "t_" may not be alphanumeric.
                   1142:                 */
                   1143:                if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
                   1144:                {
                   1145:                    len = 4;
                   1146:                }
                   1147:                else
                   1148:                {
                   1149:                    while (isalnum(arg[len]) || arg[len] == '_')
                   1150:                        ++len;
                   1151:                }
                   1152:                nextchar = arg[len];
                   1153:                arg[len] = NUL;                     /* put NUL after name */
                   1154:                opt_idx = findoption(arg);
                   1155:                key = 0;
                   1156:                if (opt_idx == -1)
                   1157:                    key = find_key_option(arg);
                   1158:                arg[len] = nextchar;                /* restore nextchar */
                   1159:            }
                   1160:
                   1161:            if (opt_idx == -1 && key == 0)      /* found a mismatch: skip */
                   1162:            {
                   1163:                errmsg = (char_u *)"Unknown option";
                   1164:                goto skip;
                   1165:            }
                   1166:
                   1167:            if (opt_idx >= 0)
                   1168:            {
                   1169:                if (options[opt_idx].var == NULL)   /* hidden option: skip */
                   1170:                    goto skip;
                   1171:
                   1172:                flags = options[opt_idx].flags;
                   1173:                varp = get_varp(&(options[opt_idx]));
                   1174:            }
                   1175:            else
                   1176:                flags = P_STRING;
                   1177:
                   1178:            /* remember character after option name */
                   1179:            afterchar = nextchar;
                   1180:
                   1181:            /* skip white space, allow ":set ai  ?" */
                   1182:            while (vim_iswhite(nextchar))
                   1183:                nextchar = arg[++len];
                   1184:
                   1185:            if (vim_strchr((char_u *)"?=:!&", nextchar) != NULL)
                   1186:            {
                   1187:                arg += len;
                   1188:                len = 0;
                   1189:            }
                   1190:
                   1191:            /*
                   1192:             * allow '=' and ':' as MSDOS command.com allows only one
                   1193:             * '=' character per "set" command line. grrr. (jw)
                   1194:             */
                   1195:            if (nextchar == '?' || (prefix == 1 && vim_strchr((char_u *)"=:&",
                   1196:                                      nextchar) == NULL && !(flags & P_BOOL)))
                   1197:            {                                       /* print value */
                   1198:                if (did_show)
                   1199:                    msg_outchar('\n');      /* cursor below last one */
                   1200:                else
                   1201:                {
                   1202:                    gotocmdline(TRUE);      /* cursor at status line */
                   1203:                    did_show = TRUE;        /* remember that we did a line */
                   1204:                }
                   1205:                if (opt_idx >= 0)
                   1206:                    showoneopt(&options[opt_idx]);
                   1207:                else
                   1208:                {
                   1209:                    char_u          name[2];
                   1210:                    char_u          *p;
                   1211:
                   1212:                    name[0] = KEY2TERMCAP0(key);
                   1213:                    name[1] = KEY2TERMCAP1(key);
                   1214:                    p = find_termcode(name);
                   1215:                    if (p == NULL)
                   1216:                    {
                   1217:                        errmsg = (char_u *)"Unknown option";
                   1218:                        goto skip;
                   1219:                    }
                   1220:                    else
                   1221:                        (void)show_one_termcode(name, p, TRUE);
                   1222:                }
                   1223:                if (nextchar != '?' && nextchar != NUL &&
                   1224:                                                      !vim_iswhite(afterchar))
                   1225:                    errmsg = e_trailing;
                   1226:            }
                   1227:            else
                   1228:            {
                   1229:                if (flags & P_BOOL)                 /* boolean */
                   1230:                {
                   1231:                    if (nextchar == '=' || nextchar == ':')
                   1232:                    {
                   1233:                        errmsg = e_invarg;
                   1234:                        goto skip;
                   1235:                    }
                   1236:
                   1237:                    /*
                   1238:                     * in secure mode, setting of the secure option is not
                   1239:                     * allowed
                   1240:                     */
                   1241:                    if (secure && (int *)varp == &p_secure)
                   1242:                    {
                   1243:                        errmsg = (char_u *)"not allowed here";
                   1244:                        goto skip;
                   1245:                    }
                   1246:
                   1247:                    oldbin = curbuf->b_p_bin;   /* remember old bin option */
                   1248:
                   1249:                    /*
                   1250:                     * ":set opt!" or ":set invopt": invert
                   1251:                     * ":set opt&": reset to default value
                   1252:                     * ":set opt" or ":set noopt": set or reset
                   1253:                     */
                   1254:                    if (prefix == 2 || nextchar == '!')
                   1255:                        *(int *)(varp) ^= 1;
                   1256:                    else if (nextchar == '&')
                   1257:                                /* the cast to long is required for Manx C */
                   1258:                        *(int *)(varp) = (int)(long)options[opt_idx].def_val;
                   1259:                    else
                   1260:                        *(int *)(varp) = prefix;
                   1261:
                   1262:                    /* handle the setting of the compatible option */
                   1263:                    if ((int *)varp == &p_cp && p_cp)
                   1264:                    {
                   1265:                        p_compatible_set();
                   1266:                    }
                   1267:                    /* when 'readonly' is reset, also reset readonlymode */
                   1268:                    else if ((int *)varp == &curbuf->b_p_ro && !curbuf->b_p_ro)
                   1269:                        readonlymode = FALSE;
                   1270:
                   1271:                    /* when 'bin' is set also set some other options */
                   1272:                    else if ((int *)varp == &curbuf->b_p_bin)
                   1273:                    {
                   1274:                        set_options_bin(oldbin, curbuf->b_p_bin);
                   1275:                    }
                   1276:                    /* when 'terse' is set change 'shortmess' */
                   1277:                    else if ((int *)varp == &p_terse)
                   1278:                    {
                   1279:                        char_u  *p;
                   1280:
                   1281:                        p = vim_strchr(p_shm, SHM_SEARCH);
                   1282:
                   1283:                        /* insert 's' in p_shm */
                   1284:                        if (p_terse && p == NULL)
                   1285:                        {
                   1286:                            STRCPY(IObuff, p_shm);
                   1287:                            STRCAT(IObuff, "s");
                   1288:                            set_string_option((char_u *)"shm", -1,
                   1289:                                                                IObuff, TRUE);
                   1290:                        }
                   1291:                        /* remove 's' from p_shm */
                   1292:                        else if (!p_terse && p != NULL)
                   1293:                            vim_memmove(p, p + 1, STRLEN(p));
                   1294:                    }
                   1295:                    /* when 'paste' is set or reset also change other options */
                   1296:                    else if ((int *)varp == &p_paste)
                   1297:                    {
                   1298:                        paste_option_changed();
                   1299:                    }
                   1300:                    /*
                   1301:                     * When 'lisp' option changes include/exclude '-' in
                   1302:                     * keyword characters.
                   1303:                     */
                   1304:                    else if (varp == (char_u *)&(curbuf->b_p_lisp))
                   1305:                        init_chartab();     /* ignore errors */
                   1306:
                   1307:                    else if (!starting && ((int *)varp == &p_title ||
                   1308:                                                      (int *)varp == &p_icon))
                   1309:                    {
                   1310:                        /*
                   1311:                         * When setting 'title' or 'icon' on, call maketitle()
                   1312:                         * to create and display it.
                   1313:                         * When resetting 'title' or 'icon', call maketitle()
                   1314:                         * to clear it and call mch_restore_title() to get the
                   1315:                         * old value back.
                   1316:                         */
                   1317:                        maketitle();
                   1318:                        if (!*(int *)varp)
                   1319:                            mch_restore_title((int *)varp == &p_title ? 1 : 2);
                   1320:                    }
                   1321:                }
                   1322:                else                                /* numeric or string */
                   1323:                {
                   1324:                    if (vim_strchr((char_u *)"=:&", nextchar) == NULL ||
                   1325:                                                                  prefix != 1)
                   1326:                    {
                   1327:                        errmsg = e_invarg;
                   1328:                        goto skip;
                   1329:                    }
                   1330:                    if (flags & P_NUM)              /* numeric */
                   1331:                    {
                   1332:                        /*
                   1333:                         * Different ways to set a number option:
                   1334:                         * &        set to default value
                   1335:                         * <xx>     accept special key codes for 'wildchar'
                   1336:                         * c        accept any non-digit for 'wildchar'
                   1337:                         * 0-9      set number
                   1338:                         * other    error
                   1339:                         */
                   1340:                        arg += len + 1;
                   1341:                        if (nextchar == '&')
                   1342:                            *(long *)(varp) = (long)options[opt_idx].def_val;
                   1343:                        else if ((long *)varp == &p_wc &&
                   1344:                                                (*arg == '<' || *arg == '^' ||
                   1345:                                          ((!arg[1] || vim_iswhite(arg[1])) &&
                   1346:                                                             !isdigit(*arg))))
                   1347:                        {
                   1348:                            if (*arg == '<')
                   1349:                            {
                   1350:                                i = get_special_key_code(arg + 1);
                   1351:                                if (i == 0)
                   1352:                                    i = find_key_option(arg + 1);
                   1353:                            }
                   1354:                            else if (*arg == '^')
                   1355:                                i = arg[1] ^ 0x40;
                   1356:                            else
                   1357:                                i = *arg;
                   1358:                            if (i == 0)
                   1359:                            {
                   1360:                                errmsg = e_invarg;
                   1361:                                goto skip;
                   1362:                            }
                   1363:                            p_wc = i;
                   1364:                        }
                   1365:                                /* allow negative numbers (for 'undolevels') */
                   1366:                        else if (*arg == '-' || isdigit(*arg))
                   1367:                        {
                   1368:                            i = 0;
                   1369:                            if (*arg == '-')
                   1370:                                i = 1;
                   1371: #ifdef HAVE_STRTOL
                   1372:                            *(long *)(varp) = strtol((char *)arg, NULL, 0);
                   1373:                            if (arg[i] == '0' && TO_UPPER(arg[i + 1]) == 'X')
                   1374:                                i += 2;
                   1375: #else
                   1376:                            *(long *)(varp) = atol((char *)arg);
                   1377: #endif
                   1378:                            while (isdigit(arg[i]))
                   1379:                                ++i;
                   1380:                            if (arg[i] != NUL && !vim_iswhite(arg[i]))
                   1381:                            {
                   1382:                                errmsg = e_invarg;
                   1383:                                goto skip;
                   1384:                            }
                   1385:                        }
                   1386:                        else
                   1387:                        {
                   1388:                            errmsg = (char_u *)"Number required after =";
                   1389:                            goto skip;
                   1390:                        }
                   1391:
                   1392:                        /*
                   1393:                         * Number options that need some action when changed
                   1394:                         */
                   1395:                        if ((long *)varp == &p_wh || (long *)varp == &p_hh)
                   1396:                        {
                   1397:                            if (p_wh < 0)
                   1398:                            {
                   1399:                                errmsg = e_positive;
                   1400:                                p_wh = 0;
                   1401:                            }
                   1402:                            if (p_hh < 0)
                   1403:                            {
                   1404:                                errmsg = e_positive;
                   1405:                                p_hh = 0;
                   1406:                            }
                   1407:                                /* Change window height NOW */
                   1408:                            if (p_wh && lastwin != firstwin)
                   1409:                            {
                   1410:                                win_equal(curwin, FALSE);
                   1411:                                must_redraw = CLEAR;
                   1412:                            }
                   1413:                        }
                   1414:                        /* (re)set last window status line */
                   1415:                        if ((long *)varp == &p_ls)
                   1416:                            last_status();
                   1417:                    }
                   1418:                    else if (opt_idx >= 0)                  /* string */
                   1419:                    {
                   1420:                        char_u      *save_arg = NULL;
                   1421:                        char_u      *s, *p;
                   1422:                        int         new_value_alloced;  /* new string option
                   1423:                                                           was allocated */
                   1424:
                   1425:                        /* The old value is kept until we are sure that the new
                   1426:                         * value is valid. set_option_default() is therefore
                   1427:                         * called with FALSE
                   1428:                         */
                   1429:                        oldval = *(char_u **)(varp);
                   1430:                        if (nextchar == '&')        /* set to default val */
                   1431:                        {
                   1432:                            set_option_default(opt_idx, FALSE);
                   1433:                            new_value_alloced =
                   1434:                                         (options[opt_idx].flags & P_ALLOCED);
                   1435:                        }
                   1436:                        else
                   1437:                        {
                   1438:                            arg += len + 1; /* jump to after the '=' or ':' */
                   1439:
                   1440:                            /*
                   1441:                             * Convert 'whichwrap' number to string, for
                   1442:                             * backwards compatibility with Vim 3.0.
                   1443:                             * Misuse errbuf[] for the resulting string.
                   1444:                             */
                   1445:                            if (varp == (char_u *)&p_ww && isdigit(*arg))
                   1446:                            {
                   1447:                                *errbuf = NUL;
                   1448:                                i = getdigits(&arg);
                   1449:                                if (i & 1)
                   1450:                                    STRCAT(errbuf, "b,");
                   1451:                                if (i & 2)
                   1452:                                    STRCAT(errbuf, "s,");
                   1453:                                if (i & 4)
                   1454:                                    STRCAT(errbuf, "h,l,");
                   1455:                                if (i & 8)
                   1456:                                    STRCAT(errbuf, "<,>,");
                   1457:                                if (i & 16)
                   1458:                                    STRCAT(errbuf, "[,],");
                   1459:                                if (*errbuf != NUL)     /* remove trailing , */
                   1460:                                    errbuf[STRLEN(errbuf) - 1] = NUL;
                   1461:                                save_arg = arg;
                   1462:                                arg = errbuf;
                   1463:                            }
                   1464:                            /*
                   1465:                             * Remove '>' before 'dir' and 'bdir', for
                   1466:                             * backwards compatibility with version 3.0
                   1467:                             */
                   1468:                            else if (*arg == '>' && (varp == (char_u *)&p_dir ||
                   1469:                                                   varp == (char_u *)&p_bdir))
                   1470:                            {
                   1471:                                ++arg;
                   1472:                            }
                   1473:
                   1474:                            /*
                   1475:                             * Copy the new string into allocated memory.
                   1476:                             * Can't use set_string_option(), because we need
                   1477:                             * to remove the backslashes.
                   1478:                             */
                   1479:                                                /* get a bit too much */
                   1480:                            s = alloc((unsigned)(STRLEN(arg) + 1));
                   1481:                            if (s == NULL)  /* out of memory, don't change */
                   1482:                                break;
                   1483:                            *(char_u **)(varp) = s;
                   1484:
                   1485:                            /*
                   1486:                             * Copy the string, skip over escaped chars.
                   1487:                             * For MS-DOS and WIN32 backslashes before normal
                   1488:                             * file name characters are not removed.
                   1489:                             */
                   1490:                            while (*arg && !vim_iswhite(*arg))
                   1491:                            {
                   1492:                                if (*arg == '\\' && arg[1] != NUL
                   1493: #ifdef BACKSLASH_IN_FILENAME
                   1494:                                        && !((flags & P_EXPAND)
                   1495:                                                && isfilechar(arg[1])
                   1496:                                                && arg[1] != '\\')
                   1497: #endif
                   1498:                                                                    )
                   1499:                                    ++arg;
                   1500:                                *s++ = *arg++;
                   1501:                            }
                   1502:                            *s = NUL;
                   1503:                            if (save_arg != NULL)   /* number for 'whichwrap' */
                   1504:                                arg = save_arg;
                   1505:                            new_value_alloced = TRUE;
                   1506:                        }
                   1507:
                   1508:                            /* expand environment variables and ~ */
                   1509:                        s = option_expand(opt_idx);
                   1510:                        if (s != NULL)
                   1511:                        {
                   1512:                            if (new_value_alloced)
                   1513:                                vim_free(*(char_u **)(varp));
                   1514:                            *(char_u **)(varp) = s;
                   1515:                            new_value_alloced = TRUE;
                   1516:                        }
                   1517:
                   1518:                        /*
                   1519:                         * options that need some action
                   1520:                         * to perform when changed (jw)
                   1521:                         */
                   1522:                        if (varp == (char_u *)&term_strings[KS_NAME])
                   1523:                        {
                   1524:                            if (term_strings[KS_NAME][0] == NUL)
                   1525:                                errmsg = (char_u *)"Cannot set 'term' to empty string";
                   1526: #ifdef USE_GUI
                   1527:                            if (gui.in_use)
                   1528:                                errmsg = (char_u *)"Cannot change term in GUI";
                   1529: #endif
                   1530:                            else if (set_termname(term_strings[KS_NAME]) ==
                   1531:                                                                         FAIL)
                   1532:                                errmsg = (char_u *)"Not found in termcap";
                   1533:                            else
                   1534:                            {
                   1535:                                /* Screen colors may have changed. */
                   1536:                                outstr(T_ME);
                   1537:                                updateScreen(CLEAR);
                   1538:                            }
                   1539:                        }
                   1540:
                   1541:                        else if ((varp == (char_u *)&p_bex ||
                   1542:                                                     varp == (char_u *)&p_pm))
                   1543:                        {
                   1544:                            if (STRCMP(*p_bex == '.' ? p_bex + 1 : p_bex,
                   1545:                                         *p_pm == '.' ? p_pm + 1 : p_pm) == 0)
                   1546:                                errmsg = (char_u *)"'backupext' and 'patchmode' are equal";
                   1547:                        }
                   1548:                        /*
                   1549:                         * 'isident', 'iskeyword', 'isprint or 'isfname'
                   1550:                         *  option: refill chartab[]
                   1551:                         * If the new option is invalid, use old value.
                   1552:                         * 'lisp' option: refill chartab[] for '-' char
                   1553:                         */
                   1554:                        else if (varp == (char_u *)&p_isi ||
                   1555:                                 varp == (char_u *)&(curbuf->b_p_isk) ||
                   1556:                                 varp == (char_u *)&p_isp ||
                   1557:                                 varp == (char_u *)&p_isf)
                   1558:                        {
                   1559:                            if (init_chartab() == FAIL)
                   1560:                                errmsg = e_invarg;      /* error in value */
                   1561:                        }
                   1562:                        else if (varp == (char_u *)&p_hl)
                   1563:                        {
                   1564:                            /* Check 'highlight' */
                   1565:                            for (s = p_hl; *s; )
                   1566:                            {
                   1567:                                if (vim_strchr((char_u *)"8dehmMnrstvw",
                   1568:                                                        (i = s[0])) == NULL ||
                   1569:                                    vim_strchr((char_u *)"bsnuir",
                   1570:                                                        (i = s[1])) == NULL ||
                   1571:                                              ((i = s[2]) != NUL && i != ','))
                   1572:                                {
                   1573:                                    illegal_char(errbuf, i);
                   1574:                                    errmsg = errbuf;
                   1575:                                    break;
                   1576:                                }
                   1577:                                if (s[2] == NUL)
                   1578:                                    break;
                   1579:                                s = skipwhite(s + 3);
                   1580:                            }
                   1581:                        }
                   1582:                        else if (varp == (char_u *)&(curbuf->b_p_com))
                   1583:                        {
                   1584:                            for (s = curbuf->b_p_com; *s; )
                   1585:                            {
                   1586:                                while (*s && *s != ':')
                   1587:                                {
                   1588:                                    if (vim_strchr((char_u *)COM_ALL, *s) == NULL)
                   1589:                                    {
                   1590:                                        errmsg = (char_u *)"Illegal flag";
                   1591:                                        break;
                   1592:                                    }
                   1593:                                    ++s;
                   1594:                                }
                   1595:                                if (*s++ == NUL)
                   1596:                                    errmsg = (char_u *)"Missing colon";
                   1597:                                else if (*s == ',')
                   1598:                                    errmsg = (char_u *)"Zero length string";
                   1599:                                if (errmsg != NULL)
                   1600:                                    break;
                   1601:                                while (*s && *s != ',')
                   1602:                                {
                   1603:                                    if (*s == '\\' && s[1] != NUL)
                   1604:                                        ++s;
                   1605:                                    ++s;
                   1606:                                }
                   1607:                                s = skip_to_option_part(s);
                   1608:                            }
                   1609:                        }
                   1610: #ifdef VIMINFO
                   1611:                        else if (varp == (char_u *)&(p_viminfo))
                   1612:                        {
                   1613:                            for (s = p_viminfo; *s;)
                   1614:                            {
                   1615:                                /* Check it's a valid character */
                   1616:                                if (vim_strchr((char_u *)"\"'fr:/", *s) == NULL)
                   1617:                                {
                   1618:                                    illegal_char(errbuf, *s);
                   1619:                                    errmsg = errbuf;
                   1620:                                    break;
                   1621:                                }
                   1622:                                if (*s == 'r')
                   1623:                                {
                   1624:                                    while (*++s && *s != ',')
                   1625:                                        ;
                   1626:                                }
                   1627:                                else
                   1628:                                {
                   1629:                                    while (isdigit(*++s))
                   1630:                                        ;
                   1631:
                   1632:                                    /* Must be a number after the character */
                   1633:                                    if (!isdigit(*(s - 1)))
                   1634:                                    {
                   1635:                                        sprintf((char *)errbuf,
                   1636:                                                "Missing number after <%s>",
                   1637:                                                transchar(*(s - 1)));
                   1638:                                        errmsg = errbuf;
                   1639:                                        break;
                   1640:                                    }
                   1641:                                }
                   1642:                                s = skip_to_option_part(s);
                   1643:                            }
                   1644:                            if (*p_viminfo && errmsg == NULL
                   1645:                                            && get_viminfo_parameter('\'') < 0)
                   1646:                                errmsg = (char_u *)"Must specify a ' value";
                   1647:                        }
                   1648: #endif /* VIMINFO */
                   1649:                        else if (istermoption(&options[opt_idx]) && full_screen)
                   1650:                        {
                   1651:                            ttest(FALSE);
                   1652:                            if (varp == (char_u *)&term_strings[KS_ME])
                   1653:                            {
                   1654:                                outstr(T_ME);
                   1655:                                updateScreen(CLEAR);
                   1656:                            }
                   1657:                        }
                   1658:                        else if (varp == (char_u *)&p_sbr)
                   1659:                        {
                   1660:                            for (s = p_sbr; *s; ++s)
                   1661:                                if (charsize(*s) != 1)
                   1662:                                    errmsg = (char_u *)"contains unprintable character";
                   1663:                        }
                   1664: #ifdef USE_GUI
                   1665:                        else if (varp == (char_u *)&p_guifont)
                   1666:                        {
                   1667:                            gui_init_font();
                   1668:                        }
                   1669: #endif /* USE_GUI */
                   1670: #ifdef HAVE_LANGMAP
                   1671:                        else if (varp == (char_u *)&p_langmap)
                   1672:                            langmap_set();
                   1673: #endif
                   1674:                        else if (varp == (char_u *)&p_breakat)
                   1675:                            fill_breakat_flags();
                   1676:                        else
                   1677:                        {
                   1678:                            /*
                   1679:                             * Check options that are a list of flags.
                   1680:                             */
                   1681:                            p = NULL;
                   1682:                            if (varp == (char_u *)&p_ww)
                   1683:                                p = (char_u *)WW_ALL;
                   1684:                            if (varp == (char_u *)&p_shm)
                   1685:                                p = (char_u *)SHM_ALL;
                   1686:                            else if (varp == (char_u *)&(p_cpo))
                   1687:                                p = (char_u *)CPO_ALL;
                   1688:                            else if (varp == (char_u *)&(curbuf->b_p_fo))
                   1689:                                p = (char_u *)FO_ALL;
                   1690:                            else if (varp == (char_u *)&p_mouse)
                   1691:                            {
                   1692: #ifdef USE_MOUSE
                   1693:                                p = (char_u *)MOUSE_ALL;
                   1694: #else
                   1695:                                if (*p_mouse != NUL)
                   1696:                                    errmsg = (char_u *)"No mouse support";
                   1697: #endif
                   1698:                            }
                   1699: #ifdef USE_GUI
                   1700:                            else if (varp == (char_u *)&p_guioptions)
                   1701:                                p = (char_u *)GO_ALL;
                   1702: #endif /* USE_GUI */
                   1703:                            if (p != NULL)
                   1704:                            {
                   1705:                                for (s = *(char_u **)(varp); *s; ++s)
                   1706:                                    if (vim_strchr(p, *s) == NULL)
                   1707:                                    {
                   1708:                                        illegal_char(errbuf, *s);
                   1709:                                        errmsg = errbuf;
                   1710:                                        break;
                   1711:                                    }
                   1712:                            }
                   1713:                        }
                   1714:                        if (errmsg != NULL) /* error detected */
                   1715:                        {
                   1716:                            if (new_value_alloced)
                   1717:                                vim_free(*(char_u **)(varp));
                   1718:                            *(char_u **)(varp) = oldval;
                   1719:                            (void)init_chartab();   /* back to the old value */
                   1720:                            goto skip;
                   1721:                        }
                   1722:
                   1723: #ifdef USE_GUI
                   1724:                        if (varp == (char_u *)&p_guioptions)
                   1725:                            gui_init_which_components(oldval);
                   1726: #endif /* USE_GUI */
                   1727:
                   1728:                        /*
                   1729:                         * Free string options that are in allocated memory.
                   1730:                         */
                   1731:                        if (flags & P_ALLOCED)
                   1732:                            free_string_option(oldval);
                   1733:                        if (new_value_alloced)
                   1734:                            options[opt_idx].flags |= P_ALLOCED;
                   1735:                    }
                   1736:                    else            /* key code option */
                   1737:                    {
                   1738:                        char_u      name[2];
                   1739:                        char_u      *p;
                   1740:
                   1741:                        name[0] = KEY2TERMCAP0(key);
                   1742:                        name[1] = KEY2TERMCAP1(key);
                   1743:                        if (nextchar == '&')
                   1744:                        {
                   1745:                            if (add_termcap_entry(name, TRUE) == FAIL)
                   1746:                                errmsg = (char_u *)"Not found in termcap";
                   1747:                        }
                   1748:                        else
                   1749:                        {
                   1750:                            arg += len + 1; /* jump to after the '=' or ':' */
                   1751:                            for(p = arg; *p && !vim_iswhite(*p); ++p)
                   1752:                            {
                   1753:                                if (*p == '\\' && *(p + 1))
                   1754:                                    ++p;
                   1755:                            }
                   1756:                            nextchar = *p;
                   1757:                            *p = NUL;
                   1758:                            add_termcode(name, arg);
                   1759:                            *p = nextchar;
                   1760:                        }
                   1761:                        if (full_screen)
                   1762:                            ttest(FALSE);
                   1763:                    }
                   1764:                }
                   1765:                if (opt_idx >= 0)
                   1766:                    options[opt_idx].flags |= P_WAS_SET;
                   1767:            }
                   1768:
                   1769: skip:
                   1770:            /*
                   1771:             * Check the bounds for numeric options here
                   1772:             */
                   1773:            if (Rows < min_rows() && full_screen)
                   1774:            {
                   1775:                sprintf((char *)errbuf, "Need at least %d lines", min_rows());
                   1776:                errmsg = errbuf;
                   1777:                Rows = min_rows();
                   1778:            }
                   1779:            if (Columns < MIN_COLUMNS && full_screen)
                   1780:            {
                   1781:                sprintf((char *)errbuf, "Need at least %d columns",
                   1782:                                                                 MIN_COLUMNS);
                   1783:                errmsg = errbuf;
                   1784:                Columns = MIN_COLUMNS;
                   1785:            }
                   1786:            /*
                   1787:             * If the screenheight has been changed, assume it is the physical
                   1788:             * screenheight.
                   1789:             */
                   1790:            if ((oldRows != Rows || oldColumns != Columns) && full_screen)
                   1791:            {
                   1792:                mch_set_winsize();          /* try to change the window size */
                   1793:                check_winsize();            /* in case 'columns' changed */
                   1794: #ifdef MSDOS
                   1795:                set_window();       /* active window may have changed */
                   1796: #endif
                   1797:            }
                   1798:
                   1799:            if (curbuf->b_p_ts <= 0)
                   1800:            {
                   1801:                errmsg = e_positive;
                   1802:                curbuf->b_p_ts = 8;
                   1803:            }
                   1804:            if (curbuf->b_p_tw < 0)
                   1805:            {
                   1806:                errmsg = e_positive;
                   1807:                curbuf->b_p_tw = 0;
                   1808:            }
                   1809:            if (p_tm < 0)
                   1810:            {
                   1811:                errmsg = e_positive;
                   1812:                p_tm = 0;
                   1813:            }
                   1814:            if ((curwin->w_p_scroll <= 0 ||
                   1815:                        curwin->w_p_scroll > curwin->w_height) && full_screen)
                   1816:            {
                   1817:                if (curwin->w_p_scroll != 0)
                   1818:                    errmsg = e_scroll;
                   1819:                win_comp_scroll(curwin);
                   1820:            }
                   1821:            if (p_report < 0)
                   1822:            {
                   1823:                errmsg = e_positive;
                   1824:                p_report = 1;
                   1825:            }
                   1826:            if ((p_sj < 0 || p_sj >= Rows) && full_screen)
                   1827:            {
                   1828:                if (Rows != oldRows)        /* Rows changed, just adjust p_sj */
                   1829:                    p_sj = Rows / 2;
                   1830:                else
                   1831:                {
                   1832:                    errmsg = e_scroll;
                   1833:                    p_sj = 1;
                   1834:                }
                   1835:            }
                   1836:            if (p_so < 0 && full_screen)
                   1837:            {
                   1838:                errmsg = e_scroll;
                   1839:                p_so = 0;
                   1840:            }
                   1841:            if (p_uc < 0)
                   1842:            {
                   1843:                errmsg = e_positive;
                   1844:                p_uc = 100;
                   1845:            }
                   1846:            if (p_ch < 1)
                   1847:            {
                   1848:                errmsg = e_positive;
                   1849:                p_ch = 1;
                   1850:            }
                   1851:            if (p_ut < 0)
                   1852:            {
                   1853:                errmsg = e_positive;
                   1854:                p_ut = 2000;
                   1855:            }
                   1856:            if (p_ss < 0)
                   1857:            {
                   1858:                errmsg = e_positive;
                   1859:                p_ss = 0;
                   1860:            }
                   1861:
                   1862:            /*
                   1863:             * Advance to next argument.
                   1864:             * - skip until a blank found, taking care of backslashes
                   1865:             * - skip blanks
                   1866:             */
                   1867:            while (*arg != NUL && !vim_iswhite(*arg))
                   1868:                if (*arg++ == '\\' && *arg != NUL)
                   1869:                    ++arg;
                   1870:        }
                   1871:        arg = skipwhite(arg);
                   1872:
                   1873:        if (errmsg)
                   1874:        {
                   1875:            ++no_wait_return;   /* wait_return done below */
                   1876: #ifdef SLEEP_IN_EMSG
                   1877:            ++dont_sleep;       /* don't wait in emsg() */
                   1878: #endif
                   1879:            emsg(errmsg);       /* show error highlighted */
                   1880: #ifdef SLEEP_IN_EMSG
                   1881:            --dont_sleep;
                   1882: #endif
                   1883:            MSG_OUTSTR(": ");
                   1884:                                /* show argument normal */
                   1885:            while (startarg < arg)
                   1886:                msg_outstr(transchar(*startarg++));
                   1887:            msg_end();          /* check for scrolling */
                   1888:            --no_wait_return;
                   1889:
                   1890:            ++errcnt;           /* count number of errors */
                   1891:            did_show = TRUE;    /* error message counts as show */
                   1892:            if (sourcing_name != NULL)
                   1893:                break;
                   1894:        }
                   1895:    }
                   1896:
                   1897:    /*
                   1898:     * when 'updatecount' changes from zero to non-zero, open swap files
                   1899:     */
                   1900:    if (p_uc && !olduc)
                   1901:        ml_open_files();
                   1902:
                   1903:    if (p_ch != oldch)              /* p_ch changed value */
                   1904:        command_height();
                   1905: #ifdef USE_MOUSE
                   1906:    if (*p_mouse == NUL)
                   1907:        mch_setmouse(FALSE);        /* switch mouse off */
                   1908:    else
                   1909:        setmouse();                 /* in case 'mouse' changed */
                   1910: #endif
                   1911:    comp_col();                     /* in case 'ruler' or 'showcmd' changed */
                   1912:    curwin->w_set_curswant = TRUE;  /* in case 'list' changed */
                   1913:
                   1914:    /*
                   1915:     * Update the screen in case we changed something like "tabstop" or
                   1916:     * "lines" or "list" that will change its appearance.
                   1917:     * Also update the cursor position, in case 'wrap' is changed.
                   1918:     */
                   1919:    for (wp = firstwin; wp; wp = wp->w_next)
                   1920:        wp->w_redr_status = TRUE;       /* mark all status lines dirty */
                   1921:    if (p_ea && !oldea)
                   1922:        win_equal(curwin, FALSE);
                   1923:    updateScreen(CURSUPD);
                   1924:    return (errcnt == 0 ? OK : FAIL);
                   1925: }
                   1926:
                   1927:    static void
                   1928: illegal_char(errbuf, c)
                   1929:    char_u      *errbuf;
                   1930:    int         c;
                   1931: {
                   1932:    sprintf((char *)errbuf, "Illegal character <%s>", (char *)transchar(c));
                   1933: }
                   1934:
                   1935: /*
                   1936:  * set_options_bin -  called when 'bin' changes value.
                   1937:  */
                   1938:    void
                   1939: set_options_bin(oldval, newval)
                   1940:    int     oldval;
                   1941:    int     newval;
                   1942: {
                   1943:    /*
                   1944:     * The option values that are changed when 'bin' changes are
                   1945:     * copied when 'bin is set and restored when 'bin' is reset.
                   1946:     */
                   1947:    if (newval)
                   1948:    {
                   1949:        if (!oldval)            /* switched on */
                   1950:        {
                   1951:            curbuf->b_p_tw_nobin = curbuf->b_p_tw;
                   1952:            curbuf->b_p_wm_nobin = curbuf->b_p_wm;
                   1953:            curbuf->b_p_tx_nobin = curbuf->b_p_tx;
                   1954:            curbuf->b_p_ta_nobin = p_ta;
                   1955:            curbuf->b_p_ml_nobin = curbuf->b_p_ml;
                   1956:            curbuf->b_p_et_nobin = curbuf->b_p_et;
                   1957:        }
                   1958:
                   1959:        curbuf->b_p_tw = 0;     /* no automatic line wrap */
                   1960:        curbuf->b_p_wm = 0;     /* no automatic line wrap */
                   1961:        curbuf->b_p_tx = 0;     /* no text mode */
                   1962:        p_ta           = 0;     /* no text auto */
                   1963:        curbuf->b_p_ml = 0;     /* no modelines */
                   1964:        curbuf->b_p_et = 0;     /* no expandtab */
                   1965:    }
                   1966:    else if (oldval)            /* switched off */
                   1967:    {
                   1968:        curbuf->b_p_tw = curbuf->b_p_tw_nobin;
                   1969:        curbuf->b_p_wm = curbuf->b_p_wm_nobin;
                   1970:        curbuf->b_p_tx = curbuf->b_p_tx_nobin;
                   1971:        p_ta           = curbuf->b_p_ta_nobin;
                   1972:        curbuf->b_p_ml = curbuf->b_p_ml_nobin;
                   1973:        curbuf->b_p_et = curbuf->b_p_et_nobin;
                   1974:    }
                   1975: }
                   1976:
                   1977: #ifdef VIMINFO
                   1978: /*
                   1979:  * Find the parameter represented by the given character (eg ', :, ", or /),
                   1980:  * and return its associated value in the 'viminfo' string.  If the parameter
                   1981:  * is not specified in the string, return -1.
                   1982:  */
                   1983:    int
                   1984: get_viminfo_parameter(type)
                   1985:    int     type;
                   1986: {
                   1987:    char_u  *p;
                   1988:
                   1989:    p = vim_strchr(p_viminfo, type);
                   1990:    if (p != NULL && isdigit(*++p))
                   1991:        return (int)atol((char *)p);
                   1992:    return -1;
                   1993: }
                   1994: #endif
                   1995:
                   1996: /*
                   1997:  * Expand environment variables for some string options.
                   1998:  * These string options cannot be indirect!
                   1999:  * Return pointer to allocated memory, or NULL when not expanded.
                   2000:  */
                   2001:    static char_u *
                   2002: option_expand(opt_idx)
                   2003:    int     opt_idx;
                   2004: {
                   2005:    char_u      *p;
                   2006:
                   2007:        /* if option doesn't need expansion or is hidden: nothing to do */
                   2008:    if (!(options[opt_idx].flags & P_EXPAND) || options[opt_idx].var == NULL)
                   2009:        return NULL;
                   2010:
                   2011:    p = *(char_u **)(options[opt_idx].var);
                   2012:
                   2013:    /*
                   2014:     * Expanding this with NameBuff, expand_env() must not be passed IObuff.
                   2015:     */
                   2016:    expand_env(p, NameBuff, MAXPATHL);
                   2017:    if (STRCMP(NameBuff, p) == 0)   /* they are the same */
                   2018:        return NULL;
                   2019:
                   2020:    return strsave(NameBuff);
                   2021: }
                   2022:
                   2023: /*
                   2024:  * Check for string options that are NULL (normally only termcap options).
                   2025:  */
                   2026:    void
                   2027: check_options()
                   2028: {
                   2029:    int     opt_idx;
                   2030:    char_u  **p;
                   2031:
                   2032:    for (opt_idx = 0; options[opt_idx].fullname != NULL; opt_idx++)
                   2033:        if ((options[opt_idx].flags & P_STRING) && options[opt_idx].var != NULL)
                   2034:        {
                   2035:            p = (char_u **)get_varp(&(options[opt_idx]));
                   2036:            if (*p == NULL)
                   2037:                *p = empty_option;
                   2038:        }
                   2039: }
                   2040:
                   2041: /*
                   2042:  * Check string options in a buffer for NULL value.
                   2043:  */
                   2044:    void
                   2045: check_buf_options(buf)
                   2046:    BUF     *buf;
                   2047: {
                   2048:    if (buf->b_p_fo == NULL)
                   2049:        buf->b_p_fo = empty_option;
                   2050:    if (buf->b_p_isk == NULL)
                   2051:        buf->b_p_isk = empty_option;
                   2052:    if (buf->b_p_com == NULL)
                   2053:        buf->b_p_com = empty_option;
                   2054: #ifdef CINDENT
                   2055:    if (buf->b_p_cink == NULL)
                   2056:        buf->b_p_cink = empty_option;
                   2057:    if (buf->b_p_cino == NULL)
                   2058:        buf->b_p_cino = empty_option;
                   2059: #endif
                   2060: #if defined(SMARTINDENT) || defined(CINDENT)
                   2061:    if (buf->b_p_cinw == NULL)
                   2062:        buf->b_p_cinw = empty_option;
                   2063: #endif
                   2064: }
                   2065:
                   2066: /*
                   2067:  * Free the string allocated for an option.
                   2068:  * Checks for the string being empty_option. This may happen if we're out of
                   2069:  * memory, strsave() returned NULL, which was replaced by empty_option by
                   2070:  * check_options().
                   2071:  * Does NOT check for P_ALLOCED flag!
                   2072:  */
                   2073:    void
                   2074: free_string_option(p)
                   2075:    char_u      *p;
                   2076: {
                   2077:    if (p != empty_option)
                   2078:        vim_free(p);
                   2079: }
                   2080:
                   2081: /*
                   2082:  * Set a string option to a new value.
                   2083:  * The string is copied into allocated memory.
                   2084:  * If 'dofree' is set, the old value may be freed.
                   2085:  * if (opt_idx == -1) name is used, otherwise opt_idx is used.
                   2086:  */
                   2087:    void
                   2088: set_string_option(name, opt_idx, val, dofree)
                   2089:    char_u  *name;
                   2090:    int     opt_idx;
                   2091:    char_u  *val;
                   2092:    int     dofree;
                   2093: {
                   2094:    char_u  *s;
                   2095:    char_u  **varp;
                   2096:
                   2097:    if (opt_idx == -1)          /* use name */
                   2098:    {
                   2099:        opt_idx = findoption(name);
                   2100:        if (opt_idx == -1)      /* not found (should not happen) */
                   2101:            return;
                   2102:    }
                   2103:
                   2104:    if (options[opt_idx].var == NULL)   /* don't set hidden option */
                   2105:        return;
                   2106:
                   2107:    s = strsave(val);
                   2108:    if (s != NULL)
                   2109:    {
                   2110:        varp = (char_u **)get_varp(&(options[opt_idx]));
                   2111:        if (dofree && (options[opt_idx].flags & P_ALLOCED))
                   2112:            free_string_option(*varp);
                   2113:        *varp = s;
                   2114:            /* if 'term' option set for the first time: set default value */
                   2115:        if (varp == &(term_strings[KS_NAME]) &&
                   2116:                                           *(options[opt_idx].def_val) == NUL)
                   2117:        {
                   2118:            options[opt_idx].def_val = s;
                   2119:            options[opt_idx].flags |= P_DEF_ALLOCED;
                   2120:        }
                   2121:        else
                   2122:            options[opt_idx].flags |= P_ALLOCED;
                   2123:    }
                   2124: }
                   2125:
                   2126: /*
                   2127:  * find index for option 'arg'
                   2128:  * return -1 if not found
                   2129:  */
                   2130:    static int
                   2131: findoption(arg)
                   2132:    char_u *arg;
                   2133: {
                   2134:    int     opt_idx;
                   2135:    char    *s;
                   2136:
                   2137:    for (opt_idx = 0; (s = options[opt_idx].fullname) != NULL; opt_idx++)
                   2138:    {
                   2139:        if (STRCMP(arg, s) == 0) /* match full name */
                   2140:            break;
                   2141:    }
                   2142:    if (s == NULL)
                   2143:    {
                   2144:        for (opt_idx = 0; options[opt_idx].fullname != NULL; opt_idx++)
                   2145:        {
                   2146:            s = options[opt_idx].shortname;
                   2147:            if (s != NULL && STRCMP(arg, s) == 0) /* match short name */
                   2148:                break;
                   2149:            s = NULL;
                   2150:        }
                   2151:    }
                   2152:    if (s == NULL)
                   2153:        opt_idx = -1;
                   2154:    return opt_idx;
                   2155: }
                   2156:
                   2157:    char_u *
                   2158: get_highlight_default()
                   2159: {
                   2160:    int i;
                   2161:
                   2162:    i = findoption((char_u *)"hl");
                   2163:    if (i >= 0)
                   2164:        return options[i].def_val;
                   2165:    return (char_u *)NULL;
                   2166: }
                   2167:
                   2168:    static int
                   2169: find_key_option(arg)
                   2170:    char_u *arg;
                   2171: {
                   2172:    int         key;
                   2173:    int         c;
                   2174:
                   2175:    /* don't use get_special_key_code() for t_xx, we don't want it to call
                   2176:     * add_termcap_entry() */
                   2177:    if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
                   2178:        key = TERMCAP2KEY(arg[2], arg[3]);
                   2179:
                   2180:    /* <S-Tab> is a special case, because TAB isn't a special key */
                   2181:    else if (vim_strnicmp(arg, (char_u *)"S-Tab", (size_t)5) == 0)
                   2182:        key = K_S_TAB;
                   2183:    else
                   2184:    {
                   2185:        /* Currently only the shift modifier is recognized */
                   2186:        mod_mask = 0;
                   2187:        if (TO_LOWER(arg[0]) == 's' && arg[1] == '-')
                   2188:        {
                   2189:            mod_mask = MOD_MASK_SHIFT;
                   2190:            arg += 2;
                   2191:        }
                   2192:        c = get_special_key_code(arg);
                   2193:        key = check_shifted_spec_key(c);
                   2194:        if (mod_mask && c == key)           /* key can't be shifted */
                   2195:            key = 0;
                   2196:    }
                   2197:    return key;
                   2198: }
                   2199:
                   2200: /*
                   2201:  * if 'all' == 0: show changed options
                   2202:  * if 'all' == 1: show all normal options
                   2203:  * if 'all' == 2: show all terminal options
                   2204:  */
                   2205:    static void
                   2206: showoptions(all)
                   2207:    int         all;
                   2208: {
                   2209:    struct option   *p;
                   2210:    int             col;
                   2211:    int             isterm;
                   2212:    char_u          *varp;
                   2213:    struct option   **items;
                   2214:    int             item_count;
                   2215:    int             run;
                   2216:    int             row, rows;
                   2217:    int             cols;
                   2218:    int             i;
                   2219:    int             len;
                   2220:
                   2221: #define INC    20
                   2222: #define GAP 3
                   2223:
                   2224:    items = (struct option **)alloc((unsigned)(sizeof(struct option *) *
                   2225:                                                                PARAM_COUNT));
                   2226:    if (items == NULL)
                   2227:        return;
                   2228:
                   2229:    set_highlight('t');     /* Highlight title */
                   2230:    start_highlight();
                   2231:    if (all == 2)
                   2232:        MSG_OUTSTR("\n--- Terminal codes ---");
                   2233:    else
                   2234:        MSG_OUTSTR("\n--- Options ---");
                   2235:    stop_highlight();
                   2236:
                   2237:    /*
                   2238:     * do the loop two times:
                   2239:     * 1. display the short items
                   2240:     * 2. display the long items (only strings and numbers)
                   2241:     */
                   2242:    for (run = 1; run <= 2 && !got_int; ++run)
                   2243:    {
                   2244:        /*
                   2245:         * collect the items in items[]
                   2246:         */
                   2247:        item_count = 0;
                   2248:        for (p = &options[0]; p->fullname != NULL; p++)
                   2249:        {
                   2250:            isterm = istermoption(p);
                   2251:            varp = get_varp(p);
                   2252:            if (varp != NULL && (
                   2253:                (all == 2 && isterm) ||
                   2254:                (all == 1 && !isterm) ||
                   2255:                (all == 0 && option_changed(p))))
                   2256:            {
                   2257:                if (p->flags & P_BOOL)
                   2258:                    len = 1;            /* a toggle option fits always */
                   2259:                else
                   2260:                {
                   2261:                    option_value2string(p);
                   2262:                    len = STRLEN(p->fullname) + strsize(NameBuff) + 1;
                   2263:                }
                   2264:                if ((len <= INC - GAP && run == 1) ||
                   2265:                                                (len > INC - GAP && run == 2))
                   2266:                    items[item_count++] = p;
                   2267:            }
                   2268:        }
                   2269:
                   2270:        /*
                   2271:         * display the items
                   2272:         */
                   2273:        if (run == 1)
                   2274:        {
                   2275:            cols = (Columns + GAP - 3) / INC;
                   2276:            if (cols == 0)
                   2277:                cols = 1;
                   2278:            rows = (item_count + cols - 1) / cols;
                   2279:        }
                   2280:        else    /* run == 2 */
                   2281:            rows = item_count;
                   2282:        for (row = 0; row < rows && !got_int; ++row)
                   2283:        {
                   2284:            msg_outchar('\n');                      /* go to next line */
                   2285:            if (got_int)                            /* 'q' typed in more */
                   2286:                break;
                   2287:            col = 0;
                   2288:            for (i = row; i < item_count; i += rows)
                   2289:            {
                   2290:                msg_pos(-1, col);                   /* make columns */
                   2291:                showoneopt(items[i]);
                   2292:                col += INC;
                   2293:            }
                   2294:            flushbuf();
                   2295:            mch_breakcheck();
                   2296:        }
                   2297:    }
                   2298:    vim_free(items);
                   2299: }
                   2300:
                   2301: /*
                   2302:  * Return TRUE if option is different from the default value
                   2303:  */
                   2304:    static int
                   2305: option_changed(p)
                   2306:    struct option   *p;
                   2307: {
                   2308:    char_u  *varp;
                   2309:
                   2310:    varp = get_varp(p);
                   2311:    if (varp == NULL)
                   2312:        return FALSE;   /* hidden option is never changed */
                   2313:
                   2314:    if (p->flags & P_NUM)
                   2315:        return (*(long *)varp != (long)p->def_val);
                   2316:    if (p->flags & P_BOOL)
                   2317:                        /* the cast to long is required for Manx C */
                   2318:        return (*(int *)varp != (int)(long)p->def_val);
                   2319:    /* P_STRING */
                   2320:    return STRCMP(*(char_u **)varp, p->def_val);
                   2321: }
                   2322:
                   2323: /*
                   2324:  * showoneopt: show the value of one option
                   2325:  * must not be called with a hidden option!
                   2326:  */
                   2327:    static void
                   2328: showoneopt(p)
                   2329:    struct option *p;
                   2330: {
                   2331:    char_u          *varp;
                   2332:
                   2333:    varp = get_varp(p);
                   2334:
                   2335:    if ((p->flags & P_BOOL) && !*(int *)varp)
                   2336:        MSG_OUTSTR("no");
                   2337:    else
                   2338:        MSG_OUTSTR("  ");
                   2339:    MSG_OUTSTR(p->fullname);
                   2340:    if (!(p->flags & P_BOOL))
                   2341:    {
                   2342:        msg_outchar('=');
                   2343:        option_value2string(p);     /* put string of option value in NameBuff */
                   2344:        msg_outtrans(NameBuff);
                   2345:    }
                   2346: }
                   2347:
                   2348: /*
                   2349:  * Write modified options as set command to a file.
                   2350:  * Return FAIL on error, OK otherwise.
                   2351:  */
                   2352:    int
                   2353: makeset(fd)
                   2354:    FILE *fd;
                   2355: {
                   2356:    struct option   *p;
                   2357:    char_u          *s;
                   2358:    int             e;
                   2359:    char_u          *varp;
                   2360:
                   2361:    /*
                   2362:     * The options that don't have a default (terminal name, columns, lines)
                   2363:     * are never written. Terminal options are also not written.
                   2364:     */
                   2365:    for (p = &options[0]; !istermoption(p); p++)
                   2366:        if (!(p->flags & P_NO_MKRC) && !istermoption(p) &&
                   2367:                                                          (option_changed(p)))
                   2368:        {
                   2369:            varp = get_varp(p);
                   2370:            if (p->flags & P_BOOL)
                   2371:                fprintf(fd, "set %s%s", *(int *)(varp) ? "" : "no",
                   2372:                                                                 p->fullname);
                   2373:            else if (p->flags & P_NUM)
                   2374:                fprintf(fd, "set %s=%ld", p->fullname, *(long *)(varp));
                   2375:            else    /* P_STRING */
                   2376:            {
                   2377:                fprintf(fd, "set %s=", p->fullname);
                   2378:                s = *(char_u **)(varp);
                   2379:                /* some characters have to be escaped with CTRL-V or
                   2380:                 * backslash */
                   2381:                if (s != NULL && putescstr(fd, s, TRUE) == FAIL)
                   2382:                    return FAIL;
                   2383:            }
                   2384: #ifdef USE_CRNL
                   2385:            putc('\r', fd);
                   2386: #endif
                   2387:                /*
                   2388:                 * Only check error for this putc, should catch at least
                   2389:                 * the "disk full" situation.
                   2390:                 */
                   2391:            e = putc('\n', fd);
                   2392:            if (e < 0)
                   2393:                return FAIL;
                   2394:        }
                   2395:    return OK;
                   2396: }
                   2397:
                   2398: /*
                   2399:  * Clear all the terminal options.
                   2400:  * If the option has been allocated, free the memory.
                   2401:  * Terminal options are never hidden or indirect.
                   2402:  */
                   2403:    void
                   2404: clear_termoptions()
                   2405: {
                   2406:    struct option   *p;
                   2407:
                   2408:    /*
                   2409:     * Reset a few things before clearing the old options. This may cause
                   2410:     * outputting a few things that the terminal doesn't understand, but the
                   2411:     * screen will be cleared later, so this is OK.
                   2412:     */
                   2413: #ifdef USE_MOUSE
                   2414:    mch_setmouse(FALSE);            /* switch mouse off */
                   2415: #endif
                   2416:    mch_restore_title(3);           /* restore window titles */
                   2417: #ifdef WIN32
                   2418:    /*
                   2419:     * Check if this is allowed now.
                   2420:     */
                   2421:    if (can_end_termcap_mode(FALSE) == TRUE)
                   2422: #endif
                   2423:        stoptermcap();                  /* stop termcap mode */
                   2424:
                   2425:    for (p = &options[0]; p->fullname != NULL; p++)
                   2426:        if (istermoption(p))
                   2427:        {
                   2428:            if (p->flags & P_ALLOCED)
                   2429:                free_string_option(*(char_u **)(p->var));
                   2430:            if (p->flags & P_DEF_ALLOCED)
                   2431:                free_string_option(p->def_val);
                   2432:            *(char_u **)(p->var) = empty_option;
                   2433:            p->def_val = empty_option;
                   2434:            p->flags &= ~(P_ALLOCED|P_DEF_ALLOCED);
                   2435:        }
                   2436:    clear_termcodes();
                   2437: }
                   2438:
                   2439: /*
                   2440:  * Set the terminal option defaults to the current value.
                   2441:  * Used after setting the terminal name.
                   2442:  */
                   2443:    void
                   2444: set_term_defaults()
                   2445: {
                   2446:    struct option   *p;
                   2447:
                   2448:    for (p = &options[0]; p->fullname != NULL; p++)
                   2449:        if (istermoption(p) && p->def_val != *(char_u **)(p->var))
                   2450:        {
                   2451:            if (p->flags & P_DEF_ALLOCED)
                   2452:            {
                   2453:                free_string_option(p->def_val);
                   2454:                p->flags &= ~P_DEF_ALLOCED;
                   2455:            }
                   2456:            p->def_val = *(char_u **)(p->var);
                   2457:            if (p->flags & P_ALLOCED)
                   2458:            {
                   2459:                p->flags |= P_DEF_ALLOCED;
                   2460:                p->flags &= ~P_ALLOCED;     /* don't free the value now */
                   2461:            }
                   2462:        }
                   2463: }
                   2464:
                   2465: /*
                   2466:  * return TRUE if 'p' starts with 't_'
                   2467:  */
                   2468:    static int
                   2469: istermoption(p)
                   2470:    struct option *p;
                   2471: {
                   2472:    return (p->fullname[0] == 't' && p->fullname[1] == '_');
                   2473: }
                   2474:
                   2475: /*
                   2476:  * Compute columns for ruler and shown command. 'sc_col' is also used to
                   2477:  * decide what the maximum length of a message on the status line can be.
                   2478:  * If there is a status line for the last window, 'sc_col' is independent
                   2479:  * of 'ru_col'.
                   2480:  */
                   2481:
                   2482: #define COL_RULER 17       /* columns needed by ruler */
                   2483:
                   2484:    void
                   2485: comp_col()
                   2486: {
                   2487:    int last_has_status = (p_ls == 2 || (p_ls == 1 && firstwin != lastwin));
                   2488:
                   2489:    sc_col = 0;
                   2490:    ru_col = 0;
                   2491:    if (p_ru)
                   2492:    {
                   2493:        ru_col = COL_RULER + 1;
                   2494:                            /* no last status line, adjust sc_col */
                   2495:        if (!last_has_status)
                   2496:            sc_col = ru_col;
                   2497:    }
                   2498:    if (p_sc)
                   2499:    {
                   2500:        sc_col += SHOWCMD_COLS;
                   2501:        if (!p_ru || last_has_status)       /* no need for separating space */
                   2502:            ++sc_col;
                   2503:    }
                   2504:    sc_col = Columns - sc_col;
                   2505:    ru_col = Columns - ru_col;
                   2506:    if (sc_col <= 0)            /* screen too narrow, will become a mess */
                   2507:        sc_col = 1;
                   2508:    if (ru_col <= 0)
                   2509:        ru_col = 1;
                   2510: }
                   2511:
                   2512:    static char_u *
                   2513: get_varp(p)
                   2514:    struct option   *p;
                   2515: {
                   2516:    if (!(p->flags & P_IND) || p->var == NULL)
                   2517:        return p->var;
                   2518:
                   2519:    switch ((long)(p->var))
                   2520:    {
                   2521:        case PV_LIST:   return (char_u *)&(curwin->w_p_list);
                   2522:        case PV_NU:     return (char_u *)&(curwin->w_p_nu);
                   2523: #ifdef RIGHTLEFT
                   2524:        case PV_RL:     return (char_u *)&(curwin->w_p_rl);
                   2525: #endif
                   2526:        case PV_SCROLL: return (char_u *)&(curwin->w_p_scroll);
                   2527:        case PV_WRAP:   return (char_u *)&(curwin->w_p_wrap);
                   2528:        case PV_LBR:    return (char_u *)&(curwin->w_p_lbr);
                   2529:
                   2530:        case PV_AI:     return (char_u *)&(curbuf->b_p_ai);
                   2531:        case PV_BIN:    return (char_u *)&(curbuf->b_p_bin);
                   2532: #ifdef CINDENT
                   2533:        case PV_CIN:    return (char_u *)&(curbuf->b_p_cin);
                   2534:        case PV_CINK:   return (char_u *)&(curbuf->b_p_cink);
                   2535:        case PV_CINO:   return (char_u *)&(curbuf->b_p_cino);
                   2536: #endif
                   2537: #if defined(SMARTINDENT) || defined(CINDENT)
                   2538:        case PV_CINW:   return (char_u *)&(curbuf->b_p_cinw);
                   2539: #endif
                   2540:        case PV_COM:    return (char_u *)&(curbuf->b_p_com);
                   2541:        case PV_EOL:    return (char_u *)&(curbuf->b_p_eol);
                   2542:        case PV_ET:     return (char_u *)&(curbuf->b_p_et);
                   2543:        case PV_FO:     return (char_u *)&(curbuf->b_p_fo);
                   2544:        case PV_INF:    return (char_u *)&(curbuf->b_p_inf);
                   2545:        case PV_ISK:    return (char_u *)&(curbuf->b_p_isk);
                   2546:        case PV_LISP:   return (char_u *)&(curbuf->b_p_lisp);
                   2547:        case PV_ML:     return (char_u *)&(curbuf->b_p_ml);
                   2548:        case PV_MOD:    return (char_u *)&(curbuf->b_changed);
                   2549:        case PV_RO:     return (char_u *)&(curbuf->b_p_ro);
                   2550: #ifdef SMARTINDENT
                   2551:        case PV_SI:     return (char_u *)&(curbuf->b_p_si);
                   2552: #endif
                   2553: #ifndef SHORT_FNAME
                   2554:        case PV_SN:     return (char_u *)&(curbuf->b_p_sn);
                   2555: #endif
                   2556:        case PV_SW:     return (char_u *)&(curbuf->b_p_sw);
                   2557:        case PV_TS:     return (char_u *)&(curbuf->b_p_ts);
                   2558:        case PV_TW:     return (char_u *)&(curbuf->b_p_tw);
                   2559:        case PV_TX:     return (char_u *)&(curbuf->b_p_tx);
                   2560:        case PV_WM:     return (char_u *)&(curbuf->b_p_wm);
                   2561:        default:        EMSG("get_varp ERROR");
                   2562:    }
                   2563:    /* always return a valid pointer to avoid a crash! */
                   2564:    return (char_u *)&(curbuf->b_p_wm);
                   2565: }
                   2566:
                   2567: /*
                   2568:  * Copy options from one window to another.
                   2569:  * Used when creating a new window.
                   2570:  * The 'scroll' option is not copied, because it depends on the window height.
                   2571:  */
                   2572:    void
                   2573: win_copy_options(wp_from, wp_to)
                   2574:    WIN     *wp_from;
                   2575:    WIN     *wp_to;
                   2576: {
                   2577:    wp_to->w_p_list = wp_from->w_p_list;
                   2578:    wp_to->w_p_nu = wp_from->w_p_nu;
                   2579: #ifdef RIGHTLEFT
                   2580:    wp_to->w_p_rl = wp_from->w_p_rl;
                   2581: #endif
                   2582:    wp_to->w_p_wrap = wp_from->w_p_wrap;
                   2583:    wp_to->w_p_lbr = wp_from->w_p_lbr;
                   2584: }
                   2585:
                   2586: /*
                   2587:  * Copy options from one buffer to another.
                   2588:  * Used when creating a new buffer and when entering a buffer.
                   2589:  * Only do this once for a new buffer, otherwise allocated memory for the
                   2590:  * string option will be lost.
                   2591:  * When "entering" is TRUE we will enter the bp_to buffer.
                   2592:  */
                   2593:    void
                   2594: buf_copy_options(bp_from, bp_to, entering)
                   2595:    BUF     *bp_from;
                   2596:    BUF     *bp_to;
                   2597:    int     entering;
                   2598: {
                   2599:    /*
                   2600:     * Don't copy if one of the pointers is NULL or they are the same.
                   2601:     */
                   2602:    if (bp_from == NULL || bp_to == NULL || bp_from == bp_to)
                   2603:        return;
                   2604:
                   2605:    /*
                   2606:     * Always copy when entering and 'cpo' contains 'S'.
                   2607:     * Don't copy when already initialized.
                   2608:     * Don't copy when 'cpo' contains 's' and not entering.
                   2609:     */
                   2610:    if ((vim_strchr(p_cpo, CPO_BUFOPTGLOB) == NULL || !entering) &&
                   2611:            (bp_to->b_p_initialized ||
                   2612:                        (!entering && vim_strchr(p_cpo, CPO_BUFOPT) != NULL)))
                   2613:    {
                   2614:        check_buf_options(bp_to);       /* make sure we don't have NULLs */
                   2615:        return;
                   2616:    }
                   2617:
                   2618:    /*
                   2619:     * If already initialized, need to free the allocated strings.
                   2620:     * Copy 'readonly' and 'textmode' only when not initialized.
                   2621:     */
                   2622:    if (bp_to->b_p_initialized)
                   2623:    {
                   2624:        free_string_option(bp_to->b_p_fo);
                   2625:        free_string_option(bp_to->b_p_isk);
                   2626:        free_string_option(bp_to->b_p_com);
                   2627: #ifdef CINDENT
                   2628:        free_string_option(bp_to->b_p_cink);
                   2629:        free_string_option(bp_to->b_p_cino);
                   2630: #endif
                   2631: #if defined(CINDENT) || defined(SMARTINDENT)
                   2632:        free_string_option(bp_to->b_p_cinw);
                   2633: #endif
                   2634:    }
                   2635:    else
                   2636:    {
                   2637:        bp_to->b_p_ro = FALSE;              /* don't copy readonly */
                   2638:        bp_to->b_p_tx = bp_from->b_p_tx;
                   2639:        bp_to->b_p_tx_nobin = bp_from->b_p_tx_nobin;
                   2640:    }
                   2641:
                   2642:    bp_to->b_p_ai = bp_from->b_p_ai;
                   2643:    bp_to->b_p_ai_save = bp_from->b_p_ai_save;
                   2644:    bp_to->b_p_sw = bp_from->b_p_sw;
                   2645:    bp_to->b_p_tw = bp_from->b_p_tw;
                   2646:    bp_to->b_p_tw_save = bp_from->b_p_tw_save;
                   2647:    bp_to->b_p_tw_nobin = bp_from->b_p_tw_nobin;
                   2648:    bp_to->b_p_wm = bp_from->b_p_wm;
                   2649:    bp_to->b_p_wm_save = bp_from->b_p_wm_save;
                   2650:    bp_to->b_p_wm_nobin = bp_from->b_p_wm_nobin;
                   2651:    bp_to->b_p_bin = bp_from->b_p_bin;
                   2652:    bp_to->b_p_et = bp_from->b_p_et;
                   2653:    bp_to->b_p_et_nobin = bp_from->b_p_et_nobin;
                   2654:    bp_to->b_p_ml = bp_from->b_p_ml;
                   2655:    bp_to->b_p_ml_nobin = bp_from->b_p_ml_nobin;
                   2656:    bp_to->b_p_inf = bp_from->b_p_inf;
                   2657: #ifndef SHORT_FNAME
                   2658:    bp_to->b_p_sn = bp_from->b_p_sn;
                   2659: #endif
                   2660:    bp_to->b_p_com = strsave(bp_from->b_p_com);
                   2661:    bp_to->b_p_fo = strsave(bp_from->b_p_fo);
                   2662: #ifdef SMARTINDENT
                   2663:    bp_to->b_p_si = bp_from->b_p_si;
                   2664:    bp_to->b_p_si_save = bp_from->b_p_si_save;
                   2665: #endif
                   2666: #ifdef CINDENT
                   2667:    bp_to->b_p_cin = bp_from->b_p_cin;
                   2668:    bp_to->b_p_cin_save = bp_from->b_p_cin_save;
                   2669:    bp_to->b_p_cink = strsave(bp_from->b_p_cink);
                   2670:    bp_to->b_p_cino = strsave(bp_from->b_p_cino);
                   2671: #endif
                   2672: #if defined(SMARTINDENT) || defined(CINDENT)
                   2673:    bp_to->b_p_cinw = strsave(bp_from->b_p_cinw);
                   2674: #endif
                   2675: #ifdef LISPINDENT
                   2676:    bp_to->b_p_lisp = bp_from->b_p_lisp;
                   2677:    bp_to->b_p_lisp_save = bp_from->b_p_lisp_save;
                   2678: #endif
                   2679:    bp_to->b_p_ta_nobin = bp_from->b_p_ta_nobin;
                   2680:
                   2681:    /*
                   2682:     * Don't copy the options set by do_help(), use the saved values
                   2683:     */
                   2684:    if (!keep_help_flag && bp_from->b_help && help_save_isk != NULL)
                   2685:    {
                   2686:        bp_to->b_p_isk = strsave(help_save_isk);
                   2687:        if (bp_to->b_p_isk != NULL)
                   2688:            init_chartab();
                   2689:        bp_to->b_p_ts = help_save_ts;
                   2690:        bp_to->b_help = FALSE;
                   2691:    }
                   2692:    else
                   2693:    {
                   2694:        bp_to->b_p_isk = strsave(bp_from->b_p_isk);
                   2695:        vim_memmove(bp_to->b_chartab, bp_from->b_chartab, (size_t)256);
                   2696:        bp_to->b_p_ts = bp_from->b_p_ts;
                   2697:        bp_to->b_help = bp_from->b_help;
                   2698:    }
                   2699:    check_buf_options(bp_to);
                   2700:
                   2701:    /*
                   2702:     * Set the flag that indicates that the options have been ininitialized.
                   2703:     * Avoids loosing allocated memory.
                   2704:     */
                   2705:    bp_to->b_p_initialized = TRUE;
                   2706: }
                   2707:
                   2708: static int expand_option_idx = -1;
                   2709: static char_u expand_option_name[5] = {'t', '_', NUL, NUL, NUL};
                   2710:
                   2711:    void
                   2712: set_context_in_set_cmd(arg)
                   2713:    char_u *arg;
                   2714: {
                   2715:    int         nextchar;
                   2716:    int         flags = 0;      /* init for GCC */
                   2717:    int         opt_idx = 0;    /* init for GCC */
                   2718:    char_u      *p;
                   2719:    char_u      *after_blank = NULL;
                   2720:    int         is_term_option = FALSE;
                   2721:    int         key;
                   2722:
                   2723:    expand_context = EXPAND_SETTINGS;
                   2724:    if (*arg == NUL)
                   2725:    {
                   2726:        expand_pattern = arg;
                   2727:        return;
                   2728:    }
                   2729:    p = arg + STRLEN(arg) - 1;
                   2730:    if (*p == ' ' && *(p - 1) != '\\')
                   2731:    {
                   2732:        expand_pattern = p + 1;
                   2733:        return;
                   2734:    }
                   2735:    while (p != arg && (*p != ' ' || *(p - 1) == '\\'))
                   2736:    {
                   2737:        /* remember possible start of file name to expand */
                   2738:        if ((*p == ' ' || (*p == ',' && *(p - 1) != '\\')) &&
                   2739:                                                          after_blank == NULL)
                   2740:            after_blank = p + 1;
                   2741:        p--;
                   2742:    }
                   2743:    if (p != arg)
                   2744:        p++;
                   2745:    if (STRNCMP(p, "no", (size_t) 2) == 0)
                   2746:    {
                   2747:        expand_context = EXPAND_BOOL_SETTINGS;
                   2748:        p += 2;
                   2749:    }
                   2750:    if (STRNCMP(p, "inv", (size_t) 3) == 0)
                   2751:    {
                   2752:        expand_context = EXPAND_BOOL_SETTINGS;
                   2753:        p += 3;
                   2754:    }
                   2755:    expand_pattern = arg = p;
                   2756:    if (*arg == '<')
                   2757:    {
                   2758:        while (*p != '>')
                   2759:            if (*p++ == NUL)        /* expand terminal option name */
                   2760:                return;
                   2761:        key = get_special_key_code(arg + 1);
                   2762:        if (key == 0)               /* unknown name */
                   2763:        {
                   2764:            expand_context = EXPAND_NOTHING;
                   2765:            return;
                   2766:        }
                   2767:        nextchar = *++p;
                   2768:        is_term_option = TRUE;
                   2769:        expand_option_name[2] = KEY2TERMCAP0(key);
                   2770:        expand_option_name[3] = KEY2TERMCAP1(key);
                   2771:    }
                   2772:    else
                   2773:    {
                   2774:        if (p[0] == 't' && p[1] == '_')
                   2775:        {
                   2776:            p += 2;
                   2777:            if (*p != NUL)
                   2778:                ++p;
                   2779:            if (*p == NUL)
                   2780:                return;         /* expand option name */
                   2781:            nextchar = *++p;
                   2782:            is_term_option = TRUE;
                   2783:            expand_option_name[2] = p[-2];
                   2784:            expand_option_name[3] = p[-1];
                   2785:        }
                   2786:        else
                   2787:        {
                   2788:            while (isalnum(*p) || *p == '_' || *p == '*')   /* Allow * wildcard */
                   2789:                p++;
                   2790:            if (*p == NUL)
                   2791:                return;
                   2792:            nextchar = *p;
                   2793:            *p = NUL;
                   2794:            opt_idx = findoption(arg);
                   2795:            *p = nextchar;
                   2796:            if (opt_idx == -1 || options[opt_idx].var == NULL)
                   2797:            {
                   2798:                expand_context = EXPAND_NOTHING;
                   2799:                return;
                   2800:            }
                   2801:            flags = options[opt_idx].flags;
                   2802:            if (flags & P_BOOL)
                   2803:            {
                   2804:                expand_context = EXPAND_NOTHING;
                   2805:                return;
                   2806:            }
                   2807:        }
                   2808:    }
                   2809:    if ((nextchar != '=' && nextchar != ':')
                   2810:                                    || expand_context == EXPAND_BOOL_SETTINGS)
                   2811:    {
                   2812:        expand_context = EXPAND_UNSUCCESSFUL;
                   2813:        return;
                   2814:    }
                   2815:    if (expand_context != EXPAND_BOOL_SETTINGS && p[1] == NUL)
                   2816:    {
                   2817:        expand_context = EXPAND_OLD_SETTING;
                   2818:        if (is_term_option)
                   2819:            expand_option_idx = -1;
                   2820:        else
                   2821:            expand_option_idx = opt_idx;
                   2822:        expand_pattern = p + 1;
                   2823:        return;
                   2824:    }
                   2825:    expand_context = EXPAND_NOTHING;
                   2826:    if (is_term_option || (flags & P_NUM))
                   2827:        return;
                   2828:    if (after_blank != NULL)
                   2829:        expand_pattern = after_blank;
                   2830:    else
                   2831:        expand_pattern = p + 1;
                   2832:    if (flags & P_EXPAND)
                   2833:    {
                   2834:        p = options[opt_idx].var;
                   2835:        if (p == (char_u *)&p_bdir || p == (char_u *)&p_dir ||
                   2836:                                                       p == (char_u *)&p_path)
                   2837:            expand_context = EXPAND_DIRECTORIES;
                   2838:        else
                   2839:            expand_context = EXPAND_FILES;
                   2840:    }
                   2841:    return;
                   2842: }
                   2843:
                   2844:    int
                   2845: ExpandSettings(prog, num_file, file)
                   2846:    regexp      *prog;
                   2847:    int         *num_file;
                   2848:    char_u      ***file;
                   2849: {
                   2850:    int num_normal = 0;     /* Number of matching non-term-code settings */
                   2851:    int num_term = 0;       /* Number of matching terminal code settings */
                   2852:    int opt_idx;
                   2853:    int match;
                   2854:    int count = 0;
                   2855:    char_u *str;
                   2856:    int loop;
                   2857:    int is_term_opt;
                   2858:    char_u  name_buf[MAX_KEY_NAME_LEN];
                   2859:
                   2860:    /* do this loop twice:
                   2861:     * loop == 0: count the number of matching options
                   2862:     * loop == 1: copy the matching options into allocated memory
                   2863:     */
                   2864:    for (loop = 0; loop <= 1; ++loop)
                   2865:    {
                   2866:        if (expand_context != EXPAND_BOOL_SETTINGS)
                   2867:        {
                   2868:            if (vim_regexec(prog, (char_u *)"all", TRUE))
                   2869:            {
                   2870:                if (loop == 0)
                   2871:                    num_normal++;
                   2872:                else
                   2873:                    (*file)[count++] = strsave((char_u *)"all");
                   2874:            }
                   2875:            if (vim_regexec(prog, (char_u *)"termcap", TRUE))
                   2876:            {
                   2877:                if (loop == 0)
                   2878:                    num_normal++;
                   2879:                else
                   2880:                    (*file)[count++] = strsave((char_u *)"termcap");
                   2881:            }
                   2882:        }
                   2883:        for (opt_idx = 0; (str = (char_u *)options[opt_idx].fullname) != NULL;
                   2884:                                                                    opt_idx++)
                   2885:        {
                   2886:            if (options[opt_idx].var == NULL)
                   2887:                continue;
                   2888:            if (expand_context == EXPAND_BOOL_SETTINGS
                   2889:              && !(options[opt_idx].flags & P_BOOL))
                   2890:                continue;
                   2891:            is_term_opt = istermoption(&options[opt_idx]);
                   2892:            if (is_term_opt && num_normal > 0)
                   2893:                continue;
                   2894:            match = FALSE;
                   2895:            if (vim_regexec(prog, str, TRUE) ||
                   2896:                                        (options[opt_idx].shortname != NULL &&
                   2897:                         vim_regexec(prog,
                   2898:                                 (char_u *)options[opt_idx].shortname, TRUE)))
                   2899:                match = TRUE;
                   2900:            else if (is_term_opt)
                   2901:            {
                   2902:                name_buf[0] = '<';
                   2903:                name_buf[1] = 't';
                   2904:                name_buf[2] = '_';
                   2905:                name_buf[3] = str[2];
                   2906:                name_buf[4] = str[3];
                   2907:                name_buf[5] = '>';
                   2908:                name_buf[6] = NUL;
                   2909:                if (vim_regexec(prog, name_buf, TRUE))
                   2910:                {
                   2911:                    match = TRUE;
                   2912:                    str = name_buf;
                   2913:                }
                   2914:            }
                   2915:            if (match)
                   2916:            {
                   2917:                if (loop == 0)
                   2918:                {
                   2919:                    if (is_term_opt)
                   2920:                        num_term++;
                   2921:                    else
                   2922:                        num_normal++;
                   2923:                }
                   2924:                else
                   2925:                    (*file)[count++] = strsave(str);
                   2926:            }
                   2927:        }
                   2928:        /*
                   2929:         * Check terminal key codes, these are not in the option table
                   2930:         */
                   2931:        if (expand_context != EXPAND_BOOL_SETTINGS  && num_normal == 0)
                   2932:        {
                   2933:            for (opt_idx = 0; (str = get_termcode(opt_idx)) != NULL; opt_idx++)
                   2934:            {
                   2935:                if (!isprint(str[0]) || !isprint(str[1]))
                   2936:                    continue;
                   2937:
                   2938:                name_buf[0] = 't';
                   2939:                name_buf[1] = '_';
                   2940:                name_buf[2] = str[0];
                   2941:                name_buf[3] = str[1];
                   2942:                name_buf[4] = NUL;
                   2943:
                   2944:                match = FALSE;
                   2945:                if (vim_regexec(prog, name_buf, TRUE))
                   2946:                    match = TRUE;
                   2947:                else
                   2948:                {
                   2949:                    name_buf[0] = '<';
                   2950:                    name_buf[1] = 't';
                   2951:                    name_buf[2] = '_';
                   2952:                    name_buf[3] = str[0];
                   2953:                    name_buf[4] = str[1];
                   2954:                    name_buf[5] = '>';
                   2955:                    name_buf[6] = NUL;
                   2956:
                   2957:                    if (vim_regexec(prog, name_buf, TRUE))
                   2958:                        match = TRUE;
                   2959:                }
                   2960:                if (match)
                   2961:                {
                   2962:                    if (loop == 0)
                   2963:                        num_term++;
                   2964:                    else
                   2965:                        (*file)[count++] = strsave(name_buf);
                   2966:                }
                   2967:            }
                   2968:            /*
                   2969:             * Check special key names.
                   2970:             */
                   2971:            for (opt_idx = 0; (str = get_key_name(opt_idx)) != NULL; opt_idx++)
                   2972:            {
                   2973:                name_buf[0] = '<';
                   2974:                STRCPY(name_buf + 1, str);
                   2975:                STRCAT(name_buf, ">");
                   2976:
                   2977:                reg_ic = TRUE;                  /* ignore case here */
                   2978:                if (vim_regexec(prog, name_buf, TRUE))
                   2979:                {
                   2980:                    if (loop == 0)
                   2981:                        num_term++;
                   2982:                    else
                   2983:                        (*file)[count++] = strsave(name_buf);
                   2984:                }
                   2985:            }
                   2986:        }
                   2987:        if (loop == 0)
                   2988:        {
                   2989:            if (num_normal > 0)
                   2990:                *num_file = num_normal;
                   2991:            else if (num_term > 0)
                   2992:                *num_file = num_term;
                   2993:            else
                   2994:                return OK;
                   2995:            *file = (char_u **) alloc((unsigned)(*num_file * sizeof(char_u *)));
                   2996:            if (*file == NULL)
                   2997:            {
                   2998:                *file = (char_u **)"";
                   2999:                return FAIL;
                   3000:            }
                   3001:        }
                   3002:    }
                   3003:    return OK;
                   3004: }
                   3005:
                   3006:    int
                   3007: ExpandOldSetting(num_file, file)
                   3008:    int     *num_file;
                   3009:    char_u  ***file;
                   3010: {
                   3011:    char_u  *var = NULL;        /* init for GCC */
                   3012:    char_u  *buf;
                   3013:
                   3014:    *num_file = 0;
                   3015:    *file = (char_u **)alloc((unsigned)sizeof(char_u *));
                   3016:    if (*file == NULL)
                   3017:        return FAIL;
                   3018:
                   3019:    /*
                   3020:     * For a terminal key code epand_option_idx is < 0.
                   3021:     */
                   3022:    if (expand_option_idx < 0)
                   3023:    {
                   3024:        var = find_termcode(expand_option_name + 2);
                   3025:        if (var == NULL)
                   3026:            expand_option_idx = findoption(expand_option_name);
                   3027:    }
                   3028:
                   3029:    if (expand_option_idx >= 0)
                   3030:    {
                   3031:        /* put string of option value in NameBuff */
                   3032:        option_value2string(&options[expand_option_idx]);
                   3033:        var = NameBuff;
                   3034:    }
                   3035:    else if (var == NULL)
                   3036:        var = (char_u *)"";
                   3037:
                   3038:    /* A backslash is required before some characters */
                   3039:    buf = strsave_escaped(var, escape_chars);
                   3040:
                   3041:    if (buf == NULL)
                   3042:    {
                   3043:        vim_free(*file);
                   3044:        *file = NULL;
                   3045:        return FAIL;
                   3046:    }
                   3047:
                   3048:    *file[0] = buf;
                   3049:    *num_file = 1;
                   3050:    return OK;
                   3051: }
                   3052:
                   3053: /*
                   3054:  * Get the value for the numeric or string option *op in a nice format into
                   3055:  * NameBuff[].  Must not be called with a hidden option!
                   3056:  */
                   3057:    static void
                   3058: option_value2string(op)
                   3059:    struct option   *op;
                   3060: {
                   3061:    char_u  *varp;
                   3062:
                   3063:    varp = get_varp(op);
                   3064:    if (op->flags & P_NUM)
                   3065:    {
                   3066:        if ((long *)varp == &p_wc)
                   3067:        {
                   3068:            if (IS_SPECIAL(p_wc) || find_special_key_in_table((int)p_wc) >= 0)
                   3069:                STRCPY(NameBuff, get_special_key_name((int)p_wc, 0));
                   3070:            else
                   3071:                STRCPY(NameBuff, transchar((int)p_wc));
                   3072:        }
                   3073:        else
                   3074:            sprintf((char *)NameBuff, "%ld", *(long *)varp);
                   3075:    }
                   3076:    else    /* P_STRING */
                   3077:    {
                   3078:        varp = *(char_u **)(varp);
                   3079:        if (varp == NULL)                   /* just in case */
                   3080:            NameBuff[0] = NUL;
                   3081:        else if (op->flags & P_EXPAND)
                   3082:            home_replace(NULL, varp, NameBuff, MAXPATHL);
                   3083:        else
                   3084:            STRNCPY(NameBuff, varp, MAXPATHL);
                   3085:    }
                   3086: }
                   3087:
                   3088: /*
                   3089:  * Convert the given pattern "pat" which has shell style wildcards in it, into
                   3090:  * a regular expression, and return the result.  If there is a directory path
                   3091:  * separator to be matched, then TRUE is put in allow_directories, otherwise
                   3092:  * FALSE is put there -- webb.
                   3093:  */
                   3094:    char_u *
                   3095: file_pat_to_reg_pat(pat, pat_end, allow_directories)
                   3096:    char_u  *pat;
                   3097:    char_u  *pat_end;               /* first char after pattern */
                   3098:    int     *allow_directories;     /* Result passed back out in here */
                   3099: {
                   3100:    int     size;
                   3101:    char_u  *endp;
                   3102:    char_u  *reg_pat;
                   3103:    char_u  *p;
                   3104:    int     i;
                   3105:    int     nested = 0;
                   3106:    int     add_dollar = TRUE;
                   3107:
                   3108:    if (allow_directories != NULL)
                   3109:        *allow_directories = FALSE;
                   3110:
                   3111:    size = 2;               /* '^' at start, '$' at end */
                   3112:    for (p = pat; p < pat_end; p++)
                   3113:    {
                   3114:        switch (*p)
                   3115:        {
                   3116:            case '*':
                   3117:            case '.':
                   3118:            case ',':
                   3119:            case '{':
                   3120:            case '}':
                   3121:            case '~':
                   3122: #ifdef BACKSLASH_IN_FILENAME
                   3123:            case '\\':
                   3124: #endif
                   3125:                size += 2;
                   3126:                break;
                   3127:            default:
                   3128:                size++;
                   3129:                break;
                   3130:        }
                   3131:    }
                   3132:    reg_pat = alloc(size + 1);
                   3133:    if (reg_pat == NULL)
                   3134:        return NULL;
                   3135:    i = 0;
                   3136:    if (pat[0] == '*')
                   3137:        while (pat[0] == '*' && pat < pat_end - 1)
                   3138:            pat++;
                   3139:    else
                   3140:        reg_pat[i++] = '^';
                   3141:    endp = pat_end - 1;
                   3142:    if (*endp == '*')
                   3143:    {
                   3144:        while (endp - pat > 0 && *endp == '*')
                   3145:            endp--;
                   3146:        add_dollar = FALSE;
                   3147:    }
                   3148:    for (p = pat; *p && nested >= 0 && p <= endp; p++)
                   3149:    {
                   3150:        switch (*p)
                   3151:        {
                   3152:            case '*':
                   3153:                reg_pat[i++] = '.';
                   3154:                reg_pat[i++] = '*';
                   3155:                break;
                   3156:            case '.':
                   3157:            case '~':
                   3158:                reg_pat[i++] = '\\';
                   3159:                reg_pat[i++] = *p;
                   3160:                break;
                   3161:            case '?':
                   3162:                reg_pat[i++] = '.';
                   3163:                break;
                   3164:            case '\\':
                   3165:                if (p[1] == NUL)
                   3166:                    break;
                   3167: #ifdef BACKSLASH_IN_FILENAME
                   3168:                /* translate "\x" to "\\x", "\*" to "\\.*", and "\?" to "\\." */
                   3169:                if (isfilechar(p[1]) || p[1] == '*' || p[1] == '?')
                   3170:                {
                   3171:                    reg_pat[i++] = '\\';
                   3172:                    reg_pat[i++] = '\\';
                   3173:                    if (allow_directories != NULL)
                   3174:                        *allow_directories = TRUE;
                   3175:                    break;
                   3176:                }
                   3177:                ++p;
                   3178: #else
                   3179:                if (*++p == '?')
                   3180:                    reg_pat[i++] = '?';
                   3181:                else
                   3182: #endif
                   3183:                     if (*p == ',')
                   3184:                    reg_pat[i++] = ',';
                   3185:                else
                   3186:                {
                   3187:                    if (allow_directories != NULL && ispathsep(*p))
                   3188:                        *allow_directories = TRUE;
                   3189:                    reg_pat[i++] = '\\';
                   3190:                    reg_pat[i++] = *p;
                   3191:                }
                   3192:                break;
                   3193:            case '{':
                   3194:                reg_pat[i++] = '\\';
                   3195:                reg_pat[i++] = '(';
                   3196:                nested++;
                   3197:                break;
                   3198:            case '}':
                   3199:                reg_pat[i++] = '\\';
                   3200:                reg_pat[i++] = ')';
                   3201:                --nested;
                   3202:                break;
                   3203:            case ',':
                   3204:                if (nested)
                   3205:                {
                   3206:                    reg_pat[i++] = '\\';
                   3207:                    reg_pat[i++] = '|';
                   3208:                }
                   3209:                else
                   3210:                    reg_pat[i++] = ',';
                   3211:                break;
                   3212:            default:
                   3213:                if (allow_directories != NULL && ispathsep(*p))
                   3214:                    *allow_directories = TRUE;
                   3215:                reg_pat[i++] = *p;
                   3216:                break;
                   3217:        }
                   3218:    }
                   3219:    if (add_dollar)
                   3220:        reg_pat[i++] = '$';
                   3221:    reg_pat[i] = NUL;
                   3222:    if (nested != 0)
                   3223:    {
                   3224:        if (nested < 0)
                   3225:            EMSG("Missing {.");
                   3226:        else
                   3227:            EMSG("Missing }.");
                   3228:        vim_free(reg_pat);
                   3229:        reg_pat = NULL;
                   3230:    }
                   3231:    return reg_pat;
                   3232: }
                   3233:
                   3234: #ifdef AUTOCMD
                   3235: /*
                   3236:  * functions for automatic commands
                   3237:  */
                   3238:
                   3239: static void show_autocmd __ARGS((AutoPat *ap, int event));
                   3240: static void del_autocmd __ARGS((AutoPat *ap));
                   3241: static void del_autocmd_cmds __ARGS((AutoPat *ap));
                   3242: static int event_name2nr __ARGS((char_u *start, char_u **end));
                   3243: static char *event_nr2name __ARGS((int event));
                   3244: static char_u *find_end_event __ARGS((char_u *arg));
                   3245: static int do_autocmd_event __ARGS((int event, char_u *pat,
                   3246:                                                     char_u *cmd, int force));
                   3247:
                   3248:    static void
                   3249: show_autocmd(ap, event)
                   3250:    AutoPat *ap;
                   3251:    int     event;
                   3252: {
                   3253:    AutoCmd *ac;
                   3254:
                   3255:    if (got_int)                /* "q" hit for "--more--" */
                   3256:        return;
                   3257:    msg_outchar('\n');
                   3258:    if (got_int)                /* "q" hit for "--more--" */
                   3259:        return;
                   3260:    msg_outchar('\n');
                   3261:    if (got_int)                /* "q" hit for "--more--" */
                   3262:        return;
                   3263:    MSG_OUTSTR(event_nr2name(event));
                   3264:    MSG_OUTSTR("  ");
                   3265:    msg_outstr(ap->pat);
                   3266:    for (ac = ap->cmds; ac != NULL; ac = ac->next)
                   3267:    {
                   3268:        MSG_OUTSTR("\n    ");
                   3269:        if (got_int)            /* hit "q" at "--more--" prompt */
                   3270:            return;
                   3271:        msg_outtrans(ac->cmd);
                   3272:    }
                   3273: }
                   3274:
                   3275: /*
                   3276:  * Delete an autocommand pattern.
                   3277:  */
                   3278:    static void
                   3279: del_autocmd(ap)
                   3280:    AutoPat *ap;
                   3281: {
                   3282:    vim_free(ap->pat);
                   3283:    vim_free(ap->reg_pat);
                   3284:    del_autocmd_cmds(ap);
                   3285:    vim_free(ap);
                   3286: }
                   3287:
                   3288: /*
                   3289:  * Delete the commands from a pattern.
                   3290:  */
                   3291:    static void
                   3292: del_autocmd_cmds(ap)
                   3293:    AutoPat *ap;
                   3294: {
                   3295:    AutoCmd *ac;
                   3296:
                   3297:    while (ap->cmds != NULL)
                   3298:    {
                   3299:        ac = ap->cmds;
                   3300:        ap->cmds = ac->next;
                   3301:        vim_free(ac->cmd);
                   3302:        vim_free(ac);
                   3303:    }
                   3304: }
                   3305:
                   3306: /*
                   3307:  * Return the event number for event name "start".
                   3308:  * Return -1 if the event name was not found.
                   3309:  * Return a pointer to the next event name in "end".
                   3310:  */
                   3311:    static int
                   3312: event_name2nr(start, end)
                   3313:    char_u  *start;
                   3314:    char_u  **end;
                   3315: {
                   3316:    char_u      *p;
                   3317:    int         i;
                   3318:    int         len;
                   3319:
                   3320:    /* the event name ends with end of line, a blank or a comma */
                   3321:    for (p = start; *p && !vim_iswhite(*p) && *p != ','; ++p)
                   3322:        ;
                   3323:    for (i = 0; event_names[i].name != NULL; ++i)
                   3324:    {
                   3325:        len = strlen(event_names[i].name);
                   3326:        if (len == p - start &&
                   3327:                   vim_strnicmp((char_u *)event_names[i].name, (char_u *)start, (size_t)len) == 0)
                   3328:            break;
                   3329:    }
                   3330:    if (*p == ',')
                   3331:        ++p;
                   3332:    *end = p;
                   3333:    if (event_names[i].name == NULL)
                   3334:        return -1;
                   3335:    return event_names[i].event;
                   3336: }
                   3337:
                   3338: /*
                   3339:  * Return the name for event "event".
                   3340:  */
                   3341:    static char *
                   3342: event_nr2name(event)
                   3343:    int     event;
                   3344: {
                   3345:    int     i;
                   3346:
                   3347:    for (i = 0; event_names[i].name != NULL; ++i)
                   3348:        if (event_names[i].event == event)
                   3349:            return event_names[i].name;
                   3350:    return "Unknown";
                   3351: }
                   3352:
                   3353: /*
                   3354:  * Scan over the events.  "*" stands for all events.
                   3355:  */
                   3356:    static char_u *
                   3357: find_end_event(arg)
                   3358:    char_u  *arg;
                   3359: {
                   3360:    char_u  *pat;
                   3361:    char_u  *p;
                   3362:
                   3363:    if (*arg == '*')
                   3364:    {
                   3365:        if (arg[1] && !vim_iswhite(arg[1]))
                   3366:        {
                   3367:            EMSG2("Illegal character after *: %s", arg);
                   3368:            return NULL;
                   3369:        }
                   3370:        pat = arg + 1;
                   3371:    }
                   3372:    else
                   3373:    {
                   3374:        for (pat = arg; *pat && !vim_iswhite(*pat); pat = p)
                   3375:        {
                   3376:            if (event_name2nr(pat, &p) < 0)
                   3377:            {
                   3378:                EMSG2("No such event: %s", pat);
                   3379:                return NULL;
                   3380:            }
                   3381:        }
                   3382:    }
                   3383:    return pat;
                   3384: }
                   3385:
                   3386: /*
                   3387:  * do_autocmd() -- implements the :autocmd command.  Can be used in the
                   3388:  * following ways:
                   3389:  *
                   3390:  * :autocmd <event> <pat> <cmd>        Add <cmd> to the list of commands that
                   3391:  *                                 will be automatically executed for <event>
                   3392:  *                                 when editing a file matching <pat>.
                   3393:  * :autocmd <event> <pat>          Show the auto-commands associated with
                   3394:  *                                 <event> and <pat>.
                   3395:  * :autocmd    <event>                 Show the auto-commands associated with
                   3396:  *                                 <event>.
                   3397:  * :autocmd                            Show all auto-commands.
                   3398:  * :autocmd! <event> <pat> <cmd>   Remove all auto-commands associated with
                   3399:  *                                 <event> and <pat>, and add the command
                   3400:  *                                 <cmd>.
                   3401:  * :autocmd! <event> <pat>         Remove all auto-commands associated with
                   3402:  *                                 <event> and <pat>.
                   3403:  * :autocmd! <event>               Remove all auto-commands associated with
                   3404:  *                                 <event>.
                   3405:  * :autocmd!                       Remove ALL auto-commands.
                   3406:  *
                   3407:  * Multiple events and patterns may be given separated by commas.  Here are
                   3408:  * some examples:
                   3409:  * :autocmd bufread,bufenter *.c,*.h   set tw=0 smartindent noic
                   3410:  * :autocmd bufleave        *          set tw=79 nosmartindent ic infercase
                   3411:  *
                   3412:  * :autocmd * *.c              show all autocommands for *.c files.
                   3413:  */
                   3414:    void
                   3415: do_autocmd(arg, force)
                   3416:    char_u  *arg;
                   3417:    int     force;
                   3418: {
                   3419:    char_u  *pat;
                   3420:    char_u  *cmd;
                   3421:    int     event;
                   3422:
                   3423:    /*
                   3424:     * Don't change autocommands while executing one.
                   3425:     */
                   3426:    if (autocmd_busy)
                   3427:        return;
                   3428:
                   3429:    /*
                   3430:     * Scan over the events.
                   3431:     * If we find an illegal name, return here, don't do anything.
                   3432:     */
                   3433:    pat = find_end_event(arg);
                   3434:    if (pat == NULL)
                   3435:        return;
                   3436:
                   3437:    /*
                   3438:     * Scan over the pattern.  Put a NUL at the end.
                   3439:     */
                   3440:    pat = skipwhite(pat);
                   3441:    cmd = pat;
                   3442:    while (*cmd && (!vim_iswhite(*cmd) || cmd[-1] == '\\'))
                   3443:        cmd++;
                   3444:    if (*cmd)
                   3445:        *cmd++ = NUL;
                   3446:
                   3447:    /*
                   3448:     * Find the start of the commands.
                   3449:     */
                   3450:    cmd = skipwhite(cmd);
                   3451:
                   3452:    /*
                   3453:     * Print header when showing autocommands.
                   3454:     */
                   3455:    if (!force && *cmd == NUL)
                   3456:    {
                   3457:        set_highlight('t');     /* Highlight title */
                   3458:        start_highlight();
                   3459:        MSG_OUTSTR("\n--- Auto-Commands ---");
                   3460:        stop_highlight();
                   3461:    }
                   3462:
                   3463:    /*
                   3464:     * Loop over the events.
                   3465:     */
                   3466:    if (*arg == '*' || *arg == NUL)
                   3467:    {
                   3468:        for (event = 0; event < NUM_EVENTS; ++event)
                   3469:            if (do_autocmd_event(event, pat, cmd, force) == FAIL)
                   3470:                break;
                   3471:    }
                   3472:    else
                   3473:    {
                   3474:        while (*arg && !vim_iswhite(*arg))
                   3475:            if (do_autocmd_event(event_name2nr(arg, &arg), pat,
                   3476:                                                          cmd, force) == FAIL)
                   3477:                break;
                   3478:    }
                   3479: }
                   3480:
                   3481: /*
                   3482:  * do_autocmd() for one event.
                   3483:  * If *pat == NUL do for all patterns.
                   3484:  * If *cmd == NUL show entries.
                   3485:  * If force == TRUE delete entries.
                   3486:  */
                   3487:    static int
                   3488: do_autocmd_event(event, pat, cmd, force)
                   3489:    int     event;
                   3490:    char_u  *pat;
                   3491:    char_u  *cmd;
                   3492:    int     force;
                   3493: {
                   3494:    AutoPat     *ap;
                   3495:    AutoPat     *ap2;
                   3496:    AutoPat     **final_ap;
                   3497:    AutoCmd     *ac;
                   3498:    AutoCmd     **final_ac;
                   3499:    int         nested;
                   3500:    char_u      *endpat;
                   3501:    int         len;
                   3502:
                   3503:    /*
                   3504:     * Show or delete all patterns for an event.
                   3505:     */
                   3506:    if (*pat == NUL)
                   3507:    {
                   3508:        for (ap = first_autopat[event]; ap != NULL; ap = ap2)
                   3509:        {
                   3510:            ap2 = ap->next;
                   3511:            if (force)
                   3512:                del_autocmd(ap);
                   3513:            else
                   3514:                show_autocmd(ap, event);
                   3515:        }
                   3516:        if (force)
                   3517:            first_autopat[event] = NULL;
                   3518:    }
                   3519:
                   3520:    /*
                   3521:     * Loop through all the specified patterns.
                   3522:     */
                   3523:    for ( ; *pat; pat = (*endpat == ',' ? endpat + 1 : endpat))
                   3524:    {
                   3525:        /*
                   3526:         * Find end of the pattern.
                   3527:         * Watch out for a comma in braces, like "*.\{obj,o\}".
                   3528:         */
                   3529:        nested = 0;
                   3530:        for (endpat = pat;
                   3531:                *endpat && (*endpat != ',' || nested || endpat[-1] == '\\');
                   3532:                ++endpat)
                   3533:        {
                   3534:            if (*endpat == '{')
                   3535:                nested++;
                   3536:            else if (*endpat == '}')
                   3537:                nested--;
                   3538:        }
                   3539:        if (pat == endpat)              /* ignore single comma */
                   3540:            continue;
                   3541:
                   3542:        /*
                   3543:         * Find entry with same pattern.
                   3544:         */
                   3545:        final_ap = &first_autopat[event];
                   3546:        for (ap = first_autopat[event]; ap != NULL; ap = *final_ap)
                   3547:        {
                   3548:            len = STRLEN(ap->pat);
                   3549:            if (len == endpat - pat && STRNCMP(pat, ap->pat, len) == 0)
                   3550:                break;
                   3551:            final_ap = &ap->next;
                   3552:        }
                   3553:
                   3554:        /*
                   3555:         * Add a new pattern.
                   3556:         * Show and delete are ignored if pattern is not found.
                   3557:         */
                   3558:        if (ap == NULL)
                   3559:        {
                   3560:            if (*cmd == NUL)
                   3561:                continue;
                   3562:
                   3563:            /* Add the autocmd at the end of the list */
                   3564:            ap = (AutoPat *)alloc((unsigned)sizeof(AutoPat));
                   3565:            if (ap == NULL)
                   3566:                return FAIL;
                   3567:            ap->pat = strnsave(pat, (int)(endpat - pat));
                   3568:            if (ap->pat == NULL)
                   3569:            {
                   3570:                vim_free(ap);
                   3571:                return FAIL;
                   3572:            }
                   3573:            ap->reg_pat = file_pat_to_reg_pat(pat, endpat,
                   3574:                                                      &ap->allow_directories);
                   3575:            if (ap->reg_pat == NULL)
                   3576:            {
                   3577:                vim_free(ap->pat);
                   3578:                vim_free(ap);
                   3579:                return FAIL;
                   3580:            }
                   3581:            ap->cmds = NULL;
                   3582:            *final_ap = ap;
                   3583:            ap->next = NULL;
                   3584:        }
                   3585:
                   3586:        /*
                   3587:         * Remove existing autocommands.
                   3588:         * If not adding any new autocmd's for this pattern, delete the
                   3589:         * pattern from the autopat list
                   3590:         */
                   3591:        else if (force)
                   3592:        {
                   3593:            del_autocmd_cmds(ap);
                   3594:            if (*cmd == NUL)
                   3595:            {
                   3596:                if (ap == first_autopat[event])
                   3597:                    first_autopat[event] = ap->next;
                   3598:                else
                   3599:                {
                   3600:                    for (ap2 = first_autopat[event];
                   3601:                            ap2->next != ap;
                   3602:                            ap2 = ap2->next)
                   3603:                        ;
                   3604:                    ap2->next = ap->next;
                   3605:                }
                   3606:                del_autocmd(ap);
                   3607:            }
                   3608:        }
                   3609:
                   3610:        /*
                   3611:         * Show autocmd's for this autopat
                   3612:         */
                   3613:        if (*cmd == NUL && !force)
                   3614:        {
                   3615:            show_autocmd(ap, event);
                   3616:        }
                   3617:
                   3618:        /*
                   3619:         * Add the autocmd at the end if it's not already there.
                   3620:         */
                   3621:        else if (*cmd != NUL)
                   3622:        {
                   3623:            final_ac = &(ap->cmds);
                   3624:            for (ac = ap->cmds;
                   3625:                    ac != NULL && STRCMP(cmd, ac->cmd) != 0;
                   3626:                    ac = ac->next)
                   3627:                final_ac = &ac->next;
                   3628:            if (ac == NULL)
                   3629:            {
                   3630:                ac = (AutoCmd *)alloc((unsigned)sizeof(AutoCmd));
                   3631:                if (ac == NULL)
                   3632:                    return FAIL;
                   3633:                ac->cmd = strsave(cmd);
                   3634:                if (ac->cmd == NULL)
                   3635:                {
                   3636:                    vim_free(ac);
                   3637:                    return FAIL;
                   3638:                }
                   3639:                ac->next = NULL;
                   3640:                *final_ac = ac;
                   3641:            }
                   3642:        }
                   3643:    }
                   3644:    return OK;
                   3645: }
                   3646:
                   3647: /*
                   3648:  * Implementation of ":doautocmd event [fname]".
                   3649:  */
                   3650:    void
                   3651: do_doautocmd(arg)
                   3652:    char_u      *arg;
                   3653: {
                   3654:    char_u      *fname;
                   3655:    int         nothing_done = TRUE;
                   3656:
                   3657:    if (*arg == '*')
                   3658:    {
                   3659:        EMSG("Can't execute autocommands for ALL events");
                   3660:        return;
                   3661:    }
                   3662:
                   3663:    /*
                   3664:     * Scan over the events.
                   3665:     * If we find an illegal name, return here, don't do anything.
                   3666:     */
                   3667:    fname = find_end_event(arg);
                   3668:    if (fname == NULL)
                   3669:        return;
                   3670:
                   3671:    fname = skipwhite(fname);
                   3672:
                   3673:    /*
                   3674:     * Loop over the events.
                   3675:     */
                   3676:    while (*arg && !vim_iswhite(*arg))
                   3677:        if (apply_autocmds(event_name2nr(arg, &arg), fname, NULL))
                   3678:            nothing_done = FALSE;
                   3679:
                   3680:    if (nothing_done)
                   3681:        MSG("No matching autocommands");
                   3682: }
                   3683:
                   3684: /*
                   3685:  * Execute autocommands for "event" and file name "fname".
                   3686:  * Return TRUE if some commands were executed.
                   3687:  */
                   3688:    int
                   3689: apply_autocmds(event, fname, fname_io)
                   3690:    int             event;
                   3691:    char_u          *fname;     /* NULL or empty means use actual file name */
                   3692:    char_u          *fname_io;  /* fname to use for "^Vf" on cmdline */
                   3693: {
                   3694:    struct regexp   *prog;
                   3695:    char_u          *tail;
                   3696:    AutoPat         *ap;
                   3697:    AutoCmd         *ac;
                   3698:    int             temp;
                   3699:    int             save_changed = curbuf->b_changed;
                   3700:    char_u          *save_name;
                   3701:    char_u          *full_fname = NULL;
                   3702:    int             retval = FALSE;
                   3703:
                   3704:    if (autocmd_busy)           /* no nesting allowed */
                   3705:        return retval;
                   3706:
                   3707:        /* Don't redraw while doing auto commands. */
                   3708:    temp = RedrawingDisabled;
                   3709:    RedrawingDisabled = TRUE;
                   3710:    save_name = sourcing_name;  /* may be called from .vimrc */
                   3711:    autocmd_fname = fname_io;
                   3712:
                   3713:    /*
                   3714:     * While applying autocmds, we don't want to allow the commands
                   3715:     * :doautocmd or :autocmd.
                   3716:     */
                   3717:    autocmd_busy = TRUE;
                   3718:
                   3719:    /*
                   3720:     * When the file name is NULL or empty, use the file name of the current
                   3721:     * buffer.  Always use the full path of the file name to match with, in
                   3722:     * case "allow_directories" is set.
                   3723:     */
                   3724:    if (fname == NULL || *fname == NUL)
                   3725:    {
                   3726:        fname = curbuf->b_filename;
                   3727:        if (fname == NULL)
                   3728:            fname = (char_u *)"";
                   3729:    }
                   3730:    else
                   3731:    {
                   3732:        full_fname = FullName_save(fname);
                   3733:        fname = full_fname;
                   3734:    }
                   3735:
                   3736:    tail = gettail(fname);
                   3737:
                   3738:    for (ap = first_autopat[event]; ap != NULL; ap = ap->next)
                   3739:    {
                   3740: #ifdef CASE_INSENSITIVE_FILENAME
                   3741:        reg_ic = TRUE;      /* Always ignore case */
                   3742: #else
                   3743:        reg_ic = FALSE;     /* Don't ever ignore case */
                   3744: #endif
                   3745:        reg_magic = TRUE;   /* Always use magic */
                   3746:        prog = vim_regcomp(ap->reg_pat);
                   3747:
                   3748:        if (prog != NULL &&
                   3749:            ((ap->allow_directories && vim_regexec(prog, fname, TRUE)) ||
                   3750:            (!ap->allow_directories && vim_regexec(prog, tail, TRUE))))
                   3751:        {
                   3752:            sprintf((char *)IObuff, "%s Auto commands for \"%s\"",
                   3753:                                       event_nr2name(event), (char *)ap->pat);
                   3754:            sourcing_name = strsave(IObuff);
                   3755:            for (ac = ap->cmds; ac != NULL; ac = ac->next)
                   3756:            {
                   3757:                do_cmdline(ac->cmd, TRUE, TRUE);
                   3758:                retval = TRUE;
                   3759:            }
                   3760:            vim_free(sourcing_name);
                   3761:        }
                   3762:        vim_free(prog);
                   3763:    }
                   3764:    RedrawingDisabled = temp;
                   3765:    autocmd_busy = FALSE;
                   3766:    sourcing_name = save_name;
                   3767:    autocmd_fname = NULL;
                   3768:    vim_free(full_fname);
                   3769:
                   3770:    /* Some events don't set or reset the Changed flag */
                   3771:    if (event == EVENT_BUFREADPOST || event == EVENT_BUFWRITEPOST ||
                   3772:                     event == EVENT_FILEAPPENDPOST || event == EVENT_VIMLEAVE)
                   3773:        curbuf->b_changed = save_changed;
                   3774:
                   3775:    return retval;
                   3776: }
                   3777:
                   3778:    char_u  *
                   3779: set_context_in_autocmd(arg, doautocmd)
                   3780:    char_u  *arg;
                   3781:    int     doautocmd;      /* TRUE for :doautocmd, FALSE for :autocmd */
                   3782: {
                   3783:    char_u  *p;
                   3784:
                   3785:    /* skip over event name */
                   3786:    for (p = arg; *p && !vim_iswhite(*p); ++p)
                   3787:        if (*p == ',')
                   3788:            arg = p + 1;
                   3789:    if (*p == NUL)
                   3790:    {
                   3791:        expand_context = EXPAND_EVENTS;     /* expand event name */
                   3792:        expand_pattern = arg;
                   3793:        return NULL;
                   3794:    }
                   3795:
                   3796:    /* skip over pattern */
                   3797:    arg = skipwhite(p);
                   3798:    while (*arg && (!vim_iswhite(*arg) || arg[-1] == '\\'))
                   3799:        arg++;
                   3800:    if (*arg)
                   3801:        return arg;                         /* expand (next) command */
                   3802:
                   3803:    if (doautocmd)
                   3804:        expand_context = EXPAND_FILES;      /* expand file names */
                   3805:    else
                   3806:        expand_context = EXPAND_NOTHING;    /* pattern is not expanded */
                   3807:    return NULL;
                   3808: }
                   3809:
                   3810:    int
                   3811: ExpandEvents(prog, num_file, file)
                   3812:    regexp      *prog;
                   3813:    int         *num_file;
                   3814:    char_u      ***file;
                   3815: {
                   3816:    int     i;
                   3817:    int     count;
                   3818:    int     round;
                   3819:
                   3820:    /*
                   3821:     * round == 1: Count the matches.
                   3822:     * round == 2: Save the matches into the array.
                   3823:     */
                   3824:    for (round = 1; round <= 2; ++round)
                   3825:    {
                   3826:        count = 0;
                   3827:        for (i = 0; event_names[i].name != NULL; i++)
                   3828:            if (vim_regexec(prog, (char_u *)event_names[i].name, TRUE))
                   3829:            {
                   3830:                if (round == 1)
                   3831:                    count++;
                   3832:                else
                   3833:                    (*file)[count++] = strsave((char_u *)event_names[i].name);
                   3834:            }
                   3835:        if (round == 1)
                   3836:        {
                   3837:            *num_file = count;
                   3838:            if (count == 0 || (*file = (char_u **)
                   3839:                         alloc((unsigned)(count * sizeof(char_u *)))) == NULL)
                   3840:                return FAIL;
                   3841:        }
                   3842:    }
                   3843:    return OK;
                   3844: }
                   3845:
                   3846: #endif  /* AUTOCMD */
                   3847:
                   3848: #ifdef HAVE_LANGMAP
                   3849: /*
                   3850:  * Any character has an equivalent character.  This is used for keyboards that
                   3851:  * have a special language mode that sends characters above 128 (although
                   3852:  * other characters can be translated too).
                   3853:  */
                   3854:
                   3855: /*
                   3856:  * char_u langmap_mapchar[256];
                   3857:  * Normally maps each of the 128 upper chars to an <128 ascii char; used to
                   3858:  * "translate" native lang chars in normal mode or some cases of
                   3859:  * insert mode without having to tediously switch lang mode back&forth.
                   3860:  */
                   3861:
                   3862:    static void
                   3863: langmap_init()
                   3864: {
                   3865:    int i;
                   3866:
                   3867:    for (i = 0; i < 256; i++)           /* we init with a-one-to one map */
                   3868:        langmap_mapchar[i] = i;
                   3869: }
                   3870:
                   3871: /*
                   3872:  * Called when langmap option is set; the language map can be
                   3873:  * changed at any time!
                   3874:  */
                   3875:    static void
                   3876: langmap_set()
                   3877: {
                   3878:    char_u  *p;
                   3879:    char_u  *p2;
                   3880:    int     from, to;
                   3881:
                   3882:    langmap_init();                         /* back to one-to-one map first */
                   3883:
                   3884:    for (p = p_langmap; p[0]; )
                   3885:    {
                   3886:        for (p2 = p; p2[0] && p2[0] != ',' && p2[0] != ';'; ++p2)
                   3887:            if (p2[0] == '\\' && p2[1])
                   3888:                ++p2;
                   3889:        if (p2[0] == ';')
                   3890:            ++p2;           /* abcd;ABCD form, p2 points to A */
                   3891:        else
                   3892:            p2 = NULL;      /* aAbBcCdD form, p2 is NULL */
                   3893:        while (p[0])
                   3894:        {
                   3895:            if (p[0] == '\\' && p[1])
                   3896:                ++p;
                   3897:            from = p[0];
                   3898:            if (p2 == NULL)
                   3899:            {
                   3900:                if (p[1] == '\\')
                   3901:                    ++p;
                   3902:                to = p[1];
                   3903:            }
                   3904:            else
                   3905:            {
                   3906:                if (p2[0] == '\\')
                   3907:                    ++p2;
                   3908:                to = p2[0];
                   3909:            }
                   3910:            if (to == NUL)
                   3911:            {
                   3912:                EMSG2("'langmap': Matching character missing for %s",
                   3913:                                                             transchar(from));
                   3914:                return;
                   3915:            }
                   3916:            langmap_mapchar[from] = to;
                   3917:
                   3918:            /* Advance to next pair */
                   3919:            if (p2 == NULL)
                   3920:            {
                   3921:                p += 2;
                   3922:                if (p[0] == ',')
                   3923:                {
                   3924:                    ++p;
                   3925:                    break;
                   3926:                }
                   3927:            }
                   3928:            else
                   3929:            {
                   3930:                ++p;
                   3931:                ++p2;
                   3932:                if (*p == ';')
                   3933:                {
                   3934:                    p = p2;
                   3935:                    if (p[0])
                   3936:                    {
                   3937:                        if (p[0] != ',')
                   3938:                        {
                   3939:                            EMSG2("'langmap': Extra characters after semicolon: %s", p);
                   3940:                            return;
                   3941:                        }
                   3942:                        ++p;
                   3943:                    }
                   3944:                    break;
                   3945:                }
                   3946:            }
                   3947:        }
                   3948:    }
                   3949: }
                   3950: #endif
                   3951:
                   3952: /*
                   3953:  * Return TRUE if format option 'x' is in effect.
                   3954:  * Take care of no formatting when 'paste' is set.
                   3955:  */
                   3956:    int
                   3957: has_format_option(x)
                   3958:    int     x;
                   3959: {
                   3960:    if (p_paste)
                   3961:        return FALSE;
                   3962:    return (vim_strchr(curbuf->b_p_fo, x) != NULL);
                   3963: }
                   3964:
                   3965: /*
                   3966:  * Return TRUE if "x" is present in 'shortmess' option, or
                   3967:  * 'shortmess' contains 'a' and "x" is present in SHM_A.
                   3968:  */
                   3969:    int
                   3970: shortmess(x)
                   3971:    int     x;
                   3972: {
                   3973:    return (vim_strchr(p_shm, x) != NULL || (vim_strchr(p_shm, 'a') != NULL &&
                   3974:                                       vim_strchr((char_u *)SHM_A, x) != NULL));
                   3975: }
                   3976:
                   3977: /*
                   3978:  * set_paste_option() - Called after p_paste was set or reset.
                   3979:  */
                   3980:    static void
                   3981: paste_option_changed()
                   3982: {
                   3983:    static int      old_p_paste = FALSE;
                   3984:    static int      save_sm = 0;
                   3985:    static int      save_ru = 0;
                   3986: #ifdef RIGHTLEFT
                   3987:    static int      save_ri = 0;
                   3988:    static int      save_hkmap = 0;
                   3989: #endif
                   3990:    BUF             *buf;
                   3991:
                   3992:    if (p_paste)
                   3993:    {
                   3994:        /*
                   3995:         * Paste switched from off to on.
                   3996:         * Save the current values, so they can be restored later.
                   3997:         */
                   3998:        if (!old_p_paste)
                   3999:        {
                   4000:            /* save options for each buffer */
                   4001:            for (buf = firstbuf; buf != NULL; buf = buf->b_next)
                   4002:            {
                   4003:                buf->b_p_tw_save = buf->b_p_tw;
                   4004:                buf->b_p_wm_save = buf->b_p_wm;
                   4005:                buf->b_p_ai_save = buf->b_p_ai;
                   4006: #ifdef SMARTINDENT
                   4007:                buf->b_p_si_save = buf->b_p_si;
                   4008: #endif
                   4009: #ifdef CINDENT
                   4010:                buf->b_p_cin_save = buf->b_p_cin;
                   4011: #endif
                   4012: #ifdef LISPINDENT
                   4013:                buf->b_p_lisp_save = buf->b_p_lisp;
                   4014: #endif
                   4015:            }
                   4016:
                   4017:            /* save global options */
                   4018:            save_sm = p_sm;
                   4019:            save_ru = p_ru;
                   4020: #ifdef RIGHTLEFT
                   4021:            save_ri = p_ri;
                   4022:            save_hkmap = p_hkmap;
                   4023: #endif
                   4024:        }
                   4025:
                   4026:        /*
                   4027:         * Always set the option values, also when 'paste' is set when it is
                   4028:         * already on.
                   4029:         */
                   4030:        /* set options for each buffer */
                   4031:        for (buf = firstbuf; buf != NULL; buf = buf->b_next)
                   4032:        {
                   4033:            buf->b_p_tw = 0;        /* textwidth is 0 */
                   4034:            buf->b_p_wm = 0;        /* wrapmargin is 0 */
                   4035:            buf->b_p_ai = 0;        /* no auto-indent */
                   4036: #ifdef SMARTINDENT
                   4037:            buf->b_p_si = 0;        /* no smart-indent */
                   4038: #endif
                   4039: #ifdef CINDENT
                   4040:            buf->b_p_cin = 0;       /* no c indenting */
                   4041: #endif
                   4042: #ifdef LISPINDENT
                   4043:            buf->b_p_lisp = 0;      /* no lisp indenting */
                   4044: #endif
                   4045:        }
                   4046:
                   4047:        /* set global options */
                   4048:        p_sm = 0;                   /* no showmatch */
                   4049:        p_ru = 0;                   /* no ruler */
                   4050: #ifdef RIGHTLEFT
                   4051:        p_ri = 0;                   /* no reverse insert */
                   4052:        p_hkmap = 0;                /* no Hebrew keyboard */
                   4053: #endif
                   4054:    }
                   4055:
                   4056:    /*
                   4057:     * Paste switched from on to off: Restore saved values.
                   4058:     */
                   4059:    else if (old_p_paste)
                   4060:    {
                   4061:        /* restore options for each buffer */
                   4062:        for (buf = firstbuf; buf != NULL; buf = buf->b_next)
                   4063:        {
                   4064:            buf->b_p_tw = buf->b_p_tw_save;
                   4065:            buf->b_p_wm = buf->b_p_wm_save;
                   4066:            buf->b_p_ai = buf->b_p_ai_save;
                   4067: #ifdef SMARTINDENT
                   4068:            buf->b_p_si = buf->b_p_si_save;
                   4069: #endif
                   4070: #ifdef CINDENT
                   4071:            buf->b_p_cin = buf->b_p_cin_save;
                   4072: #endif
                   4073: #ifdef LISPINDENT
                   4074:            buf->b_p_lisp = buf->b_p_lisp_save;
                   4075: #endif
                   4076:        }
                   4077:
                   4078:        /* restore global options */
                   4079:        p_sm = save_sm;
                   4080:        p_ru = save_ru;
                   4081: #ifdef RIGHTLEFT
                   4082:        p_ri = save_ri;
                   4083:        p_hkmap = save_hkmap;
                   4084: #endif
                   4085:    }
                   4086:
                   4087:    old_p_paste = p_paste;
                   4088: }
                   4089:
                   4090: /*
                   4091:  * p_compatible_set() - Called when p_cp has been set.
                   4092:  */
                   4093:    static void
                   4094: p_compatible_set()
                   4095: {
                   4096:    p_bs = 0;                       /* normal backspace */
                   4097:                                    /* backspace and space do not wrap */
                   4098:    set_string_option((char_u *)"ww", -1, (char_u *)"", TRUE);
                   4099:    p_bk = 0;                       /* no backup file */
                   4100:                    /* Use textwidth for formatting, don't format comments */
                   4101:    set_string_option((char_u *)"fo", -1, (char_u *)FO_DFLT_VI, TRUE);
                   4102:                                    /* all compatible flags on */
                   4103:    set_string_option((char_u *)"cpo", -1, (char_u *)CPO_ALL, TRUE);
                   4104:    set_string_option((char_u *)"isk", -1, (char_u *)"@,48-57,_", TRUE);
                   4105:                                    /* no short messages */
                   4106:    set_string_option((char_u *)"shm", -1, (char_u *)"", TRUE);
                   4107: #ifdef DIGRAPHS
                   4108:    p_dg = 0;                       /* no digraphs */
                   4109: #endif /* DIGRAPHS */
                   4110:    p_ek = 0;                       /* no ESC keys in insert mode */
                   4111:    curbuf->b_p_et = 0;             /* no expansion of tabs */
                   4112:    p_gd = 0;                       /* /g is not default for :s */
                   4113:    p_hi = 0;                       /* no history */
                   4114:    p_scs = 0;                      /* no ignore case switch */
                   4115:    p_im = 0;                       /* do not start in insert mode */
                   4116:    p_js = 1;                       /* insert 2 spaces after period */
                   4117:    curbuf->b_p_ml = 0;             /* no modelines */
                   4118:    p_more = 0;                     /* no -- more -- for listings */
                   4119:    p_ru = 0;                       /* no ruler */
                   4120: #ifdef RIGHTLEFT
                   4121:    p_ri = 0;                       /* no reverse insert */
                   4122:    p_hkmap = 0;                    /* no Hebrew keyboard mapping */
                   4123: #endif
                   4124:    p_sj = 1;                       /* no scrolljump */
                   4125:    p_so = 0;                       /* no scrolloff */
                   4126:    p_sr = 0;                       /* do not round indent to shiftwidth */
                   4127:    p_sc = 0;                       /* no showcommand */
                   4128:    p_smd = 0;                      /* no showmode */
                   4129: #ifdef SMARTINDENT
                   4130:    curbuf->b_p_si = 0;             /* no smartindent */
                   4131: #endif
                   4132: #ifdef CINDENT
                   4133:    curbuf->b_p_cin = 0;            /* no C indenting */
                   4134: #endif
                   4135:    p_sta = 0;                      /* no smarttab */
                   4136:    p_sol = TRUE;                   /* Move cursor to start-of-line */
                   4137:    p_ta = 0;                       /* no automatic textmode detection */
                   4138:    curbuf->b_p_tw = 0;             /* no automatic line wrap */
                   4139:    p_to = 0;                       /* no tilde operator */
                   4140:    p_ttimeout = 0;                 /* no terminal timeout */
                   4141:    p_tr = 0;                       /* tag file names not relative */
                   4142:    p_ul = 0;                       /* no multilevel undo */
                   4143:    p_uc = 0;                       /* no autoscript file */
                   4144:    p_wb = 0;                       /* no backup file */
                   4145:    if (p_wc == TAB)
                   4146:        p_wc = Ctrl('E');           /* normal use for TAB */
                   4147:    init_chartab();                 /* make b_p_isk take effect */
                   4148: }
                   4149:
                   4150: /*
                   4151:  * fill_breakat_flags() -- called when 'breakat' changes value.
                   4152:  */
                   4153:    static void
                   4154: fill_breakat_flags()
                   4155: {
                   4156:    char_u      *c;
                   4157:    int         i;
                   4158:
                   4159:    for (i = 0; i < 256; i++)
                   4160:        breakat_flags[i] = FALSE;
                   4161:
                   4162:    if (p_breakat != NULL)
                   4163:        for (c = p_breakat; *c; c++)
                   4164:            breakat_flags[*c] = TRUE;
                   4165: }