Browse Source

Breakpoint hotkeys, autocomplete fix

Brian Fiete 5 years ago
parent
commit
1c6c06fa4d

+ 5 - 4
BeefBuild/src/BuildApp.bf

@@ -13,7 +13,7 @@ namespace BeefBuild
 		const int cProgressSize = 30;
 		int mProgressIdx = 0;		
 		public bool mIsTest;
-		public bool mIsFailTest;
+		public bool mTestIncludeIgnored;
 		public bool mDidRun;
 
 		/*void Test()
@@ -103,7 +103,7 @@ namespace BeefBuild
 
 			if (mIsTest)
 			{
-				RunTests(false);
+				RunTests(mTestIncludeIgnored, false);
 			}
 			else if (mVerb != .New)
 				Compile(.Normal, null);
@@ -129,8 +129,9 @@ namespace BeefBuild
 				case "-test":
 					mIsTest = true;
 					return true;
-				case "-testfail":
-					mIsFailTest = true;
+				case "-testall":
+					mIsTest = true;
+					mTestIncludeIgnored = true;
 					return true;
 				case "-clean":
 					mWantsClean = true;

+ 38 - 17
BeefLibs/Beefy2D/src/widgets/EditWidget.bf

@@ -1842,22 +1842,31 @@ namespace Beefy.widgets
             return Math.Max(0, Math.Min(newY, mHeight - mEditWidget.mScrollContentContainer.mHeight - mMaximalScrollAddedHeight));
         }
 
-        int32 GetCharType(char8 theChar)
+		enum CharType
+		{
+			Unknown = -1,
+			NewLine,
+			WhiteSpace,
+			NonBreaking,
+			Opening,
+			Other
+		}
+        CharType GetCharType(char8 theChar)
         {
             if (theChar == '\n')
-                return 2;
+                return .NewLine;
             if (theChar.IsWhiteSpace)
-                return 0;
+                return .WhiteSpace;
             if (IsNonBreakingChar(theChar))
-                return 1;
+                return .NonBreaking;
 
             // We break on each instance of these
             switch (theChar)
             {
             case '<', '>', '(', ')', '[', ']', '{', '}':
-                return 3;
+                return .Opening;
             }
-            return 4;
+            return .Other;
         }
 
         public void GetTextCoordAtCursor(out float x, out float y)
@@ -2053,9 +2062,11 @@ namespace Beefy.widgets
 						    }
 						}
 
+						bool isWordMove = mWidgetWindow.IsKeyDown(.Alt);
                         wasMoveKey = true;
                         int anIndex = GetTextIdx(lineIdx, lineChar);
-                        int prevCharType = (anIndex > 0) ? GetCharType((char8)mData.mText[anIndex - 1].mChar) : -1;
+						char8 prevC = 0;
+                        CharType prevCharType = (anIndex > 0) ? GetCharType((char8)mData.mText[anIndex - 1].mChar) : .Unknown;
                         while (true)
                         {
                             if (lineChar > 0)
@@ -2082,19 +2093,23 @@ namespace Beefy.widgets
                             if (anIndex == 0)
                                 break;
 
-                            char8 aChar = (char8)mData.mText[anIndex - 1].mChar;
-                            int32 char8Type = GetCharType(aChar);
-                            if (prevCharType == 3)
+                            char8 c = (char8)mData.mText[anIndex - 1].mChar;
+                            CharType char8Type = GetCharType(c);
+                            if (prevCharType == .Opening)
                                 break;
                             if (char8Type != prevCharType)
                             {
                                 if ((char8Type == 0) && (prevCharType != 0))
                                     break;
-                                if ((prevCharType == 2) || (prevCharType == 1) || (prevCharType == 4))
+                                if ((prevCharType == .NewLine) || (prevCharType == .NonBreaking) || (prevCharType == .Other))
                                     break;
                             }
 
+							if ((isWordMove) && (c.IsLower) && (prevC.IsUpper))
+								break;
+
                             prevCharType = char8Type;
+							prevC = c;
                         }
                     }
                 }
@@ -2131,9 +2146,11 @@ namespace Beefy.widgets
 	                        }
 						}
 
+						bool isWordMove = mWidgetWindow.IsKeyDown(.Alt);
                         wasMoveKey = true;
                         int anIndex = GetTextIdx(lineIdx, lineChar);
-                        int prevCharType = (anIndex < mData.mTextLength) ? GetCharType((char8)mData.mText[anIndex].mChar) : -1;
+						char8 prevC = 0;
+                        CharType prevCharType = (anIndex < mData.mTextLength) ? GetCharType((char8)mData.mText[anIndex].mChar) : .Unknown;
                         while (true)
                         {
                             int lineStart;
@@ -2165,19 +2182,23 @@ namespace Beefy.widgets
                             if (anIndex == mData.mTextLength)
                                 break;
 
-                            char8 aChar = (char8)mData.mText[anIndex].mChar;
-                            int32 char8Type = GetCharType(aChar);
-                            if (char8Type == 3)
+                            char8 c = (char8)mData.mText[anIndex].mChar;
+                            CharType char8Type = GetCharType(c);
+                            if (char8Type == .Opening)
                                 break;
                             if (char8Type != prevCharType)
                             {
-                                if ((char8Type != 0) && (prevCharType == 0))
+                                if ((char8Type != .WhiteSpace) && (prevCharType == .WhiteSpace))
                                     break;
-                                if ((char8Type == 2) || (char8Type == 1) || (char8Type == 4))
+                                if ((char8Type == .NewLine) || (char8Type == .NonBreaking) || (char8Type == .Other))
                                     break;
                             }
 
+							if ((isWordMove) && (c.IsUpper) && (prevC.IsLower))
+								break;
+
                             prevCharType = char8Type;
+							prevC = c;
                         }
                     }
                 }

+ 9 - 1
BeefLibs/corlib/src/Collections/Generic/HashSet.bf

@@ -290,11 +290,19 @@ namespace System.Collections.Generic
 		}
 
 		/// Number of elements in this hashset
-		public int32 Count
+		public int Count
 		{
 			get { return mCount; }
 		}
 
+		public bool IsEmpty
+		{
+			get
+			{
+				return mCount == 0;
+			}
+		}
+
 		/// Whether this is readonly
 		/*bool ICollection<T>.IsReadOnly
 		{

+ 1 - 1
IDE/BeefProj.toml

@@ -25,7 +25,7 @@ OtherLinkFlags = ""
 TargetDirectory = "$(WorkspaceDir)/dist"
 TargetName = "BeefIDE_d"
 OtherLinkFlags = "$(LinkFlags) Comdlg32.lib kernel32.lib user32.lib advapi32.lib shell32.lib IDEHelper64_d.lib"
-DebugCommandArguments = "-workspace=C:\\Beef\\BeefBuild"
+DebugCommandArguments = "-workspace=C:\\Beef\\IDEHelper\\Tests"
 DebugWorkingDirectory = "c:\\Beef\\IDE\\Tests\\EmptyTest"
 EnvironmentVars = ["_NO_DEBUG_HEAP=1"]
 

+ 0 - 8
IDE/mintest/BeefSpace.toml

@@ -95,14 +95,6 @@ COptimizationLevel = "O2"
 ConfigSelections = {mintest = {Config = "Debug"}}
 
 [Configs.Test.Win64]
-EmitDynamicCastCheck = false
-EnableObjectDebugFlags = false
-EmitObjectAccessCheck = false
-EnableRealtimeLeakCheck = false
-AllowHotSwapping = false
-AllocStackTraceDepth = 0
-COptimizationLevel = "O2"
-ConfigSelections = {mintest = {Config = "Debug"}}
 
 [Configs.Test.WinFart]
 Toolset = "GNU"

+ 0 - 31
IDE/mintest/mintest2/src/main4.bf

@@ -1,33 +1,2 @@
 using System;
 
-/*class Zlobs : IDisposable
-{
-	int IDisposable.Floo()
-	{
-
-	}
-
-	int Zag()
-	{
-		return 123;
-	}
-}*/
-
-class Fligs
-{
-	class Bligs
-	{
-		class Snorf
-		{
-
-		}
-	}
-
-	class Zang
-	{
-		class Flang
-		{
-
-		}
-	}
-}

