ultimatepp/uppsrc/CodeEditor/Lang.cpp
mdelfede 263ff5f895 changed svn layout
git-svn-id: svn://ultimatepp.org/upp/trunk@281 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2008-06-07 22:31:27 +00:00

204 lines
3.8 KiB
C++

#include "CodeEditor.h"
NAMESPACE_UPP
Array<IdentPos> GetLineIdent(const char *line)
{
Array<IdentPos> 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<Point> GetLineString(const wchar *wline, bool& is_begin, bool& is_end)
{
Vector<Point> 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<Point> 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<Point> 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<IdentPos> 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