1 /* |
|
2 * Copyright (c) 2002-2016, the original author or authors. |
|
3 * |
|
4 * This software is distributable under the BSD license. See the terms of the |
|
5 * BSD license in the documentation provided with this software. |
|
6 * |
|
7 * http://www.opensource.org/licenses/bsd-license.php |
|
8 */ |
|
9 package jdk.internal.jline.console.completer; |
|
10 |
|
11 import java.util.ArrayList; |
|
12 import java.util.Arrays; |
|
13 import java.util.Collection; |
|
14 import java.util.LinkedList; |
|
15 import java.util.List; |
|
16 |
|
17 import static jdk.internal.jline.internal.Preconditions.checkNotNull; |
|
18 |
|
19 /** |
|
20 * Completer which contains multiple completers and aggregates them together. |
|
21 * |
|
22 * @author <a href="mailto:jason@planet57.com">Jason Dillon</a> |
|
23 * @since 2.3 |
|
24 */ |
|
25 public class AggregateCompleter |
|
26 implements Completer |
|
27 { |
|
28 private final List<Completer> completers = new ArrayList<Completer>(); |
|
29 |
|
30 public AggregateCompleter() { |
|
31 // empty |
|
32 } |
|
33 |
|
34 /** |
|
35 * Construct an AggregateCompleter with the given collection of completers. |
|
36 * The completers will be used in the iteration order of the collection. |
|
37 * |
|
38 * @param completers the collection of completers |
|
39 */ |
|
40 public AggregateCompleter(final Collection<Completer> completers) { |
|
41 checkNotNull(completers); |
|
42 this.completers.addAll(completers); |
|
43 } |
|
44 |
|
45 /** |
|
46 * Construct an AggregateCompleter with the given completers. |
|
47 * The completers will be used in the order given. |
|
48 * |
|
49 * @param completers the completers |
|
50 */ |
|
51 public AggregateCompleter(final Completer... completers) { |
|
52 this(Arrays.asList(completers)); |
|
53 } |
|
54 |
|
55 /** |
|
56 * Retrieve the collection of completers currently being aggregated. |
|
57 * |
|
58 * @return the aggregated completers |
|
59 */ |
|
60 public Collection<Completer> getCompleters() { |
|
61 return completers; |
|
62 } |
|
63 |
|
64 /** |
|
65 * Perform a completion operation across all aggregated completers. |
|
66 * |
|
67 * @see Completer#complete(String, int, java.util.List) |
|
68 * @return the highest completion return value from all completers |
|
69 */ |
|
70 public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) { |
|
71 // buffer could be null |
|
72 checkNotNull(candidates); |
|
73 |
|
74 List<Completion> completions = new ArrayList<Completion>(completers.size()); |
|
75 |
|
76 // Run each completer, saving its completion results |
|
77 int max = -1; |
|
78 for (Completer completer : completers) { |
|
79 Completion completion = new Completion(candidates); |
|
80 completion.complete(completer, buffer, cursor); |
|
81 |
|
82 // Compute the max cursor position |
|
83 max = Math.max(max, completion.cursor); |
|
84 |
|
85 completions.add(completion); |
|
86 } |
|
87 |
|
88 // Append candidates from completions which have the same cursor position as max |
|
89 for (Completion completion : completions) { |
|
90 if (completion.cursor == max) { |
|
91 candidates.addAll(completion.candidates); |
|
92 } |
|
93 } |
|
94 |
|
95 return max; |
|
96 } |
|
97 |
|
98 /** |
|
99 * @return a string representing the aggregated completers |
|
100 */ |
|
101 @Override |
|
102 public String toString() { |
|
103 return getClass().getSimpleName() + "{" + |
|
104 "completers=" + completers + |
|
105 '}'; |
|
106 } |
|
107 |
|
108 private class Completion |
|
109 { |
|
110 public final List<CharSequence> candidates; |
|
111 |
|
112 public int cursor; |
|
113 |
|
114 public Completion(final List<CharSequence> candidates) { |
|
115 checkNotNull(candidates); |
|
116 this.candidates = new LinkedList<CharSequence>(candidates); |
|
117 } |
|
118 |
|
119 public void complete(final Completer completer, final String buffer, final int cursor) { |
|
120 checkNotNull(completer); |
|
121 this.cursor = completer.complete(buffer, cursor, candidates); |
|
122 } |
|
123 } |
|
124 } |
|