Exemplo n.º 1
0
        internal void DoAutocomplete(bool forced)
        {
            if (!this.Menu.Enabled)
            {
                this.Menu.Close();
                return;
            }

            visibleItems.Clear();
            this.FocussedItemIndex    = 0;
            this.VerticalScroll.Value = 0;
            //some magic for update scrolls
            this.AutoScrollMinSize -= new Size(1, 0);
            this.AutoScrollMinSize += new Size(1, 0);
            //get fragment around caret
            Range fragment      = tb.Selection.GetFragment(this.Menu.SearchPattern);
            var   line          = tb.GetLine(tb.Selection.FromLine).Text;
            var   column        = tb.Selection.Start.iChar;
            var   text          = fragment.Text;
            var   fragmentStart = fragment.Start.iChar;

            System.Diagnostics.Debug.WriteLine($"Autocomplete: \"{text}\", {fragmentStart}, \"{line}\", {column}");
            //calc screen point for popup menu
            Point point = tb.PlaceToPoint(fragment.End);

            point.Offset(2, tb.CharHeight);
            //
            if (forced || (text.Length >= this.Menu.MinFragmentLength &&
                           tb.Selection.IsEmpty && /*pops up only if selected range is empty*/
                           (tb.Selection.Start > fragment.Start || text.Length == 0 /*pops up only if caret is after first letter*/)))
            {
                //this.Menu.Fragment = fragment;
                //this.Menu.FragmentStart = fragmentStart;
                //this.Menu.EditLine = line;
                //this.Menu.CursorColumn = column;
                bool foundSelected = false;
                //build popup menu
                var items = new List <AutocompleteItem>();
                foreach (var creator in autocompleteCreators)
                {
                    foreach (var item in creator.CreateItems(tb.Selection.FromLine, tb.Selection.Start.iChar))
                    {
                        items.Add(item);
                    }
                }

                // Sorting: MatchWeight first. If MatchWeight is the same, compare the text.
                items.Sort((f, s) => (f.MatchWeight == s.MatchWeight) ? String.Compare(f.Text, s.Text) : ((f.MatchWeight < s.MatchWeight) ? -1 : 1));
                var maxItem = items.OrderByDescending(i => i.MatchWeight).FirstOrDefault();
                if (maxItem != null)
                {
                    foundSelected          = true;
                    this.FocussedItemIndex = items.IndexOf(maxItem);
                }
                visibleItems.AddRange(items);

                if (foundSelected)
                {
                    this.AdjustScroll();
                    this.DoSelectedVisible();
                }
            }

            //show popup menu
            if (this.Count > 0)
            {
                if (!this.Menu.Visible)
                {
                    CancelEventArgs args = new CancelEventArgs();
                    this.Menu.OnOpening(args);
                    if (!args.Cancel)
                    {
                        this.Menu.Show(tb, point);
                    }
                }

                this.DoSelectedVisible();
                this.Invalidate();
            }
            else
            {
                this.Menu.Close();
            }
        }