1 #include "CodeEditor.h"
2
3 namespace Upp {
4
GetLineIdent(const char * line)5 Array<IdentPos> GetLineIdent(const char *line)
6 {
7 Array<IdentPos> out;
8 const char *p = line;
9 while(*p && *p != '\n')
10 if(*p == '\"' || *p == '\'')
11 {
12 char term = *p++;
13 while(*p && *p != term)
14 if(*p++ == '\\' && *p)
15 p++;
16 if(*p == term)
17 p++;
18 }
19 else if(*p == 's' && p[1] == '_' && p[2] == '(' && (IsAlpha(p[3]) || p[3] == '_'))
20 {
21 IdentPos& pos = out.Add();
22 pos.begin = int(p - line);
23 const char *b = (p += 3);
24 while(IsAlNum(*++p) || *p == '_')
25 ;
26 pos.ident = String(b, p);
27 if(*p == ')')
28 p++;
29 pos.end = int(p - line);
30 }
31 else if(IsAlpha(*p) || *p == '_')
32 {
33 while(IsAlNum(*++p) || *p == '_')
34 ;
35 }
36 else
37 p++;
38 return out;
39 }
40
GetLineString(const wchar * wline,bool & is_begin,bool & is_end)41 Vector<Point> GetLineString(const wchar *wline, bool& is_begin, bool& is_end)
42 {
43 Vector<Point> out;
44 const wchar *p = wline;
45 while(*p <= ' ' && *p && *p != '\n')
46 p++;
47 is_begin = (*p == '\"');
48 is_end = false;
49 while(*p && *p != '\n')
50 {
51 wchar term = *p;
52 if(term == '\"' || term == '\'')
53 {
54 int begin = int(p++ - wline);
55 while(*p && *p != '\n')
56 if(*p == term)
57 {
58 const wchar *lim = ++p;
59 while((byte)*p <= ' ' && *p && *p != '\n')
60 p++;
61 if(*p != term)
62 {
63 is_end = (*p == '\n' || *p == 0);
64 p = lim;
65 break;
66 }
67 p++;
68 }
69 else if(*p++ == '\\' && *p && *p != '\n')
70 p++;
71 if(term == '\"')
72 out.Add(Point(begin, int(p - wline)));
73 }
74 else
75 p++;
76 }
77 return out;
78 }
79
GetStringRange(int64 cursor,int64 & b,int64 & e) const80 bool CodeEditor::GetStringRange(int64 cursor, int64& b, int64& e) const
81 {
82 int cl = GetLine(cursor);
83 cursor -= GetPos64(cl);
84 bool is_begin, is_end; //@@@@@@
85 Vector<Point> list = GetLineString(GetWLine(cl), is_begin, is_end);
86 int i = list.GetCount();
87 while(--i >= 0 && (list[i].x > cursor || list[i].y < cursor))
88 ;
89 if(i < 0)
90 return false;
91 int bl = cl, bp = list[i].x;
92 int el = cl, ep = list[i].y;
93 while(is_begin && bl > 0)
94 {
95 list = GetLineString(GetWLine(bl - 1), is_begin, is_end);
96 if(list.IsEmpty() || !is_end)
97 break;
98 bl--;
99 bp = list.Top().x;
100 }
101 while(el + 1 < GetLineCount() && ep >= GetLineLength(el))
102 {
103 list = GetLineString(GetWLine(el + 1), is_begin, is_end);
104 if(list.IsEmpty() || !is_begin)
105 break;
106 el++;
107 ep = list[0].y;
108 }
109 b = GetPos64(bl, bp);
110 e = GetPos64(el, ep);
111 return b < e;
112 }
113
FindString(bool back)114 bool CodeEditor::FindString(bool back)
115 {
116 int64 ll, hh;
117 hh = GetSelection(ll, hh) ? back ? ll : hh
118 : GetCursor64();
119 int l = GetLine(hh);
120 int h = LimitSize(hh - GetPos64(l));
121
122 while(l >= 0 && l < GetLineCount())
123 {
124 bool is_begin, is_end;
125 Vector<Point> list = GetLineString(GetWLine(l), is_begin, is_end);
126 if(back)
127 {
128 int i = list.GetCount();
129 while(--i >= 0 && list[i].x >= h)
130 ;
131 if(i >= 0)
132 {
133 h = list[i].x;
134 break;
135 }
136 h = 1000000;
137 --l;
138 }
139 else
140 {
141 int i = 0;
142 while(i < list.GetCount() && list[i].y <= h)
143 i++;
144 if(i < list.GetCount())
145 {
146 h = list[i].x;
147 break;
148 }
149 h = 0;
150 ++l;
151 }
152 }
153 int64 b, e;
154 if(l < 0 || l >= GetLineCount() || !GetStringRange(GetPos64(l, h), b, e))
155 return false;
156 SetSelection(b, e);
157 return true;
158 }
159
FindLangString(bool back)160 bool CodeEditor::FindLangString(bool back)
161 {
162 int64 ll, hh;
163 hh = GetSelection(ll, hh) ? back ? ll : hh
164 : GetCursor64();
165 int l = GetLine(hh);
166 int h = LimitSize(hh - GetPos64(l));
167
168 for(;;)
169 {
170 Array<IdentPos> list = GetLineIdent(GetUtf8Line(l));
171 int64 b, e;
172 if(back)
173 {
174 int i = list.GetCount();
175 while(--i >= 0 && list[i].begin >= h)
176 ;
177 if(i < 0)
178 {
179 h = 1000000;
180 if(--l < 0)
181 break;
182 continue;
183 }
184 b = GetPos64(l, list[i].begin);
185 e = GetPos64(l, list[i].end);
186 }
187 else
188 {
189 int i = 0;
190 while(i < list.GetCount() && list[i].end <= h)
191 i++;
192 if(i >= list.GetCount())
193 {
194 h = 0;
195 if(++l >= GetLineCount())
196 break;
197 continue;
198 }
199 b = GetPos64(l, list[i].begin);
200 e = GetPos64(l, list[i].end);
201 }
202 SetSelection(b, e);
203 return true;
204 }
205 return false;
206 }
207
208 }
209