001 /* 002 * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved. 003 * 004 * This software is distributable under the BSD license. See the terms of the 005 * BSD license in the documentation provided with this software. 006 */ 007 package jline; 008 009 import java.io.*; 010 import java.util.*; 011 012 /** 013 * A command history buffer. 014 * 015 * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a> 016 */ 017 public class History { 018 private List history = new ArrayList(); 019 020 private PrintWriter output = null; 021 022 private int maxSize = 500; 023 024 private int currentIndex = 0; 025 026 /** 027 * Construstor: initialize a blank history. 028 */ 029 public History() { 030 } 031 032 /** 033 * Construstor: initialize History object the the specified {@link File} for 034 * storage. 035 */ 036 public History(final File historyFile) throws IOException { 037 setHistoryFile(historyFile); 038 } 039 040 public void setHistoryFile(final File historyFile) throws IOException { 041 if (historyFile.isFile()) { 042 load(new FileInputStream(historyFile)); 043 } 044 045 setOutput(new PrintWriter(new FileWriter(historyFile), true)); 046 flushBuffer(); 047 } 048 049 /** 050 * Load the history buffer from the specified InputStream. 051 */ 052 public void load(final InputStream in) throws IOException { 053 load(new InputStreamReader(in)); 054 } 055 056 /** 057 * Load the history buffer from the specified Reader. 058 */ 059 public void load(final Reader reader) throws IOException { 060 BufferedReader breader = new BufferedReader(reader); 061 List lines = new ArrayList(); 062 String line; 063 064 while ((line = breader.readLine()) != null) { 065 lines.add(line); 066 } 067 068 for (Iterator i = lines.iterator(); i.hasNext();) { 069 addToHistory((String) i.next()); 070 } 071 } 072 073 public int size() { 074 return history.size(); 075 } 076 077 /** 078 * Clear the history buffer 079 */ 080 public void clear() { 081 history.clear(); 082 currentIndex = 0; 083 } 084 085 /** 086 * Add the specified buffer to the end of the history. The pointer is set to 087 * the end of the history buffer. 088 */ 089 public void addToHistory(final String buffer) { 090 // don't append duplicates to the end of the buffer 091 if ((history.size() != 0) 092 && buffer.equals(history.get(history.size() - 1))) { 093 return; 094 } 095 096 history.add(buffer); 097 098 while (history.size() > getMaxSize()) { 099 history.remove(0); 100 } 101 102 currentIndex = history.size(); 103 104 if (getOutput() != null) { 105 getOutput().println(buffer); 106 getOutput().flush(); 107 } 108 } 109 110 /** 111 * Flush the entire history buffer to the output PrintWriter. 112 */ 113 public void flushBuffer() throws IOException { 114 if (getOutput() != null) { 115 for (Iterator i = history.iterator(); i.hasNext(); getOutput() 116 .println((String) i.next())) { 117 ; 118 } 119 120 getOutput().flush(); 121 } 122 } 123 124 /** 125 * This moves the history to the last entry. This entry is one position 126 * before the moveToEnd() position. 127 * 128 * @return Returns false if there were no history entries or the history 129 * index was already at the last entry. 130 */ 131 public boolean moveToLastEntry() { 132 int lastEntry = history.size() - 1; 133 if (lastEntry >= 0 && lastEntry != currentIndex) { 134 currentIndex = history.size() - 1; 135 return true; 136 } 137 138 return false; 139 } 140 141 /** 142 * Move to the end of the history buffer. This will be a blank entry, after 143 * all of the other entries. 144 */ 145 public void moveToEnd() { 146 currentIndex = history.size(); 147 } 148 149 /** 150 * Set the maximum size that the history buffer will store. 151 */ 152 public void setMaxSize(final int maxSize) { 153 this.maxSize = maxSize; 154 } 155 156 /** 157 * Get the maximum size that the history buffer will store. 158 */ 159 public int getMaxSize() { 160 return this.maxSize; 161 } 162 163 /** 164 * The output to which all history elements will be written (or null of 165 * history is not saved to a buffer). 166 */ 167 public void setOutput(final PrintWriter output) { 168 this.output = output; 169 } 170 171 /** 172 * Returns the PrintWriter that is used to store history elements. 173 */ 174 public PrintWriter getOutput() { 175 return this.output; 176 } 177 178 /** 179 * Returns the current history index. 180 */ 181 public int getCurrentIndex() { 182 return this.currentIndex; 183 } 184 185 /** 186 * Return the content of the current buffer. 187 */ 188 public String current() { 189 if (currentIndex >= history.size()) { 190 return ""; 191 } 192 193 return (String) history.get(currentIndex); 194 } 195 196 /** 197 * Move the pointer to the previous element in the buffer. 198 * 199 * @return true if we successfully went to the previous element 200 */ 201 public boolean previous() { 202 if (currentIndex <= 0) { 203 return false; 204 } 205 206 currentIndex--; 207 208 return true; 209 } 210 211 /** 212 * Move the pointer to the next element in the buffer. 213 * 214 * @return true if we successfully went to the next element 215 */ 216 public boolean next() { 217 if (currentIndex >= history.size()) { 218 return false; 219 } 220 221 currentIndex++; 222 223 return true; 224 } 225 226 /** 227 * Returns an immutable list of the history buffer. 228 */ 229 public List getHistoryList() { 230 return Collections.unmodifiableList(history); 231 } 232 233 /** 234 * Returns the standard {@link AbstractCollection#toString} representation 235 * of the history list. 236 */ 237 public String toString() { 238 return history.toString(); 239 } 240 241 /** 242 * Moves the history index to the first entry. 243 * 244 * @return Return false if there are no entries in the history or if the 245 * history is already at the beginning. 246 */ 247 public boolean moveToFirstEntry() { 248 if (history.size() > 0 && currentIndex != 0) { 249 currentIndex = 0; 250 return true; 251 } 252 253 return false; 254 } 255 }