⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tio.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* tio.c *//* Author: *	Steve Kirkendall *	14407 SW Teal Blvd. #C *	Beaverton, OR 97005 *	kirkenda@cs.pdx.edu *//* This file contains terminal I/O functions */#include "config.h"#include "vi.h"#include "ctype.h"/* This function reads in a line from the terminal. */int vgets(prompt, buf, bsize)	char	prompt;	/* the prompt character, or '\0' for none */	char	*buf;	/* buffer into which the string is read */	int	bsize;	/* size of the buffer */{	int	len;	/* how much we've read so far */	int	ch;	/* a character from the user */	int	quoted;	/* is the next char quoted? */	int	tab;	/* column position of cursor */	char	widths[132];	/* widths of characters */	int	word;	/* index of first letter of word */#ifndef NO_DIGRAPH	int	erased;	/* 0, or first char of a digraph */#endif	/* show the prompt */	move(LINES - 1, 0);	tab = 0;	if (prompt)	{		addch(prompt);		tab = 1;	}	clrtoeol();	refresh();	/* read in the line */#ifndef NO_DIGRAPH	erased =#endif	quoted = len = 0;	for (;;)	{#ifndef NO_ABBR		if (quoted || mode == MODE_EX)		{			ch = getkey(0);		}		else		{			/* maybe expand an abbreviation while getting key */			for (word = len; --word >= 0 && isalnum(buf[word]); )			{			}			word++;			ch = getabkey(WHEN_EX, &buf[word], len - word);		}#else		ch = getkey(0);#endif#ifndef NO_EXTENSIONS		if (ch == ctrl('O'))		{			ch = getkey(quoted ? 0 : WHEN_EX);		}#endif		/* some special conversions */		if (ch == ctrl('D') && len == 0)			ch = ctrl('[');#ifndef NO_DIGRAPH		if (*o_digraph && erased != 0 && ch != '\b')		{			ch = digraph(erased, ch);			erased = 0;		}#endif		/* inhibit detection of special chars (except ^J) after a ^V */		if (quoted && ch != '\n')		{			ch |= 256;		}		/* process the character */		switch(ch)		{		  case ctrl('V'):			qaddch('^');			qaddch('\b');			quoted = TRUE;			break;		  case ctrl('['):			return -1;		  case '\n':#if OSK		  case '\l':#else		  case '\r':#endif			clrtoeol();			goto BreakBreak;		  case '\b':			if (len > 0)			{				len--;#ifndef NO_DIGRAPH				erased = buf[len];#endif				for (ch = widths[len]; ch > 0; ch--)					addch('\b');				if (mode == MODE_EX)				{					clrtoeol();				}				tab -= widths[len];			}			else			{				return -1;			}			break;		  default:			/* strip off quotation bit */			if (ch & 256)			{				ch &= ~256;				qaddch(' ');				qaddch('\b');			}			/* add & echo the char */			if (len < bsize - 1)			{				if (ch == '\t' && !quoted)				{					widths[len] = *o_tabstop - (tab % *o_tabstop);					addstr("        " + 8 - widths[len]);					tab += widths[len];				}				else if (ch > 0 && ch < ' ') /* > 0 by GB */				{					addch('^');					addch(ch + '@');					widths[len] = 2;					tab += 2;				}				else if (ch == '\177')				{					addch('^');					addch('?');					widths[len] = 2;					tab += 2;				}				else				{					addch(ch);					widths[len] = 1;					tab++;				}				buf[len++] = ch;			}			else			{				beep();			}			quoted = FALSE;		}	}BreakBreak:	refresh();	buf[len] = '\0';	return len;}static int	manymsgs; /* This variable keeps msgs from overwriting each other */static char	pmsg[80]; /* previous message (waiting to be displayed) */static int showmsg(){	/* if there is no message to show, then don't */	if (!manymsgs)		return FALSE;	/* display the message */	move(LINES - 1, 0);	if (*pmsg)	{		standout();		qaddch(' ');		qaddstr(pmsg);		qaddch(' ');		standend();	}	clrtoeol();	manymsgs = FALSE;	return TRUE;}void endmsgs(){	if (manymsgs)	{		showmsg();		addch('\n');	}}/* Write a message in an appropriate way.  This should really be a varargs * function, but there is no such thing as vwprintw.  Hack!!! * * In MODE_EX or MODE_COLON, the message is written immediately, with a * newline at the end. * * In MODE_VI, the message is stored in a character buffer.  It is not * displayed until getkey() is called.  msg() will call getkey() itself, * if necessary, to prevent messages from being lost. * * msg("")		- clears the message line * msg("%s %d", ...)	- does a printf onto the message line *//*VARARGS1*/void msg(fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7)	char	*fmt;	long	arg1, arg2, arg3, arg4, arg5, arg6, arg7;{	if (mode != MODE_VI)	{		sprintf(pmsg, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7);		qaddstr(pmsg);		addch('\n');		exrefresh();	}	else	{		/* wait for keypress between consecutive msgs */		if (manymsgs)		{			getkey(WHEN_MSG);		}		/* real message */		sprintf(pmsg, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7);		if (*fmt)		{			manymsgs = TRUE;		}	}}/* This function calls refresh() if the option exrefresh is set */void exrefresh(){	char	*scan;	/* If this ex command wrote ANYTHING set exwrote so vi's  :  command	 * can tell that it must wait for a user keystroke before redrawing.	 */	for (scan=kbuf; scan<stdscr; scan++)		if (*scan == '\n')			exwrote = TRUE;	/* now we do the refresh thing */	if (*o_exrefresh)	{		refresh();	}	else	{		wqrefresh();	}	if (mode != MODE_VI)	{		manymsgs = FALSE;	}}/* This structure is used to store maps and abbreviations.  The distinction * between them is that maps are stored in the list referenced by the "maps" * pointer, while abbreviations are referenced by the "abbrs" pointer. */typedef struct _map{	struct _map	*next;	/* another abbreviation */	short		len;	/* length of the "rawin" characters */	short		flags;	/* various flags */	char		*label;	/* label of the map/abbr, or NULL */	char		*rawin;	/* the "rawin" characters */	char		*cooked;/* the "cooked" characters */} MAP;static char	keybuf[KEYBUFSIZE];static int	cend;	/* end of input characters */static int	user;	/* from user through end are chars typed by user */static int	next;	/* index of the next character to be returned */static MAP	*match;	/* the matching map, found by countmatch() */static MAP	*maps;	/* the map table */#ifndef NO_ABBRstatic MAP	*abbrs;	/* the abbreviation table */#endif/* ring the terminal's bell */void beep(){	/* do a visible/audible bell */	if (*o_flash)	{		do_VB();		refresh();	}	else if (*o_errorbells)	{		ttywrite("\007", 1);	}	/* discard any buffered input, and abort macros */	next = user = cend;}/* This function replaces a "rawin" character sequence with the "cooked" version, * by modifying the internal type-ahead buffer. */void execmap(rawlen, cookedstr, visual)	int	rawlen;		/* length of rawin text -- string to delete */	char	*cookedstr;	/* the cooked text -- string to insert */	int	visual;		/* boolean -- chars to be executed in visual mode? */{	int	cookedlen;	char	*src, *dst;	int	i;	/* find the length of the cooked string */	cookedlen = strlen(cookedstr);#ifndef NO_EXTENSIONS	if (visual)	{		cookedlen *= 2;	}#endif	/* if too big to fit in type-ahead buffer, then don't do it */	if (cookedlen + (cend - next) - rawlen > KEYBUFSIZE)	{		return;	}	/* shift to make room for cookedstr at the front of keybuf */	src = &keybuf[next + rawlen];	dst = &keybuf[cookedlen];	i = cend - (next + rawlen);	if (src >= dst)	{		while (i-- > 0)		{			*dst++ = *src++;		}	}	else	{		src += i;		dst += i;		while (i-- > 0)		{			*--dst = *--src;		}	}	/* insert cookedstr, and adjust offsets */	cend += cookedlen - rawlen - next;	user += cookedlen - rawlen - next;	next = 0;	for (dst = keybuf, src = cookedstr; *src; )	{#ifndef NO_EXTENSIONS		if (visual)		{			*dst++ = ctrl('O');			cookedlen--;		}#endif		*dst++ = *src++;	}#ifdef DEBUG2	{#include <stdio.h>		FILE	*debout;		int		i;		debout = fopen("debug.out", "a");		fprintf(debout, "After execmap(%d, \"%s\", %d)...\n", rawlen, cookedstr, visual);		for (i = 0; i < cend; i++)		{			if (i == next) fprintf(debout, "(next)");			if (i == user) fprintf(debout, "(user)");			if (UCHAR(keybuf[i]) < ' ')				fprintf(debout, "^%c", keybuf[i] ^ '@');			else				fprintf(debout, "%c", keybuf[i]);		}		fprintf(debout, "(end)\n");		fclose(debout);	}#endif}/* This function calls ttyread().  If necessary, it will also redraw the screen, * change the cursor shape, display the mode, and update the ruler.  If the * number of characters read is 0, and we didn't time-out, then it exits because * we've apparently reached the end of an EX script. */static int fillkeybuf(when, timeout)	int	when;	/* mixture of WHEN_XXX flags */	int	timeout;/* timeout in 1/10 second increments, or 0 */{	int	nkeys;#ifndef NO_SHOWMODE	static int	oldwhen;	/* "when" from last time */	static int	oldleft;	static long	oldtop;	static long	oldnlines;	char		*str;#endif#ifndef NO_CURSORSHAPE	static int	oldcurs;#endif#ifdef DEBUG	watch();#endif#ifndef NO_CURSORSHAPE	/* make sure the cursor is the right shape */	if (has_CQ)	{		if (when != oldcurs)		{			switch (when)			{			  case WHEN_EX:		do_CX();	break;			  case WHEN_VICMD:	do_CV();	break;			  case WHEN_VIINP:	do_CI();	break;			  case WHEN_VIREP:	do_CR();	break;			}			oldcurs = when;		}	}#endif#ifndef NO_SHOWMODE	/* if "showmode" then say which mode we're in */	if (*o_smd && (when & WHENMASK))	{		/* redraw the screen before we check to see whether the		 * "showmode" message needs to be redrawn.		 */		redraw(cursor, !(when & WHEN_VICMD));		/* now the "topline" test should be valid */		if (when != oldwhen || topline != oldtop || leftcol != oldleft || nlines != oldnlines)		{			oldwhen = when;			oldtop = topline;			oldleft = leftcol;			oldnlines = nlines;			if (when & WHEN_VICMD)	    str = "Command";			else if (when & WHEN_VIINP) str = " Input ";			else if (when & WHEN_VIREP) str = "Replace";			else if (when & WHEN_REP1)  str = " Rep 1 ";			else if (when & WHEN_CUT)   str = "BufName";			else if (when & WHEN_MARK)  str = "Mark AZ";			else if (when & WHEN_CHAR)  str = "Dest Ch";			else			    str = (char *)0;			if (str)			{				move(LINES - 1, COLS - 10);				standout();				qaddstr(str);				standend();			}		}	}#endif#ifndef NO_EXTENSIONS	/* maybe display the ruler */	if (*o_ruler && (when & (WHEN_VICMD|WHEN_VIINP|WHEN_VIREP)))	{		char	buf[20];

⌨️ 快捷键说明

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