+ 17 - 29
IDE/mintest/src/main3.bf

@@ -211,7 +211,7 @@ struct Blurg
 		}
 	}
 
-	static int[] gArr = new .(1, 2, 3, 4, 5, );
+	//static int[] gArr = new .(1, 2, 3, 4, 5, );
 
 	[Checked]
 	public static int32 GetVal()
@@ -305,12 +305,6 @@ struct Blurg
 		 //int len = str.[Friend]GetLength();
 	}				   
 
-	
-	static void Test(int a, int b, Span<int> iSpan)
-	{
-
-	}
-
 	public static mixin Florf(int a, int b)
 	{
 
@@ -324,36 +318,30 @@ struct Blurg
 		}
 	}
 
-	public static int32 Hey()
+	public static int sA = 123;
+
+	/*public static void Test<T>(T val)
 	{
-		for (int i < 100)
-		{
-			Yoofer.ColorizeCodeString("abc", .Callstack);
-		}
-		return (int32)123;
-	}
 
-}
+	}*/
 
-class Yoofer
-{
-	public enum CodeKind
+	public static void Test<T, T2>(T val) where T : Span<T2>
 	{
-		Callstack,
-		Method,
-		Field,
-		Type
-	}
 
-	public static void Zorg()
-	{
-		int a = 1;
 	}
 
-	public static void ColorizeCodeString(String label, CodeKind codeKind)
+	public static int32 Hey()
 	{
-		Zorg();
-		int a = 1;
+		Span<uint8> valSpan = .();
+		StringView sv = "Hey";
+
+		Span<char8> span = sv;
+
+		Test(sv);
+
+		return (int32)123;
 	}
+
 }
 
+

+ 8 - 5
IDE/src/Commands.bf

@@ -177,8 +177,10 @@ namespace IDE
 			Add("Bookmark Toggle", new => gApp.Cmd_ToggleBookmark, .Editor);
 			Add("Bookmark Clear", new => gApp.Cmd_ClearBookmarks, .Editor);
 			Add("Break All", new => gApp.[Friend]Cmd_Break);
-			Add("Breakpoint Memory", new () => { gApp.mBreakpointPanel.AddMemoryBreakpoint(gApp.[Friend]GetCurrentWindow()); }, .Editor);
-			Add("Breakpoint Symbol", new () => { gApp.mBreakpointPanel.AddSymbolBreakpoint(gApp.[Friend]GetCurrentWindow()); }, .Editor);
+			Add("Breakpoint Configure", new () => gApp.ConfigureBreakpoint());
+			Add("Breakpoint Disable", new () => gApp.DisableBreakpoint());
+			Add("Breakpoint Memory", new () => { gApp.mBreakpointPanel.AddMemoryBreakpoint(gApp.[Friend]GetCurrentWindow()); });
+			Add("Breakpoint Symbol", new () => { gApp.mBreakpointPanel.AddSymbolBreakpoint(gApp.[Friend]GetCurrentWindow()); });
 			Add("Breakpoint Toggle Thread", new => gApp.[Friend]ToggleThreadBreakpoint, .Editor);
 			Add("Breakpoint Toggle", new => gApp.[Friend]ToggleBreakpoint, .Editor);
 			Add("Build Solution", new => gApp.[Friend]Compile);
@@ -189,7 +191,8 @@ namespace IDE
 			Add("Close Window", new () => { gApp.[Friend]TryCloseCurrentDocument(); });
 			Add("Close Workspace", new => gApp.[Friend]Cmd_CloseWorkspaceAndSetupNew);
 			Add("Compile File", new => gApp.Cmd_CompileFile);
-			Add("Debug All Tests", new () => { gApp.[Friend]RunTests(true); });
+			Add("Debug All Tests", new () => { gApp.[Friend]RunTests(true, true); });
+			Add("Debug Normal Tests", new () => { gApp.[Friend]RunTests(false, true); });
 			Add("Exit", new => gApp.[Friend]Cmd_Exit);
 			Add("Find All References", new => gApp.Cmd_FindAllReferences);
 			Add("Find Class", new => gApp.Cmd_FindClass);
@@ -229,7 +232,8 @@ namespace IDE
 			Add("Replace in Document", new => gApp.Cmd_Document__Replace);
 			Add("Replace in Files", new => gApp.Cmd_Replace);
 			Add("Report Memory", new => gApp.[Friend]ReportMemory);
