Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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->nc)
43
		p0 = f->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->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->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->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->nc && c=='\n');
160
			}
161
			return;
162
		}
163
	}
164
	/* try filling out word to right */
165
	p = p1;
166
	while(p < f->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
}
173