in completion/src/main/java/jetbrains/jetpad/completion/CompletionMenuModel.java [51:130]
public CompletionMenuModel(int chunkSize, int distanceFromEnd) {
myChunkSize = chunkSize;
myDistanceFromEndToLoad = distanceFromEnd;
visibleCount = new ValueProperty<>(myChunkSize);
visibleItems = Transformers.filter(new Function<CompletionItem, ReadableProperty<Boolean>>() {
@Override
public ReadableProperty<Boolean> apply(final CompletionItem input) {
return new DerivedProperty<Boolean>(text) {
@Override
public Boolean doGet() {
return input.isMatchPrefix(text.get() == null ? "" : text.get());
}
@Override
public String getPropExpr() {
return "isMatchPrefix(" + text.getPropExpr() + ", " + input + ")";
}
};
}
}).andThen(
Transformers.sortBy(new Function<CompletionItem, ReadableProperty<CompletionItem>>() {
@Override
public ReadableProperty<CompletionItem> apply(final CompletionItem input) {
return Properties.constant(input);
}
}, new Comparator<CompletionItem>() {
@Override
public int compare(CompletionItem c1, CompletionItem c2) {
String text = "";
int delta = c2.getSortPriority() - c1.getSortPriority();
if (delta != 0) {
return delta;
}
String t1 = c1.visibleText(text);
String t2 = c2.visibleText(text);
if (c1.isMatch(text) && !c2.isMatch(text)) {
return -1;
}
if (!c1.isMatch(text) && c2.isMatch(text)) {
return 1;
}
return t1.compareTo(t2);
}
})
).andThen(
Transformers.<CompletionItem>firstN(visibleCount)
).transform(items).getTarget();
visibleItems.addHandler(new EventHandler<CollectionItemEvent<? extends CompletionItem>>() {
@Override
public void onEvent(CollectionItemEvent<? extends CompletionItem> event) {
if (myDisableReset) return;
if (visibleItems.isEmpty()) {
selectedItem.set(null);
} else {
selectedItem.set(visibleItems.get(0));
}
}
});
selectedItem.addHandler(new EventHandler<PropertyChangeEvent<CompletionItem>>() {
@Override
public void onEvent(PropertyChangeEvent<CompletionItem> event) {
int index = visibleItems.lastIndexOf(event.getNewValue());
if (index == -1) return;
if ((visibleCount.get() - 1) - index <= myDistanceFromEndToLoad) {
myDisableReset = true;
try {
visibleCount.set(visibleCount.get() + myChunkSize);
} finally {
myDisableReset = false;
}
}
}
});
}