xref: /netbsd/external/bsd/nvi/dist/vi/v_delete.c (revision cc73507a)
1*cc73507aSchristos /*	$NetBSD: v_delete.c,v 1.3 2014/01/26 21:43:45 christos Exp $	*/
23a571abcSchristos /*-
33a571abcSchristos  * Copyright (c) 1992, 1993, 1994
43a571abcSchristos  *	The Regents of the University of California.  All rights reserved.
53a571abcSchristos  * Copyright (c) 1992, 1993, 1994, 1995, 1996
63a571abcSchristos  *	Keith Bostic.  All rights reserved.
73a571abcSchristos  *
83a571abcSchristos  * See the LICENSE file for redistribution information.
93a571abcSchristos  */
103a571abcSchristos 
113a571abcSchristos #include "config.h"
123a571abcSchristos 
13*cc73507aSchristos #include <sys/cdefs.h>
14*cc73507aSchristos #if 0
153a571abcSchristos #ifndef lint
163a571abcSchristos static const char sccsid[] = "Id: v_delete.c,v 10.11 2001/06/25 15:19:31 skimo Exp  (Berkeley) Date: 2001/06/25 15:19:31 ";
173a571abcSchristos #endif /* not lint */
18*cc73507aSchristos #else
19*cc73507aSchristos __RCSID("$NetBSD: v_delete.c,v 1.3 2014/01/26 21:43:45 christos Exp $");
20*cc73507aSchristos #endif
213a571abcSchristos 
223a571abcSchristos #include <sys/types.h>
233a571abcSchristos #include <sys/queue.h>
243a571abcSchristos #include <sys/time.h>
253a571abcSchristos 
263a571abcSchristos #include <bitstring.h>
273a571abcSchristos #include <limits.h>
283a571abcSchristos #include <stdio.h>
293a571abcSchristos 
303a571abcSchristos #include "../common/common.h"
313a571abcSchristos #include "vi.h"
323a571abcSchristos 
333a571abcSchristos /*
343a571abcSchristos  * v_delete -- [buffer][count]d[count]motion
353a571abcSchristos  *	       [buffer][count]D
363a571abcSchristos  *	Delete a range of text.
373a571abcSchristos  *
383a571abcSchristos  * PUBLIC: int v_delete __P((SCR *, VICMD *));
393a571abcSchristos  */
403a571abcSchristos int
v_delete(SCR * sp,VICMD * vp)413a571abcSchristos v_delete(SCR *sp, VICMD *vp)
423a571abcSchristos {
433a571abcSchristos 	db_recno_t nlines;
443a571abcSchristos 	size_t len;
453a571abcSchristos 	int lmode;
463a571abcSchristos 
473a571abcSchristos 	lmode = F_ISSET(vp, VM_LMODE) ? CUT_LINEMODE : 0;
483a571abcSchristos 
493a571abcSchristos 	/* Yank the lines. */
503a571abcSchristos 	if (cut(sp, F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,
513a571abcSchristos 	    &vp->m_start, &vp->m_stop,
523a571abcSchristos 	    lmode | (F_ISSET(vp, VM_CUTREQ) ? CUT_NUMREQ : CUT_NUMOPT)))
533a571abcSchristos 		return (1);
543a571abcSchristos 
553a571abcSchristos 	/* Delete the lines. */
563a571abcSchristos 	if (del(sp, &vp->m_start, &vp->m_stop, lmode))
573a571abcSchristos 		return (1);
583a571abcSchristos 
593a571abcSchristos 	/*
603a571abcSchristos 	 * Check for deletion of the entire file.  Try to check a close
613a571abcSchristos 	 * by line so we don't go to the end of the file unnecessarily.
623a571abcSchristos 	 */
633a571abcSchristos 	if (!db_exist(sp, vp->m_final.lno + 1)) {
643a571abcSchristos 		if (db_last(sp, &nlines))
653a571abcSchristos 			return (1);
663a571abcSchristos 		if (nlines == 0) {
673a571abcSchristos 			vp->m_final.lno = 1;
683a571abcSchristos 			vp->m_final.cno = 0;
693a571abcSchristos 			return (0);
703a571abcSchristos 		}
713a571abcSchristos 	}
723a571abcSchristos 
733a571abcSchristos 	/*
743a571abcSchristos 	 * One special correction, in case we've deleted the current line or
753a571abcSchristos 	 * character.  We check it here instead of checking in every command
763a571abcSchristos 	 * that can be a motion component.
773a571abcSchristos 	 */
783a571abcSchristos 	if (db_get(sp, vp->m_final.lno, 0, NULL, &len)) {
793a571abcSchristos 		if (db_get(sp, nlines, DBG_FATAL, NULL, &len))
803a571abcSchristos 			return (1);
813a571abcSchristos 		vp->m_final.lno = nlines;
823a571abcSchristos 	}
833a571abcSchristos 
843a571abcSchristos 	/*
853a571abcSchristos 	 * !!!
863a571abcSchristos 	 * Cursor movements, other than those caused by a line mode command
873a571abcSchristos 	 * moving to another line, historically reset the relative position.
883a571abcSchristos 	 *
893a571abcSchristos 	 * This currently matches the check made in v_yank(), I'm hoping that
903a571abcSchristos 	 * they should be consistent...
913a571abcSchristos 	 */
923a571abcSchristos 	if (!F_ISSET(vp, VM_LMODE)) {
933a571abcSchristos 		F_CLR(vp, VM_RCM_MASK);
943a571abcSchristos 		F_SET(vp, VM_RCM_SET);
953a571abcSchristos 
963a571abcSchristos 		/* Make sure the set cursor position exists. */
973a571abcSchristos 		if (vp->m_final.cno >= len)
983a571abcSchristos 			vp->m_final.cno = len ? len - 1 : 0;
993a571abcSchristos 	}
1003a571abcSchristos 
1013a571abcSchristos 	/*
1023a571abcSchristos 	 * !!!
1033a571abcSchristos 	 * The "dd" command moved to the first non-blank; "d<motion>"
1043a571abcSchristos 	 * didn't.
1053a571abcSchristos 	 */
1063a571abcSchristos 	if (F_ISSET(vp, VM_LDOUBLE)) {
1073a571abcSchristos 		F_CLR(vp, VM_RCM_MASK);
1083a571abcSchristos 		F_SET(vp, VM_RCM_SETFNB);
1093a571abcSchristos 	}
1103a571abcSchristos 	return (0);
1113a571abcSchristos }
112