diff --git a/IDE/src/ui/SourceEditWidgetContent.bf b/IDE/src/ui/SourceEditWidgetContent.bf index 19b1bc10..dc526471 100644 --- a/IDE/src/ui/SourceEditWidgetContent.bf +++ b/IDE/src/ui/SourceEditWidgetContent.bf @@ -152,26 +152,27 @@ namespace IDE.ui if (rect.mHeight >= DarkTheme.sDarkTheme.mSmallBoldFont.GetLineSpacing()) g.SetFont(DarkTheme.sDarkTheme.mSmallBoldFont); + using (g.PushColor(0xFF404040)) + { + g.FillRect(rect.mX, rect.mY, rect.mWidth, rect.mHeight); + } + if ((mEditWidgetContent.mSelection != null) && (mCollapseIndex < mEditWidgetContent.mOrderedCollapseEntries.Count)) { var collapseEntry = mEditWidgetContent.mOrderedCollapseEntries[mCollapseIndex]; - if ((mEditWidgetContent.mSelection.Value.MinPos <= collapseEntry.mEndIdx) && (mEditWidgetContent.mSelection.Value.MaxPos >= collapseEntry.mStartIdx)) + int32 startIdx = mEditWidgetContent.mData.mLineStarts[collapseEntry.mStartLine]; + if ((mEditWidgetContent.mSelection.Value.MinPos <= collapseEntry.mEndIdx) && (mEditWidgetContent.mSelection.Value.MaxPos >= startIdx)) { using (g.PushColor(mEditWidgetContent.GetSelectionColor(0))) g.FillRect(rect.mX, rect.mY, rect.mWidth, rect.mHeight); } } - using (g.PushColor(0x80FFFFFF)) + using (g.PushColor(0xFF909090)) { g.OutlineRect(rect.mX, rect.mY, rect.mWidth, rect.mHeight); } - using (g.PushColor(0x20FFFFFF)) - { - g.FillRect(rect.mX, rect.mY, rect.mWidth, rect.mHeight); - } - var summaryString = "..."; if ((mHideString != null) && (hideLine)) summaryString = scope:: $"{mHideString} ..."; @@ -190,16 +191,15 @@ namespace IDE.ui Property = 'P', Region = 'R', Type = 'T', + UsingNamespaces = 'U', Unknown = '?' } public Kind mKind; public int32 mAnchorIdx; - public int32 mStartIdx; public int32 mEndIdx; public int32 mAnchorId; - public int32 mStartId; public int32 mEndId; public int32 mAnchorLine = -1; @@ -216,19 +216,6 @@ namespace IDE.ui public int32 mParseRevision; public int32 mTextRevision; public bool mDeleted; - - public void FixAfterUpdate() mut - { - if (mAnchorLine == mEndLine) - { - mDeleted = true; - } - else if (mAnchorLine == mStartLine) - { - if (mAnchorId != mStartId) - mStartLine++; - } - } } public class Data : DarkEditWidgetContent.Data @@ -4809,7 +4796,7 @@ namespace IDE.ui { bool hadSelection = HasSelection(); - if ((dir > 0) && (HasSelection())) + if ((dir > 0) && (HasSelection()) && (mSelection.Value.Length > 1) && (!mWidgetWindow.IsKeyDown(.Shift))) { GetLineCharAtIdx(mSelection.Value.MaxPos - 1, var maxLine, ?); if (IsLineCollapsed(maxLine)) @@ -4831,6 +4818,8 @@ namespace IDE.ui int anchorLine = FindUncollapsedLine(line); CursorLineAndColumn = .(anchorLine, 0); base.CursorToLineEnd(); + if ((mWidgetWindow.IsKeyDown(.Shift)) && (HasSelection())) + mSelection.ValueRef.mEndPos = (.)CursorTextPos; return true; } } @@ -5173,6 +5162,29 @@ namespace IDE.ui mHilitePairedCharState = .NeedToRecalculate; } + void FixCollapseAfterUpdate(int idx, CollapseEntry* entry) + { + if (idx > 0) + { + var prevEntry = mOrderedCollapseEntries[idx - 1]; + if (entry.mAnchorLine == prevEntry.mEndLine) + { + entry.mAnchorLine = prevEntry.mEndLine + 1; + entry.mStartLine = entry.mAnchorLine; + } + } + + if (entry.mAnchorLine >= entry.mEndLine) + { + entry.mDeleted = true; + } + else if (entry.mAnchorLine == entry.mStartLine) + { + if ((entry.mKind != .Comment) && (entry.mKind != .UsingNamespaces)) + entry.mStartLine++; + } + } + public override void GetTextData() { var data = Data; @@ -5212,7 +5224,7 @@ namespace IDE.ui for (var entry in mOrderedCollapseEntries) { - entry.FixAfterUpdate(); + FixCollapseAfterUpdate(@entry.Index, entry); if (entry.mDeleted) { @@ -5491,6 +5503,9 @@ namespace IDE.ui activeEntry = null; } + if (entry.mKind == .Region) + continue; + if (activeEntry != null) { if (activeEntry.mKind == .Type) @@ -5550,7 +5565,8 @@ namespace IDE.ui FinishCollapseClose(collapseIdx, entry); } - if ((!wantOpen) && (mSelection != null) && (mSelection.Value.MinPos >= entry.mStartIdx) && (mSelection.Value.MinPos <= entry.mEndIdx)) + int32 startIdx = mData.mLineStarts[entry.mStartLine]; + if ((!wantOpen) && (mSelection != null) && (mSelection.Value.MinPos >= startIdx) && (mSelection.Value.MinPos <= entry.mEndIdx)) { if (mSelection.Value.MaxPos > entry.mEndIdx + 1) mSelection = .(entry.mEndIdx + 1, mSelection.Value.MaxPos); @@ -5630,10 +5646,10 @@ namespace IDE.ui { failed = false; Update(entry.mAnchorId, ref entry.mAnchorIdx, ref entry.mAnchorLine); - Update(entry.mStartId, ref entry.mStartIdx, ref entry.mStartLine); Update(entry.mEndId, ref entry.mEndIdx, ref entry.mEndLine); + entry.mStartLine = entry.mAnchorLine; - entry.FixAfterUpdate(); + FixCollapseAfterUpdate(@entry.Index, entry); } if (entry.mDeleted) @@ -5676,21 +5692,18 @@ namespace IDE.ui collapseData.mAnchorIdx = int32.Parse(itr.GetNext().Value); collapseData.mAnchorId = lookupCtx.GetIdAtIndex(collapseData.mAnchorIdx); collapseData.mKind = kind; - collapseData.mStartIdx = int32.Parse(itr.GetNext().Value); collapseData.mEndIdx = int32.Parse(itr.GetNext().Value); GetLineCharAtIdx(collapseData.mAnchorIdx, var line, var lineChar); collapseData.mAnchorLine = (.)line; - collapseData.mStartId = lookupCtx.GetIdAtIndex(collapseData.mStartIdx); - GetLineCharAtIdx(collapseData.mStartIdx, out line, out lineChar); - collapseData.mStartLine = (.)line; + collapseData.mStartLine = collapseData.mAnchorLine; collapseData.mEndId = lookupCtx.GetIdAtIndex(collapseData.mEndIdx); GetLineCharAtIdx(collapseData.mEndIdx, out line, out lineChar); collapseData.mEndLine = (.)line; - if ((collapseData.mAnchorId == -1) || (collapseData.mStartId == -1) || (collapseData.mEndId == -1)) + if ((collapseData.mAnchorId == -1) || (collapseData.mEndId == -1)) { Debug.FatalError(); continue; @@ -5715,7 +5728,8 @@ namespace IDE.ui collapseSummary.mKind = .HideLine; *valuePtr = collapseSummary; - var content = ExtractString(entry.mStartIdx, Math.Min(entry.mEndId - entry.mStartIdx + 1, 8192), .. scope .()); + int startIdx = mData.mLineStarts[entry.mStartLine]; + var content = ExtractString(startIdx, Math.Min(entry.mEndIdx - startIdx + 1, 8192), .. scope .()); content.Trim(); collapseSummary.mHideString = new .(); diff --git a/IDE/src/ui/SourceViewPanel.bf b/IDE/src/ui/SourceViewPanel.bf index b1749f06..7aac00f2 100644 --- a/IDE/src/ui/SourceViewPanel.bf +++ b/IDE/src/ui/SourceViewPanel.bf @@ -4278,6 +4278,8 @@ namespace IDE.ui if ((drawLineNum < lineStart) || (drawLineNum >= lineEnd)) continue; + if (ewc.IsLineCollapsed(drawLineNum)) + continue; var curLineFlags = ref lineFlags[drawLineNum - lineStart]; int breakpointCount = (.)(curLineFlags & .BreakpointCountMask); curLineFlags++; @@ -4303,6 +4305,8 @@ namespace IDE.ui int32 drawLineNum = bookmark.mLineNum; if ((drawLineNum < lineStart) || (drawLineNum >= lineEnd)) continue; + if (ewc.IsLineCollapsed(drawLineNum)) + continue; //hadLineIcon[drawLineNum - lineStart] = true; g.Draw(DarkTheme.sDarkTheme.GetImage(.IconBookmark), Math.Max(GS!(-5), mEditWidget.mX - GS!(30) - leftAdjust), 0 + bookmark.mLineNum * lineSpacing); diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index efd83bc7..ef3d6658 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -9159,9 +9159,10 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo class CollapseVisitor : public BfElementVisitor { public: + BfAstNode* mParentNode; BfParser* mParser; String& mOutString; - HashSet mStartsFound; + HashSet mEndsFound; char mSeriesKind; int mStartSeriesIdx; int mEndSeriesIdx; @@ -9170,7 +9171,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo CollapseVisitor(BfParser* parser, String& string) : mOutString(string) { mParser = parser; - + mParentNode = NULL; mSeriesKind = 0; mStartSeriesIdx = -1; mEndSeriesIdx = -1; @@ -9180,10 +9181,9 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo { if (mStartSeriesIdx != -1) { - if ((node->mTriviaStart != mEndSeriesIdx + 1) || (kind != mSeriesKind)) + if ((node->mTriviaStart != mEndSeriesIdx) || (kind != mSeriesKind)) { - // Flush - Add(mStartSeriesIdx, mStartSeriesIdx, mEndSeriesIdx, mSeriesKind); + FlushSeries(); mStartSeriesIdx = node->mSrcStart; } } @@ -9191,13 +9191,35 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo mStartSeriesIdx = node->mSrcStart; mSeriesKind = kind; - mEndSeriesIdx = node->mSrcEnd - 1; + mEndSeriesIdx = BF_MIN(node->mSrcEnd, mParser->mSrcLength -1); } void FlushSeries() - { + { if (mStartSeriesIdx != -1) - Add(mStartSeriesIdx, mStartSeriesIdx, mEndSeriesIdx, mSeriesKind); + { + bool ownsLine = true; + for (int checkIdx = mStartSeriesIdx - 1; checkIdx >= 0; checkIdx--) + { + char c = mParser->mSrc[checkIdx]; + if (c == '\n') + break; + if (!isspace((uint8)c)) + { + ownsLine = false; + break; + } + } + + int anchor = mStartSeriesIdx; + if (!ownsLine) + { + int nextLine = GetLineStartAfter(anchor); + if (nextLine != -1) + anchor = nextLine; + } + Add(anchor, mEndSeriesIdx, mSeriesKind); + } mStartSeriesIdx = -1; } @@ -9221,54 +9243,49 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo return -1; } - void Add(int anchor, int start, int end, char kind = '?') + void Add(int anchor, int end, char kind = '?', int minLines = 2) { - if ((anchor == -1) || (start == -1) || (end == -1)) + if ((anchor == -1) || (end == -1)) return; - bool isMultiline = false; - for (int i = start; i < end; i++) + if (!mEndsFound.Add(end)) + return; + + int lineCount = 1; + for (int i = anchor; i < end; i++) { if (mParser->mSrc[i] == '\n') { - isMultiline = true; - break; + lineCount++; + if (lineCount >= minLines) + break; } } - if (!isMultiline) + if (lineCount < minLines) return; char str[1024]; - sprintf(str, "%c%d,%d,%d\n", kind, anchor, start, end); + sprintf(str, "%c%d,%d\n", kind, anchor, end); mOutString.Append(str); } - void Add(BfAstNode* anchor, BfAstNode* start, BfAstNode* end, char kind = '?') + void Add(BfAstNode* anchor, BfAstNode* end, char kind = '?', int minLines = 2) { - if ((anchor == NULL) || (start == NULL) || (end == NULL)) - return; - if (!mStartsFound.Add(start->mSrcStart)) - return; - Add(anchor->mSrcStart, start->mSrcStart, end->mSrcStart, kind); + if ((anchor == NULL) || (end == NULL)) + return; + Add(anchor->mSrcStart, end->mSrcEnd - 1, kind, minLines); } - - void Add(BfAstNode* anchor, BfAstNode* body, char kind = '?') - { - if (auto block = BfNodeDynCast(body)) - { - Add(anchor, block->mOpenBrace, block->mCloseBrace, kind); - } - } - + virtual void Visit(BfMethodDeclaration* methodDeclaration) override - { - BfAstNode* anchorNode = methodDeclaration->mNameNode; - if (auto ctorDeclaration = BfNodeDynCast(methodDeclaration)) - anchorNode = ctorDeclaration->mThisToken; - if (auto dtorDeclaration = BfNodeDynCast(methodDeclaration)) - anchorNode = dtorDeclaration->mThisToken; - if (auto propertyDeclaration = BfNodeDynCast(methodDeclaration)) - anchorNode = propertyDeclaration->mOperatorToken; - Add(anchorNode, methodDeclaration->mBody, 'M'); + { + int anchorIdx = methodDeclaration->mSrcStart; + + if (methodDeclaration->mNameNode != NULL) + anchorIdx = methodDeclaration->mNameNode->mSrcEnd - 1; + if (methodDeclaration->mCloseParen != NULL) + anchorIdx = methodDeclaration->mCloseParen->mSrcEnd - 1; + + if (methodDeclaration->mBody != NULL) + Add(anchorIdx, methodDeclaration->mBody->mSrcEnd - 1, 'M'); BfElementVisitor::Visit(methodDeclaration); } @@ -9319,24 +9336,25 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo } virtual void Visit(BfIfStatement* ifStatement) override - { - Add(ifStatement->mIfToken, ifStatement->mTrueStatement); - Add(ifStatement->mElseToken, ifStatement->mFalseStatement); + { + Add(ifStatement->mCloseParen, ifStatement->mTrueStatement); + if (auto elseBlock = BfNodeDynCast(ifStatement->mFalseStatement)) + Add(ifStatement->mElseToken, elseBlock); BfElementVisitor::Visit(ifStatement); } virtual void Visit(BfRepeatStatement* repeatStatement) override { - Add(repeatStatement->mRepeatToken, repeatStatement->mEmbeddedStatement); - + Add(repeatStatement->mRepeatToken, repeatStatement); + if (repeatStatement->mEmbeddedStatement != NULL) + mEndsFound.Add(repeatStatement->mEmbeddedStatement->mSrcEnd - 1); BfElementVisitor::Visit(repeatStatement); } virtual void Visit(BfWhileStatement* whileStatement) override { - Add(whileStatement->mWhileToken, whileStatement->mEmbeddedStatement); - + Add(whileStatement->mCloseParen, whileStatement->mEmbeddedStatement); BfElementVisitor::Visit(whileStatement); } @@ -9348,53 +9366,52 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo } virtual void Visit(BfForStatement* forStatement) override - { - Add(forStatement->mForToken, forStatement->mEmbeddedStatement); - + { + Add(forStatement->mCloseParen, forStatement->mEmbeddedStatement); BfElementVisitor::Visit(forStatement); } virtual void Visit(BfForEachStatement* forStatement) override - { - Add(forStatement->mForToken, forStatement->mEmbeddedStatement); - + { + Add(forStatement->mCloseParen, forStatement->mEmbeddedStatement); BfElementVisitor::Visit(forStatement); } virtual void Visit(BfUsingStatement* usingStatement) override { Add(usingStatement->mUsingToken, usingStatement->mEmbeddedStatement); - BfElementVisitor::Visit(usingStatement); } virtual void Visit(BfSwitchStatement* switchStatement) override { - Add(switchStatement->mSwitchToken, switchStatement->mOpenBrace, switchStatement->mCloseBrace); - + Add(switchStatement->mOpenParen, switchStatement->mCloseBrace); BfElementVisitor::Visit(switchStatement); } virtual void Visit(BfLambdaBindExpression* lambdaExpression) override { Add(lambdaExpression->mFatArrowToken, lambdaExpression->mBody); - BfElementVisitor::Visit(lambdaExpression); } virtual void Visit(BfBlock* block) override { - Add(block->mOpenBrace, block->mOpenBrace, block->mCloseBrace); - + Add(block->mOpenBrace, block->mCloseBrace); BfElementVisitor::Visit(block); } virtual void Visit(BfInitializerExpression* initExpr) override { - Add(initExpr->mOpenBrace, initExpr->mOpenBrace, initExpr->mCloseBrace); - + Add(initExpr->mOpenBrace, initExpr->mCloseBrace); BfElementVisitor::Visit(initExpr); } + + virtual void Visit(BfInvocationExpression* invocationExpr) override + { + Add(invocationExpr->mOpenParen, invocationExpr->mCloseParen, '?', 3); + BfElementVisitor::Visit(invocationExpr); + } }; CollapseVisitor collapseVisitor(bfParser, outString); @@ -9411,7 +9428,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo { if ((ignoredSectionStart != -1) && (prevPreprocessorNode != NULL) && (prevPreprocessorNode->mCommand != NULL)) { - collapseVisitor.Add(prevPreprocessorNode->mCommand->mSrcStart, ignoredSectionStart, preprocessorNode->mSrcEnd - 1); + collapseVisitor.Add(prevPreprocessorNode->mCommand->mSrcStart, preprocessorNode->mSrcEnd - 1); ignoredSectionStart = -1; } @@ -9421,7 +9438,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo else if (sv == "endregion") { if (regionStart != NULL) - collapseVisitor.Add(regionStart->mSrcStart, collapseVisitor.GetLineStartAfter(regionStart->mSrcStart), preprocessorNode->mCommand->mSrcStart, 'R'); + collapseVisitor.Add(regionStart->mSrcStart, preprocessorNode->mCommand->mSrcStart, 'R'); regionStart = NULL; } else if (sv == "if") @@ -9431,13 +9448,13 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo else if (sv == "endif") { if (condStart != NULL) - collapseVisitor.Add(condStart->mSrcStart, collapseVisitor.GetLineStartAfter(condStart->mSrcStart), preprocessorNode->mCommand->mSrcStart, 'R'); + collapseVisitor.Add(condStart->mSrcStart, preprocessorNode->mCommand->mSrcStart); condStart = NULL; } else if ((sv == "else") || (sv == "elif")) { if (condStart != NULL) - collapseVisitor.Add(condStart->mSrcStart, collapseVisitor.GetLineStartAfter(condStart->mSrcStart), collapseVisitor.GetLineEndBefore(preprocessorNode->mSrcStart), 'R'); + collapseVisitor.Add(condStart->mSrcStart, collapseVisitor.GetLineEndBefore(preprocessorNode->mSrcStart)); condStart = preprocessorNode->mCommand; } @@ -9461,7 +9478,9 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo char kind = 0; if (auto commentNode = BfNodeDynCast(element)) + { collapseVisitor.UpdateSeries(commentNode, 'C'); + } } collapseVisitor.FlushSeries();