diff --git a/src/dlangide/tools/d/DCDInterface.d b/src/dlangide/tools/d/DCDInterface.d index 19705ce..5fffb4c 100644 --- a/src/dlangide/tools/d/DCDInterface.d +++ b/src/dlangide/tools/d/DCDInterface.d @@ -1,23 +1,84 @@ module dlangide.tools.d.DCDInterface; +import dlangui.core.logger; + import dlangide.builders.extprocess; +import std.typecons; +import std.conv; +import std.string; + +enum DCDResult : int { + DCD_NOT_RUNNING = 0, + SUCCESS, + NO_RESULT, + FAIL, +} +alias ResultSet = Tuple!(DCDResult, "result", dstring[], "output"); + //Interface to DCD //TODO: Check if server is running, start server if needed etc. class DCDInterface { ExternalProcess dcdProcess; + ProtectedTextStorage stdoutTarget; this() { dcdProcess = new ExternalProcess(); + stdoutTarget = new ProtectedTextStorage(); } - bool execute(char[][] arguments ,ref dstring output, dstring input) { - ProtectedTextStorage stdoutTarget = new ProtectedTextStorage(); + + ResultSet goToDefinition(in dstring content, int index) { ExternalProcess dcdProcess = new ExternalProcess(); + + ResultSet result; + if(dcdProcess.state != ExternalProcessState.None) { + result.result = DCDResult.FAIL; + return result; + } + + char[][] arguments = ["-l".dup, "-c".dup]; + arguments ~= [to!(char[])(index)]; + ProtectedTextStorage stdoutTarget = new ProtectedTextStorage(); + + dcdProcess.run("dcd-client".dup, arguments, "/usr/bin".dup, stdoutTarget); + dcdProcess.write(content); + dcdProcess.wait(); + + dstring[] output = stdoutTarget.readText.splitLines(); + + if(dcdProcess.poll() == ExternalProcessState.Stopped) { + result.result = DCDResult.SUCCESS; + } + else { + result.result = DCDResult.FAIL; + return result; + } + + if(output.length > 0) { + if(output[0].indexOf("Not Found".dup) == 0) { + result.result = DCDResult.NO_RESULT; + return result; + } + } + + auto split = output[0].indexOf("\t"); + if(split == -1) { + Log.d("DCD output format error."); + result.result = DCDResult.FAIL; + return result; + } + + result.output ~= output[0][0 .. split]; + result.output ~= output[0][split+1 .. $]; + return result; + } + + bool execute(char[][] arguments ,ref dstring output, dstring input) { //TODO: Working Directory, where is that? //TODO: Inform user when dcd-client is not available. dcdProcess.run("dcd-client".dup, arguments, "/usr/bin".dup, stdoutTarget); dcdProcess.write(input); - while(dcdProcess.poll() == ExternalProcessState.Running){ } + while(dcdProcess.poll() == ExternalProcessState.Running){ } output = stdoutTarget.readText(); return true; diff --git a/src/dlangide/tools/d/DEditorTool.d b/src/dlangide/tools/d/DEditorTool.d index 7e8c5d6..86e9bc2 100644 --- a/src/dlangide/tools/d/DEditorTool.d +++ b/src/dlangide/tools/d/DEditorTool.d @@ -22,46 +22,33 @@ class DEditorTool : EditorTool override bool goToDefinition(DSourceEdit editor, TextPosition caretPosition) { - - auto content = editor.text(); - auto byteOffset = caretPositionToByteOffset(content, caretPosition); + auto byteOffset = caretPositionToByteOffset(editor.text, caretPosition); + ResultSet output = _dcd.goToDefinition(editor.text, byteOffset); - char[][] arguments = ["-l".dup, "-c".dup]; - arguments ~= [to!(char[])(byteOffset)]; - //arguments ~= [to!(char[])(editor.projectSourceFile.filename())]; - dstring output; - _dcd.execute(arguments, output, content); - - string[] outputLines = to!string(output).splitLines(); - Log.d("DCD:", outputLines); - - foreach(string outputLine ; outputLines) { - if(outputLine.indexOf("Not Found".dup) == -1) { - auto split = outputLine.indexOf("\t"); - if(split == -1) { - Log.d("DCD output format error."); - break; + switch(output.result) { + //TODO: Show dialog + case DCDResult.FAIL: + case DCDResult.DCD_NOT_RUNNING: + case DCDResult.NO_RESULT: + return false; + case DCDResult.SUCCESS: + auto target = to!int(output.output[1]); + if(output.output[0].indexOf("stdin".dup) != -1) { + Log.d("Declaration is in current file. Jumping to it."); + auto destPos = byteOffsetToCaret(editor.text, target); + editor.setCaretPos(destPos.line,destPos.pos); + } + else { + //Must open file first to get the content for finding the correct caret position. + _frame.openSourceFile(to!string(output.output[0])); + auto destPos = byteOffsetToCaret(_frame.currentEditor.text(), target); + _frame.currentEditor.setCaretPos(destPos.line,destPos.pos); } - if(indexOf(outputLine[0 .. split],"stdin".dup) != -1) { - Log.d("Declaration is in current file. Can jump to it."); - auto target = to!int(outputLine[split+1 .. $]); - auto destPos = byteOffsetToCaret(content, target); - editor.setCaretPos(destPos.line,destPos.pos); - } - else { - auto filename = outputLine[0 .. split]; - if(_frame !is null) { - _frame.openSourceFile(filename); - auto target = to!int(outputLine[split+1 .. $]); - auto destPos = byteOffsetToCaret(_frame.currentEditor.text(), target); - - _frame.currentEditor.setCaretPos(destPos.line,destPos.pos); - } - } - } - } - return true; + return true; + default: + return false; + } } override dstring[] getCompletions(DSourceEdit editor, TextPosition caretPosition) {