• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
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 package jline;
8 
9 import java.io.*;
10 import java.util.*;
11 
12 /**
13  * A command history buffer.
14  *
15  * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
16  */
17 public class History {
18 
19     private List history = new ArrayList();
20     private PrintWriter output = null;
21     private int maxSize = 500;
22     private int currentIndex = 0;
23 
24     /**
25      * Construstor: initialize a blank history.
26      */
History()27     public History() {
28     }
29 
30     /**
31      * Construstor: initialize History object the the specified {@link File} for
32      * storage.
33      */
History(final File historyFile)34     public History(final File historyFile) throws IOException {
35         setHistoryFile(historyFile);
36     }
37 
setHistoryFile(final File historyFile)38     public void setHistoryFile(final File historyFile) throws IOException {
39         if (historyFile.isFile()) {
40             load(new FileInputStream(historyFile));
41         }
42 
43         setOutput(new PrintWriter(new FileWriter(historyFile), true));
44         flushBuffer();
45     }
46 
47     /**
48      * Load the history buffer from the specified InputStream.
49      */
load(final InputStream in)50     public void load(final InputStream in) throws IOException {
51         load(new InputStreamReader(in));
52     }
53 
54     /**
55      * Load the history buffer from the specified Reader.
56      */
load(final Reader reader)57     public void load(final Reader reader) throws IOException {
58         BufferedReader breader = new BufferedReader(reader);
59         List lines = new ArrayList();
60         String line;
61 
62         while ((line = breader.readLine()) != null) {
63             lines.add(line);
64         }
65 
66         for (Iterator i = lines.iterator(); i.hasNext();) {
67             addToHistory((String) i.next());
68         }
69     }
70 
size()71     public int size() {
72         return history.size();
73     }
74 
75     /**
76      * Clear the history buffer
77      */
clear()78     public void clear() {
79         history.clear();
80         currentIndex = 0;
81     }
82 
83     /**
84      * Add the specified buffer to the end of the history. The pointer is set to
85      * the end of the history buffer.
86      */
addToHistory(final String buffer)87     public void addToHistory(final String buffer) {
88         // don't append duplicates to the end of the buffer
89         if ((history.size() != 0) && buffer.equals(history.get(history.size() - 1))) {
90             return;
91         }
92 
93         history.add(buffer);
94 
95         while (history.size() > getMaxSize()) {
96             history.remove(0);
97         }
98 
99         currentIndex = history.size();
100 
101         if (getOutput() != null) {
102             getOutput().println(buffer);
103             getOutput().flush();
104         }
105     }
106 
107     /**
108      * Flush the entire history buffer to the output PrintWriter.
109      */
flushBuffer()110     public void flushBuffer() throws IOException {
111         if (getOutput() != null) {
112             for (Iterator i = history.iterator(); i.hasNext(); getOutput().println((String) i.next())) {
113                 ;
114             }
115 
116             getOutput().flush();
117         }
118     }
119 
120     /**
121      * This moves the history to the last entry. This entry is one position
122      * before the moveToEnd() position.
123      *
124      * @return Returns false if there were no history entries or the history
125      *         index was already at the last entry.
126      */
moveToLastEntry()127     public boolean moveToLastEntry() {
128         int lastEntry = history.size() - 1;
129         if (lastEntry >= 0 && lastEntry != currentIndex) {
130             currentIndex = history.size() - 1;
131             return true;
132         }
133 
134         return false;
135     }
136 
137     /**
138      * Move to the end of the history buffer. This will be a blank entry, after
139      * all of the other entries.
140      */
moveToEnd()141     public void moveToEnd() {
142         currentIndex = history.size();
143     }
144 
145     /**
146      * Set the maximum size that the history buffer will store.
147      */
setMaxSize(final int maxSize)148     public void setMaxSize(final int maxSize) {
149         this.maxSize = maxSize;
150     }
151 
152     /**
153      * Get the maximum size that the history buffer will store.
154      */
getMaxSize()155     public int getMaxSize() {
156         return this.maxSize;
157     }
158 
159     /**
160      * The output to which all history elements will be written (or null of
161      * history is not saved to a buffer).
162      */
setOutput(final PrintWriter output)163     public void setOutput(final PrintWriter output) {
164         this.output = output;
165     }
166 
167     /**
168      * Returns the PrintWriter that is used to store history elements.
169      */
getOutput()170     public PrintWriter getOutput() {
171         return this.output;
172     }
173 
174     /**
175      * Returns the current history index.
176      */
getCurrentIndex()177     public int getCurrentIndex() {
178         return this.currentIndex;
179     }
180 
181     /**
182      * Return the content of the current buffer.
183      */
current()184     public String current() {
185         if (currentIndex >= history.size()) {
186             return "";
187         }
188 
189         return (String) history.get(currentIndex);
190     }
191 
192     /**
193      * Move the pointer to the previous element in the buffer.
194      *
195      * @return true if we successfully went to the previous element
196      */
previous()197     public boolean previous() {
198         if (currentIndex <= 0) {
199             return false;
200         }
201 
202         currentIndex--;
203 
204         return true;
205     }
206 
207     /**
208      * Move the pointer to the next element in the buffer.
209      *
210      * @return true if we successfully went to the next element
211      */
next()212     public boolean next() {
213         if (currentIndex >= history.size()) {
214             return false;
215         }
216 
217         currentIndex++;
218 
219         return true;
220     }
221 
222     /**
223      * Returns an immutable list of the history buffer.
224      */
getHistoryList()225     public List getHistoryList() {
226         return Collections.unmodifiableList(history);
227     }
228 
229     /**
230      * Returns the standard {@link AbstractCollection#toString} representation
231      * of the history list.
232      */
toString()233     public String toString() {
234         return history.toString();
235     }
236 
237     /**
238      * Moves the history index to the first entry.
239      *
240      * @return Return false if there are no entries in the history or if the
241      *         history is already at the beginning.
242      */
moveToFirstEntry()243     public boolean moveToFirstEntry() {
244         if (history.size() > 0 && currentIndex != 0) {
245             currentIndex = 0;
246             return true;
247         }
248 
249         return false;
250     }
251 
252     /**
253      * Search backward in history from a given position.
254      *
255      * @param searchTerm substring to search for.
256      * @param startIndex the index from which on to search
257      * @return index where this substring has been found, or -1 else.
258      */
searchBackwards(String searchTerm, int startIndex)259     public int searchBackwards(String searchTerm, int startIndex) {
260         for (int i = startIndex - 1; i >= 0; i--) {
261             if (i >= size())
262                 continue;
263             if (getHistory(i).indexOf(searchTerm) != -1) {
264                 return i;
265             }
266         }
267         return -1;
268     }
269 
270     /**
271      * Search backwards in history from the current position.
272      *
273      * @param searchTerm substring to search for.
274      * @return index where the substring has been found, or -1 else.
275      */
searchBackwards(String s)276     public int searchBackwards(String s) {
277         return searchBackwards(s, getCurrentIndex());
278     }
279 
280     /**
281      * Get the history string for the given index.
282      *
283      * @param index
284      * @return
285      */
getHistory(int index)286     public String getHistory(int index) {
287         return (String) history.get(index);
288     }
289 
290     /**
291      * Set current index to given number.
292      *
293      * @param index
294      */
setCurrentIndex(int index)295     public void setCurrentIndex(int index) {
296         if (index >= 0 && index < history.size())
297             currentIndex = index;
298     }
299 }
300