Custom Autocompletion - desjarlais/Scintilla.NET GitHub Wiki

What Is This For?

Basically, a lot of people already know that Scintilla's auto-complete is pretty basic and simply just lacking a lot of features.

So, I will be explaining here on how to add the AutoCompleteMenu to ScintillaNET.

For people who don't know it, here are some images explaining its abilities:

NOTE: the images shown are for regular TextBoxes, but it'll work just exactly for Scintilla.

FirstImage SecondImage ThridImage

Adding the Library to Your Project

Downloading:

To save you time, I have created my own repository on GitHub with a wrapper already made for you :)

You can download the compiled library from NuGet. The package name is AutoCompleteMenu-ScintillaNET.

If you want to browse the code, the repository is here: https://github.com/JohnyMac/AutoCompleteMenu-ScintillaNET.

Binding it to ScintillaNET

Next, we want to make it work with Scintilla. Simply, go to your Form_Load event or wherever you want and add this: AutoCompleteMenu.TargetControlWrapper = New ScintillaWrapper(scintilla1);

Then the wrapper will do all the rest. All you need to do now is add the keywords.

Adding Keywords:

There are several methods for doing so, and it depends on what you need it for.

Method 1: (Static)

This is useful if the keywords are basically static and not added on run-time. To do this, simply edit the property Items found in the AutoCompleteMenu.

Method 2: (Static but on runtime)

If you want to change the keywords during runtime, you can use this. However, don't use this if the keywords are dynamic. Only use it for static because there is a better way.

Here is an example:

string[] snippets = { "Whatever", "Bla", "Another_bla", "HEY" };

private void BuildAutocompleteMenu()
{
    var items = new List<AutocompleteItem>();

    foreach (var item in snippets)
        items.Add(new SnippetAutocompleteItem(item) { ImageIndex = 1 });

    //set as autocomplete source
    autocompleteMenu1.SetAutocompleteItems(items);
}
Method 3: (Static but object oriented)

If you want to basically just store objects instead of strings. For example, if you want to store the ToolTip info alongside with the items.

Simply create an object that inherits the AutocompleteItem. For example:

internal class EmailSnippet : AutocompleteItem
{
    public EmailSnippet(string email): base(email)
    {
        ImageIndex = 0;
        ToolTipTitle = "Insert email:";
        ToolTipText = email;
    }

    public override CompareResult Compare(string fragmentText)
    {
        if (fragmentText == Text)
            return CompareResult.VisibleAndSelected;
        if (fragmentText.Contains("@"))
            return CompareResult.Visible;
        return CompareResult.Hidden;
    }
}
Method 4: (Dynamic)

This is very useful when the list shouldn't be the same each time. For example, if you parse the code and the auto-complete is shown depending on that.

Simply, you create a class that implements IEnumerable<AutocompleteItem> and then use that in the function SetAutocompleteItems once. For example:

internal class DynamicCollection : IEnumerable<AutocompleteItem>
{
    public IEnumerator<AutocompleteItem> GetEnumerator()
    {
        return BuildList().GetEnumerator();
    }

    private IEnumerable<AutocompleteItem> BuildList()
    {
        //find all words of the text
        var words = new Dictionary<string, string>();
        foreach (Match m in Regex.Matches(tb.Text, @"\b\w+\b"))
            words[m.Value] = m.Value;

        //return autocomplete items
        foreach(var word in words.Keys)
            yield return new AutocompleteItem(word);
    }
}
...
autocompleteMenu1.SetAutocompleteItems(new DynamicCollection(tb));

Here you don't do SetAutocompleteItems each time you parse the codem but simply modify the collection and it will do the rest.

Credits and Sources

First of all, great thanks to Pavel Torgashov who created this library.

The original post and the source of everything: http://www.codeproject.com/Articles/365974/Autocomplete-Menu. Also, that topic can be very helpful if you need any help in the library too.