Blob


1 #include "sam.h"
3 void
4 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 void
17 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 void
28 tellpat(void)
29 {
30 outTS(Hsetpat, &lastpat);
31 patset = FALSE;
32 }
34 #define CHARSHIFT 128
36 void
37 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 else
57 p0 = 0;
58 }else
59 p0 = oldp0;
60 outTsl(Horigin, f->tag, p0);
61 }
63 int
64 alnum(int c)
65 {
66 /*
67 * Hard to get absolutely right. Use what we know about ASCII
68 * and assume anything above the Latin control characters is
69 * 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 int
81 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++;
102 return cl=='\n' && nest==1;
105 Rune*
106 strrune(Rune *s, Rune c)
108 Rune c1;
110 if(c == 0) {
111 while(*s++)
113 return s-1;
116 while(c1 = *s++)
117 if(c1 == c)
118 return s-1;
119 return 0;
122 void
123 doubleclick(File *f, Posn p1)
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 else
140 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');
146 return;
148 /* try right match */
149 p = p1;
150 if(p1 == f->b.nc)
151 c = '\n';
152 else
153 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');
161 return;
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--;