Blame


1 b3994ec5 2003-12-11 devnull #include <u.h>
2 b3994ec5 2003-12-11 devnull #include <libc.h>
3 b3994ec5 2003-12-11 devnull #include <draw.h>
4 b3994ec5 2003-12-11 devnull #include <thread.h>
5 b3994ec5 2003-12-11 devnull #include <cursor.h>
6 b3994ec5 2003-12-11 devnull #include <mouse.h>
7 b3994ec5 2003-12-11 devnull #include <keyboard.h>
8 b3994ec5 2003-12-11 devnull #include <frame.h>
9 b3994ec5 2003-12-11 devnull #include <fcall.h>
10 b3994ec5 2003-12-11 devnull #include <plumb.h>
11 b3994ec5 2003-12-11 devnull #include "dat.h"
12 b3994ec5 2003-12-11 devnull #include "fns.h"
13 b3994ec5 2003-12-11 devnull
14 b3994ec5 2003-12-11 devnull /*
15 b3994ec5 2003-12-11 devnull * Structure of Undo list:
16 b3994ec5 2003-12-11 devnull * The Undo structure follows any associated data, so the list
17 b3994ec5 2003-12-11 devnull * can be read backwards: read the structure, then read whatever
18 b3994ec5 2003-12-11 devnull * data is associated (insert string, file name) and precedes it.
19 b3994ec5 2003-12-11 devnull * The structure includes the previous value of the modify bit
20 b3994ec5 2003-12-11 devnull * and a sequence number; successive Undo structures with the
21 b3994ec5 2003-12-11 devnull * same sequence number represent simultaneous changes.
22 b3994ec5 2003-12-11 devnull */
23 b3994ec5 2003-12-11 devnull
24 b3994ec5 2003-12-11 devnull typedef struct Undo Undo;
25 b3994ec5 2003-12-11 devnull struct Undo
26 b3994ec5 2003-12-11 devnull {
27 b3994ec5 2003-12-11 devnull short type; /* Delete, Insert, Filename */
28 b3994ec5 2003-12-11 devnull short mod; /* modify bit */
29 b3994ec5 2003-12-11 devnull uint seq; /* sequence number */
30 b3994ec5 2003-12-11 devnull uint p0; /* location of change (unused in f) */
31 b3994ec5 2003-12-11 devnull uint n; /* # runes in string or file name */
32 b3994ec5 2003-12-11 devnull };
33 b3994ec5 2003-12-11 devnull
34 b3994ec5 2003-12-11 devnull enum
35 b3994ec5 2003-12-11 devnull {
36 cbeb0b26 2006-04-01 devnull Undosize = sizeof(Undo)/sizeof(Rune)
37 b3994ec5 2003-12-11 devnull };
38 b3994ec5 2003-12-11 devnull
39 b3994ec5 2003-12-11 devnull File*
40 b3994ec5 2003-12-11 devnull fileaddtext(File *f, Text *t)
41 b3994ec5 2003-12-11 devnull {
42 b3994ec5 2003-12-11 devnull if(f == nil){
43 b3994ec5 2003-12-11 devnull f = emalloc(sizeof(File));
44 b3994ec5 2003-12-11 devnull f->unread = TRUE;
45 b3994ec5 2003-12-11 devnull }
46 b3994ec5 2003-12-11 devnull f->text = realloc(f->text, (f->ntext+1)*sizeof(Text*));
47 b3994ec5 2003-12-11 devnull f->text[f->ntext++] = t;
48 b3994ec5 2003-12-11 devnull f->curtext = t;
49 b3994ec5 2003-12-11 devnull return f;
50 b3994ec5 2003-12-11 devnull }
51 b3994ec5 2003-12-11 devnull
52 b3994ec5 2003-12-11 devnull void
53 b3994ec5 2003-12-11 devnull filedeltext(File *f, Text *t)
54 b3994ec5 2003-12-11 devnull {
55 b3994ec5 2003-12-11 devnull int i;
56 b3994ec5 2003-12-11 devnull
57 b3994ec5 2003-12-11 devnull for(i=0; i<f->ntext; i++)
58 b3994ec5 2003-12-11 devnull if(f->text[i] == t)
59 b3994ec5 2003-12-11 devnull goto Found;
60 b3994ec5 2003-12-11 devnull error("can't find text in filedeltext");
61 b3994ec5 2003-12-11 devnull
62 b3994ec5 2003-12-11 devnull Found:
63 b3994ec5 2003-12-11 devnull f->ntext--;
64 b3994ec5 2003-12-11 devnull if(f->ntext == 0){
65 b3994ec5 2003-12-11 devnull fileclose(f);
66 b3994ec5 2003-12-11 devnull return;
67 b3994ec5 2003-12-11 devnull }
68 b3994ec5 2003-12-11 devnull memmove(f->text+i, f->text+i+1, (f->ntext-i)*sizeof(Text*));
69 b3994ec5 2003-12-11 devnull if(f->curtext == t)
70 b3994ec5 2003-12-11 devnull f->curtext = f->text[0];
71 b3994ec5 2003-12-11 devnull }
72 b3994ec5 2003-12-11 devnull
73 b3994ec5 2003-12-11 devnull void
74 b3994ec5 2003-12-11 devnull fileinsert(File *f, uint p0, Rune *s, uint ns)
75 b3994ec5 2003-12-11 devnull {
76 b3994ec5 2003-12-11 devnull if(p0 > f->b.nc)
77 b3994ec5 2003-12-11 devnull error("internal error: fileinsert");
78 b3994ec5 2003-12-11 devnull if(f->seq > 0)
79 b3994ec5 2003-12-11 devnull fileuninsert(f, &f->delta, p0, ns);
80 b3994ec5 2003-12-11 devnull bufinsert(&f->b, p0, s, ns);
81 b3994ec5 2003-12-11 devnull if(ns)
82 b3994ec5 2003-12-11 devnull f->mod = TRUE;
83 b3994ec5 2003-12-11 devnull }
84 b3994ec5 2003-12-11 devnull
85 b3994ec5 2003-12-11 devnull void
86 b3994ec5 2003-12-11 devnull fileuninsert(File *f, Buffer *delta, uint p0, uint ns)
87 b3994ec5 2003-12-11 devnull {
88 b3994ec5 2003-12-11 devnull Undo u;
89 b3994ec5 2003-12-11 devnull
90 b3994ec5 2003-12-11 devnull /* undo an insertion by deleting */
91 b3994ec5 2003-12-11 devnull u.type = Delete;
92 b3994ec5 2003-12-11 devnull u.mod = f->mod;
93 b3994ec5 2003-12-11 devnull u.seq = f->seq;
94 b3994ec5 2003-12-11 devnull u.p0 = p0;
95 b3994ec5 2003-12-11 devnull u.n = ns;
96 b3994ec5 2003-12-11 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
97 b3994ec5 2003-12-11 devnull }
98 b3994ec5 2003-12-11 devnull
99 b3994ec5 2003-12-11 devnull void
100 b3994ec5 2003-12-11 devnull filedelete(File *f, uint p0, uint p1)
101 b3994ec5 2003-12-11 devnull {
102 b3994ec5 2003-12-11 devnull if(!(p0<=p1 && p0<=f->b.nc && p1<=f->b.nc))
103 b3994ec5 2003-12-11 devnull error("internal error: filedelete");
104 b3994ec5 2003-12-11 devnull if(f->seq > 0)
105 b3994ec5 2003-12-11 devnull fileundelete(f, &f->delta, p0, p1);
106 b3994ec5 2003-12-11 devnull bufdelete(&f->b, p0, p1);
107 b3994ec5 2003-12-11 devnull if(p1 > p0)
108 b3994ec5 2003-12-11 devnull f->mod = TRUE;
109 b3994ec5 2003-12-11 devnull }
110 b3994ec5 2003-12-11 devnull
111 b3994ec5 2003-12-11 devnull void
112 b3994ec5 2003-12-11 devnull fileundelete(File *f, Buffer *delta, uint p0, uint p1)
113 b3994ec5 2003-12-11 devnull {
114 b3994ec5 2003-12-11 devnull Undo u;
115 b3994ec5 2003-12-11 devnull Rune *buf;
116 b3994ec5 2003-12-11 devnull uint i, n;
117 b3994ec5 2003-12-11 devnull
118 b3994ec5 2003-12-11 devnull /* undo a deletion by inserting */
119 b3994ec5 2003-12-11 devnull u.type = Insert;
120 b3994ec5 2003-12-11 devnull u.mod = f->mod;
121 b3994ec5 2003-12-11 devnull u.seq = f->seq;
122 b3994ec5 2003-12-11 devnull u.p0 = p0;
123 b3994ec5 2003-12-11 devnull u.n = p1-p0;
124 b3994ec5 2003-12-11 devnull buf = fbufalloc();
125 b3994ec5 2003-12-11 devnull for(i=p0; i<p1; i+=n){
126 b3994ec5 2003-12-11 devnull n = p1 - i;
127 b3994ec5 2003-12-11 devnull if(n > RBUFSIZE)
128 b3994ec5 2003-12-11 devnull n = RBUFSIZE;
129 b3994ec5 2003-12-11 devnull bufread(&f->b, i, buf, n);
130 b3994ec5 2003-12-11 devnull bufinsert(delta, delta->nc, buf, n);
131 b3994ec5 2003-12-11 devnull }
132 b3994ec5 2003-12-11 devnull fbuffree(buf);
133 b3994ec5 2003-12-11 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
134 b3994ec5 2003-12-11 devnull
135 b3994ec5 2003-12-11 devnull }
136 b3994ec5 2003-12-11 devnull
137 b3994ec5 2003-12-11 devnull void
138 b3994ec5 2003-12-11 devnull filesetname(File *f, Rune *name, int n)
139 b3994ec5 2003-12-11 devnull {
140 b3994ec5 2003-12-11 devnull if(f->seq > 0)
141 b3994ec5 2003-12-11 devnull fileunsetname(f, &f->delta);
142 b3994ec5 2003-12-11 devnull free(f->name);
143 b3994ec5 2003-12-11 devnull f->name = runemalloc(n);
144 b3994ec5 2003-12-11 devnull runemove(f->name, name, n);
145 b3994ec5 2003-12-11 devnull f->nname = n;
146 b3994ec5 2003-12-11 devnull f->unread = TRUE;
147 b3994ec5 2003-12-11 devnull }
148 b3994ec5 2003-12-11 devnull
149 b3994ec5 2003-12-11 devnull void
150 b3994ec5 2003-12-11 devnull fileunsetname(File *f, Buffer *delta)
151 b3994ec5 2003-12-11 devnull {
152 b3994ec5 2003-12-11 devnull Undo u;
153 b3994ec5 2003-12-11 devnull
154 b3994ec5 2003-12-11 devnull /* undo a file name change by restoring old name */
155 b3994ec5 2003-12-11 devnull u.type = Filename;
156 b3994ec5 2003-12-11 devnull u.mod = f->mod;
157 b3994ec5 2003-12-11 devnull u.seq = f->seq;
158 b3994ec5 2003-12-11 devnull u.p0 = 0; /* unused */
159 b3994ec5 2003-12-11 devnull u.n = f->nname;
160 b3994ec5 2003-12-11 devnull if(f->nname)
161 b3994ec5 2003-12-11 devnull bufinsert(delta, delta->nc, f->name, f->nname);
162 b3994ec5 2003-12-11 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
163 b3994ec5 2003-12-11 devnull }
164 b3994ec5 2003-12-11 devnull
165 b3994ec5 2003-12-11 devnull uint
166 b3994ec5 2003-12-11 devnull fileload(File *f, uint p0, int fd, int *nulls)
167 b3994ec5 2003-12-11 devnull {
168 b3994ec5 2003-12-11 devnull if(f->seq > 0)
169 b3994ec5 2003-12-11 devnull error("undo in file.load unimplemented");
170 b3994ec5 2003-12-11 devnull return bufload(&f->b, p0, fd, nulls);
171 b3994ec5 2003-12-11 devnull }
172 b3994ec5 2003-12-11 devnull
173 b3994ec5 2003-12-11 devnull /* return sequence number of pending redo */
174 b3994ec5 2003-12-11 devnull uint
175 b3994ec5 2003-12-11 devnull fileredoseq(File *f)
176 b3994ec5 2003-12-11 devnull {
177 b3994ec5 2003-12-11 devnull Undo u;
178 b3994ec5 2003-12-11 devnull Buffer *delta;
179 b3994ec5 2003-12-11 devnull
180 b3994ec5 2003-12-11 devnull delta = &f->epsilon;
181 b3994ec5 2003-12-11 devnull if(delta->nc == 0)
182 b3994ec5 2003-12-11 devnull return 0;
183 b3994ec5 2003-12-11 devnull bufread(delta, delta->nc-Undosize, (Rune*)&u, Undosize);
184 b3994ec5 2003-12-11 devnull return u.seq;
185 b3994ec5 2003-12-11 devnull }
186 b3994ec5 2003-12-11 devnull
187 b3994ec5 2003-12-11 devnull void
188 b3994ec5 2003-12-11 devnull fileundo(File *f, int isundo, uint *q0p, uint *q1p)
189 b3994ec5 2003-12-11 devnull {
190 b3994ec5 2003-12-11 devnull Undo u;
191 b3994ec5 2003-12-11 devnull Rune *buf;
192 b3994ec5 2003-12-11 devnull uint i, j, n, up;
193 b3994ec5 2003-12-11 devnull uint stop;
194 b3994ec5 2003-12-11 devnull Buffer *delta, *epsilon;
195 b3994ec5 2003-12-11 devnull
196 b3994ec5 2003-12-11 devnull if(isundo){
197 b3994ec5 2003-12-11 devnull /* undo; reverse delta onto epsilon, seq decreases */
198 b3994ec5 2003-12-11 devnull delta = &f->delta;
199 b3994ec5 2003-12-11 devnull epsilon = &f->epsilon;
200 b3994ec5 2003-12-11 devnull stop = f->seq;
201 b3994ec5 2003-12-11 devnull }else{
202 b3994ec5 2003-12-11 devnull /* redo; reverse epsilon onto delta, seq increases */
203 b3994ec5 2003-12-11 devnull delta = &f->epsilon;
204 b3994ec5 2003-12-11 devnull epsilon = &f->delta;
205 b3994ec5 2003-12-11 devnull stop = 0; /* don't know yet */
206 b3994ec5 2003-12-11 devnull }
207 b3994ec5 2003-12-11 devnull
208 b3994ec5 2003-12-11 devnull buf = fbufalloc();
209 b3994ec5 2003-12-11 devnull while(delta->nc > 0){
210 b3994ec5 2003-12-11 devnull up = delta->nc-Undosize;
211 b3994ec5 2003-12-11 devnull bufread(delta, up, (Rune*)&u, Undosize);
212 b3994ec5 2003-12-11 devnull if(isundo){
213 b3994ec5 2003-12-11 devnull if(u.seq < stop){
214 b3994ec5 2003-12-11 devnull f->seq = u.seq;
215 b3994ec5 2003-12-11 devnull goto Return;
216 b3994ec5 2003-12-11 devnull }
217 b3994ec5 2003-12-11 devnull }else{
218 b3994ec5 2003-12-11 devnull if(stop == 0)
219 b3994ec5 2003-12-11 devnull stop = u.seq;
220 b3994ec5 2003-12-11 devnull if(u.seq > stop)
221 b3994ec5 2003-12-11 devnull goto Return;
222 b3994ec5 2003-12-11 devnull }
223 b3994ec5 2003-12-11 devnull switch(u.type){
224 b3994ec5 2003-12-11 devnull default:
225 b3994ec5 2003-12-11 devnull fprint(2, "undo: 0x%ux\n", u.type);
226 b3994ec5 2003-12-11 devnull abort();
227 b3994ec5 2003-12-11 devnull break;
228 b3994ec5 2003-12-11 devnull
229 b3994ec5 2003-12-11 devnull case Delete:
230 b3994ec5 2003-12-11 devnull f->seq = u.seq;
231 b3994ec5 2003-12-11 devnull fileundelete(f, epsilon, u.p0, u.p0+u.n);
232 b3994ec5 2003-12-11 devnull f->mod = u.mod;
233 b3994ec5 2003-12-11 devnull bufdelete(&f->b, u.p0, u.p0+u.n);
234 b3994ec5 2003-12-11 devnull for(j=0; j<f->ntext; j++)
235 b3994ec5 2003-12-11 devnull textdelete(f->text[j], u.p0, u.p0+u.n, FALSE);
236 b3994ec5 2003-12-11 devnull *q0p = u.p0;
237 b3994ec5 2003-12-11 devnull *q1p = u.p0;
238 b3994ec5 2003-12-11 devnull break;
239 b3994ec5 2003-12-11 devnull
240 b3994ec5 2003-12-11 devnull case Insert:
241 b3994ec5 2003-12-11 devnull f->seq = u.seq;
242 b3994ec5 2003-12-11 devnull fileuninsert(f, epsilon, u.p0, u.n);
243 b3994ec5 2003-12-11 devnull f->mod = u.mod;
244 b3994ec5 2003-12-11 devnull up -= u.n;
245 b3994ec5 2003-12-11 devnull for(i=0; i<u.n; i+=n){
246 b3994ec5 2003-12-11 devnull n = u.n - i;
247 b3994ec5 2003-12-11 devnull if(n > RBUFSIZE)
248 b3994ec5 2003-12-11 devnull n = RBUFSIZE;
249 b3994ec5 2003-12-11 devnull bufread(delta, up+i, buf, n);
250 b3994ec5 2003-12-11 devnull bufinsert(&f->b, u.p0+i, buf, n);
251 b3994ec5 2003-12-11 devnull for(j=0; j<f->ntext; j++)
252 b3994ec5 2003-12-11 devnull textinsert(f->text[j], u.p0+i, buf, n, FALSE);
253 b3994ec5 2003-12-11 devnull }
254 b3994ec5 2003-12-11 devnull *q0p = u.p0;
255 b3994ec5 2003-12-11 devnull *q1p = u.p0+u.n;
256 b3994ec5 2003-12-11 devnull break;
257 b3994ec5 2003-12-11 devnull
258 b3994ec5 2003-12-11 devnull case Filename:
259 b3994ec5 2003-12-11 devnull f->seq = u.seq;
260 b3994ec5 2003-12-11 devnull fileunsetname(f, epsilon);
261 b3994ec5 2003-12-11 devnull f->mod = u.mod;
262 b3994ec5 2003-12-11 devnull up -= u.n;
263 b3994ec5 2003-12-11 devnull free(f->name);
264 b3994ec5 2003-12-11 devnull if(u.n == 0)
265 b3994ec5 2003-12-11 devnull f->name = nil;
266 b3994ec5 2003-12-11 devnull else
267 b3994ec5 2003-12-11 devnull f->name = runemalloc(u.n);
268 b3994ec5 2003-12-11 devnull bufread(delta, up, f->name, u.n);
269 b3994ec5 2003-12-11 devnull f->nname = u.n;
270 b3994ec5 2003-12-11 devnull break;
271 b3994ec5 2003-12-11 devnull }
272 b3994ec5 2003-12-11 devnull bufdelete(delta, up, delta->nc);
273 b3994ec5 2003-12-11 devnull }
274 b3994ec5 2003-12-11 devnull if(isundo)
275 b3994ec5 2003-12-11 devnull f->seq = 0;
276 b3994ec5 2003-12-11 devnull Return:
277 b3994ec5 2003-12-11 devnull fbuffree(buf);
278 b3994ec5 2003-12-11 devnull }
279 b3994ec5 2003-12-11 devnull
280 b3994ec5 2003-12-11 devnull void
281 b3994ec5 2003-12-11 devnull filereset(File *f)
282 b3994ec5 2003-12-11 devnull {
283 b3994ec5 2003-12-11 devnull bufreset(&f->delta);
284 b3994ec5 2003-12-11 devnull bufreset(&f->epsilon);
285 b3994ec5 2003-12-11 devnull f->seq = 0;
286 b3994ec5 2003-12-11 devnull }
287 b3994ec5 2003-12-11 devnull
288 b3994ec5 2003-12-11 devnull void
289 b3994ec5 2003-12-11 devnull fileclose(File *f)
290 b3994ec5 2003-12-11 devnull {
291 b3994ec5 2003-12-11 devnull free(f->name);
292 b3994ec5 2003-12-11 devnull f->nname = 0;
293 b3994ec5 2003-12-11 devnull f->name = nil;
294 b3994ec5 2003-12-11 devnull free(f->text);
295 b3994ec5 2003-12-11 devnull f->ntext = 0;
296 b3994ec5 2003-12-11 devnull f->text = nil;
297 b3994ec5 2003-12-11 devnull bufclose(&f->b);
298 b3994ec5 2003-12-11 devnull bufclose(&f->delta);
299 b3994ec5 2003-12-11 devnull bufclose(&f->epsilon);
300 b3994ec5 2003-12-11 devnull elogclose(f);
301 b3994ec5 2003-12-11 devnull free(f);
302 b3994ec5 2003-12-11 devnull }
303 b3994ec5 2003-12-11 devnull
304 b3994ec5 2003-12-11 devnull void
305 b3994ec5 2003-12-11 devnull filemark(File *f)
306 b3994ec5 2003-12-11 devnull {
307 b3994ec5 2003-12-11 devnull if(f->epsilon.nc)
308 b3994ec5 2003-12-11 devnull bufdelete(&f->epsilon, 0, f->epsilon.nc);
309 b3994ec5 2003-12-11 devnull f->seq = seq;
310 b3994ec5 2003-12-11 devnull }