The completion is already asynchronous. addCompletionVariants() is called in a background thread, and the completion is updated as you call result.addElement().
result.addLookupAdvertisement("Select one or more users separated with comma, | or new lines"); List<String> values = dataProvider.getValues(prefix); // Web serice Call for (String completionVariant : values) { final LookupElementBuilder element = LookupElementBuilder.create(completionVariant); result.addElement(element.withLookupString(completionVariant.toLowerCase())); }
} } }
This is my code snipet. As I type in the text field Intellij hangs. I'm not able to figure out what is missing. Thanks :)
To avoid IDE freezing, completion thread must not perform any blocking calls, and should call ProgressManager.checkCanceled often enough (e.g. every 50ms). You can start another thread, wait for the web service to return there (while doing a busy-loop with checkCanceled on the completion thread), and cancel this operation if checkCanceled throws ProcessCanceledException. Then, after you get all the variants from the web service, you can feed them into CompletionResultSet on the completion thread again.
The completion is already asynchronous. addCompletionVariants() is called in a background thread, and the completion is updated as you call result.addElement().
public class MultiValueAutoComplete {
private static final char[] SEPARATORS = {','};
public static EditorTextField create(Project project, DataProvider dataProvider) {
List<EditorCustomization> customizations =
Arrays.<EditorCustomization>asList(SoftWrapsEditorCustomization.ENABLED, SpellCheckingEditorCustomization.DISABLED);
EditorTextField editorField = ServiceManager.getService(project, EditorTextFieldProvider.class)
.getEditorField(FileTypes.PLAIN_TEXT.getLanguage(), project, customizations);
new CommaSeparatedTextFieldCompletion(dataProvider).apply(editorField);
return editorField;
}
public interface DataProvider {
List<String> getValues(String prefix);
}
private static class CommaSeparatedTextFieldCompletion extends TextFieldCompletionProvider {
private DataProvider dataProvider;
public CommaSeparatedTextFieldCompletion(DataProvider dataProvider) {
this.dataProvider = dataProvider;
}
@NotNull
@Override
protected String getPrefix(@NotNull String currentTextPrefix) {
final int separatorPosition = lastSeparatorPosition(currentTextPrefix);
return separatorPosition == -1 ? currentTextPrefix : currentTextPrefix.substring(separatorPosition + 1).trim();
}
private static int lastSeparatorPosition(@NotNull String text) {
int lastPosition = -1;
for (char separator : SEPARATORS) {
int lio = text.lastIndexOf(separator);
if (lio > lastPosition) {
lastPosition = lio;
}
}
return lastPosition;
}
@Override
protected void addCompletionVariants(@NotNull String text, int offset, @NotNull String prefix,
@NotNull CompletionResultSet result) {
result.addLookupAdvertisement("Select one or more users separated with comma, | or new lines");
List<String> values = dataProvider.getValues(prefix); // Web serice Call
for (String completionVariant : values) {
final LookupElementBuilder element = LookupElementBuilder.create(completionVariant);
result.addElement(element.withLookupString(completionVariant.toLowerCase()));
}
}
}
}
This is my code snipet.
As I type in the text field Intellij hangs. I'm not able to figure out what is missing. Thanks :)
To avoid IDE freezing, completion thread must not perform any blocking calls, and should call ProgressManager.checkCanceled often enough (e.g. every 50ms). You can start another thread, wait for the web service to return there (while doing a busy-loop with checkCanceled on the completion thread), and cancel this operation if checkCanceled throws ProcessCanceledException. Then, after you get all the variants from the web service, you can feed them into CompletionResultSet on the completion thread again.
Peter Gromov Can you please help with a sample code