Skip to content

Instantly share code, notes, and snippets.

@gnodet
Created August 11, 2019 15:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gnodet/6863cda58b4e202c111553b359238a6c to your computer and use it in GitHub Desktop.
Save gnodet/6863cda58b4e202c111553b359238a6c to your computer and use it in GitHub Desktop.
package org.jline.example;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.StringTokenizer;
import org.jline.reader.Completer;
import org.jline.reader.EndOfFileException;
import org.jline.reader.LineReader;
import org.jline.reader.LineReaderBuilder;
import org.jline.reader.UserInterruptException;
import org.jline.reader.impl.completer.ArgumentCompleter;
public class ConsoleRunner {
private static LineReader reader;
private static InputStream systemIn = System.in;
public static LineReader getReader() { return reader; }
public static final String property = "jline.history";
public static void main(final String[] args) throws Exception {
List<String> argList = new ArrayList<>(Arrays.asList(args));
if (argList.size() == 0) {
usage();
return;
}
String historyFileName = System.getProperty(ConsoleRunner.property, null);
// invoke the main() method
String mainClass = (String) argList.remove(0);
// setup the inpout stream
LineReaderBuilder builder = LineReaderBuilder.builder();
if (historyFileName != null) {
builder.variable(LineReader.HISTORY_FILE, new File
(System.getProperty("user.home"),
".jline-" + mainClass
+ "." + historyFileName + ".history"));
} else {
builder.variable(LineReader.HISTORY_FILE, new File
(System.getProperty("user.home"),
".jline-" + mainClass + ".history"));
}
String completors = System.getProperty
(ConsoleRunner.class.getName() + ".completors", "");
List<Completer> completorList = new ArrayList<>();
for (StringTokenizer tok = new StringTokenizer(completors, ",");
tok.hasMoreTokens();) {
completorList.add((Completer) Class.forName(tok.nextToken()).newInstance());
}
if (completorList.size() > 0) {
builder.completer(new ArgumentCompleter(completorList));
}
reader = LineReaderBuilder.builder().build();
System.setIn(new ConsoleReaderInputStream(reader));
try {
Class.forName(mainClass).
getMethod("main", new Class[] { String[].class }).
invoke(null, new Object[] { argList.toArray(new String[0]) });
} finally {
// just in case this main method is called from another program
System.setIn(systemIn);
}
}
private static void usage() {
System.out.println("Usage: \n java " + "[-Djline.history='name'] "
+ ConsoleRunner.class.getName()
+ " <target class name> [args]"
+ "\n\nThe -Djline.history option will avoid history"
+ "\nmangling when running ConsoleRunner on the same application."
+ "\n\nargs will be passed directly to the target class name.");
}
}
class ConsoleReaderInputStream extends SequenceInputStream {
public ConsoleReaderInputStream(final LineReader reader) {
super(new ConsoleEnumeration(reader));
}
private static class ConsoleEnumeration implements Enumeration<ConsoleLineInputStream> {
private final LineReader reader;
private ConsoleLineInputStream next = null;
private ConsoleLineInputStream prev = null;
public ConsoleEnumeration(final LineReader reader) {
this.reader = reader;
}
public ConsoleLineInputStream nextElement() {
if (next != null) {
ConsoleLineInputStream n = next;
prev = next;
next = null;
return n;
}
return new ConsoleLineInputStream(reader);
}
public boolean hasMoreElements() {
// the last line was null
if ((prev != null) && prev.wasNull) {
return false;
}
if (next == null) {
next = nextElement();
}
return next != null;
}
}
private static class ConsoleLineInputStream extends InputStream {
private final LineReader reader;
private String line = null;
private int index = 0;
private boolean eol = false;
protected boolean wasNull = false;
public ConsoleLineInputStream(final LineReader reader) {
this.reader = reader;
}
public int read() throws IOException {
if (eol) {
return -1;
}
if (line == null) {
try {
line = reader.readLine();
} catch (UserInterruptException | EndOfFileException e) {
line = null;
}
}
if (line == null) {
wasNull = true;
return -1;
}
if (index >= line.length()) {
eol = true;
return '\n'; // lines are ended with a newline
}
return line.charAt(index++);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment