Annotation of src/usr.bin/mg/main.c, Revision 1.42
1.42 ! kjell 1: /* $OpenBSD: main.c,v 1.41 2005/08/09 00:53:48 kjell Exp $ */
1.40 kjell 2:
3: /* This file is in the public domain. */
1.6 niklas 4:
1.1 deraadt 5: /*
1.5 millert 6: * Mainline.
1.1 deraadt 7: */
1.5 millert 8:
1.38 db 9: #include "def.h"
10: #include "kbd.h"
11: #include "funmap.h"
1.5 millert 12:
1.1 deraadt 13: #ifndef NO_MACRO
1.38 db 14: #include "macro.h"
1.5 millert 15: #endif /* NO_MACRO */
1.1 deraadt 16:
1.24 vincent 17: #include <err.h>
18:
1.5 millert 19: int thisflag; /* flags, this command */
20: int lastflag; /* flags, last command */
21: int curgoal; /* goal column */
1.36 deraadt 22: int startrow; /* row to start */
1.5 millert 23: BUFFER *curbp; /* current buffer */
1.38 db 24: BUFFER *bheadp; /* BUFFER list head */
1.5 millert 25: MGWIN *curwp; /* current window */
1.8 art 26: MGWIN *wheadp; /* MGWIN listhead */
1.5 millert 27: char pat[NPAT]; /* pattern */
1.1 deraadt 28:
1.24 vincent 29: static void edinit(PF);
1.1 deraadt 30:
1.2 deraadt 31: int
1.19 vincent 32: main(int argc, char **argv)
1.1 deraadt 33: {
1.24 vincent 34: char *cp, *init_fcn_name = NULL;
1.38 db 35: PF init_fcn = NULL;
36: int o, i, nfiles, status;
37: int nobackups = 0;
1.24 vincent 38:
1.35 henning 39: while ((o = getopt(argc, argv, "nf:")) != -1)
1.24 vincent 40: switch (o) {
1.35 henning 41: case 'n':
42: nobackups = 1;
43: break;
1.24 vincent 44: case 'f':
45: if (init_fcn_name != NULL)
46: errx(1, "cannot specify more than one "
47: "initial function");
48: init_fcn_name = optarg;
49: break;
50: default:
1.37 jmc 51: errx(1, "usage: mg [options] [file ...]");
1.24 vincent 52: }
53: argc -= optind;
54: argv += optind;
1.1 deraadt 55:
1.12 art 56: maps_init(); /* Keymaps and modes. */
1.11 art 57: funmap_init(); /* Functions. */
1.19 vincent 58:
1.13 art 59: /*
60: * This is where we initialize standalone extensions that should
61: * be loaded dynamically sometime in the future.
62: */
63: {
64: extern void grep_init(void);
1.14 art 65: extern void theo_init(void);
1.42 ! kjell 66: extern void mail_init(void);
! 67: #ifndef NO_DIRED
! 68: extern void dired_init(void);
1.13 art 69:
1.42 ! kjell 70: dired_init();
! 71: #endif /* !NO_DIRED */
1.13 art 72: grep_init();
1.14 art 73: theo_init();
1.24 vincent 74: mail_init();
1.13 art 75: }
1.5 millert 76:
1.24 vincent 77: if (init_fcn_name &&
78: (init_fcn = name_function(init_fcn_name)) == NULL)
79: errx(1, "Unknown function `%s'", init_fcn_name);
80:
81: vtinit(); /* Virtual terminal. */
82: #ifndef NO_DIR
83: dirinit(); /* Get current directory. */
84: #endif /* !NO_DIR */
85: edinit(init_fcn); /* Buffers, windows. */
86: ttykeymapinit(); /* Symbols, bindings. */
87:
1.4 millert 88: /*
89: * doing update() before reading files causes the error messages from
90: * the file I/O show up on the screen. (and also an extra display of
91: * the mode line if there are files specified on the command line.)
1.1 deraadt 92: */
93: update();
1.5 millert 94:
95: #ifndef NO_STARTUP
96: /* user startup file */
1.8 art 97: if ((cp = startupfile(NULL)) != NULL)
1.7 art 98: (void)load(cp);
1.5 millert 99: #endif /* !NO_STARTUP */
1.35 henning 100:
101: if (nobackups)
102: makebkfile(FFARG, 0);
1.27 vincent 103:
104: for (nfiles = 0, i = 0; i < argc; i++) {
105: if (argv[i][0] == '+' && strlen(argv[i]) >= 2) {
1.30 pvalchev 106: int lval;
107: const char *errstr;
1.23 deraadt 108:
1.32 vincent 109: lval = strtonum(&argv[i][1], INT_MIN, INT_MAX, &errstr);
1.33 vincent 110: if (argv[i][1] == '\0' || errstr != NULL)
1.23 deraadt 111: goto notnum;
1.30 pvalchev 112: startrow = lval;
1.24 vincent 113: } else {
1.23 deraadt 114: notnum:
1.27 vincent 115: cp = adjustname(argv[i]);
1.24 vincent 116: if (cp != NULL) {
1.38 db 117: if (nfiles == 1)
1.27 vincent 118: splitwind(0, 1);
1.38 db 119:
1.39 beck 120: if ((curbp = findbuffer(cp)) == NULL) {
121: vttidy();
122: errx(1, "Can't find current buffer!");
123: }
1.24 vincent 124: (void)showbuffer(curbp, curwp, 0);
1.38 db 125: if ((status = readin(cp)) != TRUE)
1.34 jfb 126: killbuffer(curbp);
1.38 db 127: else {
1.34 jfb 128: if (init_fcn_name)
129: init_fcn(0, 1);
130: nfiles++;
131: }
1.24 vincent 132: }
1.22 vincent 133: }
1.1 deraadt 134: }
1.29 vincent 135:
136: if (nfiles > 2)
137: listbuffers(0, 1);
1.5 millert 138:
139: /* fake last flags */
140: thisflag = 0;
1.4 millert 141: for (;;) {
1.1 deraadt 142: #ifndef NO_DPROMPT
1.4 millert 143: if (epresf == KPROMPT)
144: eerase();
1.5 millert 145: #endif /* !NO_DPROMPT */
1.17 deraadt 146: if (winch_flag) {
147: refresh(0, 0);
148: winch_flag = 0;
149: }
1.4 millert 150: update();
151: lastflag = thisflag;
152: thisflag = 0;
1.5 millert 153:
1.4 millert 154: switch (doin()) {
155: case TRUE:
156: break;
1.1 deraadt 157: case ABORT:
1.5 millert 158: ewprintf("Quit");
159: /* and fall through */
1.1 deraadt 160: case FALSE:
161: default:
1.4 millert 162: ttbeep();
1.1 deraadt 163: #ifndef NO_MACRO
1.4 millert 164: macrodef = FALSE;
1.5 millert 165: #endif /* !NO_MACRO */
1.4 millert 166: }
1.1 deraadt 167: }
168: }
169:
170: /*
171: * Initialize default buffer and window.
172: */
1.7 art 173: static void
1.24 vincent 174: edinit(PF init_fcn)
1.4 millert 175: {
1.5 millert 176: BUFFER *bp;
177: MGWIN *wp;
1.1 deraadt 178:
179: bheadp = NULL;
1.5 millert 180: bp = bfind("*scratch*", TRUE); /* Text buffer. */
1.26 vincent 181: wp = new_window(bp);
1.21 vincent 182: if (wp == NULL)
183: panic("Out of memory");
1.4 millert 184: if (bp == NULL || wp == NULL)
185: panic("edinit");
1.5 millert 186: curbp = bp; /* Current ones. */
1.1 deraadt 187: wheadp = wp;
1.4 millert 188: curwp = wp;
1.5 millert 189: wp->w_wndp = NULL; /* Initialize window. */
1.1 deraadt 190: wp->w_linep = wp->w_dotp = bp->b_linep;
1.38 db 191: wp->w_ntrows = nrow - 2; /* 2 = mode, echo. */
192: wp->w_flag = WFMODE | WFHARD; /* Full. */
1.24 vincent 193:
194: if (init_fcn)
1.25 vincent 195: init_fcn(0, 1);
1.1 deraadt 196: }
197:
198: /*
1.5 millert 199: * Quit command. If an argument, always quit. Otherwise confirm if a buffer
200: * has been changed and not written out. Normally bound to "C-X C-C".
1.1 deraadt 201: */
1.4 millert 202: /* ARGSUSED */
1.5 millert 203: int
1.20 vincent 204: quit(int f, int n)
1.1 deraadt 205: {
1.5 millert 206: int s;
1.1 deraadt 207:
1.4 millert 208: if ((s = anycb(FALSE)) == ABORT)
1.38 db 209: return (ABORT);
1.1 deraadt 210: if (s == FALSE
1.41 kjell 211: || eyesno("Modified buffers exist; really exit") == TRUE) {
1.1 deraadt 212: vttidy();
1.5 millert 213: #ifdef SYSCLEANUP
1.4 millert 214: SYSCLEANUP;
1.5 millert 215: #endif /* SYSCLEANUP */
1.1 deraadt 216: exit(GOOD);
217: }
1.38 db 218: return (TRUE);
1.1 deraadt 219: }
220:
221: /*
1.10 mickey 222: * User abort. Should be called by any input routine that sees a C-g to abort
1.5 millert 223: * whatever C-g is aborting these days. Currently does nothing.
1.1 deraadt 224: */
1.4 millert 225: /* ARGSUSED */
226: int
1.20 vincent 227: ctrlg(int f, int n)
1.1 deraadt 228: {
1.24 vincent 229: return (ABORT);
1.1 deraadt 230: }