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 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"
14 b3994ec5 2003-12-11 devnull
15 b3994ec5 2003-12-11 devnull /*
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.
23 b3994ec5 2003-12-11 devnull */
24 b3994ec5 2003-12-11 devnull
25 b3994ec5 2003-12-11 devnull typedef struct Undo Undo;
26 b3994ec5 2003-12-11 devnull struct Undo
27 b3994ec5 2003-12-11 devnull {
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 */
33 b3994ec5 2003-12-11 devnull };
34 b3994ec5 2003-12-11 devnull
35 b3994ec5 2003-12-11 devnull enum
36 b3994ec5 2003-12-11 devnull {
37 cbeb0b26 2006-04-01 devnull Undosize = sizeof(Undo)/sizeof(Rune)
38 b3994ec5 2003-12-11 devnull };
39 b3994ec5 2003-12-11 devnull
40 b3994ec5 2003-12-11 devnull File*
41 b3994ec5 2003-12-11 devnull fileaddtext(File *f, Text *t)
42 b3994ec5 2003-12-11 devnull {
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;
46 b3994ec5 2003-12-11 devnull }
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;
51 b3994ec5 2003-12-11 devnull }
52 b3994ec5 2003-12-11 devnull
53 b3994ec5 2003-12-11 devnull void
54 b3994ec5 2003-12-11 devnull filedeltext(File *f, Text *t)
55 b3994ec5 2003-12-11 devnull {
56 b3994ec5 2003-12-11 devnull int i;
57 b3994ec5 2003-12-11 devnull
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");
62 b3994ec5 2003-12-11 devnull
63 b3994ec5 2003-12-11 devnull Found:
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);
67 b3994ec5 2003-12-11 devnull return;
68 b3994ec5 2003-12-11 devnull }
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];
72 b3994ec5 2003-12-11 devnull }
73 b3994ec5 2003-12-11 devnull
74 b3994ec5 2003-12-11 devnull void
75 b3994ec5 2003-12-11 devnull fileinsert(File *f, uint p0, Rune *s, uint ns)
76 b3994ec5 2003-12-11 devnull {
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);
82 b3994ec5 2003-12-11 devnull if(ns)
83 b3994ec5 2003-12-11 devnull f->mod = TRUE;
84 b3994ec5 2003-12-11 devnull }
85 b3994ec5 2003-12-11 devnull
86 b3994ec5 2003-12-11 devnull void
87 b3994ec5 2003-12-11 devnull fileuninsert(File *f, Buffer *delta, uint p0, uint ns)
88 b3994ec5 2003-12-11 devnull {
89 b3994ec5 2003-12-11 devnull Undo u;
90 b3994ec5 2003-12-11 devnull
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);
98 b3994ec5 2003-12-11 devnull }
99 b3994ec5 2003-12-11 devnull
100 b3994ec5 2003-12-11 devnull void
101 b3994ec5 2003-12-11 devnull filedelete(File *f, uint p0, uint p1)
102 b3994ec5 2003-12-11 devnull {
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;
110 b3994ec5 2003-12-11 devnull }
111 b3994ec5 2003-12-11 devnull
112 b3994ec5 2003-12-11 devnull void
113 b3994ec5 2003-12-11 devnull fileundelete(File *f, Buffer *delta, uint p0, uint p1)
114 b3994ec5 2003-12-11 devnull {
115 b3994ec5 2003-12-11 devnull Undo u;
116 b3994ec5 2003-12-11 devnull Rune *buf;
117 b3994ec5 2003-12-11 devnull uint i, n;
118 b3994ec5 2003-12-11 devnull
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);
132 b3994ec5 2003-12-11 devnull }
133 b3994ec5 2003-12-11 devnull fbuffree(buf);
134 b3994ec5 2003-12-11 devnull bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
135 b3994ec5 2003-12-11 devnull
136 b3994ec5 2003-12-11 devnull }
137 b3994ec5 2003-12-11 devnull
138 b3994ec5 2003-12-11 devnull void
139 b3994ec5 2003-12-11 devnull filesetname(File *f, Rune *name, int n)
140 b3994ec5 2003-12-11 devnull {
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;
148 b3994ec5 2003-12-11 devnull }
149 b3994ec5 2003-12-11 devnull
150 b3994ec5 2003-12-11 devnull void
151 b3994ec5 2003-12-11 devnull fileunsetname(File *f, Buffer *delta)
152 b3994ec5 2003-12-11 devnull {
153 b3994ec5 2003-12-11 devnull Undo u;
154 b3994ec5 2003-12-11 devnull
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);
164 b3994ec5 2003-12-11 devnull }
165 b3994ec5 2003-12-11 devnull
166 b3994ec5 2003-12-11 devnull uint
167 67dbeee5 2017-10-10 rsc fileload(File *f, uint p0, int fd, int *nulls, DigestState *h)
168 b3994ec5 2003-12-11 devnull {
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);
172 b3994ec5 2003-12-11 devnull }
173 b3994ec5 2003-12-11 devnull
174 b3994ec5 2003-12-11 devnull /* return sequence number of pending redo */
175 b3994ec5 2003-12-11 devnull uint
176 b3994ec5 2003-12-11 devnull fileredoseq(File *f)
177 b3994ec5 2003-12-11 devnull {
178 b3994ec5 2003-12-11 devnull Undo u;
179 b3994ec5 2003-12-11 devnull Buffer *delta;
180 b3994ec5 2003-12-11 devnull
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;
186 b3994ec5 2003-12-11 devnull }
187 b3994ec5 2003-12-11 devnull
188 b3994ec5 2003-12-11 devnull void
189 b3994ec5 2003-12-11 devnull fileundo(File *f, int isundo, uint *q0p, uint *q1p)
190 b3994ec5 2003-12-11 devnull {
191 b3994ec5 2003-12-11 devnull Undo u;
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;
196 b3994ec5 2003-12-11 devnull
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;
202 b3994ec5 2003-12-11 devnull }else{
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 */
207 b3994ec5 2003-12-11 devnull }
208 b3994ec5 2003-12-11 devnull
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;
217 b3994ec5 2003-12-11 devnull }
218 b3994ec5 2003-12-11 devnull }else{
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;
223 b3994ec5 2003-12-11 devnull }
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();
228 b3994ec5 2003-12-11 devnull break;
229 b3994ec5 2003-12-11 devnull
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;
239 b3994ec5 2003-12-11 devnull break;
240 b3994ec5 2003-12-11 devnull
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);
254 b3994ec5 2003-12-11 devnull }
255 b3994ec5 2003-12-11 devnull *q0p = u.p0;
256 b3994ec5 2003-12-11 devnull *q1p = u.p0+u.n;
257 b3994ec5 2003-12-11 devnull break;
258 b3994ec5 2003-12-11 devnull
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;
267 b3994ec5 2003-12-11 devnull else
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;
271 b3994ec5 2003-12-11 devnull break;
272 b3994ec5 2003-12-11 devnull }
273 b3994ec5 2003-12-11 devnull bufdelete(delta, up, delta->nc);
274 b3994ec5 2003-12-11 devnull }
275 b3994ec5 2003-12-11 devnull if(isundo)
276 b3994ec5 2003-12-11 devnull f->seq = 0;
277 b3994ec5 2003-12-11 devnull Return:
278 b3994ec5 2003-12-11 devnull fbuffree(buf);
279 b3994ec5 2003-12-11 devnull }
280 b3994ec5 2003-12-11 devnull
281 b3994ec5 2003-12-11 devnull void
282 b3994ec5 2003-12-11 devnull filereset(File *f)
283 b3994ec5 2003-12-11 devnull {
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;
287 b3994ec5 2003-12-11 devnull }
288 b3994ec5 2003-12-11 devnull
289 b3994ec5 2003-12-11 devnull void
290 b3994ec5 2003-12-11 devnull fileclose(File *f)
291 b3994ec5 2003-12-11 devnull {
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);
303 b3994ec5 2003-12-11 devnull }
304 b3994ec5 2003-12-11 devnull
305 b3994ec5 2003-12-11 devnull void
306 b3994ec5 2003-12-11 devnull filemark(File *f)
307 b3994ec5 2003-12-11 devnull {
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;
311 b3994ec5 2003-12-11 devnull }