v_delete.c revision 19304
119304Speter/*-
219304Speter * Copyright (c) 1992, 1993, 1994
319304Speter *	The Regents of the University of California.  All rights reserved.
419304Speter * Copyright (c) 1992, 1993, 1994, 1995, 1996
519304Speter *	Keith Bostic.  All rights reserved.
619304Speter *
719304Speter * See the LICENSE file for redistribution information.
819304Speter */
919304Speter
1019304Speter#include "config.h"
1119304Speter
1219304Speter#ifndef lint
1319304Speterstatic const char sccsid[] = "@(#)v_delete.c	10.9 (Berkeley) 10/23/96";
1419304Speter#endif /* not lint */
1519304Speter
1619304Speter#include <sys/types.h>
1719304Speter#include <sys/queue.h>
1819304Speter#include <sys/time.h>
1919304Speter
2019304Speter#include <bitstring.h>
2119304Speter#include <limits.h>
2219304Speter#include <stdio.h>
2319304Speter
2419304Speter#include "../common/common.h"
2519304Speter#include "vi.h"
2619304Speter
2719304Speter/*
2819304Speter * v_delete -- [buffer][count]d[count]motion
2919304Speter *	       [buffer][count]D
3019304Speter *	Delete a range of text.
3119304Speter *
3219304Speter * PUBLIC: int v_delete __P((SCR *, VICMD *));
3319304Speter */
3419304Speterint
3519304Speterv_delete(sp, vp)
3619304Speter	SCR *sp;
3719304Speter	VICMD *vp;
3819304Speter{
3919304Speter	recno_t nlines;
4019304Speter	size_t len;
4119304Speter	int lmode;
4219304Speter
4319304Speter	lmode = F_ISSET(vp, VM_LMODE) ? CUT_LINEMODE : 0;
4419304Speter
4519304Speter	/* Yank the lines. */
4619304Speter	if (cut(sp, F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,
4719304Speter	    &vp->m_start, &vp->m_stop,
4819304Speter	    lmode | (F_ISSET(vp, VM_CUTREQ) ? CUT_NUMREQ : CUT_NUMOPT)))
4919304Speter		return (1);
5019304Speter
5119304Speter	/* Delete the lines. */
5219304Speter	if (del(sp, &vp->m_start, &vp->m_stop, lmode))
5319304Speter		return (1);
5419304Speter
5519304Speter	/*
5619304Speter	 * Check for deletion of the entire file.  Try to check a close
5719304Speter	 * by line so we don't go to the end of the file unnecessarily.
5819304Speter	 */
5919304Speter	if (!db_exist(sp, vp->m_final.lno + 1)) {
6019304Speter		if (db_last(sp, &nlines))
6119304Speter			return (1);
6219304Speter		if (nlines == 0) {
6319304Speter			vp->m_final.lno = 1;
6419304Speter			vp->m_final.cno = 0;
6519304Speter			return (0);
6619304Speter		}
6719304Speter	}
6819304Speter
6919304Speter	/*
7019304Speter	 * One special correction, in case we've deleted the current line or
7119304Speter	 * character.  We check it here instead of checking in every command
7219304Speter	 * that can be a motion component.
7319304Speter	 */
7419304Speter	if (db_get(sp, vp->m_final.lno, 0, NULL, &len)) {
7519304Speter		if (db_get(sp, nlines, DBG_FATAL, NULL, &len))
7619304Speter			return (1);
7719304Speter		vp->m_final.lno = nlines;
7819304Speter	}
7919304Speter
8019304Speter	/*
8119304Speter	 * !!!
8219304Speter	 * Cursor movements, other than those caused by a line mode command
8319304Speter	 * moving to another line, historically reset the relative position.
8419304Speter	 *
8519304Speter	 * This currently matches the check made in v_yank(), I'm hoping that
8619304Speter	 * they should be consistent...
8719304Speter	 */
8819304Speter	if (!F_ISSET(vp, VM_LMODE)) {
8919304Speter		F_CLR(vp, VM_RCM_MASK);
9019304Speter		F_SET(vp, VM_RCM_SET);
9119304Speter
9219304Speter		/* Make sure the set cursor position exists. */
9319304Speter		if (vp->m_final.cno >= len)
9419304Speter			vp->m_final.cno = len ? len - 1 : 0;
9519304Speter	}
9619304Speter
9719304Speter	/*
9819304Speter	 * !!!
9919304Speter	 * The "dd" command moved to the first non-blank; "d<motion>"
10019304Speter	 * didn't.
10119304Speter	 */
10219304Speter	if (F_ISSET(vp, VM_LDOUBLE)) {
10319304Speter		F_CLR(vp, VM_RCM_MASK);
10419304Speter		F_SET(vp, VM_RCM_SETFNB);
10519304Speter	}
10619304Speter	return (0);
10719304Speter}
108