KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jline > CandidateListCompletionHandler


1 /**
2  * jline - Java console input library
3  * Copyright (c) 2002,2003 Marc Prud'hommeaux mwp1@cornell.edu
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

19 package jline;
20
21 import java.io.*;
22 import java.text.*;
23 import java.util.*;
24
25 /**
26  * <p>
27  * A {@link CompletionHandler} that deals with multiple distinct completions
28  * by outputting the complete list of possibilities to the console. This
29  * mimics the behavior of the
30  * <a HREF="http://www.gnu.org/directory/readline.html">readline</a>
31  * library.
32  * </p>
33  *
34  * @author <a HREF="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
35  */

36 public class CandidateListCompletionHandler
37     implements CompletionHandler
38 {
39     private static ResourceBundle loc = ResourceBundle.getBundle (
40         CandidateListCompletionHandler.class.getName ());
41
42
43     public boolean complete (ConsoleReader reader, List candidates, int pos)
44         throws IOException
45     {
46         CursorBuffer buf = reader.getCursorBuffer ();
47
48         // if there is only one completion, then fill in the buffer
49
if (candidates.size () == 1)
50         {
51             String JavaDoc value = candidates.get (0).toString ();
52
53             // fail if the only candidate is the same as the current buffer
54
if (value.equals (buf.toString ()))
55                 return false;
56             setBuffer (reader, value, pos);
57             return true;
58         }
59         else if (candidates.size () > 1)
60         {
61             String JavaDoc value = getUnambiguousCompletions (candidates);
62             String JavaDoc bufString = buf.toString ();
63             setBuffer (reader, value, pos);
64
65             // if we have changed the buffer, then just return withough
66
// printing out all the subsequent candidates
67
if (bufString.length () - pos + 1 != value.length ())
68                 return true;
69         }
70
71         reader.printNewline ();
72         printCandidates (reader, candidates);
73
74         // redraw the current console buffer
75
reader.drawLine ();
76
77         return true;
78     }
79
80
81     private static void setBuffer (ConsoleReader reader,
82         String JavaDoc value, int offset)
83         throws IOException
84     {
85         while (reader.getCursorBuffer ().cursor >= offset
86             && reader.backspace ());
87         reader.putString (value);
88         reader.setCursorPosition (offset + value.length ());
89     }
90
91
92     /**
93      * Print out the candidates. If the size of the candidates
94      * is greated than the {@link getAutoprintThreshhold},
95      * they prompt with aq warning.
96      *
97      * @param candidates the list of candidates to print
98      */

99     private final void printCandidates (ConsoleReader reader,
100         Collection candidates)
101         throws IOException
102     {
103         Set distinct = new HashSet (candidates);
104
105         if (distinct.size () > reader.getAutoprintThreshhold ())
106         {
107             reader.printString (MessageFormat.format (
108                 loc.getString ("display-candidates"),
109                 new Object JavaDoc [] { new Integer JavaDoc (candidates.size ()) } ) + " ");
110
111             reader.flushConsole ();
112
113             int c;
114             
115             String JavaDoc noOpt = loc.getString ("display-candidates-no");
116             String JavaDoc yesOpt = loc.getString ("display-candidates-yes");
117
118             while ((c = reader.readCharacter (
119                 new char[] { yesOpt.charAt (0), noOpt.charAt (0) })) != -1)
120             {
121                 if (noOpt.startsWith (new String JavaDoc (new char[] {(char)c})))
122                 {
123                     reader.printNewline ();
124                     return;
125                 }
126                 else if (yesOpt.startsWith (new String JavaDoc (new char[] {(char)c})))
127                 {
128                     break;
129                 }
130                 else
131                 {
132                     reader.beep ();
133                 }
134             }
135         }
136
137         // copy the values and make them distinct, without otherwise
138
// affecting the ordering. Only do it if the sizes differ.
139
if (distinct.size () != candidates.size ())
140         {
141             Collection copy = new ArrayList ();
142             for (Iterator i = candidates.iterator (); i.hasNext (); )
143             {
144                 Object JavaDoc next = i.next ();
145                 if (!(copy.contains (next)))
146                     copy.add (next);
147             }
148
149             candidates = copy;
150         }
151
152         reader.printNewline ();
153         reader.printColumns (candidates);
154     }
155
156
157
158
159     /**
160      * Returns a root that matches all the {@link String} elements
161      * of the specified {@link List}, or null if there are
162      * no commalities. For example, if the list contains
163      * <i>foobar</i>, <i>foobaz</i>, <i>foobuz</i>, the
164      * method will return <i>foob</i>.
165      */

166     private final String JavaDoc getUnambiguousCompletions (List candidates)
167     {
168         if (candidates == null || candidates.size () == 0)
169             return null;
170
171         // convert to an array for speed
172
String JavaDoc [] strings = (String JavaDoc [])candidates.toArray (
173             new String JavaDoc [candidates.size ()]);
174
175         String JavaDoc first = strings [0];
176         StringBuffer JavaDoc candidate = new StringBuffer JavaDoc ();
177         for (int i = 0; i < first.length (); i++)
178         {
179             if (startsWith (first.substring (0, i + 1), strings))
180                 candidate.append (first.charAt (i));
181             else
182                 break;
183         }
184
185         return candidate.toString ();
186     }
187
188
189     /**
190      * @return true is all the elements of <i>candidates</i>
191      * start with <i>starts</i>
192      */

193     private final boolean startsWith (String JavaDoc starts, String JavaDoc [] candidates)
194     {
195         for (int i = 0; i < candidates.length; i++)
196         {
197             if (!candidates [i].startsWith (starts))
198                 return false;
199         }
200
201         return true;
202     }
203 }
204
205
Popular Tags