diff --git a/dub.json b/dub.json index 32e5d59..993ad7c 100644 --- a/dub.json +++ b/dub.json @@ -12,7 +12,7 @@ "stringImportPaths": ["views", "views/res", "views/res/i18n", "views/res/mdpi", "views/res/hdpi"], "dependencies": { - "dlangui": "~>0.7.58", + "dlangui": "~>0.7.59", "dcd": "~>0.7.5" }, diff --git a/src/dlangide/tools/d/dcdinterface.d b/src/dlangide/tools/d/dcdinterface.d index 0feac88..e67e2e6 100644 --- a/src/dlangide/tools/d/dcdinterface.d +++ b/src/dlangide/tools/d/dcdinterface.d @@ -61,6 +61,13 @@ class DCDInterface : Thread { _queue = null; } + protected ModuleCache * getModuleCache(in string[] importPaths) { + // TODO: clear cache if import paths removed or changed + // hold several module cache instances - make cache of caches + _moduleCache.addImportPaths(importPaths); + return &_moduleCache; + } + void threadFunc() { Log.d("Starting DCD tasks thread"); while (!_queue.closed()) { @@ -93,13 +100,12 @@ class DCDInterface : Thread { DocCommentsResultSet getDocComments(in string[] importPaths, in string filename, in string content, int index) { debug(DCD) Log.d("getDocComments: ", dumpContext(content, index)); - _moduleCache.addImportPaths(importPaths); AutocompleteRequest request; request.sourceCode = cast(ubyte[])content; request.fileName = filename; request.cursorPosition = index; - AutocompleteResponse response = getDoc(request, _moduleCache); + AutocompleteResponse response = getDoc(request, *getModuleCache(importPaths)); DocCommentsResultSet result; result.docComments = response.docComments; @@ -113,16 +119,15 @@ class DCDInterface : Thread { return result; } - FindDeclarationResultSet goToDefinition(in string[] importPaths, in string filename, in string content, int index) { + void goToDefinition(in string[] importPaths, in string filename, in string content, int index, void delegate(FindDeclarationResultSet res) callback) { debug(DCD) Log.d("DCD Context: ", dumpContext(content, index)); - _moduleCache.addImportPaths(importPaths); AutocompleteRequest request; request.sourceCode = cast(ubyte[])content; request.fileName = filename; request.cursorPosition = index; - AutocompleteResponse response = findDeclaration(request, _moduleCache); + AutocompleteResponse response = findDeclaration(request, *getModuleCache(importPaths)); FindDeclarationResultSet result; result.fileName = response.symbolFilePath; @@ -134,20 +139,19 @@ class DCDInterface : Thread { if (result.fileName is null) { result.result = DCDResult.NO_RESULT; } - return result; + callback(result); } ResultSet getCompletions(in string[] importPaths, in string filename, in string content, int index) { debug(DCD) Log.d("DCD Context: ", dumpContext(content, index)); - _moduleCache.addImportPaths(importPaths); ResultSet result; AutocompleteRequest request; request.sourceCode = cast(ubyte[])content; request.fileName = filename; request.cursorPosition = index; - AutocompleteResponse response = complete(request, _moduleCache); + AutocompleteResponse response = complete(request, *getModuleCache(importPaths)); if(response.completions is null || response.completions.length == 0){ result.result = DCDResult.NO_RESULT; return result; @@ -167,21 +171,25 @@ class DCDInterface : Thread { /// DCD doc comments task class DocCommentsTask : DCDTask { - this(string[] importPaths, in string filename, in string content, int index) { + + protected void delegate(DocCommentsResultSet output) _callback; + protected DocCommentsResultSet result; + + this(string[] importPaths, in string filename, in string content, int index, void delegate(DocCommentsResultSet output) callback) { super(importPaths, filename, content, index); + _callback = callback; } + override void execute() { if (_cancelled) return; - _moduleCache.addImportPaths(_importPaths); AutocompleteRequest request; request.sourceCode = cast(ubyte[])_content; request.fileName = _filename; request.cursorPosition = _index; - AutocompleteResponse response = getDoc(request, _moduleCache); + AutocompleteResponse response = getDoc(request, *getModuleCache(_importPaths)); - DocCommentsResultSet result; result.docComments = response.docComments; result.result = DCDResult.SUCCESS; @@ -190,6 +198,9 @@ class DCDInterface : Thread { if (result.docComments is null) { result.result = DCDResult.NO_RESULT; } + + if (!_cancelled) + _callback(result); } } } diff --git a/src/dlangide/tools/d/deditortool.d b/src/dlangide/tools/d/deditortool.d index 0a81853..612f8bc 100644 --- a/src/dlangide/tools/d/deditortool.d +++ b/src/dlangide/tools/d/deditortool.d @@ -43,40 +43,45 @@ class DEditorTool : EditorTool } } - override bool goToDefinition(DSourceEdit editor, TextPosition caretPosition) { + override void cancelGoToDefinition() { + // override it + } + + override void goToDefinition(DSourceEdit editor, TextPosition caretPosition) { string[] importPaths = editor.importPaths(); string content = toUTF8(editor.text); auto byteOffset = caretPositionToByteOffset(content, caretPosition); - FindDeclarationResultSet output = _frame.dcdInterface.goToDefinition(importPaths, editor.filename, content, byteOffset); + _frame.dcdInterface.goToDefinition(importPaths, editor.filename, content, byteOffset, delegate(FindDeclarationResultSet output) { + // handle result + switch(output.result) { + //TODO: Show dialog + case DCDResult.FAIL: + case DCDResult.NO_RESULT: + editor.setFocus(); + break; + case DCDResult.SUCCESS: + auto fileName = output.fileName; + if(fileName.indexOf("stdin") == 0) { + Log.d("Declaration is in current file. Jumping to it."); + } else { + //Must open file first to get the content for finding the correct caret position. + if (!_frame.openSourceFile(to!string(fileName))) + break; + if (_frame.currentEditor.parent) + _frame.currentEditor.parent.layout(_frame.currentEditor.parent.pos); + content = toUTF8(_frame.currentEditor.text); + } + auto target = to!int(output.offset); + auto destPos = byteOffsetToCaret(content, target); + _frame.currentEditor.setCaretPos(destPos.line,destPos.pos, true, true); + _frame.currentEditor.setFocus(); + break; + default: + break; + } + }); - - switch(output.result) { - //TODO: Show dialog - case DCDResult.FAIL: - case DCDResult.NO_RESULT: - editor.setFocus(); - return false; - case DCDResult.SUCCESS: - auto fileName = output.fileName; - if(fileName.indexOf("stdin") == 0) { - Log.d("Declaration is in current file. Jumping to it."); - } else { - //Must open file first to get the content for finding the correct caret position. - if (!_frame.openSourceFile(to!string(fileName))) - return false; - if (_frame.currentEditor.parent) - _frame.currentEditor.parent.layout(_frame.currentEditor.parent.pos); - content = toUTF8(_frame.currentEditor.text); - } - auto target = to!int(output.offset); - auto destPos = byteOffsetToCaret(content, target); - _frame.currentEditor.setCaretPos(destPos.line,destPos.pos, true, true); - _frame.currentEditor.setFocus(); - return true; - default: - return false; - } } override dstring[] getCompletions(DSourceEdit editor, TextPosition caretPosition) { @@ -97,25 +102,28 @@ class DEditorTool : EditorTool private: - int caretPositionToByteOffset(string content, TextPosition caretPosition) { + static int caretPositionToByteOffset(string content, TextPosition caretPosition) { auto line = 0; auto pos = 0; auto bytes = 0; foreach(c; content) { - bytes++; - if(c == '\n') { - line++; - } if(line == caretPosition.line) { if(pos == caretPosition.pos) break; pos++; + } else if (line > caretPosition.line) { + break; + } + bytes++; + if(c == '\n') { + line++; + pos = 0; } } return bytes; } - TextPosition byteOffsetToCaret(string content, int byteOffset) { + static TextPosition byteOffsetToCaret(string content, int byteOffset) { int bytes = 0; int line = 0; int pos = 0; diff --git a/src/dlangide/tools/editortool.d b/src/dlangide/tools/editortool.d index 18b328f..88ba0ff 100644 --- a/src/dlangide/tools/editortool.d +++ b/src/dlangide/tools/editortool.d @@ -15,7 +15,10 @@ class EditorTool _frame = frame; } //Since files might be unsaved, we must send all the text content. - abstract bool goToDefinition(DSourceEdit editor, TextPosition caretPosition); + abstract void goToDefinition(DSourceEdit editor, TextPosition caretPosition); + void cancelGoToDefinition() { + // override it + } abstract dstring[] getCompletions(DSourceEdit editor, TextPosition caretPosition); abstract string[] getDocComments(DSourceEdit editor, TextPosition caretPosition); @@ -29,7 +32,7 @@ class DefaultEditorTool : EditorTool super(frame); } - override bool goToDefinition(DSourceEdit editor, TextPosition caretPosition) { + override void goToDefinition(DSourceEdit editor, TextPosition caretPosition) { assert(0); //Go To Definition should not be called for normal files. }