AutoComplete icon indicating copy to clipboard operation
AutoComplete copied to clipboard

Problem sorting logic.

Open ricardojlrufino opened this issue 11 years ago • 3 comments

I found a problem when mixing TemplateCompletion with other types.

The filtering logic uses getInputText (); org.fife.ui.autocomplete.AbstractCompletionProvider.getCompletionsImpl (JTextComponent) if (Util.startsWithIgnoreCase(c.getInputText(), text))

But sorting is done using the toString org.fife.ui.autocomplete.AbstractCompletion.compareTo (Completion)

ricardojlrufino avatar Dec 07 '14 15:12 ricardojlrufino

Problem appears if completions are sorted not by inputString. E.g. TemplateCompletions are sorted by definitionString. If inputString != definitionString tehn filter will work incorrectly. In example below template "new function" is not proposed by editor neither typed text is "new" nor "fu".

import org.fife.ui.autocomplete.AutoCompletion;
import org.fife.ui.autocomplete.DefaultCompletionProvider;
import org.fife.ui.autocomplete.TemplateCompletion;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;

public class TextPane extends RSyntaxTextArea
{
    public TextPane()
    {
        DefaultCompletionProvider cp = prepareCP();

        AutoCompletion asaComp = new AutoCompletion(cp);
        asaComp.setParameterAssistanceEnabled(true);
        asaComp.setAutoCompleteSingleChoices(false);
        asaComp.install(this);
    }

    public static DefaultCompletionProvider prepareCP()
    {
        DefaultCompletionProvider cp = new DefaultCompletionProvider();

        // populate dc
        for(char c = 'd'; c < 'p'; c++)
        {
            for(int i = 0; i < 3; i++)
            {
                String str = c + "_" + i;
                TemplateCompletion tc = prepareTC(cp, str);
                tc.setRelevance(1);
                cp.addCompletion(tc);
            }
        }

        String template = "function() {\n${cursor}\n}";
        TemplateCompletion tc = new TemplateCompletion(cp, 
                 "function()", 
                 "new function", 
                 template);
        cp.addCompletion(tc);
        tc.setRelevance(10);
        return cp;
    }

    public static TemplateCompletion prepareTC(DefaultCompletionProvider cp, String str)
    {
        return new TemplateCompletion(cp, str + "_input"  , str + "_def", str + "_template\n${cursor}" );

todaviaCaliente avatar May 13 '16 11:05 todaviaCaliente

It appeared that there is an implicit requirement that each implementation of a Completion natural comparison order needs to have the inputText as a prefix. This is in order to make the case insensitive inputText ordering compatible with the natural ordering. I don't know if better Javadoc documentation in the TemplateCompletion would address the issue.

However, there is one more problem. On one hand you want case insensitivity for retrieval, and yet you also want uniqueness for deletion in removeCompletion(). In my own project I have a method called StrUtil.cmpUniqueIgnoreCase(s1,s2) that meets these two requirements at the same time.

I am interested to fix this defect. ETA of 2 weeks since I am still new to github. I have to figure out how to generate a pull request. I also need to consider backward compatibility, and adding junit test cases.

Pull request is out. I have not changed TemplateCompletion yet to include its inputText in its compareTo() method, because I don't fully understand that piece of code yet.

FYI. I have released my personal finance project which uses AutoComplete at SourceForge. https://sourceforge.net/projects/cash-flow/

tttwang23 avatar Nov 08 '16 07:11 tttwang23

I have studied this class a bit more. For now the workaround is to change the previous example from:

TemplateCompletion tc = new TemplateCompletion(cp, 
                 "function()", 
                 "new function", 
                 template);

to

TemplateCompletion tc = new TemplateCompletion(cp, 
                 "function()", 
                 "function() ...", 
                 template);

The idea is to make definitionString attribute to contain the inputText attribute as a prefix.

tttwang23 avatar Nov 17 '16 00:11 tttwang23