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