-			Add("Run All Tests", new => gApp.Cmd_RunAllTests);
+			Add("Run All Tests", new () => { gApp.[Friend]RunTests(true, false); });
+			Add("Run Normal Tests", new () => { gApp.[Friend]RunTests(false, false); });
 			Add("Run To Cursor", new => gApp.[Friend]RunToCursor);
 			Add("Run Without Compiling", new => gApp.[Friend]RunWithoutCompiling);
 			Add("Save All", new () => { gApp.SaveAll(); });
@@ -276,7 +280,6 @@ namespace IDE
 			Add("Attach to Process", new => gApp.[Friend]DoAttach);
 
 			Add("Test Enable Console", new => gApp.Cmd_TestEnableConsole);
-			Add("Test Include Ignored", new => gApp.Cmd_TestIncludeIgnored);
 		}
 	}
 }

+ 15 - 0
IDE/src/Debugger/Breakpoint.bf

@@ -19,6 +19,21 @@ namespace IDE.Debugger
 			MultipleOf
 		};
 
+		public enum SetKind
+		{
+			Toggle,
+			Force,
+			EnsureExists,
+			MustExist
+		}
+
+		public enum SetFlags
+		{
+			None,
+			Configure,
+			Disable
+		}
+
         [StdCall, CLink]
         static extern void Breakpoint_Delete(void* nativeBreakpoint);
         

+ 54 - 33
IDE/src/IDEApp.bf

@@ -295,7 +295,6 @@ namespace IDE
 		public bool mEnableGCCollect = true;
 		public bool mDbgFastUpdate;
 		public bool mTestEnableConsole = false;
-		public bool mTestIncludeIgnored = false;
 		public ProfileInstance mLongUpdateProfileId;
 		public uint32 mLastLongUpdateCheck;
 		public uint32 mLastLongUpdateCheckError;
@@ -3988,11 +3987,11 @@ namespace IDE
 			if (sourceViewPanel != null)
 			{
 				BfLog.LogDbg("Creating mRunToCursorBreakpoint\n");
-				mDebugger.mRunToCursorBreakpoint = sourceViewPanel.ToggleBreakpointAtCursor(true, mDebugger.GetActiveThread());
+				mDebugger.mRunToCursorBreakpoint = sourceViewPanel.ToggleBreakpointAtCursor(.Force, .None, mDebugger.GetActiveThread());
 			}
 			else if (var disassemblyPanel = GetActiveDocumentPanel() as DisassemblyPanel)
 			{
-				mDebugger.mRunToCursorBreakpoint = disassemblyPanel.ToggleAddrBreakpointAtCursor(true, mDebugger.GetActiveThread());
+				mDebugger.mRunToCursorBreakpoint = disassemblyPanel.ToggleAddrBreakpointAtCursor(.Force, .None, mDebugger.GetActiveThread());
 			}
 
 			if (mDebugger.mIsRunning)
@@ -4090,17 +4089,17 @@ namespace IDE
 			}
 		}
 
-		void ToggleBreakpoint(WidgetWindow window, bool bindToThread = false)
+		void ToggleBreakpoint(WidgetWindow window, Breakpoint.SetKind setKind, Breakpoint.SetFlags setFlags, bool bindToThread = false)
 		{
 			var documentPanel = GetActiveDocumentPanel();
 
 			if (var sourceViewPanel = documentPanel as SourceViewPanel)
 			{
-			    sourceViewPanel.ToggleBreakpointAtCursor(false, bindToThread ? gApp.mDebugger.GetActiveThread() : -1);
+			    sourceViewPanel.ToggleBreakpointAtCursor(setKind, setFlags, bindToThread ? gApp.mDebugger.GetActiveThread() : -1);
 			}
 			else if (var disassemblyPanel = documentPanel as DisassemblyPanel)
 			{				
-				disassemblyPanel.ToggleBreakpointAtCursor(false, bindToThread ? gApp.mDebugger.GetActiveThread() : -1);
+				disassemblyPanel.ToggleBreakpointAtCursor(setKind, setFlags, bindToThread ? gApp.mDebugger.GetActiveThread() : -1);
 			}
 		}
 
@@ -4118,13 +4117,37 @@ namespace IDE
 		[IDECommand]
 		void ToggleBreakpoint()
 		{
-			ToggleBreakpoint(GetCurrentWindow(), false);
+			ToggleBreakpoint(GetCurrentWindow(), .Toggle, .None);
+		}
+
+		[IDECommand]
+		public void ConfigureBreakpoint()
+		{
+			if (var breakpointPanel = GetActivePanel() as BreakpointPanel)
+			{
+				breakpointPanel.ConfigureBreakpoints(breakpointPanel.mWidgetWindow);
+				return;
+			}
+
+			ToggleBreakpoint(GetCurrentWindow(), .EnsureExists, .Configure);
+		}
+
+		[IDECommand]
+		public void DisableBreakpoint()
+		{
+			if (var breakpointPanel = GetActivePanel() as BreakpointPanel)
+			{
+				breakpointPanel.SetBreakpointsDisabled(null);
+				return;
+			}
+
+			ToggleBreakpoint(GetCurrentWindow(), .MustExist, .Disable);
 		}
 
 		[IDECommand]
 		void ToggleThreadBreakpoint()
 		{
-			ToggleBreakpoint(GetCurrentWindow(), true);
+			ToggleBreakpoint(GetCurrentWindow(), .Toggle, .None, true);
 		}
 
 		void CompileCurrentFile()
@@ -4498,18 +4521,21 @@ namespace IDE
 			var tabbedView = GetActiveTabbedView();
 			if ((tabbedView == null) || (tabbedView.mTabs.IsEmpty))
 				return;
+			TabbedView.TabButton activateTab = tabbedView.mTabs[0];
 			for (var tab in tabbedView.mTabs)
 			{
 				if (tab.mIsActive)
 				{
 					if (@tab.Index < tabbedView.mTabs.Count - 1)
 					{
-						tabbedView.mTabs[@tab.Index + 1].Activate();
-						return;
+						activateTab = tabbedView.mTabs[@tab.Index + 1];
+						break;
 					}
 				}
 			}
-			tabbedView.mTabs[0].Activate();
+			activateTab.Activate();
+			if (var sourceViewPanel = activateTab.mContent as SourceViewPanel)
+				sourceViewPanel.HilitePosition(.Extra);
 		}
 
 		[IDECommand]
