async DCD get code completions handling - close #93

This commit is contained in:
Vadim Lopatin 2016-01-28 11:58:21 +03:00
parent 7ba06e6bfe
commit 13f2656550
5 changed files with 53 additions and 37 deletions

View File

@ -19,7 +19,7 @@ enum DCDResult : int {
alias DocCommentsResultSet = Tuple!(DCDResult, "result", string[], "docComments");
alias FindDeclarationResultSet = Tuple!(DCDResult, "result", string, "fileName", ulong, "offset");
alias ResultSet = Tuple!(DCDResult, "result", dstring[], "output");
alias CompletionResultSet = Tuple!(DCDResult, "result", dstring[], "output");
import server.autocomplete;
import common.messages;
@ -199,32 +199,43 @@ class DCDInterface : Thread {
return task;
}
ResultSet getCompletions(CustomEventTarget guiExecutor, in string[] importPaths, in string filename, in string content, int index) {
/// DCD get code completions task
class GetCompletionsTask : DCDTask {
debug(DCD) Log.d("DCD Context: ", dumpContext(content, index));
ResultSet result;
AutocompleteRequest request;
request.sourceCode = cast(ubyte[])content;
request.fileName = filename;
request.cursorPosition = index;
protected void delegate(CompletionResultSet output) _callback;
protected CompletionResultSet result;
AutocompleteResponse response = complete(request, *getModuleCache(importPaths));
if(response.completions is null || response.completions.length == 0){
result.result = DCDResult.NO_RESULT;
return result;
this(CustomEventTarget guiExecutor, string[] importPaths, in string filename, in string content, int index, void delegate(CompletionResultSet output) callback) {
super(guiExecutor, importPaths, filename, content, index);
_callback = callback;
}
result.result = DCDResult.SUCCESS;
result.output.length = response.completions.length;
int i=0;
foreach(s;response.completions){
result.output[i++]=to!dstring(s);
}
debug(DCD) Log.d("DCD output:\n", response.completions);
override void performRequest() {
AutocompleteResponse response = complete(request, *getModuleCache(_importPaths));
if(response.completions is null || response.completions.length == 0){
result.result = DCDResult.NO_RESULT;
return;
}
return result;
result.result = DCDResult.SUCCESS;
result.output.length = response.completions.length;
int i=0;
foreach(s;response.completions){
result.output[i++]=to!dstring(s);
}
debug(DCD) Log.d("DCD output:\n", response.completions);
}
override void postResults() {
_callback(result);
}
}
DCDTask getCompletions(CustomEventTarget guiExecutor, string[] importPaths, string filename, string content, int index, void delegate(CompletionResultSet output) callback) {
debug(DCD) Log.d("DCD Context: ", dumpContext(content, index));
GetCompletionsTask task = new GetCompletionsTask(guiExecutor, importPaths, filename, content, index, callback);
_queue.put(task);
return task;
}
}

View File

@ -24,6 +24,7 @@ class DEditorTool : EditorTool
~this() {
cancelGoToDefinition();
cancelGetDocComments();
cancelGetCompletions();
}
DCDTask _getDocCommentsTask;
@ -44,22 +45,26 @@ class DEditorTool : EditorTool
}
override void cancelGetDocComments() {
// override it
if (_getDocCommentsTask) {
_getDocCommentsTask.cancel();
_getDocCommentsTask = null;
}
}
override void cancelGoToDefinition() {
// override it
if (_goToDefinitionTask) {
_goToDefinitionTask.cancel();
_goToDefinitionTask = null;
}
}
override void cancelGetCompletions() {
if (_getCompletionsTask) {
_getCompletionsTask.cancel();
_getCompletionsTask = null;
}
}
DCDTask _goToDefinitionTask;
override void goToDefinition(DSourceEdit editor, TextPosition caretPosition) {
cancelGoToDefinition();
@ -101,20 +106,16 @@ class DEditorTool : EditorTool
}
override dstring[] getCompletions(DSourceEdit editor, TextPosition caretPosition) {
DCDTask _getCompletionsTask;
override void getCompletions(DSourceEdit editor, TextPosition caretPosition, void delegate(dstring[]) callback) {
string[] importPaths = editor.importPaths();
string content = toUTF8(editor.text);
auto byteOffset = caretPositionToByteOffset(content, caretPosition);
ResultSet output = _frame.dcdInterface.getCompletions(editor.window, importPaths, editor.filename, content, byteOffset);
switch(output.result) {
//TODO: Show dialog
case DCDResult.FAIL:
case DCDResult.NO_RESULT:
case DCDResult.SUCCESS:
default:
return output.output;
}
_getCompletionsTask = _frame.dcdInterface.getCompletions(editor.window, importPaths, editor.filename, content, byteOffset, delegate(CompletionResultSet output) {
callback(output.output);
_getCompletionsTask = null;
});
}
private:

View File

@ -17,10 +17,11 @@ class EditorTool
//Since files might be unsaved, we must send all the text content.
abstract void goToDefinition(DSourceEdit editor, TextPosition caretPosition);
abstract void getDocComments(DSourceEdit editor, TextPosition caretPosition, void delegate(string[]) callback);
abstract dstring[] getCompletions(DSourceEdit editor, TextPosition caretPosition);
abstract void getCompletions(DSourceEdit editor, TextPosition caretPosition, void delegate(dstring[]) callback);
void cancelGoToDefinition() {}
void cancelGetDocComments() {}
void cancelGetCompletions() {}
protected IDEFrame _frame;
@ -36,7 +37,7 @@ class DefaultEditorTool : EditorTool
assert(0); //Go To Definition should not be called for normal files.
}
override dstring[] getCompletions(DSourceEdit editor, TextPosition caretPosition) {
override void getCompletions(DSourceEdit editor, TextPosition caretPosition, void delegate(dstring[]) callback) {
assert(0);
}

View File

@ -530,6 +530,7 @@ class DSourceEdit : SourceEdit, EditableContentMarksChangeListener {
popup.flags = PopupFlags.CloseOnClickOutside;
Log.d("Showing popup at ", textPosToClient(_caretPos).left, " ", textPosToClient(_caretPos).top);
window.update();
}
}

View File

@ -895,8 +895,10 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
return true;
case IDEActions.GetCompletionSuggestions:
Log.d("Getting auto completion suggestions.");
auto results = currentEditor.editorTool.getCompletions(currentEditor, currentEditor.caretPos);
currentEditor.showCompletionPopup(results);
currentEditor.editorTool.getCompletions(currentEditor, currentEditor.caretPos, delegate(dstring[] results) {
if (currentEditor)
currentEditor.showCompletionPopup(results);
});
return true;
case IDEActions.EditPreferences:
showPreferences();