void filemark(File *f) { if(f->epsilon.nc) bufdelete(&f->epsilon, 0, f->epsilon.nc); f->seq = seq; }
void filedelete(File *f, uint p0, uint p1) { if(!(p0<=p1 && p0<=f->b.nc && p1<=f->b.nc)) error("internal error: filedelete"); if(f->seq > 0) fileundelete(f, &f->delta, p0, p1); bufdelete(&f->b, p0, p1); if(p1 > p0) f->mod = TRUE; }
void filemark(File *f) { if(f->unread) return; if(f->epsilon.nc) bufdelete(&f->epsilon, 0, f->epsilon.nc); if(f != cmd){ f->prevdot = f->dot.r; f->prevmark = f->mark; f->prevseq = f->seq; f->prevmod = f->mod; } f->ndot = f->dot; f->seq = seq; f->hiposn = 0; }
void hiccough(char *s) { File *f; int i; if(rescuing) exits("rescue"); if(s) dprint("%s\n", s); resetcmd(); resetxec(); resetsys(); if(io > 0) close(io); /* * back out any logged changes & restore old sequences */ for(i=0; i<file.nused; i++) { f = file.filepptr[i]; if(f==cmd) continue; if(f->seq==seq) { bufdelete(&f->epsilon, 0, f->epsilon.nc); f->seq = f->prevseq; f->dot.r = f->prevdot; f->mark = f->prevmark; state(f, f->prevmod ? Dirty: Clean); } } update(); if (curfile) { if (curfile->unread) curfile->unread = FALSE; else if (downloaded) outTs(Hcurrent, curfile->tag); } longjmp(mainloop, 1); }
void fileundo(File *f, int isundo, uint *q0p, uint *q1p) { Undo u; Rune *buf; uint i, j, n, up; uint stop; Buffer *delta, *epsilon; if(isundo){ /* undo; reverse delta onto epsilon, seq decreases */ delta = &f->delta; epsilon = &f->epsilon; stop = f->seq; }else{ /* redo; reverse epsilon onto delta, seq increases */ delta = &f->epsilon; epsilon = &f->delta; stop = 0; /* don't know yet */ } buf = fbufalloc(); while(delta->nc > 0){ up = delta->nc-Undosize; bufread(delta, up, (Rune*)&u, Undosize); if(isundo){ if(u.seq < stop){ f->seq = u.seq; goto Return; } }else{ if(stop == 0) stop = u.seq; if(u.seq > stop) goto Return; } switch(u.type){ default: fprint(2, "undo: 0x%ux\n", u.type); abort(); break; case Delete: f->seq = u.seq; fileundelete(f, epsilon, u.p0, u.p0+u.n); f->mod = u.mod; bufdelete(&f->b, u.p0, u.p0+u.n); for(j=0; j<f->ntext; j++) textdelete(f->text[j], u.p0, u.p0+u.n, FALSE); *q0p = u.p0; *q1p = u.p0; break; case Insert: f->seq = u.seq; fileuninsert(f, epsilon, u.p0, u.n); f->mod = u.mod; up -= u.n; for(i=0; i<u.n; i+=n){ n = u.n - i; if(n > RBUFSIZE) n = RBUFSIZE; bufread(delta, up+i, buf, n); bufinsert(&f->b, u.p0+i, buf, n); for(j=0; j<f->ntext; j++) textinsert(f->text[j], u.p0+i, buf, n, FALSE); } *q0p = u.p0; *q1p = u.p0+u.n; break; case Filename: f->seq = u.seq; fileunsetname(f, epsilon); f->mod = u.mod; up -= u.n; free(f->name); if(u.n == 0) f->name = nil; else f->name = runemalloc(u.n); bufread(delta, up, f->name, u.n); f->nname = u.n; break; } bufdelete(delta, up, delta->nc); } if(isundo) f->seq = 0; Return: fbuffree(buf); }
void fileundo(File *f, int isundo, int canredo, uint *q0p, uint *q1p, int flag) { Undo u; Rune *buf; uint i, n, up; uint stop; Buffer *delta, *epsilon; if(isundo){ /* undo; reverse delta onto epsilon, seq decreases */ delta = &f->delta; epsilon = &f->epsilon; stop = f->seq; }else{ /* redo; reverse epsilon onto delta, seq increases */ delta = &f->epsilon; epsilon = &f->delta; stop = 0; /* don't know yet */ } raspstart(f); while(delta->nc > 0){ /* rasp and buffer are in sync; sync with wire if needed */ if(needoutflush()) raspflush(f); up = delta->nc-Undosize; bufread(delta, up, (Rune*)&u, Undosize); if(isundo){ if(u.seq < stop){ f->seq = u.seq; raspdone(f, flag); return; } }else{ if(stop == 0) stop = u.seq; if(u.seq > stop){ raspdone(f, flag); return; } } switch(u.type){ default: panic("undo unknown u.type"); break; case Delete: f->seq = u.seq; if(canredo) fileundelete(f, epsilon, u.p0, u.p0+u.n); f->mod = u.mod; bufdelete(&f->Buffer, u.p0, u.p0+u.n); raspdelete(f, u.p0, u.p0+u.n, flag); *q0p = u.p0; *q1p = u.p0; break; case Insert: f->seq = u.seq; if(canredo) fileuninsert(f, epsilon, u.p0, u.n); f->mod = u.mod; up -= u.n; buf = fbufalloc(); for(i=0; i<u.n; i+=n){ n = u.n - i; if(n > RBUFSIZE) n = RBUFSIZE; bufread(delta, up+i, buf, n); bufinsert(&f->Buffer, u.p0+i, buf, n); raspinsert(f, u.p0+i, buf, n, flag); } fbuffree(buf); *q0p = u.p0; *q1p = u.p0+u.n; break; case Filename: f->seq = u.seq; if(canredo) fileunsetname(f, epsilon); f->mod = u.mod; up -= u.n; Strinsure(&f->name, u.n+1); bufread(delta, up, f->name.s, u.n); f->name.s[u.n] = 0; f->name.n = u.n; fixname(&f->name); sortname(f); break; case Dot: f->seq = u.seq; if(canredo) fileunsetdot(f, epsilon, f->dot.r); f->mod = u.mod; f->dot.r.p1 = u.p0; f->dot.r.p2 = u.p0 + u.n; break; case Mark: f->seq = u.seq; if(canredo) fileunsetmark(f, epsilon, f->mark); f->mod = u.mod; f->mark.p1 = u.p0; f->mark.p2 = u.p0 + u.n; break; } bufdelete(delta, up, delta->nc); } if(isundo) f->seq = 0; raspdone(f, flag); }