V9/jtools/src/sam/moveto.c
#include "sam.h"
moveto(f, r)
register File *f;
Range r;
{
register Posn p1=r.p1, p2=r.p2;
f->dot.r.p1=p1;
f->dot.r.p2=p2;
if(f->rasp){
telldot(f);
outTsl(Hmoveto, f->tag, f->dot.r.p1);
}
}
telldot(f)
register File *f;
{
if(f->rasp==0)
panic("telldot");
if(f->dot.r.p1==f->tdot.p1 && f->dot.r.p2==f->tdot.p2)
return;
outTsll(Hsetdot, f->tag, f->dot.r.p1, f->dot.r.p2);
f->tdot=f->dot.r;
}
tellpat()
{
uchar buf[16];
bcopy(lastpat.s, lastpat.s+15, buf, 1);
buf[15]=0;
outTS(Hsetpat, buf);
patset=FALSE;
}
#define CHARSHIFT 128
lookorigin(f, p0, ls)
register File *f;
register Posn p0, ls;
{
register nl, nc, c;
register Posn oldp0;
if(p0>f->nbytes)
p0=f->nbytes;
oldp0=p0;
Fgetcset(f, p0);
for(nl=nc=c=0; c!=-1 && nl<ls && nc<ls*CHARSHIFT; nc++)
if((c=Fbgetc(f))=='\n'){
nl++;
oldp0=p0-nc;
}
if(c==-1)
p0=0;
else if(nl==0){
if(p0>=CHARSHIFT/2)
p0-=CHARSHIFT/2;
else
p0=0;
}else
p0=oldp0;
outTsl(Horigin, f->tag, p0);
}
char *left[]= {
"{[(<",
"\n",
"'\"`",
0
};
char *right[]= {
"}])>",
"\n",
"'\"`",
0
};
doubleclick(f, p1)
register File *f;
register Posn p1;
{
register c, i;
register char *r, *l;
if(p1>f->nbytes)
return;
f->dot.r.p1=f->dot.r.p2=p1;
for(i=0; left[i]; i++){
l=left[i];
r=right[i];
/* try left match */
if(p1==0){
Fgetcset(f, p1);
c='\n';
}else{
Fgetcset(f, p1-1);
c=Fgetc(f);
}
if(strchr(l, c)){
if(clickmatch(f, c, r[strchr(l, c)-l], 1)){
f->dot.r.p1=p1;
f->dot.r.p2=f->getcp-(c!='\n');
}
return;
}
/* try right match */
if(p1==f->nbytes){
Fbgetcset(f, p1);
c='\n';
}else{
Fbgetcset(f, p1+1);
c=Fbgetc(f);
}
if(strchr(r, c)){
if(clickmatch(f, c, l[strchr(r, c)-r], -1)){
f->dot.r.p1=f->getcp;
if(c!='\n' || f->getcp!=0 ||
(Fgetcset(f, (Posn)0),Fgetc(f))=='\n')
f->dot.r.p1++;
f->dot.r.p2=p1+(p1<f->nbytes && c=='\n');
}
return;
}
}
/* try filling out word to right */
Fgetcset(f, p1);
while(alnum(Fgetc(f)))
f->dot.r.p2++;
/* try filling out word to left */
Fbgetcset(f, p1);
while(alnum(Fbgetc(f)))
f->dot.r.p1--;
}
alnum(c)
register c;
{
return ('0'<=c && c<='9') || (c=='_') ||
('a'<=c && c<='z') || ('A'<=c && c<='Z');
}
clickmatch(f, cl, cr, dir)
register File *f;
register cl, cr;
int dir;
{
register c;
register nest=1;
while((c=(dir>0? Fgetc(f) : Fbgetc(f)))>0)
if(c==cr){
if(--nest==0)
return 1;
}else if(c==cl)
nest++;
return cl=='\n' && --nest==0;
}