void dobeep(void) { if (doaudiblebell) { ttbeep(); } if (dovisiblebell) { sgarbf = TRUE; update(CNONE); usleep(50000); } donebell = 1; }
/* * Hack to show matching paren. Self-insert character, then show matching * character, if any. Bound to "blink-and-insert". */ int showmatch(int f, int n) { int i, s; for (i = 0; i < n; i++) { if ((s = selfinsert(FFRAND, 1)) != TRUE) return (s); /* unbalanced -- warn user */ if (balance() != TRUE) ttbeep(); } return (TRUE); }
/* ARGSUSED */ int backpage(int f, int n) { struct line *lp, *lp2; if (!(f & FFARG)) { n = curwp->w_ntrows - 2; /* Default scroll. */ if (n <= 0) /* Don't blow up if the */ return (backline(f, 1));/* window is tiny. */ } else if (n < 0) return (forwpage(f | FFRAND, -n)); lp = lp2 = curwp->w_linep; while (n-- && lback(lp) != curbp->b_headp) { lp = lback(lp); } if (lp == curwp->w_linep) { ttbeep(); ewprintf("Beginning of buffer"); } curwp->w_linep = lp; curwp->w_rflag |= WFFULL; /* if in current window, don't move dot */ for (n = curwp->w_ntrows; n-- && lp != curbp->b_headp; lp = lforw(lp)) if (lp == curwp->w_dotp) return (TRUE); lp2 = lforw(lp2); /* Move the dot the slow way, for line nos */ while (curwp->w_dotp != lp2) { if (curwp->w_dotline <= curwp->w_ntrows) return (TRUE); curwp->w_dotp = lback(curwp->w_dotp); curwp->w_dotline--; } curwp->w_doto = 0; return (TRUE); }
/* ARGSUSED */ int forwpage(int f, int n) { struct line *lp; if (!(f & FFARG)) { n = curwp->w_ntrows - 2; /* Default scroll. */ if (n <= 0) /* Forget the overlap */ n = 1; /* if tiny window. */ } else if (n < 0) return (backpage(f | FFRAND, -n)); lp = curwp->w_linep; while (n--) if ((lp = lforw(lp)) == curbp->b_headp) { ttbeep(); ewprintf("End of buffer"); return(TRUE); } curwp->w_linep = lp; curwp->w_rflag |= WFFULL; /* if in current window, don't move dot */ for (n = curwp->w_ntrows; n-- && lp != curbp->b_headp; lp = lforw(lp)) if (lp == curwp->w_dotp) return (TRUE); /* Advance the dot the slow way, for line nos */ while (curwp->w_dotp != curwp->w_linep) { curwp->w_dotp = lforw(curwp->w_dotp); curwp->w_dotline++; } curwp->w_doto = 0; return (TRUE); }
int main(int argc, char **argv) { char *cp, *init_fcn_name = NULL; PF init_fcn = NULL; int o, i, nfiles; int nobackups = 0; struct buffer *bp = NULL; #ifdef MRUBY mrb_mg_init(); int noinitfile = 0; #endif /* MRUBY */ while ((o = getopt(argc, argv, "nf:q")) != -1) switch (o) { case 'n': nobackups = 1; break; case 'f': if (init_fcn_name != NULL) errx(1, "cannot specify more than one " "initial function"); init_fcn_name = optarg; break; case 'q': noinitfile = 1; break; default: usage(); } argc -= optind; argv += optind; maps_init(); /* Keymaps and modes. */ funmap_init(); /* Functions. */ /* * This is where we initialize standalone extensions that should * be loaded dynamically sometime in the future. */ { extern void grep_init(void); extern void theo_init(void); extern void cmode_init(void); extern void dired_init(void); dired_init(); grep_init(); theo_init(); cmode_init(); #ifdef UTF8 utf8_init(); #endif /* UTF8 */ } if (init_fcn_name && (init_fcn = name_function(init_fcn_name)) == NULL) errx(1, "Unknown function `%s'", init_fcn_name); vtinit(); /* Virtual terminal. */ dirinit(); /* Get current directory. */ edinit(bp); /* Buffers, windows. */ ttykeymapinit(); /* Symbols, bindings. */ /* * doing update() before reading files causes the error messages from * the file I/O show up on the screen. (and also an extra display of * the mode line if there are files specified on the command line.) */ update(); /* user startup file */ #ifdef MRUBY if (noinitfile == 0 && (cp = startupfile(NULL)) != NULL) mrb_mg_load(cp); #else if ((cp = startupfile(NULL)) != NULL) (void)load(cp); #endif /* MRUBY */ /* * Now ensure any default buffer modes from the startup file are * given to any files opened when parsing the startup file. * Note *scratch* will also be updated. */ for (bp = bheadp; bp != NULL; bp = bp->b_bufp) { bp->b_flag = defb_flag; for (i = 0; i <= defb_nmodes; i++) { bp->b_modes[i] = defb_modes[i]; } } /* Force FFOTHARG=1 so that this mode is enabled, not simply toggled */ if (init_fcn) init_fcn(FFOTHARG, 1); if (nobackups) makebkfile(FFARG, 0); for (nfiles = 0, i = 0; i < argc; i++) { if (argv[i][0] == '+' && strlen(argv[i]) >= 2) { long long lval; const char *errstr; lval = strtonum(&argv[i][1], INT_MIN, INT_MAX, &errstr); if (argv[i][1] == '\0' || errstr != NULL) goto notnum; startrow = lval; } else { notnum: cp = adjustname(argv[i], FALSE); if (cp != NULL) { if (nfiles == 1) splitwind(0, 1); if ((curbp = findbuffer(cp)) == NULL) { vttidy(); errx(1, "Can't find current buffer!"); } (void)showbuffer(curbp, curwp, 0); if (readin(cp) != TRUE) killbuffer(curbp); else { /* Ensure enabled, not just toggled */ if (init_fcn_name) init_fcn(FFOTHARG, 1); nfiles++; } } } } if (nfiles > 2) listbuffers(0, 1); /* fake last flags */ thisflag = 0; for (;;) { if (epresf == KCLEAR) eerase(); if (epresf == TRUE) epresf = KCLEAR; if (winch_flag) { do_redraw(0, 0, TRUE); winch_flag = 0; } update(); lastflag = thisflag; thisflag = 0; switch (doin()) { case TRUE: break; case ABORT: ewprintf("Quit"); /* FALLTHRU */ case FALSE: default: ttbeep(); macrodef = FALSE; } } }
/* * Incremental Search. * dir is used as the initial direction to search. * ^S switch direction to forward * ^R switch direction to reverse * ^Q quote next character (allows searching for ^N etc.) * <ESC> exit from Isearch * <DEL> undoes last character typed. (tricky job to do this correctly). * other ^ exit search, don't set mark * else accumulate into search string */ static int isearch(int dir) { struct line *clp; /* Saved line pointer */ int c; int cbo; /* Saved offset */ int success; int pptr; int firstc; int xcase; int i; char opat[NPAT]; int cdotline; /* Saved line number */ #ifndef NO_MACRO if (macrodef) { ewprintf("Can't isearch in macro"); return (FALSE); } #endif /* !NO_MACRO */ for (cip = 0; cip < NSRCH; cip++) cmds[cip].s_code = SRCH_NOPR; (void)strlcpy(opat, pat, sizeof(opat)); cip = 0; pptr = -1; clp = curwp->w_dotp; cbo = curwp->w_doto; cdotline = curwp->w_dotline; is_lpush(); is_cpush(SRCH_BEGIN); success = TRUE; is_prompt(dir, TRUE, success); for (;;) { update(); switch (c = getkey(FALSE)) { case CCHR('['): /* * If new characters come in the next 300 msec, * we can assume that they belong to a longer * escaped sequence so we should ungetkey the * ESC to avoid writing out garbage. */ if (ttwait(300) == FALSE) ungetkey(c); srch_lastdir = dir; curwp->w_markp = clp; curwp->w_marko = cbo; curwp->w_markline = cdotline; ewprintf("Mark set"); return (TRUE); case CCHR('G'): if (success != TRUE) { while (is_peek() == SRCH_ACCM) is_undo(&pptr, &dir); success = TRUE; is_prompt(dir, pptr < 0, success); break; } curwp->w_dotp = clp; curwp->w_doto = cbo; curwp->w_dotline = cdotline; curwp->w_rflag |= WFMOVE; srch_lastdir = dir; (void)ctrlg(FFRAND, 0); (void)strlcpy(pat, opat, sizeof(pat)); return (ABORT); case CCHR('S'): if (dir == SRCH_BACK) { dir = SRCH_FORW; is_lpush(); is_cpush(SRCH_FORW); success = TRUE; } if (success == FALSE && dir == SRCH_FORW) { /* wrap the search to beginning */ curwp->w_dotp = bfirstlp(curbp); curwp->w_doto = 0; curwp->w_dotline = 1; if (is_find(dir) != FALSE) { is_cpush(SRCH_MARK); success = TRUE; } ewprintf("Overwrapped I-search: %s", pat); break; } is_lpush(); pptr = strlen(pat); (void)forwchar(FFRAND, 1); if (is_find(SRCH_FORW) != FALSE) is_cpush(SRCH_MARK); else { (void)backchar(FFRAND, 1); ttbeep(); success = FALSE; ewprintf("Failed I-search: %s", pat); } is_prompt(dir, pptr < 0, success); break; case CCHR('R'): if (dir == SRCH_FORW) { dir = SRCH_BACK; is_lpush(); is_cpush(SRCH_BACK); success = TRUE; } if (success == FALSE && dir == SRCH_BACK) { /* wrap the search to end */ curwp->w_dotp = blastlp(curbp); curwp->w_doto = llength(curwp->w_dotp); curwp->w_dotline = curwp->w_bufp->b_lines; if (is_find(dir) != FALSE) { is_cpush(SRCH_MARK); success = TRUE; } ewprintf("Overwrapped I-search: %s", pat); break; } is_lpush(); pptr = strlen(pat); (void)backchar(FFRAND, 1); if (is_find(SRCH_BACK) != FALSE) is_cpush(SRCH_MARK); else { (void)forwchar(FFRAND, 1); ttbeep(); success = FALSE; } is_prompt(dir, pptr < 0, success); break; case CCHR('W'): /* add the rest of the current word to the pattern */ clp = curwp->w_dotp; cbo = curwp->w_doto; firstc = 1; if (pptr == -1) pptr = 0; if (dir == SRCH_BACK) { /* when isearching backwards, cbo is the start of the pattern */ cbo += pptr; } /* if the search is case insensitive, add to pattern using lowercase */ xcase = 0; for (i = 0; pat[i]; i++) if (ISUPPER(CHARMASK(pat[i]))) xcase = 1; while (cbo < llength(clp)) { c = lgetc(clp, cbo++); if ((!firstc && !isalnum(c))) break; if (pptr == NPAT - 1) { ttbeep(); break; } firstc = 0; if (!xcase && ISUPPER(c)) c = TOLOWER(c); pat[pptr++] = c; pat[pptr] = '\0'; /* cursor only moves when isearching forwards */ if (dir == SRCH_FORW) { curwp->w_doto = cbo; curwp->w_rflag |= WFMOVE; update(); } } is_prompt(dir, pptr < 0, success); break; case CCHR('H'): case CCHR('?'): is_undo(&pptr, &dir); if (is_peek() != SRCH_ACCM) success = TRUE; is_prompt(dir, pptr < 0, success); break; case CCHR('\\'): case CCHR('Q'): c = (char)getkey(FALSE); goto addchar; case CCHR('M'): c = CCHR('J'); goto addchar; default: if (ISCTRL(c)) { ungetkey(c); curwp->w_markp = clp; curwp->w_marko = cbo; curwp->w_markline = cdotline; ewprintf("Mark set"); curwp->w_rflag |= WFMOVE; return (TRUE); } /* FALLTHRU */ case CCHR('I'): case CCHR('J'): addchar: if (pptr == -1) pptr = 0; if (pptr == 0) success = TRUE; if (pptr == NPAT - 1) ttbeep(); else { pat[pptr++] = c; pat[pptr] = '\0'; } is_lpush(); if (success != FALSE) { if (is_find(dir) != FALSE) is_cpush(c); else { success = FALSE; ttbeep(); is_cpush(SRCH_ACCM); } } else is_cpush(SRCH_ACCM); is_prompt(dir, FALSE, success); } } /* NOTREACHED */ }