Plan 9 from Bell Labs’s /usr/web/sources/contrib/nemo/sys/src/cmd/omero/undo.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <libc.h>
#include <thread.h>
#include <fcall.h>
#include <draw.h>
#include <mouse.h>
#include <cursor.h>
#include <keyboard.h>
#include <frame.h>
#include <9p.h>
#include <ctype.h>
#include "gui.h"

int textdebug;

static void
dumpop(char* pref, Edit* e)
{
	int	nr;

	nr = e->nr > 3 ? 3 : e->nr;
	fprint(2, "%s%c%s %3d #%d\t [%.*S]\n", pref,
		e->end ? '*' : ' ',
		e->op == Ins ? "ins" : "del",
		e->pos, e->nr, nr, e->r);
}

static void
dumpedits(Panel* p)
{
	Edit*	e;

	fprint(2, "%s edits:\n", p->name);
	for (e = p->undos; e && e < p->undo; e++)
		dumpop("\t", e);
	fprint(2, "\n");
}

Edit*
addedit(Panel* p, int op, Rune* r, int nr, int pos)
{
	Edit*	e;
	int	nlen;
	Edit*	last;

	/* merge to succesive inserts into a single one, if feasible.
	 */
	if (op == Ins && p->undos && p->undo > p->undos){
		last = p->undo - 1;
		if (last->op == Ins && !last->end && pos == last->pos + last->nr){
			nlen = (nr + last->nr) * sizeof(Rune);
			last->r = erealloc9p(last->r, nlen);
			memmove(last->r + last->nr, r, nr*sizeof(Rune));
			last->nr += nr;
			return last;
		}
	}
	if (p->undo == p->undos+p->nundos){
		if (!(p->nundos%16))
			p->undos = erealloc9p(p->undos, (p->nundos+16)*sizeof(Edit));
		e = p->undos + p->nundos++;
		p->undo = p->undos + p->nundos;
	} else {
		assert(p->undo && p->undo < p->undos+p->nundos);
		e = p->undo++;
		free(e->r);
	}
	e->r = emalloc9p(nr * sizeof(Rune));
	memmove(e->r, r, nr*sizeof(Rune));
	e->nr = nr;
	e->pos= pos;
	e->op= op;
	e->end = 0;
	if (textdebug)
		dumpedits(p);
	return e;
}

void
newedit(Panel* p)
{
	Edit*	e;

	if (p->undo && p->undo > p->undos){
		e = p->undo-1;
		e->end = 1;
	}
}

int
hasedits(Panel* p)
{
	if (!p->undo)
		return 0;
	return (p->undo - p->undos) != p->cundo;
}

void
setnoedits(Panel* p)
{
	if (!p->undo)
		p->cundo = 0;
	else
		p->cundo = p->undo - p->undos;
}

void
cleanedits(Panel* p)
{
	int	i;

	for (i = 0; i < p->nundos; i++){
		free(p->undos[i].r);
	}
	free(p->undos);
	p->undos = p->undo = nil;
	p->nundos = 0;
	p->cundo = 0;
	if (textdebug)
		dumpedits(p);
}

static int
undo1(Panel* p)
{
	int	r;

	p->undo--;
	r = p->undo->pos;
	if (p->undo->op == Ins){
		textdel(p, p->undo->r, p->undo->nr, p->undo->pos);
		filltext(p);
	} else
		textins(p, p->undo->r, p->undo->nr, p->undo->pos);
	return r;
}

int
undo(Panel* p, int* ppos)
{
	Edit*	e;
	int	some;
	int	pos;
	some = 0;
	while(p->undo && p->undo > p->undos){
		pos = undo1(p);
		if (ppos)
			*ppos = pos;
		some++;
		if (p->undo > p->undos){
			e = p->undo - 1;
			if (e->end)
				break;
		}
	}
	return some;
}

static int
redo1(Panel* p)
{
	int	r;

	r = p->undo->pos;
	if (p->undo->op == Ins)
		textins(p, p->undo->r, p->undo->nr, p->undo->pos);
	else {
		textdel(p, p->undo->r, p->undo->nr, p->undo->pos);
		filltext(p);
	}
	p->undo++;
	return r;
}

int
redo(Panel* p, int* ppos)
{
	Edit*	e;
	int	last;
	int	some;
	int	pos;

	e = p->undos + p->nundos;
	for(last = some = 0; !last && p->undo && p->undo < e; some++){
		last = p->undo->end;
		pos = redo1(p);
		if (ppos)
			*ppos = pos;
	}
	return some;
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.