📄 edstruct.c
字号:
register char *cp4; register char *cp5; register int nbflag; cp1 = &vline[0]; /* Compute left match. */ cp2 = &pline[0]; while (cp1!=&vline[term.t_ncol] && cp1[0]==cp2[0]) { ++cp1; ++cp2; } /* This can still happen, even though we only call this routine on changed * lines. A hard update is always done when a line splits, a massive * change is done, or a buffer is displayed twice. This optimizes out most * of the excess updating. A lot of computes are used, but these tend to * be hard operations that do a lot of update, so I don't really care. */ if (cp1 == &vline[term.t_ncol]) /* All equal. */ return; nbflag = FALSE; cp3 = &vline[term.t_ncol]; /* Compute right match. */ cp4 = &pline[term.t_ncol]; while (cp3[-1] == cp4[-1]) { --cp3; --cp4; if (cp3[0] != ' ') /* Note if any nonblank */ nbflag = TRUE; /* in right match. */ } cp5 = cp3; if (nbflag == FALSE) /* Erase to EOL ? */ { while (cp5!=cp1 && cp5[-1]==' ') --cp5; if (cp3-cp5 <= 3) /* Use only if erase is */ cp5 = cp3; /* fewer characters. */ } movecursor(row, (int) (cp1-&vline[0])); /* Go to start of line. */ while (cp1 != cp5) /* Ordinary. */ { (*term.t_putchar)(*cp1); ++ttcol; *cp2++ = *cp1++; } if (cp5 != cp3) /* Erase. */ { (*term.t_eeol)(); while (cp1 != cp3) *cp2++ = *cp1++; }}/* * Redisplay the mode line for the window pointed to by the "wp". This is the * only routine that has any idea of how the modeline is formatted. You can * change the modeline format by hacking at this routine. Called by "update" * any time there is a dirty window. */globle void modeline( WINDOW *wp){ register char *cp; register int c; register int n; register BUFFER *bp; n = wp->w_toprow+wp->w_ntrows; /* Location. */ vscreen[n]->v_flag |= VFCHG; /* Redraw next time. */ vtmove(n, 0); /* Seek to right line. */ vtputc('-'); bp = wp->w_bufp; if ((bp->b_flag&BFCHG) != 0) /* "*" if changed. */ vtputc('*'); else vtputc('-'); n = 2; cp = " MicroEMACS -- "; while ((c = *cp++) != 0) { vtputc(c); ++n; } cp = &bp->b_bname[0]; while ((c = *cp++) != 0) { vtputc(c); ++n; } vtputc(' '); ++n; if (bp->b_fname[0] != 0) /* File name. */ { cp = "-- File: "; while ((c = *cp++) != 0) { vtputc(c); ++n; } cp = &bp->b_fname[0]; while ((c = *cp++) != 0) { vtputc(c); ++n; } vtputc(' '); ++n; }#if WFDEBUG vtputc('-'); vtputc((wp->w_flag&WFMODE)!=0 ? 'M' : '-'); vtputc((wp->w_flag&WFHARD)!=0 ? 'H' : '-'); vtputc((wp->w_flag&WFEDIT)!=0 ? 'E' : '-'); vtputc((wp->w_flag&WFMOVE)!=0 ? 'V' : '-'); vtputc((wp->w_flag&WFFORCE)!=0 ? 'F' : '-'); n += 6;#endif while (n < term.t_ncol) /* Pad to full width. */ { vtputc('-'); ++n; }}/* * Send a command to the terminal to move the hardware cursor to row "row" * and column "col". The row and column arguments are origin 0. Optimize out * random calls. Update "ttrow" and "ttcol". */globle void movecursor(int row,int col) { if (row!=ttrow || col!=ttcol) { ttrow = row; ttcol = col; (*term.t_move)(row, col); } }/* * Erase the message line. This is a special routine because the message line * is not considered to be part of the virtual screen. It always works * immediately; the terminal buffer is flushed via a call to the flusher. */globle void mlerase() { movecursor(term.t_nrow, 0); (*term.t_eeol)(); (*term.t_flush)(); mpresf = FALSE; }/* * Ask a yes or no question in the message line. Return either TRUE, FALSE, or * ABORT. The ABORT status is returned if the user bumps out of the question * with a ^G. Used any time a confirmation is required. */globle int mlyesno( void *theEnv, char *prompt) { register int s; char buf[64]; for (;;) { genstrcpy(buf, prompt); genstrcat(buf, " [y/n]? "); s = mlreply(theEnv,buf, buf, sizeof(buf)); if (s == ABORT) return (ABORT); if (s != FALSE) { if (buf[0]=='y' || buf[0]=='Y') return (TRUE); if (buf[0]=='n' || buf[0]=='N') return (FALSE); } } }/* * Write a prompt into the message line, then read back a response. Keep * track of the physical position of the cursor. If we are in a keyboard * macro throw the prompt away, and return the remembered response. This * lets macros run at full speed. The reply is always terminated by a * carriage return. Handle erase, kill, and abort keys. */globle int mlreply( void *theEnv, char *prompt, char *buf, int nbuf) { register int cpos; register int i; register int c; cpos = 0; if (kbdmop != NULL) { while ((c = *kbdmop++) != '\0') buf[cpos++] = (char) c; buf[cpos] = 0; if (buf[0] == 0) return (FALSE); return (TRUE); } mlwrite(prompt); for (;;) { c = (*term.t_getchar)(); switch (c) { case 0x0D: /* Return, end of line */ buf[cpos++] = 0; if (kbdmip != NULL) { if (kbdmip+cpos > &kbdm[NKBDM-3]) { ctrlg(theEnv,FALSE, 0); (*term.t_flush)(); return (ABORT); } for (i=0; i<cpos; ++i) *kbdmip++ = buf[i]; } (*term.t_putchar)('\r'); ttcol = 0; (*term.t_flush)(); if (buf[0] == 0) return (FALSE); return (TRUE); case 0x07: /* Bell, abort */ (*term.t_putchar)('^'); (*term.t_putchar)('G'); ttcol += 2; ctrlg(theEnv,FALSE, 0); (*term.t_flush)(); return (ABORT); case 0x7F: /* Rubout, erase */ case 0x08: /* Backspace, erase */ if (cpos != 0) { (*term.t_putchar)('\b'); (*term.t_putchar)(' '); (*term.t_putchar)('\b'); --ttcol; if (buf[--cpos] < 0x20) { (*term.t_putchar)('\b'); (*term.t_putchar)(' '); (*term.t_putchar)('\b'); --ttcol; } (*term.t_flush)(); } break; case 0x15: /* C-U, kill */ while (cpos != 0) { (*term.t_putchar)('\b'); (*term.t_putchar)(' '); (*term.t_putchar)('\b'); --ttcol; if (buf[--cpos] < 0x20) { (*term.t_putchar)('\b'); (*term.t_putchar)(' '); (*term.t_putchar)('\b'); --ttcol; } } (*term.t_flush)(); break; default: if (cpos < nbuf-1) { buf[cpos++] = (char) c; if (c < ' ') { (*term.t_putchar)('^'); ++ttcol; c ^= 0x40; } (*term.t_putchar)(c); ++ttcol; (*term.t_flush)(); } } } }/* * Write a message into the message line. Keep track of the physical cursor * position. A small class of printf like format items is handled. Assumes the * stack grows down; this assumption is made by the "++" in the argument scan * loop. Set the "message line" flag TRUE. */globle void mlwrite(char *fmt,...) { register int c; va_list ap; movecursor(term.t_nrow, 0); va_start(ap,fmt); while ((c = *fmt++) != 0) { if (c != '%') { (*term.t_putchar)(c); ++ttcol; } else { c = *fmt++; switch (c) { case 'd': mlputi(va_arg(ap,int), 10); break; case 'o': mlputi(va_arg(ap,int), 8); break; case 'x': mlputi(va_arg(ap,int), 16); break; case 'D': mlputli(va_arg(ap,long), 10); break; case 's': mlputs(va_arg(ap,char *)); break; default: (*term.t_putchar)(c); ++ttcol; } } } va_end(ap); (*term.t_eeol)(); (*term.t_flush)(); mpresf = TRUE; }/* * Write out a string. Update the physical cursor position. This assumes that * the characters in the string all have width "1"; if this is not the case * things will get screwed up a little. */globle void mlputs( char *s) { register int c; while ((c = *s++) != 0) { (*term.t_putchar)(c); ++ttcol; } }/* * Write out an integer, in the specified radix. Update the physical cursor * position. This will not handle any negative numbers; maybe it should. */gl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -