📄 edstruct.c
字号:
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(wp) 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(row, col)int row,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(prompt) char *prompt; { register int s; char buf[64]; for (;;) { strcpy(buf, prompt); strcat(buf, " [y/n]? "); s = mlreply(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(prompt, buf, nbuf) 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(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(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. */#if ANSI_COMPILERgloble 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; }#else/* You can only pass mlwrite a maximum of 5 arguments reliably*/globle VOID mlwrite(fmt,arg1,arg2,arg3,arg4,arg5) char *fmt; double arg1,arg2,arg3,arg4,arg5; { register int c; register char *ap; movecursor(term.t_nrow, 0); ap = (char *) &arg1; while ((c = *fmt++) != 0) { if (c != '%') { (*term.t_putchar)(c); ++ttcol; } else { c = *fmt++; switch (c) { case 'd': mlputi(*(int *)ap, 10); ap += sizeof(int); break; case 'o': mlputi(*(int *)ap, 8); ap += sizeof(int); break; case 'x': mlputi(*(int *)ap, 16); ap += sizeof(int); break; case 'D': mlputli(*(long *)ap, 10); ap += sizeof(long); break; case 's': mlputs(*(char **)ap); ap += sizeof(char *); break; default: (*term.t_putchar)(c); ++ttcol; } } } (*term.t_eeol)(); (*term.t_flush)(); mpresf = TRUE; }#endif/* * 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. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -