Skip to content

Commit

Permalink
history command: implemented some missing options
Browse files Browse the repository at this point in the history
  • Loading branch information
mattirn committed Mar 2, 2019
1 parent 367a5bf commit d08ba29
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 19 deletions.
106 changes: 89 additions & 17 deletions builtins/src/main/java/org/jline/builtins/Commands.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.io.InputStream;
import java.io.PrintStream;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
Expand All @@ -24,13 +25,15 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import java.util.Set;
import java.util.TreeSet;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

import org.jline.builtins.Completers.CompletionData;
import org.jline.builtins.Options;
import org.jline.builtins.Source.StdInSource;
import org.jline.builtins.Source.URLSource;
import org.jline.keymap.KeyMap;
Expand Down Expand Up @@ -159,26 +162,31 @@ public static void less(Terminal terminal, InputStream in, PrintStream out, Prin
}

public static void history(LineReader reader, PrintStream out, PrintStream err,
String[] argv) throws IOException {
String[] argv) throws IOException, IllegalArgumentException {
final String[] usage = {
"history - list history of commands",
"Usage: history [OPTIONS]",
"Usage: history [-dnrfEi] [-m match] [first] [last]",
" history --clear",
" history --save",
" -? --help Displays command help",
" --clear Clear history",
" --save Save history",
" -d Print timestamps for each event"};

" -m match If option -m is present the first argument is taken as a pattern",
" and only the history events matching the pattern will be shown",
" -d Print timestamps for each event",
" -f Print full time-date stamps in the US format",
" -E Print full time-date stamps in the European format",
" -i Print full time-date stamps in ISO8601 format",
" -n Suppresses command numbers",
" -r Reverses the order of the commands",
" [first] [last] These optional arguments are numbers. A negative number is",
" used as an offset to the current history event number"};
Options opt = Options.compile(usage).parse(argv);

if (opt.isSet("help")) {
opt.usage(err);
return;
}
if (!opt.args().isEmpty()) {
err.println("usage: history [OPTIONS]");
return;
}

