@@ -9,7 +9,7 @@ import 'package:collection/collection.dart';
99
1010typedef Suggestions = List <Suggestion >;
1111
12- class Suggestion {
12+ class Suggestion implements Comparable < Suggestion > {
1313 final int start;
1414 final int end;
1515 final String value;
@@ -32,15 +32,25 @@ class Suggestion {
3232 'html' : html,
3333 'score' : score,
3434 };
35+
36+ @override
37+ int compareTo (Suggestion other) {
38+ final sc = - score.compareTo (other.score);
39+ if (sc != 0 ) return sc;
40+ final lc = value.length.compareTo (other.value.length);
41+ if (lc != 0 ) return lc;
42+ return value.compareTo (other.value);
43+ }
3544}
3645
3746/// Given [data] and [caret] position inside [text] what suggestions do we
3847/// want to offer and should completion be automatically triggered?
39- ({bool trigger, Suggestions suggestions}) suggest (
48+ ({bool trigger, Suggestions suggestions, bool isTrimmed }) suggest (
4049 CompletionData data,
4150 String text,
42- int caret,
43- ) {
51+ int caret, {
52+ int maxOptionCount = 50 ,
53+ }) {
4454 // Get position before caret
4555 final beforeCaret = caret > 0 ? caret - 1 : 0 ;
4656 // Get position of space after the caret
@@ -81,6 +91,7 @@ class Suggestion {
8191 return (
8292 trigger: false ,
8393 suggestions: [],
94+ isTrimmed: false ,
8495 );
8596 }
8697
@@ -94,6 +105,7 @@ class Suggestion {
94105 return (
95106 trigger: false ,
96107 suggestions: [],
108+ isTrimmed: false ,
97109 );
98110 }
99111 // We don't to auto trigger completion unless there is an option that is
@@ -106,7 +118,7 @@ class Suggestion {
106118 // Terminate suggestion with a ' ' suffix, if this is a terminal completion
107119 final suffix = completion.terminal ? ' ' : '' ;
108120
109- final suggestions = completion.options.map ((option) {
121+ var suggestions = completion.options.map ((option) {
110122 final overlap = _lcs (prefix, option);
111123 var html = option;
112124 // highlight the overlapping part of the text
@@ -129,15 +141,32 @@ class Suggestion {
129141 html: html,
130142 score: score,
131143 );
132- }).sorted ((a, b) {
133- final x = - a.score.compareTo (b.score);
134- if (x != 0 ) return x;
135- return a.value.compareTo (b.value);
136- });
144+ }).toList ();
145+ final isTrimmed = suggestions.length > maxOptionCount;
146+ if (! isTrimmed) {
147+ suggestions.sort ();
148+ } else {
149+ // List of score bucket entries ordered by decreasing score.
150+ final buckets = suggestions
151+ .groupListsBy ((s) => s.score.floor ())
152+ .entries
153+ .toList ()
154+ ..sort ((a, b) => - a.key.compareTo (b.key));
155+ suggestions = [];
156+ for (final bucket in buckets) {
157+ bucket.value.sort ();
158+ suggestions
159+ .addAll (bucket.value.take (maxOptionCount - suggestions.length));
160+ if (suggestions.length >= maxOptionCount) {
161+ break ;
162+ }
163+ }
164+ }
137165
138166 return (
139167 trigger: trigger,
140168 suggestions: suggestions,
169+ isTrimmed: isTrimmed,
141170 );
142171}
143172
0 commit comments