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

📄 v_text.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
 *	Change line command. */intv_Change(sp, ep, vp)	SCR *sp;	EXF *ep;	VICMDARG *vp;{	return (v_CS(sp, ep, vp, 0));}/* * v_Subst -- [buffer][count]S *	Line substitute command. */intv_Subst(sp, ep, vp)	SCR *sp;	EXF *ep;	VICMDARG *vp;{	u_int flags;	/*	 * The S command is the same as a 'C' command from the beginning	 * of the line.  This is hard to do in the parser, so do it here.	 *	 * If autoindent is on, the change is from the first *non-blank*	 * character of the line, not the first character.  And, to make	 * it just a bit more exciting, the initial space is handled as	 * auto-indent characters.	 */	LF_INIT(0);	if (O_ISSET(sp, O_AUTOINDENT)) {		vp->m_start.cno = 0;		if (nonblank(sp, ep, vp->m_start.lno, &vp->m_start.cno))			return (1);		LF_SET(TXT_AICHARS);	} else		vp->m_start.cno = 0;	sp->cno = vp->m_start.cno;	return (v_CS(sp, ep, vp, flags));}/* * v_CS -- *	C and S commands. */static intv_CS(sp, ep, vp, iflags)	SCR *sp;	EXF *ep;	VICMDARG *vp;	u_int iflags;{	MARK *tm;	recno_t lno;	size_t len;	char *p;	u_int flags;	flags = set_txt_std(sp, vp, iflags);	/*	 * There are two cases -- if a count is supplied, we do a line	 * mode change where we delete the lines and then insert text	 * into a new line.  Otherwise, we replace the current line.	 */	vp->m_stop.lno =	    vp->m_start.lno + (F_ISSET(vp, VC_C1SET) ? vp->count - 1 : 0);	if (vp->m_start.lno != vp->m_stop.lno) {		/* Make sure that the to line is real. */		if (file_gline(sp, ep,		    vp->m_stop.lno, &vp->m_stop.cno) == NULL) {			v_eof(sp, ep, &vp->m_start);			return (1);		}		if (vp->m_stop.cno != 0)			--vp->m_stop.cno;		/* Cut the lines. */		if (cut(sp, ep,		    NULL, F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,		    &vp->m_start, &vp->m_stop, CUT_LINEMODE))			return (1);		/* Insert a line while we still can... */		if (file_iline(sp, ep, vp->m_start.lno, "", 0))			return (1);		++vp->m_start.lno;		++vp->m_stop.lno;		/* Delete the lines. */		if (delete(sp, ep, &vp->m_start, &vp->m_stop, 1))			return (1);		/* Get the inserted line. */		if ((p = file_gline(sp, ep, --vp->m_start.lno, &len)) == NULL) {			GETLINE_ERR(sp, vp->m_start.lno);			return (1);		}		tm = NULL;		sp->lno = vp->m_start.lno;		sp->cno = 0;		LF_SET(TXT_APPENDEOL);	} else {		/* The line may be empty, but that's okay. */		if ((p = file_gline(sp, ep, vp->m_start.lno, &len)) == NULL) {			if (file_lline(sp, ep, &lno))				return (1);			if (lno != 0) {				GETLINE_ERR(sp, vp->m_start.lno);				return (1);			}			vp->m_stop.cno = len = 0;			LF_SET(TXT_APPENDEOL);		} else {			if (len == 0) {				vp->m_stop.cno = 0;				LF_SET(TXT_APPENDEOL);			} else				vp->m_stop.cno = len - 1;			if (cut(sp, ep,			    NULL, F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,			    &vp->m_start, &vp->m_stop, CUT_LINEMODE))				return (1);			LF_SET(TXT_EMARK | TXT_OVERWRITE);		}		tm = &vp->m_stop;	}	/* Correct logging for implied cursor motion. */	LOG_CORRECT;	return (v_ntext(sp, ep,	    sp->tiqp, tm, p, len, &vp->m_final, 0, OOBLNO, flags));}/* * v_change -- [buffer][count]c[count]motion *	Change command. */intv_change(sp, ep, vp)	SCR *sp;	EXF *ep;	VICMDARG *vp;{	recno_t lno;	size_t blen, len;	u_int flags;	int lmode, rval;	char *bp, *p;	flags = set_txt_std(sp, vp, 0);	/*	 * Move the cursor to the start of the change.  Note, if autoindent	 * is turned on, the cc command in line mode changes from the first	 * *non-blank* character of the line, not the first character.  And,	 * to make it just a bit more exciting, the initial space is handled	 * as auto-indent characters.	 */	lmode = F_ISSET(vp, VM_LMODE) ? CUT_LINEMODE : 0;	if (lmode) {		vp->m_start.cno = 0;		if (O_ISSET(sp, O_AUTOINDENT)) {			if (nonblank(sp, ep, vp->m_start.lno, &vp->m_start.cno))				return (1);			LF_SET(TXT_AICHARS);		}	}	sp->lno = vp->m_start.lno;	sp->cno = vp->m_start.cno;	/* Correct logging for implied cursor motion. */	LOG_CORRECT;	/*	 * If changing within a single line, the line either currently has	 * text or it doesn't.  If it doesn't, just insert text.  Otherwise,	 * copy it and overwrite it.	 */	if (vp->m_start.lno == vp->m_stop.lno) {		if ((p = file_gline(sp, ep, vp->m_start.lno, &len)) == NULL) {			if (p == NULL) {				if (file_lline(sp, ep, &lno))					return (1);				if (lno != 0) {					GETLINE_ERR(sp, vp->m_start.lno);					return (1);				}			}			vp->m_stop.cno = len = 0;			LF_SET(TXT_APPENDEOL);		} else {			if (cut(sp, ep,			    NULL, F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,			    &vp->m_start, &vp->m_stop, lmode))				return (1);			if (len == 0)				LF_SET(TXT_APPENDEOL);			LF_SET(TXT_EMARK | TXT_OVERWRITE);		}		return (v_ntext(sp, ep, sp->tiqp,		    &vp->m_stop, p, len, &vp->m_final, 0, OOBLNO, flags));	}	/*	 * It's trickier if changing over multiple lines.  If we're in	 * line mode we delete all of the lines and insert a replacement	 * line which the user edits.  If there was leading whitespace	 * in the first line being changed, we copy it and use it as the	 * replacement.  If we're not in line mode, we just delete the	 * text and start inserting.	 *	 * Copy the text.	 */	if (cut(sp, ep, NULL, F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,	    &vp->m_start, &vp->m_stop, lmode))		return (1);	/* If replacing entire lines and there's leading text. */	if (lmode && vp->m_start.cno) {		/* Get a copy of the first line changed. */		if ((p = file_gline(sp, ep, vp->m_start.lno, &len)) == NULL) {			GETLINE_ERR(sp, vp->m_start.lno);			return (1);		}		/* Copy the leading text elsewhere. */		GET_SPACE_RET(sp, bp, blen, vp->m_start.cno);		memmove(bp, p, vp->m_start.cno);	} else		bp = NULL;	/* Delete the text. */	if (delete(sp, ep, &vp->m_start, &vp->m_stop, lmode))		return (1);	/* If replacing entire lines, insert a replacement line. */	if (lmode) {		if (file_iline(sp, ep, vp->m_start.lno, bp, vp->m_start.cno))			return (1);		sp->lno = vp->m_start.lno;		len = sp->cno = vp->m_start.cno;	}	/* Get the line we're editing. */	if ((p = file_gline(sp, ep, vp->m_start.lno, &len)) == NULL) {		if (file_lline(sp, ep, &lno))			return (1);		if (lno != 0) {			GETLINE_ERR(sp, vp->m_start.lno);			return (1);		}		len = 0;	}	/* Check to see if we're appending to the line. */	if (vp->m_start.cno >= len)		LF_SET(TXT_APPENDEOL);	rval = v_ntext(sp, ep,	    sp->tiqp, NULL, p, len, &vp->m_final, 0, OOBLNO, flags);	if (bp != NULL)		FREE_SPACE(sp, bp, blen);	return (rval);}/* * v_Replace -- [count]R *	Overwrite multiple characters. */intv_Replace(sp, ep, vp)	SCR *sp;	EXF *ep;	VICMDARG *vp;{	recno_t lno;	u_long cnt;	size_t len;	u_int flags;	char *p;	flags = set_txt_std(sp, vp, 0);	cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1;	if ((p = file_gline(sp, ep, vp->m_start.lno, &len)) == NULL) {		if (file_lline(sp, ep, &lno))			return (1);		if (lno != 0) {			GETLINE_ERR(sp, vp->m_start.lno);			return (1);		}		len = 0;		LF_SET(TXT_APPENDEOL);	} else {		if (len == 0)			LF_SET(TXT_APPENDEOL);		LF_SET(TXT_OVERWRITE | TXT_REPLACE);	}	vp->m_stop.lno = vp->m_start.lno;	vp->m_stop.cno = len ? len - 1 : 0;	if (v_ntext(sp, ep, sp->tiqp,	    &vp->m_stop, p, len, &vp->m_final, 0, OOBLNO, flags))		return (1);	if (F_ISSET(sp, S_INTERRUPTED))		return (0);	/*	 * Special case.  The historic vi handled [count]R badly, in that R	 * would replace some number of characters, and then the count would	 * append count-1 copies of the replacing chars to the replaced space.	 * This seems wrong, so this version counts R commands.  There is some	 * trickiness in moving back to where the user stopped replacing after	 * each R command.  Basically, if the user ended with a newline, we	 * want to use vp->m_final.cno (which will be 0).  Otherwise, use the	 * column after the returned cursor, unless it would be past the end of	 * the line, in which case we append to the line.	 */	while (--cnt) {		if ((p = file_gline(sp, ep, vp->m_final.lno, &len)) == NULL)			GETLINE_ERR(sp, vp->m_final.lno);		flags = set_txt_std(sp, vp, TXT_REPLAY);		sp->lno = vp->m_final.lno;		if (len == 0 || vp->m_final.cno == len - 1) {			sp->cno = len;			LF_SET(TXT_APPENDEOL);		} else {			sp->cno = vp->m_final.cno;			if (vp->m_final.cno != 0)				++sp->cno;			LF_SET(TXT_OVERWRITE | TXT_REPLACE);		}		vp->m_stop.lno = sp->lno;		vp->m_stop.cno = sp->cno;		if (v_ntext(sp, ep, sp->tiqp,		    &vp->m_stop, p, len, &vp->m_final, 0, OOBLNO, flags))			return (1);		if (F_ISSET(sp, S_INTERRUPTED))			break;	}	return (0);}/* * v_subst -- [buffer][count]s *	Substitute characters. */intv_subst(sp, ep, vp)	SCR *sp;	EXF *ep;	VICMDARG *vp;{	recno_t lno;	size_t len;	u_int flags;	char *p;	flags = set_txt_std(sp, vp, 0);	if ((p = file_gline(sp, ep, vp->m_start.lno, &len)) == NULL) {		if (file_lline(sp, ep, &lno))			return (1);		if (lno != 0) {			GETLINE_ERR(sp, vp->m_start.lno);			return (1);		}		len = 0;		LF_SET(TXT_APPENDEOL);	} else {		if (len == 0)			LF_SET(TXT_APPENDEOL);		LF_SET(TXT_EMARK | TXT_OVERWRITE);	}	vp->m_stop.lno = vp->m_start.lno;	vp->m_stop.cno =	    vp->m_start.cno + (F_ISSET(vp, VC_C1SET) ? vp->count - 1 : 0);	if (vp->m_stop.cno > len - 1)		vp->m_stop.cno = len - 1;	if (p != NULL &&	    cut(sp, ep, NULL, F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,	    &vp->m_start, &vp->m_stop, 0))		return (1);	return (v_ntext(sp, ep, sp->tiqp,	    &vp->m_stop, p, len, &vp->m_final, 0, OOBLNO, flags));}/* * set_txt_std -- *	Initialize text processing flags. */static u_intset_txt_std(sp, vp, init)	SCR *sp;	VICMDARG *vp;	u_int init;{	u_int flags;	/* Text operations are all interruptible. */	F_SET(sp, S_INTERRUPTIBLE);	LF_INIT(init);	LF_SET(TXT_CNTRLT |	    TXT_ESCAPE | TXT_MAPINPUT | TXT_RECORD | TXT_RESOLVE);	if (O_ISSET(sp, O_ALTWERASE))		LF_SET(TXT_ALTWERASE);	if (O_ISSET(sp, O_AUTOINDENT))		LF_SET(TXT_AUTOINDENT);	if (O_ISSET(sp, O_BEAUTIFY))		LF_SET(TXT_BEAUTIFY);	if (O_ISSET(sp, O_SHOWMATCH))		LF_SET(TXT_SHOWMATCH);	if (O_ISSET(sp, O_WRAPMARGIN))		LF_SET(TXT_WRAPMARGIN);	if (F_ISSET(sp, S_SCRIPT))		LF_SET(TXT_CR);	if (O_ISSET(sp, O_TTYWERASE))		LF_SET(TXT_TTYWERASE);	if (F_ISSET(vp,  VC_ISDOT))		LF_SET(TXT_REPLAY);	return (flags);}

⌨️ 快捷键说明

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