in cell/src/main/java/jetbrains/jetpad/cell/completion/CompletionSupport.java [86:193]
static void showCompletion(final TextCell editor, Async<Iterable<CompletionItem>> items,
final Runnable restoreCompletionState, final Runnable restoreFocusState) {
if (!editor.focused().get()) {
throw new IllegalArgumentException();
}
final CompletionMenuModel menuModel = new CompletionMenuModel();
menuModel.loading.set(true);
final CompositeRegistration completionReg = new CompositeRegistration();
final ReadableProperty<String> prefixText = prefixText(editor);
completionReg.add(PropertyBinding.bindOneWay(prefixText, menuModel.text));
final Handler<CompletionItem> completer = new Handler<CompletionItem>() {
@Override
public void handle(CompletionItem item) {
completionReg.remove();
restoreFocusState.run();
item.complete(prefixText.get()).run();
}
};
final CompositeRegistration disposeMenuMapper = new CompositeRegistration();
final Cell completionCell = CompletionMenu.createCell(menuModel, completer, disposeMenuMapper);
completionReg.add(editor.focused().addHandler(new EventHandler<PropertyChangeEvent<Boolean>>() {
@Override
public void onEvent(PropertyChangeEvent<Boolean> event) {
if (!event.getNewValue()) {
completionReg.remove();
}
}
}));
completionReg.add(editor.addTrait(new CellTrait() {
@Override
public void onKeyPressed(Cell cell, KeyEvent event) {
CompletionItem selectedItem = menuModel.selectedItem.get();
if (event.is(Key.ESCAPE)) {
completionReg.remove();
restoreFocusState.run();
event.consume();
return;
}
if (selectedItem == null) return;
if (event.is(Key.ENTER)) {
completer.handle(selectedItem);
event.consume();
cell.dispatch(new Event(), Cells.AFTER_COMPLETED);
return;
}
if (event.is(Key.UP)) {
menuModel.up();
event.consume();
return;
}
if (event.is(Key.DOWN)) {
menuModel.down();
event.consume();
return;
}
if (event.is(Key.PAGE_UP) || event.is(Key.PAGE_DOWN)) {
int pageHeight = completionCell.getBounds().dimension.y / editor.dimension().y;
for (int i = 0; i < pageHeight; i++) {
if (event.is(Key.PAGE_DOWN)) {
menuModel.down();
} else {
menuModel.up();
}
}
event.consume();
}
}
}));
completionReg.add(new Registration() {
@Override
protected void doRemove() {
completionCell.removeFromParent();
disposeMenuMapper.remove();
restoreCompletionState.run();
}
});
items.onSuccess(new Handler<Iterable<CompletionItem>>() {
@Override
public void handle(Iterable<CompletionItem> items) {
menuModel.loading.set(false);
menuModel.items.addAll(FluentIterable.from(items).toList());
}
});
items.onFailure(new Handler<Throwable>() {
@Override
public void handle(Throwable item) {
menuModel.loading.set(false);
}
});
editor.bottomPopup().set(completionCell);
completionCell.scrollTo();
}