1 /* @(#)delcmds.c	1.27 09/07/09 Copyright 1984-2009 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static	UConst char sccsid[] =
5 	"@(#)delcmds.c	1.27 09/07/09 Copyright 1984-2009 J. Schilling";
6 #endif
7 /*
8  *	Commands that deal with deletions
9  *
10  *	Copyright (c) 1984-2009 J. Schilling
11  */
12 /*
13  * The contents of this file are subject to the terms of the
14  * Common Development and Distribution License, Version 1.0 only
15  * (the "License").  You may not use this file except in compliance
16  * with the License.
17  *
18  * See the file CDDL.Schily.txt in this distribution for details.
19  * A copy of the CDDL is also available via the Internet at
20  * http://www.opensource.org/licenses/cddl1.txt
21  *
22  * When distributing Covered Code, include this CDDL HEADER in each
23  * file and include the License file CDDL.Schily.txt from this distribution.
24  */
25 
26 #include "ved.h"
27 #include "movedot.h"
28 
29 EXPORT	void	delchars	__PR((ewin_t *wp, epos_t numchars));
30 EXPORT	void	rubchars	__PR((ewin_t *wp, epos_t numchars));
31 EXPORT	void	vdel		__PR((ewin_t *wp));
32 EXPORT	void	vrub		__PR((ewin_t *wp));
33 EXPORT	void	vwdel		__PR((ewin_t *wp));
34 EXPORT	void	vwrub		__PR((ewin_t *wp));
35 EXPORT	void	vkill		__PR((ewin_t *wp));
36 EXPORT	void	vpkill		__PR((ewin_t *wp));
37 EXPORT	void	vskill		__PR((ewin_t *wp));
38 EXPORT	void	vundel		__PR((ewin_t *wp));
39 
40 /*
41  * Delete characters forwards starting at the current cursor position.
42  * First save them in the delete buffer if needed.
43  */
44 EXPORT void
delchars(wp,nchars)45 delchars(wp, nchars)
46 	ewin_t	*wp;
47 	epos_t nchars;
48 {
49 	if (nchars <= 0)
50 		return;
51 
52 	if (nchars > wp->eof-wp->dot)
53 		nchars = wp->eof-wp->dot;
54 
55 	if ((wp->eflags & SAVEDEL) != 0) {
56 		if ((wp->eflags & KEEPDEL) == 0)
57 			rubsize = delsize = 0;
58 		lseek(fdown(delfile), (off_t)delsize, SEEK_SET);
59 		savefile(wp, wp->dot, wp->dot+nchars, delfile, "DEL BUF");
60 		delsize += nchars;
61 		wp->eflags |= DELDONE;
62 	}
63 	dispup(wp, wp->dot, wp->dot+nchars);
64 
65 	delete(wp, nchars);
66 	modified(wp);
67 }
68 
69 /*
70  * Delete characters backwards starting at the current cursor position.
71  * First save them in the rub-out buffer if needed. We have to save them
72  * backwards to be able to restore backward deletions correctly.
73  */
74 EXPORT void
rubchars(wp,nchars)75 rubchars(wp, nchars)
76 	ewin_t	*wp;
77 	epos_t nchars;
78 {
79 	epos_t	savedot;
80 	epos_t	newdot;
81 
82 	if (nchars <= 0)
83 		return;
84 
85 	if (nchars > wp->dot)
86 		nchars = wp->dot;
87 
88 	if ((wp->eflags & SAVEDEL) != 0) {
89 		if ((wp->eflags & KEEPDEL) == 0)
90 			rubsize = delsize = 0;
91 		lseek(fdown(rubfile), (off_t)rubsize, SEEK_SET);
92 		backsavefile(wp, wp->dot-nchars, wp->dot, rubfile, "DEL BUF");
93 		rubsize += nchars;
94 		wp->eflags |= DELDONE;
95 	}
96 
97 	savedot = wp->dot;
98 	newdot = wp->dot -= nchars;
99 	if (newdot < wp->window)
100 		wp->dot = wp->window;
101 	setpos(wp);			/* update part on screen */
102 	setcursor(wp);
103 	dispup(wp, wp->dot, savedot);
104 	if (newdot < wp->window)
105 		findwpos(wp, wp->window = newdot);
106 	wp->dot = savedot;
107 
108 	rubout(wp, nchars);
109 	modified(wp);
110 }
111 
112 /*
113  * Delete 'curnum' characters atfer the cursor
114  */
115 EXPORT void
vdel(wp)116 vdel(wp)
117 	ewin_t	*wp;
118 {
119 	if (wp->dot == wp->eof) {
120 		ringbell();
121 	} else {
122 		if (wp->dot+wp->curnum > wp->eof)	/* Make sure we don't go bejond eof. */
123 			wp->curnum = wp->eof-wp->dot;
124 		delchars(wp, (epos_t)wp->curnum);
125 	}
126 }
127 
128 /*
129  * Delete 'curnum' characters before the cursor
130  */
131 EXPORT void
vrub(wp)132 vrub(wp)
133 	ewin_t	*wp;
134 {
135 	if (wp->dot == 0) {
136 		ringbell();
137 	} else {
138 		if (wp->curnum > wp->dot)
139 			wp->curnum = wp->dot;
140 		rubchars(wp, (epos_t)wp->curnum);
141 	}
142 }
143 
144 /*
145  * Delete 'curnum' words after the cursor
146  */
147 EXPORT void
vwdel(wp)148 vwdel(wp)
149 	ewin_t	*wp;
150 {
151 	wp->curnum = forwword(wp, wp->dot, wp->curnum) - wp->dot;
152 	vdel(wp);
153 }
154 
155 /*
156  * Delete 'curnum' words before the cursor
157  */
158 EXPORT void
vwrub(wp)159 vwrub(wp)
160 	ewin_t	*wp;
161 {
162 	epos_t	pos;
163 
164 	pos = revword(wp, wp->dot, wp->curnum);
165 	wp->curnum = wp->dot - pos;
166 	vrub(wp);
167 }
168 
169 /*
170  * Delete from cursor to the end of the 'curnum-1' th line
171  */
172 EXPORT void
vkill(wp)173 vkill(wp)
174 	ewin_t	*wp;
175 {
176 	wp->curnum = forwline(wp, wp->dot, wp->curnum) - wp->dot;
177 	vdel(wp);
178 }
179 
180 /*
181  * Delete from cursor to the end of the 'curnum-1' th paragraph
182  */
183 EXPORT void
vpkill(wp)184 vpkill(wp)
185 	ewin_t	*wp;
186 {
187 	wp->curnum = forwpara(wp, wp->dot, wp->curnum) - wp->dot;
188 	vdel(wp);
189 }
190 
191 /*
192  * Delete characters in selection (between cursor and mark)
193  */
194 EXPORT void
vskill(wp)195 vskill(wp)
196 	ewin_t	*wp;
197 {
198 	if (wp->markvalid) {
199 		if (wp->mark > wp->dot) {
200 			delchars(wp, wp->mark-wp->dot);
201 		} else {
202 			rubchars(wp, wp->dot-wp->mark);
203 		}
204 	} else {
205 		nomarkmsg(wp);
206 	}
207 }
208 
209 /*
210  * Undo previous deletions
211  *
212  * First insert the content of the rub-out (back delete) buffer,
213  * then insert the content of the forward delete buffer.
214  * After doing that, the cursor is between both insertions.
215  */
216 EXPORT void
vundel(wp)217 vundel(wp)
218 	ewin_t	*wp;
219 {
220 	wp->curnum = 1;
221 	backgetfile(wp, rubfile, rubsize, "RUB BUF");
222 	update(wp);
223 	getfile(wp, delfile, delsize, "DEL BUF");
224 	rubsize = delsize = 0;
225 }
226