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

📄 input.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* input.c *//* Author: *	Steve Kirkendall *	14407 SW Teal Blvd. #C *	Beaverton, OR 97005 *	kirkenda@cs.pdx.edu *//* This file contains the input() function, which implements vi's INPUT mode. * It also contains the code that supports digraphs. */#include "config.h"#include "ctype.h"#include "vi.h"#ifndef NO_DIGRAPHstatic struct _DIG{	struct _DIG	*next;	char		key1;	char		key2;	char		dig;	char		save;} *digs;char digraph(key1, key2)	char	key1;	/* the underlying character */	char	key2;	/* the second character */{	int		newkey;	REG struct _DIG	*dp;	/* if digraphs are disabled, then just return the new char */	if (!*o_digraph)	{		return key2;	}	/* remember the new key, so we can return it if this isn't a digraph */	newkey = key2;	/* sort key1 and key2, so that their original order won't matter */	if (key1 > key2)	{		key2 = key1;		key1 = newkey;	}	/* scan through the digraph chart */	for (dp = digs;	     dp && (dp->key1 != key1 || dp->key2 != key2);	     dp = dp->next)	{	}	/* if this combination isn't in there, just use the new key */	if (!dp)	{		return newkey;	}	/* else use the digraph key */	return dp->dig;}/* this function lists or defines digraphs */void do_digraph(bang, extra)	int	bang;	char	extra[];{	int		dig;	REG struct _DIG	*dp;	struct _DIG	*prev;	static int	user_defined = FALSE; /* boolean: are all later digraphs user-defined? */	char		listbuf[8];	/* if "extra" is NULL, then we've reached the end of the built-ins */	if (!extra)	{		user_defined = TRUE;		return;	}	/* if no args, then display the existing digraphs */	if (*extra < ' ')	{		listbuf[0] = listbuf[1] = listbuf[2] = listbuf[5] = ' ';		listbuf[7] = '\0';		for (dig = 0, dp = digs; dp; dp = dp->next)		{			if (dp->save || bang)			{				dig += 7;				if (dig >= COLS)				{					addch('\n');					exrefresh();					dig = 7;				}				listbuf[3] = dp->key1;				listbuf[4] = dp->key2;				listbuf[6] = dp->dig;				qaddstr(listbuf);			}		}		addch('\n');		exrefresh();		return;	}	/* make sure we have at least two characters */	if (!extra[1])	{		msg("Digraphs must be composed of two characters");		return;	}	/* sort key1 and key2, so that their original order won't matter */	if (extra[0] > extra[1])	{		dig = extra[0];		extra[0] = extra[1];		extra[1] = dig;	}	/* locate the new digraph character */	for (dig = 2; extra[dig] == ' ' || extra[dig] == '\t'; dig++)	{	}	dig = extra[dig];	if (!bang && dig)	{		dig |= 0x80;	}	/* search for the digraph */	for (prev = (struct _DIG *)0, dp = digs;	     dp && (dp->key1 != extra[0] || dp->key2 != extra[1]);	     prev = dp, dp = dp->next)	{	}	/* deleting the digraph? */	if (!dig)	{		if (!dp)		{#ifndef CRUNCH			msg("%c%c not a digraph", extra[0], extra[1]);#endif			return;		}		if (prev)			prev->next = dp->next;		else			digs = dp->next;		free(dp);		return;	}	/* if necessary, create a new digraph struct for the new digraph */	if (dig && !dp)	{		dp = (struct _DIG *)malloc(sizeof *dp);		if (!dp)		{			msg("Out of space in the digraph table");			return;		}		if (prev)			prev->next = dp;		else			digs = dp;		dp->next = (struct _DIG *)0;	}	/* assign it the new digraph value */	dp->key1 = extra[0];	dp->key2 = extra[1];	dp->dig = dig;	dp->save = user_defined;}# ifndef NO_MKEXRCvoid savedigs(fd)	int		fd;{	static char	buf[] = "digraph! XX Y\n";	REG struct _DIG	*dp;	for (dp = digs; dp; dp = dp->next)	{		if (dp->save)		{			buf[9] = dp->key1;			buf[10] = dp->key2;			buf[12] = dp->dig;			write(fd, buf, (unsigned)14);		}	}}# endif#endif/* This function allows the user to replace an existing (possibly zero-length) * chunk of text with typed-in text.  It returns the MARK of the last character * that the user typed in. */MARK input(from, to, when, above)	MARK	from;	/* where to start inserting text */	MARK	to;	/* extent of text to delete */	int	when;	/* either WHEN_VIINP or WHEN_VIREP */	int	above;	/* boolean: take indentation from lower line? */{	char	key[2];	/* key char followed by '\0' char */	char	*build;	/* used in building a newline+indent string */	char	*scan;	/* used while looking at the indent chars of a line */	MARK	m;	/* some place in the text */#ifndef NO_EXTENSIONS	int	quit = FALSE;	/* boolean: are we exiting after this? */	int	inchg;	/* boolean: have we done a "beforedo()" yet? */#endif#ifdef DEBUG	/* if "from" and "to" are reversed, complain */	if (from > to)	{		msg("ERROR: input(%ld:%d, %ld:%d)",			markline(from), markidx(from),			markline(to), markidx(to));		return MARK_UNSET;	}#endif	key[1] = 0;	/* if we're replacing text with new text, save the old stuff */	/* (Alas, there is no easy way to save text for replace mode) */	if (from != to)	{		cut(from, to);	}	/* if doing a dot command, then reuse the previous text */	if (doingdot)	{		ChangeText		{			/* delete the text that's there now */			if (from != to)			{				delete(from, to);			}			/* insert the previous text */			cutname('.');			cursor = paste(from, FALSE, TRUE) + 1L;		}	}	else /* interactive version */	{		/* assume that whoever called this already did a beforedo() */#ifndef NO_EXTENSIONS		inchg = TRUE;#endif		/* if doing a change within the line... */		if (from != to && markline(from) == markline(to))		{			/* mark the end of the text with a "$" */			change(to - 1, to, "$");		}		else		{			/* delete the old text right off */			if (from != to)			{				delete(from, to);			}			to = from;		}		/* handle autoindent of the first line, maybe */		cursor = from;		m = (above ? (cursor + BLKSIZE) : (cursor - BLKSIZE));		if (*o_autoindent && markidx(m) == 0		 && markline(m) >= 1L && markline(m) <= nlines)		{			/* Only autoindent blank lines. */			pfetch(markline(cursor));			if (plen == 0)			{				/* Okay, we really want to autoindent */				pfetch(markline(m));				for (scan = ptext, build = tmpblk.c;				     *scan == ' ' || *scan == '\t';				     )				{					*build++ = *scan++;				}				if (build > tmpblk.c)				{					*build = '\0';					add(cursor, tmpblk.c);					cursor += (build - tmpblk.c);					if (cursor > to)						to = cursor;				}			}		}		/* repeatedly add characters from the user */		for (;;)		{			/* Get a character */			redraw(cursor, TRUE);#ifdef DEBUG2			msg("cursor=%ld.%d, to=%ld.%d",				markline(cursor), markidx(cursor),				markline(to), markidx(to));#endif#ifndef NO_ABBR			pfetch(markline(cursor));			build = ptext;			if (pline == markline(from))				build += markidx(from);			for (scan = ptext + markidx(cursor); --scan >= build && isalnum(*scan); )			{			}			scan++;			key[0] = getabkey(when, scan, (int)(ptext + markidx(cursor) - scan));#else			key[0] = getkey(when);#endif#ifndef NO_VISIBLE			if (key[0] != '\0' && V_from != MARK_UNSET)			{				msg("Can't modify text during a selection");				beep();				continue;			}#endif#ifndef NO_EXTENSIONS			if (key[0] == ctrl('O'))			{				if (inchg)				{					if (cursor < to)					{						delete(cursor, to);						redraw(cursor, TRUE);					}					afterdo();					inchg = FALSE;				}			}			else if (key[0] != ctrl('['))			{				if (!inchg)				{					beforedo(FALSE);					inchg = TRUE;				}			}#endif#ifndef CRUNCH			/* if wrapmargin is set & we're past the			 * warpmargin, then change the last whitespace			 * characters on line into a newline			 */			if (*o_wrapmargin != 0)			{				pfetch(markline(cursor));				if (idx2col(cursor, ptext, TRUE) > COLS - (*o_wrapmargin & 0xff))				{					build = tmpblk.c;					*build++ = '\n';					if (*o_autoindent)					{						/* figure out indent for next line */						for (scan = ptext; *scan == ' ' || *scan == '\t'; )						{							*build++ = *scan++;						}					}					*build = '\0';					scan = ptext + plen;					m = cursor & ~(BLKSIZE - 1);					while (ptext < scan)					{						scan--;						if (*scan != ' ' && *scan != '\t')							continue;						/*break up line, and we do autoindent if needed*/						change(m + (scan - ptext), m + (scan - ptext) + 1, tmpblk.c);						cursor = (cursor & ~(BLKSIZE - 1))							+ BLKSIZE							+ strlen(tmpblk.c) - 1							+ plen - (scan - ptext) - 1;						/*remove trailing spaces on previous line*/						pfetch(markline(m));						scan = ptext + plen;						while (ptext < scan)						{							scan--;							if (*scan != ' ' && *scan != '\t')								break;						}						delete(m + (scan-ptext) + 1, m + plen);						break;					}				}			}#endif /* !CRUNCH */			/* process it */

⌨️ 快捷键说明

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