1
2
3
4
5
6
7 package jline;
8
9 import java.io.*;
10 import java.util.*;
11
12 /***
13 * <p>
14 * A simple {@link Completor} implementation that handles a pre-defined
15 * list of completion words.
16 * </p>
17 *
18 * <p>
19 * Example usage:
20 * </p>
21 * <pre>
22 * myConsoleReader.addCompletor (new SimpleCompletor (new String [] { "now", "yesterday", "tomorrow" }));
23 * </pre>
24 *
25 * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
26 */
27 public class SimpleCompletor implements Completor, Cloneable {
28 /***
29 * The list of candidates that will be completed.
30 */
31 SortedSet candidates;
32
33 /***
34 * A delimiter to use to qualify completions.
35 */
36 String delimiter;
37 final SimpleCompletorFilter filter;
38
39 /***
40 * Create a new SimpleCompletor with a single possible completion
41 * values.
42 */
43 public SimpleCompletor(final String candidateString) {
44 this(new String[] {
45 candidateString
46 });
47 }
48
49 /***
50 * Create a new SimpleCompletor with a list of possible completion
51 * values.
52 */
53 public SimpleCompletor(final String[] candidateStrings) {
54 this(candidateStrings, null);
55 }
56
57 public SimpleCompletor(final String[] strings,
58 final SimpleCompletorFilter filter) {
59 this.filter = filter;
60 setCandidateStrings(strings);
61 }
62
63 /***
64 * Complete candidates using the contents of the specified Reader.
65 */
66 public SimpleCompletor(final Reader reader) throws IOException {
67 this(getStrings(reader));
68 }
69
70 /***
71 * Complete candidates using the whitespearated values in
72 * read from the specified Reader.
73 */
74 public SimpleCompletor(final InputStream in) throws IOException {
75 this(getStrings(new InputStreamReader(in)));
76 }
77
78 private static String[] getStrings(final Reader in)
79 throws IOException {
80 final Reader reader =
81 (in instanceof BufferedReader) ? in : new BufferedReader(in);
82
83 List words = new LinkedList();
84 String line;
85
86 while ((line = ((BufferedReader) reader).readLine()) != null) {
87 for (StringTokenizer tok = new StringTokenizer(line);
88 tok.hasMoreTokens(); words.add(tok.nextToken())) {
89 ;
90 }
91 }
92
93 return (String[]) words.toArray(new String[words.size()]);
94 }
95
96 public int complete(final String buffer, final int cursor, final List clist) {
97 String start = (buffer == null) ? "" : buffer;
98
99 SortedSet matches = candidates.tailSet(start);
100
101 for (Iterator i = matches.iterator(); i.hasNext();) {
102 String can = (String) i.next();
103
104 if (!(can.startsWith(start))) {
105 break;
106 }
107
108 if (delimiter != null) {
109 int index = can.indexOf(delimiter, cursor);
110
111 if (index != -1) {
112 can = can.substring(0, index + 1);
113 }
114 }
115
116 clist.add(can);
117 }
118
119 if (clist.size() == 1) {
120 clist.set(0, ((String) clist.get(0)) + " ");
121 }
122
123
124
125 return (clist.size() == 0) ? (-1) : 0;
126 }
127
128 public void setDelimiter(final String delimiter) {
129 this.delimiter = delimiter;
130 }
131
132 public String getDelimiter() {
133 return this.delimiter;
134 }
135
136 public void setCandidates(final SortedSet candidates) {
137 if (filter != null) {
138 TreeSet filtered = new TreeSet();
139
140 for (Iterator i = candidates.iterator(); i.hasNext();) {
141 String element = (String) i.next();
142 element = filter.filter(element);
143
144 if (element != null) {
145 filtered.add(element);
146 }
147 }
148
149 this.candidates = filtered;
150 } else {
151 this.candidates = candidates;
152 }
153 }
154
155 public SortedSet getCandidates() {
156 return Collections.unmodifiableSortedSet(this.candidates);
157 }
158
159 public void setCandidateStrings(final String[] strings) {
160 setCandidates(new TreeSet(Arrays.asList(strings)));
161 }
162
163 public void addCandidateString(final String candidateString) {
164 final String string =
165 (filter == null) ? candidateString : filter.filter(candidateString);
166
167 if (string != null) {
168 candidates.add(string);
169 }
170 }
171
172 public Object clone() throws CloneNotSupportedException {
173 return super.clone();
174 }
175
176 /***
177 * Filter for elements in the completor.
178 *
179 * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
180 */
181 public static interface SimpleCompletorFilter {
182 /***
183 * Filter the specified String. To not filter it, return the
184 * same String as the parameter. To exclude it, return null.
185 */
186 public String filter(String element);
187 }
188
189 public static class NoOpFilter implements SimpleCompletorFilter {
190 public String filter(final String element) {
191 return element;
192 }
193 }
194 }