tmoveto.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
tmoveto.c (2711B) | |
--- | |
1 #include "sam.h" | |
2 | |
3 void | |
4 moveto(File *f, Range r) | |
5 { | |
6 Posn p1 = r.p1, p2 = r.p2; | |
7 | |
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 } | |
15 | |
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 } | |
26 | |
27 void | |
28 tellpat(void) | |
29 { | |
30 outTS(Hsetpat, &lastpat); | |
31 patset = FALSE; | |
32 } | |
33 | |
34 #define CHARSHIFT 128 | |
35 | |
36 void | |
37 lookorigin(File *f, Posn p0, Posn ls) | |
38 { | |
39 int nl, nc, c; | |
40 Posn p, oldp0; | |
41 | |
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 } | |
62 | |
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 } | |
79 | |
80 int | |
81 clickmatch(File *f, int cl, int cr, int dir, Posn *p) | |
82 { | |
83 int c; | |
84 int nest = 1; | |
85 | |
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 } | |
104 | |
105 Rune* | |
106 strrune(Rune *s, Rune c) | |
107 { | |
108 Rune c1; | |
109 | |
110 if(c == 0) { | |
111 while(*s++) | |
112 ; | |
113 return s-1; | |
114 } | |
115 | |
116 while(c1 = *s++) | |
117 if(c1 == c) | |
118 return s-1; | |
119 return 0; | |
120 } | |
121 | |
122 void | |
123 doubleclick(File *f, Posn p1) | |
124 { | |
125 int c, i; | |
126 Rune *r, *l; | |
127 Posn p; | |
128 | |
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'); | |
145 } | |
146 return; | |
147 } | |
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)=='… | |
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 } |