F_CLR(vp, VM_RCM_MASK); F_SET(vp, VM_RCM_SET);
v_change(sp, vp)	SCR *sp;	VICMD *vp;{	size_t blen, len;	u_int32_t flags;	int isempty, lmode, rval;	char *bp, *p;	/*	 * Find out if the file is empty, it's easier to handle it as a	 * special case.	 */	if (vp->m_start.lno == vp->m_stop.lno &&	    db_eget(sp, vp->m_start.lno, &p, &len, &isempty)) {		if (!isempty)			return (1);		return (v_ia(sp, vp));	}	flags = set_txt_std(sp, vp, 0);	sp->showmode = SM_CHANGE;	/*	 * 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, 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;	LOG_CORRECT;	/*	 * 'c' can be combined with motion commands that set the resulting	 * cursor position, i.e. "cG".  Clear the VM_RCM flags and make the	 * resulting cursor position stick, inserting text has its own rules	 * for cursor positioning.	 */	F_CLR(vp, VM_RCM_MASK);	F_SET(vp, VM_RCM_SET);	/*	 * If not in line mode and changing within a single line, copy the	 * text and overwrite it.	 */	if (!lmode && vp->m_start.lno == vp->m_stop.lno) {		/*		 * !!!		 * Historic practice, c did not cut into the numeric buffers,		 * only the unnamed one.		 */		if (cut(sp,		    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_txt(sp, vp, &vp->m_stop, p, len,		    0, OOBLNO, F_ISSET(vp, VC_C1SET) ? vp->count : 1, flags));	}	/*	 * It's trickier if in line mode or changing over multiple lines.  If	 * we're in line mode 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 delete the text and start inserting.	 *	 * !!!	 * Copy the text.  Historic practice, c did not cut into the numeric	 * buffers, only the unnamed one.	 */	if (cut(sp,	    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, and copy out the		 * leading text.		 */		if (db_get(sp, vp->m_start.lno, DBG_FATAL, &p, &len))			return (1);		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, &vp->m_start, &vp->m_stop, lmode))		return (1);	/* If replacing entire lines, insert a replacement line. */	if (lmode) {		if (db_insert(sp, 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 (db_eget(sp, vp->m_start.lno, &p, &len, &isempty)) {		if (!isempty)			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_txt(sp, vp, NULL, p, len,	    0, OOBLNO, F_ISSET(vp, VC_C1SET) ? vp->count : 1, flags);	if (bp != NULL)		FREE_SPACE(sp, bp, blen);	return (rval);}