5 * 14407 SW Teal Blvd. #C
11 /* This file contains the code that manages the run-time options -- The
12 * values that can be modified via the "set" command.
19 extern char *getenv();
21 /* maximum width to permit for strings, including ="" */
24 /* These are the default values of all options */
25 char o_autoindent
[1] = {FALSE
};
26 char o_autoprint
[1] = {TRUE
};
27 char o_autotab
[1] = {TRUE
};
28 char o_autowrite
[1] = {FALSE
};
29 char o_columns
[3] = {80, 32, 255};
30 char o_directory
[30] = TMPDIR
;
31 char o_edcompatible
[1] = {FALSE
};
32 char o_equalprg
[80] = {"fmt"};
33 char o_errorbells
[1] = {TRUE
};
34 char o_exrefresh
[1] = {TRUE
};
35 char o_ignorecase
[1] = {FALSE
};
36 char o_keytime
[3] = {1, 0, 50};
37 char o_keywordprg
[80] = {KEYWORDPRG
};
38 char o_lines
[3] = {25, 2, 96};
39 char o_list
[1] = {FALSE
};
40 char o_number
[1] = {FALSE
};
41 char o_readonly
[1] = {FALSE
};
42 char o_remap
[1] = {TRUE
};
43 char o_report
[3] = {5, 1, 127};
44 char o_scroll
[3] = {12, 1, 127};
45 char o_shell
[60] = SHELL
;
46 char o_shiftwidth
[3] = {8, 1, 255};
47 char o_sidescroll
[3] = {8, 1, 40};
48 char o_sync
[1] = {NEEDSYNC
};
49 char o_tabstop
[3] = {8, 1, 40};
50 char o_term
[30] = "?";
51 char o_flash
[1] = {TRUE
};
52 char o_warn
[1] = {TRUE
};
53 char o_wrapscan
[1] = {TRUE
};
56 char o_beautify
[1] = {FALSE
};
57 char o_exrc
[1] = {FALSE
};
58 char o_mesg
[1] = {TRUE
};
59 char o_more
[1] = {TRUE
};
60 char o_novice
[1] = {FALSE
};
61 char o_prompt
[1] = {TRUE
};
62 char o_taglength
[3] = {0, 0, 30};
63 char o_terse
[1] = {FALSE
};
64 char o_window
[3] = {0, 1, 24};
65 char o_wrapmargin
[3] = {0, 0, 255};
66 char o_writeany
[1] = {FALSE
};
70 char o_cc
[30] = {CC_COMMAND
};
71 char o_make
[30] = {MAKE_COMMAND
};
75 char o_charattr
[1] = {FALSE
};
79 char o_digraph
[1] = {FALSE
};
82 = {"\207\200\201\232\202\220\204\216\206\217\221\222\224\231\244\245"}
85 /* initialized by initopts() */
91 char o_hideformat
[1] = {FALSE
};
95 char o_inputmode
[1] = {FALSE
};
96 char o_ruler
[1] = {FALSE
};
100 char o_magic
[1] = {TRUE
};
104 char o_modelines
[1] = {FALSE
};
108 char o_paragraphs
[30] = "PPppIPLPQP";
109 char o_sections
[30] = "NHSHSSSEse";
113 char o_pcbios
[1] = {TRUE
};
117 char o_showmatch
[1] = {FALSE
};
121 char o_smd
[1] = {FALSE
};
125 /* The following describes the names & types of all options */
129 #define SET 0x01 /* this option has had its value altered */
130 #define CANSET 0x02 /* this option can be set at any time */
131 #define RCSET 0x06 /* this option can be set in a .exrc file only */
132 #define NOSAVE 0x0a /* this option should never be saved by mkexrc */
133 #define WSET 0x20 /* is this the "window" size option? */
134 #define MR 0x40 /* does this option affect the way text is displayed? */
137 char *name
; /* name of an option */
138 char *nm
; /* short name of an option */
139 char type
; /* type of an option */
140 char flags
; /* boolean: has this option been set? */
141 char *value
; /* value */
145 /* name type flags value */
146 { "autoindent", "ai", BOOL
, CANSET
, o_autoindent
},
147 { "autoprint", "ap", BOOL
, CANSET
, o_autoprint
},
148 { "autotab", "at", BOOL
, CANSET
, o_autotab
},
149 { "autowrite", "aw", BOOL
, CANSET
, o_autowrite
},
151 { "beautify", "bf", BOOL
, CANSET
, o_beautify
},
154 { "cc", "cc", STR
, CANSET
, o_cc
},
157 { "charattr", "ca", BOOL
, CANSET
|MR
, o_charattr
},
159 { "columns", "co", NUM
, SET
|NOSAVE
|MR
, o_columns
},
161 { "digraph", "dig", BOOL
, CANSET
, o_digraph
},
163 { "directory", "dir", STR
, RCSET
, o_directory
},
164 { "edcompatible","ed", BOOL
, CANSET
, o_edcompatible
},
165 { "equalprg", "ep", STR
, CANSET
, o_equalprg
},
166 { "errorbells", "eb", BOOL
, CANSET
, o_errorbells
},
168 { "exrc", "exrc", BOOL
, CANSET
, o_exrc
},
170 { "exrefresh", "er", BOOL
, CANSET
, o_exrefresh
},
171 { "flash", "vbell",BOOL
, CANSET
, o_flash
},
173 { "flipcase", "fc", STR
, CANSET
, o_flipcase
},
176 { "hideformat", "hf", BOOL
, CANSET
|MR
, o_hideformat
},
178 { "ignorecase", "ic", BOOL
, CANSET
, o_ignorecase
},
179 #ifndef NO_EXTENSIONS
180 { "inputmode", "im", BOOL
, CANSET
, o_inputmode
},
182 { "keytime", "kt", NUM
, CANSET
, o_keytime
},
183 { "keywordprg", "kp", STR
, CANSET
, o_keywordprg
},
184 { "lines", "ls", NUM
, SET
|NOSAVE
|MR
, o_lines
},
185 { "list", "li", BOOL
, CANSET
|MR
, o_list
},
187 { "magic", "ma", BOOL
, CANSET
, o_magic
},
190 { "make", "mk", STR
, CANSET
, o_make
},
193 { "mesg", "me", BOOL
, CANSET
, o_mesg
},
196 { "modelines", "ml", BOOL
, CANSET
, o_modelines
},
199 { "more", "mo", BOOL
, CANSET
, o_more
},
200 { "novice", "nov", BOOL
, CANSET
, o_novice
},
202 { "number", "nu", BOOL
, CANSET
|MR
, o_number
},
204 { "paragraphs", "para", STR
, CANSET
, o_paragraphs
},
207 { "pcbios", "pc", BOOL
, SET
|NOSAVE
, o_pcbios
},
210 { "prompt", "pr", BOOL
, CANSET
, o_prompt
},
212 { "readonly", "ro", BOOL
, CANSET
, o_readonly
},
213 { "remap", "remap",BOOL
, CANSET
, o_remap
},
214 { "report", "re", NUM
, CANSET
, o_report
},
215 #ifndef NO_EXTENSIONS
216 { "ruler", "ru", BOOL
, CANSET
, o_ruler
},
218 { "scroll", "sc", NUM
, CANSET
, o_scroll
},
220 { "sections", "sect", STR
, CANSET
, o_sections
},
222 { "shell", "sh", STR
, CANSET
, o_shell
},
224 { "showmatch", "sm", BOOL
, CANSET
, o_showmatch
},
227 { "showmode", "smd", BOOL
, CANSET
, o_smd
},
229 { "shiftwidth", "sw", NUM
, CANSET
, o_shiftwidth
},
230 { "sidescroll", "ss", NUM
, CANSET
, o_sidescroll
},
231 { "sync", "sy", BOOL
, CANSET
, o_sync
},
232 { "tabstop", "ts", NUM
, CANSET
|MR
, o_tabstop
},
234 { "taglength", "tl", NUM
, CANSET
, o_taglength
},
236 { "term", "te", STR
, SET
, o_term
},
238 { "terse", "tr", BOOL
, CANSET
, o_terse
},
239 { "timeout", "to", BOOL
, CANSET
, o_keytime
},
242 { "window", "wi", NUM
, CANSET
|MR
|WSET
, o_window
},
243 { "wrapmargin", "wm", NUM
, CANSET
, o_wrapmargin
},
245 { "wrapscan", "ws", BOOL
, CANSET
, o_wrapscan
},
247 { "writeany", "wr", BOOL
, CANSET
, o_writeany
},
249 { NULL
, NULL
, 0, CANSET
, NULL
}
253 /* This function initializes certain options from environment variables, etc. */
259 /* set some stuff from environment variables */
261 if (val
= getenv("COMSPEC")) /* yes, ASSIGNMENT! */
263 if (val
= getenv("SHELL")) /* yes, ASSIGNMENT! */
266 strcpy(o_shell
, val
);
269 strcpy(o_term
, termtype
);
271 if (strcmp(termtype
, "pcbios"))
281 #if AMIGA || MSDOS || TOS
282 if ((val
= getenv("TMP")) /* yes, ASSIGNMENT! */
283 || (val
= getenv("TEMP")))
284 strcpy(o_directory
, val
);
288 if ((val
= getenv("LINES")) && atoi(val
) > 4) /* yes, ASSIGNMENT! */
292 if ((val
= getenv("COLUMNS")) && atoi(val
) > 30) /* yes, ASSIGNMENT! */
299 *o_scroll
= LINES
/ 2 - 1;
301 if (o_window
[0] == 0)
303 o_window
[0] = o_window
[2] = *o_lines
;
307 /* disable the flash option if we don't know how to do a flash */
310 for (i
= 0; opts
[i
].value
!= o_flash
; i
++)
313 opts
[i
].flags
&= ~CANSET
;
319 for (i
= 0, val
= o_flipcase
; i
< 32; i
++)
321 /* leave out the multiply/divide symbols */
325 /* add lower/uppercase pair */
330 # endif /* CS_LATIN1 */
332 /* initialize the ctype package */
333 _ct_init(o_flipcase
);
336 #endif /* not NO_DIGRAPH */
339 /* This function lists the current values of all options */
341 int all
; /* boolean: dump all options, or just set ones? */
345 char nbuf
[4]; /* used for converting numbers to ASCII */
346 int widths
[5]; /* width of each column, including gap */
347 int ncols
; /* number of columns */
348 int nrows
; /* number of options per column */
349 int nset
; /* number of options to be output */
350 int width
; /* width of a particular option */
351 int todump
[60]; /* indicies of options to be dumped */
353 /* step 1: count the number of set options */
354 for (nset
= i
= 0; opts
[i
].name
; i
++)
356 if (all
|| (opts
[i
].flags
& SET
))
362 /* step two: try to use as many columns as possible */
363 for (ncols
= (nset
> 5 ? 5 : nset
); ncols
> 1; ncols
--)
365 /* how many would go in this column? */
366 nrows
= (nset
+ ncols
- 1) / ncols
;
368 /* figure out the width of each column */
369 for (i
= 0; i
< ncols
; i
++)
372 for (j
= 0, k
= nrows
* i
; j
< nrows
&& k
< nset
; j
++, k
++)
374 /* figure out the width of a particular option */
375 switch (opts
[todump
[k
]].type
)
378 if (!*opts
[todump
[k
]].value
)
385 width
= 3 + strlen(opts
[todump
[k
]].value
);
386 if (width
> MAXWIDTH
)
394 width
+= strlen(opts
[todump
[k
]].name
);
396 /* if this is the widest so far, widen col */
397 if (width
> widths
[i
])
405 /* if the total width is narrow enough, then use it */
406 for (width
= -2, i
= 0; i
< ncols
; i
++)
408 width
+= widths
[i
] + 2;
410 if (width
< COLS
- 1)
416 /* step 3: output the columns */
417 nrows
= (nset
+ ncols
- 1) / ncols
;
418 for (i
= 0; i
< nrows
; i
++)
420 for (j
= 0; j
< ncols
; j
++)
422 /* if we hit the end of the options, quit */
429 /* output this option's value */
431 switch (opts
[todump
[k
]].type
)
434 if (!*opts
[todump
[k
]].value
)
440 qaddstr(opts
[todump
[k
]].name
);
441 width
+= strlen(opts
[todump
[k
]].name
);
445 sprintf(nbuf
, "%-3d", UCHAR(*opts
[todump
[k
]].value
));
446 qaddstr(opts
[todump
[k
]].name
);
449 width
= 4 + strlen(opts
[todump
[k
]].name
);
453 qaddstr(opts
[todump
[k
]].name
);
456 strcpy(tmpblk
.c
, opts
[todump
[k
]].value
);
457 width
= 3 + strlen(tmpblk
.c
);
458 if (width
> MAXWIDTH
)
461 strcpy(tmpblk
.c
+ MAXWIDTH
- 6, "...");
465 width
+= strlen(opts
[todump
[k
]].name
);
469 /* pad the field to the correct size */
470 if (k
+ nrows
<= nset
)
472 while (width
< widths
[j
] + 2)
487 for (i
= col
= 0; opts
[i
].name
; i
++)
489 /* if not set and not all, ignore this option */
490 if (!all
&& !(opts
[i
].flags
& SET
))
495 /* align this option in one of the columns */
518 switch (opts
[i
].type
)
527 qaddstr(opts
[i
].name
);
528 col
+= strlen(opts
[i
].name
);
532 sprintf(nbuf
, "%-3d", UCHAR(*opts
[i
].value
));
533 qaddstr(opts
[i
].name
);
536 col
+= 4 + strlen(opts
[i
].name
);
540 qaddstr(opts
[i
].name
);
543 qaddstr(opts
[i
].value
);
545 col
+= 3 + strlen(opts
[i
].name
) + strlen(opts
[i
].value
);
559 /* This function saves the current configuration of options to a file */
561 int fd
; /* file descriptor to write to */
566 /* write each set options */
567 for (i
= 0; opts
[i
].name
; i
++)
569 /* if unset or unsettable, ignore this option */
570 if ((opts
[i
].flags
& (SET
|CANSET
|NOSAVE
)) != (SET
|CANSET
))
577 switch (opts
[i
].type
)
585 strcpy(pos
, opts
[i
].name
);
590 sprintf(pos
, "%s=%-3d\n", opts
[i
].name
, *opts
[i
].value
& 0xff);
594 sprintf(pos
, "%s=\"%s\"\n", opts
[i
].name
, opts
[i
].value
);
597 twrite(fd
, buf
, (unsigned)strlen(buf
));
603 /* This function changes the values of one or more options. */
604 void setopts(assignments
)
605 char *assignments
; /* a string containing option assignments */
607 char *name
; /* name of variable in assignments */
608 char *value
; /* value of the variable */
609 char *scan
; /* used for moving through strings */
610 char *build
; /* used for copying chars from "scan" */
611 char *prefix
; /* pointer to "neg" or "no" at front of a boolean */
612 int quote
; /* boolean: inside '"' quotes? */
616 /* reset the upper limit of "window" option to lines-1 */
617 *o_window
= *o_lines
- 1;
620 /* for each assignment... */
621 for (name
= assignments
; *name
; )
623 /* skip whitespace */
624 if (*name
== ' ' || *name
== '\t')
630 /* after the name, find the value (if any) */
631 for (scan
= name
; isalnum(*scan
); scan
++)
637 value
= build
= scan
;
638 for (quote
= FALSE
; *scan
&& (quote
|| !isspace(*scan
)); scan
++)
644 else if (*scan
== '\\' && scan
[1])
657 else /* no "=" so it is probably boolean... */
666 if (!strcmp(name
, "novice"))
667 /* don't check for a "no" prefix */;
670 if (prefix
[0] == 'n' && prefix
[1] == 'o')
672 else if (prefix
[0] == 'n' && prefix
[1] == 'e' && prefix
[2] == 'g')
676 /* find the variable */
678 opts
[i
].name
&& strcmp(opts
[i
].name
, name
) && strcmp(opts
[i
].nm
, name
);
683 /* change the variable */
686 msg("invalid option name \"%s\"", name
);
688 else if ((opts
[i
].flags
& CANSET
) != CANSET
)
690 msg("option \"%s\" can't be altered", name
);
692 else if ((opts
[i
].flags
& RCSET
) != CANSET
&& nlines
>= 1L)
694 msg("option \"%s\" can only be set in a %s file", name
, EXRC
);
698 switch (opts
[i
].type
)
701 msg("option \"[no]%s\" is boolean", name
);
706 if (j
== 0 && *value
!= '0')
708 msg("option \"%s\" must have a numeric value", name
);
710 else if (j
< opts
[i
].value
[1] || j
> (opts
[i
].value
[2] & 0xff))
712 msg("option \"%s\" must have a value between %d and %d",
713 name
, opts
[i
].value
[1], opts
[i
].value
[2] & 0xff);
717 *opts
[i
].value
= atoi(value
);
718 opts
[i
].flags
|= SET
;
723 strcpy(opts
[i
].value
, value
);
724 opts
[i
].flags
|= SET
;
727 if (opts
[i
].flags
& MR
)
729 redraw(MARK_UNSET
, FALSE
);
732 if (opts
[i
].flags
& WSET
)
738 else /* valid option, no value */
740 if (opts
[i
].type
== BOOL
)
743 *opts
[i
].value
= TRUE
;
744 else if (prefix
[1] == 'o')
745 *opts
[i
].value
= FALSE
;
747 *opts
[i
].value
= !*opts
[i
].value
;
749 opts
[i
].flags
|= SET
;
750 if (opts
[i
].flags
& MR
)
752 redraw(MARK_UNSET
, FALSE
);
757 msg("option \"%s\" must be given a value", name
);
761 /* move on to the next option */
765 /* special processing ... */
768 /* if "novice" is set, then ":set report=1 showmode nomagic" */
781 /* if "readonly" then set the READONLY flag for this file */
784 setflag(file
, READONLY
);
788 /* re-initialize the ctype package */
789 _ct_init(o_flipcase
);
790 #endif /* not NO_DIGRAPH */
792 /* copy o_lines and o_columns into LINES and COLS */
793 LINES
= (*o_lines
& 255);
794 COLS
= (*o_columns
& 255);