diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Decoration.cxx | 120 | ||||
-rw-r--r-- | src/Decoration.h | 20 | ||||
-rw-r--r-- | src/EditView.cxx | 4 | ||||
-rw-r--r-- | src/Editor.cxx | 13 | ||||
-rw-r--r-- | src/PositionCache.cxx | 2 |
5 files changed, 71 insertions, 88 deletions
diff --git a/src/Decoration.cxx b/src/Decoration.cxx index 2a6060c52..f5f82832f 100644 --- a/src/Decoration.cxx +++ b/src/Decoration.cxx @@ -11,6 +11,7 @@ #include <cstdarg> #include <stdexcept> +#include <vector> #include <algorithm> #include <memory> @@ -27,7 +28,7 @@ using namespace Scintilla; #endif -Decoration::Decoration(int indicator_) : indicator(indicator_), next(0) { +Decoration::Decoration(int indicator_) : indicator(indicator_) { } Decoration::~Decoration() { @@ -37,76 +38,48 @@ bool Decoration::Empty() const { return (rs.Runs() == 1) && (rs.AllSameAs(0)); } -DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(0), - lengthDocument(0), root(0), clickNotified(false) { +DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(nullptr), + lengthDocument(0), clickNotified(false) { } DecorationList::~DecorationList() { - Decoration *deco = root; - while (deco) { - Decoration *decoNext = deco->Next(); - delete deco; - deco = decoNext; - } - root = 0; - current = 0; + current = nullptr; } Decoration *DecorationList::DecorationFromIndicator(int indicator) { - for (Decoration *deco=root; deco; deco = deco->Next()) { + for (const std::unique_ptr<Decoration> &deco : decorationList) { if (deco->Indicator() == indicator) { - return deco; + return deco.get(); } } - return 0; + return nullptr; } Decoration *DecorationList::Create(int indicator, int length) { currentIndicator = indicator; - Decoration *decoNew = new Decoration(indicator); + std::unique_ptr<Decoration> decoNew(new Decoration(indicator)); decoNew->rs.InsertSpace(0, length); - Decoration *decoPrev = 0; - Decoration *deco = root; + std::vector<std::unique_ptr<Decoration>>::iterator it = std::lower_bound( + decorationList.begin(), decorationList.end(), decoNew, + [](const std::unique_ptr<Decoration> &a, const std::unique_ptr<Decoration> &b) { + return a->Indicator() < b->Indicator(); + }); + std::vector<std::unique_ptr<Decoration>>::iterator itAdded = + decorationList.insert(it, std::move(decoNew)); - while (deco && (deco->Indicator() < indicator)) { - decoPrev = deco; - deco = deco->Next(); - } - if (decoPrev == 0) { - decoNew->next = root; - root = decoNew; - } else { - decoNew->next = deco; - decoPrev->next = decoNew; - } - return decoNew; + SetView(); + + return itAdded->get(); } void DecorationList::Delete(int indicator) { - Decoration *decoToDelete = 0; - if (root) { - if (root->Indicator() == indicator) { - decoToDelete = root; - root = root->Next(); - } else { - Decoration *deco = root; - while (deco && deco->Next() && !decoToDelete) { - // decoNext ensures no warning from MSVC Code Analysis - Decoration *decoNext = deco->Next(); - if (decoNext && deco->Next()->Indicator() == indicator) { - decoToDelete = decoNext; - deco->next = decoToDelete->Next(); - } else { - deco = deco->Next(); - } - } - } - } - if (decoToDelete) { - delete decoToDelete; - current = 0; - } + decorationList.erase(std::remove_if(decorationList.begin(), decorationList.end(), + [=](const std::unique_ptr<Decoration> &deco) { + return deco->Indicator() == indicator; + }), decorationList.end()); + current = nullptr; + SetView(); } void DecorationList::SetCurrentIndicator(int indicator) { @@ -136,7 +109,7 @@ bool DecorationList::FillRange(int &position, int value, int &fillLength) { void DecorationList::InsertSpace(int position, int insertLength) { const bool atEnd = position == lengthDocument; lengthDocument += insertLength; - for (Decoration *deco=root; deco; deco = deco->Next()) { + for (const std::unique_ptr<Decoration> &deco : decorationList) { deco->rs.InsertSpace(position, insertLength); if (atEnd) { deco->rs.FillRange(position, 0, insertLength); @@ -146,28 +119,47 @@ void DecorationList::InsertSpace(int position, int insertLength) { void DecorationList::DeleteRange(int position, int deleteLength) { lengthDocument -= deleteLength; - Decoration *deco; - for (deco=root; deco; deco = deco->Next()) { + for (const std::unique_ptr<Decoration> &deco : decorationList) { deco->rs.DeleteRange(position, deleteLength); } DeleteAnyEmpty(); + if (decorationList.size() != decorationView.size()) { + // One or more empty decorations deleted so update view. + current = nullptr; + SetView(); + } +} + +void DecorationList::DeleteLexerDecorations() { + decorationList.erase(std::remove_if(decorationList.begin(), decorationList.end(), + [=](const std::unique_ptr<Decoration> &deco) { + return deco->Indicator() < INDIC_CONTAINER; + }), decorationList.end()); + current = nullptr; + SetView(); } void DecorationList::DeleteAnyEmpty() { - Decoration *deco = root; - while (deco) { - if ((lengthDocument == 0) || deco->Empty()) { - Delete(deco->Indicator()); - deco = root; - } else { - deco = deco->Next(); - } + if (lengthDocument == 0) { + decorationList.clear(); + } else { + decorationList.erase(std::remove_if(decorationList.begin(), decorationList.end(), + [=](const std::unique_ptr<Decoration> &deco) { + return deco->Empty(); + }), decorationList.end()); + } +} + +void DecorationList::SetView() { + decorationView.clear(); + for (const std::unique_ptr<Decoration> &deco : decorationList) { + decorationView.push_back(deco.get()); } } int DecorationList::AllOnFor(int position) const { int mask = 0; - for (Decoration *deco=root; deco; deco = deco->Next()) { + for (const std::unique_ptr<Decoration> &deco : decorationList) { if (deco->rs.ValueAt(position)) { if (deco->Indicator() < INDIC_IME) { mask |= 1 << deco->Indicator(); diff --git a/src/Decoration.h b/src/Decoration.h index 881bd1ff5..d096da385 100644 --- a/src/Decoration.h +++ b/src/Decoration.h @@ -14,16 +14,12 @@ namespace Scintilla { class Decoration { int indicator; public: - Decoration *next; RunStyles rs; explicit Decoration(int indicator_); ~Decoration(); bool Empty() const; - Decoration *Next() const { - return next; - } int Indicator() const { return indicator; } @@ -32,22 +28,24 @@ public: class DecorationList { int currentIndicator; int currentValue; - Decoration *current; + Decoration *current; // Cached so FillRange doesn't have to search for each call. int lengthDocument; + // Ordered by indicator + std::vector<std::unique_ptr<Decoration>> decorationList; + std::vector<const Decoration*> decorationView; // Read-only view of decorationList + bool clickNotified; + Decoration *DecorationFromIndicator(int indicator); Decoration *Create(int indicator, int length); void Delete(int indicator); void DeleteAnyEmpty(); - Decoration *root; - bool clickNotified; + void SetView(); public: DecorationList(); ~DecorationList(); - Decoration *Root() const { - return root; - } + const std::vector<const Decoration*> &View() const { return decorationView; } void SetCurrentIndicator(int indicator); int GetCurrentIndicator() const { return currentIndicator; } @@ -61,6 +59,8 @@ public: void InsertSpace(int position, int insertLength); void DeleteRange(int position, int deleteLength); + void DeleteLexerDecorations(); + int AllOnFor(int position) const; int ValueAt(int indicator, int position); int Start(int indicator, int position); diff --git a/src/EditView.cxx b/src/EditView.cxx index 2798bb25f..808daa6fa 100644 --- a/src/EditView.cxx +++ b/src/EditView.cxx @@ -1041,7 +1041,7 @@ static void DrawIndicators(Surface *surface, const EditModel &model, const ViewS const Sci::Position lineStart = ll->LineStart(subLine); const Sci::Position posLineEnd = posLineStart + lineEnd; - for (Decoration *deco = model.pdoc->decorations.Root(); deco; deco = deco->Next()) { + for (const Decoration *deco : model.pdoc->decorations.View()) { if (under == vsDraw.indicators[deco->Indicator()].under) { Sci::Position startPos = posLineStart + lineStart; if (!deco->rs.ValueAt(startPos)) { @@ -1658,7 +1658,7 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi } if (vsDraw.indicatorsSetFore) { // At least one indicator sets the text colour so see if it applies to this segment - for (Decoration *deco = model.pdoc->decorations.Root(); deco; deco = deco->Next()) { + for (const Decoration *deco : model.pdoc->decorations.View()) { const int indicatorValue = deco->rs.ValueAt(ts.start + posLineStart); if (indicatorValue) { const Indicator &indicator = vsDraw.indicators[deco->Indicator()]; diff --git a/src/Editor.cxx b/src/Editor.cxx index 9344b7d94..77443d52f 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -2097,16 +2097,7 @@ void Editor::ClearAll() { } void Editor::ClearDocumentStyle() { - Decoration *deco = pdoc->decorations.Root(); - while (deco) { - // Save next in case deco deleted - Decoration *decoNext = deco->Next(); - if (deco->Indicator() < INDIC_CONTAINER) { - pdoc->DecorationSetCurrentIndicator(deco->Indicator()); - pdoc->DecorationFillRange(0, 0, pdoc->Length()); - } - deco = decoNext; - } + pdoc->decorations.DeleteLexerDecorations(); pdoc->StartStyling(0, '\377'); pdoc->SetStyleFor(pdoc->Length(), 0); cs.ShowAll(); @@ -4651,7 +4642,7 @@ void Editor::SetHoverIndicatorPosition(Sci::Position position) { if (!vs.indicatorsDynamic) return; if (position != INVALID_POSITION) { - for (Decoration *deco = pdoc->decorations.Root(); deco; deco = deco->Next()) { + for (const Decoration *deco : pdoc->decorations.View()) { if (vs.indicators[deco->Indicator()].IsDynamic()) { if (pdoc->decorations.ValueAt(deco->Indicator(), position)) { hoverIndicatorPos = position; diff --git a/src/PositionCache.cxx b/src/PositionCache.cxx index b6e6c375c..2099046b8 100644 --- a/src/PositionCache.cxx +++ b/src/PositionCache.cxx @@ -470,7 +470,7 @@ BreakFinder::BreakFinder(const LineLayout *ll_, const Selection *psel, Range lin } } if (pvsDraw && pvsDraw->indicatorsSetFore) { - for (Decoration *deco = pdoc->decorations.Root(); deco; deco = deco->Next()) { + for (const Decoration *deco : pdoc->decorations.View()) { if (pvsDraw->indicators[deco->Indicator()].OverridesTextFore()) { Sci::Position startPos = deco->rs.EndRun(posLineStart); while (startPos < (posLineStart + lineRange.end)) { |