home *** CD-ROM | disk | FTP | other *** search
- /* vi:set ts=4 sw=4:
- *
- * VIM - Vi IMproved by Bram Moolenaar
- *
- * Do ":help uganda" in Vim to read copying and usage conditions.
- * Do ":help credits" in Vim to see a list of people who contributed.
- */
-
- /*
- * Code to handle user-settable options. This is all pretty much table-
- * driven. To add a new option, put it in the options array, and add a
- * variable for it in option.h. If it's a numeric option, add any necessary
- * bounds checks to do_set().
- */
-
- #include "vim.h"
- #include "globals.h"
- #include "proto.h"
- #include "option.h"
-
- struct option
- {
- char *fullname; /* full option name */
- char *shortname; /* permissible abbreviation */
- short flags; /* see below */
- char_u *var; /* pointer to variable */
- char_u *def_val; /* default value for variable (can be the same
- as the actual value) */
- };
-
- /*
- * Flags
- *
- * Note: P_EXPAND and P_IND can never be used at the same time.
- * Note: P_IND cannot be used for a terminal option.
- */
- #define P_BOOL 0x01 /* the option is boolean */
- #define P_NUM 0x02 /* the option is numeric */
- #define P_STRING 0x04 /* the option is a string */
- #define P_ALLOCED 0x08 /* the string option is in allocated memory,
- must use vim_free() when assigning new
- value. Not set if default is the same. */
- #define P_EXPAND 0x10 /* environment expansion */
- #define P_IND 0x20 /* indirect, is in curwin or curbuf */
- #define P_NODEFAULT 0x40 /* has no default value */
- #define P_DEF_ALLOCED 0x80 /* default value is in allocated memory, must
- use vim_free() when assigning new value */
- #define P_WAS_SET 0x100 /* option has been set/reset */
- #define P_NO_MKRC 0x200 /* don't include in :mkvimrc output */
-
- /*
- * The options that are in curwin or curbuf have P_IND set and a var field
- * that contains one of the values below.
- */
- #define PV_LIST 1
- #define PV_NU 2
- #define PV_SCROLL 3
- #define PV_WRAP 4
- #define PV_LBR 5
-
- #define PV_AI 6
- #define PV_BIN 7
- #define PV_CIN 8
- #define PV_CINK 9
- #define PV_CINO 10
- #define PV_CINW 11
- #define PV_COM 12
- #define PV_EOL 13
- #define PV_ET 14
- #define PV_FO 15
- #define PV_LISP 16
- #define PV_ML 17
- #define PV_MOD 18
- #define PV_RO 20
- #define PV_SI 21
- #define PV_SN 22
- #define PV_SW 23
- #define PV_TS 24
- #define PV_TW 25
- #define PV_TX 26
- #define PV_WM 27
- #define PV_ISK 28
- #define PV_INF 29
- #define PV_RL 30
-
- /*
- * The option structure is initialized here.
- * The order of the options should be alphabetic for ":set all".
- * The options with a NULL variable are 'hidden': a set command for
- * them is ignored and they are not printed.
- */
- static struct option options[] =
- {
- #ifdef RIGHTLEFT
- {"aleph", "al", P_NUM, (char_u *)&p_aleph,
- # if defined(MSDOS) || defined(WIN32) || defined(OS2)
- (char_u *)128L},
- # else
- (char_u *)224L},
- # endif
- #endif
- {"autoindent", "ai", P_BOOL|P_IND, (char_u *)PV_AI,
- (char_u *)FALSE},
- {"autoprint", "ap", P_BOOL, (char_u *)NULL,
- (char_u *)FALSE},
- {"autowrite", "aw", P_BOOL, (char_u *)&p_aw,
- (char_u *)FALSE},
- {"backspace", "bs", P_NUM, (char_u *)&p_bs,
- (char_u *)0L},
- {"backup", "bk", P_BOOL, (char_u *)&p_bk,
- (char_u *)FALSE},
- {"backupdir", "bdir", P_STRING|P_EXPAND,
- (char_u *)&p_bdir,
- (char_u *)DEF_BDIR},
- {"backupext", "bex", P_STRING, (char_u *)&p_bex,
- #ifdef VMS
- (char_u *)"_"},
- #else
- (char_u *)"~"},
- #endif
- {"beautify", "bf", P_BOOL, (char_u *)NULL,
- (char_u *)FALSE},
- {"binary", "bin", P_BOOL|P_IND, (char_u *)PV_BIN,
- (char_u *)FALSE},
- {"bioskey", "biosk",P_BOOL,
- #ifdef MSDOS
- (char_u *)&p_biosk,
- #else
- (char_u *)NULL,
- #endif
- (char_u *)TRUE},
- {"breakat", "brk", P_STRING, (char_u *)&p_breakat,
- (char_u *)" \t!@*-+_;:,./?"},
- #ifdef CINDENT
- {"cindent", "cin", P_BOOL|P_IND, (char_u *)PV_CIN,
- (char_u *)FALSE},
- {"cinkeys", "cink", P_STRING|P_IND|P_ALLOCED, (char_u *)PV_CINK,
- (char_u *)"0{,0},:,0#,!^F,o,O,e"},
- {"cinoptions", "cino", P_STRING|P_IND|P_ALLOCED, (char_u *)PV_CINO,
- (char_u *)""},
- #endif /* CINDENT */
- #if defined(SMARTINDENT) || defined(CINDENT)
- {"cinwords", "cinw", P_STRING|P_IND|P_ALLOCED, (char_u *)PV_CINW,
- (char_u *)"if,else,while,do,for,switch"},
- #endif
- {"cmdheight", "ch", P_NUM, (char_u *)&p_ch,
- (char_u *)1L},
- {"columns", "co", P_NUM|P_NODEFAULT|P_NO_MKRC, (char_u *)&Columns,
- (char_u *)80L},
- {"comments", "com", P_STRING|P_IND|P_ALLOCED, (char_u *)PV_COM,
- (char_u *)"sr:/*,mb:*,el:*/,://,b:#,:%,:XCOMM,n:>,fb:-"},
- {"compatible", "cp", P_BOOL, (char_u *)&p_cp,
- (char_u *)FALSE},
- {"cpoptions", "cpo", P_STRING, (char_u *)&p_cpo,
- #ifdef COMPATIBLE
- (char_u *)CPO_ALL},
- #else
- (char_u *)CPO_DEFAULT},
- #endif
- {"define", "def", P_STRING, (char_u *)&p_def,
- (char_u *)"^#[ \\t]*define"},
- {"dictionary", "dict", P_STRING|P_EXPAND, (char_u *)&p_dict,
- (char_u *)""},
- {"digraph", "dg", P_BOOL,
- #ifdef DIGRAPHS
- (char_u *)&p_dg,
- #else
- (char_u *)NULL,
- #endif /* DIGRAPHS */
- (char_u *)FALSE},
- {"directory", "dir", P_STRING|P_EXPAND, (char_u *)&p_dir,
- (char_u *)DEF_DIR},
- {"edcompatible","ed", P_BOOL, (char_u *)&p_ed,
- (char_u *)FALSE},
- {"endofline", "eol", P_BOOL|P_IND|P_NO_MKRC, (char_u *)PV_EOL,
- (char_u *)FALSE},
- {"equalalways", "ea", P_BOOL, (char_u *)&p_ea,
- (char_u *)TRUE},
- {"equalprg", "ep", P_STRING|P_EXPAND, (char_u *)&p_ep,
- (char_u *)""},
- {"errorbells", "eb", P_BOOL, (char_u *)&p_eb,
- (char_u *)FALSE},
- {"errorfile", "ef", P_STRING|P_EXPAND, (char_u *)&p_ef,
- #ifdef AMIGA
- (char_u *)"AztecC.Err"},
- #else
- (char_u *)"errors.vim"},
- #endif
- {"errorformat", "efm", P_STRING, (char_u *)&p_efm,
- #ifdef AMIGA
- /* don't use [^0-9] here, Manx C can't handle it */
- (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"},
- #else
- # if defined MSDOS || defined WIN32
- (char_u *)"%f(%l) : %t%*[^0-9]%n: %m,%*[^\"]\"%f\"%*[^0-9]%l: %m,%f(%l) : %m,%*[^ ] %f %l: %m,%f:%l:%m"},
- # else
- # if defined(__EMX__) /* put most common here (i.e. gcc format) at front */
- (char_u *)"%f:%l:%m,%*[^\"]\"%f\"%*[^0-9]%l: %m,\"%f\"%*[^0-9]%l: %m,%f(%l:%c) : %m"},
- # else
- # if defined(__QNX__)
- (char_u *)"%f(%l):%*[^WE]%t%*[^0123456789]%n:%m"},
- # else /* Unix, probably */
- (char_u *)"%*[^\"]\"%f\"%*[^0-9]%l: %m,\"%f\"%*[^0-9]%l: %m,%f:%l:%m,\"%f\"\\, line %l%*[^0-9]%c%*[^ ] %m"},
- # endif
- # endif
- # endif
- #endif
- {"esckeys", "ek", P_BOOL, (char_u *)&p_ek,
- #ifdef COMPATIBLE
- (char_u *)FALSE},
- #else
- (char_u *)TRUE},
- #endif
- {"expandtab", "et", P_BOOL|P_IND, (char_u *)PV_ET,
- (char_u *)FALSE},
- {"exrc", "ex", P_BOOL, (char_u *)&p_exrc,
- (char_u *)FALSE},
- {"flash", "fl", P_BOOL, (char_u *)NULL,
- (char_u *)FALSE},
- {"formatoptions","fo", P_STRING|P_IND|P_ALLOCED, (char_u *)PV_FO,
- #ifdef COMPATIBLE
- (char_u *)FO_DFLT_VI},
- #else
- (char_u *)FO_DFLT},
- #endif
- {"formatprg", "fp", P_STRING|P_EXPAND, (char_u *)&p_fp,
- (char_u *)""},
- {"gdefault", "gd", P_BOOL, (char_u *)&p_gd,
- (char_u *)FALSE},
- {"graphic", "gr", P_BOOL, (char_u *)NULL,
- (char_u *)FALSE},
- {"guifont", "gfn", P_STRING,
- #ifdef USE_GUI
- (char_u *)&p_guifont,
- (char_u *)""},
- #else
- (char_u *)NULL,
- (char_u *)NULL},
- #endif
- {"guioptions", "go", P_STRING,
- #ifdef USE_GUI
- (char_u *)&p_guioptions,
- # ifdef UNIX
- (char_u *)"agmr"},
- # else
- (char_u *)"gmr"},
- # endif
- #else
- (char_u *)NULL,
- (char_u *)NULL},
- #endif
- #if defined(USE_GUI)
- {"guipty", NULL, P_BOOL, (char_u *)&p_guipty,
- (char_u *)FALSE},
- #endif
- {"hardtabs", "ht", P_NUM, (char_u *)NULL,
- (char_u *)0L},
- {"helpfile", "hf", P_STRING|P_EXPAND, (char_u *)&p_hf,
- (char_u *)""},
- {"helpheight", "hh", P_NUM, (char_u *)&p_hh,
- (char_u *)20L},
- {"hidden", "hid", P_BOOL, (char_u *)&p_hid,
- (char_u *)FALSE},
- {"highlight", "hl", P_STRING, (char_u *)&p_hl,
- (char_u *)"8b,db,es,mb,Mn,nu,rs,sr,tb,vr,ws"},
- {"history", "hi", P_NUM, (char_u *)&p_hi,
- #ifdef COMPATIBLE
- (char_u *)0L},
- #else
- (char_u *)20L},
- #endif
- #ifdef RIGHTLEFT
- {"hkmap", "hk", P_BOOL, (char_u *)&p_hkmap,
- (char_u *)FALSE},
- #endif
- {"icon", NULL, P_BOOL, (char_u *)&p_icon,
- (char_u *)FALSE},
- {"ignorecase", "ic", P_BOOL, (char_u *)&p_ic,
- (char_u *)FALSE},
- {"include", "inc", P_STRING, (char_u *)&p_inc,
- (char_u *)"^#[ \\t]*include"},
- {"incsearch", "is", P_BOOL, (char_u *)&p_is,
- (char_u *)FALSE},
- {"infercase", "inf", P_BOOL|P_IND, (char_u *)PV_INF,
- (char_u *)FALSE},
- {"insertmode", "im", P_BOOL, (char_u *)&p_im,
- (char_u *)FALSE},
- {"isfname", "isf", P_STRING, (char_u *)&p_isf,
- #ifdef BACKSLASH_IN_FILENAME
- (char_u *)"@,48-57,/,.,-,_,+,,,$,:,\\"},
- #else
- # ifdef AMIGA
- (char_u *)"@,48-57,/,.,-,_,+,,,$,:"},
- # else /* UNIX */
- (char_u *)"@,48-57,/,.,-,_,+,,,$,:,~"},
- # endif
- #endif
- {"isident", "isi", P_STRING, (char_u *)&p_isi,
- #if defined(MSDOS) || defined(WIN32) || defined(OS2)
- (char_u *)"@,48-57,_,128-167,224-235"},
- #else
- (char_u *)"@,48-57,_,192-255"},
- #endif
- {"iskeyword", "isk", P_STRING|P_IND|P_ALLOCED, (char_u *)PV_ISK,
- #ifdef COMPATIBLE
- (char_u *)"@,48-57,_"},
- #else
- # if defined MSDOS || defined WIN32
- (char_u *)"@,48-57,_,128-167,224-235"},
- # else
- (char_u *)"@,48-57,_,192-255"},
- # endif
- #endif
- {"isprint", "isp", P_STRING, (char_u *)&p_isp,
- #if defined MSDOS || defined WIN32
- (char_u *)"@,~-255"},
- #else
- (char_u *)"@,161-255"},
- #endif
- {"joinspaces", "js", P_BOOL, (char_u *)&p_js,
- (char_u *)TRUE},
- {"keywordprg", "kp", P_STRING|P_EXPAND, (char_u *)&p_kp,
- #if defined(MSDOS) || defined(WIN32)
- (char_u *)""},
- #else
- (char_u *)"man"},
- #endif
- {"langmap", "lmap", P_STRING,
- #ifdef HAVE_LANGMAP
- (char_u *)&p_langmap,
- (char_u *)""},
- #else
- (char_u *)NULL,
- (char_u *)NULL},
- #endif
- {"laststatus", "ls", P_NUM, (char_u *)&p_ls,
- (char_u *)1L},
- {"linebreak", "lbr", P_BOOL|P_IND, (char_u *)PV_LBR,
- (char_u *)FALSE},
- {"lines", NULL, P_NUM|P_NODEFAULT|P_NO_MKRC, (char_u *)&Rows,
- #if defined MSDOS || defined WIN32
- (char_u *)25L},
- #else
- (char_u *)24L},
- #endif
- {"lisp", NULL, P_BOOL|P_IND, (char_u *)PV_LISP,
- (char_u *)FALSE},
- {"list", NULL, P_BOOL|P_IND, (char_u *)PV_LIST,
- (char_u *)FALSE},
- {"magic", NULL, P_BOOL, (char_u *)&p_magic,
- (char_u *)TRUE},
- {"makeprg", "mp", P_STRING|P_EXPAND, (char_u *)&p_mp,
- (char_u *)"make"},
- {"maxmapdepth", "mmd", P_NUM, (char_u *)&p_mmd,
- (char_u *)1000L},
- {"maxmem", "mm", P_NUM, (char_u *)&p_mm,
- (char_u *)MAXMEM},
- {"maxmemtot", "mmt", P_NUM, (char_u *)&p_mmt,
- (char_u *)MAXMEMTOT},
- {"mesg", NULL, P_BOOL, (char_u *)NULL,
- (char_u *)FALSE},
- {"modeline", "ml", P_BOOL|P_IND, (char_u *)PV_ML,
- #ifdef COMPATIBLE
- (char_u *)FALSE},
- #else
- (char_u *)TRUE},
- #endif
- {"modelines", "mls", P_NUM, (char_u *)&p_mls,
- (char_u *)5L},
- {"modified", "mod", P_BOOL|P_IND|P_NO_MKRC, (char_u *)PV_MOD,
- (char_u *)FALSE},
- {"more", NULL, P_BOOL, (char_u *)&p_more,
- #ifdef COMPATIBLE
- (char_u *)FALSE},
- #else
- (char_u *)TRUE},
- #endif
- {"mouse", NULL, P_STRING, (char_u *)&p_mouse,
- #if defined(MSDOS) || defined(WIN32)
- (char_u *)"a"},
- #else
- (char_u *)""},
- #endif
- {"mousetime", "mouset", P_NUM, (char_u *)&p_mouset,
- (char_u *)500L},
- {"novice", NULL, P_BOOL, (char_u *)NULL,
- (char_u *)FALSE},
- {"number", "nu", P_BOOL|P_IND, (char_u *)PV_NU,
- (char_u *)FALSE},
- {"open", NULL, P_BOOL, (char_u *)NULL,
- (char_u *)FALSE},
- {"optimize", "opt", P_BOOL, (char_u *)NULL,
- (char_u *)FALSE},
- {"paragraphs", "para", P_STRING, (char_u *)&p_para,
- (char_u *)"IPLPPPQPP LIpplpipbp"},
- {"paste", NULL, P_BOOL, (char_u *)&p_paste,
- (char_u *)FALSE},
- {"patchmode", "pm", P_STRING, (char_u *)&p_pm,
- (char_u *)""},
- {"path", "pa", P_STRING|P_EXPAND, (char_u *)&p_path,
- #if defined AMIGA || defined MSDOS || defined WIN32
- (char_u *)".,,"},
- #else
- # if defined(__EMX__)
- (char_u *)".,/emx/include,,"},
- # else /* Unix, probably */
- (char_u *)".,/usr/include,,"},
- # endif
- #endif
- {"prompt", NULL, P_BOOL, (char_u *)NULL,
- (char_u *)FALSE},
- {"readonly", "ro", P_BOOL|P_IND, (char_u *)PV_RO,
- (char_u *)FALSE},
- {"redraw", NULL, P_BOOL, (char_u *)NULL,
- (char_u *)FALSE},
- {"remap", NULL, P_BOOL, (char_u *)&p_remap,
- (char_u *)TRUE},
- {"report", NULL, P_NUM, (char_u *)&p_report,
- (char_u *)2L},
- #ifdef WIN32
- {"restorescreen", "rs", P_BOOL, (char_u *)&p_rs,
- (char_u *)TRUE},
- #endif
- #ifdef RIGHTLEFT
- {"revins", "ri", P_BOOL, (char_u *)&p_ri,
- (char_u *)FALSE},
- {"rightleft", "rl", P_BOOL|P_IND, (char_u *)PV_RL,
- (char_u *)FALSE},
- #endif
- {"ruler", "ru", P_BOOL, (char_u *)&p_ru,
- (char_u *)FALSE},
- {"scroll", "scr", P_NUM|P_IND|P_NO_MKRC, (char_u *)PV_SCROLL,
- (char_u *)12L},
- {"scrolljump", "sj", P_NUM, (char_u *)&p_sj,
- (char_u *)1L},
- {"scrolloff", "so", P_NUM, (char_u *)&p_so,
- (char_u *)0L},
- {"sections", "sect", P_STRING, (char_u *)&p_sections,
- (char_u *)"SHNHH HUnhsh"},
- {"secure", NULL, P_BOOL, (char_u *)&p_secure,
- (char_u *)FALSE},
- {"shell", "sh", P_STRING|P_EXPAND, (char_u *)&p_sh,
- #if defined(MSDOS)
- (char_u *)"command"},
- #else
- # if defined(WIN32)
- (char_u *)""}, /* set in set_init_1() */
- # else
- # if defined(__EMX__)
- (char_u *)"cmd.exe"},
- # else
- # if defined(ARCHIE)
- (char_u *)"gos"},
- # else
- (char_u *)"sh"},
- # endif
- # endif
- # endif
- #endif
- {"shellcmdflag","shcf", P_STRING, (char_u *)&p_shcf,
- #if defined(MSDOS) || defined(WIN32)
- (char_u *)"/c"},
- #else
- (char_u *)"-c"},
- #endif
- {"shellpipe", "sp", P_STRING, (char_u *)&p_sp,
- #if defined(UNIX) || defined(OS2)
- # ifdef ARCHIE
- (char_u *)"2>"},
- # else
- (char_u *)"| tee"},
- # endif
- #else
- (char_u *)">"},
- #endif
- {"shellquote", "shq", P_STRING, (char_u *)&p_shq,
- (char_u *)""},
- {"shellredir", "srr", P_STRING, (char_u *)&p_srr,
- (char_u *)">"},
- {"shelltype", "st", P_NUM, (char_u *)&p_st,
- (char_u *)0L},
- {"shiftround", "sr", P_BOOL, (char_u *)&p_sr,
- (char_u *)FALSE},
- {"shiftwidth", "sw", P_NUM|P_IND, (char_u *)PV_SW,
- (char_u *)8L},
- {"shortmess", "shm", P_STRING, (char_u *)&p_shm,
- (char_u *)""},
- {"shortname", "sn", P_BOOL|P_IND,
- #ifdef SHORT_FNAME
- (char_u *)NULL,
- #else
- (char_u *)PV_SN,
- #endif
- (char_u *)FALSE},
- {"showbreak", "sbr", P_STRING, (char_u *)&p_sbr,
- (char_u *)""},
- {"showcmd", "sc", P_BOOL, (char_u *)&p_sc,
- #if defined(COMPATIBLE) || defined(UNIX)
- (char_u *)FALSE},
- #else
- (char_u *)TRUE},
- #endif
- {"showmatch", "sm", P_BOOL, (char_u *)&p_sm,
- (char_u *)FALSE},
- {"showmode", "smd", P_BOOL, (char_u *)&p_smd,
- #if defined(COMPATIBLE)
- (char_u *)FALSE},
- #else
- (char_u *)TRUE},
- #endif
- {"sidescroll", "ss", P_NUM, (char_u *)&p_ss,
- (char_u *)0L},
- {"slowopen", "slow", P_BOOL, (char_u *)NULL,
- (char_u *)FALSE},
- {"smartcase", "scs", P_BOOL, (char_u *)&p_scs,
- (char_u *)FALSE},
- #ifdef SMARTINDENT
- {"smartindent", "si", P_BOOL|P_IND, (char_u *)PV_SI,
- (char_u *)FALSE},
- #endif
- {"smarttab", "sta", P_BOOL, (char_u *)&p_sta,
- (char_u *)FALSE},
- {"sourceany", NULL, P_BOOL, (char_u *)NULL,
- (char_u *)FALSE},
- {"splitbelow", "sb", P_BOOL, (char_u *)&p_sb,
- (char_u *)FALSE},
- {"startofline", "sol", P_BOOL, (char_u *)&p_sol,
- (char_u *)TRUE},
- {"suffixes", "su", P_STRING, (char_u *)&p_su,
- (char_u *)".bak,~,.o,.h,.info,.swp"},
- {"swapsync", "sws", P_STRING, (char_u *)&p_sws,
- (char_u *)"fsync"},
- {"tabstop", "ts", P_NUM|P_IND, (char_u *)PV_TS,
- (char_u *)8L},
- {"taglength", "tl", P_NUM, (char_u *)&p_tl,
- (char_u *)0L},
- {"tagrelative", "tr", P_BOOL, (char_u *)&p_tr,
- #if defined(COMPATIBLE)
- (char_u *)FALSE},
- #else
- (char_u *)TRUE},
- #endif
- {"tags", "tag", P_STRING|P_EXPAND, (char_u *)&p_tags,
- #ifdef EMACS_TAGS
- (char_u *)"./tags,./TAGS,tags,TAGS"},
- #else
- (char_u *)"./tags,tags"},
- #endif
- {"tagstack", "tgst", P_BOOL, (char_u *)NULL,
- (char_u *)FALSE},
- {"term", NULL, P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC,
- (char_u *)&term_strings[KS_NAME],
- (char_u *)""},
- {"terse", NULL, P_BOOL, (char_u *)&p_terse,
- (char_u *)FALSE},
- {"textauto", "ta", P_BOOL, (char_u *)&p_ta,
- #if defined(COMPATIBLE)
- (char_u *)FALSE},
- #else
- (char_u *)TRUE},
- #endif
- {"textmode", "tx", P_BOOL|P_IND, (char_u *)PV_TX,
- #ifdef USE_CRNL
- (char_u *)TRUE},
- #else
- (char_u *)FALSE},
- #endif
- {"textwidth", "tw", P_NUM|P_IND, (char_u *)PV_TW,
- (char_u *)0L},
- {"tildeop", "top", P_BOOL, (char_u *)&p_to,
- (char_u *)FALSE},
- {"timeout", "to", P_BOOL, (char_u *)&p_timeout,
- (char_u *)TRUE},
- {"timeoutlen", "tm", P_NUM, (char_u *)&p_tm,
- (char_u *)1000L},
- {"title", NULL, P_BOOL, (char_u *)&p_title,
- (char_u *)FALSE},
- {"titlelen", NULL, P_NUM, (char_u *)&p_titlelen,
- (char_u *)85L},
- {"ttimeout", NULL, P_BOOL, (char_u *)&p_ttimeout,
- (char_u *)FALSE},
- {"ttimeoutlen", "ttm", P_NUM, (char_u *)&p_ttm,
- (char_u *)-1L},
- {"ttybuiltin", "tbi", P_BOOL, (char_u *)&p_tbi,
- (char_u *)TRUE},
- {"ttyfast", "tf", P_BOOL|P_NO_MKRC, (char_u *)&p_tf,
- (char_u *)FALSE},
- {"ttyscroll", "tsl", P_NUM, (char_u *)&p_ttyscroll,
- (char_u *)999L},
- {"ttytype", "tty", P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC,
- (char_u *)&term_strings[KS_NAME],
- (char_u *)""},
- {"undolevels", "ul", P_NUM, (char_u *)&p_ul,
- #ifdef COMPATIBLE
- (char_u *)0L},
- #else
- # if defined(UNIX) || defined(WIN32) || defined(OS2)
- (char_u *)1000L},
- # else
- (char_u *)100L},
- # endif
- #endif
- {"updatecount", "uc", P_NUM, (char_u *)&p_uc,
- #ifdef COMPATIBLE
- (char_u *)0L},
- #else
- (char_u *)200L},
- #endif
- {"updatetime", "ut", P_NUM, (char_u *)&p_ut,
- (char_u *)4000L},
- {"viminfo", "vi", P_STRING,
- #ifdef VIMINFO
- (char_u *)&p_viminfo,
- #else
- (char_u *)NULL,
- #endif /* VIMINFO */
- (char_u *)""},
- {"visualbell", "vb", P_BOOL, (char_u *)&p_vb,
- (char_u *)FALSE},
- {"w300", NULL, P_NUM, (char_u *)NULL,
- (char_u *)0L},
- {"w1200", NULL, P_NUM, (char_u *)NULL,
- (char_u *)0L},
- {"w9600", NULL, P_NUM, (char_u *)NULL,
- (char_u *)0L},
- {"warn", NULL, P_BOOL, (char_u *)&p_warn,
- (char_u *)TRUE},
- {"weirdinvert", "wiv", P_BOOL, (char_u *)&p_wiv,
- (char_u *)FALSE},
- {"whichwrap", "ww", P_STRING, (char_u *)&p_ww,
- #ifdef COMPATIBLE
- (char_u *)""},
- #else
- (char_u *)"b,s"},
- #endif
- {"wildchar", "wc", P_NUM, (char_u *)&p_wc,
- #ifdef COMPATIBLE
- (char_u *)(long)Ctrl('E')},
- #else
- (char_u *)(long)TAB},
- #endif
- {"window", "wi", P_NUM, (char_u *)NULL,
- (char_u *)0L},
- {"winheight", "wh", P_NUM, (char_u *)&p_wh,
- (char_u *)0L},
- {"wrap", NULL, P_BOOL|P_IND, (char_u *)PV_WRAP,
- (char_u *)TRUE},
- {"wrapmargin", "wm", P_NUM|P_IND, (char_u *)PV_WM,
- (char_u *)0L},
- {"wrapscan", "ws", P_BOOL, (char_u *)&p_ws,
- (char_u *)TRUE},
- {"writeany", "wa", P_BOOL, (char_u *)&p_wa,
- (char_u *)FALSE},
- {"writebackup", "wb", P_BOOL, (char_u *)&p_wb,
- #if defined(COMPATIBLE) && !defined(WRITEBACKUP)
- (char_u *)FALSE},
- #else
- (char_u *)TRUE},
- #endif
- {"writedelay", "wd", P_NUM, (char_u *)&p_wd,
- (char_u *)0L},
-
- /* terminal output codes */
- {"t_AL", NULL, P_STRING, (char_u *)&term_strings[KS_CAL],
- (char_u *)""},
- {"t_al", NULL, P_STRING, (char_u *)&term_strings[KS_AL],
- (char_u *)""},
- {"t_cd", NULL, P_STRING, (char_u *)&term_strings[KS_CD],
- (char_u *)""},
- {"t_ce", NULL, P_STRING, (char_u *)&term_strings[KS_CE],
- (char_u *)""},
- {"t_cl", NULL, P_STRING, (char_u *)&term_strings[KS_CL],
- (char_u *)""},
- {"t_cm", NULL, P_STRING, (char_u *)&term_strings[KS_CM],
- (char_u *)""},
- {"t_CS", NULL, P_STRING, (char_u *)&term_strings[KS_CSC],
- (char_u *)""},
- {"t_cs", NULL, P_STRING, (char_u *)&term_strings[KS_CS],
- (char_u *)""},
- {"t_da", NULL, P_STRING, (char_u *)&term_strings[KS_DA],
- (char_u *)""},
- {"t_db", NULL, P_STRING, (char_u *)&term_strings[KS_DB],
- (char_u *)""},
- {"t_DL", NULL, P_STRING, (char_u *)&term_strings[KS_CDL],
- (char_u *)""},
- {"t_dl", NULL, P_STRING, (char_u *)&term_strings[KS_DL],
- (char_u *)""},
- {"t_ke", NULL, P_STRING, (char_u *)&term_strings[KS_KE],
- (char_u *)""},
- {"t_ks", NULL, P_STRING, (char_u *)&term_strings[KS_KS],
- (char_u *)""},
- {"t_md", NULL, P_STRING, (char_u *)&term_strings[KS_MD],
- (char_u *)""},
- {"t_me", NULL, P_STRING, (char_u *)&term_strings[KS_ME],
- (char_u *)""},
- {"t_mr", NULL, P_STRING, (char_u *)&term_strings[KS_MR],
- (char_u *)""},
- {"t_ms", NULL, P_STRING, (char_u *)&term_strings[KS_MS],
- (char_u *)""},
- {"t_RI", NULL, P_STRING, (char_u *)&term_strings[KS_CRI],
- (char_u *)""},
- {"t_se", NULL, P_STRING, (char_u *)&term_strings[KS_SE],
- (char_u *)""},
- {"t_so", NULL, P_STRING, (char_u *)&term_strings[KS_SO],
- (char_u *)""},
- {"t_sr", NULL, P_STRING, (char_u *)&term_strings[KS_SR],
- (char_u *)""},
- {"t_te", NULL, P_STRING, (char_u *)&term_strings[KS_TE],
- (char_u *)""},
- {"t_ti", NULL, P_STRING, (char_u *)&term_strings[KS_TI],
- (char_u *)""},
- {"t_ue", NULL, P_STRING, (char_u *)&term_strings[KS_UE],
- (char_u *)""},
- {"t_us", NULL, P_STRING, (char_u *)&term_strings[KS_US],
- (char_u *)""},
- {"t_vb", NULL, P_STRING, (char_u *)&term_strings[KS_VB],
- (char_u *)""},
- {"t_ve", NULL, P_STRING, (char_u *)&term_strings[KS_VE],
- (char_u *)""},
- {"t_vi", NULL, P_STRING, (char_u *)&term_strings[KS_VI],
- (char_u *)""},
- {"t_vs", NULL, P_STRING, (char_u *)&term_strings[KS_VS],
- (char_u *)""},
- {"t_ZH", NULL, P_STRING, (char_u *)&term_strings[KS_CZH],
- (char_u *)""},
- {"t_ZR", NULL, P_STRING, (char_u *)&term_strings[KS_CZR],
- (char_u *)""},
-
- /* terminal key codes are not here */
-
- {NULL, NULL, 0, NULL, NULL} /* end marker */
- };
-
- #define PARAM_COUNT (sizeof(options) / sizeof(struct option))
-
- #ifdef AUTOCMD
- /*
- * structures for automatic commands
- */
-
- typedef struct AutoCmd
- {
- char_u *cmd; /* The command to be executed */
- struct AutoCmd *next; /* Next AutoCmd in list */
- } AutoCmd;
-
- typedef struct AutoPat
- {
- char_u *pat; /* pattern as typed */
- char_u *reg_pat; /* pattern converted to regexp */
- int allow_directories; /* Pattern may match whole path */
- AutoCmd *cmds; /* list of commands to do */
- struct AutoPat *next; /* next AutoPat in AutoPat list */
- } AutoPat;
-
- static struct event_name
- {
- char *name; /* event name */
- int event; /* event number */
- } event_names[] =
- {
- {"BufEnter", EVENT_BUFENTER},
- {"BufLeave", EVENT_BUFLEAVE},
- {"BufNewFile", EVENT_BUFNEWFILE},
- {"BufReadPost", EVENT_BUFREADPOST},
- {"BufReadPre", EVENT_BUFREADPRE},
- {"BufRead", EVENT_BUFREADPOST},
- {"BufWritePost", EVENT_BUFWRITEPOST},
- {"BufWritePre", EVENT_BUFWRITEPRE},
- {"BufWrite", EVENT_BUFWRITEPRE},
- {"FileAppendPost", EVENT_FILEAPPENDPOST},
- {"FileAppendPre", EVENT_FILEAPPENDPRE},
- {"FileReadPost", EVENT_FILEREADPOST},
- {"FileReadPre", EVENT_FILEREADPRE},
- {"FileWritePost", EVENT_FILEWRITEPOST},
- {"FileWritePre", EVENT_FILEWRITEPRE},
- {"FilterReadPost", EVENT_FILTERREADPOST},
- {"FilterReadPre", EVENT_FILTERREADPRE},
- {"FilterWritePost", EVENT_FILTERWRITEPOST},
- {"FilterWritePre", EVENT_FILTERWRITEPRE},
- {"VimLeave", EVENT_VIMLEAVE},
- {"WinEnter", EVENT_WINENTER},
- {"WinLeave", EVENT_WINLEAVE},
- {NULL, 0}
- };
-
- static AutoPat *first_autopat[NUM_EVENTS] =
- {
- NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL
- };
- #endif
-
- static void set_option_default __ARGS((int, int));
- static void illegal_char __ARGS((char_u *, int));
- static char_u *option_expand __ARGS((int));
- static int findoption __ARGS((char_u *));
- static int find_key_option __ARGS((char_u *));
- static void showoptions __ARGS((int));
- static int option_changed __ARGS((struct option *));
- static void showoneopt __ARGS((struct option *));
- static int istermoption __ARGS((struct option *));
- static char_u *get_varp __ARGS((struct option *));
- static void option_value2string __ARGS((struct option *));
- #ifdef HAVE_LANGMAP
- static void langmap_init __ARGS((void));
- static void langmap_set __ARGS((void));
- #endif
- static void paste_option_changed __ARGS((void));
- static void p_compatible_set __ARGS((void));
- static void fill_breakat_flags __ARGS((void));
-
- /*
- * Initialize the options, first part.
- *
- * Called only once from main(), just after creating the first buffer.
- */
- void
- set_init_1()
- {
- char_u *p;
- int opt_idx;
- long n;
-
- #ifdef HAVE_LANGMAP
- langmap_init();
- #endif
-
- /*
- * Find default value for 'shell' option.
- */
- if ((p = vim_getenv((char_u *)"SHELL")) != NULL
- #if defined(MSDOS) || defined(WIN32) || defined(OS2)
- # ifdef __EMX__
- || (p = vim_getenv((char_u *)"EMXSHELL")) != NULL
- # endif
- || (p = vim_getenv((char_u *)"COMSPEC")) != NULL
- # ifdef WIN32
- || (p = default_shell()) != NULL
- # endif
- #endif
- )
- {
- p = strsave(p);
- if (p != NULL) /* we don't want a NULL */
- {
- opt_idx = findoption((char_u *)"sh");
- options[opt_idx].def_val = p;
- options[opt_idx].flags |= P_DEF_ALLOCED;
- }
- }
-
- /*
- * Set default for 'helpfile' option. This cannot be done at compile time,
- * because for Unix it is an external variable.
- */
- opt_idx = findoption((char_u *)"hf");
- #if defined(HAVE_CONFIG_H) || defined(OS2)
- options[opt_idx].def_val = help_fname;
- #else
- options[opt_idx].def_val = (char_u *)VIM_HLP;
- #endif
-
- /*
- * 'maxmemtot' and 'maxmem' may have to be adjusted for available memory
- */
- opt_idx = findoption((char_u *)"maxmemtot");
- if (options[opt_idx].def_val == (char_u *)0L)
- {
- n = (mch_avail_mem(FALSE) >> 11);
- options[opt_idx].def_val = (char_u *)n;
- opt_idx = findoption((char_u *)"maxmem");
- if ((long)options[opt_idx].def_val > n ||
- (long)options[opt_idx].def_val == 0L)
- options[opt_idx].def_val = (char_u *)n;
- }
-
- /*
- * set all the options (except the terminal options) to their default value
- */
- for (opt_idx = 0; !istermoption(&options[opt_idx]); opt_idx++)
- if (!(options[opt_idx].flags & P_NODEFAULT))
- set_option_default(opt_idx, FALSE);
-
- curbuf->b_p_initialized = TRUE;
- check_buf_options(curbuf);
- check_options();
-
- /*
- * initialize the table for 'iskeyword' et.al.
- * Must be before option_expand(), because that one needs isidchar()
- */
- init_chartab();
-
- /*
- * initialize the table for 'breakat'.
- */
- fill_breakat_flags();
-
- /*
- * Expand environment variables and things like "~" for the defaults.
- * If option_expand() returns non-NULL the variable is expanded. This can
- * only happen for non-indirect options.
- * Also set the default to the expanded value, so ":set" does not list
- * them. Don't set the P_ALLOCED flag, because we don't want to free the
- * default.
- */
- for (opt_idx = 0; !istermoption(&options[opt_idx]); opt_idx++)
- {
- p = option_expand(opt_idx);
- if (p != NULL)
- {
- *(char_u **)options[opt_idx].var = p;
- options[opt_idx].def_val = p;
- options[opt_idx].flags |= P_DEF_ALLOCED;
- }
- }
- }
-
- /*
- * Set an option to its default value.
- */
- static void
- set_option_default(opt_idx, dofree)
- int opt_idx;
- int dofree; /* TRUE when old value may be freed */
- {
- char_u *varp; /* pointer to variable for current option */
-
- varp = get_varp(&(options[opt_idx]));
- if (varp != NULL) /* nothing to do for hidden option */
- {
- if (options[opt_idx].flags & P_STRING)
- {
- /* indirect options are always in allocated memory */
- if (options[opt_idx].flags & P_IND)
- set_string_option(NULL, opt_idx,
- options[opt_idx].def_val, dofree);
- else
- {
- if (dofree && (options[opt_idx].flags & P_ALLOCED))
- free_string_option(*(char_u **)(varp));
- *(char_u **)varp = options[opt_idx].def_val;
- options[opt_idx].flags &= ~P_ALLOCED;
- }
- }
- else if (options[opt_idx].flags & P_NUM)
- *(long *)varp = (long)options[opt_idx].def_val;
- else /* P_BOOL */
- /* the cast to long is required for Manx C */
- *(int *)varp = (int)(long)options[opt_idx].def_val;
- }
- }
-
- /*
- * Initialize the options, part two: After getting Rows and Columns
- */
- void
- set_init_2()
- {
- /*
- * 'scroll' defaults to half the window height. Note that this default is
- * wrong when the window height changes.
- */
- options[findoption((char_u *)"scroll")].def_val = (char_u *)(Rows >> 1);
-
- comp_col();
- }
-
- /*
- * Initialize the options, part three: After reading the .vimrc
- */
- void
- set_init_3()
- {
- int idx1;
-
- #if defined(UNIX) || defined(OS2)
- /*
- * Set 'shellpipe' and 'shellredir', depending on the 'shell' option.
- * This is done after other initializations, where 'shell' might have been
- * set, but only if they have not been set before.
- */
- char_u *p;
- int idx2;
- int do_sp;
- int do_srr;
-
- idx1 = findoption((char_u *)"sp");
- idx2 = findoption((char_u *)"srr");
- do_sp = !(options[idx1].flags & P_WAS_SET);
- do_srr = !(options[idx2].flags & P_WAS_SET);
-
- /*
- * Isolate the name of the shell:
- * - Skip beyond any path. E.g., "/usr/bin/csh -f" -> "csh -f".
- * - Remove any argument. E.g., "csh -f" -> "csh".
- */
- p = gettail(p_sh);
- p = strnsave(p, skiptowhite(p) - p);
- if (p != NULL)
- {
- /*
- * Default for p_sp is "| tee", for p_srr is ">".
- * For known shells it is changed here to include stderr.
- */
- if ( fnamecmp(p, "csh") == 0 ||
- fnamecmp(p, "tcsh") == 0
- # ifdef OS2 /* also check with .exe extension */
- || fnamecmp(p, "csh.exe") == 0
- || fnamecmp(p, "tcsh.exe") == 0
- # endif
- )
- {
- if (do_sp)
- {
- p_sp = (char_u *)"|& tee";
- options[idx1].def_val = p_sp;
- }
- if (do_srr)
- {
- p_srr = (char_u *)">&";
- options[idx2].def_val = p_srr;
- }
- }
- else
- # ifndef OS2 /* Always use bourne shell style redirection if we reach this */
- if ( STRCMP(p, "sh") == 0 ||
- STRCMP(p, "ksh") == 0 ||
- STRCMP(p, "zsh") == 0 ||
- STRCMP(p, "bash") == 0)
- # endif
- {
- if (do_sp)
- {
- p_sp = (char_u *)"2>&1| tee";
- options[idx1].def_val = p_sp;
- }
- if (do_srr)
- {
- p_srr = (char_u *)">%s 2>&1";
- options[idx2].def_val = p_srr;
- }
- }
- vim_free(p);
- }
- #endif
-
- #if defined(MSDOS) || defined(WIN32)
- /*
- * Set 'shellcmdflag and 'shellquote' depending on the 'shell' option.
- * This is done after other initializations, where 'shell' might have been
- * set, but only if they have not been set before. Default for p_shcf is
- * "/c", for p_shq is "". For "sh" like shells it is changed here to
- * "-c" and "\"".
- */
- if (strstr((char *)p_sh, "sh") != NULL)
- {
- idx1 = findoption((char_u *)"shcf");
- if (!(options[idx1].flags & P_WAS_SET))
- {
- p_shcf = (char_u *)"-c";
- options[idx1].def_val = p_shcf;
- }
-
- idx1 = findoption((char_u *)"shq");
- if (!(options[idx1].flags & P_WAS_SET))
- {
- p_shq = (char_u *)"\"";
- options[idx1].def_val = p_shq;
- }
- }
- #endif
-
- /*
- * 'title' and 'icon' only default to true if they have not been set or reset
- * in .vimrc and we can read the old value.
- * When 'title' and 'icon' have been reset in .vimrc, we won't even check if
- * they can be reset. This reduces startup time when using X on a remote
- * machine.
- */
- idx1 = findoption((char_u *)"title");
- if (!(options[idx1].flags & P_WAS_SET) && mch_can_restore_title())
- {
- options[idx1].def_val = (char_u *)TRUE;
- p_title = TRUE;
- }
- idx1 = findoption((char_u *)"icon");
- if (!(options[idx1].flags & P_WAS_SET) && mch_can_restore_icon())
- {
- options[idx1].def_val = (char_u *)TRUE;
- p_icon = TRUE;
- }
- }
-
- /*
- * Parse 'arg' for option settings.
- *
- * 'arg' may be IObuff, but only when no errors can be present and option
- * does not need to be expanded with option_expand().
- *
- * return FAIL if errors are detected, OK otherwise
- */
- int
- do_set(arg)
- char_u *arg; /* option string (may be written to!) */
- {
- register int opt_idx;
- char_u *errmsg;
- char_u errbuf[80];
- char_u *startarg;
- int prefix; /* 1: nothing, 0: "no", 2: "inv" in front of name */
- int nextchar; /* next non-white char after option name */
- int afterchar; /* character just after option name */
- int len;
- int i;
- int key;
- int flags; /* flags for current option */
- char_u *varp = NULL; /* pointer to variable for current option */
- char_u *oldval; /* previous value if *varp */
- int errcnt = 0; /* number of errornous entries */
- long oldRows = Rows; /* remember old Rows */
- long oldColumns = Columns; /* remember old Columns */
- int oldbin; /* remember old bin option */
- long oldch = p_ch; /* remember old command line height */
- int oldea = p_ea; /* remember old 'equalalways' */
- long olduc = p_uc; /* remember old 'updatecount' */
- int did_show = FALSE; /* already showed one value */
- WIN *wp;
-
- if (*arg == NUL)
- {
- showoptions(0);
- return OK;
- }
-
- while (*arg) /* loop to process all options */
- {
- errmsg = NULL;
- startarg = arg; /* remember for error message */
-
- if (STRNCMP(arg, "all", (size_t)3) == 0)
- {
- showoptions(1);
- arg += 3;
- }
- else if (STRNCMP(arg, "termcap", (size_t)7) == 0)
- {
- showoptions(2);
- show_termcodes();
- arg += 7;
- }
- else
- {
- prefix = 1;
- if (STRNCMP(arg, "no", (size_t)2) == 0)
- {
- prefix = 0;
- arg += 2;
- }
- else if (STRNCMP(arg, "inv", (size_t)3) == 0)
- {
- prefix = 2;
- arg += 3;
- }
- /* find end of name */
- if (*arg == '<')
- {
- opt_idx = -1;
- /* check for <t_>;> */
- if (arg[1] == 't' && arg[2] == '_' && arg[3] && arg[4])
- len = 5;
- else
- {
- len = 1;
- while (arg[len] != NUL && arg[len] != '>')
- ++len;
- }
- if (arg[len] != '>')
- {
- errmsg = e_invarg;
- goto skip;
- }
- nextchar = arg[len];
- arg[len] = NUL; /* put NUL after name */
- if (arg[1] == 't' && arg[2] == '_') /* could be term code */
- opt_idx = findoption(arg + 1);
- key = 0;
- if (opt_idx == -1)
- key = find_key_option(arg + 1);
- arg[len++] = nextchar; /* restore nextchar */
- nextchar = arg[len];
- }
- else
- {
- len = 0;
- /*
- * The two characters after "t_" may not be alphanumeric.
- */
- if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
- {
- len = 4;
- }
- else
- {
- while (isalnum(arg[len]) || arg[len] == '_')
- ++len;
- }
- nextchar = arg[len];
- arg[len] = NUL; /* put NUL after name */
- opt_idx = findoption(arg);
- key = 0;
- if (opt_idx == -1)
- key = find_key_option(arg);
- arg[len] = nextchar; /* restore nextchar */
- }
-
- if (opt_idx == -1 && key == 0) /* found a mismatch: skip */
- {
- errmsg = (char_u *)"Unknown option";
- goto skip;
- }
-
- if (opt_idx >= 0)
- {
- if (options[opt_idx].var == NULL) /* hidden option: skip */
- goto skip;
-
- flags = options[opt_idx].flags;
- varp = get_varp(&(options[opt_idx]));
- }
- else
- flags = P_STRING;
-
- /* remember character after option name */
- afterchar = nextchar;
-
- /* skip white space, allow ":set ai ?" */
- while (vim_iswhite(nextchar))
- nextchar = arg[++len];
-
- if (vim_strchr((char_u *)"?=:!&", nextchar) != NULL)
- {
- arg += len;
- len = 0;
- }
-
- /*
- * allow '=' and ':' as MSDOS command.com allows only one
- * '=' character per "set" command line. grrr. (jw)
- */
- if (nextchar == '?' || (prefix == 1 && vim_strchr((char_u *)"=:&",
- nextchar) == NULL && !(flags & P_BOOL)))
- { /* print value */
- if (did_show)
- msg_outchar('\n'); /* cursor below last one */
- else
- {
- gotocmdline(TRUE); /* cursor at status line */
- did_show = TRUE; /* remember that we did a line */
- }
- if (opt_idx >= 0)
- showoneopt(&options[opt_idx]);
- else
- {
- char_u name[2];
- char_u *p;
-
- name[0] = KEY2TERMCAP0(key);
- name[1] = KEY2TERMCAP1(key);
- p = find_termcode(name);
- if (p == NULL)
- {
- errmsg = (char_u *)"Unknown option";
- goto skip;
- }
- else
- (void)show_one_termcode(name, p, TRUE);
- }
- if (nextchar != '?' && nextchar != NUL &&
- !vim_iswhite(afterchar))
- errmsg = e_trailing;
- }
- else
- {
- if (flags & P_BOOL) /* boolean */
- {
- if (nextchar == '=' || nextchar == ':')
- {
- errmsg = e_invarg;
- goto skip;
- }
-
- /*
- * in secure mode, setting of the secure option is not
- * allowed
- */
- if (secure && (int *)varp == &p_secure)
- {
- errmsg = (char_u *)"not allowed here";
- goto skip;
- }
-
- oldbin = curbuf->b_p_bin; /* remember old bin option */
-
- /*
- * ":set opt!" or ":set invopt": invert
- * ":set opt&": reset to default value
- * ":set opt" or ":set noopt": set or reset
- */
- if (prefix == 2 || nextchar == '!')
- *(int *)(varp) ^= 1;
- else if (nextchar == '&')
- /* the cast to long is required for Manx C */
- *(int *)(varp) = (int)(long)options[opt_idx].def_val;
- else
- *(int *)(varp) = prefix;
-
- /* handle the setting of the compatible option */
- if ((int *)varp == &p_cp && p_cp)
- {
- p_compatible_set();
- }
- /* when 'readonly' is reset, also reset readonlymode */
- else if ((int *)varp == &curbuf->b_p_ro && !curbuf->b_p_ro)
- readonlymode = FALSE;
-
- /* when 'bin' is set also set some other options */
- else if ((int *)varp == &curbuf->b_p_bin)
- {
- set_options_bin(oldbin, curbuf->b_p_bin);
- }
- /* when 'terse' is set change 'shortmess' */
- else if ((int *)varp == &p_terse)
- {
- char_u *p;
-
- p = vim_strchr(p_shm, SHM_SEARCH);
-
- /* insert 's' in p_shm */
- if (p_terse && p == NULL)
- {
- STRCPY(IObuff, p_shm);
- STRCAT(IObuff, "s");
- set_string_option((char_u *)"shm", -1,
- IObuff, TRUE);
- }
- /* remove 's' from p_shm */
- else if (!p_terse && p != NULL)
- vim_memmove(p, p + 1, STRLEN(p));
- }
- /* when 'paste' is set or reset also change other options */
- else if ((int *)varp == &p_paste)
- {
- paste_option_changed();
- }
- /*
- * When 'lisp' option changes include/exclude '-' in
- * keyword characters.
- */
- else if (varp == (char_u *)&(curbuf->b_p_lisp))
- init_chartab(); /* ignore errors */
-
- else if (!starting &&
- #ifdef USE_GUI
- !gui.starting &&
- #endif
- ((int *)varp == &p_title || (int *)varp == &p_icon))
- {
- /*
- * When setting 'title' or 'icon' on, call maketitle()
- * to create and display it.
- * When resetting 'title' or 'icon', call maketitle()
- * to clear it and call mch_restore_title() to get the
- * old value back.
- */
- maketitle();
- if (!*(int *)varp)
- mch_restore_title((int *)varp == &p_title ? 1 : 2);
- }
- }
- else /* numeric or string */
- {
- if (vim_strchr((char_u *)"=:&", nextchar) == NULL ||
- prefix != 1)
- {
- errmsg = e_invarg;
- goto skip;
- }
- if (flags & P_NUM) /* numeric */
- {
- /*
- * Different ways to set a number option:
- * & set to default value
- * <xx> accept special key codes for 'wildchar'
- * c accept any non-digit for 'wildchar'
- * 0-9 set number
- * other error
- */
- arg += len + 1;
- if (nextchar == '&')
- *(long *)(varp) = (long)options[opt_idx].def_val;
- else if ((long *)varp == &p_wc &&
- (*arg == '<' || *arg == '^' ||
- ((!arg[1] || vim_iswhite(arg[1])) &&
- !isdigit(*arg))))
- {
- if (*arg == '<')
- {
- i = get_special_key_code(arg + 1);
- if (i == 0)
- i = find_key_option(arg + 1);
- }
- else if (*arg == '^')
- i = arg[1] ^ 0x40;
- else
- i = *arg;
- if (i == 0)
- {
- errmsg = e_invarg;
- goto skip;
- }
- p_wc = i;
- }
- /* allow negative numbers (for 'undolevels') */
- else if (*arg == '-' || isdigit(*arg))
- {
- i = 0;
- if (*arg == '-')
- i = 1;
- #ifdef HAVE_STRTOL
- *(long *)(varp) = strtol((char *)arg, NULL, 0);
- if (arg[i] == '0' && TO_UPPER(arg[i + 1]) == 'X')
- i += 2;
- #else
- *(long *)(varp) = atol((char *)arg);
- #endif
- while (isdigit(arg[i]))
- ++i;
- if (arg[i] != NUL && !vim_iswhite(arg[i]))
- {
- errmsg = e_invarg;
- goto skip;
- }
- }
- else
- {
- errmsg = (char_u *)"Number required after =";
- goto skip;
- }
-
- /*
- * Number options that need some action when changed
- */
- if ((long *)varp == &p_wh || (long *)varp == &p_hh)
- {
- if (p_wh < 0)
- {
- errmsg = e_positive;
- p_wh = 0;
- }
- if (p_hh < 0)
- {
- errmsg = e_positive;
- p_hh = 0;
- }
- /* Change window height NOW */
- if (p_wh && lastwin != firstwin)
- {
- win_equal(curwin, FALSE);
- must_redraw = CLEAR;
- }
- }
- /* (re)set last window status line */
- if ((long *)varp == &p_ls)
- last_status();
- if ((long *)varp == &p_titlelen && !starting)
- maketitle();
- }
- else if (opt_idx >= 0) /* string */
- {
- char_u *save_arg = NULL;
- char_u *s, *p;
- int new_value_alloced; /* new string option
- was allocated */
-
- /* The old value is kept until we are sure that the new
- * value is valid. set_option_default() is therefore
- * called with FALSE
- */
- oldval = *(char_u **)(varp);
- if (nextchar == '&') /* set to default val */
- {
- set_option_default(opt_idx, FALSE);
- new_value_alloced =
- (options[opt_idx].flags & P_ALLOCED);
- }
- else
- {
- arg += len + 1; /* jump to after the '=' or ':' */
-
- /*
- * Convert 'whichwrap' number to string, for
- * backwards compatibility with Vim 3.0.
- * Misuse errbuf[] for the resulting string.
- */
- if (varp == (char_u *)&p_ww && isdigit(*arg))
- {
- *errbuf = NUL;
- i = getdigits(&arg);
- if (i & 1)
- STRCAT(errbuf, "b,");
- if (i & 2)
- STRCAT(errbuf, "s,");
- if (i & 4)
- STRCAT(errbuf, "h,l,");
- if (i & 8)
- STRCAT(errbuf, "<,>,");
- if (i & 16)
- STRCAT(errbuf, "[,],");
- if (*errbuf != NUL) /* remove trailing , */
- errbuf[STRLEN(errbuf) - 1] = NUL;
- save_arg = arg;
- arg = errbuf;
- }
- /*
- * Remove '>' before 'dir' and 'bdir', for
- * backwards compatibility with version 3.0
- */
- else if (*arg == '>' && (varp == (char_u *)&p_dir ||
- varp == (char_u *)&p_bdir))
- {
- ++arg;
- }
-
- /*
- * Copy the new string into allocated memory.
- * Can't use set_string_option(), because we need
- * to remove the backslashes.
- */
- /* get a bit too much */
- s = alloc((unsigned)(STRLEN(arg) + 1));
- if (s == NULL) /* out of memory, don't change */
- break;
- *(char_u **)(varp) = s;
-
- /*
- * Copy the string, skip over escaped chars.
- * For MS-DOS and WIN32 backslashes before normal
- * file name characters are not removed.
- */
- while (*arg && !vim_iswhite(*arg))
- {
- if (*arg == '\\' && arg[1] != NUL
- #ifdef BACKSLASH_IN_FILENAME
- && !((flags & P_EXPAND)
- && isfilechar(arg[1])
- && arg[1] != '\\')
- #endif
- )
- ++arg;
- *s++ = *arg++;
- }
- *s = NUL;
- if (save_arg != NULL) /* number for 'whichwrap' */
- arg = save_arg;
- new_value_alloced = TRUE;
- }
-
- /* expand environment variables and ~ */
- s = option_expand(opt_idx);
- if (s != NULL)
- {
- if (new_value_alloced)
- vim_free(*(char_u **)(varp));
- *(char_u **)(varp) = s;
- new_value_alloced = TRUE;
- }
-
- /*
- * options that need some action
- * to perform when changed (jw)
- */
- if (varp == (char_u *)&term_strings[KS_NAME])
- {
- if (term_strings[KS_NAME][0] == NUL)
- errmsg = (char_u *)"Cannot set 'term' to empty string";
- #ifdef USE_GUI
- if (gui.in_use)
- errmsg = (char_u *)"Cannot change term in GUI";
- #endif
- else if (set_termname(term_strings[KS_NAME]) ==
- FAIL)
- errmsg = (char_u *)"Not found in termcap";
- else
- {
- /* Screen colors may have changed. */
- outstr(T_ME);
- updateScreen(CLEAR);
- }
- }
-
- else if ((varp == (char_u *)&p_bex ||
- varp == (char_u *)&p_pm))
- {
- if (STRCMP(*p_bex == '.' ? p_bex + 1 : p_bex,
- *p_pm == '.' ? p_pm + 1 : p_pm) == 0)
- errmsg = (char_u *)"'backupext' and 'patchmode' are equal";
- }
- /*
- * 'isident', 'iskeyword', 'isprint or 'isfname'
- * option: refill chartab[]
- * If the new option is invalid, use old value.
- * 'lisp' option: refill chartab[] for '-' char
- */
- else if (varp == (char_u *)&p_isi ||
- varp == (char_u *)&(curbuf->b_p_isk) ||
- varp == (char_u *)&p_isp ||
- varp == (char_u *)&p_isf)
- {
- if (init_chartab() == FAIL)
- errmsg = e_invarg; /* error in value */
- }
- else if (varp == (char_u *)&p_hl)
- {
- /* Check 'highlight' */
- for (s = p_hl; *s; )
- {
- if (vim_strchr((char_u *)"8dehmMnrstvw",
- (i = s[0])) == NULL ||
- vim_strchr((char_u *)"bsnuir",
- (i = s[1])) == NULL ||
- ((i = s[2]) != NUL && i != ','))
- {
- illegal_char(errbuf, i);
- errmsg = errbuf;
- break;
- }
- if (s[2] == NUL)
- break;
- s = skipwhite(s + 3);
- }
- }
- else if (varp == (char_u *)&(curbuf->b_p_com))
- {
- for (s = curbuf->b_p_com; *s; )
- {
- while (*s && *s != ':')
- {
- if (vim_strchr((char_u *)COM_ALL, *s) == NULL)
- {
- errmsg = (char_u *)"Illegal flag";
- break;
- }
- ++s;
- }
- if (*s++ == NUL)
- errmsg = (char_u *)"Missing colon";
- else if (*s == ',' || *s == NUL)
- errmsg = (char_u *)"Zero length string";
- if (errmsg != NULL)
- break;
- while (*s && *s != ',')
- {
- if (*s == '\\' && s[1] != NUL)
- ++s;
- ++s;
- }
- s = skip_to_option_part(s);
- }
- }
- #ifdef VIMINFO
- else if (varp == (char_u *)&(p_viminfo))
- {
- for (s = p_viminfo; *s;)
- {
- /* Check it's a valid character */
- if (vim_strchr((char_u *)"\"'frn:/", *s)
- == NULL)
- {
- illegal_char(errbuf, *s);
- errmsg = errbuf;
- break;
- }
- if (*s == 'n') /* name is always last one */
- {
- break;
- }
- else if (*s == 'r') /* skip until next ',' */
- {
- while (*++s && *s != ',')
- ;
- }
- else /* must have a number */
- {
- while (isdigit(*++s))
- ;
-
- if (!isdigit(*(s - 1)))
- {
- sprintf((char *)errbuf,
- "Missing number after <%s>",
- transchar(*(s - 1)));
- errmsg = errbuf;
- break;
- }
- }
- s = skip_to_option_part(s);
- }
- if (*p_viminfo && errmsg == NULL
- && get_viminfo_parameter('\'') < 0)
- errmsg = (char_u *)"Must specify a ' value";
- }
- #endif /* VIMINFO */
- else if (istermoption(&options[opt_idx]) && full_screen)
- {
- ttest(FALSE);
- if (varp == (char_u *)&term_strings[KS_ME])
- {
- outstr(T_ME);
- updateScreen(CLEAR);
- }
- }
- else if (varp == (char_u *)&p_sbr)
- {
- for (s = p_sbr; *s; ++s)
- if (charsize(*s) != 1)
- errmsg = (char_u *)"contains unprintable character";
- }
- #ifdef USE_GUI
- else if (varp == (char_u *)&p_guifont)
- {
- gui_init_font();
- }
- #endif /* USE_GUI */
- #ifdef HAVE_LANGMAP
- else if (varp == (char_u *)&p_langmap)
- langmap_set();
- #endif
- else if (varp == (char_u *)&p_breakat)
- fill_breakat_flags();
- else
- {
- /*
- * Check options that are a list of flags.
- */
- p = NULL;
- if (varp == (char_u *)&p_ww)
- p = (char_u *)WW_ALL;
- if (varp == (char_u *)&p_shm)
- p = (char_u *)SHM_ALL;
- else if (varp == (char_u *)&(p_cpo))
- p = (char_u *)CPO_ALL;
- else if (varp == (char_u *)&(curbuf->b_p_fo))
- p = (char_u *)FO_ALL;
- else if (varp == (char_u *)&p_mouse)
- {
- #ifdef USE_MOUSE
- p = (char_u *)MOUSE_ALL;
- #else
- if (*p_mouse != NUL)
- errmsg = (char_u *)"No mouse support";
- #endif
- }
- #ifdef USE_GUI
- else if (varp == (char_u *)&p_guioptions)
- p = (char_u *)GO_ALL;
- #endif /* USE_GUI */
- if (p != NULL)
- {
- for (s = *(char_u **)(varp); *s; ++s)
- if (vim_strchr(p, *s) == NULL)
- {
- illegal_char(errbuf, *s);
- errmsg = errbuf;
- break;
- }
- }
- }
- if (errmsg != NULL) /* error detected */
- {
- if (new_value_alloced)
- vim_free(*(char_u **)(varp));
- *(char_u **)(varp) = oldval;
- (void)init_chartab(); /* back to the old value */
- goto skip;
- }
-
- #ifdef USE_GUI
- if (varp == (char_u *)&p_guioptions)
- gui_init_which_components(oldval);
- #endif /* USE_GUI */
-
- /*
- * Free string options that are in allocated memory.
- */
- if (flags & P_ALLOCED)
- free_string_option(oldval);
- if (new_value_alloced)
- options[opt_idx].flags |= P_ALLOCED;
- }
- else /* key code option */
- {
- char_u name[2];
- char_u *p;
-
- name[0] = KEY2TERMCAP0(key);
- name[1] = KEY2TERMCAP1(key);
- if (nextchar == '&')
- {
- if (add_termcap_entry(name, TRUE) == FAIL)
- errmsg = (char_u *)"Not found in termcap";
- }
- else
- {
- arg += len + 1; /* jump to after the '=' or ':' */
- for(p = arg; *p && !vim_iswhite(*p); ++p)
- {
- if (*p == '\\' && *(p + 1))
- ++p;
- }
- nextchar = *p;
- *p = NUL;
- add_termcode(name, arg);
- *p = nextchar;
- }
- if (full_screen)
- ttest(FALSE);
- }
- }
- if (opt_idx >= 0)
- options[opt_idx].flags |= P_WAS_SET;
- }
-
- skip:
- /*
- * Check the bounds for numeric options here
- */
- if (Rows < min_rows() && full_screen)
- {
- sprintf((char *)errbuf, "Need at least %d lines", min_rows());
- errmsg = errbuf;
- Rows = min_rows();
- }
- if (Columns < MIN_COLUMNS && full_screen)
- {
- sprintf((char *)errbuf, "Need at least %d columns",
- MIN_COLUMNS);
- errmsg = errbuf;
- Columns = MIN_COLUMNS;
- }
- /*
- * If the screenheight has been changed, assume it is the physical
- * screenheight.
- */
- if ((oldRows != Rows || oldColumns != Columns) && full_screen)
- {
- mch_set_winsize(); /* try to change the window size */
- check_winsize(); /* in case 'columns' changed */
- #ifdef MSDOS
- set_window(); /* active window may have changed */
- #endif
- }
-
- if (curbuf->b_p_ts <= 0)
- {
- errmsg = e_positive;
- curbuf->b_p_ts = 8;
- }
- if (curbuf->b_p_tw < 0)
- {
- errmsg = e_positive;
- curbuf->b_p_tw = 0;
- }
- if (p_tm < 0)
- {
- errmsg = e_positive;
- p_tm = 0;
- }
- if (p_titlelen <= 0)
- {
- errmsg = e_positive;
- p_titlelen = 85;
- }
- if ((curwin->w_p_scroll <= 0 ||
- curwin->w_p_scroll > curwin->w_height) && full_screen)
- {
- if (curwin->w_p_scroll != 0)
- errmsg = e_scroll;
- win_comp_scroll(curwin);
- }
- if (p_report < 0)
- {
- errmsg = e_positive;
- p_report = 1;
- }
- if ((p_sj < 0 || p_sj >= Rows) && full_screen)
- {
- if (Rows != oldRows) /* Rows changed, just adjust p_sj */
- p_sj = Rows / 2;
- else
- {
- errmsg = e_scroll;
- p_sj = 1;
- }
- }
- if (p_so < 0 && full_screen)
- {
- errmsg = e_scroll;
- p_so = 0;
- }
- if (p_uc < 0)
- {
- errmsg = e_positive;
- p_uc = 100;
- }
- if (p_ch < 1)
- {
- errmsg = e_positive;
- p_ch = 1;
- }
- if (p_ut < 0)
- {
- errmsg = e_positive;
- p_ut = 2000;
- }
- if (p_ss < 0)
- {
- errmsg = e_positive;
- p_ss = 0;
- }
-
- /*
- * Advance to next argument.
- * - skip until a blank found, taking care of backslashes
- * - skip blanks
- */
- while (*arg != NUL && !vim_iswhite(*arg))
- if (*arg++ == '\\' && *arg != NUL)
- ++arg;
- }
- arg = skipwhite(arg);
-
- if (errmsg)
- {
- ++no_wait_return; /* wait_return done below */
- #ifdef SLEEP_IN_EMSG
- ++dont_sleep; /* don't wait in emsg() */
- #endif
- emsg(errmsg); /* show error highlighted */
- #ifdef SLEEP_IN_EMSG
- --dont_sleep;
- #endif
- MSG_OUTSTR(": ");
- /* show argument normal */
- while (startarg < arg)
- msg_outstr(transchar(*startarg++));
- msg_end(); /* check for scrolling */
- --no_wait_return;
-
- ++errcnt; /* count number of errors */
- did_show = TRUE; /* error message counts as show */
- if (sourcing_name != NULL)
- break;
- }
- }
-
- /*
- * when 'updatecount' changes from zero to non-zero, open swap files
- */
- if (p_uc && !olduc)
- ml_open_files();
-
- if (p_ch != oldch) /* p_ch changed value */
- command_height(oldch);
- #ifdef USE_MOUSE
- if (*p_mouse == NUL)
- mch_setmouse(FALSE); /* switch mouse off */
- else
- setmouse(); /* in case 'mouse' changed */
- #endif
- comp_col(); /* in case 'ruler' or 'showcmd' changed */
- curwin->w_set_curswant = TRUE; /* in case 'list' changed */
-
- /*
- * Update the screen in case we changed something like "tabstop" or
- * "lines" or "list" that will change its appearance.
- * Also update the cursor position, in case 'wrap' is changed.
- */
- for (wp = firstwin; wp; wp = wp->w_next)
- wp->w_redr_status = TRUE; /* mark all status lines dirty */
- if (p_ea && !oldea)
- win_equal(curwin, FALSE);
- updateScreen(CURSUPD);
- return (errcnt == 0 ? OK : FAIL);
- }
-
- static void
- illegal_char(errbuf, c)
- char_u *errbuf;
- int c;
- {
- sprintf((char *)errbuf, "Illegal character <%s>", (char *)transchar(c));
- }
-
- /*
- * set_options_bin - called when 'bin' changes value.
- */
- void
- set_options_bin(oldval, newval)
- int oldval;
- int newval;
- {
- /*
- * The option values that are changed when 'bin' changes are
- * copied when 'bin is set and restored when 'bin' is reset.
- */
- if (newval)
- {
- if (!oldval) /* switched on */
- {
- curbuf->b_p_tw_nobin = curbuf->b_p_tw;
- curbuf->b_p_wm_nobin = curbuf->b_p_wm;
- curbuf->b_p_tx_nobin = curbuf->b_p_tx;
- curbuf->b_p_ta_nobin = p_ta;
- curbuf->b_p_ml_nobin = curbuf->b_p_ml;
- curbuf->b_p_et_nobin = curbuf->b_p_et;
- }
-
- curbuf->b_p_tw = 0; /* no automatic line wrap */
- curbuf->b_p_wm = 0; /* no automatic line wrap */
- curbuf->b_p_tx = 0; /* no text mode */
- p_ta = 0; /* no text auto */
- curbuf->b_p_ml = 0; /* no modelines */
- curbuf->b_p_et = 0; /* no expandtab */
- }
- else if (oldval) /* switched off */
- {
- curbuf->b_p_tw = curbuf->b_p_tw_nobin;
- curbuf->b_p_wm = curbuf->b_p_wm_nobin;
- curbuf->b_p_tx = curbuf->b_p_tx_nobin;
- p_ta = curbuf->b_p_ta_nobin;
- curbuf->b_p_ml = curbuf->b_p_ml_nobin;
- curbuf->b_p_et = curbuf->b_p_et_nobin;
- }
- }
-
- #ifdef VIMINFO
- /*
- * Find the parameter represented by the given character (eg ', :, ", or /),
- * and return its associated value in the 'viminfo' string.
- * Only works for number parameters, not for 'r' or 'n'.
- * If the parameter is not specified in the string, return -1.
- */
- int
- get_viminfo_parameter(type)
- int type;
- {
- char_u *p;
-
- p = find_viminfo_parameter(type);
- if (p != NULL && isdigit(*p))
- return atoi((char *)p);
- return -1;
- }
-
- /*
- * Find the parameter represented by the given character (eg ', :, ", or /) in
- * the 'viminfo' option and return a pointer to the string after it.
- * Return NULL if the parameter is not specified in the string.
- */
- char_u *
- find_viminfo_parameter(type)
- int type;
- {
- char_u *p;
-
- for (p = p_viminfo; *p; ++p)
- {
- if (*p == type)
- return p + 1;
- if (*p == 'n') /* 'n' is always the last one */
- break;
- p = vim_strchr(p, ','); /* skip until next ',' */
- if (p == NULL) /* hit the end without finding parameter */
- break;
- }
- return NULL;
- }
- #endif
-
- /*
- * Expand environment variables for some string options.
- * These string options cannot be indirect!
- * Return pointer to allocated memory, or NULL when not expanded.
- */
- static char_u *
- option_expand(opt_idx)
- int opt_idx;
- {
- char_u *p;
-
- /* if option doesn't need expansion or is hidden: nothing to do */
- if (!(options[opt_idx].flags & P_EXPAND) || options[opt_idx].var == NULL)
- return NULL;
-
- p = *(char_u **)(options[opt_idx].var);
-
- /*
- * Expanding this with NameBuff, expand_env() must not be passed IObuff.
- */
- expand_env(p, NameBuff, MAXPATHL);
- if (STRCMP(NameBuff, p) == 0) /* they are the same */
- return NULL;
-
- return strsave(NameBuff);
- }
-
- /*
- * Check for string options that are NULL (normally only termcap options).
- */
- void
- check_options()
- {
- int opt_idx;
- char_u **p;
-
- for (opt_idx = 0; options[opt_idx].fullname != NULL; opt_idx++)
- if ((options[opt_idx].flags & P_STRING) && options[opt_idx].var != NULL)
- {
- p = (char_u **)get_varp(&(options[opt_idx]));
- if (*p == NULL)
- *p = empty_option;
- }
- }
-
- /*
- * Check string options in a buffer for NULL value.
- */
- void
- check_buf_options(buf)
- BUF *buf;
- {
- if (buf->b_p_fo == NULL)
- buf->b_p_fo = empty_option;
- if (buf->b_p_isk == NULL)
- buf->b_p_isk = empty_option;
- if (buf->b_p_com == NULL)
- buf->b_p_com = empty_option;
- #ifdef CINDENT
- if (buf->b_p_cink == NULL)
- buf->b_p_cink = empty_option;
- if (buf->b_p_cino == NULL)
- buf->b_p_cino = empty_option;
- #endif
- #if defined(SMARTINDENT) || defined(CINDENT)
- if (buf->b_p_cinw == NULL)
- buf->b_p_cinw = empty_option;
- #endif
- }
-
- /*
- * Free the string allocated for an option.
- * Checks for the string being empty_option. This may happen if we're out of
- * memory, strsave() returned NULL, which was replaced by empty_option by
- * check_options().
- * Does NOT check for P_ALLOCED flag!
- */
- void
- free_string_option(p)
- char_u *p;
- {
- if (p != empty_option)
- vim_free(p);
- }
-
- /*
- * Set a string option to a new value.
- * The string is copied into allocated memory.
- * If 'dofree' is set, the old value may be freed.
- * if (opt_idx == -1) name is used, otherwise opt_idx is used.
- */
- void
- set_string_option(name, opt_idx, val, dofree)
- char_u *name;
- int opt_idx;
- char_u *val;
- int dofree;
- {
- char_u *s;
- char_u **varp;
-
- if (opt_idx == -1) /* use name */
- {
- opt_idx = findoption(name);
- if (opt_idx == -1) /* not found (should not happen) */
- return;
- }
-
- if (options[opt_idx].var == NULL) /* don't set hidden option */
- return;
-
- s = strsave(val);
- if (s != NULL)
- {
- varp = (char_u **)get_varp(&(options[opt_idx]));
- if (dofree && (options[opt_idx].flags & P_ALLOCED))
- free_string_option(*varp);
- *varp = s;
- /* if 'term' option set for the first time: set default value */
- if (varp == &(term_strings[KS_NAME]) &&
- *(options[opt_idx].def_val) == NUL)
- {
- options[opt_idx].def_val = s;
- options[opt_idx].flags |= P_DEF_ALLOCED;
- }
- else
- options[opt_idx].flags |= P_ALLOCED;
- }
- }
-
- /*
- * find index for option 'arg'
- * return -1 if not found
- */
- static int
- findoption(arg)
- char_u *arg;
- {
- int opt_idx;
- char *s;
-
- for (opt_idx = 0; (s = options[opt_idx].fullname) != NULL; opt_idx++)
- {
- if (STRCMP(arg, s) == 0) /* match full name */
- break;
- }
- if (s == NULL)
- {
- for (opt_idx = 0; options[opt_idx].fullname != NULL; opt_idx++)
- {
- s = options[opt_idx].shortname;
- if (s != NULL && STRCMP(arg, s) == 0) /* match short name */
- break;
- s = NULL;
- }
- }
- if (s == NULL)
- opt_idx = -1;
- return opt_idx;
- }
-
- char_u *
- get_highlight_default()
- {
- int i;
-
- i = findoption((char_u *)"hl");
- if (i >= 0)
- return options[i].def_val;
- return (char_u *)NULL;
- }
-
- static int
- find_key_option(arg)
- char_u *arg;
- {
- int key;
- int c;
-
- /* don't use get_special_key_code() for t_xx, we don't want it to call
- * add_termcap_entry() */
- if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
- key = TERMCAP2KEY(arg[2], arg[3]);
-
- /* <S-Tab> is a special case, because TAB isn't a special key */
- else if (vim_strnicmp(arg, (char_u *)"S-Tab", (size_t)5) == 0)
- key = K_S_TAB;
- else
- {
- /* Currently only the shift modifier is recognized */
- mod_mask = 0;
- if (TO_LOWER(arg[0]) == 's' && arg[1] == '-')
- {
- mod_mask = MOD_MASK_SHIFT;
- arg += 2;
- }
- c = get_special_key_code(arg);
- key = check_shifted_spec_key(c);
- if (mod_mask && c == key) /* key can't be shifted */
- key = 0;
- }
- return key;
- }
-
- /*
- * if 'all' == 0: show changed options
- * if 'all' == 1: show all normal options
- * if 'all' == 2: show all terminal options
- */
- static void
- showoptions(all)
- int all;
- {
- struct option *p;
- int col;
- int isterm;
- char_u *varp;
- struct option **items;
- int item_count;
- int run;
- int row, rows;
- int cols;
- int i;
- int len;
-
- #define INC 20
- #define GAP 3
-
- items = (struct option **)alloc((unsigned)(sizeof(struct option *) *
- PARAM_COUNT));
- if (items == NULL)
- return;
-
- set_highlight('t'); /* Highlight title */
- start_highlight();
- if (all == 2)
- MSG_OUTSTR("\n--- Terminal codes ---");
- else
- MSG_OUTSTR("\n--- Options ---");
- stop_highlight();
-
- /*
- * do the loop two times:
- * 1. display the short items
- * 2. display the long items (only strings and numbers)
- */
- for (run = 1; run <= 2 && !got_int; ++run)
- {
- /*
- * collect the items in items[]
- */
- item_count = 0;
- for (p = &options[0]; p->fullname != NULL; p++)
- {
- isterm = istermoption(p);
- varp = get_varp(p);
- if (varp != NULL && (
- (all == 2 && isterm) ||
- (all == 1 && !isterm) ||
- (all == 0 && option_changed(p))))
- {
- if (p->flags & P_BOOL)
- len = 1; /* a toggle option fits always */
- else
- {
- option_value2string(p);
- len = STRLEN(p->fullname) + strsize(NameBuff) + 1;
- }
- if ((len <= INC - GAP && run == 1) ||
- (len > INC - GAP && run == 2))
- items[item_count++] = p;
- }
- }
-
- /*
- * display the items
- */
- if (run == 1)
- {
- cols = (Columns + GAP - 3) / INC;
- if (cols == 0)
- cols = 1;
- rows = (item_count + cols - 1) / cols;
- }
- else /* run == 2 */
- rows = item_count;
- for (row = 0; row < rows && !got_int; ++row)
- {
- msg_outchar('\n'); /* go to next line */
- if (got_int) /* 'q' typed in more */
- break;
- col = 0;
- for (i = row; i < item_count; i += rows)
- {
- msg_pos(-1, col); /* make columns */
- showoneopt(items[i]);
- col += INC;
- }
- flushbuf();
- mch_breakcheck();
- }
- }
- vim_free(items);
- }
-
- /*
- * Return TRUE if option is different from the default value
- */
- static int
- option_changed(p)
- struct option *p;
- {
- char_u *varp;
-
- varp = get_varp(p);
- if (varp == NULL)
- return FALSE; /* hidden option is never changed */
-
- if (p->flags & P_NUM)
- return (*(long *)varp != (long)p->def_val);
- if (p->flags & P_BOOL)
- /* the cast to long is required for Manx C */
- return (*(int *)varp != (int)(long)p->def_val);
- /* P_STRING */
- return STRCMP(*(char_u **)varp, p->def_val);
- }
-
- /*
- * showoneopt: show the value of one option
- * must not be called with a hidden option!
- */
- static void
- showoneopt(p)
- struct option *p;
- {
- char_u *varp;
-
- varp = get_varp(p);
-
- if ((p->flags & P_BOOL) && !*(int *)varp)
- MSG_OUTSTR("no");
- else
- MSG_OUTSTR(" ");
- MSG_OUTSTR(p->fullname);
- if (!(p->flags & P_BOOL))
- {
- msg_outchar('=');
- option_value2string(p); /* put string of option value in NameBuff */
- msg_outtrans(NameBuff);
- }
- }
-
- /*
- * Write modified options as set command to a file.
- * Return FAIL on error, OK otherwise.
- */
- int
- makeset(fd)
- FILE *fd;
- {
- struct option *p;
- char_u *s;
- int e;
- char_u *varp;
-
- /*
- * The options that don't have a default (terminal name, columns, lines)
- * are never written. Terminal options are also not written.
- */
- for (p = &options[0]; !istermoption(p); p++)
- if (!(p->flags & P_NO_MKRC) && !istermoption(p) &&
- (option_changed(p)))
- {
- varp = get_varp(p);
- if (p->flags & P_BOOL)
- fprintf(fd, "set %s%s", *(int *)(varp) ? "" : "no",
- p->fullname);
- else if (p->flags & P_NUM)
- fprintf(fd, "set %s=%ld", p->fullname, *(long *)(varp));
- else /* P_STRING */
- {
- fprintf(fd, "set %s=", p->fullname);
- s = *(char_u **)(varp);
- /* some characters have to be escaped with CTRL-V or
- * backslash */
- if (s != NULL && putescstr(fd, s, TRUE) == FAIL)
- return FAIL;
- }
- #ifdef USE_CRNL
- putc('\r', fd);
- #endif
- /*
- * Only check error for this putc, should catch at least
- * the "disk full" situation.
- */
- e = putc('\n', fd);
- if (e < 0)
- return FAIL;
- }
- return OK;
- }
-
- /*
- * Clear all the terminal options.
- * If the option has been allocated, free the memory.
- * Terminal options are never hidden or indirect.
- */
- void
- clear_termoptions()
- {
- struct option *p;
-
- /*
- * Reset a few things before clearing the old options. This may cause
- * outputting a few things that the terminal doesn't understand, but the
- * screen will be cleared later, so this is OK.
- */
- #ifdef USE_MOUSE
- mch_setmouse(FALSE); /* switch mouse off */
- #endif
- mch_restore_title(3); /* restore window titles */
- #ifdef WIN32
- /*
- * Check if this is allowed now.
- */
- if (can_end_termcap_mode(FALSE) == TRUE)
- #endif
- stoptermcap(); /* stop termcap mode */
-
- for (p = &options[0]; p->fullname != NULL; p++)
- if (istermoption(p))
- {
- if (p->flags & P_ALLOCED)
- free_string_option(*(char_u **)(p->var));
- if (p->flags & P_DEF_ALLOCED)
- free_string_option(p->def_val);
- *(char_u **)(p->var) = empty_option;
- p->def_val = empty_option;
- p->flags &= ~(P_ALLOCED|P_DEF_ALLOCED);
- }
- clear_termcodes();
- }
-
- /*
- * Set the terminal option defaults to the current value.
- * Used after setting the terminal name.
- */
- void
- set_term_defaults()
- {
- struct option *p;
-
- for (p = &options[0]; p->fullname != NULL; p++)
- if (istermoption(p) && p->def_val != *(char_u **)(p->var))
- {
- if (p->flags & P_DEF_ALLOCED)
- {
- free_string_option(p->def_val);
- p->flags &= ~P_DEF_ALLOCED;
- }
- p->def_val = *(char_u **)(p->var);
- if (p->flags & P_ALLOCED)
- {
- p->flags |= P_DEF_ALLOCED;
- p->flags &= ~P_ALLOCED; /* don't free the value now */
- }
- }
- }
-
- /*
- * return TRUE if 'p' starts with 't_'
- */
- static int
- istermoption(p)
- struct option *p;
- {
- return (p->fullname[0] == 't' && p->fullname[1] == '_');
- }
-
- /*
- * Compute columns for ruler and shown command. 'sc_col' is also used to
- * decide what the maximum length of a message on the status line can be.
- * If there is a status line for the last window, 'sc_col' is independent
- * of 'ru_col'.
- */
-
- #define COL_RULER 17 /* columns needed by ruler */
-
- void
- comp_col()
- {
- int last_has_status = (p_ls == 2 || (p_ls == 1 && firstwin != lastwin));
-
- sc_col = 0;
- ru_col = 0;
- if (p_ru)
- {
- ru_col = COL_RULER + 1;
- /* no last status line, adjust sc_col */
- if (!last_has_status)
- sc_col = ru_col;
- }
- if (p_sc)
- {
- sc_col += SHOWCMD_COLS;
- if (!p_ru || last_has_status) /* no need for separating space */
- ++sc_col;
- }
- sc_col = Columns - sc_col;
- ru_col = Columns - ru_col;
- if (sc_col <= 0) /* screen too narrow, will become a mess */
- sc_col = 1;
- if (ru_col <= 0)
- ru_col = 1;
- }
-
- static char_u *
- get_varp(p)
- struct option *p;
- {
- if (!(p->flags & P_IND) || p->var == NULL)
- return p->var;
-
- switch ((long)(p->var))
- {
- case PV_LIST: return (char_u *)&(curwin->w_p_list);
- case PV_NU: return (char_u *)&(curwin->w_p_nu);
- #ifdef RIGHTLEFT
- case PV_RL: return (char_u *)&(curwin->w_p_rl);
- #endif
- case PV_SCROLL: return (char_u *)&(curwin->w_p_scroll);
- case PV_WRAP: return (char_u *)&(curwin->w_p_wrap);
- case PV_LBR: return (char_u *)&(curwin->w_p_lbr);
-
- case PV_AI: return (char_u *)&(curbuf->b_p_ai);
- case PV_BIN: return (char_u *)&(curbuf->b_p_bin);
- #ifdef CINDENT
- case PV_CIN: return (char_u *)&(curbuf->b_p_cin);
- case PV_CINK: return (char_u *)&(curbuf->b_p_cink);
- case PV_CINO: return (char_u *)&(curbuf->b_p_cino);
- #endif
- #if defined(SMARTINDENT) || defined(CINDENT)
- case PV_CINW: return (char_u *)&(curbuf->b_p_cinw);
- #endif
- case PV_COM: return (char_u *)&(curbuf->b_p_com);
- case PV_EOL: return (char_u *)&(curbuf->b_p_eol);
- case PV_ET: return (char_u *)&(curbuf->b_p_et);
- case PV_FO: return (char_u *)&(curbuf->b_p_fo);
- case PV_INF: return (char_u *)&(curbuf->b_p_inf);
- case PV_ISK: return (char_u *)&(curbuf->b_p_isk);
- case PV_LISP: return (char_u *)&(curbuf->b_p_lisp);
- case PV_ML: return (char_u *)&(curbuf->b_p_ml);
- case PV_MOD: return (char_u *)&(curbuf->b_changed);
- case PV_RO: return (char_u *)&(curbuf->b_p_ro);
- #ifdef SMARTINDENT
- case PV_SI: return (char_u *)&(curbuf->b_p_si);
- #endif
- #ifndef SHORT_FNAME
- case PV_SN: return (char_u *)&(curbuf->b_p_sn);
- #endif
- case PV_SW: return (char_u *)&(curbuf->b_p_sw);
- case PV_TS: return (char_u *)&(curbuf->b_p_ts);
- case PV_TW: return (char_u *)&(curbuf->b_p_tw);
- case PV_TX: return (char_u *)&(curbuf->b_p_tx);
- case PV_WM: return (char_u *)&(curbuf->b_p_wm);
- default: EMSG("get_varp ERROR");
- }
- /* always return a valid pointer to avoid a crash! */
- return (char_u *)&(curbuf->b_p_wm);
- }
-
- /*
- * Copy options from one window to another.
- * Used when creating a new window.
- * The 'scroll' option is not copied, because it depends on the window height.
- */
- void
- win_copy_options(wp_from, wp_to)
- WIN *wp_from;
- WIN *wp_to;
- {
- wp_to->w_p_list = wp_from->w_p_list;
- wp_to->w_p_nu = wp_from->w_p_nu;
- #ifdef RIGHTLEFT
- wp_to->w_p_rl = wp_from->w_p_rl;
- #endif
- wp_to->w_p_wrap = wp_from->w_p_wrap;
- wp_to->w_p_lbr = wp_from->w_p_lbr;
- }
-
- /*
- * Copy options from one buffer to another.
- * Used when creating a new buffer and sometimes when entering a buffer.
- * When "entering" is TRUE we will enter the bp_to buffer.
- * When "always" is TRUE, always copy the options, but only set
- * b_p_initialized when appropriate.
- */
- void
- buf_copy_options(bp_from, bp_to, entering, always)
- BUF *bp_from;
- BUF *bp_to;
- int entering;
- int always;
- {
- int should_copy = TRUE;
-
- /*
- * Don't do anything of the "to" buffer is invalid.
- */
- if (bp_to == NULL || !buf_valid(bp_to))
- return;
-
- /*
- * Only copy if the "from" buffer is valid and "to" and "from" are
- * different.
- */
- if (bp_from != NULL && buf_valid(bp_from) && bp_from != bp_to)
- {
- /*
- * Always copy when entering and 'cpo' contains 'S'.
- * Don't copy when already initialized.
- * Don't copy when 'cpo' contains 's' and not entering.
- * 'S' entering initialized 's' should_copy
- * yes yes X X TRUE
- * yes no yes X FALSE
- * no X yes X FALSE
- * X no no yes FALSE
- * X no no no TRUE
- * no yes no X TRUE
- */
- if ((vim_strchr(p_cpo, CPO_BUFOPTGLOB) == NULL || !entering) &&
- (bp_to->b_p_initialized ||
- (!entering && vim_strchr(p_cpo, CPO_BUFOPT) != NULL)))
- should_copy = FALSE;
-
- if (should_copy || always)
- {
- /*
- * Always free the allocated strings.
- * If not already initialized, set 'readonly' and copy 'textmode'.
- */
- free_buf_options(bp_to);
- if (!bp_to->b_p_initialized)
- {
- bp_to->b_p_ro = FALSE; /* don't copy readonly */
- bp_to->b_p_tx = bp_from->b_p_tx;
- bp_to->b_p_tx_nobin = bp_from->b_p_tx_nobin;
- }
-
- bp_to->b_p_ai = bp_from->b_p_ai;
- bp_to->b_p_ai_save = bp_from->b_p_ai_save;
- bp_to->b_p_sw = bp_from->b_p_sw;
- bp_to->b_p_tw = bp_from->b_p_tw;
- bp_to->b_p_tw_save = bp_from->b_p_tw_save;
- bp_to->b_p_tw_nobin = bp_from->b_p_tw_nobin;
- bp_to->b_p_wm = bp_from->b_p_wm;
- bp_to->b_p_wm_save = bp_from->b_p_wm_save;
- bp_to->b_p_wm_nobin = bp_from->b_p_wm_nobin;
- bp_to->b_p_bin = bp_from->b_p_bin;
- bp_to->b_p_et = bp_from->b_p_et;
- bp_to->b_p_et_nobin = bp_from->b_p_et_nobin;
- bp_to->b_p_ml = bp_from->b_p_ml;
- bp_to->b_p_ml_nobin = bp_from->b_p_ml_nobin;
- bp_to->b_p_inf = bp_from->b_p_inf;
- #ifndef SHORT_FNAME
- bp_to->b_p_sn = bp_from->b_p_sn;
- #endif
- bp_to->b_p_com = strsave(bp_from->b_p_com);
- bp_to->b_p_fo = strsave(bp_from->b_p_fo);
- #ifdef SMARTINDENT
- bp_to->b_p_si = bp_from->b_p_si;
- bp_to->b_p_si_save = bp_from->b_p_si_save;
- #endif
- #ifdef CINDENT
- bp_to->b_p_cin = bp_from->b_p_cin;
- bp_to->b_p_cin_save = bp_from->b_p_cin_save;
- bp_to->b_p_cink = strsave(bp_from->b_p_cink);
- bp_to->b_p_cino = strsave(bp_from->b_p_cino);
- #endif
- #if defined(SMARTINDENT) || defined(CINDENT)
- bp_to->b_p_cinw = strsave(bp_from->b_p_cinw);
- #endif
- #ifdef LISPINDENT
- bp_to->b_p_lisp = bp_from->b_p_lisp;
- bp_to->b_p_lisp_save = bp_from->b_p_lisp_save;
- #endif
- bp_to->b_p_ta_nobin = bp_from->b_p_ta_nobin;
-
- /*
- * Don't copy the options set by do_help(), use the saved values
- */
- if (!keep_help_flag && bp_from->b_help && help_save_isk != NULL)
- {
- bp_to->b_p_isk = strsave(help_save_isk);
- if (bp_to->b_p_isk != NULL)
- init_chartab();
- bp_to->b_p_ts = help_save_ts;
- bp_to->b_help = FALSE;
- }
- else
- {
- bp_to->b_p_isk = strsave(bp_from->b_p_isk);
- vim_memmove(bp_to->b_chartab, bp_from->b_chartab, (size_t)256);
- bp_to->b_p_ts = bp_from->b_p_ts;
- bp_to->b_help = bp_from->b_help;
- }
- }
-
- /*
- * When the options should be copied (ignoring "always"), set the flag
- * that indicates that the options have been initialized.
- */
- if (should_copy)
- bp_to->b_p_initialized = TRUE;
- }
-
- check_buf_options(bp_to); /* make sure we don't have NULLs */
- }
-
-
- static int expand_option_idx = -1;
- static char_u expand_option_name[5] = {'t', '_', NUL, NUL, NUL};
-
- void
- set_context_in_set_cmd(arg)
- char_u *arg;
- {
- int nextchar;
- int flags = 0; /* init for GCC */
- int opt_idx = 0; /* init for GCC */
- char_u *p;
- char_u *after_blank = NULL;
- int is_term_option = FALSE;
- int key;
-
- expand_context = EXPAND_SETTINGS;
- if (*arg == NUL)
- {
- expand_pattern = arg;
- return;
- }
- p = arg + STRLEN(arg) - 1;
- if (*p == ' ' && *(p - 1) != '\\')
- {
- expand_pattern = p + 1;
- return;
- }
- while (p != arg && (*p != ' ' || *(p - 1) == '\\'))
- {
- /* remember possible start of file name to expand */
- if ((*p == ' ' || (*p == ',' && *(p - 1) != '\\')) &&
- after_blank == NULL)
- after_blank = p + 1;
- p--;
- }
- if (p != arg)
- p++;
- if (STRNCMP(p, "no", (size_t) 2) == 0)
- {
- expand_context = EXPAND_BOOL_SETTINGS;
- p += 2;
- }
- if (STRNCMP(p, "inv", (size_t) 3) == 0)
- {
- expand_context = EXPAND_BOOL_SETTINGS;
- p += 3;
- }
- expand_pattern = arg = p;
- if (*arg == '<')
- {
- while (*p != '>')
- if (*p++ == NUL) /* expand terminal option name */
- return;
- key = get_special_key_code(arg + 1);
- if (key == 0) /* unknown name */
- {
- expand_context = EXPAND_NOTHING;
- return;
- }
- nextchar = *++p;
- is_term_option = TRUE;
- expand_option_name[2] = KEY2TERMCAP0(key);
- expand_option_name[3] = KEY2TERMCAP1(key);
- }
- else
- {
- if (p[0] == 't' && p[1] == '_')
- {
- p += 2;
- if (*p != NUL)
- ++p;
- if (*p == NUL)
- return; /* expand option name */
- nextchar = *++p;
- is_term_option = TRUE;
- expand_option_name[2] = p[-2];
- expand_option_name[3] = p[-1];
- }
- else
- {
- while (isalnum(*p) || *p == '_' || *p == '*') /* Allow * wildcard */
- p++;
- if (*p == NUL)
- return;
- nextchar = *p;
- *p = NUL;
- opt_idx = findoption(arg);
- *p = nextchar;
- if (opt_idx == -1 || options[opt_idx].var == NULL)
- {
- expand_context = EXPAND_NOTHING;
- return;
- }
- flags = options[opt_idx].flags;
- if (flags & P_BOOL)
- {
- expand_context = EXPAND_NOTHING;
- return;
- }
- }
- }
- if ((nextchar != '=' && nextchar != ':')
- || expand_context == EXPAND_BOOL_SETTINGS)
- {
- expand_context = EXPAND_UNSUCCESSFUL;
- return;
- }
- if (expand_context != EXPAND_BOOL_SETTINGS && p[1] == NUL)
- {
- expand_context = EXPAND_OLD_SETTING;
- if (is_term_option)
- expand_option_idx = -1;
- else
- expand_option_idx = opt_idx;
- expand_pattern = p + 1;
- return;
- }
- expand_context = EXPAND_NOTHING;
- if (is_term_option || (flags & P_NUM))
- return;
- if (after_blank != NULL)
- expand_pattern = after_blank;
- else
- expand_pattern = p + 1;
- if (flags & P_EXPAND)
- {
- p = options[opt_idx].var;
- if (p == (char_u *)&p_bdir || p == (char_u *)&p_dir ||
- p == (char_u *)&p_path)
- expand_context = EXPAND_DIRECTORIES;
- else
- expand_context = EXPAND_FILES;
- }
- return;
- }
-
- int
- ExpandSettings(prog, num_file, file)
- regexp *prog;
- int *num_file;
- char_u ***file;
- {
- int num_normal = 0; /* Number of matching non-term-code settings */
- int num_term = 0; /* Number of matching terminal code settings */
- int opt_idx;
- int match;
- int count = 0;
- char_u *str;
- int loop;
- int is_term_opt;
- char_u name_buf[MAX_KEY_NAME_LEN];
- int save_reg_ic;
-
- /* do this loop twice:
- * loop == 0: count the number of matching options
- * loop == 1: copy the matching options into allocated memory
- */
- for (loop = 0; loop <= 1; ++loop)
- {
- if (expand_context != EXPAND_BOOL_SETTINGS)
- {
- if (vim_regexec(prog, (char_u *)"all", TRUE))
- {
- if (loop == 0)
- num_normal++;
- else
- (*file)[count++] = strsave((char_u *)"all");
- }
- if (vim_regexec(prog, (char_u *)"termcap", TRUE))
- {
- if (loop == 0)
- num_normal++;
- else
- (*file)[count++] = strsave((char_u *)"termcap");
- }
- }
- for (opt_idx = 0; (str = (char_u *)options[opt_idx].fullname) != NULL;
- opt_idx++)
- {
- if (options[opt_idx].var == NULL)
- continue;
- if (expand_context == EXPAND_BOOL_SETTINGS
- && !(options[opt_idx].flags & P_BOOL))
- continue;
- is_term_opt = istermoption(&options[opt_idx]);
- if (is_term_opt && num_normal > 0)
- continue;
- match = FALSE;
- if (vim_regexec(prog, str, TRUE) ||
- (options[opt_idx].shortname != NULL &&
- vim_regexec(prog,
- (char_u *)options[opt_idx].shortname, TRUE)))
- match = TRUE;
- else if (is_term_opt)
- {
- name_buf[0] = '<';
- name_buf[1] = 't';
- name_buf[2] = '_';
- name_buf[3] = str[2];
- name_buf[4] = str[3];
- name_buf[5] = '>';
- name_buf[6] = NUL;
- if (vim_regexec(prog, name_buf, TRUE))
- {
- match = TRUE;
- str = name_buf;
- }
- }
- if (match)
- {
- if (loop == 0)
- {
- if (is_term_opt)
- num_term++;
- else
- num_normal++;
- }
- else
- (*file)[count++] = strsave(str);
- }
- }
- /*
- * Check terminal key codes, these are not in the option table
- */
- if (expand_context != EXPAND_BOOL_SETTINGS && num_normal == 0)
- {
- for (opt_idx = 0; (str = get_termcode(opt_idx)) != NULL; opt_idx++)
- {
- if (!isprint(str[0]) || !isprint(str[1]))
- continue;
-
- name_buf[0] = 't';
- name_buf[1] = '_';
- name_buf[2] = str[0];
- name_buf[3] = str[1];
- name_buf[4] = NUL;
-
- match = FALSE;
- if (vim_regexec(prog, name_buf, TRUE))
- match = TRUE;
- else
- {
- name_buf[0] = '<';
- name_buf[1] = 't';
- name_buf[2] = '_';
- name_buf[3] = str[0];
- name_buf[4] = str[1];
- name_buf[5] = '>';
- name_buf[6] = NUL;
-
- if (vim_regexec(prog, name_buf, TRUE))
- match = TRUE;
- }
- if (match)
- {
- if (loop == 0)
- num_term++;
- else
- (*file)[count++] = strsave(name_buf);
- }
- }
- /*
- * Check special key names.
- */
- for (opt_idx = 0; (str = get_key_name(opt_idx)) != NULL; opt_idx++)
- {
- name_buf[0] = '<';
- STRCPY(name_buf + 1, str);
- STRCAT(name_buf, ">");
-
- save_reg_ic = reg_ic;
- reg_ic = TRUE; /* ignore case here */
- if (vim_regexec(prog, name_buf, TRUE))
- {
- if (loop == 0)
- num_term++;
- else
- (*file)[count++] = strsave(name_buf);
- }
- reg_ic = save_reg_ic;
- }
- }
- if (loop == 0)
- {
- if (num_normal > 0)
- *num_file = num_normal;
- else if (num_term > 0)
- *num_file = num_term;
- else
- return OK;
- *file = (char_u **) alloc((unsigned)(*num_file * sizeof(char_u *)));
- if (*file == NULL)
- {
- *file = (char_u **)"";
- return FAIL;
- }
- }
- }
- return OK;
- }
-
- int
- ExpandOldSetting(num_file, file)
- int *num_file;
- char_u ***file;
- {
- char_u *var = NULL; /* init for GCC */
- char_u *buf;
-
- *num_file = 0;
- *file = (char_u **)alloc((unsigned)sizeof(char_u *));
- if (*file == NULL)
- return FAIL;
-
- /*
- * For a terminal key code epand_option_idx is < 0.
- */
- if (expand_option_idx < 0)
- {
- var = find_termcode(expand_option_name + 2);
- if (var == NULL)
- expand_option_idx = findoption(expand_option_name);
- }
-
- if (expand_option_idx >= 0)
- {
- /* put string of option value in NameBuff */
- option_value2string(&options[expand_option_idx]);
- var = NameBuff;
- }
- else if (var == NULL)
- var = (char_u *)"";
-
- /* A backslash is required before some characters */
- buf = strsave_escaped(var, escape_chars);
-
- if (buf == NULL)
- {
- vim_free(*file);
- *file = NULL;
- return FAIL;
- }
-
- *file[0] = buf;
- *num_file = 1;
- return OK;
- }
-
- /*
- * Get the value for the numeric or string option *op in a nice format into
- * NameBuff[]. Must not be called with a hidden option!
- */
- static void
- option_value2string(op)
- struct option *op;
- {
- char_u *varp;
-
- varp = get_varp(op);
- if (op->flags & P_NUM)
- {
- if ((long *)varp == &p_wc)
- {
- if (IS_SPECIAL(p_wc) || find_special_key_in_table((int)p_wc) >= 0)
- STRCPY(NameBuff, get_special_key_name((int)p_wc, 0));
- else
- STRCPY(NameBuff, transchar((int)p_wc));
- }
- else
- sprintf((char *)NameBuff, "%ld", *(long *)varp);
- }
- else /* P_STRING */
- {
- varp = *(char_u **)(varp);
- if (varp == NULL) /* just in case */
- NameBuff[0] = NUL;
- else if (op->flags & P_EXPAND)
- home_replace(NULL, varp, NameBuff, MAXPATHL);
- else
- STRNCPY(NameBuff, varp, MAXPATHL);
- }
- }
-
- /*
- * Convert the given pattern "pat" which has shell style wildcards in it, into
- * a regular expression, and return the result. If there is a directory path
- * separator to be matched, then TRUE is put in allow_directories, otherwise
- * FALSE is put there -- webb.
- */
- char_u *
- file_pat_to_reg_pat(pat, pat_end, allow_directories)
- char_u *pat;
- char_u *pat_end; /* first char after pattern */
- int *allow_directories; /* Result passed back out in here */
- {
- int size;
- char_u *endp;
- char_u *reg_pat;
- char_u *p;
- int i;
- int nested = 0;
- int add_dollar = TRUE;
-
- if (allow_directories != NULL)
- *allow_directories = FALSE;
-
- size = 2; /* '^' at start, '$' at end */
- for (p = pat; p < pat_end; p++)
- {
- switch (*p)
- {
- case '*':
- case '.':
- case ',':
- case '{':
- case '}':
- case '~':
- #ifdef BACKSLASH_IN_FILENAME
- case '\\':
- #endif
- size += 2;
- break;
- default:
- size++;
- break;
- }
- }
- reg_pat = alloc(size + 1);
- if (reg_pat == NULL)
- return NULL;
- i = 0;
- if (pat[0] == '*')
- while (pat[0] == '*' && pat < pat_end - 1)
- pat++;
- else
- reg_pat[i++] = '^';
- endp = pat_end - 1;
- if (*endp == '*')
- {
- while (endp - pat > 0 && *endp == '*')
- endp--;
- add_dollar = FALSE;
- }
- for (p = pat; *p && nested >= 0 && p <= endp; p++)
- {
- switch (*p)
- {
- case '*':
- reg_pat[i++] = '.';
- reg_pat[i++] = '*';
- break;
- case '.':
- case '~':
- reg_pat[i++] = '\\';
- reg_pat[i++] = *p;
- break;
- case '?':
- reg_pat[i++] = '.';
- break;
- case '\\':
- if (p[1] == NUL)
- break;
- #ifdef BACKSLASH_IN_FILENAME
- /* translate "\x" to "\\x", "\*" to "\\.*", and "\?" to "\\." */
- if (isfilechar(p[1]) || p[1] == '*' || p[1] == '?')
- {
- reg_pat[i++] = '\\';
- reg_pat[i++] = '\\';
- if (allow_directories != NULL)
- *allow_directories = TRUE;
- break;
- }
- ++p;
- #else
- if (*++p == '?')
- reg_pat[i++] = '?';
- else
- #endif
- if (*p == ',')
- reg_pat[i++] = ',';
- else
- {
- if (allow_directories != NULL && ispathsep(*p))
- *allow_directories = TRUE;
- reg_pat[i++] = '\\';
- reg_pat[i++] = *p;
- }
- break;
- case '{':
- reg_pat[i++] = '\\';
- reg_pat[i++] = '(';
- nested++;
- break;
- case '}':
- reg_pat[i++] = '\\';
- reg_pat[i++] = ')';
- --nested;
- break;
- case ',':
- if (nested)
- {
- reg_pat[i++] = '\\';
- reg_pat[i++] = '|';
- }
- else
- reg_pat[i++] = ',';
- break;
- default:
- if (allow_directories != NULL && ispathsep(*p))
- *allow_directories = TRUE;
- reg_pat[i++] = *p;
- break;
- }
- }
- if (add_dollar)
- reg_pat[i++] = '$';
- reg_pat[i] = NUL;
- if (nested != 0)
- {
- if (nested < 0)
- EMSG("Missing {.");
- else
- EMSG("Missing }.");
- vim_free(reg_pat);
- reg_pat = NULL;
- }
- return reg_pat;
- }
-
- #ifdef AUTOCMD
- /*
- * functions for automatic commands
- */
-
- static void show_autocmd __ARGS((AutoPat *ap, int event));
- static void del_autocmd __ARGS((AutoPat *ap));
- static void del_autocmd_cmds __ARGS((AutoPat *ap));
- static int event_name2nr __ARGS((char_u *start, char_u **end));
- static char *event_nr2name __ARGS((int event));
- static char_u *find_end_event __ARGS((char_u *arg));
- static int do_autocmd_event __ARGS((int event, char_u *pat,
- char_u *cmd, int forceit));
-
- static void
- show_autocmd(ap, event)
- AutoPat *ap;
- int event;
- {
- AutoCmd *ac;
-
- if (got_int) /* "q" hit for "--more--" */
- return;
- msg_outchar('\n');
- if (got_int) /* "q" hit for "--more--" */
- return;
- msg_outchar('\n');
- if (got_int) /* "q" hit for "--more--" */
- return;
- MSG_OUTSTR(event_nr2name(event));
- MSG_OUTSTR(" ");
- msg_outstr(ap->pat);
- for (ac = ap->cmds; ac != NULL; ac = ac->next)
- {
- MSG_OUTSTR("\n ");
- if (got_int) /* hit "q" at "--more--" prompt */
- return;
- msg_outtrans(ac->cmd);
- }
- }
-
- /*
- * Delete an autocommand pattern.
- */
- static void
- del_autocmd(ap)
- AutoPat *ap;
- {
- vim_free(ap->pat);
- vim_free(ap->reg_pat);
- del_autocmd_cmds(ap);
- vim_free(ap);
- }
-
- /*
- * Delete the commands from a pattern.
- */
- static void
- del_autocmd_cmds(ap)
- AutoPat *ap;
- {
- AutoCmd *ac;
-
- while (ap->cmds != NULL)
- {
- ac = ap->cmds;
- ap->cmds = ac->next;
- vim_free(ac->cmd);
- vim_free(ac);
- }
- }
-
- /*
- * Return the event number for event name "start".
- * Return -1 if the event name was not found.
- * Return a pointer to the next event name in "end".
- */
- static int
- event_name2nr(start, end)
- char_u *start;
- char_u **end;
- {
- char_u *p;
- int i;
- int len;
-
- /* the event name ends with end of line, a blank or a comma */
- for (p = start; *p && !vim_iswhite(*p) && *p != ','; ++p)
- ;
- for (i = 0; event_names[i].name != NULL; ++i)
- {
- len = strlen(event_names[i].name);
- if (len == p - start &&
- vim_strnicmp((char_u *)event_names[i].name, (char_u *)start, (size_t)len) == 0)
- break;
- }
- if (*p == ',')
- ++p;
- *end = p;
- if (event_names[i].name == NULL)
- return -1;
- return event_names[i].event;
- }
-
- /*
- * Return the name for event "event".
- */
- static char *
- event_nr2name(event)
- int event;
- {
- int i;
-
- for (i = 0; event_names[i].name != NULL; ++i)
- if (event_names[i].event == event)
- return event_names[i].name;
- return "Unknown";
- }
-
- /*
- * Scan over the events. "*" stands for all events.
- */
- static char_u *
- find_end_event(arg)
- char_u *arg;
- {
- char_u *pat;
- char_u *p;
-
- if (*arg == '*')
- {
- if (arg[1] && !vim_iswhite(arg[1]))
- {
- EMSG2("Illegal character after *: %s", arg);
- return NULL;
- }
- pat = arg + 1;
- }
- else
- {
- for (pat = arg; *pat && !vim_iswhite(*pat); pat = p)
- {
- if (event_name2nr(pat, &p) < 0)
- {
- EMSG2("No such event: %s", pat);
- return NULL;
- }
- }
- }
- return pat;
- }
-
- /*
- * do_autocmd() -- implements the :autocmd command. Can be used in the
- * following ways:
- *
- * :autocmd <event> <pat> <cmd> Add <cmd> to the list of commands that
- * will be automatically executed for <event>
- * when editing a file matching <pat>.
- * :autocmd <event> <pat> Show the auto-commands associated with
- * <event> and <pat>.
- * :autocmd <event> Show the auto-commands associated with
- * <event>.
- * :autocmd Show all auto-commands.
- * :autocmd! <event> <pat> <cmd> Remove all auto-commands associated with
- * <event> and <pat>, and add the command
- * <cmd>.
- * :autocmd! <event> <pat> Remove all auto-commands associated with
- * <event> and <pat>.
- * :autocmd! <event> Remove all auto-commands associated with
- * <event>.
- * :autocmd! Remove ALL auto-commands.
- *
- * Multiple events and patterns may be given separated by commas. Here are
- * some examples:
- * :autocmd bufread,bufenter *.c,*.h set tw=0 smartindent noic
- * :autocmd bufleave * set tw=79 nosmartindent ic infercase
- *
- * :autocmd * *.c show all autocommands for *.c files.
- */
- void
- do_autocmd(arg, forceit)
- char_u *arg;
- int forceit;
- {
- char_u *pat;
- char_u *cmd;
- int event;
-
- /*
- * Don't change autocommands while executing one.
- */
- if (autocmd_busy)
- return;
-
- /*
- * Scan over the events.
- * If we find an illegal name, return here, don't do anything.
- */
- pat = find_end_event(arg);
- if (pat == NULL)
- return;
-
- /*
- * Scan over the pattern. Put a NUL at the end.
- */
- pat = skipwhite(pat);
- cmd = pat;
- while (*cmd && (!vim_iswhite(*cmd) || cmd[-1] == '\\'))
- cmd++;
- if (*cmd)
- *cmd++ = NUL;
-
- /*
- * Find the start of the commands.
- */
- cmd = skipwhite(cmd);
-
- /*
- * Print header when showing autocommands.
- */
- if (!forceit && *cmd == NUL)
- {
- set_highlight('t'); /* Highlight title */
- start_highlight();
- MSG_OUTSTR("\n--- Auto-Commands ---");
- stop_highlight();
- }
-
- /*
- * Loop over the events.
- */
- if (*arg == '*' || *arg == NUL)
- {
- for (event = 0; event < NUM_EVENTS; ++event)
- if (do_autocmd_event(event, pat, cmd, forceit) == FAIL)
- break;
- }
- else
- {
- while (*arg && !vim_iswhite(*arg))
- if (do_autocmd_event(event_name2nr(arg, &arg), pat,
- cmd, forceit) == FAIL)
- break;
- }
- }
-
- /*
- * do_autocmd() for one event.
- * If *pat == NUL do for all patterns.
- * If *cmd == NUL show entries.
- * If forceit == TRUE delete entries.
- */
- static int
- do_autocmd_event(event, pat, cmd, forceit)
- int event;
- char_u *pat;
- char_u *cmd;
- int forceit;
- {
- AutoPat *ap;
- AutoPat *ap2;
- AutoPat **final_ap;
- AutoCmd *ac;
- AutoCmd **final_ac;
- int nested;
- char_u *endpat;
- int len;
-
- /*
- * Show or delete all patterns for an event.
- */
- if (*pat == NUL)
- {
- for (ap = first_autopat[event]; ap != NULL; ap = ap2)
- {
- ap2 = ap->next;
- if (forceit)
- del_autocmd(ap);
- else
- show_autocmd(ap, event);
- }
- if (forceit)
- first_autopat[event] = NULL;
- }
-
- /*
- * Loop through all the specified patterns.
- */
- for ( ; *pat; pat = (*endpat == ',' ? endpat + 1 : endpat))
- {
- /*
- * Find end of the pattern.
- * Watch out for a comma in braces, like "*.\{obj,o\}".
- */
- nested = 0;
- for (endpat = pat;
- *endpat && (*endpat != ',' || nested || endpat[-1] == '\\');
- ++endpat)
- {
- if (*endpat == '{')
- nested++;
- else if (*endpat == '}')
- nested--;
- }
- if (pat == endpat) /* ignore single comma */
- continue;
-
- /*
- * Find entry with same pattern.
- */
- final_ap = &first_autopat[event];
- for (ap = first_autopat[event]; ap != NULL; ap = *final_ap)
- {
- len = STRLEN(ap->pat);
- if (len == endpat - pat && STRNCMP(pat, ap->pat, len) == 0)
- break;
- final_ap = &ap->next;
- }
-
- /*
- * Add a new pattern.
- * Show and delete are ignored if pattern is not found.
- */
- if (ap == NULL)
- {
- if (*cmd == NUL)
- continue;
-
- /* Add the autocmd at the end of the list */
- ap = (AutoPat *)alloc((unsigned)sizeof(AutoPat));
- if (ap == NULL)
- return FAIL;
- ap->pat = strnsave(pat, (int)(endpat - pat));
- if (ap->pat == NULL)
- {
- vim_free(ap);
- return FAIL;
- }
- ap->reg_pat = file_pat_to_reg_pat(pat, endpat,
- &ap->allow_directories);
- if (ap->reg_pat == NULL)
- {
- vim_free(ap->pat);
- vim_free(ap);
- return FAIL;
- }
- ap->cmds = NULL;
- *final_ap = ap;
- ap->next = NULL;
- }
-
- /*
- * Remove existing autocommands.
- * If not adding any new autocmd's for this pattern, delete the
- * pattern from the autopat list
- */
- else if (forceit)
- {
- del_autocmd_cmds(ap);
- if (*cmd == NUL)
- {
- if (ap == first_autopat[event])
- first_autopat[event] = ap->next;
- else
- {
- for (ap2 = first_autopat[event];
- ap2->next != ap;
- ap2 = ap2->next)
- ;
- ap2->next = ap->next;
- }
- del_autocmd(ap);
- }
- }
-
- /*
- * Show autocmd's for this autopat
- */
- if (*cmd == NUL && !forceit)
- {
- show_autocmd(ap, event);
- }
-
- /*
- * Add the autocmd at the end if it's not already there.
- */
- else if (*cmd != NUL)
- {
- final_ac = &(ap->cmds);
- for (ac = ap->cmds;
- ac != NULL && STRCMP(cmd, ac->cmd) != 0;
- ac = ac->next)
- final_ac = &ac->next;
- if (ac == NULL)
- {
- ac = (AutoCmd *)alloc((unsigned)sizeof(AutoCmd));
- if (ac == NULL)
- return FAIL;
- ac->cmd = strsave(cmd);
- if (ac->cmd == NULL)
- {
- vim_free(ac);
- return FAIL;
- }
- ac->next = NULL;
- *final_ac = ac;
- }
- }
- }
- return OK;
- }
-
- /*
- * Implementation of ":doautocmd event [fname]".
- */
- void
- do_doautocmd(arg)
- char_u *arg;
- {
- char_u *fname;
- int nothing_done = TRUE;
- static int nesting = 0;
-
- /*
- * Allow nesting of autocommands, but restrict the depth, because it's
- * possible to create an endless loop.
- */
- if (nesting == 10)
- {
- EMSG(":doautocmd nesting too deep");
- return;
- }
-
- if (*arg == '*')
- {
- EMSG("Can't execute autocommands for ALL events");
- return;
- }
-
- /*
- * Scan over the events.
- * If we find an illegal name, return here, don't do anything.
- */
- fname = find_end_event(arg);
- if (fname == NULL)
- return;
-
- fname = skipwhite(fname);
-
- ++nesting;
- /*
- * Loop over the events.
- */
- while (*arg && !vim_iswhite(*arg))
- if (apply_autocmds(event_name2nr(arg, &arg), fname, NULL, TRUE))
- nothing_done = FALSE;
-
- if (nothing_done)
- MSG("No matching autocommands");
- --nesting;
- }
-
- /*
- * Execute autocommands for "event" and file name "fname".
- * Return TRUE if some commands were executed.
- */
- int
- apply_autocmds(event, fname, fname_io, force)
- int event;
- char_u *fname; /* NULL or empty means use actual file name */
- char_u *fname_io; /* fname to use for "^Vf" on cmdline */
- int force; /* when TRUE, ignore autocmd_busy */
- {
- struct regexp *prog;
- char_u *tail;
- AutoPat *ap;
- AutoCmd *ac;
- int temp;
- int save_changed = curbuf->b_changed;
- BUF *old_curbuf = curbuf;
- char_u *save_name;
- char_u *full_fname = NULL;
- int retval = FALSE;
-
- if (autocmd_busy && !force) /* no nesting allowed */
- return retval;
- /*
- * Check if these autocommands are disabled. Used when doing ":all" or
- * ":ball".
- */
- if ( (autocmd_no_enter &&
- (event == EVENT_WINENTER || event == EVENT_BUFENTER)) ||
- (autocmd_no_leave &&
- (event == EVENT_WINLEAVE || event == EVENT_BUFLEAVE)))
- return retval;
-
- /* Don't redraw while doing auto commands. */
- temp = RedrawingDisabled;
- RedrawingDisabled = TRUE;
- save_name = sourcing_name; /* may be called from .vimrc */
- autocmd_fname = fname_io;
-
- /*
- * While applying autocmds, we don't want to allow the commands
- * :doautocmd or :autocmd.
- */
- autocmd_busy = TRUE;
-
- /*
- * When the file name is NULL or empty, use the file name of the current
- * buffer. Always use the full path of the file name to match with, in
- * case "allow_directories" is set.
- */
- if (fname == NULL || *fname == NUL)
- {
- fname = curbuf->b_filename;
- if (fname == NULL)
- fname = (char_u *)"";
- }
- else
- {
- full_fname = FullName_save(fname);
- fname = full_fname;
- }
-
- tail = gettail(fname);
-
- for (ap = first_autopat[event]; ap != NULL && !got_int; ap = ap->next)
- {
- #ifdef CASE_INSENSITIVE_FILENAME
- reg_ic = TRUE; /* Always ignore case */
- #else
- reg_ic = FALSE; /* Don't ever ignore case */
- #endif
- reg_magic = TRUE; /* Always use magic */
- prog = vim_regcomp(ap->reg_pat);
-
- if (prog != NULL &&
- ((ap->allow_directories && vim_regexec(prog, fname, TRUE)) ||
- (!ap->allow_directories && vim_regexec(prog, tail, TRUE))))
- {
- sprintf((char *)IObuff, "%s Auto commands for \"%s\"",
- event_nr2name(event), (char *)ap->pat);
- sourcing_name = strsave(IObuff);
- for (ac = ap->cmds; ac != NULL; ac = ac->next)
- {
- do_cmdline(ac->cmd, TRUE, TRUE);
- retval = TRUE;
- }
- vim_free(sourcing_name);
- }
- vim_free(prog);
- mch_breakcheck();
- }
- RedrawingDisabled = temp;
- autocmd_busy = FALSE;
- sourcing_name = save_name;
- autocmd_fname = NULL;
- vim_free(full_fname);
-
- /*
- * Some events don't set or reset the Changed flag.
- * Check if still in the same buffer!
- */
- if (curbuf == old_curbuf &&
- (event == EVENT_BUFREADPOST || event == EVENT_BUFWRITEPOST ||
- event == EVENT_FILEAPPENDPOST || event == EVENT_VIMLEAVE))
- curbuf->b_changed = save_changed;
-
- return retval;
- }
-
- char_u *
- set_context_in_autocmd(arg, doautocmd)
- char_u *arg;
- int doautocmd; /* TRUE for :doautocmd, FALSE for :autocmd */
- {
- char_u *p;
-
- /* skip over event name */
- for (p = arg; *p && !vim_iswhite(*p); ++p)
- if (*p == ',')
- arg = p + 1;
- if (*p == NUL)
- {
- expand_context = EXPAND_EVENTS; /* expand event name */
- expand_pattern = arg;
- return NULL;
- }
-
- /* skip over pattern */
- arg = skipwhite(p);
- while (*arg && (!vim_iswhite(*arg) || arg[-1] == '\\'))
- arg++;
- if (*arg)
- return arg; /* expand (next) command */
-
- if (doautocmd)
- expand_context = EXPAND_FILES; /* expand file names */
- else
- expand_context = EXPAND_NOTHING; /* pattern is not expanded */
- return NULL;
- }
-
- int
- ExpandEvents(prog, num_file, file)
- regexp *prog;
- int *num_file;
- char_u ***file;
- {
- int i;
- int count;
- int round;
-
- /*
- * round == 1: Count the matches.
- * round == 2: Save the matches into the array.
- */
- for (round = 1; round <= 2; ++round)
- {
- count = 0;
- for (i = 0; event_names[i].name != NULL; i++)
- if (vim_regexec(prog, (char_u *)event_names[i].name, TRUE))
- {
- if (round == 1)
- count++;
- else
- (*file)[count++] = strsave((char_u *)event_names[i].name);
- }
- if (round == 1)
- {
- *num_file = count;
- if (count == 0 || (*file = (char_u **)
- alloc((unsigned)(count * sizeof(char_u *)))) == NULL)
- return FAIL;
- }
- }
- return OK;
- }
-
- #endif /* AUTOCMD */
-
- #ifdef HAVE_LANGMAP
- /*
- * Any character has an equivalent character. This is used for keyboards that
- * have a special language mode that sends characters above 128 (although
- * other characters can be translated too).
- */
-
- /*
- * char_u langmap_mapchar[256];
- * Normally maps each of the 128 upper chars to an <128 ascii char; used to
- * "translate" native lang chars in normal mode or some cases of
- * insert mode without having to tediously switch lang mode back&forth.
- */
-
- static void
- langmap_init()
- {
- int i;
-
- for (i = 0; i < 256; i++) /* we init with a-one-to one map */
- langmap_mapchar[i] = i;
- }
-
- /*
- * Called when langmap option is set; the language map can be
- * changed at any time!
- */
- static void
- langmap_set()
- {
- char_u *p;
- char_u *p2;
- int from, to;
-
- langmap_init(); /* back to one-to-one map first */
-
- for (p = p_langmap; p[0]; )
- {
- for (p2 = p; p2[0] && p2[0] != ',' && p2[0] != ';'; ++p2)
- if (p2[0] == '\\' && p2[1])
- ++p2;
- if (p2[0] == ';')
- ++p2; /* abcd;ABCD form, p2 points to A */
- else
- p2 = NULL; /* aAbBcCdD form, p2 is NULL */
- while (p[0])
- {
- if (p[0] == '\\' && p[1])
- ++p;
- from = p[0];
- if (p2 == NULL)
- {
- if (p[1] == '\\')
- ++p;
- to = p[1];
- }
- else
- {
- if (p2[0] == '\\')
- ++p2;
- to = p2[0];
- }
- if (to == NUL)
- {
- EMSG2("'langmap': Matching character missing for %s",
- transchar(from));
- return;
- }
- langmap_mapchar[from] = to;
-
- /* Advance to next pair */
- if (p2 == NULL)
- {
- p += 2;
- if (p[0] == ',')
- {
- ++p;
- break;
- }
- }
- else
- {
- ++p;
- ++p2;
- if (*p == ';')
- {
- p = p2;
- if (p[0])
- {
- if (p[0] != ',')
- {
- EMSG2("'langmap': Extra characters after semicolon: %s", p);
- return;
- }
- ++p;
- }
- break;
- }
- }
- }
- }
- }
- #endif
-
- /*
- * Return TRUE if format option 'x' is in effect.
- * Take care of no formatting when 'paste' is set.
- */
- int
- has_format_option(x)
- int x;
- {
- if (p_paste)
- return FALSE;
- return (vim_strchr(curbuf->b_p_fo, x) != NULL);
- }
-
- /*
- * Return TRUE if "x" is present in 'shortmess' option, or
- * 'shortmess' contains 'a' and "x" is present in SHM_A.
- */
- int
- shortmess(x)
- int x;
- {
- return (vim_strchr(p_shm, x) != NULL || (vim_strchr(p_shm, 'a') != NULL &&
- vim_strchr((char_u *)SHM_A, x) != NULL));
- }
-
- /*
- * set_paste_option() - Called after p_paste was set or reset.
- */
- static void
- paste_option_changed()
- {
- static int old_p_paste = FALSE;
- static int save_sm = 0;
- static int save_ru = 0;
- #ifdef RIGHTLEFT
- static int save_ri = 0;
- static int save_hkmap = 0;
- #endif
- BUF *buf;
-
- if (p_paste)
- {
- /*
- * Paste switched from off to on.
- * Save the current values, so they can be restored later.
- */
- if (!old_p_paste)
- {
- /* save options for each buffer */
- for (buf = firstbuf; buf != NULL; buf = buf->b_next)
- {
- buf->b_p_tw_save = buf->b_p_tw;
- buf->b_p_wm_save = buf->b_p_wm;
- buf->b_p_ai_save = buf->b_p_ai;
- #ifdef SMARTINDENT
- buf->b_p_si_save = buf->b_p_si;
- #endif
- #ifdef CINDENT
- buf->b_p_cin_save = buf->b_p_cin;
- #endif
- #ifdef LISPINDENT
- buf->b_p_lisp_save = buf->b_p_lisp;
- #endif
- }
-
- /* save global options */
- save_sm = p_sm;
- save_ru = p_ru;
- #ifdef RIGHTLEFT
- save_ri = p_ri;
- save_hkmap = p_hkmap;
- #endif
- }
-
- /*
- * Always set the option values, also when 'paste' is set when it is
- * already on.
- */
- /* set options for each buffer */
- for (buf = firstbuf; buf != NULL; buf = buf->b_next)
- {
- buf->b_p_tw = 0; /* textwidth is 0 */
- buf->b_p_wm = 0; /* wrapmargin is 0 */
- buf->b_p_ai = 0; /* no auto-indent */
- #ifdef SMARTINDENT
- buf->b_p_si = 0; /* no smart-indent */
- #endif
- #ifdef CINDENT
- buf->b_p_cin = 0; /* no c indenting */
- #endif
- #ifdef LISPINDENT
- buf->b_p_lisp = 0; /* no lisp indenting */
- #endif
- }
-
- /* set global options */
- p_sm = 0; /* no showmatch */
- p_ru = 0; /* no ruler */
- #ifdef RIGHTLEFT
- p_ri = 0; /* no reverse insert */
- p_hkmap = 0; /* no Hebrew keyboard */
- #endif
- }
-
- /*
- * Paste switched from on to off: Restore saved values.
- */
- else if (old_p_paste)
- {
- /* restore options for each buffer */
- for (buf = firstbuf; buf != NULL; buf = buf->b_next)
- {
- buf->b_p_tw = buf->b_p_tw_save;
- buf->b_p_wm = buf->b_p_wm_save;
- buf->b_p_ai = buf->b_p_ai_save;
- #ifdef SMARTINDENT
- buf->b_p_si = buf->b_p_si_save;
- #endif
- #ifdef CINDENT
- buf->b_p_cin = buf->b_p_cin_save;
- #endif
- #ifdef LISPINDENT
- buf->b_p_lisp = buf->b_p_lisp_save;
- #endif
- }
-
- /* restore global options */
- p_sm = save_sm;
- p_ru = save_ru;
- #ifdef RIGHTLEFT
- p_ri = save_ri;
- p_hkmap = save_hkmap;
- #endif
- }
-
- old_p_paste = p_paste;
- }
-
- /*
- * p_compatible_set() - Called when p_cp has been set.
- */
- static void
- p_compatible_set()
- {
- p_bs = 0; /* normal backspace */
- /* backspace and space do not wrap */
- set_string_option((char_u *)"ww", -1, (char_u *)"", TRUE);
- p_bk = 0; /* no backup file */
- /* Use textwidth for formatting, don't format comments */
- set_string_option((char_u *)"fo", -1, (char_u *)FO_DFLT_VI, TRUE);
- /* all compatible flags on */
- set_string_option((char_u *)"cpo", -1, (char_u *)CPO_ALL, TRUE);
- set_string_option((char_u *)"isk", -1, (char_u *)"@,48-57,_", TRUE);
- /* no short messages */
- set_string_option((char_u *)"shm", -1, (char_u *)"", TRUE);
- #ifdef DIGRAPHS
- p_dg = 0; /* no digraphs */
- #endif /* DIGRAPHS */
- p_ek = 0; /* no ESC keys in insert mode */
- curbuf->b_p_et = 0; /* no expansion of tabs */
- p_gd = 0; /* /g is not default for :s */
- p_hi = 0; /* no history */
- p_scs = 0; /* no ignore case switch */
- p_im = 0; /* do not start in insert mode */
- p_js = 1; /* insert 2 spaces after period */
- curbuf->b_p_ml = 0; /* no modelines */
- p_more = 0; /* no -- more -- for listings */
- p_ru = 0; /* no ruler */
- #ifdef RIGHTLEFT
- p_ri = 0; /* no reverse insert */
- p_hkmap = 0; /* no Hebrew keyboard mapping */
- #endif
- p_sj = 1; /* no scrolljump */
- p_so = 0; /* no scrolloff */
- p_sr = 0; /* do not round indent to shiftwidth */
- p_sc = 0; /* no showcommand */
- p_smd = 0; /* no showmode */
- #ifdef SMARTINDENT
- curbuf->b_p_si = 0; /* no smartindent */
- #endif
- #ifdef CINDENT
- curbuf->b_p_cin = 0; /* no C indenting */
- #endif
- p_sta = 0; /* no smarttab */
- p_sol = TRUE; /* Move cursor to start-of-line */
- p_ta = 0; /* no automatic textmode detection */
- curbuf->b_p_tw = 0; /* no automatic line wrap */
- p_to = 0; /* no tilde operator */
- p_ttimeout = 0; /* no terminal timeout */
- p_tr = 0; /* tag file names not relative */
- p_ul = 0; /* no multilevel undo */
- p_uc = 0; /* no autoscript file */
- p_wb = 0; /* no backup file */
- if (p_wc == TAB)
- p_wc = Ctrl('E'); /* normal use for TAB */
- init_chartab(); /* make b_p_isk take effect */
- }
-
- /*
- * fill_breakat_flags() -- called when 'breakat' changes value.
- */
- static void
- fill_breakat_flags()
- {
- char_u *c;
- int i;
-
- for (i = 0; i < 256; i++)
- breakat_flags[i] = FALSE;
-
- if (p_breakat != NULL)
- for (c = p_breakat; *c; c++)
- breakat_flags[*c] = TRUE;
- }
-