|
28 | 28 | import java.nio.file.Path; |
29 | 29 | import java.util.ArrayList; |
30 | 30 | import java.util.Collections; |
| 31 | +import java.util.Comparator; |
31 | 32 | import java.util.List; |
| 33 | +import java.util.Optional; |
32 | 34 | import java.util.function.Function; |
33 | 35 | import java.util.jar.JarEntry; |
34 | 36 | import java.util.jar.JarFile; |
35 | 37 | import java.util.regex.Matcher; |
36 | 38 | import java.util.regex.Pattern; |
37 | 39 | import java.util.stream.Collectors; |
38 | 40 |
|
| 41 | +import org.fife.ui.autocomplete.AbstractCompletion; |
39 | 42 | import org.fife.ui.autocomplete.BasicCompletion; |
40 | 43 | import org.fife.ui.autocomplete.Completion; |
41 | 44 | import org.fife.ui.autocomplete.CompletionProvider; |
42 | 45 | import org.python.indexer.types.NModuleType; |
43 | 46 | import org.scijava.ui.swing.script.autocompletion.AutoCompletionListener; |
| 47 | +import org.scijava.ui.swing.script.autocompletion.ClassUtil; |
44 | 48 | import org.scijava.ui.swing.script.autocompletion.JythonAutocompletionProvider; |
45 | 49 |
|
46 | 50 | public class JythonAutoCompletions implements AutoCompletionListener |
@@ -252,12 +256,47 @@ public List<Completion> completionsFor(final CompletionProvider provider, String |
252 | 256 | JythonScriptParser.print("codeWithoutLastLine:\n" + codeWithoutLastLine); |
253 | 257 | } |
254 | 258 | final DotAutocompletions da = JythonScriptParser.parseAST(code).getLast().find(varName, DotAutocompletions.EMPTY); |
255 | | - return da.get().stream() |
256 | | - .filter(s -> s.startsWith(seed)) |
257 | | - .map(s -> new BasicCompletion(provider, lastLine.substring(crop) + s.substring(seed.length()), null, da.getClassname())) |
| 259 | + final String lowerCaseSeed = seed.toLowerCase(); |
| 260 | + List<Completion> list = da.get().stream() |
| 261 | + .filter(s -> s.getReplacementText().toLowerCase().contains(lowerCaseSeed)) |
| 262 | + .map(s -> s.getCompletion(provider, lastLine.substring(crop) + s.getReplacementText().substring(seed.length()))) |
258 | 263 | .collect(Collectors.toList()); |
| 264 | + sortCompletions(list, lowerCaseSeed); |
| 265 | + return list; |
259 | 266 | } |
260 | | - |
| 267 | + |
261 | 268 | return Collections.emptyList(); |
262 | 269 | } |
| 270 | + |
| 271 | + @SuppressWarnings("unused") |
| 272 | + private static String removeLastOptionalDot(final String s) { |
| 273 | + System.out.println("removeLastOptionalDot input: " + s); |
| 274 | + return (s != null && s.endsWith(".")) ? s.substring(0, s.length() - 1) : s; |
| 275 | + } |
| 276 | + |
| 277 | + /** |
| 278 | + * NB: Case-insensitive sorting |
| 279 | + * @param completions The list of completions |
| 280 | + * @param pre the text just before the current caret position that could |
| 281 | + * be the start of something auto-completable. |
| 282 | + */ |
| 283 | + private void sortCompletions(final List<Completion> completions, final String pre) { |
| 284 | + Collections.sort(completions, new Comparator<Completion>() { |
| 285 | + int prefix1Index = Integer.MAX_VALUE; |
| 286 | + int prefix2Index = Integer.MAX_VALUE; |
| 287 | + @Override |
| 288 | + public int compare(final Completion o1, final Completion o2) { |
| 289 | + prefix1Index = Integer.MAX_VALUE; |
| 290 | + prefix2Index = Integer.MAX_VALUE; |
| 291 | + if (o1.getReplacementText().toLowerCase().startsWith(pre)) |
| 292 | + prefix1Index = 0; |
| 293 | + if (o2.getReplacementText().toLowerCase().startsWith(pre)) |
| 294 | + prefix2Index = 0; |
| 295 | + if (prefix1Index == prefix2Index) |
| 296 | + return o1.compareTo(o2); |
| 297 | + else |
| 298 | + return prefix1Index - prefix2Index; |
| 299 | + } |
| 300 | + }); |
| 301 | + } |
263 | 302 | } |
0 commit comments