1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-23 01:58:00 +02:00

Merge branch 'master' into FuzzyAutoComplete

This commit is contained in:
Brian Fiete 2021-12-28 17:07:19 +01:00 committed by GitHub
commit 62c3998521
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
64 changed files with 2485 additions and 598 deletions

View file

@ -1165,6 +1165,7 @@ namespace IDE.ui
}
}
public Stopwatch mStopwatch ~ delete _;
public EditWidget mTargetEditWidget;
public Event<Action> mOnAutoCompleteInserted ~ _.Dispose();
public Event<Action> mOnClosed ~ _.Dispose();

View file

@ -136,17 +136,15 @@ namespace IDE.ui
ClearAndDeleteItems(mResolveErrors);
mResolveErrors.Capacity = mResolveErrors.Count;
}
var bfl = scope:: List<BfPassInstance.BfError>();
for (int32 errorIdx = 0; errorIdx < errorCount; errorIdx++)
{
BfPassInstance.BfError bfError = new BfPassInstance.BfError();
passInstance.GetErrorData(errorIdx, bfError, true);
if (bfError.mFilePath == null)
bfError.mFilePath = new String(""); //for sort below
if (bfError.mIsWarning)
mWarningCount++;
else
mErrorCount++;
bfl.Add(bfError);
for (int32 moreInfoIdx < bfError.mMoreInfoCount)
{
BfPassInstance.BfError moreInfo = new BfPassInstance.BfError();
@ -155,12 +153,26 @@ namespace IDE.ui
bfError.mMoreInfo = new List<BfPassInstance.BfError>();
bfError.mMoreInfo.Add(moreInfo);
}
}
function int(int lhs, int rhs) ascLambda = (lhs, rhs) => lhs <=> rhs;
bfl.Sort(scope (lhs, rhs) => ascLambda(lhs.mFilePath.GetHashCode()+lhs.mSrcStart, rhs.mFilePath.GetHashCode()+rhs.mSrcStart));
for (int32 errorIdx = 0; errorIdx < bfl.Count; errorIdx++)
{
var bfError = bfl[errorIdx];
if (bfError.mIsWarning)
{
mWarningCount++;
}
else
mErrorCount++;
if (passKind == .Parse)
{
if (bfError.mFilePath == null)
bfError.mFilePath = new String("");
bool added = mParseErrors.TryAdd(bfError.mFilePath, var keyPtr, var valuePtr);
if (added)
{
@ -170,7 +182,7 @@ namespace IDE.ui
(*valuePtr).Add(bfError);
}
else
mResolveErrors.Add(bfError);
mResolveErrors.Add(bfError);
mDataId++;
}
@ -354,7 +366,7 @@ namespace IDE.ui
public override void Update()
{
base.Update();
if (!mVisible)
{
// Very dirty
@ -369,7 +381,8 @@ namespace IDE.ui
else
mDirtyTicks++;
ProcessErrors();
if(mDirtyTicks==0)
ProcessErrors();
}
public void SetNeedsResolveAll()
@ -379,7 +392,8 @@ namespace IDE.ui
public void ShowErrorNext()
{
ProcessErrors();
if(mDirtyTicks==0)
ProcessErrors();
bool foundFocused = false;
let root = mErrorLV.GetRoot();

View file

@ -139,7 +139,8 @@ namespace IDE.ui
mOutputWidget.SetText("");
for (var widgetEntry in mInlineWidgets)
{
widgetEntry.mWidget.RemoveSelf();
if (widgetEntry.mWidget.mParent != null)
widgetEntry.mWidget.RemoveSelf();
delete widgetEntry.mWidget;
}
mInlineWidgets.Clear();

View file

@ -293,6 +293,10 @@ namespace IDE.ui
}
}
struct ThreadEntry : this(int32 mThreadId, int32 mCPUUsage, StringView mName)
{
}
void PopulateThreadList(Menu menu)
{
if (mProfiler == null)
@ -307,6 +311,7 @@ namespace IDE.ui
var threadListStr = scope String();
mProfiler.GetThreadList(threadListStr);
List<ThreadEntry> entries = scope .();
for (var entry in threadListStr.Split('\n'))
{
if (entry.Length == 0)
@ -314,20 +319,35 @@ namespace IDE.ui
var dataItr = entry.Split('\t');
int32 threadId = int32.Parse(dataItr.GetNext());
StringView threadName = dataItr.GetNext();
ThreadEntry threadEntry = default;
threadEntry.mThreadId = int32.Parse(dataItr.GetNext());
threadEntry.mCPUUsage = int32.Parse(dataItr.GetNext());
threadEntry.mName = dataItr.GetNext();
entries.Add(threadEntry);
}
entries.Sort(scope (lhs, rhs) =>
{
int cmp = rhs.mCPUUsage <=> lhs.mCPUUsage;
if (cmp == 0)
cmp = lhs.mThreadId <=> rhs.mThreadId;
return cmp;
});
for (var entry in entries)
{
String threadStr = null;
var str = scope String();
str.AppendF("{0}", threadId);
if (!threadName.IsEmpty)
str.AppendF("{0}", entry.mThreadId);
str.AppendF($" ({entry.mCPUUsage}%)");
if (!entry.mName.IsEmpty)
{
threadStr = new String(threadName);
str.AppendF(" - {0}", threadName);
threadStr = new String(entry.mName);
str.AppendF($" - {entry.mName}");
}
subItem = menu.AddItem(str);
subItem.mOnMenuItemSelected.Add(new (item) => { Show(threadId, threadStr); } ~ delete threadStr);
subItem.mOnMenuItemSelected.Add(new (item) => { Show(entry.mThreadId, threadStr); } ~ delete threadStr);
}
}

View file

@ -127,7 +127,8 @@ namespace IDE.ui
AddPropertiesItem(category, "Enable File Recovery", "mEnableFileRecovery");
AddPropertiesItem(category, "Format on Save", "mFormatOnSave");
AddPropertiesItem(category, "Sync with Workspace Panel", "mSyncWithWorkspacePanel");
AddPropertiesItem(category, "Wrap Comments at Column", "mWrapCommentsAt");
category.Open(true, true);
}

