diff --git a/uppsrc/CodeEditor/CodeEditor.h b/uppsrc/CodeEditor/CodeEditor.h index a118d684b..fbaf57be2 100644 --- a/uppsrc/CodeEditor/CodeEditor.h +++ b/uppsrc/CodeEditor/CodeEditor.h @@ -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); diff --git a/uppsrc/CodeEditor/Highlight.cpp b/uppsrc/CodeEditor/Highlight.cpp index fdf4ef28a..2efda9579 100644 --- a/uppsrc/CodeEditor/Highlight.cpp +++ b/uppsrc/CodeEditor/Highlight.cpp @@ -387,6 +387,7 @@ void CodeEditor::HighlightLine(int line, Vector& 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& 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; } diff --git a/uppsrc/CodeEditor/Syntax.cpp b/uppsrc/CodeEditor/Syntax.cpp index fe3fdcdea..124669c5f 100644 --- a/uppsrc/CodeEditor/Syntax.cpp +++ b/uppsrc/CodeEditor/Syntax.cpp @@ -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 == '}') {