mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 06:05:58 -06:00
204 lines
3.8 KiB
C++
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
|