View file

@ -2160,11 +2160,18 @@ namespace IDE.ui
return true;
}
public bool ToggleComment(bool? doComment = null)
public bool CommentBlock()
{
bool? doComment = true;
if (CheckReadOnly())
return false;
var startLineAndCol = CursorLineAndColumn;
int startTextPos = CursorTextPos;
var prevSelection = mSelection;
bool hadSelection = HasSelection();
if ((!HasSelection()) && (doComment != null))
{
CursorToLineEnd();
@ -2173,14 +2180,15 @@ namespace IDE.ui
mSelection = .(CursorTextPos, cursorEndPos);
}
if ((HasSelection()) && (mSelection.Value.Length > 1))
{
var startLineAndCol = CursorLineAndColumn;
UndoBatchStart undoBatchStart = new UndoBatchStart("embeddedToggleComment");
if ((HasSelection()) && (mSelection.Value.Length > 1))
{
UndoBatchStart undoBatchStart = new UndoBatchStart("embeddedCommentBlock");
mData.mUndoManager.Add(undoBatchStart);
mData.mUndoManager.Add(new SetCursorAction(this));
var setCursorAction = new SetCursorAction(this);
setCursorAction.mSelection = prevSelection;
setCursorAction.mCursorTextPos = (.)startTextPos;
mData.mUndoManager.Add(setCursorAction);
int minPos = mSelection.GetValueOrDefault().MinPos;
int maxPos = mSelection.GetValueOrDefault().MaxPos;
@ -2200,20 +2208,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("/*");
@ -2227,13 +2222,320 @@ namespace IDE.ui
if (undoBatchStart != null)
mData.mUndoManager.Add(undoBatchStart.mBatchEnd);
CursorLineAndColumn = startLineAndCol;
if (startTextPos <= minPos)
CursorLineAndColumn = startLineAndCol;
else if (startTextPos < maxPos)
CursorTextPos = startTextPos + 2;
if (doComment == null)
if ((doComment == null) || (!hadSelection))
mSelection = null;
return true;
}
return true;
}
return false;
}
public bool CommentLines()
{
if (CheckReadOnly())
return false;
int startTextPos = CursorTextPos;
var prevSelection = mSelection;
bool hadSelection = HasSelection();
var startLineAndCol = CursorLineAndColumn;
if (!HasSelection())
{
CursorToLineEnd();
int cursorEndPos = CursorTextPos;
CursorToLineStart(false);
mSelection = .(CursorTextPos, cursorEndPos);
}
UndoBatchStart undoBatchStart = new UndoBatchStart("embeddedCommentLines");
mData.mUndoManager.Add(undoBatchStart);
var setCursorAction = new SetCursorAction(this);
setCursorAction.mSelection = prevSelection;
setCursorAction.mCursorTextPos = (.)startTextPos;
mData.mUndoManager.Add(setCursorAction);
int minPos = mSelection.GetValueOrDefault().MinPos;
int maxPos = mSelection.GetValueOrDefault().MaxPos;
mSelection = null;
while (minPos > 0)
{
var c = mData.mText[minPos - 1].mChar;
if (c == '\n')
break;
minPos--;
}
bool hadMaxChar = false;
int checkMaxPos = maxPos;
while (checkMaxPos > 0)
{
var c = mData.mText[checkMaxPos - 1].mChar;
if (c == '\n')
break;
if ((c != '\t') && (c != ' '))
{
hadMaxChar = true;
break;
}
checkMaxPos--;
}
if (!hadMaxChar)
{
checkMaxPos = maxPos;
while (checkMaxPos < mData.mTextLength)
{
var c = mData.mText[checkMaxPos].mChar;
if (c == '\n')
break;
if ((c != '\t') && (c != ' '))
{
maxPos = checkMaxPos + 1;
break;
}
checkMaxPos++;
}
}
int wantLineCol = -1;
int lineStartCol = 0;
bool didLineComment = false;
for (int i = minPos; i < maxPos; i++)
{
var c = mData.mText[i].mChar;
if (didLineComment)
{
if (c == '\n')
{
didLineComment = false;
lineStartCol = 0;
}
continue;
}
if (c == '\t')
lineStartCol += 4;
else if (c == ' ')
lineStartCol++;
else
{
if (wantLineCol == -1)
wantLineCol = lineStartCol;
else
wantLineCol = Math.Min(wantLineCol, lineStartCol);
didLineComment = true;
}
}
wantLineCol = Math.Max(0, wantLineCol);
didLineComment = false;
lineStartCol = 0;
for (int i = minPos; i < maxPos; i++)
{
var c = mData.mText[i].mChar;
if (didLineComment)
{
if (c == '\n')
{
didLineComment = false;
lineStartCol = 0;
}
continue;
}
bool commentNow = false;
if ((wantLineCol != -1) && (lineStartCol >= wantLineCol))
commentNow = true;
if (c == '\t')
lineStartCol += 4;
else if (c == ' ')
lineStartCol++;
else
commentNow = true;
if (commentNow)
{
CursorTextPos = i;
String str = scope .();
while (lineStartCol + 4 <= wantLineCol)
{
lineStartCol += 4;
str.Append("\t");
}
str.Append("//");
InsertAtCursor(str);
didLineComment = true;
maxPos += str.Length;
}
}
mSelection = EditSelection(minPos, maxPos);
if (undoBatchStart != null)
mData.mUndoManager.Add(undoBatchStart.mBatchEnd);
CursorLineAndColumn = startLineAndCol;
if (!hadSelection)
mSelection = null;
return true;
}
void FixSelection()
{
if (!HasSelection())
return;
if (CursorTextPos >= mSelection.Value.MaxPos)
CursorTextPos = mSelection.Value.MaxPos;
if (mSelection.Value.MaxPos - mSelection.Value.MinPos <= 1)
{
mSelection = null;
return;
}
}
public bool ToggleComment(bool? doComment = null)
{
if (CheckReadOnly())
return false;
int startTextPos = CursorTextPos;
bool doLineComment = false;
var prevSelection = mSelection;
LineAndColumn? startLineAndCol = CursorLineAndColumn;
if (!HasSelection())
{
CursorToLineEnd();
int cursorEndPos = CursorTextPos;
CursorToLineStart(false);
mSelection = .(CursorTextPos, cursorEndPos);
doLineComment = true;
}
if ((HasSelection()) && (mSelection.Value.Length > 0))
{
UndoBatchStart undoBatchStart = new UndoBatchStart("embeddedToggleComment");
mData.mUndoManager.Add(undoBatchStart);
var setCursorAction = new SetCursorAction(this);
setCursorAction.mSelection = prevSelection;
setCursorAction.mCursorTextPos = (.)startTextPos;
mData.mUndoManager.Add(setCursorAction);
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);
if (afterTrimEnd == 0)
{
if (undoBatchStart != null)
mData.mUndoManager.Add(undoBatchStart.mBatchEnd);
CursorLineAndColumn = startLineAndCol.Value;
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 (prevSelection != null)
mSelection = EditSelection(firstCharPos, lastCharPos - 4);
}
}
else if (doComment != false)
{ //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
if (doLineComment)
{
CursorTextPos = minPos;
InsertAtCursor("//"); //goes here if no selection
}
else
{
CursorTextPos = firstCharPos;
InsertAtCursor("/*");
CursorTextPos = lastCharPos + 2;
InsertAtCursor("*/");
}
mSelection = EditSelection(firstCharPos, lastCharPos + 4);
if (startTextPos <= minPos)
CursorLineAndColumn = startLineAndCol.Value;
else
CursorTextPos = startTextPos + 2;
startLineAndCol = null;
}
else
{
mSelection = prevSelection;
}
if (undoBatchStart != null)
mData.mUndoManager.Add(undoBatchStart.mBatchEnd);
if (startLineAndCol != null)
CursorLineAndColumn = startLineAndCol.Value;
if (prevSelection == null)
mSelection = null;
FixSelection();
return true;
}
return false;
}
@ -2275,6 +2577,9 @@ namespace IDE.ui
public void DuplicateLine()
{
if ((CheckReadOnly()) || (!mAllowVirtualCursor))
return;
UndoBatchStart undoBatchStart = new UndoBatchStart("duplicateLine");
mData.mUndoManager.Add(undoBatchStart);
@ -3103,7 +3408,7 @@ namespace IDE.ui
return;
}
if ((keyChar == '/') && (ToggleComment()))
if ((keyChar == '/') && (HasSelection()) && (ToggleComment()))
{
return;
}

