This is modes.c in view mode; [Download] [Up]
/* * * modes.c * * Maintain and list the editor modes and value sets. * * Original code probably by Dan Lawrence or Dave Conroy for MicroEMACS. * Major extensions for vile by Paul Fox, 1991 * * $Header: /home/tom/src/vile/RCS/modes.c,v 1.81 1997/02/09 19:33:57 tom Exp $ * */ #include "estruct.h" #include "edef.h" #include "chgdfunc.h" #define NonNull(s) ((s == 0) ? "" : s) #define ONE_COL 26 #define NCOLS 3 #define isLocalVal(valptr) ((valptr)->vp == &((valptr)->v)) #define makeLocalVal(valptr) ((valptr)->vp = &((valptr)->v)) /* * The symbol tables stored in FSM_CHOICES lists are sorted by the 'choice_name' * field, with a final null entry so that name-completion works on the lists. */ #if OPT_ENUM_MODES #define ENUM_ILLEGAL (-2) #define ENUM_UNKNOWN (-1) #define END_CHOICES { (char *)0, ENUM_ILLEGAL } typedef struct { const char * choice_name; int choice_code; } FSM_CHOICES; struct FSM { const char * mode_name; const FSM_CHOICES * choices; }; #endif /*--------------------------------------------------------------------------*/ #if OPT_UPBUFF static void relist_settings (void); #endif #if OPT_ENUM_MODES static const char * choice_to_name (const FSM_CHOICES *choices, int code); static const FSM_CHOICES * name_to_choices (const struct VALNAMES *names); #endif /*--------------------------------------------------------------------------*/ static void set_winflags(int glob_vals, int flags) { if (glob_vals) { register WINDOW *wp; for_each_window(wp) { if ((wp->w_bufp == NULL) || !b_is_scratch(wp->w_bufp) || !(flags & WFMODE)) wp->w_flag |= flags; } } else { curwp->w_flag |= flags; } } static int same_val(const struct VALNAMES *names, struct VAL *tst, struct VAL *ref) { if (ref == 0) /* can't test, not really true */ return -TRUE; switch (names->type) { case VALTYPE_BOOL: case VALTYPE_ENUM: case VALTYPE_INT: return (tst->vp->i == ref->vp->i); case VALTYPE_STRING: return (tst->vp->p != 0) && (ref->vp->p != 0) && !strcmp(tst->vp->p, ref->vp->p); case VALTYPE_REGEX: return (tst->vp->r->pat != 0) && (ref->vp->r->pat != 0) && !strcmp(tst->vp->r->pat, ref->vp->r->pat); default: mlforce("BUG: bad type %s %d", names->name, names->type); } return FALSE; } /* * Returns the formatted length of a string value. */ static int size_val(const struct VALNAMES *names, struct VAL *values) { register int n = strlen(names->name) + 3; register const char *s = 0; switch (names->type) { #if OPT_ENUM_MODES /* will show the enum name too */ case VALTYPE_ENUM: s = choice_to_name(name_to_choices(names), values->vp->i); break; #endif case VALTYPE_STRING: s = values->vp->p; break; case VALTYPE_REGEX: s = values->vp->r->pat; break; } return n + strlen(NonNull(s)); } /* * Returns a mode-value formatted as a string */ const char * string_mode_val(VALARGS *args) { register const struct VALNAMES *names = args->names; register struct VAL *values = args->local; switch(names->type) { case VALTYPE_BOOL: return values->vp->i ? truem : falsem; case VALTYPE_ENUM: #if OPT_ENUM_MODES { static char temp[20]; (void)strcpy(temp, choice_to_name(name_to_choices(names), values->vp->i)); return temp; } #endif /* else, fall-thru to use int-code */ case VALTYPE_INT: return l_itoa(values->vp->i); case VALTYPE_STRING: return NonNull(values->vp->p); case VALTYPE_REGEX: return NonNull(values->vp->r->pat); } return errorm; } /* listvalueset: print each value in the array according to type, along with its name, until a NULL name is encountered. Only print if the value in the two arrays differs, or the second array is nil */ static int listvalueset( char *which, int nflag, const struct VALNAMES *names, struct VAL *values, struct VAL *globvalues) { int show[MAX_G_VALUES+MAX_B_VALUES+MAX_W_VALUES]; int any = 0, passes = 1, padded, perline, percol, total; register int j, pass; /* * First, make a list of values we want to show. * Store: * 0 - don't show * 1 - show in first pass * 2 - show in second pass (too long) */ for (j = 0; names[j].name != 0; j++) { show[j] = 0; if (same_val(names+j, values+j, globvalues ? globvalues+j : 0) != TRUE) { if (!any++) { if (nflag) bputc('\n'); bprintf("%s:\n", which); } switch (names[j].type) { case VALTYPE_STRING: case VALTYPE_REGEX: if (size_val(names+j, values+j) > ONE_COL) { show[j] += 1; passes = 2; } /* fall-thru */ default: show[j] += 1; } } } total = j; if (any) { if (!passes) passes = 1; } else return nflag; /* * Now, go back and display the values */ for (pass = 1; pass <= passes; pass++) { register int line, col, k; int offsets[NCOLS+1]; offsets[0] = 0; if (pass == 1) { for (j = percol = 0; j < total; j++) { if (show[j] == pass) percol++; } for (j = 1; j < NCOLS; j++) { offsets[j] = (percol + NCOLS - j) / NCOLS + offsets[j-1]; } perline = NCOLS; } else { /* these are too wide for ONE_COL */ offsets[1] = total; perline = 1; } offsets[NCOLS] = total; line = 0; col = 0; for_ever { k = line + offsets[col]; for (j = 0; j < total; j++) { if (show[j] == pass) { if (k-- <= 0) break; } } if (k >= 0) /* no more cells to display */ break; if (col == 0) bputc(' '); padded = (col+1) < perline ? ONE_COL : 1; if (names[j].type == VALTYPE_BOOL) { bprintf("%s%s%*P", values[j].vp->i ? " " : "no", names[j].name, padded, ' '); } else { VALARGS args; /* patch */ args.names = names+j; args.local = values+j; args.global = 0; bprintf(" %s=%s%*P", names[j].name, string_mode_val(&args), padded, ' '); } if (++col >= perline) { col = 0; bputc('\n'); if (++line >= offsets[1]) break; } else if (line+offsets[col] >= offsets[col+1]) break; } if ((col != 0) || (pass != passes)) bputc('\n'); } return TRUE; } #ifdef lint static /*ARGSUSED*/ WINDOW *ptr2WINDOW(void *p) { return 0; } #else #define ptr2WINDOW(p) (WINDOW *)p #endif /* list the current modes into the current buffer */ /* ARGSUSED */ static void makemodelist(int dum1, void *ptr) { static char gg[] = "Universal", bb[] = "Buffer", ww[] = "Window"; int nflag, nflg2; register WINDOW *localwp = ptr2WINDOW(ptr); /* alignment okay */ register BUFFER *localbp = localwp->w_bufp; struct VAL *local_b_vals = localbp->b_values.bv; struct VAL *local_w_vals = localwp->w_values.wv; #if OPT_UPBUFF if (relisting_b_vals != 0) local_b_vals = relisting_b_vals; if (relisting_w_vals != 0) local_w_vals = relisting_w_vals; #endif bprintf("--- \"%s\" settings, if different than globals %*P\n", localbp->b_bname, term.t_ncol-1, '-'); nflag = listvalueset(bb, FALSE, b_valuenames, local_b_vals, global_b_values.bv); nflg2 = listvalueset(ww, nflag, w_valuenames, local_w_vals, global_w_values.wv); if (!(nflag || nflg2)) bputc('\n'); bputc('\n'); bprintf("--- Global settings %*P\n", term.t_ncol-1, '-'); nflag = listvalueset(gg, nflag, g_valuenames, global_g_values.gv, (struct VAL *)0); nflag = listvalueset(bb, nflag, b_valuenames, global_b_values.bv, (struct VAL *)0); (void) listvalueset(ww, nflag, w_valuenames, global_w_values.wv, (struct VAL *)0); } /* * Set tab size */ int settab(int f, int n) { register WINDOW *wp; int val; const char *whichtabs; if (b_val(curbp, MDCMOD)) { val = VAL_C_TAB; whichtabs = "C-t"; } else { val = VAL_TAB; whichtabs = "T"; } if (f && n >= 1) { make_local_b_val(curbp,val); set_b_val(curbp,val,n); curtabval = n; for_each_window(wp) if (wp->w_bufp == curbp) wp->w_flag |= WFHARD; } else if (f) { mlwarn("[Illegal tabstop value]"); return FALSE; } if (!global_b_val(MDTERSE) || !f) mlwrite("[%sabs are %d columns apart, using %s value.]", whichtabs, curtabval, is_local_b_val(curbp,val) ? "local" : "global" ); return TRUE; } /* * Set fill column to n. */ int setfillcol(int f, int n) { if (f && n >= 1) { make_local_b_val(curbp,VAL_FILL); set_b_val(curbp,VAL_FILL,n); } else if (f) { mlwarn("[Illegal fill-column value]"); return FALSE; } if (!global_b_val(MDTERSE) || !f) mlwrite("[Fill column is %d, and is %s]", b_val(curbp,VAL_FILL), is_local_b_val(curbp,VAL_FILL) ? "local" : "global" ); return(TRUE); } /* * Allocate/set a new REGEXVAL struct */ REGEXVAL * new_regexval(const char *pattern, int magic) { register REGEXVAL *rp; if ((rp = typealloc(REGEXVAL)) != 0) { rp->pat = strmalloc(pattern); rp->reg = regcomp(rp->pat, magic); } return rp; } /* * Release storage of a REGEXVAL struct */ static void free_regexval(register REGEXVAL *rp) { if (rp != 0) { FreeAndNull(rp->pat); FreeAndNull(rp->reg); free((char *)rp); } } /* * Release storage of a VAL struct */ static void free_val(const struct VALNAMES *names, struct VAL *values) { switch (names->type) { case VALTYPE_STRING: FreeAndNull(values->v.p); break; case VALTYPE_REGEX: free_regexval(values->v.r); break; default: /* nothing to free */ break; } } /* * Copy a VAL-struct, preserving the sense of local/global. */ static int copy_val(struct VAL *dst, struct VAL *src) { register int local = isLocalVal(src); *dst = *src; if (local) makeLocalVal(dst); return local; } void copy_mvals( int maximum, struct VAL *dst, struct VAL *src) { register int n; for (n = 0; n < maximum; n++) (void)copy_val(&dst[n], &src[n]); } /* * This is a special routine designed to save the values of local modes and to * restore them. The 'recompute_buffer()' procedure assumes that global modes * do not change during the recomputation process (so there is no point in * trying to convert any of those values to local ones). */ #if OPT_UPBUFF void save_vals( int maximum, struct VAL *gbl, struct VAL *dst, struct VAL *src) { register int n; for (n = 0; n < maximum; n++) if (copy_val(&dst[n], &src[n])) make_global_val(src, gbl, n); } #endif /* * free storage used by local mode-values, called only when we are freeing * all other storage associated with a buffer or window. */ void free_local_vals( const struct VALNAMES *names, struct VAL *gbl, struct VAL *val) { register int j; for (j = 0; names[j].name != 0; j++) if (is_local_val(val,j)) { make_global_val(val, gbl, j); free_val(names+j, val+j); } } /* * Convert a string to boolean, checking for errors */ static int string_to_bool(const char *base, int *np) { if (is_truem(base)) *np = TRUE; else if (is_falsem(base)) *np = FALSE; else { mlforce("[Not a boolean: '%s']", base); return FALSE; } return TRUE; } /* * Convert a string to number, checking for errors */ int string_to_number(const char *from, int *np) { long n; char *p; /* accept decimal, octal, or hex */ n = strtol(from, &p, 0); if (p == from || *p != EOS) { mlforce("[Not a number: '%s']", from); return FALSE; } *np = (int)n; return TRUE; } /* * Validate a 'glob' mode-value. It is either a boolean, or it must be a * pipe-expression with exactly one "%s" embedded (no other % characters, * unless escaped). That way, we can use the string to format the pipe * command. */ #if defined(GMD_GLOB) || defined(GVAL_GLOB) static int legal_glob_mode(const char *base) { #ifdef GVAL_GLOB /* string */ if (isShellOrPipe(base)) { register const char *s = base; int count = 0; while (*s != EOS) { if (*s == '%') { if (*++s != '%') { if (*s == 's') count++; else count = 2; } } if (*s != EOS) s++; } if (count == 1) return TRUE; } #endif if (!strcmp(base, "off") || !strcmp(base, "on")) return TRUE; mlforce("[Illegal value for glob: '%s']", base); return FALSE; } #endif /* * FSM stands for fixed string mode, so called because the strings which the * user is permitted to enter are non-arbitrary (fixed). * * It is meant to handle the following sorts of things: * * :set popup-choices off * :set popup-choices immediate * :set popup-choices delayed * * :set error quiet * :set error beep * :set error flash */ #if OPT_ENUM_MODES /* * These names and codes match the ANSI color codes. */ static const FSM_CHOICES fsm_color_choices[] = { /* names of colors */ { "black", 0 }, { "blue", 4 }, { "cyan", 6 }, #if DISP_TERMCAP || DISP_IBMPC /* FIXME: implement this for all drivers */ { "default", ENUM_UNKNOWN }, #endif { "green", 2 }, { "magenta", 5 }, { "red", 1 }, { "white", 7 }, { "yellow", 3 }, END_CHOICES }; static const FSM_CHOICES fsm_bool_choices[] = { { "false", FALSE }, { "true", TRUE }, END_CHOICES }; #if OPT_POPUPCHOICE static const FSM_CHOICES fsm_popup_choices[] = { { "delayed", POPUP_CHOICES_DELAYED}, { "immediate", POPUP_CHOICES_IMMED}, { "off", POPUP_CHOICES_OFF}, END_CHOICES }; #endif #if NEVER FSM_CHOICES fsm_error[] = { { "beep", 1}, { "flash", 2}, { "quiet", 0}, END_CHOICES }; #endif #if OPT_FILEBACK static const FSM_CHOICES fsm_backupstyle[] = { { "off", 0}, { ".bak", 1}, #if SYS_UNIX { "tilde", 2}, /* "tilde_N_existing", */ /* "tilde_N", */ #endif END_CHOICES }; #endif #if OPT_HILITEMATCH static const FSM_CHOICES fsm_mono_attributes[] = { { "bold", VABOLD }, { "color", VACOLOR }, { "italic", VAITAL }, { "none", 0 }, { "reverse", VAREV }, { "underline", VAUL }, END_CHOICES }; #endif static const struct FSM fsm_tbl[] = { { "*bool", fsm_bool_choices }, #if OPT_COLOR { "fcolor", fsm_color_choices }, { "bcolor", fsm_color_choices }, #endif #if OPT_POPUPCHOICE { "popup-choices", fsm_popup_choices }, #endif #if NEVER { "error", fsm_error }, #endif #if OPT_FILEBACK { "backup-style", fsm_backupstyle }, #endif #if OPT_HILITEMATCH { "visual-matches", fsm_mono_attributes }, #endif }; static int fsm_idx; static int choice_to_code (const FSM_CHOICES *choices, const char *name) { int code = ENUM_ILLEGAL; register int i; for (i = 0; choices[i].choice_name != 0; i++) { if (strcmp(name, choices[i].choice_name) == 0) { code = choices[i].choice_code; break; } } return code; } static const char * choice_to_name (const FSM_CHOICES *choices, int code) { const char *name = 0; register int i; for (i = 0; choices[i].choice_name != 0; i++) { if (choices[i].choice_code == code) { name = choices[i].choice_name; break; } } return name; } static const FSM_CHOICES * name_to_choices (const struct VALNAMES *names) { register SIZE_T i; for (i = 1; i < TABLESIZE(fsm_tbl); i++) if (strcmp(fsm_tbl[i].mode_name, names->name) == 0) return fsm_tbl[i].choices; return 0; } static int is_fsm(const struct VALNAMES *names) { register SIZE_T i; if (names->type == VALTYPE_ENUM || names->type == VALTYPE_STRING) { for (i = 1; i < TABLESIZE(fsm_tbl); i++) { if (strcmp(fsm_tbl[i].mode_name, names->name) == 0) { fsm_idx = (int)i; return TRUE; } } } else if (names->type == VALTYPE_BOOL) { fsm_idx = 0; return TRUE; } fsm_idx = -1; return FALSE; } /* * Test if we're processing an enum-valued mode. If so, lookup the mode value. * We'll allow a numeric index also (e.g., for colors). Note that we're * returning the table-value in that case, so we'll have to ensure that we * don't corrupt the table. */ static const char * legal_fsm(const char *val) { if (fsm_idx >= 0) { int i; int idx = fsm_idx; const FSM_CHOICES *p = fsm_tbl[idx].choices; const char *s; if (isdigit(*val)) { if (!string_to_number(val, &i)) return 0; if ((s = choice_to_name(p, i)) != 0) return s; } else { if (choice_to_code(p, val) != ENUM_ILLEGAL) return val; } mlforce("[Illegal value for %s: '%s']", fsm_tbl[idx].mode_name, val); return 0; } return val; } static int fsm_complete(int c, char *buf, int *pos) { if (isdigit(*buf)) { /* allow numbers for colors */ if (c != NAMEC) /* put it back (cf: kbd_complete) */ unkeystroke(c); return isspace(c); } return kbd_complete(FALSE, c, buf, pos, (char *)(fsm_tbl[fsm_idx].choices), sizeof (FSM_CHOICES) ); } #endif /* OPT_ENUM_MODES */ /* * Lookup the mode named with 'cp[]' and adjust its value. */ int adjvalueset( const char *cp, /* name of the mode we are changing */ int setting, /* true if setting, false if unsetting */ int global, VALARGS *args) /* symbol-table entry for the mode */ { const struct VALNAMES *names = args->names; struct VAL *values = args->local; struct VAL *globls = args->global; struct VAL oldvalue; char prompt[NLINE]; char respbuf[NFILEN]; int no = !strncmp(cp, "no", 2); const char *rp = no ? cp+2 : cp; int nval, status = TRUE; int unsetting = !setting && !global; if (no && (names->type != VALTYPE_BOOL)) return FALSE; /* this shouldn't happen */ /* * Check if we're allowed to change this mode in the current context. */ if ((names->side_effect != 0) && !(*(names->side_effect))(args, (values==globls), TRUE)) return FALSE; /* get a value if we need one */ if ((end_string() == '=') || (names->type != VALTYPE_BOOL && !unsetting)) { int regex = (names->type == VALTYPE_REGEX); int opts = regex ? 0 : KBD_NORMAL; int eolchar = (names->type == VALTYPE_REGEX || names->type == VALTYPE_STRING) ? '\n' : ' '; int (*complete) (DONE_ARGS) = no_completion; respbuf[0] = EOS; (void)lsprintf(prompt, "New %s %s: ", cp, regex ? "pattern" : "value"); #if OPT_ENUM_MODES if (is_fsm(names)) complete = fsm_complete; #endif status = kbd_string(prompt, respbuf, sizeof(respbuf), eolchar, opts, complete); if (status != TRUE) return status; if (!strlen(rp = respbuf)) return FALSE; #if defined(GMD_GLOB) || defined(GVAL_GLOB) if (!strcmp(names->name, "glob") && !legal_glob_mode(rp)) return FALSE; #endif #if OPT_ENUM_MODES if ((rp = legal_fsm(rp)) == 0) return FALSE; #endif /* Test after fsm, to allow translation */ if (names->type == VALTYPE_BOOL) { if (!string_to_bool(rp, &setting)) return FALSE; } } #if OPT_HISTORY else hst_glue(' '); #endif /* save, to simplify no-change testing */ (void)copy_val(&oldvalue, values); if (unsetting) { make_global_val(values, globls, 0); } else { makeLocalVal(values); /* make sure we point to result! */ /* we matched a name -- set the value */ switch(names->type) { case VALTYPE_BOOL: values->vp->i = no ? !setting : setting; break; case VALTYPE_ENUM: #if OPT_ENUM_MODES { const FSM_CHOICES *fp = name_to_choices(names); if (isdigit(*rp)) { if (!string_to_number(rp, &nval)) return FALSE; if (choice_to_name(fp, nval) == 0) nval = ENUM_ILLEGAL; } else { nval = choice_to_code(fp, rp); } if (nval == ENUM_ILLEGAL) { mlforce("[Not a legal enum-index: %s]", rp); return FALSE; } } values->vp->i = nval; break; #endif /* OPT_ENUM_MODES */ case VALTYPE_INT: if (!string_to_number(rp, &nval)) return FALSE; values->vp->i = nval; break; case VALTYPE_STRING: values->vp->p = strmalloc(rp); break; case VALTYPE_REGEX: values->vp->r = new_regexval(rp, TRUE); break; default: mlforce("BUG: bad type %s %d", names->name, names->type); return FALSE; } } /* * Set window flags (to force the redisplay as needed), and apply * side-effects. */ status = TRUE; if (!same_val(names, values, &oldvalue) && (names->side_effect != 0) && !(*(names->side_effect))(args, (values==globls), FALSE)) status = FALSE; if (isLocalVal(&oldvalue)) free_val(names, &oldvalue); return status; } /* ARGSUSED */ int listmodes(int f, int n) { register WINDOW *wp = curwp; register int s; s = liststuff(SETTINGS_BufName, FALSE, makemodelist,0,(void *)wp); /* back to the buffer whose modes we just listed */ if (swbuffer(wp->w_bufp)) curwp = wp; return s; } /* * The 'mode_complete()' and 'mode_eol()' functions are invoked from * 'kbd_reply()' to setup the mode-name completion and query displays. */ static int mode_complete(int c, char *buf, int *pos) { return kbd_complete(FALSE, c, buf, pos, (char *)&all_modes[0], sizeof(all_modes[0])); } int /*ARGSUSED*/ mode_eol(char * buffer, int cpos, int c, int eolchar) { return (c == ' ' || c == eolchar); } int find_mode(const char *mode, int global, VALARGS *args) { register const char *rp = !strncmp(mode, "no", 2) ? mode+2 : mode; register int class; register int j; for (class = 0; class < 3; class++) { switch (class) { default: /* universal modes */ args->names = g_valuenames; args->global = global_g_values.gv; args->local = (global != FALSE) ? args->global : (struct VAL *)0; break; case 1: /* buffer modes */ args->names = b_valuenames; args->global = global_b_values.bv; args->local = (global == TRUE) ? args->global : ((curbp != 0) ? curbp->b_values.bv : (struct VAL *)0); break; case 2: /* window modes */ args->names = w_valuenames; args->global = global_w_values.wv; args->local = (global == TRUE) ? args->global : ((curwp != 0) ? curwp->w_values.wv : (struct VAL *)0); break; } if (args->local != 0) { for (j = 0; args->names[j].name != NULL; j++) { if (!strcmp(rp, args->names[j].name) || !strcmp(rp, args->names[j].shortname)) { args->names += j; args->local += j; args->global += j; return TRUE; } } } } return FALSE; } /* * Process a single mode-setting */ static int do_a_mode(int kind, int global) { VALARGS args; register int s; static char cbuf[NLINE]; /* buffer to receive mode name into */ /* prompt the user and get an answer */ if ((s = kbd_reply( global ? "Global value: " : "Local value: ", cbuf, (int)sizeof(cbuf)-1, mode_eol, '=', KBD_NORMAL|KBD_LOWERC, mode_complete)) != TRUE) return ((s == FALSE) ? SORTOFTRUE : s); if (!strcmp(cbuf,"all")) { hst_glue(' '); return listmodes(FALSE,1); } if ((s = find_mode(cbuf, global, &args)) != TRUE) { #if OPT_EVAL if (!global && (s = find_mode(cbuf, TRUE, &args)) == TRUE) { mlforce("[Not a local mode: \"%s\"]", cbuf); return FALSE; } return set_variable(cbuf); #else mlforce("[Not a legal set option: \"%s\"]", cbuf); #endif } else if ((s = adjvalueset(cbuf, kind, global, &args)) != 0) { if (s == TRUE) mlerase(); /* erase the junk */ return s; } return FALSE; } /* * Process the list of mode-settings */ static int adjustmode( /* change the editor mode status */ int kind, /* true = set, false = delete */ int global) /* true = global flag, false = current buffer flag */ { int s; int anything = 0; while (((s = do_a_mode(kind, global)) == TRUE) && (end_string() == ' ')) anything++; if ((s == SORTOFTRUE) && anything) /* fix for trailing whitespace */ return TRUE; #if OPT_UPBUFF /* if the settings are up, redisplay them */ relist_settings(); #endif /* OPT_UPBUFF */ if (curbp) { curtabval = tabstop_val(curbp); curswval = shiftwid_val(curbp); } return s; } /* * Buffer-animation for [Settings] */ #if OPT_UPBUFF static int show_Settings(BUFFER *bp) { b_clr_obsolete(bp); return listmodes(FALSE, 1); } static void relist_settings(void) { update_scratch(SETTINGS_BufName, show_Settings); } #endif /* OPT_UPBUFF */ /* ARGSUSED */ int setlocmode(int f, int n) /* prompt and set an editor mode */ { return adjustmode(TRUE, FALSE); } /* ARGSUSED */ int dellocmode(int f, int n) /* prompt and delete an editor mode */ { return adjustmode(FALSE, FALSE); } /* ARGSUSED */ int setglobmode(int f, int n) /* prompt and set a global editor mode */ { return adjustmode(TRUE, TRUE); } /* ARGSUSED */ int delglobmode(int f, int n) /* prompt and delete a global editor mode */ { return adjustmode(FALSE, TRUE); } /* * The following functions are invoked to carry out side effects of changing * modes. */ /*ARGSUSED*/ int chgd_autobuf(CHGD_ARGS) { if (glob_vals) sortlistbuffers(); return TRUE; } /*ARGSUSED*/ int chgd_buffer(CHGD_ARGS) { if (!glob_vals) { /* i.e., ":setl" */ if (curbp == 0) return FALSE; b_clr_counted(curbp); (void)bsizes(curbp); } return TRUE; } int chgd_charset(CHGD_ARGS) { if (!testing) { charinit(); } return chgd_window(args, glob_vals, testing); } #if OPT_COLOR int chgd_color(CHGD_ARGS) { if (!testing) { if (&args->local->vp->i == &gfcolor) TTforg(gfcolor); else if (&args->local->vp->i == &gbcolor) TTbacg(gbcolor); set_winflags(glob_vals, WFHARD|WFCOLR); vile_refresh(FALSE,0); } return TRUE; } #endif /* OPT_COLOR */ /* Report mode that cannot be changed */ /*ARGSUSED*/ int chgd_disabled(CHGD_ARGS) { mlforce("[Cannot change \"%s\" ]", args->names->name); return FALSE; } /* Change "fences" mode */ /*ARGSUSED*/ int chgd_fences(CHGD_ARGS) { if (!testing) { /* was even number of fence pairs specified? */ char *value = args->local->v.p; size_t len = strlen(value); if (len & 1) { value[len-1] = EOS; mlwrite( "[Fence-pairs not in pairs: truncating to \"%s\"", value); return FALSE; } } return TRUE; } /* Change a "major" mode */ int chgd_major(CHGD_ARGS) { /* prevent major-mode changes for scratch-buffers */ if (testing) { if (!glob_vals) { if (b_is_scratch(curbp)) return chgd_disabled(args, glob_vals, testing); } } else { set_winflags(glob_vals, WFMODE); } return TRUE; } /* Change a major mode that affects the windows on the buffer */ int chgd_major_w(CHGD_ARGS) { if (testing) { if (!chgd_major(args, glob_vals, testing)) return FALSE; return chgd_window(args, glob_vals, testing); } set_winflags(glob_vals, WFHARD|WFMODE); return TRUE; } /* Change something on the mode/status line */ /*ARGSUSED*/ int chgd_status(CHGD_ARGS) { if (!testing) { set_winflags(glob_vals, WFSTAT); } return TRUE; } /* Change a mode that affects the windows on the buffer */ /*ARGSUSED*/ int chgd_window(CHGD_ARGS) { if (!testing) { set_winflags(glob_vals, WFHARD); } return TRUE; } /* Change the working mode */ #if OPT_WORKING /*ARGSUSED*/ int chgd_working(CHGD_ARGS) { if (glob_vals) imworking(0); return TRUE; } #endif /* Change the xterm-mouse mode */ /*ARGSUSED*/ int chgd_xterm(CHGD_ARGS) { #if OPT_XTERM if (glob_vals) { int new_state = global_g_val(GMDXTERM_MOUSE); set_global_g_val(GMDXTERM_MOUSE,TRUE); if (!new_state) TTkclose(); else TTkopen(); set_global_g_val(GMDXTERM_MOUSE,new_state); } #endif return TRUE; } /* Change a mode that affects the search-string highlighting */ /*ARGSUSED*/ int chgd_hilite(CHGD_ARGS) { if (!testing) attrib_matches(); return TRUE; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.