@@ -4518,18 +4544,21 @@ namespace IDE
 			var tabbedView = GetActiveTabbedView();
 			if ((tabbedView == null) || (tabbedView.mTabs.IsEmpty))
 				return;
+			TabbedView.TabButton activateTab = tabbedView.mTabs.Back;
 			for (var tab in tabbedView.mTabs)
 			{
 				if (tab.mIsActive)
 				{
 					if (@tab.Index > 0)
 					{
-						tabbedView.mTabs[@tab.Index - 1].Activate();
-						return;
+						activateTab = tabbedView.mTabs[@tab.Index - 1];
+						break;
 					}
 				}
 			}
-			tabbedView.mTabs.Back.Activate();
+			activateTab.Activate();
+			if (var sourceViewPanel = activateTab.mContent as SourceViewPanel)
+				sourceViewPanel.HilitePosition(.Extra);
 		}
 
 		void DoErrorTest()
@@ -4630,7 +4659,7 @@ namespace IDE
 			return (mTestManager != null);
 		}
 
-		protected void RunTests(bool debug)
+		protected void RunTests(bool includeIgnored, bool debug)
 		{
 			if (mOutputPanel != null)
 			{
@@ -4640,13 +4669,13 @@ namespace IDE
 
 			if (AreTestsRunning())
 			{
-				OutputLineSmart("ERROR: Tests already running");
+				OutputErrorLine("Tests already running");
 				return;
 			}
 
 			if ((mDebugger != null) && (mDebugger.mIsRunning))
 			{
-				OutputLineSmart("ERROR: Tests cannot be run while program is executing");
+				OutputErrorLine("Tests cannot be run while program is executing");
 				return;
 			}
 
@@ -4662,7 +4691,7 @@ namespace IDE
 			if (workspaceOptions.mBuildKind != .Test)
 			{
 				mMainFrame.mStatusBar.SelectConfig(prevConfigName);
-				OutputLineSmart("ERROR: No valid Test workspace configuration exists");
+				OutputErrorLine("No valid Test workspace configuration exists");
 				return;
 			}
 
@@ -4670,7 +4699,7 @@ namespace IDE
 			mTestManager = new TestManager();
 			mTestManager.mPrevConfigName = new String(prevConfigName);
 			mTestManager.mDebug = debug;
-			mTestManager.mIncludeIgnored = mTestIncludeIgnored;
+			mTestManager.mIncludeIgnored = includeIgnored;
 
 			if (mOutputPanel != null)
 				mOutputPanel.Clear();
@@ -4679,12 +4708,10 @@ namespace IDE
 			{
 				mTestManager.BuildFailed();
 			}
-		}
-
-		[IDECommand]
-		public void Cmd_RunAllTests()
-		{
-			RunTests(false);
+			if (!mTestManager.HasProjects)
+			{
+				OutputLineSmart("WARNING: No projects have a test configuration specified");
+			}
 		}
 
 		[IDECommand]
@@ -4694,13 +4721,6 @@ namespace IDE
 			ToggleCheck(ideCommand.mMenuItem, ref mTestEnableConsole);
 		}
 
