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 #define NULL (char *)0
21 extern char *getenv();
23 /* maximum width to permit for strings, including ="" */
26 /* These are the default values of all options */
27 char o_autoindent
[1] = {FALSE
};
28 char o_autoprint
[1] = {TRUE
};
29 char o_autotab
[1] = {TRUE
};
30 char o_autowrite
[1] = {FALSE
};
31 char o_columns
[3] = {80, 32, 255};
32 char o_directory
[30] = TMPDIR
;
33 char o_edcompatible
[1] = {FALSE
};
34 char o_equalprg
[80] = {"fmt"};
35 char o_errorbells
[1] = {TRUE
};
36 char o_exrefresh
[1] = {TRUE
};
37 char o_ignorecase
[1] = {FALSE
};
38 char o_keytime
[3] = {1, 0, 50};
39 char o_keywordprg
[80] = {KEYWORDPRG
};
40 char o_lines
[3] = {25, 2, 96};
41 char o_list
[1] = {FALSE
};
42 char o_number
[1] = {FALSE
};
43 char o_readonly
[1] = {FALSE
};
44 char o_remap
[1] = {TRUE
};
45 char o_report
[3] = {5, 1, 127};
46 char o_scroll
[3] = {12, 1, 127};
47 char o_shell
[60] = SHELL
;
48 char o_shiftwidth
[3] = {8, 1, 255};
49 char o_sidescroll
[3] = {8, 1, 40};
50 char o_sync
[1] = {NEEDSYNC
};
51 char o_tabstop
[3] = {8, 1, 40};
52 char o_term
[30] = "?";
53 char o_flash
[1] = {TRUE
};
54 char o_warn
[1] = {TRUE
};
55 char o_wrapscan
[1] = {TRUE
};
58 char o_beautify
[1] = {FALSE
};
59 char o_exrc
[1] = {FALSE
};
60 char o_mesg
[1] = {TRUE
};
61 char o_more
[1] = {TRUE
};
62 char o_novice
[1] = {FALSE
};
63 char o_prompt
[1] = {TRUE
};
64 char o_taglength
[3] = {0, 0, 30};
65 char o_terse
[1] = {FALSE
};
66 char o_window
[3] = {0, 1, 24};
67 char o_wrapmargin
[3] = {0, 0, 255};
68 char o_writeany
[1] = {FALSE
};
72 char o_cc
[30] = {CC_COMMAND
};
73 char o_make
[30] = {MAKE_COMMAND
};
77 char o_charattr
[1] = {FALSE
};
81 char o_digraph
[1] = {FALSE
};
84 = {"\207\200\201\232\202\220\204\216\206\217\221\222\224\231\244\245"}
87 /* initialized by initopts() */
93 char o_hideformat
[1] = {FALSE
};
97 char o_inputmode
[1] = {FALSE
};
98 char o_ruler
[1] = {FALSE
};
102 char o_magic
[1] = {TRUE
};
106 char o_modelines
[1] = {FALSE
};
110 char o_paragraphs
[30] = "PPppIPLPQP";
111 char o_sections
[30] = "NHSHSSSEse";
115 char o_pcbios
[1] = {TRUE
};
119 char o_showmatch
[1] = {FALSE
};
123 char o_smd
[1] = {FALSE
};
127 /* The following describes the names & types of all options */
131 #define SET 0x01 /* this option has had its value altered */
132 #define CANSET 0x02 /* this option can be set at any time */
133 #define RCSET 0x06 /* this option can be set in a .exrc file only */
134 #define NOSAVE 0x0a /* this option should never be saved by mkexrc */
135 #define WSET 0x20 /* is this the "window" size option? */
136 #define MR 0x40 /* does this option affect the way text is displayed? */
139 char *name
; /* name of an option */
140 char *nm
; /* short name of an option */
141 char type
; /* type of an option */
142 char flags
; /* boolean: has this option been set? */
143 char *value
; /* value */
147 /* name type flags value */
148 { "autoindent", "ai", BOOL
, CANSET
, o_autoindent
},
149 { "autoprint", "ap", BOOL
, CANSET
, o_autoprint
},
150 { "autotab", "at", BOOL
, CANSET
, o_autotab
},
151 { "autowrite", "aw", BOOL
, CANSET
, o_autowrite
},
153 { "beautify", "bf", BOOL
, CANSET
, o_beautify
},
156 { "cc", "cc", STR
, CANSET
, o_cc
},
159 { "charattr", "ca", BOOL
, CANSET
|MR
, o_charattr
},
161 { "columns", "co", NUM
, SET
|NOSAVE
|MR
, o_columns
},
163 { "digraph", "dig", BOOL
, CANSET
, o_digraph
},
165 { "directory", "dir", STR
, RCSET
, o_directory
},
166 { "edcompatible","ed", BOOL
, CANSET
, o_edcompatible
},
167 { "equalprg", "ep", STR
, CANSET
, o_equalprg
},
168 { "errorbells", "eb", BOOL
, CANSET
, o_errorbells
},
170 { "exrc", "exrc", BOOL
, CANSET
, o_exrc
},
172 { "exrefresh", "er", BOOL
, CANSET
, o_exrefresh
},
173 { "flash", "vbell",BOOL
, CANSET
, o_flash
},
175 { "flipcase", "fc", STR
, CANSET
, o_flipcase
},
178 { "hideformat", "hf", BOOL
, CANSET
|MR
, o_hideformat
},
180 { "ignorecase", "ic", BOOL
, CANSET
, o_ignorecase
},
181 #ifndef NO_EXTENSIONS
182 { "inputmode", "im", BOOL
, CANSET
, o_inputmode
},
184 { "keytime", "kt", NUM
, CANSET
, o_keytime
},
185 { "keywordprg", "kp", STR
, CANSET
, o_keywordprg
},
186 { "lines", "ls", NUM
, SET
|NOSAVE
|MR
, o_lines
},
187 { "list", "li", BOOL
, CANSET
|MR
, o_list
},
189 { "magic", "ma", BOOL
, CANSET
, o_magic
},
192 { "make", "mk", STR
, CANSET
, o_make
},
195 { "mesg", "me", BOOL
, CANSET
, o_mesg
},
198 { "modelines", "ml", BOOL
, CANSET
, o_modelines
},
201 { "more", "mo", BOOL
, CANSET
, o_more
},
202 { "novice", "nov", BOOL
, CANSET
, o_novice
},
204 { "number", "nu", BOOL
, CANSET
|MR
, o_number
},
206 { "paragraphs", "para", STR
, CANSET
, o_paragraphs
},
209 { "pcbios", "pc", BOOL
, SET
|NOSAVE
, o_pcbios
},
212 { "prompt", "pr", BOOL
, CANSET
, o_prompt
},
214 { "readonly", "ro", BOOL
, CANSET
, o_readonly
},
215 { "remap", "remap",BOOL
, CANSET
, o_remap
},
216 { "report", "re", NUM
, CANSET
, o_report
},
217 #ifndef NO_EXTENSIONS
218 { "ruler", "ru", BOOL
, CANSET
, o_ruler
},
220 { "scroll", "sc", NUM
, CANSET
, o_scroll
},
222 { "sections", "sect", STR
, CANSET
, o_sections
},
224 { "shell", "sh", STR
, CANSET
, o_shell
},
226 { "showmatch", "sm", BOOL
, CANSET
, o_showmatch
},
229 { "showmode", "smd", BOOL
, CANSET
, o_smd
},
231 { "shiftwidth", "sw", NUM
, CANSET
, o_shiftwidth
},
232 { "sidescroll", "ss", NUM
, CANSET
, o_sidescroll
},
233 { "sync", "sy", BOOL
, CANSET
, o_sync
},
234 { "tabstop", "ts", NUM
, CANSET
|MR
, o_tabstop
},
236 { "taglength", "tl", NUM
, CANSET
, o_taglength
},
238 { "term", "te", STR
, SET
, o_term
},
240 { "terse", "tr", BOOL
, CANSET
, o_terse
},
241 { "timeout", "to", BOOL
, CANSET
, o_keytime
},
244 { "window", "wi", NUM
, CANSET
|MR
|WSET
, o_window
},
245 { "wrapmargin", "wm", NUM
, CANSET
, o_wrapmargin
},
247 { "wrapscan", "ws", BOOL
, CANSET
, o_wrapscan
},
249 { "writeany", "wr", BOOL
, CANSET
, o_writeany
},
251 { NULL
, NULL
, 0, CANSET
, NULL
}
255 /* This function initializes certain options from environment variables, etc. */
261 /* set some stuff from environment variables */
263 if (val
= getenv("COMSPEC")) /* yes, ASSIGNMENT! */
265 if (val
= getenv("SHELL")) /* yes, ASSIGNMENT! */
268 strcpy(o_shell
, val
);
271 strcpy(o_term
, termtype
);
273 if (strcmp(termtype
, "pcbios"))
283 #if AMIGA || MSDOS || TOS
284 if ((val
= getenv("TMP")) /* yes, ASSIGNMENT! */
285 || (val
= getenv("TEMP")))
286 strcpy(o_directory
, val
);
290 if ((val
= getenv("LINES")) && atoi(val
) > 4) /* yes, ASSIGNMENT! */
294 if ((val
= getenv("COLUMNS")) && atoi(val
) > 30) /* yes, ASSIGNMENT! */
301 *o_scroll
= LINES
/ 2 - 1;
303 if (o_window
[0] == 0)
305 o_window
[0] = o_window
[2] = *o_lines
;
309 /* disable the flash option if we don't know how to do a flash */
312 for (i
= 0; opts
[i
].value
!= o_flash
; i
++)
315 opts
[i
].flags
&= ~CANSET
;
321 for (i
= 0, val
= o_flipcase
; i
< 32; i
++)
323 /* leave out the multiply/divide symbols */
327 /* add lower/uppercase pair */
332 # endif /* CS_LATIN1 */
334 /* initialize the ctype package */
335 _ct_init(o_flipcase
);
338 #endif /* not NO_DIGRAPH */
341 /* This function lists the current values of all options */
343 int all
; /* boolean: dump all options, or just set ones? */
347 char nbuf
[4]; /* used for converting numbers to ASCII */
348 int widths
[5]; /* width of each column, including gap */
349 int ncols
; /* number of columns */
350 int nrows
; /* number of options per column */
351 int nset
; /* number of options to be output */
352 int width
; /* width of a particular option */
353 int todump
[60]; /* indicies of options to be dumped */
355 /* step 1: count the number of set options */
356 for (nset
= i
= 0; opts
[i
].name
; i
++)
358 if (all
|| (opts
[i
].flags
& SET
))
364 /* step two: try to use as many columns as possible */
365 for (ncols
= (nset
> 5 ? 5 : nset
); ncols
> 1; ncols
--)
367 /* how many would go in this column? */
368 nrows
= (nset
+ ncols
- 1) / ncols
;
370 /* figure out the width of each column */
371 for (i
= 0; i
< ncols
; i
++)
374 for (j
= 0, k
= nrows
* i
; j
< nrows
&& k
< nset
; j
++, k
++)
376 /* figure out the width of a particular option */
377 switch (opts
[todump
[k
]].type
)
380 if (!*opts
[todump
[k
]].value
)
387 width
= 3 + strlen(opts
[todump
[k
]].value
);
388 if (width
> MAXWIDTH
)
396 width
+= strlen(opts
[todump
[k
]].name
);
398 /* if this is the widest so far, widen col */
399 if (width
> widths
[i
])
407 /* if the total width is narrow enough, then use it */
408 for (width
= -2, i
= 0; i
< ncols
; i
++)
410 width
+= widths
[i
] + 2;
412 if (width
< COLS
- 1)
418 /* step 3: output the columns */
419 nrows
= (nset
+ ncols
- 1) / ncols
;
420 for (i
= 0; i
< nrows
; i
++)
422 for (j
= 0; j
< ncols
; j
++)
424 /* if we hit the end of the options, quit */
431 /* output this option's value */
433 switch (opts
[todump
[k
]].type
)
436 if (!*opts
[todump
[k
]].value
)
442 qaddstr(opts
[todump
[k
]].name
);
443 width
+= strlen(opts
[todump
[k
]].name
);
447 sprintf(nbuf
, "%-3d", UCHAR(*opts
[todump
[k
]].value
));
448 qaddstr(opts
[todump
[k
]].name
);
451 width
= 4 + strlen(opts
[todump
[k
]].name
);
455 qaddstr(opts
[todump
[k
]].name
);
458 strcpy(tmpblk
.c
, opts
[todump
[k
]].value
);
459 width
= 3 + strlen(tmpblk
.c
);
460 if (width
> MAXWIDTH
)
463 strcpy(tmpblk
.c
+ MAXWIDTH
- 6, "...");
467 width
+= strlen(opts
[todump
[k
]].name
);
471 /* pad the field to the correct size */
472 if (k
+ nrows
<= nset
)
474 while (width
< widths
[j
] + 2)
489 for (i
= col
= 0; opts
[i
].name
; i
++)
491 /* if not set and not all, ignore this option */
492 if (!all
&& !(opts
[i
].flags
& SET
))
497 /* align this option in one of the columns */
520 switch (opts
[i
].type
)
529 qaddstr(opts
[i
].name
);
530 col
+= strlen(opts
[i
].name
);
534 sprintf(nbuf
, "%-3d", UCHAR(*opts
[i
].value
));
535 qaddstr(opts
[i
].name
);
538 col
+= 4 + strlen(opts
[i
].name
);
542 qaddstr(opts
[i
].name
);
545 qaddstr(opts
[i
].value
);
547 col
+= 3 + strlen(opts
[i
].name
) + strlen(opts
[i
].value
);
561 /* This function saves the current configuration of options to a file */
563 int fd
; /* file descriptor to write to */
568 /* write each set options */
569 for (i
= 0; opts
[i
].name
; i
++)
571 /* if unset or unsettable, ignore this option */
572 if ((opts
[i
].flags
& (SET
|CANSET
|NOSAVE
)) != (SET
|CANSET
))
579 switch (opts
[i
].type
)
587 strcpy(pos
, opts
[i
].name
);
592 sprintf(pos
, "%s=%-3d\n", opts
[i
].name
, *opts
[i
].value
& 0xff);
596 sprintf(pos
, "%s=\"%s\"\n", opts
[i
].name
, opts
[i
].value
);
599 twrite(fd
, buf
, (unsigned)strlen(buf
));
605 /* This function changes the values of one or more options. */
606 void setopts(assignments
)
607 char *assignments
; /* a string containing option assignments */
609 char *name
; /* name of variable in assignments */
610 char *value
; /* value of the variable */
611 char *scan
; /* used for moving through strings */
612 char *build
; /* used for copying chars from "scan" */
613 char *prefix
; /* pointer to "neg" or "no" at front of a boolean */
614 int quote
; /* boolean: inside '"' quotes? */
618 /* reset the upper limit of "window" option to lines-1 */
619 *o_window
= *o_lines
- 1;
622 /* for each assignment... */
623 for (name
= assignments
; *name
; )
625 /* skip whitespace */
626 if (*name
== ' ' || *name
== '\t')
632 /* after the name, find the value (if any) */
633 for (scan
= name
; isalnum(*scan
); scan
++)
639 value
= build
= scan
;
640 for (quote
= FALSE
; *scan
&& (quote
|| !isspace(*scan
)); scan
++)
646 else if (*scan
== '\\' && scan
[1])
659 else /* no "=" so it is probably boolean... */
668 if (!strcmp(name
, "novice"))
669 /* don't check for a "no" prefix */;
672 if (prefix
[0] == 'n' && prefix
[1] == 'o')
674 else if (prefix
[0] == 'n' && prefix
[1] == 'e' && prefix
[2] == 'g')
678 /* find the variable */
680 opts
[i
].name
&& strcmp(opts
[i
].name
, name
) && strcmp(opts
[i
].nm
, name
);
685 /* change the variable */
688 msg("invalid option name \"%s\"", name
);
690 else if ((opts
[i
].flags
& CANSET
) != CANSET
)
692 msg("option \"%s\" can't be altered", name
);
694 else if ((opts
[i
].flags
& RCSET
) != CANSET
&& nlines
>= 1L)
696 msg("option \"%s\" can only be set in a %s file", name
, EXRC
);
700 switch (opts
[i
].type
)
703 msg("option \"[no]%s\" is boolean", name
);
708 if (j
== 0 && *value
!= '0')
710 msg("option \"%s\" must have a numeric value", name
);
712 else if (j
< opts
[i
].value
[1] || j
> (opts
[i
].value
[2] & 0xff))
714 msg("option \"%s\" must have a value between %d and %d",
715 name
, opts
[i
].value
[1], opts
[i
].value
[2] & 0xff);
719 *opts
[i
].value
= atoi(value
);
720 opts
[i
].flags
|= SET
;
725 strcpy(opts
[i
].value
, value
);
726 opts
[i
].flags
|= SET
;
729 if (opts
[i
].flags
& MR
)
731 redraw(MARK_UNSET
, FALSE
);
734 if (opts
[i
].flags
& WSET
)
740 else /* valid option, no value */
742 if (opts
[i
].type
== BOOL
)
745 *opts
[i
].value
= TRUE
;
746 else if (prefix
[1] == 'o')
747 *opts
[i
].value
= FALSE
;
749 *opts
[i
].value
= !*opts
[i
].value
;
751 opts
[i
].flags
|= SET
;
752 if (opts
[i
].flags
& MR
)
754 redraw(MARK_UNSET
, FALSE
);
759 msg("option \"%s\" must be given a value", name
);
763 /* move on to the next option */
767 /* special processing ... */
770 /* if "novice" is set, then ":set report=1 showmode nomagic" */
783 /* if "readonly" then set the READONLY flag for this file */
786 setflag(file
, READONLY
);
790 /* re-initialize the ctype package */
791 _ct_init(o_flipcase
);
792 #endif /* not NO_DIGRAPH */
794 /* copy o_lines and o_columns into LINES and COLS */
795 LINES
= (*o_lines
& 255);
796 COLS
= (*o_columns
& 255);