Blob
1 #include "sam.h"3 void4 moveto(File *f, Range r)5 {6 Posn p1 = r.p1, p2 = r.p2;8 f->dot.r.p1 = p1;9 f->dot.r.p2 = p2;10 if(f->rasp){11 telldot(f);12 outTsl(Hmoveto, f->tag, f->dot.r.p1);13 }14 }16 void17 telldot(File *f)18 {19 if(f->rasp == 0)20 panic("telldot");21 if(f->dot.r.p1==f->tdot.p1 && f->dot.r.p2==f->tdot.p2)22 return;23 outTsll(Hsetdot, f->tag, f->dot.r.p1, f->dot.r.p2);24 f->tdot = f->dot.r;25 }27 void28 tellpat(void)29 {30 outTS(Hsetpat, &lastpat);31 patset = FALSE;32 }34 #define CHARSHIFT 12836 void37 lookorigin(File *f, Posn p0, Posn ls)38 {39 int nl, nc, c;40 Posn p, oldp0;42 if(p0 > f->b.nc)43 p0 = f->b.nc;44 oldp0 = p0;45 p = p0;46 for(nl=nc=c=0; c!=-1 && nl<ls && nc<ls*CHARSHIFT; nc++)47 if((c=filereadc(f, --p)) == '\n'){48 nl++;49 oldp0 = p0-nc;50 }51 if(c == -1)52 p0 = 0;53 else if(nl==0){54 if(p0>=CHARSHIFT/2)55 p0-=CHARSHIFT/2;56 else57 p0 = 0;58 }else59 p0 = oldp0;60 outTsl(Horigin, f->tag, p0);61 }63 int64 alnum(int c)65 {66 /*67 * Hard to get absolutely right. Use what we know about ASCII68 * and assume anything above the Latin control characters is69 * potentially an alphanumeric.70 */71 if(c<=' ')72 return 0;73 if(0x7F<=c && c<=0xA0)74 return 0;75 if(utfrune("!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~", c))76 return 0;77 return 1;78 }80 int81 clickmatch(File *f, int cl, int cr, int dir, Posn *p)82 {83 int c;84 int nest = 1;86 for(;;){87 if(dir > 0){88 if(*p >= f->b.nc)89 break;90 c = filereadc(f, (*p)++);91 }else{92 if(*p == 0)93 break;94 c = filereadc(f, --(*p));95 }96 if(c == cr){97 if(--nest==0)98 return 1;99 }else if(c == cl)100 nest++;101 }102 return cl=='\n' && nest==1;103 }105 Rune*106 strrune(Rune *s, Rune c)107 {108 Rune c1;110 if(c == 0) {111 while(*s++)112 ;113 return s-1;114 }116 while(c1 = *s++)117 if(c1 == c)118 return s-1;119 return 0;120 }122 void123 doubleclick(File *f, Posn p1)124 {125 int c, i;126 Rune *r, *l;127 Posn p;129 if(p1 > f->b.nc)130 return;131 f->dot.r.p1 = f->dot.r.p2 = p1;132 for(i=0; left[i]; i++){133 l = left[i];134 r = right[i];135 /* try left match */136 p = p1;137 if(p1 == 0)138 c = '\n';139 else140 c = filereadc(f, p - 1);141 if(strrune(l, c)){142 if(clickmatch(f, c, r[strrune(l, c)-l], 1, &p)){143 f->dot.r.p1 = p1;144 f->dot.r.p2 = p-(c!='\n');145 }146 return;147 }148 /* try right match */149 p = p1;150 if(p1 == f->b.nc)151 c = '\n';152 else153 c = filereadc(f, p);154 if(strrune(r, c)){155 if(clickmatch(f, c, l[strrune(r, c)-r], -1, &p)){156 f->dot.r.p1 = p;157 if(c!='\n' || p!=0 || filereadc(f, 0)=='\n')158 f->dot.r.p1++;159 f->dot.r.p2 = p1+(p1<f->b.nc && c=='\n');160 }161 return;162 }163 }164 /* try filling out word to right */165 p = p1;166 while(p < f->b.nc && alnum(filereadc(f, p++)))167 f->dot.r.p2++;168 /* try filling out word to left */169 p = p1;170 while(--p >= 0 && alnum(filereadc(f, p)))171 f->dot.r.p1--;172 }