mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-22 09:38:01 +02:00
Merge branch 'master' into BookmarkPanel
This commit is contained in:
commit
6884b9fc21
267 changed files with 26197 additions and 17792 deletions
|
@ -1017,6 +1017,72 @@ namespace IDE.ui
|
|||
if (cursorSection >= textSections.Count - 1)
|
||||
cursorSection = textSections.Count - 2;
|
||||
|
||||
if ((cursorSection >= 0) && (cursorSection < mAutoComplete.mInvokeSrcPositions.Count))
|
||||
{
|
||||
var argText = mAutoComplete.mTargetEditWidget.mEditWidgetContent.ExtractString(mAutoComplete.mInvokeSrcPositions[cursorSection - 1],
|
||||
mAutoComplete.mInvokeSrcPositions[cursorSection] - mAutoComplete.mInvokeSrcPositions[cursorSection - 1], .. scope .());
|
||||
|
||||
int colonPos = argText.IndexOf(':');
|
||||
|
||||
if (colonPos != -1)
|
||||
{
|
||||
do
|
||||
{
|
||||
bool foundSep = false;
|
||||
int nameStart = -1;
|
||||
for (int i = colonPos - 1; i >= 0; i--)
|
||||
{
|
||||
char8 c = argText[i];
|
||||
if (nameStart == -1)
|
||||
{
|
||||
if ((c != '_') && (!c.IsLetterOrDigit))
|
||||
nameStart = i + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!c.IsWhiteSpace)
|
||||
{
|
||||
if ((!foundSep) &&
|
||||
((c == ',') || (c == '(')))
|
||||
foundSep = true;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nameStart == -1)
|
||||
break;
|
||||
|
||||
var argParamName = argText.Substring(nameStart, colonPos - nameStart);
|
||||
for (int checkSectionIdx = 1; checkSectionIdx < textSections.Count; checkSectionIdx++)
|
||||
{
|
||||
var sectionStr = textSections[checkSectionIdx];
|
||||
|
||||
var checkParamName = sectionStr;
|
||||
if (checkParamName.EndsWith(','))
|
||||
checkParamName.RemoveFromEnd(1);
|
||||
|
||||
for (int checkIdx = checkParamName.Length - 1; checkIdx >= 0; checkIdx--)
|
||||
{
|
||||
char8 c = checkParamName[checkIdx];
|
||||
if (c.IsWhiteSpace)
|
||||
{
|
||||
checkParamName.RemoveFromStart(checkIdx + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (checkParamName == argParamName)
|
||||
{
|
||||
cursorSection = checkSectionIdx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float paramX = 0;
|
||||
for (int sectionIdx = 0; sectionIdx < textSections.Count; sectionIdx++)
|
||||
{
|
||||
|
|
|
@ -552,7 +552,7 @@ namespace IDE.ui
|
|||
return base.Deserialize(data);
|
||||
}
|
||||
|
||||
public void QueueLine(String text)
|
||||
public void AddPendingLine(String text)
|
||||
{
|
||||
mCurLineNum++;
|
||||
using (mMonitor.Enter())
|
||||
|
@ -591,7 +591,17 @@ namespace IDE.ui
|
|||
|
||||
String outStr = scope String();
|
||||
outStr.AppendF("{0}({1}):{2}", fileEditData.mFilePath, line + 1, lineStr);
|
||||
gApp.mFindResultsPanel.QueueLine(outStr);
|
||||
gApp.mFindResultsPanel.AddPendingLine(outStr);
|
||||
}
|
||||
|
||||
public void QueueLine(String text)
|
||||
{
|
||||
using (mMonitor.Enter())
|
||||
{
|
||||
QueuedEntry entry = new .();
|
||||
entry.mText = new .(text);
|
||||
mQueuedEntries.Add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
public void QueueLine(String fileName, int32 line, int32 column, String text)
|
||||
|
@ -641,7 +651,10 @@ namespace IDE.ui
|
|||
while (!mQueuedEntries.IsEmpty)
|
||||
{
|
||||
var entry = mQueuedEntries.PopFront();
|
||||
QueueLine(gApp.GetEditData(entry.mFileName, true, false), entry.mLine, entry.mColumn, entry.mText);
|
||||
if (entry.mFileName == null)
|
||||
AddPendingLine(entry.mText);
|
||||
else
|
||||
QueueLine(gApp.GetEditData(entry.mFileName, true, false), entry.mLine, entry.mColumn, entry.mText);
|
||||
delete entry;
|
||||
}
|
||||
|
||||
|
|
|
@ -406,14 +406,12 @@ namespace IDE.ui
|
|||
|
||||
void HandleMouseWheel(MouseEvent evt)
|
||||
{
|
||||
if (mChildWidgets.Count == 0)
|
||||
return;
|
||||
|
||||
var lastListView = mChildWidgets[mChildWidgets.Count - 1] as HoverListView;
|
||||
if ((lastListView != null) && (lastListView.mVertScrollbar != null))
|
||||
return;
|
||||
|
||||
if (mListViews.Count > 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (evt.mSender != mWidgetWindow)
|
||||
{
|
||||
var widgetWindow = evt.mSender as BFWindow;
|
||||
while (widgetWindow != null)
|
||||
|
@ -423,6 +421,7 @@ namespace IDE.ui
|
|||
widgetWindow = widgetWindow.mParent;
|
||||
}
|
||||
}
|
||||
|
||||
EditWidget editWidget = mEditWidget;
|
||||
if (var sourceViewPanel = mTextPanel as SourceViewPanel)
|
||||
editWidget = sourceViewPanel.mEditWidget;
|
||||
|
|
|
@ -16,9 +16,11 @@ namespace IDE.ui
|
|||
public String mName ~ delete _;
|
||||
public String mPath ~ delete _;
|
||||
public VerSpecRecord mVersion;
|
||||
public Project.TargetType mTargetType;
|
||||
}
|
||||
|
||||
protected IDEListView mProjectList;
|
||||
DarkComboBox mKindCombo;
|
||||
EditWidget mEditWidget;
|
||||
bool mFilterChanged;
|
||||
List<InstalledProject> mInstalledProjectList = new .() ~ DeleteContainerAndItems!(_);
|
||||
|
@ -58,6 +60,21 @@ namespace IDE.ui
|
|||
mEditWidget.mOnKeyDown.Add(new => EditKeyDownHandler);
|
||||
mEditWidget.mOnContentChanged.Add(new (evt) => { mFilterChanged = true; });
|
||||
|
||||
mKindCombo = new DarkComboBox();
|
||||
mKindCombo.Label = "Libraries";
|
||||
mKindCombo.mPopulateMenuAction.Add(new (menu) =>
|
||||
{
|
||||
for (var kind in String[?]("All", "Libraries"))
|
||||
{
|
||||
menu.AddItem(kind).mOnMenuItemSelected.Add(new (menu) =>
|
||||
{
|
||||
mFilterChanged = true;
|
||||
mKindCombo.Label = kind;
|
||||
});
|
||||
}
|
||||
});
|
||||
AddWidget(mKindCombo);
|
||||
|
||||
FindProjects();
|
||||
}
|
||||
|
||||
|
@ -78,6 +95,7 @@ namespace IDE.ui
|
|||
installedProject.mPath.Append("BeefProj.toml");
|
||||
default:
|
||||
}
|
||||
installedProject.mTargetType = registryEntry.mTargetType;
|
||||
mInstalledProjectList.Add(installedProject);
|
||||
}
|
||||
}
|
||||
|
@ -128,9 +146,14 @@ namespace IDE.ui
|
|||
mEditWidget.GetText(filterString);
|
||||
filterString.Trim();
|
||||
|
||||
bool onlyLibs = mKindCombo.Label == "Libraries";
|
||||
|
||||
mFilteredList.Clear();
|
||||
for (var installedProject in mInstalledProjectList)
|
||||
{
|
||||
if ((onlyLibs) && (!installedProject.mTargetType.IsLib))
|
||||
continue;
|
||||
|
||||
if ((!filterString.IsEmpty) && (installedProject.mName.IndexOf(filterString, true) == -1))
|
||||
continue;
|
||||
|
||||
|
@ -138,7 +161,7 @@ namespace IDE.ui
|
|||
listViewItem.Label = installedProject.mName;
|
||||
|
||||
var subListViewItem = listViewItem.CreateSubItem(1);
|
||||
subListViewItem.Label = installedProject.mPath;
|
||||
subListViewItem.Label = Path.GetDirectoryPath(installedProject.mPath, .. scope .());
|
||||
|
||||
mFilteredList.Add(installedProject);
|
||||
}
|
||||
|
@ -180,7 +203,7 @@ namespace IDE.ui
|
|||
VerSpec verSpec = .SemVer(new .("*"));
|
||||
defer verSpec.Dispose();
|
||||
|
||||
let project = gApp.mProjectPanel.ImportProject(entry.mPath, verSpec);
|
||||
let project = gApp.mProjectPanel.ImportProject(entry.mPath, null, verSpec);
|
||||
if (project == null)
|
||||
{
|
||||
return;
|
||||
|
@ -223,6 +246,7 @@ namespace IDE.ui
|
|||
float insetSize = GS!(6);
|
||||
mProjectList.Resize(insetSize, insetSize, mWidth - insetSize - insetSize, mHeight - GS!(66));
|
||||
mEditWidget.Resize(insetSize, mProjectList.mY + mProjectList.mHeight + insetSize, mWidth - insetSize - insetSize, GS!(22));
|
||||
mKindCombo.Resize(insetSize, mHeight - GS!(26), Math.Min(GS!(160), mDefaultButton.mX - GS!(6)), GS!(26));
|
||||
}
|
||||
|
||||
public override void CalcSize()
|
||||
|
|
|
@ -61,6 +61,17 @@ namespace IDE.ui
|
|||
else if (projectItem.mIncludeKind == .Ignore)
|
||||
color = Color.Mult(color, gApp.mSettings.mUISettings.mColors.mWorkspaceIgnoredText);
|
||||
|
||||
if (let projectFileItem = projectItem as ProjectFileItem)
|
||||
{
|
||||
if (projectPanel.mClipboardCutQueued != null)
|
||||
{
|
||||
var path = projectFileItem.mProject.GetProjectFullPath(projectFileItem.mPath, .. scope .());
|
||||
IDEUtils.MakeComparableFilePath(path);
|
||||
if (projectPanel.mClipboardCutQueued.Contains(path))
|
||||
color = Color.Mult(color, gApp.mSettings.mUISettings.mColors.mWorkspaceCutText);
|
||||
}
|
||||
}
|
||||
|
||||
if (let projectSource = projectItem as ProjectSource)
|
||||
{
|
||||
if (projectSource.mLoadFailed)
|
||||
|
@ -146,6 +157,7 @@ namespace IDE.ui
|
|||
public bool mShowIgnored = true;
|
||||
public bool mSortDirty;
|
||||
public bool mWantsRehup;
|
||||
public HashSet<String> mClipboardCutQueued ~ DeleteContainerAndItems!(_);
|
||||
|
||||
public this()
|
||||
{
|
||||
|
@ -518,10 +530,22 @@ namespace IDE.ui
|
|||
}
|
||||
}
|
||||
|
||||
public void InitProject(Project project)
|
||||
{
|
||||
public void InitProject(Project project, WorkspaceFolder workspaceFolder)
|
||||
{
|
||||
var projectListViewItem = InitProjectItem(project.mRootFolder);
|
||||
projectListViewItem.mRefObject = project;
|
||||
if (workspaceFolder != null)
|
||||
{
|
||||
let root = mListView.GetRoot();
|
||||
root.RemoveChildItem(projectListViewItem, false);
|
||||
workspaceFolder.mListView.MakeParent();
|
||||
workspaceFolder.mListView.AddChild(projectListViewItem);
|
||||
workspaceFolder.mListView.Open(true);
|
||||
mProjectToWorkspaceFolderMap[project.mRootFolder] = workspaceFolder;
|
||||
|
||||
workspaceFolder.mProjects.Add(project);
|
||||
QueueSortItem(workspaceFolder.mListView);
|
||||
}
|
||||
}
|
||||
|
||||
public void RebuildUI()
|
||||
|
@ -564,7 +588,7 @@ namespace IDE.ui
|
|||
mProjectToWorkspaceFolderMap.Clear();
|
||||
|
||||
for (var project in IDEApp.sApp.mWorkspace.mProjects)
|
||||
InitProject(project);
|
||||
InitProject(project, null);
|
||||
|
||||
let root = mListView.GetRoot();
|
||||
|
||||
|
@ -1489,6 +1513,14 @@ namespace IDE.ui
|
|||
#endif
|
||||
}
|
||||
|
||||
public WorkspaceFolder GetSelectedWorkspaceFolder()
|
||||
{
|
||||
ListViewItem selectedItem = mListView.GetRoot().FindFirstSelectedItem();
|
||||
if (mListViewToWorkspaceFolderMap.TryGetValue(selectedItem, let folder))
|
||||
return folder;
|
||||
return null;
|
||||
}
|
||||
|
||||
ListViewItem GetSelectedParentItem()
|
||||
{
|
||||
ListViewItem selectedItem = mListView.GetRoot().FindFirstSelectedItem();
|
||||
|
@ -1764,33 +1796,59 @@ namespace IDE.ui
|
|||
let root = mListView.GetRoot();
|
||||
List<ListViewItem> itemsToMove = scope .();
|
||||
List<WorkspaceFolder> foldersToDelete = scope .();
|
||||
|
||||
root.WithSelectedItems(scope [&] (selectedItem) => {
|
||||
if (mListViewToWorkspaceFolderMap.GetValue(selectedItem) case .Ok(let folder))
|
||||
{
|
||||
foldersToDelete.Add(folder);
|
||||
mListViewToWorkspaceFolderMap.Remove(folder.mListView);
|
||||
selectedItem.WithItems(scope [&] (item) => {
|
||||
if (mListViewToProjectMap.GetValue(item) case .Ok(let project))
|
||||
{
|
||||
if (project.mParentFolder == null)
|
||||
itemsToMove.Add(item);
|
||||
}
|
||||
else if (mListViewToWorkspaceFolderMap.GetValue(item) case .Ok(let itemFolder))
|
||||
{
|
||||
foldersToDelete.Add(itemFolder);
|
||||
mListViewToWorkspaceFolderMap.Remove(itemFolder.mListView);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
for (let projectListViewItem in itemsToMove)
|
||||
|
||||
for (let listViewItem in itemsToMove)
|
||||
{
|
||||
projectListViewItem.mParentItem.RemoveChildItem(projectListViewItem, false);
|
||||
root.AddChildAtIndex(1, projectListViewItem);
|
||||
if (mListViewToProjectMap.TryGetValue(projectListViewItem, let projectItem))
|
||||
listViewItem.mParentItem.RemoveChildItem(listViewItem, false);
|
||||
root.AddChildAtIndex(1, listViewItem);
|
||||
if (mListViewToProjectMap.TryGetValue(listViewItem, let projectItem))
|
||||
mProjectToWorkspaceFolderMap.Remove(projectItem);
|
||||
}
|
||||
for (let folder in foldersToDelete)
|
||||
|
||||
bool HasDeletedParent(WorkspaceFolder folder)
|
||||
{
|
||||
WorkspaceFolder parent = folder;
|
||||
repeat
|
||||
{
|
||||
parent = parent.mParent;
|
||||
|
||||
if (foldersToDelete.Contains(parent))
|
||||
return true;
|
||||
}
|
||||
while (parent != null);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let folder in foldersToDelete)
|
||||
{
|
||||
let folderItem = folder.mListView;
|
||||
mListViewToWorkspaceFolderMap.Remove(folderItem);
|
||||
folderItem.mParentItem.RemoveChildItem(folderItem);
|
||||
gApp.mWorkspace.mWorkspaceFolders.Remove(folder);
|
||||
if (!HasDeletedParent(folder))
|
||||
{
|
||||
let folderItem = folder.mListView;
|
||||
folderItem.mParentItem.RemoveChildItem(folderItem);
|
||||
}
|
||||
|
||||
gApp.mWorkspace.mWorkspaceFolders.Remove(folder);
|
||||
delete folder;
|
||||
}
|
||||
|
||||
|
@ -2004,6 +2062,307 @@ namespace IDE.ui
|
|||
}
|
||||
}
|
||||
|
||||
void CopyToClipboard()
|
||||
{
|
||||
String clipData = scope .();
|
||||
mListView.GetRoot().WithSelectedItems(scope (selectedItem) =>
|
||||
{
|
||||
if (mListViewToProjectMap.GetValue(selectedItem) case .Ok(var sourceProjectItem))
|
||||
{
|
||||
String path = scope .();
|
||||
if (var projectFileItem = sourceProjectItem as ProjectFileItem)
|
||||
{
|
||||
sourceProjectItem.mProject.GetProjectFullPath(projectFileItem.mPath, path);
|
||||
path.Replace('\\', '/');
|
||||
|
||||
if (!clipData.IsEmpty)
|
||||
clipData.Append("\n");
|
||||
clipData.Append("file:///");
|
||||
IDEUtils.URLEncode(path, clipData);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!clipData.IsEmpty)
|
||||
gApp.SetClipboardData("code/file-list", clipData.Ptr, (.)clipData.Length, true);
|
||||
}
|
||||
|
||||
void CutToClipboard()
|
||||
{
|
||||
DeleteContainerAndItems!(mClipboardCutQueued);
|
||||
mClipboardCutQueued = null;
|
||||
|
||||
CopyToClipboard();
|
||||
mClipboardCutQueued = new .();
|
||||
ValidateCutClipboard();
|
||||
}
|
||||
|
||||
void ValidateCutClipboard()
|
||||
{
|
||||
if (mClipboardCutQueued == null)
|
||||
return;
|
||||
|
||||
void* data = gApp.GetClipboardData("code/file-list", var size, 0);
|
||||
if (size == -1)
|
||||
return;
|
||||
|
||||
ClearAndDeleteItems!(mClipboardCutQueued);
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
StringView sv = .((.)data, size);
|
||||
for (var line in sv.Split('\n'))
|
||||
{
|
||||
var uri = IDEUtils.URLDecode(line, .. scope .());
|
||||
if (uri.StartsWith("file:///"))
|
||||
{
|
||||
var srcPath = scope String()..Append(uri.Substring("file:///".Length));
|
||||
IDEUtils.MakeComparableFilePath(srcPath);
|
||||
if (mClipboardCutQueued.TryAddAlt(srcPath, var entryPtr))
|
||||
*entryPtr = new String(srcPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mClipboardCutQueued.IsEmpty)
|
||||
DeleteAndNullify!(mClipboardCutQueued);
|
||||
}
|
||||
|
||||
void PasteFromClipboard()
|
||||
{
|
||||
ValidateCutClipboard();
|
||||
|
||||
var projectItem = GetSelectedProjectItem();
|
||||
var projectFolder = projectItem as ProjectFolder;
|
||||
if (projectFolder == null)
|
||||
projectFolder = projectItem.mParentFolder;
|
||||
if (projectFolder == null)
|
||||
return;
|
||||
|
||||
var folderPath = projectFolder.GetFullImportPath(.. scope .());
|
||||
|
||||
void* data = gApp.GetClipboardData("code/file-list", var size);
|
||||
if (data == null)
|
||||
return;
|
||||
|
||||
bool isCut = mClipboardCutQueued != null;
|
||||
Dictionary<String, SourceViewPanel> sourceViewPanelMap = null;
|
||||
List<(SourceViewPanel sourceViewPanel, String fromPath, String toPath)> moveList = null;
|
||||
|
||||
HashSet<String> foundDirs = scope .();
|
||||
|
||||
if (isCut)
|
||||
{
|
||||
sourceViewPanelMap = scope:: .();
|
||||
gApp.WithSourceViewPanels(scope (sourceViewPanel) =>
|
||||
{
|
||||
if (sourceViewPanel.mFilePath === null)
|
||||
return;
|
||||
if (sourceViewPanel.mProjectSource == null)
|
||||
return;
|
||||
|
||||
var path = scope String()..Append(sourceViewPanel.mFilePath);
|
||||
IDEUtils.MakeComparableFilePath(path);
|
||||
if (sourceViewPanelMap.TryAdd(path, var keyPtr, var valuePtr))
|
||||
{
|
||||
*keyPtr = new String(path);
|
||||
*valuePtr = sourceViewPanel;
|
||||
}
|
||||
});
|
||||
|
||||
moveList = scope:: .();
|
||||
}
|
||||
|
||||
defer
|
||||
{
|
||||
DeleteContainerAndItems!(mClipboardCutQueued);
|
||||
mClipboardCutQueued = null;
|
||||
|
||||
if (sourceViewPanelMap != null)
|
||||
{
|
||||
for (var key in sourceViewPanelMap.Keys)
|
||||
delete key;
|
||||
}
|
||||
|
||||
if (moveList != null)
|
||||
{
|
||||
for (var val in moveList)
|
||||
{
|
||||
delete val.fromPath;
|
||||
delete val.toPath;
|
||||
}
|
||||
}
|
||||
|
||||
ClearAndDeleteItems!(foundDirs);
|
||||
}
|
||||
|
||||
void QueueDirectoryMove(StringView fromDir, StringView toDir)
|
||||
{
|
||||
var searchStr = scope String();
|
||||
searchStr.Append(fromDir);
|
||||
searchStr.Append("/*");
|
||||
for (var dirEntry in Directory.Enumerate(searchStr, .Directories | .Files))
|
||||
{
|
||||
var fromChildPath = dirEntry.GetFilePath(.. scope .());
|
||||
|
||||
String toChildPath = scope String()..Append(toDir);
|
||||
toChildPath.Append(Path.DirectorySeparatorChar);
|
||||
dirEntry.GetFileName(toChildPath);
|
||||
|
||||
if (dirEntry.IsDirectory)
|
||||
{
|
||||
QueueDirectoryMove(fromChildPath, toChildPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
var cmpPath = IDEUtils.MakeComparableFilePath(.. scope String()..Append(fromChildPath));
|
||||
if (sourceViewPanelMap.TryGet(cmpPath, var matchKey, var sourceViewPanel))
|
||||
{
|
||||
moveList.Add((sourceViewPanel, new String(fromChildPath), new String(toChildPath)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Result<void> CopyDirectory(StringView fromDir, StringView toDir)
|
||||
{
|
||||
if (Directory.CreateDirectory(toDir) case .Err)
|
||||
{
|
||||
gApp.Fail(scope $"Failed to create directory '{toDir}'");
|
||||
return .Err;
|
||||
}
|
||||
|
||||
var searchStr = scope String();
|
||||
searchStr.Append(fromDir);
|
||||
searchStr.Append("/*");
|
||||
for (var dirEntry in Directory.Enumerate(searchStr, .Directories | .Files))
|
||||
{
|
||||
var fromChildPath = dirEntry.GetFilePath(.. scope .());
|
||||
|
||||
String toChildPath = scope String()..Append(toDir);
|
||||
toChildPath.Append("/");
|
||||
dirEntry.GetFileName(toChildPath);
|
||||
|
||||
if (dirEntry.IsDirectory)
|
||||
{
|
||||
CopyDirectory(fromChildPath, toChildPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (File.Copy(fromChildPath, toChildPath) case .Err)
|
||||
{
|
||||
gApp.Fail(scope $"Failed to copy '{fromChildPath}' to '{toChildPath}'");
|
||||
return .Err;
|
||||
}
|
||||
}
|
||||
|
||||
return .Ok;
|
||||
}
|
||||
|
||||
StringView sv = .((.)data, size);
|
||||
SrcLoop: for (var line in sv.Split('\n'))
|
||||
{
|
||||
var uri = IDEUtils.URLDecode(line, .. scope .());
|
||||
if (uri.StartsWith("file:///"))
|
||||
{
|
||||
var srcPath = scope String()..Append(uri.Substring("file:///".Length));
|
||||
|
||||
for (int i < 100)
|
||||
{
|
||||
var fileName = Path.GetFileNameWithoutExtension(srcPath, .. scope .());
|
||||
var destPath = scope String();
|
||||
destPath.Append(folderPath);
|
||||
destPath.Append("/");
|
||||
destPath.Append(fileName);
|
||||
if ((i > 0) && (!fileName.Contains(" - Copy")))
|
||||
destPath.Append(" - Copy");
|
||||
if (i > 1)
|
||||
destPath.AppendF($" ({i})");
|
||||
Path.GetExtension(srcPath, destPath);
|
||||
|
||||
IDEUtils.FixFilePath(srcPath);
|
||||
IDEUtils.FixFilePath(destPath);
|
||||
|
||||
if ((isCut) && (Path.Equals(srcPath, destPath)))
|
||||
break;
|
||||
|
||||
if (File.Exists(destPath))
|
||||
continue;
|
||||
if (Directory.Exists(destPath))
|
||||
continue;
|
||||
|
||||
if (Directory.Exists(srcPath))
|
||||
{
|
||||
if (foundDirs.TryAdd(srcPath, var entryPtr))
|
||||
*entryPtr = new String(srcPath);
|
||||
|
||||
if (isCut)
|
||||
{
|
||||
QueueDirectoryMove(srcPath, destPath);
|
||||
|
||||
if (Directory.Move(srcPath, destPath) case .Err)
|
||||
{
|
||||
gApp.Fail(scope $"Failed to move '{srcPath}' to '{destPath}'");
|
||||
return;
|
||||
}
|
||||
|
||||
for (var val in moveList)
|
||||
{
|
||||
gApp.FileRenamed(val.sourceViewPanel.mProjectSource, val.fromPath, val.toPath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CopyDirectory(srcPath, destPath) case .Err)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var checkPath = scope String()..Append(srcPath);
|
||||
while (true)
|
||||
{
|
||||
String checkDir = scope .();
|
||||
if (Path.GetDirectoryPath(checkPath, checkDir) case .Err)
|
||||
break;
|
||||
if (foundDirs.Contains(checkDir))
|
||||
{
|
||||
// Already handled
|
||||
continue SrcLoop;
|
||||
}
|
||||
checkPath.Set(checkDir);
|
||||
}
|
||||
|
||||
if (isCut)
|
||||
{
|
||||
if (File.Move(srcPath, destPath) case .Err)
|
||||
{
|
||||
gApp.Fail(scope $"Failed to move '{srcPath}' to '{destPath}'");
|
||||
return;
|
||||
}
|
||||
|
||||
var cmpPath = IDEUtils.MakeComparableFilePath(.. scope String()..Append(srcPath));
|
||||
if (sourceViewPanelMap.TryGet(cmpPath, var matchKey, var sourceViewPanel))
|
||||
{
|
||||
gApp.FileRenamed(sourceViewPanel.mProjectSource, srcPath, destPath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (File.Copy(srcPath, destPath) case .Err)
|
||||
{
|
||||
gApp.Fail(scope $"Failed to copy '{srcPath}' to '{destPath}'");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void KeyDown(KeyCode keyCode, bool isRepeat)
|
||||
{
|
||||
mListView.KeyDown(keyCode, isRepeat);
|
||||
|
@ -2015,8 +2374,25 @@ namespace IDE.ui
|
|||
}
|
||||
|
||||
base.KeyDown(keyCode, isRepeat);
|
||||
if (keyCode == KeyCode.Delete)
|
||||
RemoveSelectedItems();
|
||||
|
||||
if (mWidgetWindow.GetKeyFlags() == .Ctrl)
|
||||
{
|
||||
switch (keyCode)
|
||||
{
|
||||
case (.)'C':
|
||||
CopyToClipboard();
|
||||
case (.)'X':
|
||||
CutToClipboard();
|
||||
case (.)'V':
|
||||
PasteFromClipboard();
|
||||
default:
|
||||
}
|
||||
}
|
||||
else if (mWidgetWindow.GetKeyFlags() == .None)
|
||||
{
|
||||
if (keyCode == KeyCode.Delete)
|
||||
RemoveSelectedItems();
|
||||
}
|
||||
}
|
||||
|
||||
void ItemClicked(MouseEvent theEvent)
|
||||
|
@ -2374,7 +2750,7 @@ namespace IDE.ui
|
|||
return true;
|
||||
}
|
||||
|
||||
public void AddWorkspaceFolder(ProjectListViewItem parentListViewItem)
|
||||
public WorkspaceFolder AddWorkspaceFolder(ProjectListViewItem parentListViewItem)
|
||||
{
|
||||
ProjectListViewItem listViewItem;
|
||||
listViewItem = (ProjectListViewItem)parentListViewItem.CreateChildItem();
|
||||
|
@ -2406,10 +2782,11 @@ namespace IDE.ui
|
|||
mListView.GetRoot().SelectItemExclusively(listViewItem);
|
||||
EditListViewItem(listViewItem);
|
||||
gApp.mWorkspace.SetChanged();
|
||||
return folder;
|
||||
}
|
||||
|
||||
|
||||
public Project ImportProject(String filePath, VerSpec verSpec = .None)
|
||||
public Project ImportProject(String filePath, WorkspaceFolder workspaceFolder, VerSpec verSpec = .None)
|
||||
{
|
||||
if (gApp.IsCompiling)
|
||||
return null;
|
||||
|
@ -2456,7 +2833,7 @@ namespace IDE.ui
|
|||
gApp.AddNewProjectToWorkspace(proj, verSpec);
|
||||
gApp.mWorkspace.FixOptions();
|
||||
gApp.[Friend]FlushDeferredLoadProjects(true);
|
||||
InitProject(proj);
|
||||
InitProject(proj, workspaceFolder);
|
||||
if (failed)
|
||||
{
|
||||
gApp.Fail(StackStringFormat!("Failed to load project: {0}", filePath));
|
||||
|
@ -2502,6 +2879,8 @@ namespace IDE.ui
|
|||
initialDir.Concat(Path.DirectorySeparatorChar, "Samples");
|
||||
}
|
||||
|
||||
var workspaceFolder = GetSelectedWorkspaceFolder();
|
||||
|
||||
fileDialog.InitialDirectory = initialDir;
|
||||
fileDialog.ValidateNames = true;
|
||||
fileDialog.DefaultExt = ".toml";
|
||||
|
@ -2511,7 +2890,7 @@ namespace IDE.ui
|
|||
{
|
||||
for (String origProjFilePath in fileDialog.FileNames)
|
||||
{
|
||||
ImportProject(origProjFilePath);
|
||||
ImportProject(origProjFilePath, workspaceFolder);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -2616,6 +2995,43 @@ namespace IDE.ui
|
|||
{
|
||||
Menu anItem;
|
||||
|
||||
void AddWorkspaceMenuItems()
|
||||
{
|
||||
anItem = menu.AddItem("Add New Project...");
|
||||
anItem.mOnMenuItemSelected.Add(new (item) => {
|
||||
AddNewProject();
|
||||
});
|
||||
if (gApp.IsCompiling)
|
||||
anItem.SetDisabled(true);
|
||||
|
||||
anItem = menu.AddItem("Add Existing Project...");
|
||||
anItem.mOnMenuItemSelected.Add(new (item) => {
|
||||
mImportProjectDeferred = true;
|
||||
});
|
||||
if (gApp.IsCompiling)
|
||||
anItem.SetDisabled(true);
|
||||
|
||||
anItem = menu.AddItem("Add From Installed...");
|
||||
anItem.mOnMenuItemSelected.Add(new (item) => {
|
||||
mImportInstalledDeferred = true;
|
||||
});
|
||||
if (gApp.IsCompiling)
|
||||
anItem.SetDisabled(true);
|
||||
anItem = menu.AddItem("New Folder");
|
||||
anItem.mOnMenuItemSelected.Add(new (item) => {
|
||||
var workspaceFolder = GetSelectedWorkspaceFolder();
|
||||
if (workspaceFolder != null)
|
||||
{
|
||||
let newFolder = AddWorkspaceFolder(workspaceFolder.mListView);
|
||||
newFolder.mParent = workspaceFolder;
|
||||
}
|
||||
else
|
||||
{
|
||||
AddWorkspaceFolder((ProjectListViewItem)mListView.GetRoot());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (mListViewToWorkspaceFolderMap.TryGetValue(focusedItem, let folder))
|
||||
{
|
||||
anItem = menu.AddItem("Remove");
|
||||
|
@ -2623,8 +3039,9 @@ namespace IDE.ui
|
|||
anItem = menu.AddItem("Rename");
|
||||
anItem.mOnMenuItemSelected.Add(new (item) => { EditListViewItem(focusedItem); });
|
||||
menu.AddItem();
|
||||
anItem = menu.AddItem("New Folder");
|
||||
anItem.mOnMenuItemSelected.Add(new (item) => { AddWorkspaceFolder(folder.mListView); });
|
||||
|
||||
AddWorkspaceMenuItems();
|
||||
|
||||
handled = true;
|
||||
}
|
||||
else if (gApp.mWorkspace.IsInitialized)
|
||||
|
@ -2632,23 +3049,7 @@ namespace IDE.ui
|
|||
AddOpenContainingFolder();
|
||||
menu.AddItem();
|
||||
|
||||
anItem = menu.AddItem("Add New Project...");
|
||||
anItem.mOnMenuItemSelected.Add(new (item) => { AddNewProject(); });
|
||||
if (gApp.IsCompiling)
|
||||
anItem.SetDisabled(true);
|
||||
|
||||
anItem = menu.AddItem("Add Existing Project...");
|
||||
anItem.mOnMenuItemSelected.Add(new (item) => { mImportProjectDeferred = true; });
|
||||
if (gApp.IsCompiling)
|
||||
anItem.SetDisabled(true);
|
||||
|
||||
anItem = menu.AddItem("Add From Installed...");
|
||||
anItem.mOnMenuItemSelected.Add(new (item) => { mImportInstalledDeferred = true; });
|
||||
if (gApp.IsCompiling)
|
||||
anItem.SetDisabled(true);
|
||||
|
||||
anItem = menu.AddItem("New Folder");
|
||||
anItem.mOnMenuItemSelected.Add(new (item) => { AddWorkspaceFolder((ProjectListViewItem)mListView.GetRoot()); });
|
||||
AddWorkspaceMenuItems();
|
||||
menu.AddItem();
|
||||
anItem = menu.AddItem("Properties...");
|
||||
anItem.mOnMenuItemSelected.Add(new (item) => { ShowWorkspaceProperties(); });
|
||||
|
@ -2717,7 +3118,7 @@ namespace IDE.ui
|
|||
});
|
||||
}
|
||||
|
||||
item = menu.AddItem("Remove...");
|
||||
item = menu.AddItem("Remove...|Del");
|
||||
if (gApp.IsCompiling)
|
||||
item.SetDisabled(true);
|
||||
item.mOnMenuItemSelected.Add(new (item) =>
|
||||
|
@ -2725,7 +3126,7 @@ namespace IDE.ui
|
|||
RemoveSelectedItems();
|
||||
});
|
||||
|
||||
item = menu.AddItem("Rename");
|
||||
item = gApp.AddMenuItem(menu, "Rename", "Rename Item");
|
||||
if (gApp.IsCompiling)
|
||||
item.SetDisabled(true);
|
||||
item.mOnMenuItemSelected.Add(new (item) =>
|
||||
|
@ -2769,13 +3170,13 @@ namespace IDE.ui
|
|||
|
||||
if ((projectItem != null) && (!isProject))
|
||||
{
|
||||
item = menu.AddItem("Remove ...");
|
||||
item = menu.AddItem("Remove ...|Del");
|
||||
item.mOnMenuItemSelected.Add(new (item) =>
|
||||
{
|
||||
RemoveSelectedItems();
|
||||
});
|
||||
|
||||
item = menu.AddItem("Rename");
|
||||
item = gApp.AddMenuItem(menu, "Rename", "Rename Item");
|
||||
item.mOnMenuItemSelected.Add(new (item) =>
|
||||
{
|
||||
var projectItem = GetSelectedProjectItem();
|
||||
|
@ -2926,6 +3327,14 @@ namespace IDE.ui
|
|||
|
||||
if (!isFailedLoad)
|
||||
{
|
||||
item = menu.AddItem("Copy|Ctrl+C");
|
||||
item.mOnMenuItemSelected.Add(new (item) => CopyToClipboard());
|
||||
item = menu.AddItem("Cut|Ctrl+X");
|
||||
item.mOnMenuItemSelected.Add(new (item) => CopyToClipboard());
|
||||
item = menu.AddItem("Paste|Ctrl+V");
|
||||
item.mOnMenuItemSelected.Add(new (item) => CopyToClipboard());
|
||||
menu.AddItem();
|
||||
|
||||
item = menu.AddItem("New Folder");
|
||||
item.mOnMenuItemSelected.Add(new (item) =>
|
||||
{
|
||||
|
@ -3098,6 +3507,8 @@ namespace IDE.ui
|
|||
mImportInstalledDeferred = false;
|
||||
ImportInstalledProject();
|
||||
}
|
||||
|
||||
ValidateCutClipboard();
|
||||
}
|
||||
|
||||
public override void Resize(float x, float y, float width, float height)
|
||||
|
@ -3114,3 +3525,5 @@ namespace IDE.ui
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////
|
|
@ -244,7 +244,12 @@ namespace IDE.ui
|
|||
if (mKind == .GoToDefinition)
|
||||
{
|
||||
mSourceViewPanel.RecordHistoryLocation();
|
||||
var sourceViewPanel = gApp.ShowSourceFileLocation(scope .(filePath), -1, -1, line, lineChar, LocatorType.Smart, true);
|
||||
|
||||
var usePath = scope String(filePath);
|
||||
if (usePath.StartsWith("$Emit$"))
|
||||
usePath.Insert("$Emit$".Length, "Resolve$");
|
||||
|
||||
var sourceViewPanel = gApp.ShowSourceFileLocation(usePath, -1, -1, line, lineChar, LocatorType.Smart, true);
|
||||
sourceViewPanel.RecordHistoryLocation(true);
|
||||
Close();
|
||||
return;
|
||||
|
|
|
@ -221,6 +221,30 @@ namespace IDE.ui
|
|||
}
|
||||
}
|
||||
|
||||
// Do chord prefix search
|
||||
for (var propEntries in mPropPage.mPropEntries.Values)
|
||||
{
|
||||
var propEntry = propEntries[0];
|
||||
let keyEntry = (KeyEntry)propEntry.mTarget;
|
||||
let origKeys = propEntry.mCurValue.Get<List<KeyState>>();
|
||||
var keys = scope List<KeyState>(origKeys.GetEnumerator());
|
||||
while (keys.Count > 1)
|
||||
{
|
||||
keys.PopBack();
|
||||
let keyEntryStr = scope String();
|
||||
KeyState.ToString(keys, keyEntryStr);
|
||||
keyEntryStr.Append(" ");
|
||||
CommandContextToString(keyEntry.mContextFlags, keyEntryStr);
|
||||
|
||||
if (mappedEntries.TryGet(keyEntryStr, var keyPtr, var valuePtr))
|
||||
{
|
||||
let other = valuePtr;
|
||||
other.mHasConflict = true;
|
||||
keyEntry.mHasConflict = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let keyEntryStr in mappedEntries.Keys)
|
||||
delete keyEntryStr;
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@ using IDE.Debugger;
|
|||
using IDE.Compiler;
|
||||
using Beefy.geom;
|
||||
using Beefy.events;
|
||||
using System.Security.Cryptography;
|
||||
using System.IO;
|
||||
|
||||
namespace IDE.ui
|
||||
{
|
||||
|
@ -224,7 +226,7 @@ namespace IDE.ui
|
|||
{
|
||||
mTypeName = new .(emitEmbed.mTypeName);
|
||||
mEmitEmbed = emitEmbed;
|
||||
mSourceViewPanel = new SourceViewPanel((emitEmbed.mEmitKind == .Method) ? .Method : .Type);
|
||||
mSourceViewPanel = new SourceViewPanel((emitEmbed.mEmitKind == .Emit_Method) ? .Method : .Type);
|
||||
mSourceViewPanel.mEmbedParent = mEmitEmbed.mEditWidgetContent.mSourceViewPanel;
|
||||
var emitPath = scope $"$Emit${emitEmbed.mTypeName}";
|
||||
|
||||
|
@ -382,7 +384,7 @@ namespace IDE.ui
|
|||
}
|
||||
|
||||
mAwaitingLoad = false;
|
||||
if (!mEmitRemoved)
|
||||
if ((!mEmitRemoved) && (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve))
|
||||
{
|
||||
for (var explicitTypeName in mEmitEmbed.mEditWidgetContent.mSourceViewPanel.[Friend]mExplicitEmitTypes)
|
||||
{
|
||||
|
@ -397,6 +399,9 @@ namespace IDE.ui
|
|||
|
||||
if ((mAwaitingLoad) && (gApp.mUpdateCnt % 4 == 0))
|
||||
MarkDirty();
|
||||
|
||||
if (mSourceViewPanel.HasFocus())
|
||||
mEmitEmbed.mEditWidgetContent.mEmbedSelected = mEmitEmbed;
|
||||
}
|
||||
|
||||
public void GetGenericTypes()
|
||||
|
@ -516,6 +521,10 @@ namespace IDE.ui
|
|||
public int32 mEndLine;
|
||||
public View mView;
|
||||
|
||||
public this()
|
||||
{
|
||||
}
|
||||
|
||||
public ~this()
|
||||
{
|
||||
if (mView != null)
|
||||
|
@ -525,17 +534,29 @@ namespace IDE.ui
|
|||
}
|
||||
}
|
||||
|
||||
public bool IsSelected => mEditWidgetContent.mEmbedSelected == this;
|
||||
public float LabelWidth = GS!(42);
|
||||
|
||||
public override float GetWidth(bool hideLine)
|
||||
{
|
||||
return GS!(42);
|
||||
return IsSelected ? GS!(60) : LabelWidth;
|
||||
}
|
||||
|
||||
public override void Draw(Graphics g, Rect rect, bool hideLine)
|
||||
{
|
||||
var rect;
|
||||
rect.mWidth = LabelWidth;
|
||||
|
||||
if (rect.mHeight >= DarkTheme.sDarkTheme.mSmallBoldFont.GetLineSpacing())
|
||||
g.SetFont(DarkTheme.sDarkTheme.mSmallBoldFont);
|
||||
|
||||
using (g.PushColor(0x80707070))
|
||||
uint32 fillColor = 0x80707070;
|
||||
if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Build)
|
||||
{
|
||||
fillColor = 0x805050E0;
|
||||
}
|
||||
|
||||
using (g.PushColor(fillColor))
|
||||
{
|
||||
g.FillRect(rect.mX + 1, rect.mY + 1, rect.mWidth - 2, rect.mHeight - 2);
|
||||
}
|
||||
|
@ -558,6 +579,40 @@ namespace IDE.ui
|
|||
|
||||
var summaryString = "Emit";
|
||||
g.DrawString(summaryString, rect.mX, rect.mY + (int)((rect.mHeight - g.mFont.GetLineSpacing()) * 0.5f), .Centered, rect.mWidth);
|
||||
|
||||
if (IsSelected)
|
||||
{
|
||||
g.Draw(DarkTheme.sDarkTheme.GetImage(.DropMenuButton), rect.Right, rect.Top);
|
||||
}
|
||||
}
|
||||
|
||||
public override void MouseDown(Rect rect, float x, float y, int btn, int btnCount)
|
||||
{
|
||||
base.MouseDown(rect, x, y, btn, btnCount);
|
||||
if (x >= rect.mX + LabelWidth)
|
||||
ShowMenu(x, y);
|
||||
}
|
||||
|
||||
public void ShowMenu(float x, float y)
|
||||
{
|
||||
Menu menuItem;
|
||||
|
||||
Menu menu = new Menu();
|
||||
menuItem = menu.AddItem("Compiler");
|
||||
|
||||
var subItem = menuItem.AddItem("Resolve");
|
||||
if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve)
|
||||
subItem.mIconImage = DarkTheme.sDarkTheme.GetImage(.Check);
|
||||
subItem.mOnMenuItemSelected.Add(new (menu) => { gApp.SetEmbedCompiler(.Resolve); });
|
||||
|
||||
subItem = menuItem.AddItem("Build");
|
||||
if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Build)
|
||||
subItem.mIconImage = DarkTheme.sDarkTheme.GetImage(.Check);
|
||||
subItem.mOnMenuItemSelected.Add(new (menu) => { gApp.SetEmbedCompiler(.Build); });
|
||||
|
||||
MenuWidget menuWidget = DarkTheme.sDarkTheme.CreateMenuWidget(menu);
|
||||
|
||||
menuWidget.Init(mEditWidgetContent, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -575,10 +630,11 @@ namespace IDE.ui
|
|||
case UsingNamespaces = 'U';
|
||||
case Unknown = '?';
|
||||
case HasUncertainEmits = '~';
|
||||
case Emit = 'e';
|
||||
case Emit_Type = 't';
|
||||
case Emit_Method = 'm';
|
||||
case EmitAddType = '+';
|
||||
|
||||
public bool IsEmit => (this == .Emit);
|
||||
public bool IsEmit => (this == .Emit_Type) || (this == .Emit_Method);
|
||||
}
|
||||
|
||||
public Kind mKind;
|
||||
|
@ -602,6 +658,8 @@ namespace IDE.ui
|
|||
public int32 mParseRevision;
|
||||
public int32 mTextRevision;
|
||||
public bool mDeleted;
|
||||
|
||||
public bool DefaultOpen => mKind != .Region;
|
||||
}
|
||||
|
||||
public struct EmitData
|
||||
|
@ -614,6 +672,7 @@ namespace IDE.ui
|
|||
public bool mOnlyInResolveAll;
|
||||
public bool mIncludedInClassify;
|
||||
public bool mIncludedInResolveAll;
|
||||
public bool mIncludedInBuild;
|
||||
|
||||
public int32 mAnchorId;
|
||||
}
|
||||
|
@ -757,6 +816,8 @@ namespace IDE.ui
|
|||
public int32 mCollapseTextVersionId;
|
||||
public bool mCollapseNeedsUpdate;
|
||||
public bool mCollapseNoCheckOpen;
|
||||
public bool mCollapseDBDirty;
|
||||
public bool mCollapseAwaitingDB = true;
|
||||
|
||||
public List<PersistentTextPosition> PersistentTextPositions
|
||||
{
|
||||
|
@ -1784,7 +1845,19 @@ namespace IDE.ui
|
|||
int line;
|
||||
int lineChar;
|
||||
GetCursorLineChar(out line, out lineChar);
|
||||
return IDEApp.sApp.mHistoryManager.CreateHistory(mSourceViewPanel, mSourceViewPanel.mFilePath, line, lineChar, ignoreIfClose);
|
||||
|
||||
String useFilePath = mSourceViewPanel.mFilePath;
|
||||
if ((mSourceViewPanel.mFilePath.StartsWith("$Emit$")) &&
|
||||
(!mSourceViewPanel.mFilePath.StartsWith("$Emit$Build$")) &&
|
||||
(!mSourceViewPanel.mFilePath.StartsWith("$Emit$Resolve$")))
|
||||
{
|
||||
if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve)
|
||||
useFilePath = scope:: String("$Emit$Resolve$")..Append(mSourceViewPanel.mFilePath.Substring("$Emit$".Length));
|
||||
else
|
||||
useFilePath = scope:: String("$Emit$Build$")..Append(mSourceViewPanel.mFilePath.Substring("$Emit$".Length));
|
||||
}
|
||||
|
||||
return IDEApp.sApp.mHistoryManager.CreateHistory(mSourceViewPanel, useFilePath, line, lineChar, ignoreIfClose);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -3901,7 +3974,7 @@ namespace IDE.ui
|
|||
prevChar = mData.mText[cursorTextPos - 1].mChar;
|
||||
}
|
||||
|
||||
if (((keyChar == '\n') || (keyChar == '\r')) && (mIsMultiline) && (!CheckReadOnly()))
|
||||
if (((keyChar == '\n') || (keyChar == '\r')) && (!HasSelection()) && (mIsMultiline) && (!CheckReadOnly()))
|
||||
{
|
||||
UndoBatchStart undoBatchStart = new UndoBatchStart("newline");
|
||||
mData.mUndoManager.Add(undoBatchStart);
|
||||
|
@ -4408,6 +4481,7 @@ namespace IDE.ui
|
|||
public override void KeyDown(KeyCode keyCode, bool isRepeat)
|
||||
{
|
||||
mIgnoreKeyChar = false;
|
||||
mEmbedSelected = null;
|
||||
|
||||
bool autoCompleteRequireControl = (gApp.mSettings.mEditorSettings.mAutoCompleteRequireControl) && (mIsMultiline);
|
||||
|
||||
|
@ -4463,7 +4537,6 @@ namespace IDE.ui
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ((keyCode == KeyCode.Escape) && (mSelection != null) && (mSelection.Value.HasSelection))
|
||||
{
|
||||
|
@ -4696,6 +4769,23 @@ namespace IDE.ui
|
|||
{
|
||||
base.MouseClicked(x, y, origX, origY, btn);
|
||||
|
||||
if (btn == 1)
|
||||
{
|
||||
int line = GetLineAt(y);
|
||||
if (mEmbeds.GetValue((.)line) case .Ok(let embed))
|
||||
{
|
||||
Rect embedRect = GetEmbedRect(line, embed);
|
||||
if (embedRect.Contains(x, y))
|
||||
{
|
||||
if (var emitEmbed = embed as EmitEmbed)
|
||||
{
|
||||
emitEmbed.ShowMenu(x, y);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var useX = x;
|
||||
var useY = y;
|
||||
|
||||
|
@ -4735,15 +4825,15 @@ namespace IDE.ui
|
|||
{
|
||||
Menu menuItem;
|
||||
|
||||
menuItem = menu.AddItem("Go to Definition");
|
||||
menuItem = gApp.AddMenuItem(menu, "Go to Definition", "Goto Definition");
|
||||
menuItem.SetDisabled(!hasText);
|
||||
menuItem.mOnMenuItemSelected.Add(new (evt) => gApp.GoToDefinition(true));
|
||||
|
||||
menuItem = menu.AddItem("Find All References");
|
||||
menuItem = gApp.AddMenuItem(menu, "Find All References");
|
||||
menuItem.SetDisabled(!hasText);
|
||||
menuItem.mOnMenuItemSelected.Add(new (evt) => gApp.Cmd_FindAllReferences());
|
||||
|
||||
menuItem = menu.AddItem("Rename Symbol");
|
||||
menuItem = gApp.AddMenuItem(menu, "Rename Symbol");
|
||||
menuItem.SetDisabled(!hasText);
|
||||
menuItem.mOnMenuItemSelected.Add(new (evt) => gApp.Cmd_RenameSymbol());
|
||||
|
||||
|
@ -4823,7 +4913,12 @@ namespace IDE.ui
|
|||
var autoComplete = new AutoComplete(mEditWidget);
|
||||
autoComplete.SetInfo(infoCopy);
|
||||
autoComplete.mAutoCompleteListWidget.mSelectIdx = fixitIdx;
|
||||
|
||||
UndoBatchStart undoBatchStart = new UndoBatchStart("autocomplete");
|
||||
mData.mUndoManager.Add(undoBatchStart);
|
||||
autoComplete.InsertSelection(0);
|
||||
mData.mUndoManager.Add(undoBatchStart.mBatchEnd);
|
||||
|
||||
autoComplete.Close();
|
||||
}
|
||||
~
|
||||
|
@ -4866,10 +4961,14 @@ namespace IDE.ui
|
|||
menu.AddItem();
|
||||
var debugger = IDEApp.sApp.mDebugger;
|
||||
bool isPaused = debugger.IsPaused();
|
||||
menuItem = menu.AddItem("Show Disassembly");
|
||||
menuItem = gApp.AddMenuItem(menu, "Show Disassembly");
|
||||
menuItem.SetDisabled(!isPaused);
|
||||
menuItem.mOnMenuItemSelected.Add(new (evt) => IDEApp.sApp.ShowDisassemblyAtCursor());
|
||||
|
||||
menuItem = gApp.AddMenuItem(menu, "Set Next Statement");
|
||||
menuItem.SetDisabled(!isPaused);
|
||||
menuItem.mOnMenuItemSelected.Add(new (evt) => IDEApp.sApp.[Friend]SetNextStatement());
|
||||
|
||||
var stepIntoSpecificMenu = menu.AddItem("Step into Specific");
|
||||
stepIntoSpecificMenu.SetDisabled(!isPaused);
|
||||
stepIntoSpecificMenu.IsParent = true;
|
||||
|
@ -5019,20 +5118,26 @@ namespace IDE.ui
|
|||
Rect embedRect = GetEmbedRect(line, embed);
|
||||
if (embedRect.Contains(x, y))
|
||||
{
|
||||
if ((btn == 0) && (btnCount % 2 == 0))
|
||||
mEmbedSelected = embed;
|
||||
embed.MouseDown(GetEmbedRect(line, embed), x, y, btn, btnCount);
|
||||
if (btn == 0)
|
||||
{
|
||||
if (var collapseSummary = embed as SourceEditWidgetContent.CollapseSummary)
|
||||
SetCollapseOpen(collapseSummary.mCollapseIndex, true);
|
||||
else if (var emitEmbed = embed as EmitEmbed)
|
||||
if (btnCount % 2 == 0)
|
||||
{
|
||||
emitEmbed.mIsOpen = !emitEmbed.mIsOpen;
|
||||
mCollapseNeedsUpdate = true;
|
||||
if (var collapseSummary = embed as SourceEditWidgetContent.CollapseSummary)
|
||||
SetCollapseOpen(collapseSummary.mCollapseIndex, true);
|
||||
else if (var emitEmbed = embed as EmitEmbed)
|
||||
{
|
||||
emitEmbed.mIsOpen = !emitEmbed.mIsOpen;
|
||||
mCollapseNeedsUpdate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mEmbedSelected = null;
|
||||
base.MouseDown(x, y, btn, btnCount);
|
||||
}
|
||||
|
||||
|
@ -5727,6 +5832,13 @@ namespace IDE.ui
|
|||
}
|
||||
}
|
||||
|
||||
void DeleteEmbed(Embed embed)
|
||||
{
|
||||
if (mEmbedSelected == embed)
|
||||
mEmbedSelected = null;
|
||||
delete embed;
|
||||
}
|
||||
|
||||
public override void GetTextData()
|
||||
{
|
||||
var data = Data;
|
||||
|
@ -5755,8 +5867,14 @@ namespace IDE.ui
|
|||
}
|
||||
}
|
||||
|
||||
IdSpan.LookupContext lookupCtx = null;
|
||||
|
||||
for (var emitData in ref data.mEmitData)
|
||||
{
|
||||
if (lookupCtx == null)
|
||||
lookupCtx = scope:: .(mData.mTextIdData);
|
||||
emitData.mAnchorIdx = (.)lookupCtx.GetIndexFromId(emitData.mAnchorId);
|
||||
|
||||
GetLineCharAtIdx(emitData.mAnchorIdx, var line, var lineChar);
|
||||
|
||||
SourceEditWidgetContent.EmitEmbed emitEmbed = null;
|
||||
|
@ -5776,7 +5894,7 @@ namespace IDE.ui
|
|||
else
|
||||
{
|
||||
//Debug.WriteLine($" Occupied- deleting {emitEmbed}");
|
||||
delete emitEmbed;
|
||||
DeleteEmbed(emitEmbed);
|
||||
emitEmbed = null;
|
||||
}
|
||||
}
|
||||
|
@ -5837,13 +5955,14 @@ namespace IDE.ui
|
|||
{
|
||||
mCollapseNeedsUpdate = true;
|
||||
mEmbeds.Remove(emitEmbed.mLine);
|
||||
delete emitEmbed;
|
||||
DeleteEmbed(emitEmbed);
|
||||
}
|
||||
}
|
||||
|
||||
for (var collapseData in ref data.mCollapseData)
|
||||
{
|
||||
if (mCollapseMap.TryAdd(collapseData.mAnchorId, ?, var entry))
|
||||
bool isNew = mCollapseMap.TryAdd(collapseData.mAnchorId, ?, var entry);
|
||||
if (isNew)
|
||||
{
|
||||
*entry = .();
|
||||
}
|
||||
|
@ -5852,6 +5971,12 @@ namespace IDE.ui
|
|||
entry.mPrevAnchorLine = prevAnchorLine;
|
||||
entry.mParseRevision = mCollapseParseRevision;
|
||||
entry.mDeleted = false;
|
||||
|
||||
if ((isNew) && (!entry.DefaultOpen) && (!mCollapseAwaitingDB))
|
||||
{
|
||||
// Likely a '#region' that we need to serialize as being open
|
||||
mCollapseDBDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (var entry in ref mCollapseMap.Values)
|
||||
|
@ -5863,7 +5988,7 @@ namespace IDE.ui
|
|||
if (!(value is EmitEmbed))
|
||||
{
|
||||
mEmbeds.Remove(entry.mAnchorLine);
|
||||
delete value;
|
||||
DeleteEmbed(value);
|
||||
}
|
||||
}
|
||||
@entry.Remove();
|
||||
|
@ -5888,7 +6013,7 @@ namespace IDE.ui
|
|||
{
|
||||
//Debug.WriteLine($" Removing {val.value}");
|
||||
if (val.value is CollapseSummary)
|
||||
delete val.value;
|
||||
DeleteEmbed(val.value);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -5914,11 +6039,68 @@ namespace IDE.ui
|
|||
else
|
||||
{
|
||||
//Debug.WriteLine($" Deleting(3) {val}");
|
||||
delete val;
|
||||
DeleteEmbed(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !CLI
|
||||
if ((mCollapseAwaitingDB) && (mSourceViewPanel != null))
|
||||
{
|
||||
String filePath = scope .(mSourceViewPanel.mFilePath);
|
||||
IDEUtils.MakeComparableFilePath(filePath);
|
||||
|
||||
HashSet<int32> toggledIndices = scope .();
|
||||
|
||||
List<uint8> dbData = scope .();
|
||||
if (gApp.mFileRecovery.GetDB(filePath, dbData))
|
||||
{
|
||||
MemoryStream memStream = scope .(dbData, false);
|
||||
var dbHash = memStream.Read<MD5Hash>().GetValueOrDefault();
|
||||
|
||||
String text = scope .();
|
||||
mEditWidget.GetText(text);
|
||||
var curHash = MD5.Hash(.((uint8*)text.Ptr, text.Length));
|
||||
if (curHash == dbHash)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (memStream.Read<int32>() case .Ok(let idx))
|
||||
{
|
||||
// We recorded indices, which (upon load) will generate an id of idx+1
|
||||
toggledIndices.Add(idx + 1);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool wasCursorVisible = IsCursorVisible();
|
||||
bool hadCloses = false;
|
||||
for (var collapseEntry in mOrderedCollapseEntries)
|
||||
{
|
||||
bool wantOpen = collapseEntry.DefaultOpen;
|
||||
if (toggledIndices.Contains(collapseEntry.mAnchorId))
|
||||
wantOpen = !wantOpen;
|
||||
|
||||
if (collapseEntry.mIsOpen != wantOpen)
|
||||
{
|
||||
if (!wantOpen)
|
||||
hadCloses = true;
|
||||
SetCollapseOpen(@collapseEntry.Index, wantOpen, true, true);
|
||||
}
|
||||
}
|
||||
if ((wasCursorVisible) && (hadCloses))
|
||||
{
|
||||
UpdateCollapse(0.0f);
|
||||
EnsureCursorVisible();
|
||||
}
|
||||
|
||||
mCollapseAwaitingDB = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
//Debug.WriteLine($"ParseCollapseRegions Count:{mOrderedCollapseEntries.Count} Time:{sw.ElapsedMilliseconds}ms");
|
||||
}
|
||||
|
||||
|
@ -6221,17 +6403,26 @@ namespace IDE.ui
|
|||
}
|
||||
|
||||
|
||||
public void SetCollapseOpen(int collapseIdx, bool wantOpen, bool immediate = false)
|
||||
public void SetCollapseOpen(int collapseIdx, bool wantOpen, bool immediate = false, bool keepCursorVisible = false)
|
||||
{
|
||||
var entry = mOrderedCollapseEntries[collapseIdx];
|
||||
|
||||
var cursorLineAndColumn = CursorLineAndColumn;
|
||||
|
||||
if ((!wantOpen) && (keepCursorVisible) && (cursorLineAndColumn.mLine >= entry.mStartLine) && (cursorLineAndColumn.mLine <= entry.mEndLine))
|
||||
{
|
||||
if (CursorTextPos < entry.mEndIdx)
|
||||
{
|
||||
// Ignore close
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
entry.mIsOpen = wantOpen;
|
||||
if (immediate)
|
||||
entry.mOpenPct = entry.mIsOpen ? 1.0f : 0.0f;
|
||||
else
|
||||
mCollapseNeedsUpdate = true;
|
||||
|
||||
var cursorLineAndColumn = CursorLineAndColumn;
|
||||
mCollapseNeedsUpdate = true;
|
||||
mCollapseDBDirty = true;
|
||||
|
||||
if (wantOpen)
|
||||
{
|
||||
|
@ -6241,7 +6432,7 @@ namespace IDE.ui
|
|||
{
|
||||
if ((embed.mKind == .HideLine) || (embed.mKind == .LineEnd))
|
||||
{
|
||||
delete embed;
|
||||
DeleteEmbed(embed);
|
||||
mEmbeds.Remove(entry.mAnchorLine);
|
||||
}
|
||||
}
|
||||
|
@ -6283,7 +6474,7 @@ namespace IDE.ui
|
|||
if (!(value is EmitEmbed))
|
||||
{
|
||||
mEmbeds.Remove(prevAnchorLine);
|
||||
delete value;
|
||||
DeleteEmbed(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6304,7 +6495,7 @@ namespace IDE.ui
|
|||
else
|
||||
{
|
||||
//Debug.WriteLine($" Occupied- deleting {val}");
|
||||
delete val.value;
|
||||
DeleteEmbed(val.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6360,7 +6551,7 @@ namespace IDE.ui
|
|||
if (entry.mDeleted)
|
||||
{
|
||||
if (mEmbeds.GetAndRemove(entry.mAnchorIdx) case .Ok(let val))
|
||||
delete val.value;
|
||||
DeleteEmbed(val.value);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -6388,7 +6579,7 @@ namespace IDE.ui
|
|||
*valuePtr = val.value;
|
||||
}
|
||||
else
|
||||
delete val.value;
|
||||
DeleteEmbed(val.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6401,7 +6592,7 @@ namespace IDE.ui
|
|||
RehupLineCoords();
|
||||
}
|
||||
|
||||
public void ParseCollapseRegions(String collapseText, int32 textVersion, ref IdSpan idSpan, ResolveType resolveType)
|
||||
public void ParseCollapseRegions(String collapseText, int32 textVersion, ref IdSpan idSpan, ResolveType? resolveType)
|
||||
{
|
||||
/*if (resolveType == .None)
|
||||
return;*/
|
||||
|
@ -6410,11 +6601,13 @@ namespace IDE.ui
|
|||
|
||||
var data = PreparedData;
|
||||
|
||||
if (resolveType != .None)
|
||||
if ((resolveType != null) && (resolveType != .None))
|
||||
{
|
||||
data.ClearCollapse();
|
||||
}
|
||||
|
||||
bool wantsBuildEmits = gApp.mSettings.mEditorSettings.mEmitCompiler == .Build;
|
||||
|
||||
//Debug.WriteLine($"ParseCollapseRegions {resolveType} CollapseRevision:{data.mCollapseParseRevision+1} TextVersion:{textVersion} IdSpan:{idSpan:D}");
|
||||
|
||||
List<int32> typeNameIdxMap = scope .();
|
||||
|
@ -6429,7 +6622,7 @@ namespace IDE.ui
|
|||
if (emitInitialized)
|
||||
return;
|
||||
emitInitialized = true;
|
||||
if ((hasUncertainEmits) || (resolveType == .None))
|
||||
if ((hasUncertainEmits) || (wantsBuildEmits) || (resolveType == .None))
|
||||
{
|
||||
// Leave emits alone
|
||||
for (var typeName in data.mTypeNames)
|
||||
|
@ -6437,7 +6630,11 @@ namespace IDE.ui
|
|||
for (var emitData in ref data.mEmitData)
|
||||
{
|
||||
emitAnchorIds[emitData.mAnchorId] = (.)@emitData.Index;
|
||||
if (resolveType == .None)
|
||||
if (resolveType == null)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
else if (resolveType == .None)
|
||||
emitData.mIncludedInResolveAll = false;
|
||||
else
|
||||
emitData.mIncludedInClassify = false;
|
||||
|
@ -6491,6 +6688,7 @@ namespace IDE.ui
|
|||
emitData.mOnlyInResolveAll = resolveType == .None;
|
||||
emitData.mIncludedInClassify = resolveType != .None;
|
||||
emitData.mIncludedInResolveAll = resolveType == .None;
|
||||
emitData.mIncludedInBuild = resolveType == null;
|
||||
|
||||
if (emitData.mAnchorIdx == -1)
|
||||
{
|
||||
|
@ -6508,8 +6706,14 @@ namespace IDE.ui
|
|||
{
|
||||
curEmitData.mIncludedInResolveAll = true;
|
||||
}
|
||||
else if ((wantsBuildEmits) && (resolveType != null))
|
||||
{
|
||||
curEmitData.mIncludedInBuild |= emitData.mIncludedInBuild;
|
||||
curEmitData.mIncludedInClassify |= emitData.mIncludedInClassify;
|
||||
}
|
||||
else
|
||||
{
|
||||
emitData.mIncludedInBuild |= curEmitData.mIncludedInBuild;
|
||||
emitData.mIncludedInClassify |= curEmitData.mIncludedInClassify;
|
||||
curEmitData = emitData;
|
||||
}
|
||||
|
@ -6517,12 +6721,19 @@ namespace IDE.ui
|
|||
continue;
|
||||
}
|
||||
|
||||
if ((wantsBuildEmits) && (resolveType != null))
|
||||
{
|
||||
// Not included in the build emit data - just show as a marker
|
||||
emitData.mStartLine = 0;
|
||||
emitData.mEndLine = 0;
|
||||
}
|
||||
|
||||
//Debug.WriteLine($" New emit AnchorIdx:{emitData.mAnchorIdx} AnchorId:{emitData.mAnchorId} CurTextVersion:{textVersion} FoundTextVersion:{foundTextVersion}");
|
||||
data.mEmitData.Add(emitData);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (resolveType == .None)
|
||||
if ((resolveType == null) || (resolveType == .None))
|
||||
continue;
|
||||
|
||||
CollapseData collapseData;
|
||||
|
@ -6554,7 +6765,11 @@ namespace IDE.ui
|
|||
|
||||
for (var emitData in ref data.mEmitData)
|
||||
{
|
||||
if (((emitData.mOnlyInResolveAll) && (!emitData.mIncludedInResolveAll)) ||
|
||||
if ((emitData.mIncludedInBuild) && (gApp.mSettings.mEditorSettings.mEmitCompiler == .Build))
|
||||
{
|
||||
// Allow build-only markers to survive
|
||||
}
|
||||
else if (((emitData.mOnlyInResolveAll) && (!emitData.mIncludedInResolveAll)) ||
|
||||
((!emitData.mOnlyInResolveAll) && (!emitData.mIncludedInClassify)))
|
||||
{
|
||||
@emitData.RemoveFast();
|
||||
|
|
|
@ -367,6 +367,7 @@ namespace IDE.ui
|
|||
class QueuedCollapseData
|
||||
{
|
||||
public String mData = new .() ~ delete _;
|
||||
public String mBuildData ~ delete _;
|
||||
public int32 mTextVersion;
|
||||
public IdSpan mCharIdSpan ~ _.Dispose();
|
||||
public ResolveType mResolveType;
|
||||
|
@ -446,6 +447,7 @@ namespace IDE.ui
|
|||
int32 mTicksSinceTextChanged;
|
||||
int32 mErrorLookupTextIdx = -1;
|
||||
LinePointerDrawData mLinePointerDrawData;
|
||||
bool mIsDraggingLinePointer;
|
||||
Point? mMousePos;
|
||||
#if IDE_C_SUPPORT
|
||||
public String mClangHoverErrorData ~ delete mClangHoverErrorData;
|
||||
|
@ -1262,6 +1264,9 @@ namespace IDE.ui
|
|||
|
||||
void FindEmbeds(ResolveParams resolveParams)
|
||||
{
|
||||
if (gApp.mSettings.mEditorSettings.mEmitCompiler != .Resolve)
|
||||
return;
|
||||
|
||||
HashSet<FileEditData> foundEditData = scope .();
|
||||
Dictionary<String, String> remappedTypeNames = scope .();
|
||||
|
||||
|
@ -1478,11 +1483,31 @@ namespace IDE.ui
|
|||
|
||||
var collapseData = bfCompiler.GetCollapseRegions(parser, resolvePassData, explicitEmitTypeNames, .. scope .());
|
||||
|
||||
String buildCollapseData = null;
|
||||
if ((gApp.mSettings.mEditorSettings.mEmitCompiler == .Build) && (!gApp.mBfBuildCompiler.IsPerformingBackgroundOperation()))
|
||||
{
|
||||
gApp.mBfBuildSystem.Lock(0);
|
||||
var buildParser = gApp.mBfBuildSystem.GetParser(mProjectSource);
|
||||
if (buildParser != null)
|
||||
{
|
||||
var buildResolvePassData = buildParser.CreateResolvePassData(.None);
|
||||
defer delete buildResolvePassData;
|
||||
buildCollapseData = gApp.mBfBuildCompiler.GetCollapseRegions(buildParser, buildResolvePassData, explicitEmitTypeNames, .. scope:: .());
|
||||
}
|
||||
else
|
||||
{
|
||||
buildCollapseData = "";
|
||||
}
|
||||
gApp.mBfBuildSystem.Unlock();
|
||||
}
|
||||
|
||||
using (mMonitor.Enter())
|
||||
{
|
||||
DeleteAndNullify!(mQueuedCollapseData);
|
||||
mQueuedCollapseData = new .();
|
||||
mQueuedCollapseData.mData.Set(collapseData);
|
||||
if (buildCollapseData != null)
|
||||
mQueuedCollapseData.mBuildData = new String(buildCollapseData);
|
||||
mQueuedCollapseData.mTextVersion = textVersion;
|
||||
mQueuedCollapseData.mCharIdSpan = charIdSpan.Duplicate();
|
||||
|
||||
|
@ -1524,13 +1549,13 @@ namespace IDE.ui
|
|||
return;
|
||||
//var compiler = ResolveCompiler;
|
||||
|
||||
var char8Data = mEditWidget.Content.mData.mText;
|
||||
int char8Len = Math.Min(char8Data.Count, mEditWidget.Content.mData.mTextLength);
|
||||
var charData = mEditWidget.Content.mData.mText;
|
||||
int charLen = Math.Min(charData.Count, mEditWidget.Content.mData.mTextLength);
|
||||
|
||||
char8[] chars = new char8[char8Len];
|
||||
char8[] chars = new char8[charLen];
|
||||
defer delete chars;
|
||||
for (int32 i = 0; i < char8Len; i++)
|
||||
chars[i] = (char8)char8Data[i].mChar;
|
||||
for (int32 i = 0; i < charLen; i++)
|
||||
chars[i] = (char8)charData[i].mChar;
|
||||
|
||||
String text = scope String();
|
||||
text.Append(chars, 0, chars.Count);
|
||||
|
@ -1554,7 +1579,7 @@ namespace IDE.ui
|
|||
parser.SetEmbedKind(mEmbedKind);
|
||||
parser.Reduce(passInstance);
|
||||
}
|
||||
parser.ClassifySource(char8Data, !mIsBeefSource);
|
||||
parser.ClassifySource(charData, !mIsBeefSource);
|
||||
mWantsParserCleanup = true;
|
||||
}
|
||||
|
||||
|
@ -2208,7 +2233,7 @@ namespace IDE.ui
|
|||
{
|
||||
parser.CreateClassifier(passInstance, resolvePassData, charData);
|
||||
|
||||
if (resolveParams != null)
|
||||
if ((resolveParams != null) && (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve))
|
||||
{
|
||||
for (var emitEmbedData in resolveParams.mEmitEmbeds)
|
||||
{
|
||||
|
@ -2484,7 +2509,10 @@ namespace IDE.ui
|
|||
int32 prevLine = mEditWidget.Content.CursorLineAndColumn.mLine;
|
||||
|
||||
mEditWidget.Content.mSelection = null;
|
||||
mEditWidget.Content.CursorTextPos = cursorIdx;
|
||||
|
||||
int wantCursorPos = Math.Min(mEditWidget.Content.mData.mTextLength - 1, cursorIdx);
|
||||
if (wantCursorPos >= 0)
|
||||
mEditWidget.Content.CursorTextPos = wantCursorPos;
|
||||
mEditWidget.Content.CursorMoved();
|
||||
mEditWidget.Content.EnsureCursorVisible(true, true);
|
||||
mEditWidget.Content.mCursorImplicitlyMoved = true;
|
||||
|
@ -4476,6 +4504,8 @@ namespace IDE.ui
|
|||
BreakpointCountMask = 0x7F,
|
||||
Boomkmark = 0x80
|
||||
}
|
||||
|
||||
static float sDrawLeftAdjust = GS!(12);
|
||||
|
||||
public override void Draw(Graphics g)
|
||||
{
|
||||
|
@ -4505,7 +4535,6 @@ namespace IDE.ui
|
|||
using (g.PushTranslate(0, mEditWidget.mY + mEditWidget.Content.Y + GS!(2)))
|
||||
{
|
||||
float editX = GetEditX();
|
||||
float leftAdjust = GS!(12);
|
||||
|
||||
float lineSpacing = ewc.mFont.GetLineSpacing();
|
||||
int cursorLineNumber = mEditWidget.mEditWidgetContent.CursorLineAndColumn.mLine;
|
||||
|
@ -4623,7 +4652,7 @@ namespace IDE.ui
|
|||
int breakpointCount = (.)(curLineFlags & .BreakpointCountMask);
|
||||
curLineFlags++;
|
||||
|
||||
float iconX = Math.Max(GS!(-2), mEditWidget.mX - GS!(24) - leftAdjust) + breakpointCount*-GS!(2);
|
||||
float iconX = Math.Max(GS!(-2), mEditWidget.mX - GS!(24) - sDrawLeftAdjust) + breakpointCount*-GS!(2);
|
||||
float iconY = 0 + ewc.mLineCoords[drawLineNum] + (lineSpacing - DarkTheme.sUnitSize + GS!(5)) / 2;
|
||||
|
||||
// Just leave last digit visible
|
||||
|
@ -4648,7 +4677,7 @@ namespace IDE.ui
|
|||
continue;
|
||||
//hadLineIcon[drawLineNum - lineStart] = true;
|
||||
Image image = DarkTheme.sDarkTheme.GetImage(bookmark.mIsDisabled ? .IconBookmarkDisabled : .IconBookmark);
|
||||
g.Draw(image, Math.Max(GS!(-5), mEditWidget.mX - GS!(30) - leftAdjust),
|
||||
g.Draw(image, Math.Max(GS!(-5), mEditWidget.mX - GS!(30) - sDrawLeftAdjust),
|
||||
0 + bookmark.mLineNum * lineSpacing);
|
||||
|
||||
var curLineFlags = ref lineFlags[drawLineNum - lineStart];
|
||||
|
@ -4812,9 +4841,20 @@ namespace IDE.ui
|
|||
{
|
||||
mLinePointerDrawData.mUpdateCnt = gApp.mUpdateCnt;
|
||||
mLinePointerDrawData.mDebuggerContinueIdx = gApp.mDebuggerContinueIdx;
|
||||
g.Draw(img, mEditWidget.mX - GS!(20) - leftAdjust,
|
||||
g.Draw(img, mEditWidget.mX - GS!(20) - sDrawLeftAdjust,
|
||||
0 + ewc.GetLineY(lineNum, 0));
|
||||
}
|
||||
|
||||
if (mMousePos != null && mIsDraggingLinePointer)
|
||||
{
|
||||
int dragLineNum = GetLineAt(0, mMousePos.Value.y);
|
||||
if (dragLineNum >= 0 && dragLineNum != lineNum)
|
||||
{
|
||||
using (g.PushColor(0x7FFFFFFF))
|
||||
g.Draw(img, mEditWidget.mX - GS!(20) - sDrawLeftAdjust,
|
||||
0 + ewc.GetLineY(dragLineNum, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6275,15 +6315,15 @@ namespace IDE.ui
|
|||
emitEmbedView.mGenericMethodCombo?.mEditWidget.SetFocus();
|
||||
}
|
||||
|
||||
var sourceViewPanel = emitEmbedView.mSourceViewPanel;
|
||||
var firstSourceViewPanel = emitEmbedView.mSourceViewPanel;
|
||||
|
||||
var embedEWC = sourceViewPanel.mEditWidget.mEditWidgetContent;
|
||||
var firstEmbedEWC = firstSourceViewPanel.mEditWidget.mEditWidgetContent;
|
||||
|
||||
var prevCursorLineAndColumn = embedEWC.CursorLineAndColumn;
|
||||
var prevCursorLineAndColumn = firstEmbedEWC.CursorLineAndColumn;
|
||||
|
||||
var editData = sourceViewPanel.mEditWidget.mEditWidgetContent.mData;
|
||||
var editData = firstSourceViewPanel.mEditWidget.mEditWidgetContent.mData;
|
||||
if (editData.mTextLength == 0)
|
||||
DeleteAndNullify!(sourceViewPanel.mTrackedTextElementViewList);
|
||||
DeleteAndNullify!(firstSourceViewPanel.mTrackedTextElementViewList);
|
||||
|
||||
delete editData.mText;
|
||||
editData.mText = embed.mCharData;
|
||||
|
@ -6294,15 +6334,23 @@ namespace IDE.ui
|
|||
editData.mNextCharId = 0;
|
||||
editData.mTextIdData.Insert(0, editData.mTextLength, ref editData.mNextCharId);
|
||||
|
||||
sourceViewPanel.mEditWidget.mEditWidgetContent.ContentChanged();
|
||||
// We have a full classify now, FastClassify will just mess it up
|
||||
sourceViewPanel.mSkipFastClassify = true;
|
||||
firstSourceViewPanel.mEmitRevision = embed.mRevision;
|
||||
firstSourceViewPanel.InjectErrors(resolveResult.mPassInstance, editData.mText, editData.mTextIdData, false, true);
|
||||
|
||||
if (prevCursorLineAndColumn.mLine >= embedEWC.GetLineCount())
|
||||
embedEWC.CursorLineAndColumn = .(embedEWC.GetLineCount() - 1, prevCursorLineAndColumn.mColumn);
|
||||
|
||||
sourceViewPanel.mEmitRevision = embed.mRevision;
|
||||
sourceViewPanel.InjectErrors(resolveResult.mPassInstance, editData.mText, editData.mTextIdData, false, true);
|
||||
for (var user in editData.mUsers)
|
||||
{
|
||||
if (var embedEWC = user as SourceEditWidgetContent)
|
||||
{
|
||||
var sourceViewPanel = embedEWC.mSourceViewPanel;
|
||||
|
||||
sourceViewPanel.mEditWidget.mEditWidgetContent.ContentChanged();
|
||||
// We have a full classify now, FastClassify will just mess it up
|
||||
sourceViewPanel.mSkipFastClassify = true;
|
||||
|
||||
if (prevCursorLineAndColumn.mLine >= firstEmbedEWC.GetLineCount())
|
||||
embedEWC.CursorLineAndColumn = .(firstEmbedEWC.GetLineCount() - 1, prevCursorLineAndColumn.mColumn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6595,7 +6643,7 @@ namespace IDE.ui
|
|||
}
|
||||
if ((mTicksSinceTextChanged >= 60) && (mWantsSpellCheck))
|
||||
{
|
||||
if (IsControllingEditData())
|
||||
if ((IsControllingEditData()) && (mEmbedKind == .None))
|
||||
StartSpellCheck();
|
||||
mWantsSpellCheck = false;
|
||||
}
|
||||
|
@ -6850,7 +6898,59 @@ namespace IDE.ui
|
|||
using (mMonitor.Enter())
|
||||
{
|
||||
if (mQueuedCollapseData != null)
|
||||
{
|
||||
if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Build)
|
||||
{
|
||||
if (mQueuedCollapseData.mBuildData != null)
|
||||
{
|
||||
bool foundData = false;
|
||||
|
||||
using (gApp.mMonitor.Enter())
|
||||
{
|
||||
var projectSourceCompileInstance = gApp.mWorkspace.GetProjectSourceCompileInstance(projectSource, gApp.mWorkspace.HotCompileIdx);
|
||||
if (projectSourceCompileInstance != null)
|
||||
{
|
||||
foundData = true;
|
||||
ewc.ParseCollapseRegions(mQueuedCollapseData.mBuildData, mQueuedCollapseData.mTextVersion, ref projectSourceCompileInstance.mSourceCharIdData, null);
|
||||
|
||||
HashSet<EditWidgetContent.Data> dataLoaded = scope .();
|
||||
|
||||
for (var embed in ewc.mEmbeds.Values)
|
||||
{
|
||||
if (var emitEmbed = embed as SourceEditWidgetContent.EmitEmbed)
|
||||
{
|
||||
if (emitEmbed.mView != null)
|
||||
{
|
||||
if (dataLoaded.Add(emitEmbed.mView.mSourceViewPanel.mEditWidget.mEditWidgetContent.mData))
|
||||
{
|
||||
emitEmbed.mView.mSourceViewPanel.mSkipFastClassify = false;
|
||||
emitEmbed.mView.mSourceViewPanel.Reload();
|
||||
emitEmbed.mView.mSourceViewPanel.mWantsFastClassify = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundData)
|
||||
{
|
||||
for (var embed in ewc.mEmbeds.Values)
|
||||
{
|
||||
if (var emitEmbed = embed as SourceEditWidgetContent.EmitEmbed)
|
||||
{
|
||||
if (emitEmbed.mView != null)
|
||||
{
|
||||
emitEmbed.mView.mSourceViewPanel.mEditWidget.mEditWidgetContent.ClearText();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ewc.ParseCollapseRegions(mQueuedCollapseData.mData, mQueuedCollapseData.mTextVersion, ref mQueuedCollapseData.mCharIdSpan, mQueuedCollapseData.mResolveType);
|
||||
}
|
||||
DeleteAndNullify!(mQueuedCollapseData);
|
||||
}
|
||||
|
||||
|
@ -6858,6 +6958,38 @@ namespace IDE.ui
|
|||
|
||||
// Process after mQueuedCollapseData so mCharIdSpan is still valid
|
||||
ProcessDeferredResolveResults(0);
|
||||
|
||||
#if !CLI
|
||||
if (ewc.mCollapseDBDirty)
|
||||
{
|
||||
MemoryStream memStream = scope .();
|
||||
|
||||
String text = scope .();
|
||||
mEditWidget.GetText(text);
|
||||
var hash = MD5.Hash(.((uint8*)text.Ptr, text.Length));
|
||||
memStream.Write(hash);
|
||||
|
||||
bool hadData = false;
|
||||
|
||||
for (var kv in ewc.mOrderedCollapseEntries)
|
||||
{
|
||||
if (kv.mIsOpen != kv.DefaultOpen)
|
||||
{
|
||||
hadData = true;
|
||||
memStream.Write(kv.mAnchorIdx);
|
||||
}
|
||||
}
|
||||
|
||||
String filePath = scope .(mFilePath);
|
||||
IDEUtils.MakeComparableFilePath(filePath);
|
||||
|
||||
if (!hadData)
|
||||
gApp.mFileRecovery.DeleteDB(filePath);
|
||||
else
|
||||
gApp.mFileRecovery.SetDB(filePath, memStream.Memory);
|
||||
ewc.mCollapseDBDirty = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void UpdateF(float updatePct)
|
||||
|
@ -7070,7 +7202,7 @@ namespace IDE.ui
|
|||
|
||||
float GetEditX()
|
||||
{
|
||||
if (!gApp.mSettings.mEditorSettings.mShowLineNumbers && (mEmbedKind == .None))
|
||||
if ((!gApp.mSettings.mEditorSettings.mShowLineNumbers) || (mEmbedKind != .None))
|
||||
return GS!(24);
|
||||
|
||||
var font = IDEApp.sApp.mTinyCodeFont;
|
||||
|
@ -7268,6 +7400,29 @@ namespace IDE.ui
|
|||
}
|
||||
}
|
||||
|
||||
public override void MouseUp(float x, float y, int32 btn)
|
||||
{
|
||||
base.MouseUp(x, y, btn);
|
||||
|
||||
if (mIsDraggingLinePointer)
|
||||
{
|
||||
mIsDraggingLinePointer = false;
|
||||
|
||||
float origX;
|
||||
float origY;
|
||||
RootToSelfTranslate(mWidgetWindow.mMouseDownX, mWidgetWindow.mMouseDownY, out origX, out origY);
|
||||
|
||||
int newLine = GetLineAt(0, y);
|
||||
if (newLine >= 0 && newLine != GetLineAt(origX, origY))
|
||||
{
|
||||
gApp.mDebugger.SetNextStatement(false, mFilePath, (int)newLine, 0);
|
||||
|
||||
gApp.[Friend]PCChanged();
|
||||
gApp.[Friend]DebuggerUnpaused();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int GetLineAt(float x, float y)
|
||||
{
|
||||
if (x > mEditWidget.mX - GS!(4))
|
||||
|
@ -7321,8 +7476,9 @@ namespace IDE.ui
|
|||
{
|
||||
if ((x >= GS!(3)) && (x < mEditWidget.mX - GS!(14)))
|
||||
{
|
||||
int lineMouseDown = GetLineAt(origX, origY);
|
||||
int lineClick = GetLineAt(x, y);
|
||||
if (lineClick >= 0)
|
||||
if (lineClick >= 0 && lineMouseDown == lineClick)
|
||||
{
|
||||
ToggleBreakpointAt(lineClick, 0);
|
||||
}
|
||||
|
@ -7351,6 +7507,37 @@ namespace IDE.ui
|
|||
{
|
||||
base.MouseMove(x, y);
|
||||
mMousePos = .(x, y);
|
||||
|
||||
if (!mIsDraggingLinePointer && IDEApp.sApp.mExecutionPaused && gApp.mDebugger.mActiveCallStackIdx == 0 && mMouseFlags.HasFlag(.Left))
|
||||
{
|
||||
SourceEditWidgetContent ewc = (.)mEditWidget.Content;
|
||||
Rect linePointerRect = .(
|
||||
mEditWidget.mX - GS!(20) - sDrawLeftAdjust,
|
||||
0 + ewc.GetLineY(mLinePointerDrawData.mLine, 0),
|
||||
GS!(15),
|
||||
GS!(15)
|
||||
);
|
||||
|
||||
float origX;
|
||||
float origY;
|
||||
RootToSelfTranslate(mWidgetWindow.mMouseDownX, mWidgetWindow.mMouseDownY, out origX, out origY);
|
||||
|
||||
if (linePointerRect.Contains(origX, origY - mEditWidget.mY - mEditWidget.Content.Y - GS!(3)))
|
||||
{
|
||||
mIsDraggingLinePointer = true;
|
||||
}
|
||||
}
|
||||
else if (mIsDraggingLinePointer)
|
||||
{
|
||||
SourceEditWidgetContent ewc = (.)mEditWidget.Content;
|
||||
float linePos = ewc.GetLineY(GetLineAt(0, mMousePos.Value.y), 0);
|
||||
Rect visibleRange = mEditWidget.GetVisibleContentRange();
|
||||
|
||||
if (visibleRange.Top > linePos)
|
||||
mEditWidget.mVertScrollbar.ScrollTo(linePos);
|
||||
else if (visibleRange.Bottom - mEditWidget.mHorzScrollbar.mHeight < linePos)
|
||||
mEditWidget.mVertScrollbar.ScrollTo(linePos - visibleRange.mHeight + ewc.GetLineHeight(0));
|
||||
}
|
||||
}
|
||||
|
||||
public override void DrawAll(Graphics g)
|
||||
|
|
|
@ -384,6 +384,8 @@ namespace IDE.ui
|
|||
|
||||
protected void ConfigDeleted(String configName)
|
||||
{
|
||||
int32 category = mPropPage.mCategoryType;
|
||||
|
||||
bool currentChanged = false;
|
||||
int idx = mConfigNames.IndexOf(configName);
|
||||
if (idx != -1)
|
||||
|
@ -422,7 +424,17 @@ namespace IDE.ui
|
|||
}
|
||||
|
||||
if (currentChanged)
|
||||
SelectConfig(mConfigNames);
|
||||
{
|
||||
mPropPage = null;
|
||||
SelectConfig(mConfigNames, category);
|
||||
}
|
||||
|
||||
if ((mActiveConfigName == configName) && (!mConfigNames.IsEmpty))
|
||||
{
|
||||
var newConfigName = mConfigNames[0];
|
||||
gApp.mMainFrame.mStatusBar.SelectConfig(newConfigName);
|
||||
mActiveConfigName.Set(newConfigName);
|
||||
}
|
||||
}
|
||||
|
||||
protected void ConfigRenamed(String from, String to)
|
||||
|
@ -761,7 +773,7 @@ namespace IDE.ui
|
|||
ShowPropPage(categoryType);
|
||||
}
|
||||
|
||||
protected void SelectConfig(List<String> configNames)
|
||||
protected void SelectConfig(List<String> configNames, int32 category = -1)
|
||||
{
|
||||
if (configNames != mConfigNames)
|
||||
{
|
||||
|
@ -770,7 +782,7 @@ namespace IDE.ui
|
|||
mConfigNames.Add(configName);
|
||||
}
|
||||
if (mConfigNames.Count == 1)
|
||||
SelectConfig(mConfigNames[0]);
|
||||
SelectConfig(mConfigNames[0], category);
|
||||
else
|
||||
{
|
||||
mConfigComboBox.Label = "<Multiple>";
|
||||
|
@ -795,13 +807,16 @@ namespace IDE.ui
|
|||
}
|
||||
}
|
||||
|
||||
protected void SelectConfig(String configName)
|
||||
protected void SelectConfig(String configName, int32 category = -1)
|
||||
{
|
||||
var category;
|
||||
if (category == -1)
|
||||
category = mPropPage.mCategoryType;
|
||||
var newConfigName = new String(configName);
|
||||
ClearAndDeleteItems(mConfigNames);
|
||||
mConfigNames.Add(newConfigName);
|
||||
mConfigComboBox.Label = newConfigName;
|
||||
ShowPropPage(mPropPage.mCategoryType);
|
||||
ShowPropPage(category);
|
||||
}
|
||||
|
||||
protected void SelectPlatform(String platformName, int32 category = -1)
|
||||
|
|
|
@ -2752,20 +2752,29 @@ namespace IDE.ui
|
|||
}
|
||||
else if (memberVals0 == ":addrs")
|
||||
{
|
||||
WatchListViewItem memberItem = (WatchListViewItem)listViewItem.GetChildAtIndex(memberCount - 1);
|
||||
String.NewOrSet!(memberItem.mWatchSeriesInfo.mAddrs, memberVals[1]);
|
||||
memberItem.mWatchSeriesInfo.mAddrsEntrySize = 1;
|
||||
if (memberCount > 0)
|
||||
{
|
||||
WatchListViewItem memberItem = (WatchListViewItem)listViewItem.GetChildAtIndex(memberCount - 1);
|
||||
String.NewOrSet!(memberItem.mWatchSeriesInfo.mAddrs, memberVals[1]);
|
||||
memberItem.mWatchSeriesInfo.mAddrsEntrySize = 1;
|
||||
}
|
||||
}
|
||||
else if (memberVals0 == ":addrsEntrySize")
|
||||
{
|
||||
int32 addrsEntrySize = int32.Parse(scope String(memberVals[1]));
|
||||
WatchListViewItem memberItem = (WatchListViewItem)listViewItem.GetChildAtIndex(memberCount - 1);
|
||||
memberItem.mWatchSeriesInfo.mAddrsEntrySize = addrsEntrySize;
|
||||
if (memberCount > 0)
|
||||
{
|
||||
int32 addrsEntrySize = int32.Parse(scope String(memberVals[1]));
|
||||
WatchListViewItem memberItem = (WatchListViewItem)listViewItem.GetChildAtIndex(memberCount - 1);
|
||||
memberItem.mWatchSeriesInfo.mAddrsEntrySize = addrsEntrySize;
|
||||
}
|
||||
}
|
||||
else if (memberVals0 == ":continuation")
|
||||
{
|
||||
WatchListViewItem memberItem = (WatchListViewItem)listViewItem.GetChildAtIndex(memberCount - 1);
|
||||
String.NewOrSet!(memberItem.mWatchSeriesInfo.mContinuationData, memberVals[1]);
|
||||
if (memberCount > 0)
|
||||
{
|
||||
WatchListViewItem memberItem = (WatchListViewItem)listViewItem.GetChildAtIndex(memberCount - 1);
|
||||
String.NewOrSet!(memberItem.mWatchSeriesInfo.mContinuationData, memberVals[1]);
|
||||
}
|
||||
}
|
||||
else if (memberVals0 == ":action")
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue