autocomplete

Topics: Developer Forum, User Forum
May 28, 2009 at 9:28 AM

Hi everybody,

I want to use the autocomplet functions to  my scintillaNet editor but actyually *i did not found any documentation about haw can I do it, 

can any body help me, thanks in advance.

Developer
May 28, 2009 at 9:52 AM

Hi ferarkan,

what exactly do you want to do?

You can set the values of the Autocompletelist in the Config XML File, regarding to your lexer.

E.g.

<?xml version="1.0" encoding="utf-8"?>
<ScintillaNET>
  <Language Name="SWoDL">
    <Indentation TabWidth="8" SmartIndentType="cpp" /> <!-- set's Tabwidth -->
    <AutoComplete FillUpCharacters="" SingleLineAccept="True" IsCaseSensitive="False">
      <List>boolean break catch const declare delay do else error exit false float for gosub goto if in int long null retry return string suspend throw true try var void while</List>
    </AutoComplete>
     [...]
  </Language>
</ScintillaNET>

Or you could fill your Autocompletelist with dynamic values which you could extract with RegularExpressions from your File.

May 28, 2009 at 10:11 AM

In fact here is what I exactly want:

I am using scintillaNET to edit XML Files and I have specific items an attributes to add to my XML files thus I want to use autocomplete functions to do this and I am using of course c# with windows forms.

I dont really understand what did you exactly mean by what you mentioned above :)

Developer
May 28, 2009 at 10:39 AM
Edited May 28, 2009 at 10:40 AM

If you use a Configuration Xml, which is not necessary because you use the built-in Lexer of XML, you can change some settings e.g. Highlighting color, Font, Font-size etc.

With the second part of my post I meant you could fill your Autocompletelist from the code.

e.g. you extract some special words with RegularExpressions from the Text of your File.

With those matches you create a new Stringlist (List<string>) and set this list to your Autocompletelist:

this.sciDocument.AutoComplete.List = MyList;

The scintilla Control controls the Autocomplete list, so you write a new Eventlistener for the OnCharAdded Event of the Scintilla Control

and in this Method you could check, if your Autocompletelist contains the last insterted Characters. If so you call the this.sciDocument.AutoComplete.Show(); Method of the Control

and it shows the AutocompleteList with the value that machtes the inserted Characters.

Look here for a screenshot how it could look like.

I hope I could help a bit ;-)

May 29, 2009 at 10:23 AM

It absolutely fabtastic :),

but I have an other question :

in fact I am using scintillaNET to edit XML files and what I want to do is add many different lists to the my sciDocument and to show every list according to a specefic condition : when writing a tag, when writing an attribute or when writing a vlue .

Thanks in advance.

Developer
May 29, 2009 at 11:02 AM
Edited May 29, 2009 at 11:05 AM

You could just replace the list if the condition fit's.

        private void sciDocument_CharAdded(object sender, CharAddedEventArgs e)
        {
            if (this.CheckForFirstAutoComplete(e.Ch))
            {
                showFirstList();
            }
            else if (this.CheckForSecondAutoComplete(e.Ch))
            {
                showSecondList();
            }
        }

private void showFistList()
{
   //do something and set right list
   this.sciDocument.AutoComplete.show();
}
private void showSecondList()
{
   //do something and set right list
   this.sciDocument.AutoComplete.show();
}

private bool CheckForFistAutoComplete(char x)
{
   //check with your condition
}

May 29, 2009 at 5:30 PM

