mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-05-31 02:26:29 +03:00
Folding fixes.
This commit is contained in:
@@ -139,6 +139,8 @@ class EE_API DocumentView {
|
||||
|
||||
bool isOneToOne() const;
|
||||
|
||||
std::vector<TextRange> intersectsFoldedRegions( const TextRange& range ) const;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<TextDocument> mDoc;
|
||||
FontStyleConfig mFontStyle;
|
||||
@@ -151,7 +153,8 @@ class EE_API DocumentView {
|
||||
bool mPendingReconstruction{ false };
|
||||
bool mUnderConstruction{ false };
|
||||
|
||||
void changeVisibility( Int64 fromDocIdx, Int64 toDocIdx, bool visible );
|
||||
void changeVisibility( Int64 fromDocIdx, Int64 toDocIdx, bool visible,
|
||||
bool recomputeOffset = true );
|
||||
|
||||
void removeFoldedRegion( const TextRange& region );
|
||||
|
||||
@@ -160,6 +163,8 @@ class EE_API DocumentView {
|
||||
void verifyStructuralConsistency();
|
||||
|
||||
void recomputeDocLineToVisibleIndex( Int64 fromVisibleIndex );
|
||||
|
||||
void unfoldRegion( Int64 foldDocIdx, bool verifyConsistency, bool recomputeOffset = true );
|
||||
};
|
||||
|
||||
}}} // namespace EE::UI::Doc
|
||||
|
||||
@@ -386,13 +386,27 @@ bool DocumentView::isLineVisible( Int64 docIdx ) const {
|
||||
mDocLineToVisibleIndex[docIdx] != static_cast<Int64>( VisibleIndex::invalid );
|
||||
}
|
||||
|
||||
std::vector<TextRange> DocumentView::intersectsFoldedRegions( const TextRange& range ) const {
|
||||
std::vector<TextRange> folds;
|
||||
for ( const auto& fold : mFoldedRegions ) {
|
||||
if ( fold.intersectsLineRange( range ) )
|
||||
folds.push_back( fold );
|
||||
}
|
||||
return folds;
|
||||
}
|
||||
|
||||
void DocumentView::updateCache( Int64 fromLine, Int64 toLine, Int64 numLines ) {
|
||||
if ( isOneToOne() )
|
||||
return;
|
||||
|
||||
// Unfold ANY modification over a folded range
|
||||
if ( isFolded( fromLine ) ) {
|
||||
unfoldRegion( fromLine );
|
||||
if ( numLines < 0 ) {
|
||||
auto foldedRegions = intersectsFoldedRegions( { { fromLine, 0 }, { toLine, 0 } } );
|
||||
for ( const auto& fold : foldedRegions )
|
||||
unfoldRegion( fold.start().line(), false, false );
|
||||
} else if ( isFolded( fromLine ) ) {
|
||||
// Offsets will be recomputed here instead in the unfold operation
|
||||
unfoldRegion( fromLine, false, false );
|
||||
}
|
||||
|
||||
// Get affected visible range
|
||||
@@ -480,13 +494,18 @@ void DocumentView::foldRegion( Int64 foldDocIdx ) {
|
||||
}
|
||||
|
||||
void DocumentView::unfoldRegion( Int64 foldDocIdx ) {
|
||||
return unfoldRegion( foldDocIdx, true );
|
||||
}
|
||||
|
||||
void DocumentView::unfoldRegion( Int64 foldDocIdx, bool verifyConsistency, bool recomputeOffset ) {
|
||||
auto foldRegion = mDoc->getFoldRangeService().find( foldDocIdx );
|
||||
if ( !foldRegion )
|
||||
return;
|
||||
Int64 toDocIdx = foldRegion->end().line();
|
||||
removeFoldedRegion( *foldRegion );
|
||||
changeVisibility( foldDocIdx + 1, toDocIdx, true );
|
||||
verifyStructuralConsistency();
|
||||
changeVisibility( foldDocIdx + 1, toDocIdx, true, recomputeOffset );
|
||||
if ( verifyConsistency )
|
||||
verifyStructuralConsistency();
|
||||
if ( isOneToOne() )
|
||||
clearCache();
|
||||
}
|
||||
@@ -495,7 +514,8 @@ bool DocumentView::isOneToOne() const {
|
||||
return mConfig.mode == LineWrapMode::NoWrap && mFoldedRegions.empty();
|
||||
}
|
||||
|
||||
void DocumentView::changeVisibility( Int64 fromDocIdx, Int64 toDocIdx, bool visible ) {
|
||||
void DocumentView::changeVisibility( Int64 fromDocIdx, Int64 toDocIdx, bool visible,
|
||||
bool recomputeOffset ) {
|
||||
if ( visible ) {
|
||||
auto it = std::lower_bound( mVisibleLines.begin(), mVisibleLines.end(),
|
||||
TextPosition{ fromDocIdx, 0 } );
|
||||
@@ -503,15 +523,18 @@ void DocumentView::changeVisibility( Int64 fromDocIdx, Int64 toDocIdx, bool visi
|
||||
auto idxOffset = oldIdxFrom;
|
||||
for ( auto i = fromDocIdx; i <= toDocIdx; i++ ) {
|
||||
if ( isFolded( i, true ) ) {
|
||||
mVisibleLinesOffset[i] = computeOffsets( mDoc->line( i ).getText().view(),
|
||||
mFontStyle, mConfig.tabWidth );
|
||||
if ( recomputeOffset ) {
|
||||
mVisibleLinesOffset[i] = computeOffsets( mDoc->line( i ).getText().view(),
|
||||
mFontStyle, mConfig.tabWidth );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
auto lb = isWrapEnabled()
|
||||
? computeLineBreaks( *mDoc, i, mFontStyle, mMaxWidth, mConfig.mode,
|
||||
mConfig.keepIndentation, mConfig.tabWidth )
|
||||
: LineWrapInfo{ { 0 }, 0 };
|
||||
mVisibleLinesOffset[i] = lb.paddingStart;
|
||||
if ( recomputeOffset )
|
||||
mVisibleLinesOffset[i] = lb.paddingStart;
|
||||
for ( const auto& col : lb.wraps ) {
|
||||
mVisibleLines.insert( mVisibleLines.begin() + idxOffset, { i, col } );
|
||||
idxOffset++;
|
||||
@@ -597,7 +620,19 @@ void DocumentView::verifyStructuralConsistency() {
|
||||
}
|
||||
}
|
||||
|
||||
eeASSERT( visibleLinesOffset == mVisibleLinesOffset );
|
||||
bool offsetConsistency = visibleLinesOffset == mVisibleLinesOffset;
|
||||
eeASSERT( offsetConsistency );
|
||||
|
||||
if ( !offsetConsistency && visibleLinesOffset.size() == mVisibleLinesOffset.size() ) {
|
||||
for ( size_t i = 0; i < mVisibleLinesOffset.size(); i++ ) {
|
||||
if ( mVisibleLinesOffset[i] != visibleLinesOffset[i] ) {
|
||||
eeASSERT( mVisibleLinesOffset[i] == visibleLinesOffset[i] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eeASSERT( mVisibleLinesOffset.size() == mDoc->linesCount() );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -100,8 +100,8 @@ static std::vector<TextRange> findFoldingRangesIndentation( TextDocument* doc )
|
||||
FoldRangeServive::FoldRangeServive( TextDocument* doc ) : mDoc( doc ) {}
|
||||
|
||||
bool FoldRangeServive::canFold() const {
|
||||
// if ( mProvider && mProvider( mDoc, false ) )
|
||||
// return true;
|
||||
if ( mProvider && mProvider( mDoc, false ) )
|
||||
return true;
|
||||
auto type = mDoc->getSyntaxDefinition().getFoldRangeType();
|
||||
return type == FoldRangeType::Braces || type == FoldRangeType::Indentation;
|
||||
}
|
||||
@@ -110,8 +110,8 @@ void FoldRangeServive::findRegions() {
|
||||
if ( mDoc == nullptr || !canFold() )
|
||||
return;
|
||||
|
||||
// if ( mProvider && mProvider( mDoc, true ) )
|
||||
// return;
|
||||
if ( mProvider && mProvider( mDoc, true ) )
|
||||
return;
|
||||
|
||||
switch ( mDoc->getSyntaxDefinition().getFoldRangeType() ) {
|
||||
case FoldRangeType::Braces:
|
||||
|
||||
Reference in New Issue
Block a user