diff --git a/src/ddebug/gdb/gdbmiparser.d b/src/ddebug/gdb/gdbmiparser.d index e0c2d9d..148c9b4 100644 --- a/src/ddebug/gdb/gdbmiparser.d +++ b/src/ddebug/gdb/gdbmiparser.d @@ -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; diff --git a/src/dlangide/ui/debuggerui.d b/src/dlangide/ui/debuggerui.d index 8b1e987..9251483 100644 --- a/src/dlangide/ui/debuggerui.d +++ b/src/dlangide/ui/debuggerui.d @@ -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(); } } diff --git a/src/dlangide/ui/dsourceedit.d b/src/dlangide/ui/dsourceedit.d index 99877c4..b880ac0 100644 --- a/src/dlangide/ui/dsourceedit.d +++ b/src/dlangide/ui/dsourceedit.d @@ -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) { diff --git a/src/dlangide/ui/frame.d b/src/dlangide/ui/frame.d index 7f8a365..3e616dd 100644 --- a/src/dlangide/ui/frame.d +++ b/src/dlangide/ui/frame.d @@ -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; diff --git a/src/dlangide/workspace/project.d b/src/dlangide/workspace/project.d index 3979bc8..c3f7ec0 100644 --- a/src/dlangide/workspace/project.d +++ b/src/dlangide/workspace/project.d @@ -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; diff --git a/src/dlangide/workspace/workspace.d b/src/dlangide/workspace/workspace.d index 9c6a773..4b765c7 100644 --- a/src/dlangide/workspace/workspace.d +++ b/src/dlangide/workspace/workspace.d @@ -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; }