Skip to content

Commit e89f212

Browse files
committed
Add a history class for the upcoming script interpreters
The newly-introduced History class maintains the history of most recently executed statements and has functionality to persist and retrieve the list from the preferences. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
1 parent 71ca10e commit e89f212

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/*
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2014 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.script;
33+
34+
import org.scijava.prefs.PrefService;
35+
import org.scijava.util.LastRecentlyUsed;
36+
37+
/**
38+
* Container for a script language's interpreter history.
39+
*
40+
* @author Johannes Schindelin
41+
*/
42+
class History {
43+
44+
protected static final long serialVersionUID = 1L;
45+
46+
private static final String PREFIX = "History.";
47+
private final int MAX_ENTRIES = 1000;
48+
49+
private final PrefService prefs;
50+
private final String name;
51+
private final LastRecentlyUsed<String> entries = new LastRecentlyUsed<String>(MAX_ENTRIES);
52+
private int position = -1;
53+
54+
/**
55+
* Constructs a history object for a given scripting language.
56+
*
57+
* @param name the name of the scripting language
58+
*/
59+
public History(final PrefService prefs, final String name) {
60+
this.prefs = prefs;
61+
this.name = name;
62+
}
63+
64+
/**
65+
* Read back a persisted history.
66+
*/
67+
public void read() {
68+
entries.clear();
69+
for (final String item : prefs.getIterable(getClass(), PREFIX + name)) {
70+
entries.addToEnd(item);
71+
};
72+
}
73+
74+
/**
75+
* Persist the history.
76+
*
77+
* @see {@link Prefs}
78+
*/
79+
public void write() {
80+
prefs.putIterable(getClass(), entries, PREFIX + name);
81+
}
82+
83+
/**
84+
* Adds the most recently issued command.
85+
*
86+
* @param command the most recent command to add to the history
87+
*/
88+
public void add(final String command) {
89+
entries.add(command);
90+
position = -1;
91+
}
92+
93+
public boolean replace(final String currentCommand) {
94+
if (position < 0) return false;
95+
return entries.replace(position, currentCommand);
96+
}
97+
98+
/**
99+
* Navigates to the next (more recent) command.
100+
* <p>
101+
* This method wraps around, i.e. it returns {@code null} when there is no
102+
* more-recent command in the history.
103+
* </p>
104+
*
105+
* @return the next command
106+
*/
107+
public String next() {
108+
position = entries.next(position);
109+
return position < 0 ? null : entries.get(position);
110+
}
111+
112+
/**
113+
* Navigates to the previous (i.e less recent) command.
114+
* <p>
115+
* This method wraps around, i.e. it returns {@code null} when there is no
116+
* less-recent command in the history.
117+
* </p>
118+
*
119+
* @return the previous command
120+
*/
121+
public String previous() {
122+
position = entries.previous(position);
123+
return position < 0 ? null : entries.get(position);
124+
}
125+
126+
@Override
127+
public String toString() {
128+
final StringBuilder builder = new StringBuilder();
129+
int position = -1;
130+
for (;;) {
131+
position = entries.previous(position);
132+
if (position < 0) break;
133+
if (builder.length() > 0) builder.append(" -> ");
134+
if (this.position == position) builder.append("[");
135+
builder.append(entries.get(position));
136+
if (this.position == position) builder.append("]");
137+
}
138+
return builder.toString();
139+
}
140+
}

0 commit comments

Comments
 (0)