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 67dbeee5 2017-10-10 rsc #include <libsec.h>
12 b3994ec5 2003-12-11 devnull #include "dat.h"
13 b3994ec5 2003-12-11 devnull #include "fns.h"
16 b3994ec5 2003-12-11 devnull * Structure of Undo list:
17 b3994ec5 2003-12-11 devnull * The Undo structure follows any associated data, so the list
18 b3994ec5 2003-12-11 devnull * can be read backwards: read the structure, then read whatever
19 b3994ec5 2003-12-11 devnull * data is associated (insert string, file name) and precedes it.
20 b3994ec5 2003-12-11 devnull * The structure includes the previous value of the modify bit
21 b3994ec5 2003-12-11 devnull * and a sequence number; successive Undo structures with the
22 b3994ec5 2003-12-11 devnull * same sequence number represent simultaneous changes.
25 b3994ec5 2003-12-11 devnull typedef struct Undo Undo;
26 b3994ec5 2003-12-11 devnull struct Undo
28 b3994ec5 2003-12-11 devnull short type; /* Delete, Insert, Filename */
29 b3994ec5 2003-12-11 devnull short mod; /* modify bit */
30 b3994ec5 2003-12-11 devnull uint seq; /* sequence number */
31 b3994ec5 2003-12-11 devnull uint p0; /* location of change (unused in f) */
32 b3994ec5 2003-12-11 devnull uint n; /* # runes in string or file name */
37 cbeb0b26 2006-04-01 devnull Undosize = sizeof(Undo)/sizeof(Rune)
41 b3994ec5 2003-12-11 devnull fileaddtext(File *f, Text *t)
43 b3994ec5 2003-12-11 devnull if(f == nil){
44 b3994ec5 2003-12-11 devnull f = emalloc(sizeof(File));
45 b3994ec5 2003-12-11 devnull f->unread = TRUE;
47 b3994ec5 2003-12-11 devnull f->text = realloc(f->text, (f->ntext+1)*sizeof(Text*));
48 b3994ec5 2003-12-11 devnull f->text[f->ntext++] = t;
49 b3994ec5 2003-12-11 devnull f->curtext = t;
50 b3994ec5 2003-12-11 devnull return f;
54 b3994ec5 2003-12-11 devnull filedeltext(File *f, Text *t)
58 b3994ec5 2003-12-11 devnull for(i=0; i<f->ntext; i++)
59 b3994ec5 2003-12-11 devnull if(f->text[i] == t)
60 b3994ec5 2003-12-11 devnull goto Found;
61 b3994ec5 2003-12-11 devnull error("can't find text in filedeltext");
64 b3994ec5 2003-12-11 devnull f->ntext--;
65 b3994ec5 2003-12-11 devnull if(f->ntext == 0){
66 b3994ec5 2003-12-11 devnull fileclose(f);
69 b3994ec5 2003-12-11 devnull memmove(f->text+i, f->text+i+1, (f->ntext-i)*sizeof(Text*));
70 b3994ec5 2003-12-11 devnull if(f->curtext == t)
71 b3994ec5 2003-12-11 devnull f->curtext = f->text[0];
75 b3994ec5 2003-12-11 devnull fileinsert(File *f, uint p0, Rune *s, uint ns)
77 b3994ec5 2003-12-11 devnull if(p0 > f->b.nc)
78 b3994ec5 2003-12-11 devnull error("internal error: fileinsert");
79 b3994ec5 2003-12-11 devnull if(f->seq > 0)
80 b3994ec5 2003-12-11 devnull fileuninsert(f, &f->delta, p0, ns);
81 b3994ec5 2003-12-11 devnull bufinsert(&f->b, p0, s, ns);
83 b3994ec5 2003-12-11 devnull f->mod = TRUE;
87 b3994ec5 2003-12-11 devnull fileuninsert(File *f, Buffer *delta, uint p0, uint ns)
91 b3994ec5 2003-12-11 devnull /* undo an insertion by deleting */
92 b3994ec5 2003-12-11 devnull u.type = Delete;
93 b3994ec5 2003-12-11 devnull u.mod = f->mod;
94 b3994ec5 2003-12-11 devnull u.seq = f->seq;
95 b3994ec5 2003-12-11 devnull u.p0 = p0;
96 b3994ec5 2003-12-11 devnull u.n = ns;
97 b3994ec5 2003-12-11 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
101 b3994ec5 2003-12-11 devnull filedelete(File *f, uint p0, uint p1)
103 b3994ec5 2003-12-11 devnull if(!(p0<=p1 && p0<=f->b.nc && p1<=f->b.nc))
104 b3994ec5 2003-12-11 devnull error("internal error: filedelete");
105 b3994ec5 2003-12-11 devnull if(f->seq > 0)
106 b3994ec5 2003-12-11 devnull fileundelete(f, &f->delta, p0, p1);
107 b3994ec5 2003-12-11 devnull bufdelete(&f->b, p0, p1);
108 b3994ec5 2003-12-11 devnull if(p1 > p0)
109 b3994ec5 2003-12-11 devnull f->mod = TRUE;
113 b3994ec5 2003-12-11 devnull fileundelete(File *f, Buffer *delta, uint p0, uint p1)
116 b3994ec5 2003-12-11 devnull Rune *buf;
117 b3994ec5 2003-12-11 devnull uint i, n;
119 b3994ec5 2003-12-11 devnull /* undo a deletion by inserting */
120 b3994ec5 2003-12-11 devnull u.type = Insert;
121 b3994ec5 2003-12-11 devnull u.mod = f->mod;
122 b3994ec5 2003-12-11 devnull u.seq = f->seq;
123 b3994ec5 2003-12-11 devnull u.p0 = p0;
124 b3994ec5 2003-12-11 devnull u.n = p1-p0;
125 b3994ec5 2003-12-11 devnull buf = fbufalloc();
126 b3994ec5 2003-12-11 devnull for(i=p0; i<p1; i+=n){
127 b3994ec5 2003-12-11 devnull n = p1 - i;
128 b3994ec5 2003-12-11 devnull if(n > RBUFSIZE)
129 b3994ec5 2003-12-11 devnull n = RBUFSIZE;
130 b3994ec5 2003-12-11 devnull bufread(&f->b, i, buf, n);
131 b3994ec5 2003-12-11 devnull bufinsert(delta, delta->nc, buf, n);
133 b3994ec5 2003-12-11 devnull fbuffree(buf);
134 b3994ec5 2003-12-11 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
139 b3994ec5 2003-12-11 devnull filesetname(File *f, Rune *name, int n)
141 b3994ec5 2003-12-11 devnull if(f->seq > 0)
142 b3994ec5 2003-12-11 devnull fileunsetname(f, &f->delta);
143 b3994ec5 2003-12-11 devnull free(f->name);
144 b3994ec5 2003-12-11 devnull f->name = runemalloc(n);
145 b3994ec5 2003-12-11 devnull runemove(f->name, name, n);
146 b3994ec5 2003-12-11 devnull f->nname = n;
147 b3994ec5 2003-12-11 devnull f->unread = TRUE;
151 b3994ec5 2003-12-11 devnull fileunsetname(File *f, Buffer *delta)
155 b3994ec5 2003-12-11 devnull /* undo a file name change by restoring old name */
156 b3994ec5 2003-12-11 devnull u.type = Filename;
157 b3994ec5 2003-12-11 devnull u.mod = f->mod;
158 b3994ec5 2003-12-11 devnull u.seq = f->seq;
159 b3994ec5 2003-12-11 devnull u.p0 = 0; /* unused */
160 b3994ec5 2003-12-11 devnull u.n = f->nname;
161 b3994ec5 2003-12-11 devnull if(f->nname)
162 b3994ec5 2003-12-11 devnull bufinsert(delta, delta->nc, f->name, f->nname);
163 b3994ec5 2003-12-11 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
167 67dbeee5 2017-10-10 rsc fileload(File *f, uint p0, int fd, int *nulls, DigestState *h)
169 b3994ec5 2003-12-11 devnull if(f->seq > 0)
170 b3994ec5 2003-12-11 devnull error("undo in file.load unimplemented");
171 67dbeee5 2017-10-10 rsc return bufload(&f->b, p0, fd, nulls, h);
174 b3994ec5 2003-12-11 devnull /* return sequence number of pending redo */
176 b3994ec5 2003-12-11 devnull fileredoseq(File *f)
179 b3994ec5 2003-12-11 devnull Buffer *delta;
181 b3994ec5 2003-12-11 devnull delta = &f->epsilon;
182 b3994ec5 2003-12-11 devnull if(delta->nc == 0)
183 b3994ec5 2003-12-11 devnull return 0;
184 b3994ec5 2003-12-11 devnull bufread(delta, delta->nc-Undosize, (Rune*)&u, Undosize);
185 b3994ec5 2003-12-11 devnull return u.seq;
189 b3994ec5 2003-12-11 devnull fileundo(File *f, int isundo, uint *q0p, uint *q1p)
192 b3994ec5 2003-12-11 devnull Rune *buf;
193 b3994ec5 2003-12-11 devnull uint i, j, n, up;
194 b3994ec5 2003-12-11 devnull uint stop;
195 b3994ec5 2003-12-11 devnull Buffer *delta, *epsilon;
197 b3994ec5 2003-12-11 devnull if(isundo){
198 b3994ec5 2003-12-11 devnull /* undo; reverse delta onto epsilon, seq decreases */
199 b3994ec5 2003-12-11 devnull delta = &f->delta;
200 b3994ec5 2003-12-11 devnull epsilon = &f->epsilon;
201 b3994ec5 2003-12-11 devnull stop = f->seq;
203 b3994ec5 2003-12-11 devnull /* redo; reverse epsilon onto delta, seq increases */
204 b3994ec5 2003-12-11 devnull delta = &f->epsilon;
205 b3994ec5 2003-12-11 devnull epsilon = &f->delta;
206 b3994ec5 2003-12-11 devnull stop = 0; /* don't know yet */
209 b3994ec5 2003-12-11 devnull buf = fbufalloc();
210 b3994ec5 2003-12-11 devnull while(delta->nc > 0){
211 b3994ec5 2003-12-11 devnull up = delta->nc-Undosize;
212 b3994ec5 2003-12-11 devnull bufread(delta, up, (Rune*)&u, Undosize);
213 b3994ec5 2003-12-11 devnull if(isundo){
214 b3994ec5 2003-12-11 devnull if(u.seq < stop){
215 b3994ec5 2003-12-11 devnull f->seq = u.seq;
216 b3994ec5 2003-12-11 devnull goto Return;
219 b3994ec5 2003-12-11 devnull if(stop == 0)
220 b3994ec5 2003-12-11 devnull stop = u.seq;
221 b3994ec5 2003-12-11 devnull if(u.seq > stop)
222 b3994ec5 2003-12-11 devnull goto Return;
224 b3994ec5 2003-12-11 devnull switch(u.type){
225 b3994ec5 2003-12-11 devnull default:
226 b3994ec5 2003-12-11 devnull fprint(2, "undo: 0x%ux\n", u.type);
227 b3994ec5 2003-12-11 devnull abort();
230 b3994ec5 2003-12-11 devnull case Delete:
231 b3994ec5 2003-12-11 devnull f->seq = u.seq;
232 b3994ec5 2003-12-11 devnull fileundelete(f, epsilon, u.p0, u.p0+u.n);
233 b3994ec5 2003-12-11 devnull f->mod = u.mod;
234 b3994ec5 2003-12-11 devnull bufdelete(&f->b, u.p0, u.p0+u.n);
235 b3994ec5 2003-12-11 devnull for(j=0; j<f->ntext; j++)
236 b3994ec5 2003-12-11 devnull textdelete(f->text[j], u.p0, u.p0+u.n, FALSE);
237 b3994ec5 2003-12-11 devnull *q0p = u.p0;
238 b3994ec5 2003-12-11 devnull *q1p = u.p0;
241 b3994ec5 2003-12-11 devnull case Insert:
242 b3994ec5 2003-12-11 devnull f->seq = u.seq;
243 b3994ec5 2003-12-11 devnull fileuninsert(f, epsilon, u.p0, u.n);
244 b3994ec5 2003-12-11 devnull f->mod = u.mod;
245 b3994ec5 2003-12-11 devnull up -= u.n;
246 b3994ec5 2003-12-11 devnull for(i=0; i<u.n; i+=n){
247 b3994ec5 2003-12-11 devnull n = u.n - i;
248 b3994ec5 2003-12-11 devnull if(n > RBUFSIZE)
249 b3994ec5 2003-12-11 devnull n = RBUFSIZE;
250 b3994ec5 2003-12-11 devnull bufread(delta, up+i, buf, n);
251 b3994ec5 2003-12-11 devnull bufinsert(&f->b, u.p0+i, buf, n);
252 b3994ec5 2003-12-11 devnull for(j=0; j<f->ntext; j++)
253 b3994ec5 2003-12-11 devnull textinsert(f->text[j], u.p0+i, buf, n, FALSE);
255 b3994ec5 2003-12-11 devnull *q0p = u.p0;
256 b3994ec5 2003-12-11 devnull *q1p = u.p0+u.n;
259 b3994ec5 2003-12-11 devnull case Filename:
260 b3994ec5 2003-12-11 devnull f->seq = u.seq;
261 b3994ec5 2003-12-11 devnull fileunsetname(f, epsilon);
262 b3994ec5 2003-12-11 devnull f->mod = u.mod;
263 b3994ec5 2003-12-11 devnull up -= u.n;
264 b3994ec5 2003-12-11 devnull free(f->name);
265 b3994ec5 2003-12-11 devnull if(u.n == 0)
266 b3994ec5 2003-12-11 devnull f->name = nil;
268 b3994ec5 2003-12-11 devnull f->name = runemalloc(u.n);
269 b3994ec5 2003-12-11 devnull bufread(delta, up, f->name, u.n);
270 b3994ec5 2003-12-11 devnull f->nname = u.n;
273 b3994ec5 2003-12-11 devnull bufdelete(delta, up, delta->nc);
275 b3994ec5 2003-12-11 devnull if(isundo)
276 b3994ec5 2003-12-11 devnull f->seq = 0;
278 b3994ec5 2003-12-11 devnull fbuffree(buf);
282 b3994ec5 2003-12-11 devnull filereset(File *f)
284 b3994ec5 2003-12-11 devnull bufreset(&f->delta);
285 b3994ec5 2003-12-11 devnull bufreset(&f->epsilon);
286 b3994ec5 2003-12-11 devnull f->seq = 0;
290 b3994ec5 2003-12-11 devnull fileclose(File *f)
292 b3994ec5 2003-12-11 devnull free(f->name);
293 b3994ec5 2003-12-11 devnull f->nname = 0;
294 b3994ec5 2003-12-11 devnull f->name = nil;
295 b3994ec5 2003-12-11 devnull free(f->text);
296 b3994ec5 2003-12-11 devnull f->ntext = 0;
297 b3994ec5 2003-12-11 devnull f->text = nil;
298 b3994ec5 2003-12-11 devnull bufclose(&f->b);
299 b3994ec5 2003-12-11 devnull bufclose(&f->delta);
300 b3994ec5 2003-12-11 devnull bufclose(&f->epsilon);
301 b3994ec5 2003-12-11 devnull elogclose(f);
302 b3994ec5 2003-12-11 devnull free(f);
306 b3994ec5 2003-12-11 devnull filemark(File *f)
308 b3994ec5 2003-12-11 devnull if(f->epsilon.nc)
309 b3994ec5 2003-12-11 devnull bufdelete(&f->epsilon, 0, f->epsilon.nc);
310 b3994ec5 2003-12-11 devnull f->seq = seq;