sh.edit.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 3,065 行 · 第 1/4 页

C
3,065
字号
vadone:	*gcursor = 0;	Outchar = OO;	return (gcursor);}/* * Update line.  Output the line from cp to eol. */updateline(cp)	register char *cp;{	for (; *cp; )		exputchar(*cp++);}junk(c)	register int c;{	if (c >= ' ' && c != DELETE)		return (0);	switch (c) {	case '\t':	case '\n':	case '\f':		return (0);	default:		return (1);	}}/* * Vmaxrep determines the maximum repetitition factor * allowed that will yield total line length less than * LBSIZE characters. */vmaxrep(ch, cnt)	char ch;	register int cnt;{	register int len, replen;	if (cnt > LBSIZE - 2)		cnt = LBSIZE - 2;	replen = strlen(genbuf);	len = strlen(linebuf);	if (len + cnt * replen <= LBSIZE - 2)		return (cnt);	cnt = (LBSIZE - 2 - len) / replen;	if (cnt == 0) {		error("Line too long");	}	return (cnt);}/* * Clear to the end of the current physical line */vclreol(){	register int i;	int col;	if (CE) {		col = destcol;		vgoto(destcol,0);		vputp(CE, 1);		if (UP) {			for (i = col/COLUMNS +1; i <= markline; i++) {				vgoto(0,i);				vputp(CE, 1);			}			markline = strlen(linebuf)/COLUMNS;		}		return;	}	/*	 * No clear to end of line capability, so	 * calculate the number of blanks needed and put them out.	 */	vgoto(destcol,0);	for (i = markeol - strend(linebuf); i > 0; i--) {		exputchar(' ');	}	markeol = strend(linebuf);}/* * Gather up some more text from an insert. * If the insertion buffer oveflows, then destroy * the repeatability of the insert. */addtext(cp)	char *cp;{	if (vglobp)		return;	addto(INS, cp);	if (INS[0] == NULL)		lastcmd[0] = 0;}/* * Put text from cursor upto wcursor in BUF. * Used to put back deletes. */setBUF(BUF)	register char *BUF;{	register int c;	register char *wp = wcursor;	c = *wp;	*wp = 0;	BUF[0] = 0;	addto(BUF, cursor);	*wp = c;}addto(buf, str)	register char *buf, *str;{	if (strlen(buf) + strlen(str) + 1 >= VBSIZE) {		buf[0] = NULL;		return;	}	(void)strcat(buf, str);}/* * A complete command has been defined for * the purposes of repeat, so copy it from * the working to the previous command buffer. */setLAST(){	if (vglobp || vmacp)		return;	lasthad = Xhadcnt;	lastcnt = Xcnt;	*lastcp = 0;	CP(lastcmd, workcmd);}Copy(to, from, size)	register char *from, *to;	register int size;{	if (size > 0)		do			*to++ = *from++;		while (--size > 0);}/* * Find matching paren-like items: ({[ ]}). */lmatchp(){	register int i;	register char *parens, *cp;	for (cp = cursor; !any(*cp, "({[)}]");)		if (*cp++ == 0)			return (0);	parens = any(*cp, "()") ? "()" : any(*cp, "[]") ? "[]" : "{}";	if (*cp == parens[1]) {		dir = -1;	} else {		dir = 1;	}	wcursor = cp;	i = lskipbal(parens);	return (i);}/* * Find the matching paren-like object */lskipbal(parens)	register char *parens;{	register int level = dir;	register int c;	do {		if (!lnext()) {			return (0);		}		c = *wcursor;		if (c == parens[1])			level--;		else if (c == parens[0])			level++;	} while (level);	return (1);}/************************************************************* * Input routines. *************************************************************//* * Return the key. */ungetkey(c)	int c;{	if (Peekkey != ATTN)		Peekkey = c;}/* * Return a keystroke, but never a ^@. */getkey(){	register int c;	do {		c = getbr();		if (c==0)			beep();	} while (c == 0);	return (c);}jmp_buf	readbuf;int	doingread = 0;/* * Get a keystroke, including a ^@. * If a key was returned with ungetkey, that * comes back first.  Next comes unread input (e.g. * from repeating commands with .), and finally new * keystrokes. */getbr(){	char ch;	register int c;#define BEEHIVE#ifdef BEEHIVE	static char Peek2key;#endifgetATTN:	if (Peekkey) {		c = Peekkey;		Peekkey = 0;		return (c);	}#ifdef BEEHIVE	if (Peek2key) {		c = Peek2key;		Peek2key = 0;		return (c);	}#endif	if (vglobp) {		if (*vglobp)			return (lastvgk = *vglobp++);		lastvgk = 0;		return (ESCAPE);	}	if (vmacp) {		if (*vmacp)			return(*vmacp++);		/* End of a macro or set of nested macros */		vmacp = 0;	}	flusho();	if (setjmp(readbuf))		goto getATTN;	doingread = 1;	c = read(SHIN, &ch, 1);	doingread = 0;	if (c != 1) {		if (errno == EINTR)			goto getATTN;		error("Input read error");	}	c = ch & (QUOTE|TRIM);#ifdef BEEHIVE	if (XB && c == ESCAPE) {		if (read(SHIN, &Peek2key, 1) != 1)			goto getATTN;		Peek2key &= (QUOTE|TRIM);		switch (Peek2key) {		case 'C':	/* SPOW mode sometimes sends \EC for space */			c = ' ';			Peek2key = 0;			break;		case 'q':	/* f2 -> ^C */			c = CTRL(c);			Peek2key = 0;			break;		case 'p':	/* f1 -> esc */			Peek2key = 0;			break;		}	}#endif	lastvgk = 0;	return (c);}/* * Get a key, but if a delete, quit or attention * is typed return 0 so we will abort a partial command. */getesc(){	register int c;	c = getkey();	switch (c) {	case CTRL(v):	case CTRL(q):		c = getkey();		return (c);	case ATTN:	case QUIT:		ungetkey(c);		return (0);	case ESCAPE:		return (0);	}	return (c);}/* * Peek at the next keystroke. */peekkey(){	Peekkey = getkey();	return (Peekkey);}/* * Get a count from the keyed input stream. * A zero count is indistinguishable from no count. */vgetcnt(){	register int c, cnt;	cnt = 0;	for (;;) {		c = getkey();		if (!isdigit(c))			break;		cnt *= 10, cnt += c - '0';	}	ungetkey(c);	Xhadcnt = 1;	Xcnt = cnt;	return(cnt);}/* * fastpeekkey is just like peekkey but insists the character come in * fast (within 1 second). This will succeed if it is the 2nd char of * a machine generated sequence (such as a function pad from an escape * flavor terminal) but fail for a human hitting escape then waiting. */fastpeekkey(){	int trapalarm();	int (*Oint)();	register int c;	/*	 * We force this to die in 1 second.	 * This is pretty reliable (VMUNIX rounds it to .5 - 1.5 secs,	 * but due to system delays	 * there are times when arrow keys or very fast typing get counted	 * as separate.	 */	Oint = (int (*)())signal(SIGINT, trapalarm);	signal(SIGALRM, trapalarm);	alarm(1);	CATCH		c = peekkey();		alarm(0);	ONERR		c = 0;	ENDCATCH	signal(SIGINT,Oint);	return(c);}trapalarm() {	alarm(0);	if (vcatch)		longjmp(vreslab,1);}/************************************************************* * Terminal output and line formatting routines. *************************************************************//* * Format c for printing.  Handle funnies of upper case terminals * and crocky hazeltines which don't have ~. */normchar(c)	register short c;{	register char *colp;	c &= (QUOTE|TRIM);	if (c == '~' && HZ) {		normchar('\\');		c = '^';	}	if (c < ' ' && (c != '\b') || c == DELETE)		c = ' ';	else if (UPPERCASE)		if (isupper(c)) {			outchar('\\');			c = tolower(c);		} else {			colp = "({)}!|^~'`";			while (*colp++)				if (c == *colp++) {					outchar('\\');					c = colp[-2];					break;				}		}	outchar(c);}/* * Normal line output, no numbering. */normline(){	register char *cp;	for (cp = linebuf; *cp;)		exputchar(*cp++);}/* * The output buffer is initialized with a useful error * message so we don't have to keep it in data space. */static	char linb[66];char *exlinp = linb;/* * Indirect to current definition of putchar. */exputchar(c)	int c;{	(*Putchar)(c);}exflush(){	flush1();	flush2();}/* * Flush from small line buffer into output buffer. * Work here is destroying motion into positions, and then * letting fgoto do the optimized motion. */flush1(){	register char *lp;	register short c;	*exlinp = 0;	lp = linb;	while (*lp)		switch (c = *lp++) {		case '\r':			destcol = 0;			continue;		case '\b':			if (destcol)				destcol--;			continue;		case '\t':		case ' ':			destcol++;			continue;		case '\n':			destcol = 0;			continue;		default:			fgoto();			for (;;) {				if (AM == 0 && outcol == COLUMNS)					fgoto();				c &= (QUOTE|TRIM);				putch(c);				if (c == '\b') {					outcol--;					destcol--;				} else if (c >= ' ' && c != DELETE) {					outcol++;					destcol++;					if (outcol % COLUMNS == 0)						putch('\r'), putch('\n');				}				c = *lp++;				if (c <= ' ')					break;			}			--lp;			continue;		}	exlinp = linb;}flush2(){	fgoto();	flusho();}char	*obp = obuf;flusho(){	if (obp != obuf) {		write(SHOUT, obuf, obp - obuf);		obp = obuf;	}}putch(c)	int c;{	*obp++ = c & (QUOTE|TRIM);	if (obp >= &obuf[sizeof obuf])		flusho();}/* * Put with padding */putpad(cp)	char *cp;{	exflush();	tputs(cp, 0, putch);}/* * Insert character c at current cursor position. */vinschar(c)	int c;{	vputchar(c);}/* * Put the character c on the screen at the current cursor position. */vputchar(c)	register int c;{	c &= (QUOTE|TRIM);	if (destcol >= COLUMNS) {		if (UP) {			destline += destcol / COLUMNS;			destcol %= COLUMNS;		}	else		destcol = COLUMNS - 1;	}	switch (c) {	case '\t':		c = ' ';		/* fall into ... */	default:		if (outcol != destcol)			vgoto(destcol,destline);		vputc(c);		destcol++, outcol++;	}}/* * Put a character */vputch(c)	int c;{	vputc(c);}/************************************************************* * Cursor Motion Routines *************************************************************/vmove(){	vsetcurs(wcursor);}/* * Compute the column position implied by the cursor at ``nc'', * and move the cursor there. */vsetcurs(nc)	register char *nc;{	register int col;	col = column(nc);	vgoto(col,0);	cursor = nc;}column(cp)	char *cp;{	return(cp - linebuf);}/* * Move cursor to column x. */vgoto(x,y)	register int x,y;{	/*	 * Fold the possibly too large value of x.	 */	if (x >= COLUMNS) {		if (UP) {			y += x / COLUMNS;			x %= COLUMNS;		}		else			x = COLUMNS - 1;	}	destcol = x;	destline = y;	fgoto();}/* * Sync the position of the output cursor. */fgoto(){	if (destcol >= COLUMNS) {		if (UP) {			destline += destcol /COLUMNS;			destcol %= COLUMNS;		}		else			destcol = COLUMNS - 1;	}	plod(0);	outcol = destcol;	outline = destline;}/* * Move (slowly) to destination. * Just use character printing (move right), and backspace (move left). */static int plodcnt, plodflg;plodput(c){	if (plodflg)		plodcnt--;	else		putch(c);}plod(cnt){	register int c;	register int index;	plodcnt = plodflg = cnt;	/*	 * Move down, if necessary, to desired line	 */	if ((outline < destline) && UP) {		plodput('\r');		outcol = 0;		while (outline < destline) {			plodput('\n');			outline++;		}	}	/*	 * Move up, if necessary, to desired line	 */	while (outline > destline) {		outline--;		tputs(UP,0,plodput);	}	/*	 * Move left, if necessary, to desired column	 */	while (outcol > destcol) {		if (plodcnt < 0)			goto out;		outcol--;		if (BC)			tputs(BC, 0, plodput);		else			plodput('\b');	}	/*	 * Now move to the right, if necessary.	 */	index = outcol + outline * COLUMNS;	while (outcol < destcol) {		/*		 * Move one char to the right.  We only use ND space		 * if repositioning the cursor during insert and we can		 * have more than 80 chars (tty has upline (UP) capability).		 * Otherwise it's faster to just print the char we are		 * moving over.  There are various exceptions, however.		 * If the char is a null or a tab we want to print a space.		 * Other random chars we use space for instead, too.		 */		if ( (c=linebuf[index]) < ' ')			c = ' ';		if (insmode && UP && ND)			tputs(ND, 0, plodput);		else			plodput(c);		index++;		outcol++;		if (plodcnt < 0)			break;	}out:	return(plodcnt);}#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?