Improved parenthesis CodeEditor highlighting (recovery heurestics), improved namespace highlighting (top-level { are black even after namespace {)

git-svn-id: svn://ultimatepp.org/upp/trunk@478 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2008-09-24 08:19:04 +00:00
parent e123f063ca
commit 0599ddea0e
3 changed files with 52 additions and 11 deletions

View file

@ -205,6 +205,7 @@ protected:
bool linecomment;
bool string;
bool linecont;
bool was_namespace;
char macro;
enum { MACRO_OFF, MACRO_CONT, MACRO_END };
@ -224,8 +225,10 @@ protected:
void DropItem(int type);
bool Drop(int type);
void ClearBraces();
void Clear();
bool MatchHilite(const SyntaxState& st) const;
void Grounding(const wchar *ln, const wchar *e);
void ScanSyntax(const wchar *ln, const wchar *e);
static Color IfColor(char ifstate);

View file

@ -387,6 +387,7 @@ void CodeEditor::HighlightLine(int line, Vector<LineEdit::Highlight>& hl, int po
InitKeywords();
WString text = GetWLine(line);
SyntaxState ss = ScanSyntax(line);
ss.Grounding(text.Begin(), text.End());
SyntaxState sm = ScanSyntax(line + 1);
HlSt hls(hl);
const wchar *p = text;
@ -505,7 +506,7 @@ void CodeEditor::HighlightLine(int line, Vector<LineEdit::Highlight>& hl, int po
Bracket(int(p - text) + pos, hls);
int& l = *p == ')' ? ss.pl : *p == '}' ? ss.cl : ss.bl;
if(ss.brk.IsEmpty() || ss.brk.Pop() != *p || l <= 0) {
hls.Put(hl_style[INK_ERROR]);
hls.Put(p == ~text ? hl_style[INK_PAR0] : hl_style[INK_ERROR]);
ss.brk.Clear();
ss.cl = ss.bl = ss.pl = 0;
}

View file

@ -25,18 +25,24 @@ inline const wchar *strnext(const wchar *p, const wchar *end, int ch) {
return NULL;
}
void CodeEditor::SyntaxState::Clear() {
void CodeEditor::SyntaxState::ClearBraces() {
cl = bl = pl = 0;
spar = 0;
line = cl = bl = pl = 0;
linecont = linecomment = comment = string = false;
macro = MACRO_OFF;
brk.Clear();
blk.Clear();
bid.Clear();
bid.Add(0);
par.Clear();
}
void CodeEditor::SyntaxState::Clear() {
ClearBraces();
line = 0;
linecont = linecomment = comment = string = false;
macro = MACRO_OFF;
stmtline = endstmtline = seline = -1;
uvscolor = Null;
was_namespace = false;
ifstack.Clear();
}
@ -92,8 +98,27 @@ static WString sReadLn(const wchar *p)
return wbuf;
}
int LastC(const wchar *b, const wchar *e)
{
if(e == b)
return 0;
return *e;
}
void CodeEditor::SyntaxState::Grounding(const wchar *b, const wchar *e)
{
if(b >= e || comment || !iscib(*b))
return;
e--;
while(e > b && (*e == '\t' || *e == ' ' ))
e--;
if(*e != ':')
ClearBraces();
}
void CodeEditor::SyntaxState::ScanSyntax(const wchar *ln, const wchar *e)
{
Grounding(ln, e);
string = false;
if(!linecont)
linecomment = false;
@ -206,6 +231,13 @@ void CodeEditor::SyntaxState::ScanSyntax(const wchar *ln, const wchar *e)
pc = 0;
p = pp;
}
else
if(!iscid(pc) && p[0] == 'n' && p[1] == 'a' && p[2] == 'm' && p[3] == 'e' &&
p[4] == 's' && p[5] == 'p' && p[6] == 'a' && p[7] == 'c' && p[8] == 'e' &&
!iscid(p[9])) {
was_namespace = true;
p += 9;
}
else {
int c = *p++;
if(c == '/') break;
@ -221,15 +253,20 @@ void CodeEditor::SyntaxState::ScanSyntax(const wchar *ln, const wchar *e)
seline = stmtline;
endstmtline = line;
stmtline = -1;
was_namespace = false;
}
else
if(c == '{') {
cl++;
brk.Add('}');
blk.Add() = line;
bid.Add(lindent + 1);
stmtline = -1;
par.Clear();
if(was_namespace)
was_namespace = false;
else {
cl++;
brk.Add('}');
blk.Add() = line;
bid.Add(lindent + 1);
stmtline = -1;
par.Clear();
}
}
else
if(c == '}') {