522 lines · 9.0 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <draw.h>#include <memdraw.h>#include <thread.h>#include <cursor.h>#include <mouse.h>#include <keyboard.h>#include <frame.h>#include <plumb.h>#include <html.h>#include "dat.h"#include "fns.h" void	del(Text *, Text *, int, int, Rune *, int);void	delcol(Text *, Text *, int, int, Rune *, int);void	cut(Text *, Text *, int, int, Rune *, int);void	exit(Text *, Text *, int, int, Rune *, int);void	get(Text *, Text *, int, int, Rune *, int);void	go(Text *,Text *,  int, int, Rune *, int);void	google(Text *,Text *,  int, int, Rune *, int);void	new(Text*, Text *, int, int, Rune *, int);void	newcol(Text*, Text *, int, int, Rune *, int);void	paste(Text *, Text *, int, int, Rune *, int);void	sort(Text *, Text *, int, int, Rune *, int);void	stop(Text *, Text *, int, int, Rune *, int);void	debug(Text *, Text *, int, int, Rune *, int); typedef struct Exectab Exectab;struct Exectab{	Rune	*name;	void	(*fn)(Text *, Text *, int, int, Rune *, int);	int		flag1;	int		flag2;}; Exectab exectab[] = {	{ L"Back",		go,		FALSE,	XXX		},	{ L"Cut",		cut,		TRUE,	TRUE	},	{ L"Debug",	debug,	XXX,		XXX		},	{ L"Del",		del,		XXX,		XXX		},	{ L"Delcol",	delcol,	FALSE,	TRUE	},	{ L"Exit",		exit,		XXX,		XXX		},	{ L"Get",		get,		XXX,		XXX		},	{ L"New",		new,		XXX,		XXX		},	{ L"Newcol",	newcol,	XXX,		XXX		},	{ L"Next",		go,		TRUE,	XXX		},	{ L"Paste",		paste,	TRUE,	XXX		},	{ L"Snarf",		cut,		TRUE,	FALSE	},	{ L"Stop",		stop,		XXX,		XXX		},	{ L"Sort",		sort,		XXX,		XXX		},	{ nil, 			nil,		0,		0		},}; staticExectab*lookup(Rune *r, int n){	Exectab *e;	int nr; 	r = skipbl(r, n, &n);	if(n == 0)		return nil;	findbl(r, n, &nr);	nr = n-nr;	for(e=exectab; e->name; e++)		if(runeeq(r, nr, e->name, runestrlen(e->name)) == TRUE)			return e;	return nil;} intisexecc(int c){	if(isalnum(c))		return 1;	return c=='<' || c=='|' || c=='>';} voidexecute(Text *t, uint aq0, uint aq1, Text *){	uint q0, q1;	Rune *r, *s;	Exectab *e;	int c, n; 	q0 = aq0;	q1 = aq1;	if(q1 == q0){	/* expand to find word (actually file name) */		/* if in selection, choose selection */		if(t->q1>t->q0 && t->q0<=q0 && q0<=t->q1){			q0 = t->q0;			q1 = t->q1;		}else{			while(q1<t->rs.nr && isexecc(c=t->rs.r[q1]) && c!=':')				q1++;			while(q0>0 && isexecc(c=t->rs.r[q0-1]) && c!=':')				q0--;			if(q1 == q0)				return;		}	}	r = runemalloc(q1-q0);	runemove(r, t->rs.r+q0, q1-q0);	e = lookup(r, q1-q0);	if(e){		s = skipbl(r, q1-q0, &n);		s = findbl(s, n, &n);		s = skipbl(s, n, &n);		(*e->fn)(t, seltext, e->flag1, e->flag2, s, n);	}	free(r);} voidnewcol(Text *et, Text *, int, int, Rune *, int){	Column *c; 	c = rowadd(et->row, nil, -1);	if(c)		winsettag(coladd(c, nil, nil, -1));} voiddelcol(Text *t, Text *, int, int, Rune *, int){	Column *c; 	c = t->col;	if(c==nil || colclean(c)==0)		return; 	rowclose(c->row, c, TRUE);} voiddel(Text *et, Text *, int flag1, int, Rune *, int){	if(et==nil || et->w==nil)		return; 	if(flag1 || winclean(et->w, FALSE))		colclose(et->col, et->w, TRUE);} voidsort(Text *et, Text *, int, int, Rune *, int){	if(et->col)		colsort(et->col);} voidexit(Text *, Text *, int, int, Rune *, int){	sendul(cexit, 0);	threadexits(nil);} voiddebug(Text *, Text *, int, int, Rune *, int){	Column *c;	int i, j; 	for(j=0; j<row.ncol; j++){		c = row.col[j];		for(i=0; i<c->nw; i++){			fprint(2, "Col: %d; Win: %d\n", j, i);			windebug(c->w[i]);		}	}} voidstop(Text *t, Text *, int, int, Rune *, int){	if(t==nil || t->w==nil)		return; 	pageabort(&t->w->page);} voidget(Text *t, Text *, int, int, Rune *, int){	Window *w;	int dohist; 	if(t==nil || t->w==nil)		return;	w = t->w;	if(w->url.rs.nr == 0)		return; 	dohist = FALSE;	if(w->page.url==nil || runestreq(w->page.url->act, w->url.rs)==FALSE)		dohist = TRUE; 	pageget(&w->page, &w->url.rs, nil, HGet, dohist);} voidgo(Text *et, Text *t, int isnext, int, Rune *, int){	if(et!=nil && et->w!=nil)		t = et;	if(t==nil || t->w==nil)		return; 	wingohist(t->w, isnext);} voidcut(Text *, Text *t, int dosnarf, int docut, Rune *, int){	Runestr rs;	uint u; 	if(selpage){		if(dosnarf && !docut && !eqpt(selpage->top, selpage->bot))			pagesnarf(selpage);		return;	}	if(t==nil){		/* can only happen if seltext == nil */		return;	}	if(t->q0 > t->q1){		u = t->q0;		t->q0 = t->q1;		t->q1 =u;	} 	if(t->q0 == t->q1)		return; 	if(dosnarf){		rs.nr = t->q1-t->q0;		rs.r = runemalloc(rs.nr);		runemove(rs.r, t->rs.r+t->q0, rs.nr);		putsnarf(&rs);		closerunestr(&rs);	}	if(docut){		textdelete(t, t->q0, t->q1);		textsetselect(t, t->q0, t->q0);		if(t->w)			textscrdraw(t);	}else if(dosnarf)	/* Snarf command */		argtext = t;} voidpaste(Text *, Text *t, int selectall, int, Rune *, int){	Runestr rs;	uint q1; 	if(t == nil)		return; 	getsnarf(&rs);	if(rs.nr == 0)		return; 	cut(t, t, FALSE, TRUE, nil, 0);	textinsert(t, t->q0, rs.r, rs.nr);	q1 = t->q0+rs.nr;	if(selectall)		textsetselect(t, t->q0, q1);	else		textsetselect(t, q1, q1);	if(t->w)		textscrdraw(t); 	closerunestr(&rs);} typedef	struct	Expand Expand; struct Expand{	uint	q0;	uint	q1;	Rune	*name;	int	nname;	int	jump;	union{		Text	*at;		Rune	*ar;	};	int	(*agetc)(void*, uint);	int	a0;	int	a1;}; intexpand(Text *t, uint q0, uint q1, Expand *e){	memset(e, 0, sizeof *e); 	/* if in selection, choose selection */	e->jump = TRUE;	if(q1==q0 && t->q1>t->q0 && t->q0<=q0 && q0<=t->q1){		q0 = t->q0;		q1 = t->q1;//		if(t->what == Tag)			e->jump = FALSE;	}	if(q0 == q1){		while(q1<t->rs.nr && isalnum(t->rs.r[q1]))			q1++;		while(q0>0 && isalnum(t->rs.r[q0-1]))			q0--;	}	e->q0 = q0;	e->q1 = q1;	return q1 > q0;} voidlook3(Text *t, uint q0, uint q1){	Expand e;	Text *ct;	Runestr rs;	char buf[32];	Rune *r, c;	uint p;	int n; 	ct = seltext;	if(ct == nil)		ct = seltext = t;	if(expand(t, q0, q1, &e) == FALSE)		return;	if(plumbsendfd >= 0){		/* send whitespace-delimited word to plumber */		buf[0] = '\0';		if(q1 == q0){			if(t->q1>t->q0 && t->q0<=q0 && q0<=t->q1){				q0 = t->q0;				q1 = t->q1;			}else{				p = q0;				while(q0>0 && (c=t->rs.r[q0-1])!=L' ' && c!=L'\t' && c!=L'\n')					q0--;				while(q1<t->rs.nr && (c=t->rs.r[q1])!=L' ' && c!=L'\t' && c!=L'\n')					q1++;				if(q1 == q0)					return;				sprint(buf, "click=%d", p-q0);			}		}		rs.r = runemalloc(q1-q0);		runemove(rs.r, t->rs.r+q0, q1-q0);		rs.nr = q1-q0;		if(plumbrunestr(&rs, buf) >= 0){			closerunestr(&rs);			return;		}		/* plumber failed to match; fall through */	}	if(t == ct)		textsetselect(ct, e.q1, e.q1);	n = e.q1 - e.q0;	r = runemalloc(n);	runemove(r, t->rs.r+e.q0, n);	if(search(ct, r, n) /*&& e.jump*/)		moveto(mousectl, addpt(frptofchar(ct, ct->p0), Pt(4, ct->font->height-4))); 	free(r);} intsearch(Text *ct, Rune *r, uint n){	uint q, nb, maxn;	int around;	Rune *s, *b, *c; 	if(n==0 || n>ct->rs.nr || 2*n>RBUFSIZE)		return FALSE; 	maxn = max(n*2, RBUFSIZE);	s = runemalloc(RBUFSIZE);	b = s;	nb = 0;	b[nb] = 0;	around = 0;	q = ct->q1;	for(;;){		if(q >= ct->rs.nr){			q = 0;			around = 1;			nb = 0;			b[nb] = 0;		}		if(nb > 0){			c = runestrchr(b, r[0]);			if(c == nil){				q += nb;				nb = 0;				b[nb] = 0;				if(around && q>=ct->q1)					break;				continue;			}			q += (c-b);			nb -= (c-b);			b = c;		}		/* reload if buffer covers neither string nor rest of file */		if(nb<n && nb!=ct->rs.nr-q){			nb = ct->rs.nr-q;			if(nb >= maxn)				nb = maxn-1;//			bufread(ct->file, q, s, nb);			runemove(s, ct->rs.r+q, nb);			b = s;			b[nb] = '\0';		}		/* this runeeq is fishy but the null at b[nb] makes it safe */		if(runeeq(b, n, r, n) == TRUE){			if(ct->w)				textshow(ct, q, q+n, 1);			else{				ct->q0 = q;				ct->q1 = q+n;			}			seltext = ct;			free(s);			return TRUE;		}		if(around && q>=ct->q1)			break;		--nb;		b++;		q++;	}	free(s);	return FALSE;} Window*lookpage(Rune *s, int n){	int i, j;	Window *w;	Column *c;	Page *p; 	/* avoid terminal slash on directories */	if(n>1 && s[n-1] == '/')		--n;	for(j=0; j<row.ncol; j++){		c = row.col[j];		for(i=0; i<c->nw; i++){			w = c->w[i];			p = &w->page;			if(p->url && runeeq(p->url->src.r, p->url->src.nr, s, n))				if(w->col != nil)					return w;		}	}	return nil;}extern void urlconvience(Url*);Window *openpage(Page *p, Runestr *rs){	Window *w;	Url u; 	u.src = *rs;	urlconvience(&u);	*rs = u.src; 	if(!validurl(rs->r))		return nil; 	w = lookpage(rs->r, rs->nr);	if(w){		p = &w->page;		if(!p->col->safe && Dy(p->r)==0) /* window is obscured by full-column window */			colgrow(p->col, p->col->w[0], 1);	}else{		w = makenewwindow(p);		winsettag(w);		pageget(&w->page, rs, nil, HGet, TRUE);	}	return w;} void

Lines 1–500 of 522.