#include "CodeEditor.h" NAMESPACE_UPP Array GetLineIdent(const char *line) { Array out; const char *p = line; while(*p && *p != '\n') if(*p == '\"' || *p == '\'') { char term = *p++; while(*p && *p != term) if(*p++ == '\\' && *p) p++; if(*p == term) p++; } else if(*p == 's' && p[1] == '_' && p[2] == '(' && (IsAlpha(p[3]) || p[3] == '_')) { IdentPos& pos = out.Add(); pos.begin = int(p - line); const char *b = (p += 3); while(IsAlNum(*++p) || *p == '_') ; pos.ident = String(b, p); if(*p == ')') p++; pos.end = int(p - line); } else if(IsAlpha(*p) || *p == '_') { while(IsAlNum(*++p) || *p == '_') ; } else p++; return out; } Vector GetLineString(const wchar *wline, bool& is_begin, bool& is_end) { Vector out; const wchar *p = wline; while(*p <= ' ' && *p && *p != '\n') p++; is_begin = (*p == '\"'); is_end = false; while(*p && *p != '\n') { wchar term = *p; if(term == '\"' || term == '\'') { int begin = int(p++ - wline); while(*p && *p != '\n') if(*p == term) { const wchar *lim = ++p; while((byte)*p <= ' ' && *p && *p != '\n') p++; if(*p != term) { is_end = (*p == '\n' || *p == 0); p = lim; break; } p++; } else if(*p++ == '\\' && *p && *p != '\n') p++; if(term == '\"') out.Add(Point(begin, int(p - wline))); } else p++; } return out; } bool CodeEditor::GetStringRange(int cursor, int& b, int &e) const { int cl = GetLine(cursor); cursor -= GetPos(cl); bool is_begin, is_end; //@@@@@@ Vector list = GetLineString(GetWLine(cl), is_begin, is_end); int i = list.GetCount(); while(--i >= 0 && (list[i].x > cursor || list[i].y < cursor)) ; if(i < 0) return false; int bl = cl, bp = list[i].x; int el = cl, ep = list[i].y; while(is_begin && bl > 0) { list = GetLineString(GetWLine(bl - 1), is_begin, is_end); if(list.IsEmpty() || !is_end) break; bl--; bp = list.Top().x; } while(el + 1 < GetLineCount() && ep >= GetLineLength(el)) { list = GetLineString(GetWLine(el + 1), is_begin, is_end); if(list.IsEmpty() || !is_begin) break; el++; ep = list[0].y; } b = GetPos(bl, bp); e = GetPos(el, ep); return b < e; } bool CodeEditor::FindString(bool back) { int l, h; if(!GetSelection(l, h)) h = GetCursor(); else h = (back ? l : h); h -= GetPos(l = GetLine(h)); while(l >= 0 && l < GetLineCount()) { bool is_begin, is_end; Vector list = GetLineString(GetWLine(l), is_begin, is_end); if(back) { int i = list.GetCount(); while(--i >= 0 && list[i].x >= h) ; if(i >= 0) { h = list[i].x; break; } h = 1000000; --l; } else { int i = 0; while(i < list.GetCount() && list[i].y <= h) i++; if(i < list.GetCount()) { h = list[i].x; break; } h = 0; ++l; } } int b, e; if(l < 0 || l >= GetLineCount() || !GetStringRange(GetPos(l, h), b, e)) return false; SetSelection(b, e); return true; } bool CodeEditor::FindLangString(bool back) { int l, h; if(!GetSelection(l, h)) h = GetCursor(); else h = (back ? l : h); h -= GetPos(l = GetLine(h)); for(;;) { Array list = GetLineIdent(GetUtf8Line(l)); int b, e; if(back) { int i = list.GetCount(); while(--i >= 0 && list[i].begin >= h) ; if(i < 0) { h = 1000000; if(--l < 0) break; continue; } b = GetPos(l, list[i].begin); e = GetPos(l, list[i].end); } else { int i = 0; while(i < list.GetCount() && list[i].end <= h) i++; if(i >= list.GetCount()) { h = 0; if(++l >= GetLineCount()) break; continue; } b = GetPos(l, list[i].begin); e = GetPos(l, list[i].end); } SetSelection(b, e); return true; } return false; } END_UPP_NAMESPACE