diff --git a/uppsrc/CodeEditor/CodeEditor.cpp b/uppsrc/CodeEditor/CodeEditor.cpp index a04c27be3..e3098630c 100644 --- a/uppsrc/CodeEditor/CodeEditor.cpp +++ b/uppsrc/CodeEditor/CodeEditor.cpp @@ -1151,7 +1151,7 @@ void CodeEditor::HighlightLine(int line, Vector& hl, int64 } for(Point p : errors) if(p.y == line && p.x < hl.GetCount()) { - hl[p.x].paper = Blend(LtRed(), SColorPaper(), 100); + hl[p.x].paper = hl_style[PAPER_ERROR_FILE].color; hl[p.x].flags |= LineEdit::NOENDFILL; } } diff --git a/uppsrc/CodeEditor/EditorBar.cpp b/uppsrc/CodeEditor/EditorBar.cpp index 4b1d33770..fb6bd47de 100644 --- a/uppsrc/CodeEditor/EditorBar.cpp +++ b/uppsrc/CodeEditor/EditorBar.cpp @@ -60,97 +60,104 @@ void EditorBar::Paint(Draw& w) w.DrawRect(0, 0, sz.cx, sz.cy, bg); for(int i = 0; i < animate.GetCount(); i++) w.DrawRect(i, 0, 1, sz.cy, animate[i]); - w.DrawImage(0, 0, status_image); if(!editor) return; - int fy = editor->GetFontSize().cy; - int hy = fy >> 1; - int y = 0; - int i = editor->GetScrollPos().y; - int cy = GetSize().cy; - String hl = editor->GetHighlight(); - bool hi_if = (hilite_if_endif && findarg(hl, "cpp", "cs", "java") >= 0); - Vector previf; - if(hi_if) - previf <<= editor->GetIfStack(i); - int ptri[2]; - for(int q = 0; q < 2; q++) - ptri[q] = ptrline[q] >= 0 ? GetLineNo(ptrline[q]) : -1; - while(y < cy) { - String b; - int err = 0; - int edit = 0; - String ann; - Image icon; - if(i < li.GetCount()) { - const LnInfo& l = li[i]; - b = l.breakpoint; - err = l.error; - edit = l.edited; - icon = l.icon; - ann = l.annotation; - } - if(editor->GetCaret().top == y && editor->barline) - w.DrawRect(0, y, sz.cx, fy, Blend(SColorHighlight(), bg, 200)); - if(line_numbers && i < editor->GetLineCount()) { - String n = AsString((i + 1) % 1000000); - Font fnt = editor->GetFont(); - Size tsz = GetTextSize(n, fnt); - w.DrawText(sz.cx - Zx(4 + 12) - tsz.cx, y + (fy - tsz.cy) / 2, n, fnt, SBrown()); - } - if(hi_if) { - Vector nextif; - if(i < li.GetCount()) - nextif <<= editor->GetIfStack(i + 1); - int pifl = previf.GetCount(), nifl = nextif.GetCount(); - int dif = max(pifl, nifl); - if(--dif >= 0) { - char p = (dif < pifl ? previf[dif].state : 0); - char n = (dif < nifl ? nextif[dif].state : 0); - int wd = min(2 * (dif + 1), sz.cx); - int x = sz.cx - wd; - Color cn = EditorSyntax::IfColor(n); - if(p == n) - w.DrawRect(x, y, 1, fy, cn); - else { - Color cp = EditorSyntax::IfColor(p); - w.DrawRect(x, y, 1, hy, cp); - w.DrawRect(x, y + hy, wd, 1, Nvl(cn, cp)); - w.DrawRect(x, y + hy, 1, fy - hy, cn); + for(int pass = 0; pass < 2; pass++) { + int fy = editor->GetFontSize().cy; + int hy = fy >> 1; + int y = 0; + int i = editor->GetScrollPos().y; + int cy = GetSize().cy; + String hl = editor->GetHighlight(); + bool hi_if = (hilite_if_endif && findarg(hl, "cpp", "cs", "java") >= 0); + Vector previf; + if(hi_if) + previf <<= editor->GetIfStack(i); + int ptri[2]; + for(int q = 0; q < 2; q++) + ptri[q] = ptrline[q] >= 0 ? GetLineNo(ptrline[q]) : -1; + while(y < cy) { + String b; + int err = 0; + int edit = 0; + String ann; + Image icon; + if(i < li.GetCount()) { + const LnInfo& l = li[i]; + b = l.breakpoint; + err = l.error; + edit = l.edited; + icon = l.icon; + ann = l.annotation; + } + if(pass == 0) { + if(editor->GetCaret().top == y && editor->barline) + w.DrawRect(0, y, sz.cx, fy, Blend(SColorHighlight(), bg, 200)); + if(line_numbers && i < editor->GetLineCount()) { + String n = AsString((i + 1) % 1000000); + Font fnt = editor->GetFont(); + Size tsz = GetTextSize(n, fnt); + w.DrawText(sz.cx - Zx(4 + 12) - tsz.cx, y + (fy - tsz.cy) / 2, n, fnt, SBrown()); + } + if(hi_if) { + Vector nextif; + if(i < li.GetCount()) + nextif <<= editor->GetIfStack(i + 1); + int pifl = previf.GetCount(), nifl = nextif.GetCount(); + int dif = max(pifl, nifl); if(--dif >= 0) { - x = sz.cx - min(2 * (dif + 1), sz.cx); - if(!p) - w.DrawRect(x, y, 1, hy, EditorSyntax::IfColor(dif < pifl ? previf[dif].state : 0)); - if(!n) - w.DrawRect(x, y + hy, 1, fy - hy, EditorSyntax::IfColor(dif < nifl ? nextif[dif].state : 0)); + char p = (dif < pifl ? previf[dif].state : 0); + char n = (dif < nifl ? nextif[dif].state : 0); + int wd = min(2 * (dif + 1), sz.cx); + int x = sz.cx - wd; + Color cn = EditorSyntax::IfColor(n); + if(p == n) + w.DrawRect(x, y, 1, fy, cn); + else { + Color cp = EditorSyntax::IfColor(p); + w.DrawRect(x, y, 1, hy, cp); + w.DrawRect(x, y + hy, wd, 1, Nvl(cn, cp)); + w.DrawRect(x, y + hy, 1, fy - hy, cn); + if(--dif >= 0) { + x = sz.cx - min(2 * (dif + 1), sz.cx); + if(!p) + w.DrawRect(x, y, 1, hy, EditorSyntax::IfColor(dif < pifl ? previf[dif].state : 0)); + if(!n) + w.DrawRect(x, y + hy, 1, fy - hy, EditorSyntax::IfColor(dif < nifl ? nextif[dif].state : 0)); + } + } } + previf = pick(nextif); + } + if(editor->GetMarkLines()) { + int width = CodeEditorImg::Breakpoint().GetWidth() >> 1; + if(edit) + { + int age = (int)(log((double)(editor->GetUndoCount() + 1 - edit)) * 30); + w.DrawRect(0, y, width, fy, Blend(SLtBlue(), bg, min(220, age))); + } + if(err) + w.DrawRect(width, y, width, fy, err == 1 ? LtRed() : (err == 2 ? Color(255, 175, 0) : SGreen())); } } - previf = pick(nextif); - } - if(editor->GetMarkLines()) { - int width = CodeEditorImg::Breakpoint().GetWidth() >> 1; - if(edit) - { - int age = (int)(log((double)(editor->GetUndoCount() + 1 - edit)) * 30); - w.DrawRect(0, y, width, fy, Blend(SLtBlue(), bg, min(220, age))); + + if(pass == 1) { + if(!b.IsEmpty()) + sPaintImage(w, y, fy, b == "1" ? CodeEditorImg::Breakpoint() : + b == "\xe" ? CodeEditorImg::InvalidBreakpoint() : + CodeEditorImg::CondBreakpoint()); + for(int q = 0; q < 2; q++) + if(ptri[q] == i) + sPaintImage(w, y, fy, ptrimg[q]); + + if(annotations && !IsNull(icon)) + w.DrawImage(sz.cx - annotations, y + (fy - icon.GetSize().cy) / 2, icon); } - if(err) - w.DrawRect(width, y, width, fy, err == 1 ? LtRed() : (err == 2 ? Color(255, 175, 0) : SGreen())); + + y += fy; + i++; } - - if(!b.IsEmpty()) - sPaintImage(w, y, fy, b == "1" ? CodeEditorImg::Breakpoint() : - b == "\xe" ? CodeEditorImg::InvalidBreakpoint() : - CodeEditorImg::CondBreakpoint()); - for(int q = 0; q < 2; q++) - if(ptri[q] == i) - sPaintImage(w, y, fy, ptrimg[q]); - - if(annotations && !IsNull(icon)) - w.DrawImage(sz.cx - annotations, y + (fy - icon.GetSize().cy) / 2, icon); - - y += fy; - i++; + if(pass == 0) + w.DrawImage(0, 0, status_image); } } diff --git a/uppsrc/CodeEditor/Style.cpp b/uppsrc/CodeEditor/Style.cpp index 6e85708ed..4193ab50d 100644 --- a/uppsrc/CodeEditor/Style.cpp +++ b/uppsrc/CodeEditor/Style.cpp @@ -155,6 +155,7 @@ void HighlightSetup::DarkTheme() SetHlStyle(INK_DIFF_COMMENT, Color(173, 255, 173)); SetHlStyle(PAPER_SELWORD, Color(99, 99, 0)); SetHlStyle(PAPER_ERROR, Color(90, 40, 40)); + SetHlStyle(PAPER_ERROR_FILE, Color(120, 40, 40)); SetHlStyle(PAPER_WARNING, Color(21, 21, 0)); SetHlStyle(SHOW_LINE, Color(27, 75, 26)); SetHlStyle(SHOW_COLUMN, Color(56, 33, 29)); @@ -221,6 +222,7 @@ void HighlightSetup::WhiteTheme() SetHlStyle(PAPER_SELWORD, Yellow); SetHlStyle(PAPER_ERROR, Blend(White(), LtRed(), 50)); + SetHlStyle(PAPER_ERROR_FILE, Blend(White(), LtRed(), 150)); SetHlStyle(PAPER_WARNING, Blend(White(), Yellow(), 50)); SetHlStyle(SHOW_LINE, Color(199, 247, 198)); diff --git a/uppsrc/CodeEditor/hl_color.i b/uppsrc/CodeEditor/hl_color.i index 9c2634edb..578e89f7f 100644 --- a/uppsrc/CodeEditor/hl_color.i +++ b/uppsrc/CodeEditor/hl_color.i @@ -57,6 +57,7 @@ HL_COLOR(INK_DIFF_COMMENT, t_("Diff comment"), 0) HL_COLOR(PAPER_SELWORD, t_("Found/selected matches"), 0) HL_COLOR(PAPER_ERROR, t_("Error in compiler messages"), 0) +HL_COLOR(PAPER_ERROR_FILE, t_("Current file errors"), 0) HL_COLOR(PAPER_WARNING, t_("Warning in compiler messages"), 0) HL_COLOR(SHOW_LINE, t_("Current line highlight"), 0) HL_COLOR(SHOW_COLUMN, t_("Current column highlight"), 0) diff --git a/uppsrc/ide/Assist.cpp b/uppsrc/ide/Assist.cpp index f877a5ef3..f122bb51a 100644 --- a/uppsrc/ide/Assist.cpp +++ b/uppsrc/ide/Assist.cpp @@ -69,9 +69,7 @@ AssistEditor::AssistEditor() if(IsSourceFile(theide->editfile) || master_source.GetCount() || IsHeaderFile(theide->editfile)) { annotating = true; annotate_trigger.KillSet(500, [=] { SyncCurrentFile(); }); - errors.Clear(); - Errors(Vector()); - StatusImage(Null); + ClearErrors(); } }; } @@ -84,6 +82,13 @@ class IndexSeparatorFrameCls : public CtrlFrame { virtual void FrameAddSize(Size& sz) { sz.cx += 2; } }; +void AssistEditor::ClearErrors() +{ + errors.Clear(); + Errors(Vector()); + StatusImage(Null); +} + void AssistEditor::SyncNavigatorPlacement() { int sz = navigatorframe.GetSize(); @@ -427,30 +432,35 @@ void AssistEditor::SyncCurrentFile(const CurrentFileContext& cfx) SetCurrentFile(cfx, [=](const CppFileInfo& f, const Vector& ds) { SetAnnotations(f); - errors = clone(ds); - - Vector err; - - int di = 0; - String path = NormalizePath(theide->editfile); - while(di < ds.GetCount() && err.GetCount() < 30) { - int k = ds[di].kind; - auto Do = [&](const Diagnostic& d) { - if(d.path == path && NotIncludedFrom(d.text)) { - // ignore errors after the end of header (e.g. missing }) - if(!IsHeaderFile(path) || d.pos.y < GetLineCount() - 1 || - d.pos.y == GetLineCount() - 1 && d.pos.x < GetLineLength(GetLineCount() - 1)) - err.Add(d.pos); - } - }; - if(IsWarning(k) || IsError(k)) { - Do(ds[di++]); - while(di < ds.GetCount() && ds[di].detail) + ClearErrors(); + if(!IsCurrentFileDirty()) { + errors = clone(ds); + + Vector err; + + int di = 0; + String path = NormalizePath(theide->editfile); + while(di < ds.GetCount() && err.GetCount() < 30) { + int k = ds[di].kind; + auto Do = [&](const Diagnostic& d) { + if(d.path == path && NotIncludedFrom(d.text)) { + // ignore errors after the end of header (e.g. missing }) + if(!IsHeaderFile(path) || d.pos.y < GetLineCount() - 1 || + d.pos.y == GetLineCount() - 1 && d.pos.x < GetLineLength(GetLineCount() - 1)) + err.Add(d.pos); + } + }; + if(IsWarning(k) || IsError(k)) { Do(ds[di++]); + while(di < ds.GetCount() && ds[di].detail) + Do(ds[di++]); + } } + if(show_errors_status) + StatusImage(err.GetCount() ? IdeImg::CurrentErrors() : IdeImg::CurrentOK()); + if(show_errors) + Errors(pick(err)); } - StatusImage(err.GetCount() ? IdeImg::CurrentErrors() : IdeImg::CurrentOK()); - Errors(pick(err)); }); } @@ -978,7 +988,7 @@ void AssistEditor::SelectionChanged() void AssistEditor::SerializeNavigator(Stream& s) { - int version = 6; + int version = 7; s / version; s % navigatorframe; s % navigator; @@ -996,4 +1006,7 @@ void AssistEditor::SerializeNavigator(Stream& s) if(s.IsLoading()) SyncNavigatorPlacement(); + + if(version >= 7) + s % show_errors % show_errors_status; } \ No newline at end of file diff --git a/uppsrc/ide/Assist.h b/uppsrc/ide/Assist.h index 854fe9157..bd9ab1c72 100644 --- a/uppsrc/ide/Assist.h +++ b/uppsrc/ide/Assist.h @@ -136,6 +136,8 @@ struct AssistEditor : CodeEditor, Navigator { static Ptr assist_ptr; bool navigator_right = false; + bool show_errors = true; + bool show_errors_status = true; PPInfo ppi; String master_source; @@ -150,6 +152,7 @@ struct AssistEditor : CodeEditor, Navigator { void NewFile(bool reloading); bool DoIncludeTrick(Index& visited, int level, StringBuffer& out, String path, const String& target_path, int& line_delta); void MakeIncludeTrick(CurrentFileContext& cfx); + void ClearErrors(); void PopUpAssist(bool auto_insert = false); void CloseAssist(); diff --git a/uppsrc/ide/Setup.cpp b/uppsrc/ide/Setup.cpp index 3d15aeb40..cd013140f 100644 --- a/uppsrc/ide/Setup.cpp +++ b/uppsrc/ide/Setup.cpp @@ -509,6 +509,8 @@ void Ide::SetupFormat() { (assist.assist, editor.auto_assist) (assist.auto_indexer, AutoIndexer) (assist.navigator_right, editor.navigator_right) + (assist.show_errors, editor.show_errors) + (assist.show_errors_status, editor.show_errors_status) (assist.diagnostics, AssistDiagnostics) (assist.indexer_threads, IndexerThreads) (assist.parsed_files, ParsedFiles) diff --git a/uppsrc/ide/ide.lay b/uppsrc/ide/ide.lay index 60d2b9d00..568cfcab1 100644 --- a/uppsrc/ide/ide.lay +++ b/uppsrc/ide/ide.lay @@ -595,7 +595,9 @@ LAYOUT(SetupAssistLayout, 544, 312) ITEM(Upp::Option, barline, SetLabel(t_("Highlight line in the left bar")).LeftPosZ(4, 252).TopPosZ(172, 16)) ITEM(Upp::Option, qtfsel, SetLabel(t_("QTF designer edits selection")).LeftPosZ(4, 252).TopPosZ(192, 16)) ITEM(Upp::Option, navigator_right, SetLabel(t_("Place navigator to the right")).LeftPosZ(4, 252).TopPosZ(212, 16)) - ITEM(Upp::Option, diagnostics, SetLabel(t_("Assist diagnostics (verbose mode)")).LeftPosZ(4, 252).TopPosZ(232, 16)) + ITEM(Upp::Option, show_errors, SetLabel(t_("Show errors in the current file based on libclang parser")).LeftPosZ(4, 340).TopPosZ(232, 16)) + ITEM(Upp::Option, show_errors_status, SetLabel(t_("Show error status of the current file based on libclang parser")).LeftPosZ(4, 252).TopPosZ(252, 16)) + ITEM(Upp::Option, diagnostics, SetLabel(t_("Assist diagnostics (verbose mode)")).LeftPosZ(4, 252).TopPosZ(272, 16)) ITEM(Upp::Option, header_guards, SetLabel(t_("Insert guards to new headers")).LeftPosZ(356, 252).TopPosZ(4, 16)) ITEM(Upp::Switch, insert_include, SetLabel(t_("No #include in new sources\n#include first\n#include previous")).LeftPosZ(356, 252).TopPosZ(24, 52)) END_LAYOUT