View file

@ -160,6 +160,8 @@ namespace IDE.ui
{
public int32 mCursorPos;
public String mResult ~ delete _;
public int32? mLine;
public int32? mLineChar;
public ~this()
{
@ -621,6 +623,10 @@ namespace IDE.ui
//Classify(options.HasFlag(.HighPriority) ? ResolveType.Autocomplete_HighPri : ResolveType.Autocomplete);
ResolveParams resolveParams = new ResolveParams();
if (gApp.mDbgTimeAutocomplete)
resolveParams.mStopwatch = new .()..Start();
if (gApp.mDbgPerfAutocomplete)
resolveParams.mProfileInstance = Profiler.StartSampling("Autocomplete").GetValueOrDefault();
resolveParams.mIsUserRequested = options.HasFlag(.UserRequested);
resolveParams.mDoFuzzyAutoComplete = gApp.mSettings.mEditorSettings.mFuzzyAutoComplete;
Classify(.Autocomplete, resolveParams);
@ -1186,7 +1192,7 @@ namespace IDE.ui
//if (mCurParser != null)
{
if (gApp.mWorkspace.mProjectLoadState != .Loaded)
return false;
return true;
if (!isHi)
Debug.Assert(!mIsPerformingBackgroundClassify);
@ -2336,6 +2342,11 @@ namespace IDE.ui
if (mDisposed)
return;
if (mProjectSource?.mEditData?.HasTextChanged() == true)
{
mProjectSource.ClearEditData();
}
ProcessDeferredResolveResults(-1);
if (IDEApp.sApp.mLastActiveSourceViewPanel == this)
@ -4725,7 +4736,7 @@ namespace IDE.ui
delete parser;
}
public void UpdateMouseover(bool mouseoverFired, bool mouseInbounds, int line, int lineChar)
public void UpdateMouseover(bool mouseoverFired, bool mouseInbounds, int line, int lineChar, bool isManual = false)
{
@ -5011,6 +5022,11 @@ namespace IDE.ui
mHoverResolveTask = new HoverResolveTask();
mHoverResolveTask.mCursorPos = (int32)textIdx;
if (isManual)
{
mHoverResolveTask.mLine = (.)line;
mHoverResolveTask.mLineChar = (.)lineChar;
}
}
}
@ -5204,6 +5220,16 @@ namespace IDE.ui
#if IDE_C_SUPPORT
hasClangHoverErrorData = mClangHoverErrorData != null;
#endif
if (mHoverResolveTask != null)
{
if (mHoverResolveTask.mLine != null)
{
UpdateMouseover(true, true, mHoverResolveTask.mLine.Value, mHoverResolveTask.mLineChar.Value, true);
return;
}
}
if (((mouseoverFired) || (mHoverWatch != null) || (hasClangHoverErrorData) || (mHoverResolveTask?.mResult != null)) &&
(mousePos.x >= 0))
{
@ -5526,6 +5552,13 @@ namespace IDE.ui
HandleResolveResult(resolveResult.mResolveType, resolveResult.mAutocompleteInfo, resolveResult);
if (resolveResult.mStopwatch != null)
{
resolveResult.mStopwatch.Stop();
if (var autoComplete = GetAutoComplete())
Debug.WriteLine($"Autocomplete {resolveResult.mStopwatch.ElapsedMilliseconds}ms entries: {autoComplete.mAutoCompleteListWidget.mEntryList.Count}");
}
//Debug.WriteLine("ProcessDeferredResolveResults finished {0}", resolveResult.mResolveType);
//bool checkIt = (mFilePath.Contains("Program.bf")) && (mEditWidget.mEditWidgetContent.mData.mCurTextVersionId > 3);

View file

@ -2765,7 +2765,10 @@ namespace IDE.ui
{
String evalStr = scope String();
CompactChildExpression(listViewItem, evalStr);
evalStr.Insert(0, "&");
if (evalStr.StartsWith("*"))
evalStr.Remove(0, 1);
else
evalStr.Insert(0, "&");
gApp.mBreakpointPanel.CreateMemoryBreakpoint(evalStr);
gApp.MarkDirty();
});