mirror of https://github.com/buggins/dlangide.git
debugger support
This commit is contained in:
parent
d760fe671d
commit
33b1c744c8
|
@ -12,12 +12,27 @@ enum DebuggingState {
|
|||
stopped
|
||||
}
|
||||
|
||||
class Breakpoint {
|
||||
int id;
|
||||
enum StateChangeReason {
|
||||
unknown,
|
||||
breakpointHit,
|
||||
endSteppingRange,
|
||||
exited,
|
||||
}
|
||||
|
||||
class LocationBase {
|
||||
string file;
|
||||
string fullFilePath;
|
||||
string projectFilePath;
|
||||
int line;
|
||||
}
|
||||
|
||||
class DebugLocation : LocationBase {
|
||||
ulong address;
|
||||
string func;
|
||||
}
|
||||
|
||||
class Breakpoint : LocationBase {
|
||||
int id;
|
||||
bool enabled = true;
|
||||
string projectName;
|
||||
this() {
|
||||
|
@ -69,7 +84,7 @@ interface DebuggerCallback : ProgramExecutionStatusListener {
|
|||
void onProgramLoaded(bool successful, bool debugInfoLoaded);
|
||||
|
||||
/// state changed: running / paused / stopped
|
||||
void onDebugState(DebuggingState state, string msg, int param);
|
||||
void onDebugState(DebuggingState state, StateChangeReason reason, DebugLocation location, Breakpoint bp);
|
||||
|
||||
void onResponse(ResponseCode code, string msg);
|
||||
}
|
||||
|
@ -149,8 +164,8 @@ class DebuggerProxy : Debugger, DebuggerCallback {
|
|||
}
|
||||
|
||||
/// state changed: running / paused / stopped
|
||||
void onDebugState(DebuggingState state, string msg, int param) {
|
||||
_callbackDelegate( delegate() { _callback.onDebugState(state, msg, param); } );
|
||||
void onDebugState(DebuggingState state, StateChangeReason reason, DebugLocation location, Breakpoint bp) {
|
||||
_callbackDelegate( delegate() { _callback.onDebugState(state, reason, location, bp); } );
|
||||
}
|
||||
|
||||
void onResponse(ResponseCode code, string msg) {
|
||||
|
|
|
@ -295,6 +295,34 @@ class GDBInterface : ConsoleDebuggerInterface {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
private GDBBreakpoint findBreakpointByRequestToken(int token) {
|
||||
if (token == 0)
|
||||
return null;
|
||||
foreach(gdbbp; _breakpoints) {
|
||||
if (gdbbp.createRequestId == token)
|
||||
return gdbbp;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private GDBBreakpoint findBreakpointByNumber(string number) {
|
||||
if (number.empty)
|
||||
return null;
|
||||
foreach(gdbbp; _breakpoints) {
|
||||
if (gdbbp.number.equal(number))
|
||||
return gdbbp;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
void handleBreakpointRequestResult(GDBBreakpoint gdbbp, ResultClass resType, MIValue params) {
|
||||
if (resType == ResultClass.done) {
|
||||
if (MIValue bkpt = params["bkpt"]) {
|
||||
string number = bkpt.getString("number");
|
||||
gdbbp.number = number;
|
||||
Log.d("GDB number for breakpoint " ~ gdbbp.bp.id.to!string ~ " assigned is " ~ number);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addBreakpoint(Breakpoint bp) {
|
||||
GDBBreakpoint gdbbp = new GDBBreakpoint();
|
||||
gdbbp.bp = bp;
|
||||
|
@ -390,12 +418,30 @@ class GDBInterface : ConsoleDebuggerInterface {
|
|||
AsyncClass msgId = asyncByName(msgType);
|
||||
if (msgId == AsyncClass.other)
|
||||
Log.d("GDB WARN unknown async class type: ", msgType);
|
||||
Log.v("GDB async *[", token, "] ", msgType, " params: ", s);
|
||||
MIValue params = parseMI(s);
|
||||
if (!params) {
|
||||
Log.e("Failed to parse exec state params");
|
||||
return;
|
||||
}
|
||||
Log.v("GDB async *[", token, "] ", msgType, " params: ", params.toString);
|
||||
string reason = params.getString("reason");
|
||||
if (msgId == AsyncClass.running) {
|
||||
_callback.onDebugState(DebuggingState.running, s, 0);
|
||||
_callback.onDebugState(DebuggingState.running, StateChangeReason.unknown, null, null);
|
||||
} else if (msgId == AsyncClass.stopped) {
|
||||
|
||||
_callback.onDebugState(DebuggingState.stopped, s, 0);
|
||||
StateChangeReason reasonId = StateChangeReason.unknown;
|
||||
DebugLocation location = parseFrame(params["frame"]);
|
||||
string threadId = params.getString("thread-id");
|
||||
string stoppedThreads = params.getString("all");
|
||||
Breakpoint bp = null;
|
||||
if (reason.equal("end-stepping-range")) {
|
||||
_callback.onDebugState(DebuggingState.paused, StateChangeReason.endSteppingRange, location, bp);
|
||||
} else if (reason.equal("breakpoint-hit")) {
|
||||
if (GDBBreakpoint gdbbp = findBreakpointByNumber(params.getString("bkptno")))
|
||||
bp = gdbbp.bp;
|
||||
_callback.onDebugState(DebuggingState.paused, StateChangeReason.breakpointHit, location, bp);
|
||||
} else {
|
||||
_callback.onDebugState(DebuggingState.stopped, StateChangeReason.exited, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -419,12 +465,18 @@ class GDBInterface : ConsoleDebuggerInterface {
|
|||
|
||||
// ^resultClass,result
|
||||
void handleResultMessage(uint token, string s) {
|
||||
Log.v("GDB result ^[", token, "] ", s);
|
||||
string msgType = parseIdentAndSkipComma(s);
|
||||
ResultClass msgId = resultByName(msgType);
|
||||
if (msgId == ResultClass.other)
|
||||
Log.d("GDB WARN unknown result class type: ", msgType);
|
||||
MIValue params = parseMI(s);
|
||||
Log.v("GDB result ^[", token, "] ", msgType, " params: ", s);
|
||||
Log.v("GDB result ^[", token, "] ", msgType, " params: ", (params ? params.toString : "unparsed: " ~ s));
|
||||
if (GDBBreakpoint gdbbp = findBreakpointByRequestToken(token)) {
|
||||
// result of breakpoint creation operation
|
||||
handleBreakpointRequestResult(gdbbp, msgId, params);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool _firstIdle = true;
|
||||
|
|
|
@ -5,6 +5,7 @@ import std.utf;
|
|||
import std.conv : to;
|
||||
import std.array : empty;
|
||||
import std.algorithm : startsWith, equal;
|
||||
import ddebug.common.debugger;
|
||||
|
||||
/// result class
|
||||
enum ResultClass {
|
||||
|
@ -35,24 +36,47 @@ MIValue parseMI(string s) {
|
|||
string src = s;
|
||||
try {
|
||||
bool err = false;
|
||||
Log.e("Tokenizing MI output: " ~ src);
|
||||
//Log.e("Tokenizing MI output: " ~ src);
|
||||
MIToken[] tokens = tokenizeMI(s, err);
|
||||
if (err) {
|
||||
// tokenizer error
|
||||
Log.e("Cannot tokenize MI output `" ~ src ~ "`");
|
||||
return null;
|
||||
}
|
||||
Log.v("Parsing tokens " ~ tokens.dumpTokens);
|
||||
//Log.v("Parsing tokens " ~ tokens.dumpTokens);
|
||||
MIValue[] items = parseMIList(tokens);
|
||||
MIList res = new MIList(items);
|
||||
Log.d("Parse result:\n" ~ res.toString);
|
||||
return res;
|
||||
//Log.v("Found " ~ to!string(items.length) ~ " values in list");
|
||||
return new MIList(items);
|
||||
} catch (Exception e) {
|
||||
Log.e("Cannot parse MI output `" ~ src ~ "`", e.msg);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
frame = {
|
||||
addr = "0x00000000004015b2",
|
||||
func = "D main",
|
||||
args = [],
|
||||
file = "source\app.d",
|
||||
fullname = "D:\projects\d\dlangide\workspaces\helloworld\helloworld/source\app.d",
|
||||
line = "8"
|
||||
},
|
||||
*/
|
||||
DebugLocation parseFrame(MIValue frame) {
|
||||
import std.path;
|
||||
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.line = frame.getInt("line");
|
||||
location.func = frame.getString("func");
|
||||
location.address = frame.getUlong("addr");
|
||||
return location;
|
||||
}
|
||||
|
||||
string parseIdent(ref string s) {
|
||||
string res = null;
|
||||
int len = 0;
|
||||
|
@ -136,7 +160,7 @@ struct MIToken {
|
|||
}
|
||||
string toString() {
|
||||
//return type == MITokenType.str ? to!string(type) ~ ":\"" ~ str ~ "\"": to!string(type) ~ ":" ~ str;
|
||||
return (type == MITokenType.str) ? "\"" ~ str ~ "\"" : "`" ~ str ~ "`";
|
||||
return (type == MITokenType.str) ? "\"" ~ str ~ "\"" : str;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -248,13 +272,16 @@ MIValue parseMIValue(ref MIToken[] tokens) {
|
|||
throw new Exception("parseMIValue: unexpected token " ~ tokens[0].toString ~ " near " ~ srctokens.dumpTokens);
|
||||
}
|
||||
|
||||
MIValue[] parseMIList(ref MIToken[] tokens, MITokenType closingToken = MITokenType.eol) {
|
||||
private MIValue[] parseMIList(ref MIToken[] tokens, MITokenType closingToken = MITokenType.eol) {
|
||||
Log.v("parseMIList: " ~ tokens.dumpTokens);
|
||||
MIValue[] res;
|
||||
if (!tokens.length)
|
||||
return res;
|
||||
for (;;) {
|
||||
MITokenType tokenType = tokens.length > 0 ? tokens[0].type : MITokenType.eol;
|
||||
if (tokenType == closingToken) {
|
||||
tokens = tokens[1..$];
|
||||
if (tokenType != MITokenType.eol)
|
||||
tokens = tokens[1..$];
|
||||
return res;
|
||||
}
|
||||
if (tokenType == MITokenType.eol)
|
||||
|
@ -299,8 +326,43 @@ class MIValue {
|
|||
@property int length() { return 1; }
|
||||
MIValue opIndex(int index) { return null; }
|
||||
MIValue opIndex(string key) { return null; }
|
||||
|
||||
string getString(string name) {
|
||||
MIValue v = opIndex(name);
|
||||
if (!v)
|
||||
return null;
|
||||
return v.str;
|
||||
}
|
||||
|
||||
int getInt(string name, int defValue = 0) {
|
||||
MIValue v = opIndex(name);
|
||||
if (!v)
|
||||
return defValue;
|
||||
string s = v.str;
|
||||
if (s.empty)
|
||||
return defValue;
|
||||
return cast(int)decodeNumber(s, defValue);
|
||||
}
|
||||
|
||||
ulong getUlong(string name, ulong defValue = 0) {
|
||||
MIValue v = opIndex(name);
|
||||
if (!v)
|
||||
return defValue;
|
||||
string s = v.str;
|
||||
if (s.empty)
|
||||
return defValue;
|
||||
return decodeNumber(s, defValue);
|
||||
}
|
||||
|
||||
string getString(int index) {
|
||||
MIValue v = opIndex(index);
|
||||
if (!v)
|
||||
return null;
|
||||
return v.str;
|
||||
}
|
||||
|
||||
void dump(ref char[] buf, int level) {
|
||||
dumpLevel(buf, level);
|
||||
//dumpLevel(buf, level);
|
||||
buf ~= str;
|
||||
}
|
||||
override string toString() {
|
||||
|
@ -322,9 +384,9 @@ class MIKeyValue : MIValue {
|
|||
override @property string str() { return _key; }
|
||||
@property MIValue value() { return _value; }
|
||||
override void dump(ref char[] buf, int level) {
|
||||
dumpLevel(buf, level);
|
||||
//dumpLevel(buf, level);
|
||||
buf ~= _key;
|
||||
buf ~= "=";
|
||||
buf ~= " = ";
|
||||
if (!value)
|
||||
buf ~= "null";
|
||||
else
|
||||
|
@ -349,7 +411,7 @@ class MIString : MIValue {
|
|||
}
|
||||
override @property string str() { return _str; }
|
||||
override void dump(ref char[] buf, int level) {
|
||||
dumpLevel(buf, level);
|
||||
//dumpLevel(buf, level);
|
||||
buf ~= '\"';
|
||||
buf ~= str;
|
||||
buf ~= '\"';
|
||||
|
@ -391,12 +453,14 @@ class MIList : MIValue {
|
|||
if (length) {
|
||||
buf ~= "\n";
|
||||
for (int i = 0; i < length; i++) {
|
||||
dumpLevel(buf, level + 1);
|
||||
_items[i].dump(buf, level + 1);
|
||||
if (i < length - 1)
|
||||
buf ~= ",";
|
||||
buf ~= "\n";
|
||||
}
|
||||
buf ~= "\n";
|
||||
dumpLevel(buf, level);
|
||||
//buf ~= "\n";
|
||||
dumpLevel(buf, level - 1);
|
||||
}
|
||||
buf ~= (type == MIValueType.map) ? "}" : "]";
|
||||
}
|
||||
|
@ -507,3 +571,20 @@ private uint decodeHexDigit(T)(T ch) {
|
|||
return uint.max;
|
||||
}
|
||||
|
||||
private ulong decodeNumber(string s, ulong defValue) {
|
||||
if (s.empty)
|
||||
return defValue;
|
||||
if (s.length > 2 && s.startsWith("0x")) {
|
||||
s = s[2..$];
|
||||
ulong res = 0;
|
||||
foreach(ch; s) {
|
||||
uint digit = decodeHexDigit(ch);
|
||||
if (digit > 15)
|
||||
return defValue;
|
||||
res = res * 16 + digit;
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return to!ulong(s);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ enum IDEActions : int {
|
|||
ProjectSettings,
|
||||
|
||||
DebugStart,
|
||||
DebugRestart,
|
||||
DebugStartNoDebug,
|
||||
DebugContinue,
|
||||
DebugStop,
|
||||
|
@ -37,6 +38,9 @@ enum IDEActions : int {
|
|||
DebugToggleBreakpoint,
|
||||
DebugEnableBreakpoint,
|
||||
DebugDisableBreakpoint,
|
||||
DebugStepInto,
|
||||
DebugStepOver,
|
||||
DebugStepOut,
|
||||
|
||||
HelpAbout,
|
||||
WindowCloseAllDocuments,
|
||||
|
@ -88,11 +92,16 @@ const Action ACTION_PROJECT_SET_STARTUP = new Action(IDEActions.SetStartupProjec
|
|||
const Action ACTION_PROJECT_SETTINGS = (new Action(IDEActions.ProjectSettings, "MENU_PROJECT_SETTINGS"c, null)).disableByDefault();
|
||||
const Action ACTION_PROJECT_REFRESH = new Action(IDEActions.RefreshProject, "MENU_PROJECT_REFRESH"c);
|
||||
const Action ACTION_PROJECT_UPDATE_DEPENDENCIES = new Action(IDEActions.UpdateProjectDependencies, "MENU_PROJECT_UPDATE_DEPENDENCIES"c);
|
||||
const Action ACTION_DEBUG_START = new Action(IDEActions.DebugStart, "MENU_DEBUG_START_DEBUGGING"c, "debug-run"c, KeyCode.F5, 0);
|
||||
|
||||
const Action ACTION_DEBUG_START = new Action(IDEActions.DebugStart, "MENU_DEBUG_START_DEBUGGING"c, "debug-run"c, KeyCode.F5, KeyFlag.Control | KeyFlag.Shift);
|
||||
const Action ACTION_DEBUG_START_NO_DEBUG = new Action(IDEActions.DebugStartNoDebug, "MENU_DEBUG_START_NO_DEBUGGING"c, null, KeyCode.F5, KeyFlag.Control);
|
||||
const Action ACTION_DEBUG_CONTINUE = new Action(IDEActions.DebugContinue, "MENU_DEBUG_CONTINUE"c, "debug-run");
|
||||
const Action ACTION_DEBUG_STOP = (new Action(IDEActions.DebugStop, "MENU_DEBUG_STOP"c, "debug-stop")).disableByDefault();
|
||||
const Action ACTION_DEBUG_PAUSE = (new Action(IDEActions.DebugPause, "MENU_DEBUG_PAUSE"c, "debug-pause")).disableByDefault();
|
||||
const Action ACTION_DEBUG_RESTART = new Action(IDEActions.DebugRestart, "MENU_DEBUG_RESTART"c, "debug-restart"c, KeyCode.F5, 0);
|
||||
const Action ACTION_DEBUG_STEP_INTO = (new Action(IDEActions.DebugStepInto, "MENU_DEBUG_STEP_INTO"c, "debug-step-into"c, KeyCode.F11, 0)).disableByDefault();
|
||||
const Action ACTION_DEBUG_STEP_OVER = (new Action(IDEActions.DebugStepOver, "MENU_DEBUG_STEP_OVER"c, "debug-step-over"c, KeyCode.F10, 0)).disableByDefault();
|
||||
const Action ACTION_DEBUG_STEP_OUT = (new Action(IDEActions.DebugStepOut, "MENU_DEBUG_STEP_OUT"c, "debug-step-out"c, KeyCode.F11, KeyFlag.Shift)).disableByDefault();
|
||||
|
||||
const Action ACTION_DEBUG_TOGGLE_BREAKPOINT = (new Action(IDEActions.DebugToggleBreakpoint, "MENU_DEBUG_BREAKPOINT_TOGGLE"c, null, KeyCode.F9, 0)).disableByDefault();
|
||||
const Action ACTION_DEBUG_ENABLE_BREAKPOINT = (new Action(IDEActions.DebugEnableBreakpoint, "MENU_DEBUG_BREAKPOINT_ENABLE"c, null, KeyCode.F9, KeyFlag.Shift)).disableByDefault();
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
module dlangide.ui.debuggerui;
|
||||
|
||||
import dlangui.core.logger;
|
||||
import dlangui.core.events;
|
||||
import dlangide.ui.frame;
|
||||
import dlangide.ui.commands;
|
||||
import ddebug.common.execution;
|
||||
import ddebug.common.debugger;
|
||||
|
||||
|
@ -9,6 +11,7 @@ class DebuggerUIHandler : DebuggerCallback {
|
|||
IDEFrame _ide;
|
||||
Debugger _debugger;
|
||||
DebuggingState _state = DebuggingState.loaded;
|
||||
DebugLocation _location;
|
||||
|
||||
this(IDEFrame ide, Debugger debugger) {
|
||||
_ide = ide;
|
||||
|
@ -42,15 +45,18 @@ class DebuggerUIHandler : DebuggerCallback {
|
|||
}
|
||||
|
||||
/// state changed: running / paused / stopped
|
||||
void onDebugState(DebuggingState state, string msg, int param) {
|
||||
Log.d("onDebugState: ", state, " ", msg, " param=", param);
|
||||
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: " ~ msg);
|
||||
_ide.logPanel.logLine("Program is stopped");
|
||||
_debugger.stop();
|
||||
} else if (state == DebuggingState.running) {
|
||||
_ide.logPanel.logLine("Program is started");
|
||||
} else if (state == DebuggingState.paused) {
|
||||
_location = location;
|
||||
_ide.logPanel.logLine("Program is paused.");
|
||||
_ide.window.update();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,4 +71,64 @@ class DebuggerUIHandler : DebuggerCallback {
|
|||
void run() {
|
||||
_debugger.run();
|
||||
}
|
||||
|
||||
bool handleAction(const Action a) {
|
||||
switch(a.id) {
|
||||
case IDEActions.DebugPause:
|
||||
if (_state == DebuggingState.running)
|
||||
_debugger.execPause();
|
||||
return true;
|
||||
case IDEActions.DebugContinue:
|
||||
if (_state == DebuggingState.paused)
|
||||
_debugger.execContinue();
|
||||
return true;
|
||||
case IDEActions.DebugStop:
|
||||
_debugger.execStop();
|
||||
return true;
|
||||
case IDEActions.DebugStepInto:
|
||||
if (_state == DebuggingState.paused)
|
||||
_debugger.execStepIn();
|
||||
return true;
|
||||
case IDEActions.DebugStepOver:
|
||||
if (_state == DebuggingState.paused)
|
||||
_debugger.execStepOver();
|
||||
return true;
|
||||
case IDEActions.DebugStepOut:
|
||||
if (_state == DebuggingState.paused)
|
||||
_debugger.execStepOut();
|
||||
return true;
|
||||
case IDEActions.DebugRestart:
|
||||
//_debugger.execStepOut();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// override to handle specific actions state (e.g. change enabled state for supported actions)
|
||||
bool handleActionStateRequest(const Action a) {
|
||||
switch (a.id) {
|
||||
case IDEActions.DebugStop:
|
||||
case IDEActions.DebugPause:
|
||||
if (_state == DebuggingState.running)
|
||||
a.state = ACTION_STATE_ENABLED;
|
||||
else
|
||||
a.state = ACTION_STATE_DISABLE;
|
||||
return true;
|
||||
case IDEActions.DebugContinue:
|
||||
case IDEActions.DebugStepInto:
|
||||
case IDEActions.DebugStepOver:
|
||||
case IDEActions.DebugStepOut:
|
||||
if (_state == DebuggingState.paused)
|
||||
a.state = ACTION_STATE_ENABLED;
|
||||
else
|
||||
a.state = ACTION_STATE_DISABLE;
|
||||
return true;
|
||||
case IDEActions.DebugRestart:
|
||||
a.state = ACTION_STATE_ENABLED;
|
||||
return true;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -583,6 +583,10 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
|
|||
MenuItem debugItem = new MenuItem(new Action(23, "MENU_DEBUG"));
|
||||
debugItem.add(ACTION_DEBUG_START, ACTION_DEBUG_START_NO_DEBUG,
|
||||
ACTION_DEBUG_CONTINUE, ACTION_DEBUG_STOP, ACTION_DEBUG_PAUSE,
|
||||
ACTION_DEBUG_RESTART,
|
||||
ACTION_DEBUG_STEP_INTO,
|
||||
ACTION_DEBUG_STEP_OVER,
|
||||
ACTION_DEBUG_STEP_OUT,
|
||||
ACTION_DEBUG_TOGGLE_BREAKPOINT, ACTION_DEBUG_ENABLE_BREAKPOINT, ACTION_DEBUG_DISABLE_BREAKPOINT
|
||||
);
|
||||
|
||||
|
@ -626,6 +630,10 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
|
|||
ACTION_PROJECT_SETTINGS, ACTION_WORKSPACE_BUILD, ACTION_WORKSPACE_REBUILD, ACTION_WORKSPACE_CLEAN,
|
||||
ACTION_PROJECT_BUILD, ACTION_PROJECT_REBUILD, ACTION_PROJECT_CLEAN, ACTION_DEBUG_START,
|
||||
ACTION_DEBUG_START_NO_DEBUG, ACTION_DEBUG_CONTINUE, ACTION_DEBUG_STOP, ACTION_DEBUG_PAUSE,
|
||||
ACTION_DEBUG_RESTART,
|
||||
ACTION_DEBUG_STEP_INTO,
|
||||
ACTION_DEBUG_STEP_OVER,
|
||||
ACTION_DEBUG_STEP_OUT,
|
||||
ACTION_WINDOW_CLOSE_ALL_DOCUMENTS, ACTION_HELP_ABOUT];
|
||||
actions ~= STD_EDITOR_ACTIONS;
|
||||
saveShortcutsSettings(actions);
|
||||
|
@ -666,7 +674,12 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
|
|||
tb.addButtons(ACTION_EDIT_COPY, ACTION_EDIT_PASTE, ACTION_EDIT_CUT, ACTION_SEPARATOR,
|
||||
ACTION_EDIT_UNDO, ACTION_EDIT_REDO, ACTION_EDIT_INDENT, ACTION_EDIT_UNINDENT);
|
||||
tb = res.getOrAddToolbar("Debug");
|
||||
tb.addButtons(ACTION_DEBUG_STOP, ACTION_DEBUG_CONTINUE, ACTION_DEBUG_PAUSE);
|
||||
tb.addButtons(ACTION_DEBUG_STOP, ACTION_DEBUG_CONTINUE, ACTION_DEBUG_PAUSE,
|
||||
ACTION_DEBUG_RESTART,
|
||||
ACTION_DEBUG_STEP_INTO,
|
||||
ACTION_DEBUG_STEP_OVER,
|
||||
ACTION_DEBUG_STEP_OUT,
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -718,7 +731,14 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
|
|||
return true;
|
||||
case IDEActions.DebugContinue:
|
||||
case IDEActions.DebugPause:
|
||||
a.state = isExecutionActive && _execution.isDebugger ? ACTION_STATE_ENABLED : ACTION_STATE_DISABLE;
|
||||
case IDEActions.DebugStepInto:
|
||||
case IDEActions.DebugStepOver:
|
||||
case IDEActions.DebugStepOut:
|
||||
case IDEActions.DebugRestart:
|
||||
if (_debugHandler)
|
||||
return _debugHandler.handleActionStateRequest(a);
|
||||
else
|
||||
a.state = ACTION_STATE_DISABLE;
|
||||
return true;
|
||||
default:
|
||||
return super.handleActionStateRequest(a);
|
||||
|
@ -779,11 +799,25 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
|
|||
case IDEActions.DebugStart:
|
||||
buildAndDebugProject(cast(Project)a.objectParam);
|
||||
return true;
|
||||
case IDEActions.DebugPause:
|
||||
case IDEActions.DebugStepInto:
|
||||
case IDEActions.DebugStepOver:
|
||||
case IDEActions.DebugStepOut:
|
||||
case IDEActions.DebugRestart:
|
||||
if (_debugHandler)
|
||||
return _debugHandler.handleAction(a);
|
||||
return true;
|
||||
case IDEActions.DebugContinue:
|
||||
buildAndRunProject(cast(Project)a.objectParam);
|
||||
if (_debugHandler)
|
||||
return _debugHandler.handleAction(a);
|
||||
else
|
||||
buildAndRunProject(cast(Project)a.objectParam);
|
||||
return true;
|
||||
case IDEActions.DebugStop:
|
||||
stopExecution();
|
||||
if (_debugHandler)
|
||||
return _debugHandler.handleAction(a);
|
||||
else
|
||||
stopExecution();
|
||||
return true;
|
||||
case IDEActions.UpdateProjectDependencies:
|
||||
buildProject(BuildOperation.Upgrade, cast(Project)a.objectParam);
|
||||
|
|
|
@ -43,6 +43,10 @@ MENU_DEBUG_START_NO_DEBUGGING=Start Without Debugging
|
|||
MENU_DEBUG_CONTINUE=Continue Debugging
|
||||
MENU_DEBUG_STOP=Stop
|
||||
MENU_DEBUG_PAUSE=Pause
|
||||
MENU_DEBUG_RESTART=Restart
|
||||
MENU_DEBUG_STEP_INTO=Step Into
|
||||
MENU_DEBUG_STEP_OVER=Step Over
|
||||
MENU_DEBUG_STEP_OUT=Step Out
|
||||
|
||||
MENU_DEBUG_BREAKPOINT_TOGGLE=Toggle breakpoint
|
||||
MENU_DEBUG_BREAKPOINT_ENABLE=Enable breakpoint
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 368 B |
Binary file not shown.
After Width: | Height: | Size: 338 B |
Binary file not shown.
After Width: | Height: | Size: 352 B |
Binary file not shown.
After Width: | Height: | Size: 354 B |
|
@ -33,6 +33,10 @@ res/mdpi/cr3_logo.png
|
|||
res/mdpi/debug-run.png
|
||||
res/mdpi/debug-pause.png
|
||||
res/mdpi/debug-stop.png
|
||||
res/mdpi/debug-restart.png
|
||||
res/mdpi/debug-step-into.png
|
||||
res/mdpi/debug-step-out.png
|
||||
res/mdpi/debug-step-over.png
|
||||
res/mdpi/dlangui-logo1.png
|
||||
res/mdpi/document-close.png
|
||||
res/mdpi/document-open-recent.png
|
||||
|
|
Loading…
Reference in New Issue