-		[IDECommand]
-		public void Cmd_TestIncludeIgnored()
-		{
-			let ideCommand = gApp.mCommands.mCommandMap["Test Include Ignored"];
-			ToggleCheck(ideCommand.mMenuItem, ref mTestIncludeIgnored);
-		}
-
         public void CreateMenu()
         {
 			scope AutoBeefPerf("IDEApp.CreateMenu");
@@ -4946,13 +4966,14 @@ namespace IDE
 
 			var testMenu = root.AddMenuItem("&Test");
 			var testRunMenu = testMenu.AddMenuItem("&Run");
+			AddMenuItem(testRunMenu, "&Normal Tests", "Run Normal Tests");
 			AddMenuItem(testRunMenu, "&All Tests", "Run All Tests");
 
 			var testDebugMenu = testMenu.AddMenuItem("&Debug");
+			AddMenuItem(testDebugMenu, "&Normal Tests", "Debug Normal Tests");
 			AddMenuItem(testDebugMenu, "&All Tests", "Debug All Tests");
 
 			AddMenuItem(testMenu, "Enable Console", "Test Enable Console", null, null, true, mTestEnableConsole ? 1 : 0);
-			AddMenuItem(testMenu, "Include Ignored Tests", "Test Include Ignored", null, null, true, mTestIncludeIgnored ? 1 : 0);
 
 			//////////
 

+ 3 - 1
IDE/src/Settings.bf

@@ -412,8 +412,10 @@ namespace IDE
 				Add("Bookmark Toggle", "Ctrl+F2");
 				Add("Bookmark Clear", "Ctrl+K, Ctrl+L");
 				Add("Break All", "Ctrl+Alt+Break");
-				Add("Breakpoint Toggle Thread", "Ctrl+F9");
+				Add("Breakpoint Configure", "Alt+F9");
+				Add("Breakpoint Disable", "Ctrl+F9");
 				Add("Breakpoint Toggle", "F9");
+				Add("Breakpoint Toggle Thread", "Shift+F9");
 				Add("Build Solution", "F7");
 				Add("Cancel Build", "Ctrl+Break");
 				Add("Close Window", "Ctrl+W");

+ 8 - 0
IDE/src/TestManager.bf

@@ -51,6 +51,14 @@ namespace IDE
 		public bool mIncludeIgnored;
 		public bool mFailed;
 
+		public bool HasProjects
+		{
+			get
+			{
+				return !mProjectInfos.IsEmpty;
+			}
+		}
+
 		public ~this()
 		{
 			if (mTestInstance != null)

+ 2 - 2
IDE/src/Workspace.bf

@@ -805,10 +805,10 @@ namespace IDE
                 Config config = new Config();
 				//let configName = new String(data.Keys[configIdx]);
 				let configName = new String(configNameKey);
-				bool isDebug = configName.Contains("Debug");
 				bool isRelease = configName.Contains("Release");
 				bool isParanoid = configName.Contains("Paranoid");
 				bool isTest = configName.Contains("Test");
+				//bool isDebug = configName.Contains("Debug");
                 mConfigs[configName] = config;
                 
 				for (var platformNameKey in data.Enumerate())
@@ -858,7 +858,7 @@ namespace IDE
                     options.mIntermediateType = data.GetEnum<IntermediateType>("IntermediateType", .Object);
 
                     options.mCSIMDSetting = data.GetEnum<BuildOptions.SIMDSetting>("CSIMDSetting", .SSE2);
-                    options.mCOptimizationLevel = data.GetEnum<COptimizationLevel>("COptimizationLevel", isDebug ? .O0 : .O2);
+                    options.mCOptimizationLevel = data.GetEnum<COptimizationLevel>("COptimizationLevel", isRelease ? .O2 : .O0);
 
                     for (var projectName in data.Enumerate("ConfigSelections"))
                     {

+ 22 - 7
IDE/src/ui/AutoComplete.bf

@@ -195,6 +195,8 @@ namespace IDE.ui
 
 			public ~this()
 			{
+				//Debug.WriteLine("~this {} {}", this, mIsInitted);
+
 			    if (mIsInitted)
 			        Cleanup();
 			}
@@ -233,6 +235,13 @@ namespace IDE.ui
 
                 //Console.WriteLine("AutoCompleteContent Init");
 
+				//Debug.WriteLine("Init {} {} {} {}", this, mIsInitted, mOwnsWindow, mAutoComplete);
+
+				if (WidgetWindow.sOnMouseDown.Count > 0)
+				{
+					NOP!();
+				}
+
 				if (mOwnsWindow)
 				{
 	                WidgetWindow.sOnWindowLostFocus.Add(new => LostFocusHandler);
@@ -280,6 +289,8 @@ namespace IDE.ui
 
             public void Cleanup()
             {
+				//Debug.WriteLine("Cleanup {} {}", this, mIsInitted);
+
 				if (!mIsInitted)
 					return;
 
@@ -1004,6 +1015,13 @@ namespace IDE.ui
             mTargetEditWidget = targetEditWidget;
         }
 
+		public ~this()
+		{
+			//Debug.WriteLine("Autocomplete ~this {}", this);
+
+			Close(false);
+		}
+
 		static ~this()
 		{
 			for (var key in sAutoCompleteMRU.Keys)
@@ -1749,18 +1767,20 @@ namespace IDE.ui
 						mAutoCompleteListWidget.RemoveSelf();
 						delete mAutoCompleteListWidget;
 					}
-					if (mListWindow != null)
+					else if (mListWindow != null)
 					{
 						// Will get deleted later...
 						Debug.Assert(mListWindow.mRootWidget == mAutoCompleteListWidget);
 					}
+					else
+						delete mAutoCompleteListWidget;
                     mAutoCompleteListWidget = null;
                 }
             }
             if (mAutoCompleteListWidget == null)
 			{
                 mAutoCompleteListWidget = new AutoCompleteListWidget(this);
-				//Debug.WriteLine("Created mAutoCompleteListWidget {0}", mAutoCompleteListWidget);
+				//Debug.WriteLine("Created mAutoCompleteListWidget {} in {}", mAutoCompleteListWidget, this);
 			}
             
 			bool queueClearInvoke = false;
@@ -2107,11 +2127,6 @@ namespace IDE.ui
             Close();
         }
 
-        public ~this()
-        {
-            Close(false);
-        }
-
         public bool IsInsertEmpty()
         {
             return mInsertStartIdx == mInsertEndIdx;

+ 1 - 1
IDE/src/ui/BinaryDataWidget.bf

@@ -2400,7 +2400,7 @@ namespace IDE.ui
 			SetFocus();
 
 			var sel = GetSelectionForCursor(mSelection, false);
-			LocatorAnim.Show(this, sel.mBinRect.Left, sel.mBinRect.Top + sel.mBinRect.mHeight / 2);
+			LocatorAnim.Show(.Always, this, sel.mBinRect.Left, sel.mBinRect.Top + sel.mBinRect.mHeight / 2);
 			delete sel;
         }
 

+ 10 - 11
IDE/src/ui/BreakpointPanel.bf

@@ -177,18 +177,17 @@ namespace IDE.ui
 			gApp.MarkDirty();
 		}
 
-		public void SetBreakpointDisabled(bool disabled)
+		public void SetBreakpointsDisabled(bool? disabled)
 		{
 			mListView.GetRoot().WithSelectedItems(scope (item) =>
 				{
 					var listViewItem = (BreakpointListViewItem)item;
 					if (listViewItem.Selected)
 					{
-						gApp.mDebugger.SetBreakpointDisabled(listViewItem.mBreakpoint, disabled);
-						if (!disabled)
-						{
-
-						}	
+						bool wantDisabled = !listViewItem.mBreakpoint.mDisabled;
+						if (disabled.HasValue)
+							wantDisabled = disabled.Value;
+						gApp.mDebugger.SetBreakpointDisabled(listViewItem.mBreakpoint, wantDisabled);
 						BreakpointsChanged();
 						gApp.MarkDirty();
 					}
@@ -225,7 +224,7 @@ namespace IDE.ui
 			gApp.MarkDirty();
 		}
 
-		public void ConfigureBreakpoints(Widget relWidget)
+		public void ConfigureBreakpoints(WidgetWindow widgetWindow)
 		{
 			mListView.GetRoot().WithSelectedItems(scope (item) =>
 				{
@@ -235,7 +234,7 @@ namespace IDE.ui
 						mDeselectOnFocusLost = false;
 						ConditionDialog dialog = new ConditionDialog();
 						dialog.Init(listViewItem.mBreakpoint);
-						dialog.PopupWindow(relWidget.mWidgetWindow);
+						dialog.PopupWindow(widgetWindow);
 						mDeselectOnFocusLost = true;
 					}
 				});
@@ -285,7 +284,7 @@ namespace IDE.ui
 				menuItem = menu.AddItem("Configure Breakpoint");
 				menuItem.mOnMenuItemSelected.Add(new (evt) => 
 					{
-						ConfigureBreakpoints(relWidget);
+						ConfigureBreakpoints(relWidget.mWidgetWindow);
 					});
 				menuItem = menu.AddItem("Delete Breakpoint");
 				menuItem.mOnMenuItemSelected.Add(new (evt) => 
@@ -295,12 +294,12 @@ namespace IDE.ui
 				if (selectedEnabledBreakpoint)
 				{
 					menuItem = menu.AddItem("Disable Breakpoint");
-					menuItem.mOnMenuItemSelected.Add(new (evt) => { SetBreakpointDisabled(true); });
+					menuItem.mOnMenuItemSelected.Add(new (evt) => { SetBreakpointsDisabled(true); });
 				}
 				if (selectedDisabledBreakpoint)
 				{
 					menuItem = menu.AddItem("Enable Breakpoint");
-					menuItem.mOnMenuItemSelected.Add(new (evt) => { SetBreakpointDisabled(false); });
+					menuItem.mOnMenuItemSelected.Add(new (evt) => { SetBreakpointsDisabled(false); });
 				}
 				if (gApp.mDebugger.IsPaused())
 				{

+ 8 - 5
IDE/src/ui/DisassemblyPanel.bf

@@ -938,7 +938,7 @@ namespace IDE.ui
         }*/
 
 		// This is useful for a one-shot breakpoint within the current execution context- IE: "Run to cursor"
-        public Breakpoint ToggleAddrBreakpointAtCursor(bool forceSet, int threadId = -1)
+        public Breakpoint ToggleAddrBreakpointAtCursor(Breakpoint.SetKind setKind = .Toggle, Breakpoint.SetFlags flags = .None, int threadId = -1)
         {
             DebugManager debugManager = IDEApp.sApp.mDebugger;
 
@@ -953,7 +953,7 @@ namespace IDE.ui
                 return null;
 
             bool hadBreakpoint = false;
-			if (!forceSet)
+			if (setKind != .Force)
 			{
 	            for (int32 breakIdx = 0; breakIdx < IDEApp.sApp.mDebugger.mBreakpointList.Count; breakIdx++)
 	            {
@@ -988,7 +988,7 @@ namespace IDE.ui
 			return null;
         }
 
-        public Breakpoint ToggleBreakpointAtCursor(bool forceSet = false, int threadId = -1)
+        public Breakpoint ToggleBreakpointAtCursor(Breakpoint.SetKind setKind = .Toggle, Breakpoint.SetFlags flags = .None, int threadId = -1)
         {         
             DebugManager debugManager = IDEApp.sApp.mDebugger;
 
@@ -1005,7 +1005,7 @@ namespace IDE.ui
             {
                 if (checkIdx < 0)
                 {
-                    return ToggleAddrBreakpointAtCursor(forceSet);
+                    return ToggleAddrBreakpointAtCursor(setKind, flags, threadId);
                 }
                 lineData = mLineDatas[checkIdx];
                 if (lineData.mSourceFile != null)
@@ -1038,7 +1038,7 @@ namespace IDE.ui
 				instrOffsetCount = -1;*/
 
             bool hadBreakpoint = false;
-			if (!forceSet)
+			if (setKind != .Force)
 			{
 	            for (int32 breakIdx = 0; breakIdx < IDEApp.sApp.mDebugger.mBreakpointList.Count; breakIdx++)
 	            {
@@ -1246,6 +1246,9 @@ namespace IDE.ui
                         {
                             debugExpr = scope:: String();
                             content.ExtractString(leftIdx, rightIdx - leftIdx + 1, debugExpr);
+							int commaPos = debugExpr.LastIndexOf(',');
+							if (commaPos != -1)
+ 								debugExpr.RemoveToEnd(commaPos);
 
                             int32 semiPos = (int32)debugExpr.IndexOf(';');
                             if (semiPos != -1)

+ 24 - 3
IDE/src/ui/LocatorAnim.bf

@@ -13,29 +13,48 @@ namespace IDE.ui
     {
         None,
         Smart,
-        Always
+        Always,
+		Extra
     }
 
     public class LocatorAnim : Widget
     {
+		LocatorType mType;
         float mPct;
 
+		public this()
+		{
+
+		}
+
         public override void Draw(Graphics g)
         {
             base.Draw(g);
 
+			bool isExtra = mType == .Extra;
+
             int32 circleCount = 2;
             for (int32 i = 0; i < circleCount; i++)
             {
                 float sepPct = 0.3f;
                 float maxSep = (circleCount - 2) * sepPct;
                 float pct = (mPct - maxSep + (i * 0.3f)) / (1.0f - maxSep);
+
+				if (isExtra)
+					pct *= 1.2f;
+
                 if ((pct < 0.0f) || (pct > 1.0f))
                     continue;
 
                 float scale = (float)Math.Sin(pct * Math.PI_f / 2) * 0.5f;
                 float alpha = Math.Min(0.3f, (1.0f - (float)Math.Sin(pct * Math.PI_f / 2)) * 1.0f);
 
+				if (isExtra)
+				{
+					scale *= 1.2f;
+					alpha *= 1.2f;
+				}
+
                 using (g.PushColor(Color.Get(alpha)))
                 {
                     using (g.PushScale(scale, scale, GS!(32), GS!(32)))
@@ -48,7 +67,8 @@ namespace IDE.ui
         {
             base.Update();
 
-            mPct += 0.03f;
+            mPct += (mType == .Extra) ? 0.02f : 0.03f;
+
             if (mPct >= 1.0f)
 			{
                 RemoveSelf();
@@ -59,7 +79,7 @@ namespace IDE.ui
 			MarkDirty();
         }
 
-        public static void Show(Widget refWidget, float x, float y)
+        public static void Show(LocatorType locatorType, Widget refWidget, float x, float y)
         {
 			if (!gApp.mSettings.mEditorSettings.mShowLocatorAnim)
 				return;
@@ -68,6 +88,7 @@ namespace IDE.ui
 			float yOfs = GS!(-32.0f);
 
             LocatorAnim anim = new LocatorAnim();
+			anim.mType = locatorType;
             anim.mX = x + xOfs;
             anim.mY = y + yOfs;
             refWidget.AddWidget(anim);            

+ 0 - 53
IDE/src/ui/SourceEditWidgetContent.bf

@@ -2799,61 +2799,8 @@ namespace IDE.ui
             if ((keyCode == KeyCode.Escape) && (mSelection != null) && (mSelection.Value.HasSelection))
             {
                 mSelection = null;
-                //return;
             }
 
-            /*if (keyCode == KeyCode.F2)
-            {
-                int wantCount = 10;
-                if (mWidgetWindow.IsKeyDown(KeyCode.Shift))
-                    wantCount = 100;
-                for (int i = 0; i < wantCount; i++)
-                    mPanel.DoClassify(true, false, true);
-            }
-
-            if ((mPanel.mUseDebugKeyboard) && (keyCode == KeyCode.Menu))
-            {
-                if (mPanel.mClassifyPaused)
-                    mPanel.mClassifyPaused = false;
-                else
-                    mPanel.Classify(true, false, true);
-                return;
-            }*/
-
-            /*if ((keyCode == KeyCode.Left) && (mWidgetWindow.IsKeyDown(KeyCode.Alt)))
-            {
-                if (!IsAtCurrentHistory())
-                    IDEApp.sApp.mHistoryManager.GoToCurrentHistory();
-                else
-                    IDEApp.sApp.mHistoryManager.PrevHistory();
-                return;
-            }
-
-            if ((keyCode == KeyCode.Right) && (mWidgetWindow.IsKeyDown(KeyCode.Alt)))
-            {                
-                IDEApp.sApp.mHistoryManager.NextHistory();
-                return;
-            }*/
-
-			if (((keyCode == KeyCode.Up) || (keyCode == KeyCode.Down) || (keyCode == KeyCode.Left) || (keyCode == KeyCode.Right)) &&
-				(mWidgetWindow.IsKeyDown(KeyCode.Control) && ((mWidgetWindow.IsKeyDown(KeyCode.Alt)))))
-			{
-				// Fast cursor!
-				/*if (mFastCursorState == null)
-				{
-					mFastCursorState = new FastCursorState();
-
-					float x;
-					float y;
-					GetTextCoordAtCursor(out x, out y);
-
-					mFastCursorState.mX = x;
-					mFastCursorState.mY = y;
-				}*/
-
-				return;
-			}
-
             if (((keyCode == KeyCode.Up) || (keyCode == KeyCode.Down) || (keyCode == KeyCode.PageUp) || (keyCode == KeyCode.PageDown)) &&
                 (mWidgetWindow.IsKeyDown(KeyCode.Control)))
             {

+ 87 - 46
IDE/src/ui/SourceViewPanel.bf

@@ -2039,7 +2039,7 @@ namespace IDE.ui
             return Path.Equals(fileName, mFilePath);
         }
 
-        void HilitePosition(LocatorType hilitePosition, int32 prevLine = -1)
+        public void HilitePosition(LocatorType hilitePosition, int32 prevLine = -1)
         {
             if (hilitePosition == LocatorType.None)
                 return;
@@ -2057,7 +2057,7 @@ namespace IDE.ui
 
             var sourceEditWidgetContent = (SourceEditWidgetContent)mEditWidget.Content;
 
-            LocatorAnim.Show(mEditWidget.Content, x, y + sourceEditWidgetContent.mFont.GetLineSpacing() / 2);
+            LocatorAnim.Show(hilitePosition, mEditWidget.Content, x, y + sourceEditWidgetContent.mFont.GetLineSpacing() / 2);
         }
 
         public void ShowFileLocation(int cursorIdx, LocatorType hilitePosition)
@@ -3657,11 +3657,11 @@ namespace IDE.ui
 			return drawLineNum;
 		}
 
-        public Breakpoint ToggleBreakpointAtCursor(bool forceSet = false, int threadId = -1)
+        public Breakpoint ToggleBreakpointAtCursor(Breakpoint.SetKind setKind = .Toggle, Breakpoint.SetFlags flags = .None, int threadId = -1)
         {
 			var activePanel = GetActivePanel();
 			if (activePanel != this)
-				return activePanel.ToggleBreakpointAtCursor(forceSet, threadId);
+				return activePanel.ToggleBreakpointAtCursor(setKind, flags, threadId);
 
             if (mOldVersionPanel != null)
             {                
@@ -3674,8 +3674,16 @@ namespace IDE.ui
             int lineCharIdx;
             mEditWidget.Content.GetLineCharAtIdx(mEditWidget.Content.CursorTextPos, out lineIdx, out lineCharIdx);
 
+			/*let lineAndCol = mEditWidget.Content.CursorLineAndColumn;
+			if (SelectBreakpointsAtLine(lineAndCol.mLine))
+			{
+				gApp.mBreakpointPanel.ConfigureBreakpoints(mWidgetWindow);
+			}*/
+
+			HashSet<Breakpoint> breakpoints = scope .();
+
             bool hadBreakpoint = false;
-			if (!forceSet)
+			if (setKind != .Force)
 			{
 	            /*WithTrackedElementsAtCursor<Breakpoint>(IDEApp.sApp.mDebugger.mBreakpointList, scope [&] (breakpoint) =>
 	                {
@@ -3692,15 +3700,21 @@ namespace IDE.ui
 						int drawLineNum = GetDrawLineNum(breakpoint);
 						if (drawLineNum == lineIdx)
 						{
-							BfLog.LogDbg("SourceViewPanel.ToggleBreakpointAtCursor deleting breakpoint\n");
-							debugManager.DeleteBreakpoint(breakpoint);
 							hadBreakpoint = true;
+							if (setKind == .Toggle)
+							{
+								BfLog.LogDbg("SourceViewPanel.ToggleBreakpointAtCursor deleting breakpoint\n");
+								debugManager.DeleteBreakpoint(breakpoint);
+							}
+							else
+								breakpoints.Add(breakpoint);
 						}
 					}
 				}
 			}
-                
-            if (!hadBreakpoint)
+
+			Breakpoint newBreakpoint = null;
+            if ((!hadBreakpoint) && (setKind != .MustExist))
             {
 				RecordHistoryLocation();
 
@@ -3721,12 +3735,12 @@ namespace IDE.ui
 				if (gApp.mDebugger.mIsRunning)
                 	foundPosition = RemapActiveToCompiledLine(curCompileIdx, ref lineIdx, ref lineCharIdx);
 				bool createNow = foundPosition || !mIsBeefSource; // Only be strict about Beef source
-                Breakpoint newBreakpoint = debugManager.CreateBreakpoint_Create(mAliasFilePath ?? mFilePath, lineIdx, lineCharIdx, -1);
+                newBreakpoint = debugManager.CreateBreakpoint_Create(mAliasFilePath ?? mFilePath, lineIdx, lineCharIdx, -1);
 				newBreakpoint.mThreadId = threadId;
 				debugManager.CreateBreakpoint_Finish(newBreakpoint, createNow);
                 int newDrawLineNum = GetDrawLineNum(newBreakpoint);
 
-                if (!forceSet)
+                if (setKind != .Force)
 				{
 	                for (int32 breakIdx = 0; breakIdx < IDEApp.sApp.mDebugger.mBreakpointList.Count; breakIdx++)
 	                {
@@ -3743,7 +3757,9 @@ namespace IDE.ui
 		                        debugManager.DeleteBreakpoint(newBreakpoint);
 								newBreakpoint = null;
 								var ewc = mEditWidget.mEditWidgetContent;
-								LocatorAnim.Show(mEditWidget, ewc.mX + -GS!(15), ewc.mY + newDrawLineNum * ewc.GetLineHeight(0) + GS!(12));
+								LocatorAnim.Show(.Always, mEditWidget, ewc.mX + -GS!(15), ewc.mY + newDrawLineNum * ewc.GetLineHeight(0) + GS!(12));
+
+								breakpoints.Add(checkBreakpoint);
 								break;
 							}
 	                    }
@@ -3778,10 +3794,22 @@ namespace IDE.ui
 					}
 				}
 
-				return newBreakpoint;
+				if (newBreakpoint != null)
+					breakpoints.Add(newBreakpoint);
             }
 
-			return null;
+			if (((flags.HasFlag(.Configure)) || (flags.HasFlag(.Disable))) &&
+				(!breakpoints.IsEmpty))
+			{
+				gApp.mBreakpointPanel.Update();
+				gApp.mBreakpointPanel.SelectBreakpoints(breakpoints);
+				if (flags.HasFlag(.Configure))
+					gApp.mBreakpointPanel.ConfigureBreakpoints(mWidgetWindow);
+				if (flags.HasFlag(.Disable))
+					gApp.mBreakpointPanel.SetBreakpointsDisabled(null);
+			}
+
+			return newBreakpoint;
         }
 
         public void ToggleBookmarkAtCursor()
@@ -4481,9 +4509,7 @@ namespace IDE.ui
 			if ((mousePos.x < editX - 24) || (mousePos.x > editX - 5))
 				return false;
 
-			DarkEditWidgetContent darkEditWidgetContent = (DarkEditWidgetContent)mEditWidget.Content;
-			float lineSpacing = darkEditWidgetContent.mFont.GetLineSpacing();
-			float ofsY = mEditWidget.mY + darkEditWidgetContent.mY + (lineSpacing - DarkTheme.sUnitSize + GS!(5)) / 2;
+			int mouseLine = GetLineAt(mousePos.x, mousePos.y);
 
 			for (var breakpointView in GetTrackedElementList())
 			{
@@ -4500,8 +4526,7 @@ namespace IDE.ui
 						breakpointLineNum = breakpoint.mLineNum;
 					int drawLineNum = breakpointLineNum;
 
-					float iconY = ofsY + drawLineNum * lineSpacing;
-					if ((mousePos.y > iconY) && (mousePos.y < iconY + GS!(20)))
+					if (drawLineNum == mouseLine)
 					{
 						if (!tooltipStr.IsEmpty)
 							tooltipStr.Append("\n\n");
@@ -6080,44 +6105,60 @@ namespace IDE.ui
 			}
 		}
 
-		public override void MouseClicked(float x, float y, int32 btn)
+		public int GetLineAt(float x, float y)
 		{
-			base.MouseClicked(x, y, btn);
+			if (x > GS!(40))
+				return -1;
 
-			if (btn == 1)
-			{
-				DarkEditWidgetContent darkEditWidgetContent = (DarkEditWidgetContent)mEditWidget.Content;
-				float lineSpacing = darkEditWidgetContent.mFont.GetLineSpacing();
+			DarkEditWidgetContent darkEditWidgetContent = (DarkEditWidgetContent)mEditWidget.Content;
+			float lineSpacing = darkEditWidgetContent.mFont.GetLineSpacing();
+			float relY = y - mEditWidget.mY - mEditWidget.Content.Y - GS!(3);
+			if (relY < 0)
+				return -1;
+			return (int)(relY / lineSpacing);
+		}
+
+		public bool SelectBreakpointsAtLine(int selectLine)
+		{
+			if (selectLine == -1)
+				return false;
 
-				HashSet<Breakpoint> selectedBreakpoints = scope HashSet<Breakpoint>();
+			HashSet<Breakpoint> selectedBreakpoints = scope HashSet<Breakpoint>();
 
-				for (var breakpointView in GetTrackedElementList())
-				{
-				    var trackedElement = breakpointView.mTrackedElement;
-				    var breakpoint = trackedElement as Breakpoint;
-				    if (breakpoint != null)
-				    {
-						int drawLineNum = RemapActiveLineToHotLine(breakpoint.mLineNum);
-						//float breakX = mEditWidget.mX - 20;
-						float breakY = GS!(3) + drawLineNum * lineSpacing + mEditWidget.mY + mEditWidget.Content.Y;
-
-						if ((x <= GS!(40)) && (y >= breakY) && (y < breakY + lineSpacing + GS!(1)))
-						{
-							selectedBreakpoints.Add(breakpoint);
-						}
+			for (var breakpointView in GetTrackedElementList())
+			{
+			    var trackedElement = breakpointView.mTrackedElement;
+			    var breakpoint = trackedElement as Breakpoint;
+			    if (breakpoint != null)
+			    {
+					int drawLineNum = RemapActiveLineToHotLine(breakpoint.mLineNum);
+					if (selectLine == drawLineNum)
+					{
+						selectedBreakpoints.Add(breakpoint);
 					}
 				}
+			}
 
-				if (selectedBreakpoints.Count > 0)
+			if (selectedBreakpoints.IsEmpty)
+				return false;
+			
+			gApp.mBreakpointPanel.Update();
+			gApp.mBreakpointPanel.SelectBreakpoints(selectedBreakpoints);
+			return true;
+		}
+
+		public override void MouseClicked(float x, float y, int32 btn)
+		{
+			base.MouseClicked(x, y, btn);
+
+			if (btn == 1)
+			{
+				int lineClick = GetLineAt(x, y);
+				if (SelectBreakpointsAtLine(lineClick))
 				{
-					gApp.mBreakpointPanel.Update();
-					gApp.mBreakpointPanel.SelectBreakpoints(selectedBreakpoints);
 #unwarn
 					var menuWidget = gApp.mBreakpointPanel.ShowRightClickMenu(this, x, y, true);
-					//menuWidget.mDeletedHandler.Add(new (widget) => { gApp.mBreakpointPanel.mListView.GetRoot().SelectItemExclusively(null); });
 				}
-
-				//float checkY = y + mEditWidget.mScrollContentContainer.m;
 			}
 		}