📄 term.c
字号:
eat_typeahead(){ if (!typeahead && nextin==nextout) { /* cancel only keyboard stuff */#ifdef PENDING while (input_pending()) read_tty(buf,sizeof(buf));#else /* this is probably v7 */# ifdef I_SGTTY ioctl(_tty_ch,TIOCSETP,&_tty);# else# ifdef I_TERMIO ioctl(_tty_ch,TCSETAW,&_tty);# else tcsetattr(_tty_ch,TCSAFLUSH,&_tty);# endif# endif#endif }}voidsave_typeahead(buf, len)char *buf;int len;{ int cnt; while (input_pending()) { cnt = read_tty(buf, len); buf += cnt; len -= cnt; } *buf = '\0';}voidsettle_down(){ dingaling(); fflush(stdout); /*sleep(1);*/ nextout = nextin; /* empty circlebuf */ eat_typeahead();}/* read a character from the terminal, with multi-character pushback */intread_tty(addr,size)char *addr;int size;{ if (nextout != nextin) { *addr = circlebuf[nextout++]; nextout %= PUSHSIZE; return 1; } else { size = read(0,addr,size);#ifdef RAWONLY *addr &= 0177;#endif return size; }}#ifdef PENDING# if !defined (FIONREAD) && !defined (HAS_RDCHK)intcircfill(){ register int Howmany; errno = 0; Howmany = read(devtty,circlebuf+nextin,1); if (Howmany < 0 && (errno == EAGAIN || errno == EINTR)) Howmany = 0; if (Howmany) { nextin += Howmany; nextin %= PUSHSIZE; } return Howmany;}# endif /* PENDING */#endif /* FIONREAD */voidpushchar(c)char_int c;{ nextout--; if (nextout < 0) nextout = PUSHSIZE - 1; if (nextout == nextin) { fputs("\npushback buffer overflow\n",stdout) FLUSH; sig_catcher(0); } circlebuf[nextout] = c;}/* print an underlined string, one way or another */voidunderprint(s)register char *s;{ assert(UC); if (*UC) { /* char by char underline? */ while (*s) { if (*(unsigned char *)s < ' ') { putchar('^'); backspace();/* back up over it */ underchar();/* and do the underline */ putchar(*s+64); backspace();/* back up over it */ underchar();/* and do the underline */ } else { putchar(*s); backspace();/* back up over it */ underchar();/* and do the underline */ } s++; } } else { /* start and stop underline */ underline(); /* start underlining */ while (*s) { if (*(unsigned char *)s < ' ') { putchar('^'); putchar(*s+64); } else putchar(*s); s++; } un_underline(); /* stop underlining */ }}/* keep screen from flashing strangely on magic cookie terminals */#ifdef NOFIREWORKSvoidno_sofire(){ if (*UP && *SE) { /* should we disable fireworks? */ putchar('\n'); un_standout(); up_line(); carriage_return(); }}voidno_ulfire(){ if (*UP && *US) { /* should we disable fireworks? */ putchar('\n'); un_underline(); up_line(); carriage_return(); }}#endif/* get a character into a buffer */voidgetcmd(whatbuf)register char *whatbuf;{ register KEYMAP *curmap; register int i; bool no_macros; int times = 0; /* loop detector */ char scrchar;tryagain: curmap = topmap; no_macros = (whatbuf != buf && nextin == nextout); for (;;) { int_count = 0; errno = 0; if (read_tty(whatbuf,1) < 0){ if (!errno) errno = EINTR; if (errno == EINTR) return; perror(readerr); sig_catcher(0); } lastchar = *whatbuf; if (*whatbuf & 0200 || no_macros) { *whatbuf &= 0177; goto got_canonical; } if (curmap == Null(KEYMAP*)) goto got_canonical; for (i = (curmap->km_type[*whatbuf] >> KM_GSHIFT) & KM_GMASK; i; --i){ read_tty(&scrchar,1); } switch (curmap->km_type[*whatbuf] & KM_TMASK) { case KM_NOTHIN: /* no entry? */ if (curmap == topmap) /* unmapped canonical */ goto got_canonical; settle_down(); goto tryagain; case KM_KEYMAP: /* another keymap? */ curmap = curmap->km_ptr[*whatbuf].km_km; assert(curmap != Null(KEYMAP*)); break; case KM_STRING: /* a string? */ pushstring(curmap->km_ptr[*whatbuf].km_str,0200); if (++times > 20) { /* loop? */ fputs("\nmacro loop?\n",stdout); settle_down(); } no_macros = FALSE; goto tryagain; } }got_canonical:#ifdef I_SGTTY if (*whatbuf == '\r') *whatbuf = '\n';#endif if (whatbuf == buf) whatbuf[1] = FINISHCMD; /* tell finish_command to work */}voidpushstring(str,bits)char *str;char_int bits;{ register int i; char tmpbuf[PUSHSIZE]; register char *s = tmpbuf; assert(str != Nullch); interp(tmpbuf,PUSHSIZE,str); for (i = strlen(s)-1; i >= 0; --i) pushchar(s[i] ^ bits);}intget_anything(){ char tmpbuf[2];reask_anything: unflush_output(); /* disable any ^O in effect */ standout();#ifdef VERBOSE IF(verbose) fputs("[Type space to continue] ",stdout); ELSE#endif#ifdef TERSE fputs("[MORE] ",stdout);#endif un_standout(); fflush(stdout); eat_typeahead(); if (int_count) { return -1; } cache_until_key(); getcmd(tmpbuf); if (errno || *tmpbuf == '\f') { putchar('\n') FLUSH; /* if return from stop signal */ goto reask_anything; /* give them a prompt again */ } if (*tmpbuf == 'h') {#ifdef VERBOSE IF(verbose) fputs("\nType q to quit or space to continue.\n",stdout) FLUSH; ELSE#endif#ifdef TERSE fputs("\nq to quit, space to continue.\n",stdout) FLUSH;#endif goto reask_anything; } else if (*tmpbuf != ' ' && *tmpbuf != '\n') { carriage_return(); erase_eol(); /* erase the prompt */ carriage_return(); return *tmpbuf == 'q' ? -1 : *tmpbuf; } if (*tmpbuf == '\n') { page_line = LINES - 1; carriage_return(); erase_eol(); carriage_return(); } else { page_line = 1; if (erase_screen) /* -e? */ clear(); /* clear screen */ else { carriage_return(); erase_eol(); /* erase the prompt */ carriage_return(); } } return 0;}intpause_getcmd(){ unflush_output(); /* disable any ^O in effect */ standout();#ifdef VERBOSE IF(verbose) fputs("[Type space or a command] ",stdout); ELSE#endif#ifdef TERSE fputs("[CMD] ",stdout);#endif un_standout(); fflush(stdout); eat_typeahead(); if (int_count) return -1; cache_until_key(); getcmd(buf); if (errno || *buf == '\f') return 0; /* if return from stop signal */ else if (*buf != ' ') { carriage_return(); erase_eol(); /* erase the prompt */ carriage_return(); return *buf; } return 0;}voidin_char(prompt, newmode)char *prompt;char_int newmode;{ char oldmode = mode;reask_in_char: unflush_output(); /* disable any ^O in effect */ fputs(prompt,stdout); fflush(stdout); eat_typeahead(); mode = newmode; getcmd(buf); if (errno || *buf == '\f') { putchar('\n') FLUSH; /* if return from stop signal */ goto reask_in_char; /* give them a prompt again */ } mode = oldmode;}voidin_answer(prompt, newmode)char *prompt;char_int newmode;{ char oldmode = mode;reask_in_answer: unflush_output(); /* disable any ^O in effect */ fputs(prompt,stdout); fflush(stdout); eat_typeahead(); mode = newmode;reinp_in_answer: getcmd(buf); if (errno || *buf == '\f') { putchar('\n') FLUSH; /* if return from stop signal */ goto reask_in_answer; /* give them a prompt again */ } if (!finish_command(TRUE)) goto reinp_in_answer; mode = oldmode;}intprint_lines(what_to_print,hilite)char *what_to_print;int hilite;{ register char *s; register int i; if (page_line < 0) /* they do not want to see this? */ return -1; for (s=what_to_print; *s; ) { if (page_line >= LINES || int_count) { if (i = -1, int_count || (i = get_anything())) { page_line = -1; /* disable further print_lines */ return i; } } page_line++; if (hilite == STANDOUT) {#ifdef NOFIREWORKS if (erase_screen) no_sofire();#endif standout(); } else if (hilite == UNDERLINE) {#ifdef NOFIREWORKS if (erase_screen) no_ulfire();#endif underline(); } for (i=0; i<COLS; i++) { if (!*s) break; if (*(unsigned char *)s >= ' ') putchar(*s); else if (*s == '\t') { putchar(*s); i = ((i+8) & ~7) - 1; } else if (*s == '\n') { i = 32000; } else { i++; putchar('^'); putchar(*s + 64); } s++; } if (i) { if (hilite == STANDOUT) un_standout(); else if (hilite == UNDERLINE) un_underline(); if (AM && i == COLS) fflush(stdout); else putchar('\n') FLUSH; } } return 0;}voidpage_init(){ page_line = 1; if (erase_screen) clear(); else putchar('\n') FLUSH;}voidpad(num)int num;{ register int i; for (i = num; i; --i) putchar(PC); fflush(stdout);}/* echo the command just typed */#ifdef VERIFYvoidprintcmd(){ if (verify && buf[1] == FINISHCMD) { if (*(unsigned char *)buf < ' ') { putchar('^'); putchar(*buf | 64); backspace(); backspace(); } else { putchar(*buf); backspace(); } fflush(stdout); }}#endifvoidrubout(){ backspace(); /* do the old backspace, */ putchar(' '); /* space, */ backspace(); /* backspace trick */}voidreprint(){ register char *s; fputs("^R\n",stdout) FLUSH; for (s = buf; *s; s++) { if (*(unsigned char *)s < ' ') { putchar('^'); putchar(*s | 64); } else putchar(*s); }}voidhome_cursor(){ char *tgoto(); if (!*HO) { /* no home sequence? */ if (!*CM) { /* no cursor motion either? */ fputs ("\n\n\n", stdout); return; /* forget it. */ } tputs (tgoto (CM, 0, 0), 1, putchr); /* go to home via CM */ return; } else { /* we have home sequence */ tputs (HO, 1, putchr); /* home via HO */ }}voidgoto_line(from,to) /* assumes caller is already at beginning of line */int from,to;{ char *tgoto(), *str; int cmcost; if (from == to) return; if (*CM && !muck_up_clear) cmcost = strlen(str = tgoto(CM,0,to)); else cmcost = 9999; if (to > from) { go_down: if (to - from <= cmcost) { while(from++ < to) putchar('\n'); return; } } else if(*UP) { if ((from - to) * upcost <= cmcost) { while(from-- > to) tputs(UP,1,putchr); return; } } else if (cmcost == 9999) { home_cursor(); from = 0; goto go_down; } tputs(str,1,putchr);}voidline_col_calcs(){ if (LINES > 0) { /* is this a crt? */ if ((!initlines) || (!initlines_specified)) /* no -i or unreasonable value for initlines */ if (outspeed >= B9600) /* whole page at >= 9600 baud */ initlines = LINES; else if (outspeed >= B4800)/* 16 lines at 4800 */ initlines = 16; else /* otherwise just header */ initlines = 8; } else { /* not a crt */ LINES = 30000; /* so don't page */ CL = "\n\n"; /* put a couple of lines between */ if ((!initlines) || (!initlines_specified)) /* make initlines reasonable */ initlines = 8; } if (COLS <= 0) COLS = 80;}#ifdef SIGWINCHSignal_twinch_catcher(dummy)int dummy;{ /* Reset signal in case of System V dain bramage */ sigset(SIGWINCH, winch_catcher); /* Come here if window size change signal received */#ifdef TIOCGWINSZ { struct winsize ws; if (ioctl(0, TIOCGWINSZ, &ws) >= 0 && ws.ws_row > 0 && ws.ws_col > 0) { LINES = ws.ws_row; COLS = ws.ws_col; line_col_calcs(); } }#else /* Well, if SIGWINCH is defined, but TIOCGWINSZ isn't, there's */ /* almost certainly something wrong. Figure it out for yourself, */ /* because I don't know now to deal :-) */#endif}#endifvoidtermlib_init(){#ifdef USETITE if (TI && *TI) tputs (TI,1,putchr);#endif return;}voidtermlib_reset(){#ifdef USETITE if (TE && *TE) tputs (TE,1,putchr);#endif return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -