Pārlūkot izejas kodu

Improved collapsing anchor/start logic

Brian Fiete 3 gadi atpakaļ
vecāks
revīzija
9b7fc5564e

+ 47 - 33
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 .();

+ 4 - 0
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);

+ 83 - 64
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<int> mStartsFound;
+		HashSet<int> 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;
+
+			if (!mEndsFound.Add(end))
 				return;
 
-			bool isMultiline = false;
-			for (int i = start; i < end; i++)
+			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);
 		}
+		
+		virtual void Visit(BfMethodDeclaration* methodDeclaration) override
+		{	
+			int anchorIdx = methodDeclaration->mSrcStart;
 
-		void Add(BfAstNode* anchor, BfAstNode* body, char kind = '?')
-		{
-			if (auto block = BfNodeDynCast<BfBlock>(body))
-			{
-				Add(anchor, block->mOpenBrace, block->mCloseBrace, kind);
-			}
-		}
+			if (methodDeclaration->mNameNode != NULL)
+				anchorIdx = methodDeclaration->mNameNode->mSrcEnd - 1;
+			if (methodDeclaration->mCloseParen != NULL)
+				anchorIdx = methodDeclaration->mCloseParen->mSrcEnd - 1;
 
-		virtual void Visit(BfMethodDeclaration* methodDeclaration) override
-		{			
-			BfAstNode* anchorNode = methodDeclaration->mNameNode;
-			if (auto ctorDeclaration = BfNodeDynCast<BfConstructorDeclaration>(methodDeclaration))
-				anchorNode = ctorDeclaration->mThisToken;
-			if (auto dtorDeclaration = BfNodeDynCast<BfDestructorDeclaration>(methodDeclaration))
-				anchorNode = dtorDeclaration->mThisToken;
-			if (auto propertyDeclaration = BfNodeDynCast<BfOperatorDeclaration>(methodDeclaration))
-				anchorNode = propertyDeclaration->mOperatorToken;
-			Add(anchorNode, methodDeclaration->mBody, 'M');
+			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<BfBlock>(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<BfCommentNode>(element))
+		{
 			collapseVisitor.UpdateSeries(commentNode, 'C');
+		}
 	}
 
 	collapseVisitor.FlushSeries();