mirror of https://github.com/buggins/dlangide.git
Debugger UI
This commit is contained in:
parent
33b1c744c8
commit
a10427631c
|
@ -68,15 +68,30 @@ DebugLocation parseFrame(MIValue frame) {
|
|||
if (!frame)
|
||||
return null;
|
||||
DebugLocation location = new DebugLocation();
|
||||
location.file = baseName(frame.getString("file"));
|
||||
location.projectFilePath = frame.getString("file");
|
||||
location.fullFilePath = frame.getString("fullname");
|
||||
location.file = baseName(toNativeDelimiters(frame.getString("file")));
|
||||
location.projectFilePath = toNativeDelimiters(frame.getString("file"));
|
||||
location.fullFilePath = toNativeDelimiters(frame.getString("fullname"));
|
||||
location.line = frame.getInt("line");
|
||||
location.func = frame.getString("func");
|
||||
location.address = frame.getUlong("addr");
|
||||
return location;
|
||||
}
|
||||
|
||||
string toNativeDelimiters(string s) {
|
||||
version(Windows) {
|
||||
char[] buf;
|
||||
foreach(ch; s) {
|
||||
if (ch == '/')
|
||||
buf ~= '\\';
|
||||
else
|
||||
buf ~= ch;
|
||||
}
|
||||
return buf.dup;
|
||||
} else {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
string parseIdent(ref string s) {
|
||||
string res = null;
|
||||
int len = 0;
|
||||
|
@ -273,7 +288,7 @@ MIValue parseMIValue(ref MIToken[] tokens) {
|
|||
}
|
||||
|
||||
private MIValue[] parseMIList(ref MIToken[] tokens, MITokenType closingToken = MITokenType.eol) {
|
||||
Log.v("parseMIList: " ~ tokens.dumpTokens);
|
||||
//Log.v("parseMIList: " ~ tokens.dumpTokens);
|
||||
MIValue[] res;
|
||||
if (!tokens.length)
|
||||
return res;
|
||||
|
|
|
@ -2,8 +2,11 @@ module dlangide.ui.debuggerui;
|
|||
|
||||
import dlangui.core.logger;
|
||||
import dlangui.core.events;
|
||||
import dlangide.workspace.project;
|
||||
import dlangide.workspace.workspace;
|
||||
import dlangide.ui.frame;
|
||||
import dlangide.ui.commands;
|
||||
import dlangide.ui.dsourceedit;
|
||||
import ddebug.common.execution;
|
||||
import ddebug.common.debugger;
|
||||
|
||||
|
@ -44,18 +47,39 @@ class DebuggerUIHandler : DebuggerCallback {
|
|||
_debugger.execStart();
|
||||
}
|
||||
|
||||
void updateLocation(DebugLocation location) {
|
||||
_location = location;
|
||||
ProjectSourceFile sourceFile = currentWorkspace.findSourceFile(location.projectFilePath, location.fullFilePath);
|
||||
if (sourceFile) {
|
||||
_ide.openSourceFile(sourceFile.filename, sourceFile, true);
|
||||
} else {
|
||||
_ide.openSourceFile(location.fullFilePath, null, true);
|
||||
}
|
||||
DSourceEdit[] editors = _ide.allOpenedEditors;
|
||||
foreach(ed; editors) {
|
||||
if (ed.projectSourceFile is sourceFile)
|
||||
ed.executionLine = location.line - 1;
|
||||
else
|
||||
ed.executionLine = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// state changed: running / paused / stopped
|
||||
void onDebugState(DebuggingState state, StateChangeReason reason, DebugLocation location, Breakpoint bp) {
|
||||
Log.d("onDebugState: ", state, " reason=", reason);
|
||||
_state = state;
|
||||
if (state == DebuggingState.stopped) {
|
||||
_ide.logPanel.logLine("Program is stopped");
|
||||
_ide.statusLine.setStatusText("Stopped"d);
|
||||
_debugger.stop();
|
||||
} else if (state == DebuggingState.running) {
|
||||
_ide.logPanel.logLine("Program is started");
|
||||
_ide.statusLine.setStatusText("Running"d);
|
||||
_ide.window.update();
|
||||
} else if (state == DebuggingState.paused) {
|
||||
_location = location;
|
||||
updateLocation(location);
|
||||
_ide.logPanel.logLine("Program is paused.");
|
||||
_ide.statusLine.setStatusText("Paused"d);
|
||||
_ide.window.update();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ module dlangide.ui.dsourceedit;
|
|||
|
||||
import dlangui.core.logger;
|
||||
import dlangui.core.signals;
|
||||
import dlangui.graphics.drawbuf;
|
||||
import dlangui.widgets.editors;
|
||||
import dlangui.widgets.srcedit;
|
||||
import dlangui.widgets.menu;
|
||||
|
@ -123,6 +124,24 @@ class DSourceEdit : SourceEdit, EditableContentMarksChangeListener {
|
|||
return menu;
|
||||
}
|
||||
|
||||
uint _executionLineHighlightColor = 0x808080FF;
|
||||
int _executionLine = -1;
|
||||
@property int executionLine() { return _executionLine; }
|
||||
@property void executionLine(int line) {
|
||||
if (line == _executionLine)
|
||||
return;
|
||||
_executionLine = line;
|
||||
if (_executionLine >= 0) {
|
||||
setCaretPos(_executionLine, 0, true);
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
/// override to custom highlight of line background
|
||||
override protected void drawLineBackground(DrawBuf buf, int lineIndex, Rect lineRect, Rect visibleRect) {
|
||||
if (lineIndex == _executionLine) {
|
||||
buf.fillRect(visibleRect, _executionLineHighlightColor);
|
||||
}
|
||||
}
|
||||
|
||||
void setSyntaxSupport() {
|
||||
if (isDSourceFile) {
|
||||
|
|
|
@ -411,6 +411,18 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
|
|||
}
|
||||
}
|
||||
|
||||
/// returns array of all opened source editors
|
||||
DSourceEdit[] allOpenedEditors() {
|
||||
DSourceEdit[] res;
|
||||
for (int i = _tabs.tabCount - 1; i >= 0; i--) {
|
||||
DSourceEdit ed = cast(DSourceEdit)_tabs.tabBody(i);
|
||||
if (ed) {
|
||||
res ~= ed;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/// close editor tabs for which files are removed from filesystem
|
||||
void closeRemovedDocuments() {
|
||||
import std.file;
|
||||
|
|
|
@ -82,6 +82,14 @@ class ProjectItem {
|
|||
|
||||
void refresh() {
|
||||
}
|
||||
|
||||
ProjectSourceFile findSourceFile(string projectFileName, string fullFileName) {
|
||||
if (fullFileName.equal(_filename))
|
||||
return cast(ProjectSourceFile)this;
|
||||
if (project && projectFileName.equal(project.absoluteToRelativePath(_filename)))
|
||||
return cast(ProjectSourceFile)this;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Project folder
|
||||
|
@ -122,6 +130,14 @@ class ProjectFolder : ProjectItem {
|
|||
return null;
|
||||
}
|
||||
|
||||
override ProjectSourceFile findSourceFile(string projectFileName, string fullFileName) {
|
||||
for (int i = 0; i < _children.count; i++) {
|
||||
if (ProjectSourceFile res = _children[i].findSourceFile(projectFileName, fullFileName))
|
||||
return res;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
bool loadDir(string path) {
|
||||
string src = relativeToAbsolutePath(path);
|
||||
if (exists(src) && isDir(src)) {
|
||||
|
@ -419,6 +435,10 @@ class Project : WorkspaceItem {
|
|||
return _builderSourcePaths;
|
||||
}
|
||||
|
||||
ProjectSourceFile findSourceFile(string projectFileName, string fullFileName) {
|
||||
return _items ? _items.findSourceFile(projectFileName, fullFileName) : null;
|
||||
}
|
||||
|
||||
private static void addUnique(ref string[] dst, string[] items) {
|
||||
foreach(item; items) {
|
||||
bool found = false;
|
||||
|
|
|
@ -65,6 +65,15 @@ class Workspace : WorkspaceItem {
|
|||
_frame = frame;
|
||||
}
|
||||
|
||||
ProjectSourceFile findSourceFile(string projectFileName, string fullFileName) {
|
||||
foreach(p; _projects) {
|
||||
ProjectSourceFile res = p.findSourceFile(projectFileName, fullFileName);
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@property Project[] projects() {
|
||||
return _projects;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue