diff --git a/IDE/src/Commands.bf b/IDE/src/Commands.bf index f0b2de76..c7eeb2cf 100644 --- a/IDE/src/Commands.bf +++ b/IDE/src/Commands.bf @@ -194,6 +194,8 @@ namespace IDE Add("Close Document", new () => { gApp.[Friend]TryCloseCurrentDocument(); }); Add("Close Panel", new () => { gApp.[Friend]TryCloseCurrentPanel(); }); Add("Close Workspace", new => gApp.[Friend]Cmd_CloseWorkspaceAndSetupNew); + Add("Comment Block", new => gApp.[Friend]CommentBlock); + Add("Comment Lines", new => gApp.[Friend]CommentLines); Add("Comment Selection", new => gApp.[Friend]CommentSelection); Add("Compile File", new => gApp.Cmd_CompileFile); Add("Debug All Tests", new () => { gApp.[Friend]RunTests(true, true); }); diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index dc719197..0c695e54 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -2429,6 +2429,22 @@ namespace IDE sewc.DuplicateLine(); } + [IDECommand] + void CommentBlock() + { + var sewc = GetActiveSourceEditWidgetContent(); + if (sewc != null) + sewc.CommentBlock(); + } + + [IDECommand] + void CommentLines() + { + var sewc = GetActiveSourceEditWidgetContent(); + if (sewc != null) + sewc.CommentLines(); + } + [IDECommand] void CommentSelection() { @@ -5391,6 +5407,8 @@ namespace IDE advancedEditMenu.AddMenuItem(null); AddMenuItem(advancedEditMenu, "Make Uppercase", "Make Uppercase"); AddMenuItem(advancedEditMenu, "Make Lowercase", "Make Lowercase"); + AddMenuItem(advancedEditMenu, "Comment Block", "Comment Block"); + AddMenuItem(advancedEditMenu, "Comment Lines", "Comment Lines"); AddMenuItem(advancedEditMenu, "Comment Selection", "Comment Selection"); AddMenuItem(advancedEditMenu, "Uncomment Selection", "Uncomment Selection"); AddMenuItem(advancedEditMenu, "Reformat Document", "Reformat Document"); diff --git a/IDE/src/Settings.bf b/IDE/src/Settings.bf index 6065643e..f3a2ca1d 100644 --- a/IDE/src/Settings.bf +++ b/IDE/src/Settings.bf @@ -753,6 +753,8 @@ namespace IDE Add("Cancel Build", "Ctrl+Break"); Add("Close Document", "Ctrl+W"); Add("Compile File", "Ctrl+F7"); + Add("Comment Block", "Ctrl+K, Ctrl+B"); + Add("Comment Lines", "Ctrl+K, Ctrl+L"); Add("Comment Selection", "Ctrl+K, Ctrl+C"); Add("Duplicate Line", "Ctrl+D"); Add("Find Class", "Alt+Shift+L"); diff --git a/IDE/src/ui/SettingsDialog.bf b/IDE/src/ui/SettingsDialog.bf index 38cf60b3..ca52440c 100644 --- a/IDE/src/ui/SettingsDialog.bf +++ b/IDE/src/ui/SettingsDialog.bf @@ -126,7 +126,7 @@ namespace IDE.ui AddPropertiesItem(category, "Enable File Recovery", "mEnableFileRecovery"); AddPropertiesItem(category, "Format on Save", "mFormatOnSave"); AddPropertiesItem(category, "Sync with Workspace Panel", "mSyncWithWorkspacePanel"); - + category.Open(true, true); } diff --git a/IDE/src/ui/SourceEditWidgetContent.bf b/IDE/src/ui/SourceEditWidgetContent.bf index 1a91924f..755484b5 100644 --- a/IDE/src/ui/SourceEditWidgetContent.bf +++ b/IDE/src/ui/SourceEditWidgetContent.bf @@ -2160,8 +2160,10 @@ namespace IDE.ui return true; } - public bool ToggleComment(bool? doComment = null) + public bool CommentBlock() { + bool? doComment = true; + if (CheckReadOnly()) return false; @@ -2173,11 +2175,11 @@ namespace IDE.ui mSelection = .(CursorTextPos, cursorEndPos); } - if ((HasSelection()) && (mSelection.Value.Length > 1)) - { + if ((HasSelection()) && (mSelection.Value.Length > 1)) + { var startLineAndCol = CursorLineAndColumn; - UndoBatchStart undoBatchStart = new UndoBatchStart("embeddedToggleComment"); + UndoBatchStart undoBatchStart = new UndoBatchStart("embeddedCommentBlock"); mData.mUndoManager.Add(undoBatchStart); mData.mUndoManager.Add(new SetCursorAction(this)); @@ -2200,20 +2202,7 @@ namespace IDE.ui int firstCharPos = minPos + (startLen - afterTrimStart); int lastCharPos = maxPos - (afterTrimStart - afterTrimEnd); - if ((doComment != true) && (trimmedStr.StartsWith("/*"))) - { - if (trimmedStr.EndsWith("*/")) - { - mSelection = EditSelection(firstCharPos, firstCharPos + 2); - DeleteChar(); - mSelection = EditSelection(lastCharPos - 4, lastCharPos - 2); - DeleteChar(); - - if (doComment != null) - mSelection = EditSelection(firstCharPos, lastCharPos - 4); - } - } - else if (doComment != false) + if (doComment != false) { CursorTextPos = firstCharPos; InsertAtCursor("/*"); @@ -2232,8 +2221,244 @@ namespace IDE.ui if (doComment == null) mSelection = null; - return true; - } + return true; + } + + return false; + } + + public bool CommentLines() + { + bool? doComment = true; + if (CheckReadOnly()) + return false; + bool noStar = false; + + var startLineAndCol = CursorLineAndColumn; + if ((!HasSelection()) && (doComment != null)) + { + CursorToLineEnd(); + int cursorEndPos = CursorTextPos; + + mSelection = .(CursorTextPos, cursorEndPos); + noStar = true; + } + + if (true || (HasSelection()) && (mSelection.Value.Length > 0)) + { + // set selection to begin from line start + int lineIdx; + int lineChar; + GetLineCharAtIdx(mSelection.GetValueOrDefault().MinPos,out lineIdx, out lineChar); + MoveCursorTo(lineIdx, 0); + mSelection = .(CursorTextPos, mSelection.GetValueOrDefault().MaxPos); + + UndoBatchStart undoBatchStart = new UndoBatchStart("embeddedCommentLines"); + mData.mUndoManager.Add(undoBatchStart); + + mData.mUndoManager.Add(new SetCursorAction(this)); + + int minPos = mSelection.GetValueOrDefault().MinPos; + int maxPos = mSelection.GetValueOrDefault().MaxPos; + mSelection = null; + + var str = scope String(); + ExtractString(minPos, maxPos - minPos, str); + var trimmedStr = scope String(); + trimmedStr.Append(str); + int32 startLen = (int32)trimmedStr.Length; + trimmedStr.TrimStart(); + int32 afterTrimStart = (int32)trimmedStr.Length; + trimmedStr.TrimEnd(); + //int32 afterTrimEnd = (int32)trimmedStr.Length; + trimmedStr.Append('\n'); + + int firstCharPos = minPos + (startLen - afterTrimStart); + //int lastCharPos = maxPos - (afterTrimStart - afterTrimEnd); + + int q = 0; + + if (doComment != false) + { + while (firstCharPos >= 0 && SafeGetChar(firstCharPos) != '\n') + { + firstCharPos--; + } + bool blank=true; + for (int i = firstCharPos + 1; i < maxPos + q; i++) + { + blank=false; + CursorTextPos = i; // needed to add i < maxPos + q; for this to work with InsertAtCursor + InsertAtCursor("//"); q++; q++; + + while (SafeGetChar(i) != '\n' && i < maxPos + q) + { + i++; + } + } + mSelection = EditSelection(minPos, maxPos + q); + } + + if (undoBatchStart != null) + mData.mUndoManager.Add(undoBatchStart.mBatchEnd); + + CursorLineAndColumn = startLineAndCol; + + if (doComment == null) + mSelection = null; + + return true; + } + + //return false; + } + + public bool ToggleComment(bool? doComment = null) + { + if (CheckReadOnly()) + return false; + bool noStar = false; + + var startLineAndCol = CursorLineAndColumn; + if ((!HasSelection()) && (doComment != null)) + { + CursorToLineEnd(); + int cursorEndPos = CursorTextPos; + CursorToLineStart(false); + mSelection = .(CursorTextPos, cursorEndPos); + noStar = true; + } + + if ((HasSelection()) && (mSelection.Value.Length > 0)) + { + int lineIdx; + int lineChar; + GetLineCharAtIdx(mSelection.GetValueOrDefault().MinPos, out lineIdx, out lineChar); + MoveCursorTo(lineIdx, 0); + mSelection = .(CursorTextPos, mSelection.GetValueOrDefault().MaxPos); + + + UndoBatchStart undoBatchStart = new UndoBatchStart("embeddedToggleComment"); + mData.mUndoManager.Add(undoBatchStart); + + mData.mUndoManager.Add(new SetCursorAction(this)); + + int minPos = mSelection.GetValueOrDefault().MinPos; + int maxPos = mSelection.GetValueOrDefault().MaxPos; + mSelection = null; + + var str = scope String(); + ExtractString(minPos, maxPos - minPos, str); + var trimmedStr = scope String(); + trimmedStr.Append(str); + int32 startLen = (int32)trimmedStr.Length; + trimmedStr.TrimStart(); + int32 afterTrimStart = (int32)trimmedStr.Length; + trimmedStr.TrimEnd(); + int32 afterTrimEnd = (int32)trimmedStr.Length; + trimmedStr.Append('\n'); + + int firstCharPos = minPos + (startLen - afterTrimStart); + int lastCharPos = maxPos - (afterTrimStart - afterTrimEnd); + + int q = 0; + var nc = trimmedStr.Count('\n'); + + if(afterTrimEnd == 0) + { + if (undoBatchStart != null) + mData.mUndoManager.Add(undoBatchStart.mBatchEnd); + + CursorLineAndColumn = startLineAndCol; + + if (doComment == null) + mSelection = null; + + return false; // not sure if this should be false in blank/only whitespace selection case + } + else if ((doComment != true) && (trimmedStr.StartsWith("//"))) + { + for (int i = firstCharPos; i <= lastCharPos; i++) + { + if ((minPos == 0 && i == 0) || (minPos>=0 && SafeGetChar(i - 1) == '\n' || SafeGetChar(i - 1) == '\t')) + if (SafeGetChar(i - 0) == '/' && SafeGetChar(i + 1) == '/') + { + mSelection = EditSelection(i - 0, i + 2); + DeleteSelection(); + lastCharPos -= 2; + while (i < maxPos && SafeGetChar(i) != '\n') + { + i++; + } + } + } + + CursorToLineEnd(); + int cursorEndPos = CursorTextPos; + mSelection = .(minPos, cursorEndPos); + + } + else if ((doComment != true) && (trimmedStr.StartsWith("/*"))) + { + if (trimmedStr.EndsWith("*/\n")) + { + mSelection = EditSelection(firstCharPos, firstCharPos + 2); + DeleteChar(); + mSelection = EditSelection(lastCharPos - 4, lastCharPos - 2); + DeleteChar(); + + if (doComment != null) + mSelection = EditSelection(firstCharPos, lastCharPos - 4); + } + } + else if (doComment != false && minPos >=0 && ((nc <= 1 && (SafeGetChar(minPos-1) != ' ' && SafeGetChar(minPos-1) != '\t') && SafeGetChar(minPos-1) != '\n') + || nc >= 1 && (SafeGetChar(maxPos-1) != ' ' && SafeGetChar(maxPos-1) != '\t') && SafeGetChar(maxPos-1) != '\n')) + { //if selection is from beginning of the line then we want to use // comment, that's why the check for line count and ' ' and tab + CursorTextPos = firstCharPos; + if (noStar) { + CursorTextPos = minPos; + + InsertAtCursor("//"); //goes here if no selection + } + else + { + InsertAtCursor("/*"); + CursorTextPos = lastCharPos + 2; + InsertAtCursor("*/"); + } + if (!noStar && doComment != null) + mSelection = EditSelection(firstCharPos, lastCharPos + 4); + } + else if (doComment != false) + { + while (firstCharPos >= 0 && SafeGetChar(firstCharPos) != '\n') + { + firstCharPos--; + } + + for (int i = firstCharPos + 1; i < maxPos + q; i++) + { + CursorTextPos = i; // needed to add i < maxPos + q; for this to work with InsertAtCursor + InsertAtCursor("//"); q++; q++; + + while (SafeGetChar(i) != '\n' && i < maxPos + q) + { + i++; + } + } + mSelection = EditSelection(minPos, maxPos + q); + } + + if (undoBatchStart != null) + mData.mUndoManager.Add(undoBatchStart.mBatchEnd); + + CursorLineAndColumn = startLineAndCol; + + if (doComment == null) + mSelection = null; + + return true; + } return false; }