AutoComplete
AutoComplete copied to clipboard
Customize order of completions?
Thanks for the great packages! I'm using RSyntaxTextArea for a tool to speed up transcribing medieval manuscripts.
Now I'm trying to implement code completion too.
But BasicCompletion doesn't really help me all that much, as it sorts alphabetically.
Instead, I want all the words in the transcription to show up as completions, sorted by how often they appear in the transcription. (Assuming that words that have been common so far, would be more likely to show up again.)
My spontaneous approach was to write a Class WeightedCompletion extending BasicCompletion, with an integer weight (how often the word appears). That class, appart from adding the constructors with weight, overrides compareTo:
@Override
public int compareTo(Completion other){
if (other instanceof WeightedCompletion){
WeightedCompletion wc = (WeightedCompletion)other;
int res = -1*Integer.valueOf(getWeight()).compareTo(Integer.valueOf(wc.getWeight()));
if (res == 0)
return super.compareTo(other);
return res;
} else {
return super.compareTo(other);
}
}
This works quite neatly when the caret is at the beginning of a new line of after a blank space, whren I hit Ctrl+Space: The completions all appear in the right order.
But, when I start typing a letter, and then hit Ctrl+Space, no code completion popup shows up anymore.
I have not been able to track the problem down, really... but clearly it doesn't like my compareTo.
Long story short: Is there a good way of getting completions in an order other than alphabetical, that I'm missing?
Any ideas/help would be greatly appreciated!
In your CompletionProvider, if you're extending AbstractCompletionProvider, you can override getCompletionByInputText to do something like:
return completions.stream()
.filter(comp -> comp instanceof WeightedCompletion)
.filter(comp -> comp.getInputText().startsWith(inputText))
.sorted(Comparator.comparingInt(WeightedCompletion::getWeight))
.collect(Collectors.toList());
No need to write the custom comparator yourself.
I too have a problem with the sorting. I just want to retain the order in which the completions are added to the provider. I adapted @paul-griffith 's solution to this:
return completions.stream()
.filter(comp -> comp.getinputText().startsWith(inputText)
.collect(Collectors.toList());
I also replaced the addCompletion() and addCompletions() methods with an implementation that does NOT sort after adding a completion. Debugging of my CompletionProvider (extends DefaultCompletionProvider) shows, that the completion objects are then in the order I add them.
But somewhere still a sorting occurs (maybe CompletionProviderBase/AbstractCompletionProvider) and they are not shown in the desired order. How can this be achieved?
SOLVED:
I have extended BasicCompletion and there I override compareTo() to always return 0. This leaves the order of the completions unchanged.
In these situations it is easier to sort using an external comparator. It is less buggy if all completions are ordered by source text only (say case insensitive primary ordering, then case sensitive secondary ordering). If you hack compareTo() then inserting completions into a sorted collection will have unpredictable behaviors.