Beispiel #1
0
void
filemark(File *f)
{
	if(f->epsilon.nc)
		bufdelete(&f->epsilon, 0, f->epsilon.nc);
	f->seq = seq;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
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);
}
Beispiel #5
0
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);
}
Beispiel #6
0
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);
}