I have an other problem in fact when I write the list just eppear it does not help me to choose items :(

Coordinator
May 29, 2009 at 9:20 PM

It's really hard to know what's going on as there are a lot of settings to AutoComplete. It would probably be easiest if you gave us what you have so far. If you don't have somewhere to post your files create a new issue here and you can attach a .zip file.

May 31, 2009 at 10:02 AM

this what I coded :

ScintillaNet.Scintilla TextZone = new ScintillaNet.Scintilla();

private void TextZone_CharAdded(object sender, ScintillaNet.CharAddedEventArgs e)

        {

 

            ScintillaNet.Scintilla txt = (ScintillaNet.Scintilla)sender;

            if (e.Ch==' ')

                showsecondList(txt);

            if (e.Ch == '<')

                showFirstList(txt);

            /*else

                showFirstList(txt);*/

        }

 

        private void showFirstList(ScintillaNet.Scintilla txt)

        {

            txt.AutoComplete.FillUpCharacters = " ";

            txt.AutoComplete.List = this.taglist;

            //txt.AutoComplete.DropRestOfWord = true;

            txt.AutoComplete.Show();

 

        }

        private void showsecondList(ScintillaNet.Scintilla txt)

        {

            txt.AutoComplete.List = this.atrtaglist;

            txt.AutoComplete.DropRestOfWord = true; 

 

            txt.AutoComplete.Show();

        }

 

Developer
Jun 3, 2009 at 7:52 AM

I'm not sure but do you sort the list? If not this could cause some problems I think.

You must use a simple string sorter, which sorts your list alphabetical.

The your list should behave right, and jump to an entry which starts with the current insterted character.

This could be the Sorter:

 


 

 

#region AutoCompleteListSorter
    public class AutoCompleteStringListSorter : IComparer<string>
    {
        private SortOrder OrderOfSort;
        private CaseInsensitiveComparer ItemComparer;

        public AutoCompleteStringListSorter()
        {

            OrderOfSort = SortOrder.None;

            ItemComparer = new CaseInsensitiveComparer();
        }

        #region IComparer Member

        public int Compare(string x, string y)
        {
            int compareResult = 0;

            String ItemX, ItemY;

            ItemX = x;
            ItemY = y;

            try
            {
                if (ItemX.StartsWith("_") && !ItemY.StartsWith("_"))
                {
                    compareResult = 1;
                }
                else if (!ItemX.StartsWith("_") && ItemY.StartsWith("_"))
                {
                    compareResult = -1;
                }
                else
                {
                    compareResult = ItemComparer.Compare(ItemX, ItemY);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "AutoCompleteListSorter");
            }

            if (OrderOfSort == SortOrder.Ascending)
            {
                return compareResult;
            }
            else if (OrderOfSort == SortOrder.Descending)
            {
                return (-compareResult);
            }
            else
            {
                return 0;
            }
        }
        #endregion

        public SortOrder SortingOrder
        {
            set
            {
                OrderOfSort = value;
            }

            get
            {
                return OrderOfSort;
            }
        }
    }
    #endregion

    public class AutoCompleteItemListSorter : IComparer<SWoDLAutoCompleteItem>
    {
        private SortOrder OrderOfSort;
        private CaseInsensitiveComparer ItemComparer;

        public AutoCompleteItemListSorter()
        {

            OrderOfSort = SortOrder.None;

            ItemComparer = new CaseInsensitiveComparer();
        }

        #region IComparer Member

        public int Compare(SWoDLAutoCompleteItem x, SWoDLAutoCompleteItem y)
        {
            int compareResult = 0;

            SWoDLAutoCompleteItem ItemX, ItemY;

            ItemX = x;
            ItemY = y;

            try
            {
                if (ItemX.Name.StartsWith("_") && !ItemY.Name.StartsWith("_"))
                {
                    compareResult = 1;
                }
                else if (!ItemX.Name.StartsWith("_") && ItemY.Name.StartsWith("_"))
                {
                    compareResult = -1;
                }
                else
                {
                    compareResult = ItemComparer.Compare(ItemX.Name, ItemY.Name);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "AutoCompleteListSorter");
            }

            if (OrderOfSort == SortOrder.Ascending)
            {
                return compareResult;
            }
            else if (OrderOfSort == SortOrder.Descending)
            {
                return (-compareResult);
            }
            else
            {
                return 0;
            }
        }
        #endregion

        public SortOrder SortingOrder
        {
            set
            {
                OrderOfSort = value;
            }

            get
            {
                return OrderOfSort;
            }
        }
    }

 


 

And after you filled the List with values you call

Sorter.SortingOrder = SortOrder.Ascending;
this.sciDocument.AutoComplete.List.Sort(Sorter);

Hope it helps

Sep 1, 2009 at 7:14 PM

When I'm typing a word of the autocomplete.list, and click in this word in this list, shows the word that i was typing and the word of the list. How could i fix that?

 

example:

"public.wo"

then show the list, with the word "word".

When a click em "word", despite of show only "public.word", shows "public.woword"

Developer
Sep 2, 2009 at 8:37 AM

Look at the Setting Scintilla.Autocomplete.DropRestOfWord and play a bit with it, I guess this is what you need.

Sep 2, 2009 at 5:46 PM

Unfortunately, I alredy tried that and failed. =(

 

Sep 2, 2009 at 6:51 PM

another thing: where i enable / disable when i put "ctrl + space" to autocomplete the words?

 

Developer
Sep 9, 2009 at 11:43 AM

I'm not so sure but look at Commands.cs line 139:

AddBinding(Keys.Space, Keys.Control, BindableCommand.AutoCShow);

comment this Line to disable the binding of "Ctrl + Space" for showing the Autocomplete list

best regards

Coordinator
Sep 11, 2009 at 5:17 PM

To get the AutoComplete to get the behavior you want you have to set a couple properties:

This property makes it so that the autocomplete tries to guess where to start the replacement when an item is chosen. It does this by looking back in the document for the last word break. I think the defaults are space . , and CrLf. You may have to set Lexing.WordChars to match what you want.

scintilla.AutoComplete.AutomaticLengthEntered = true;
 This property is kind of confusing. AutoHide automatically hides the list when no possible matches are available. It also means the list won’t appear if none match either. The way I implemented the behavior of these was meant to be helpful but it has kind of a weird effect. If the AutomaticLengthEntered behavior is invoked with AutoHide and it results in no list appearing I then open AutoComplete with a 0 Length entered to force it open. But when you then choose an item it will always append at the insertion point instead of removing characters backwards.

Anyhow (I know I’m rambling) just set AutoHide to false and while you’re at it you most likely want to take off Case Sensitivity.

scintilla.AutoComplete.AutoHide = false;
scintilla.AutoComplete.IsCaseSensitive = false;

  That should get you the behavior you want.

 

To remove the command binding for AutoCompleteShow = Ctrl + Space you should have 2 options: Remove the binding based on Key Combinations, or Remove binding based on Command. Unfortunately it looks like I never implemented a remove by command overload.

If you want to remove by command (which seems more logical in your case) add this method to Commands.cs in the ScintillaNet Project.

 

/// <summary>
/// Removes all bindings to a given commands
/// </summary>
/// <param name="command">BindableCommand to unbind</param>

public void RemoveBinding(BindableCommand command)
{
    foreach (KeyValuePair<KeyBinding, List<BindableCommand>> boundCommand in _boundCommands)
    {
        if (boundCommand.Value.Contains(command))
            boundCommand.Value.Remove(command);
    }
}

 

 

That would enable you to do this:

scintilla.Commands.RemoveBinding(BindableCommand.AutoCShow);

Otherwise you can do this without modifying ScintillaNet

scintilla.Commands.RemoveBinding(Keys.Space, Keys.Control);

 

Developer
Apr 2, 2011 at 11:04 PM
Edited Apr 2, 2011 at 11:05 PM

This is currently in the process of being implemented slightly easier. For more info see

http://scintillanet.codeplex.com/discussions/221399

 

(for some reason the link button doesn't like me)