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