History history = reader.getHistory();
if (opt.isSet("clear")) {
history.purge();
Expand All @@ -189,24 +197,88 @@ public static void history(LineReader reader, PrintStream out, PrintStream err,
if (opt.isSet("clear") || opt.isSet("save")) {
return;
}
int argId = 0;
Pattern pattern = null;
if (opt.isSet("m")) {
if (opt.args().size() == 0) {
throw new IllegalArgumentException();
}
String sp = opt.args().get(argId++);
pattern = Pattern.compile(sp.toString());
}
int firstId = opt.args().size() > argId ? parseInteger(opt.args().get(argId++)) : -17;
int lastId = opt.args().size() > argId ? parseInteger(opt.args().get(argId++)) : -1;
firstId = historyId(firstId, history.size() - 1);
lastId = historyId(lastId, history.size() - 1);
if (firstId > lastId) {
throw new IllegalArgumentException();
}
int tot = lastId - firstId + 1;
int listed = 0;
final Highlighter highlighter = reader.getHighlighter();
for (History.Entry entry : history) {
Iterator<History.Entry> iter = null;
if (opt.isSet("r")) {
iter = history.reverseIterator(lastId);
} else {
iter = history.iterator(firstId);
}
while (iter.hasNext() && listed < tot) {
History.Entry entry = iter.next();
listed++;
if (pattern != null && !pattern.matcher(entry.line()).matches()) {
continue;
}
AttributedStringBuilder sb = new AttributedStringBuilder();
sb.append(" ");
sb.styled(AttributedStyle::bold, String.format("%3d", entry.index() + 1));
if (opt.isSet("d")) {
if (!opt.isSet("n")) {
sb.append(" ");
sb.styled(AttributedStyle::bold, String.format("%3d", entry.index()));
}
if (opt.isSet("d") || opt.isSet("f") || opt.isSet("E") || opt.isSet("i")) {
sb.append(" ");
LocalTime lt = LocalTime.from(entry.time().atZone(ZoneId.systemDefault()))
.truncatedTo(ChronoUnit.SECONDS);
DateTimeFormatter.ISO_LOCAL_TIME.formatTo(lt, sb);
if (opt.isSet("d")) {
LocalTime lt = LocalTime.from(entry.time().atZone(ZoneId.systemDefault()))
.truncatedTo(ChronoUnit.SECONDS);
DateTimeFormatter.ISO_LOCAL_TIME.formatTo(lt, sb);
} else {
LocalDateTime lt = LocalDateTime.from(entry.time().atZone(ZoneId.systemDefault())
.truncatedTo(ChronoUnit.MINUTES));
String format = "yyyy-MM-dd hh:mm";
if (opt.isSet("f")) {
format = "MM/dd/yy hh:mm";
} else if (opt.isSet("E")) {
format = "dd.MM.yyyy hh:mm";
}
DateTimeFormatter.ofPattern(format).formatTo(lt, sb);
}
}
sb.append(" ");
sb.append(highlighter.highlight(reader, entry.line()));
out.println(sb.toAnsi(reader.getTerminal()));
}
}

public static void complete(LineReader reader, PrintStream out, PrintStream err,
private static int historyId(int id, int maxId) {
int out = id;
if (id < 0) {
out = maxId + id + 1;
}
if (out < 0) {
out = 0;
} else if (out > maxId) {
out = maxId;
}
return out;
}

private static int parseInteger(String s) throws IllegalArgumentException {
try {
return Integer.parseInt(s);
} catch (NumberFormatException ex) {
throw new IllegalArgumentException();
}
}

public static void complete(LineReader reader, PrintStream out, PrintStream err,
Map<String, List<CompletionData>> completions,
String[] argv) {
final String[] usage = {
Expand Down
2 changes: 1 addition & 1 deletion builtins/src/main/java/org/jline/builtins/Options.java
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ else if (needArg != null) {
needArg = null;
needOpt = null;
}
else if (!arg.startsWith("-") || "-".equals(oarg)) {
else if (!arg.startsWith("-") || (arg.length() > 1 && Character.isDigit(arg.charAt(1))) || "-".equals(oarg)) {
if (optionsFirst)
endOpt = true;
xargs.add(oarg);
Expand Down
7 changes: 6 additions & 1 deletion builtins/src/test/java/org/jline/example/Example.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.jline.builtins.Commands;
import org.jline.builtins.Completers;
import org.jline.builtins.Completers.TreeCompleter;
import org.jline.keymap.KeyMap;
Expand Down Expand Up @@ -134,7 +135,7 @@ public static void main(String[] args) throws IOException {
case "brackets":
prompt = "long-prompt> ";
DefaultParser p2 = new DefaultParser();
p2.eofOnUnclosedBracket(Bracket.CURLY,Bracket.ROUND,Bracket.SQUARE);
p2.setEofOnUnclosedBracket(Bracket.CURLY, Bracket.ROUND, Bracket.SQUARE);
parser = p2;
break label;
case "foo":
Expand Down Expand Up @@ -305,6 +306,7 @@ public void complete(LineReader reader, ParsedLine line, List<Candidate> candida
break;
}
ParsedLine pl = reader.getParser().parse(line, 0);
String[] argv = pl.words().subList(1, pl.words().size()).toArray(new String[0]);
if ("set".equals(pl.word())) {
if (pl.words().size() == 3) {
reader.setVariable(pl.words().get(1), pl.words().get(2));
Expand Down Expand Up @@ -380,6 +382,9 @@ else if ("cls".equals(pl.word())) {
else if ("sleep".equals(pl.word())) {
Thread.sleep(3000);
}
else if ("history".equals(pl.word())) {
Commands.history(reader, System.out, System.err, argv);
}
}
}
catch (Throwable t) {
Expand Down

0 comments on commit d08ba29

Please sign in to comment.