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(); } }