home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / amiga / vim46src.lha / vim-4.6 / src / option.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-08  |  104.2 KB  |  4,304 lines

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