Folding fixes.

This commit is contained in:
Martín Lucas Golini
2024-05-30 20:04:03 -03:00
parent a4be2966fd
commit d39be5958d
3 changed files with 54 additions and 14 deletions

View File

@@ -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

View File

@@ -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
}

View File

@@ -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: