xref: /plan9/sys/src/cmd/sam/moveto.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
13e12c5d1SDavid du Colombier #include "sam.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier void
moveto(File * f,Range r)43e12c5d1SDavid du Colombier moveto(File *f, Range r)
53e12c5d1SDavid du Colombier {
63e12c5d1SDavid du Colombier 	Posn p1 = r.p1, p2 = r.p2;
73e12c5d1SDavid du Colombier 
83e12c5d1SDavid du Colombier 	f->dot.r.p1 = p1;
93e12c5d1SDavid du Colombier 	f->dot.r.p2 = p2;
103e12c5d1SDavid du Colombier 	if(f->rasp){
113e12c5d1SDavid du Colombier 		telldot(f);
123e12c5d1SDavid du Colombier 		outTsl(Hmoveto, f->tag, f->dot.r.p1);
133e12c5d1SDavid du Colombier 	}
143e12c5d1SDavid du Colombier }
153e12c5d1SDavid du Colombier 
163e12c5d1SDavid du Colombier void
telldot(File * f)173e12c5d1SDavid du Colombier telldot(File *f)
183e12c5d1SDavid du Colombier {
193e12c5d1SDavid du Colombier 	if(f->rasp == 0)
203e12c5d1SDavid du Colombier 		panic("telldot");
213e12c5d1SDavid du Colombier 	if(f->dot.r.p1==f->tdot.p1 && f->dot.r.p2==f->tdot.p2)
223e12c5d1SDavid du Colombier 		return;
233e12c5d1SDavid du Colombier 	outTsll(Hsetdot, f->tag, f->dot.r.p1, f->dot.r.p2);
243e12c5d1SDavid du Colombier 	f->tdot = f->dot.r;
253e12c5d1SDavid du Colombier }
263e12c5d1SDavid du Colombier 
273e12c5d1SDavid du Colombier void
tellpat(void)283e12c5d1SDavid du Colombier tellpat(void)
293e12c5d1SDavid du Colombier {
303e12c5d1SDavid du Colombier 	outTS(Hsetpat, &lastpat);
313e12c5d1SDavid du Colombier 	patset = FALSE;
323e12c5d1SDavid du Colombier }
333e12c5d1SDavid du Colombier 
343e12c5d1SDavid du Colombier #define	CHARSHIFT	128
353e12c5d1SDavid du Colombier 
363e12c5d1SDavid du Colombier void
lookorigin(File * f,Posn p0,Posn ls)373e12c5d1SDavid du Colombier lookorigin(File *f, Posn p0, Posn ls)
383e12c5d1SDavid du Colombier {
393e12c5d1SDavid du Colombier 	int nl, nc, c;
40*7dd7cddfSDavid du Colombier 	Posn p, oldp0;
413e12c5d1SDavid du Colombier 
42*7dd7cddfSDavid du Colombier 	if(p0 > f->nc)
43*7dd7cddfSDavid du Colombier 		p0 = f->nc;
443e12c5d1SDavid du Colombier 	oldp0 = p0;
45*7dd7cddfSDavid du Colombier 	p = p0;
463e12c5d1SDavid du Colombier 	for(nl=nc=c=0; c!=-1 && nl<ls && nc<ls*CHARSHIFT; nc++)
47*7dd7cddfSDavid du Colombier 		if((c=filereadc(f, --p)) == '\n'){
483e12c5d1SDavid du Colombier 			nl++;
493e12c5d1SDavid du Colombier 			oldp0 = p0-nc;
503e12c5d1SDavid du Colombier 		}
513e12c5d1SDavid du Colombier 	if(c == -1)
523e12c5d1SDavid du Colombier 		p0 = 0;
533e12c5d1SDavid du Colombier 	else if(nl==0){
543e12c5d1SDavid du Colombier 		if(p0>=CHARSHIFT/2)
553e12c5d1SDavid du Colombier 			p0-=CHARSHIFT/2;
563e12c5d1SDavid du Colombier 		else
573e12c5d1SDavid du Colombier 			p0 = 0;
583e12c5d1SDavid du Colombier 	}else
593e12c5d1SDavid du Colombier 		p0 = oldp0;
603e12c5d1SDavid du Colombier 	outTsl(Horigin, f->tag, p0);
613e12c5d1SDavid du Colombier }
623e12c5d1SDavid du Colombier 
633e12c5d1SDavid du Colombier int
alnum(int c)643e12c5d1SDavid du Colombier alnum(int c)
653e12c5d1SDavid du Colombier {
663e12c5d1SDavid du Colombier 	/*
673e12c5d1SDavid du Colombier 	 * Hard to get absolutely right.  Use what we know about ASCII
683e12c5d1SDavid du Colombier 	 * and assume anything above the Latin control characters is
693e12c5d1SDavid du Colombier 	 * potentially an alphanumeric.
703e12c5d1SDavid du Colombier 	 */
713e12c5d1SDavid du Colombier 	if(c<=' ')
723e12c5d1SDavid du Colombier 		return 0;
733e12c5d1SDavid du Colombier 	if(0x7F<=c && c<=0xA0)
743e12c5d1SDavid du Colombier 		return 0;
753e12c5d1SDavid du Colombier 	if(utfrune("!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~", c))
763e12c5d1SDavid du Colombier 		return 0;
773e12c5d1SDavid du Colombier 	return 1;
783e12c5d1SDavid du Colombier }
793e12c5d1SDavid du Colombier 
803e12c5d1SDavid du Colombier int
clickmatch(File * f,int cl,int cr,int dir,Posn * p)81*7dd7cddfSDavid du Colombier clickmatch(File *f, int cl, int cr, int dir, Posn *p)
823e12c5d1SDavid du Colombier {
833e12c5d1SDavid du Colombier 	int c;
843e12c5d1SDavid du Colombier 	int nest = 1;
853e12c5d1SDavid du Colombier 
86*7dd7cddfSDavid du Colombier 	for(;;){
87*7dd7cddfSDavid du Colombier 		if(dir > 0){
88*7dd7cddfSDavid du Colombier 			if(*p >= f->nc)
89*7dd7cddfSDavid du Colombier 				break;
90*7dd7cddfSDavid du Colombier 			c = filereadc(f, (*p)++);
91*7dd7cddfSDavid du Colombier 		}else{
92*7dd7cddfSDavid du Colombier 			if(*p == 0)
93*7dd7cddfSDavid du Colombier 				break;
94*7dd7cddfSDavid du Colombier 			c = filereadc(f, --(*p));
95*7dd7cddfSDavid du Colombier 		}
963e12c5d1SDavid du Colombier 		if(c == cr){
973e12c5d1SDavid du Colombier 			if(--nest==0)
983e12c5d1SDavid du Colombier 				return 1;
993e12c5d1SDavid du Colombier 		}else if(c == cl)
1003e12c5d1SDavid du Colombier 			nest++;
101*7dd7cddfSDavid du Colombier 	}
1023e12c5d1SDavid du Colombier 	return cl=='\n' && nest==1;
1033e12c5d1SDavid du Colombier }
1043e12c5d1SDavid du Colombier 
1053e12c5d1SDavid du Colombier Rune*
strrune(Rune * s,Rune c)1063e12c5d1SDavid du Colombier strrune(Rune *s, Rune c)
1073e12c5d1SDavid du Colombier {
1083e12c5d1SDavid du Colombier 	Rune c1;
1093e12c5d1SDavid du Colombier 
1103e12c5d1SDavid du Colombier 	if(c == 0) {
1113e12c5d1SDavid du Colombier 		while(*s++)
1123e12c5d1SDavid du Colombier 			;
1133e12c5d1SDavid du Colombier 		return s-1;
1143e12c5d1SDavid du Colombier 	}
1153e12c5d1SDavid du Colombier 
1163e12c5d1SDavid du Colombier 	while(c1 = *s++)
1173e12c5d1SDavid du Colombier 		if(c1 == c)
1183e12c5d1SDavid du Colombier 			return s-1;
1193e12c5d1SDavid du Colombier 	return 0;
1203e12c5d1SDavid du Colombier }
1213e12c5d1SDavid du Colombier 
1223e12c5d1SDavid du Colombier void
doubleclick(File * f,Posn p1)1233e12c5d1SDavid du Colombier doubleclick(File *f, Posn p1)
1243e12c5d1SDavid du Colombier {
1253e12c5d1SDavid du Colombier 	int c, i;
1263e12c5d1SDavid du Colombier 	Rune *r, *l;
127*7dd7cddfSDavid du Colombier 	Posn p;
1283e12c5d1SDavid du Colombier 
129*7dd7cddfSDavid du Colombier 	if(p1 > f->nc)
1303e12c5d1SDavid du Colombier 		return;
1313e12c5d1SDavid du Colombier 	f->dot.r.p1 = f->dot.r.p2 = p1;
1323e12c5d1SDavid du Colombier 	for(i=0; left[i]; i++){
1333e12c5d1SDavid du Colombier 		l = left[i];
1343e12c5d1SDavid du Colombier 		r = right[i];
1353e12c5d1SDavid du Colombier 		/* try left match */
136*7dd7cddfSDavid du Colombier 		p = p1;
137*7dd7cddfSDavid du Colombier 		if(p1 == 0)
1383e12c5d1SDavid du Colombier 			c = '\n';
139*7dd7cddfSDavid du Colombier 		else
140*7dd7cddfSDavid du Colombier 			c = filereadc(f, p - 1);
141*7dd7cddfSDavid du Colombier 		if(strrune(l, c)){
142*7dd7cddfSDavid du Colombier 			if(clickmatch(f, c, r[strrune(l, c)-l], 1, &p)){
1433e12c5d1SDavid du Colombier 				f->dot.r.p1 = p1;
144*7dd7cddfSDavid du Colombier 				f->dot.r.p2 = p-(c!='\n');
1453e12c5d1SDavid du Colombier 			}
1463e12c5d1SDavid du Colombier 			return;
1473e12c5d1SDavid du Colombier 		}
1483e12c5d1SDavid du Colombier 		/* try right match */
149*7dd7cddfSDavid du Colombier 		p = p1;
150*7dd7cddfSDavid du Colombier 		if(p1 == f->nc)
1513e12c5d1SDavid du Colombier 			c = '\n';
152*7dd7cddfSDavid du Colombier 		else
153*7dd7cddfSDavid du Colombier 			c = filereadc(f, p);
154*7dd7cddfSDavid du Colombier 		if(strrune(r, c)){
155*7dd7cddfSDavid du Colombier 			if(clickmatch(f, c, l[strrune(r, c)-r], -1, &p)){
156*7dd7cddfSDavid du Colombier 				f->dot.r.p1 = p;
157*7dd7cddfSDavid du Colombier 				if(c!='\n' || p!=0 || filereadc(f, 0)=='\n')
1583e12c5d1SDavid du Colombier 					f->dot.r.p1++;
159*7dd7cddfSDavid du Colombier 				f->dot.r.p2 = p1+(p1<f->nc && c=='\n');
1603e12c5d1SDavid du Colombier 			}
1613e12c5d1SDavid du Colombier 			return;
1623e12c5d1SDavid du Colombier 		}
1633e12c5d1SDavid du Colombier 	}
1643e12c5d1SDavid du Colombier 	/* try filling out word to right */
165*7dd7cddfSDavid du Colombier 	p = p1;
166*7dd7cddfSDavid du Colombier 	while(p < f->nc && alnum(filereadc(f, p++)))
1673e12c5d1SDavid du Colombier 		f->dot.r.p2++;
1683e12c5d1SDavid du Colombier 	/* try filling out word to left */
169*7dd7cddfSDavid du Colombier 	p = p1;
170*7dd7cddfSDavid du Colombier 	while(--p >= 0 && alnum(filereadc(f, p)))
1713e12c5d1SDavid du Colombier 		f->dot.r.p1--;
1723e12c5d1SDavid du Colombier }
1733e12c5d1SDavid du Colombier 
174