Skip to content

Commit

Permalink
Support clear screen in web console. Fix clearing screen starts new s…
Browse files Browse the repository at this point in the history
…ession (fixes #66)
  • Loading branch information
albertlatacz committed Dec 5, 2016
1 parent b9eb480 commit 55abe44
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 42 deletions.
69 changes: 52 additions & 17 deletions src/javarepl/Main.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package javarepl;

import com.googlecode.totallylazy.Exceptions;
import com.googlecode.totallylazy.Lists;
import com.googlecode.totallylazy.Option;
import com.googlecode.totallylazy.Sequence;
import com.googlecode.totallylazy.Strings;
import com.googlecode.totallylazy.functions.Function1;
import javarepl.client.EvaluationLog;
import javarepl.client.EvaluationResult;
import javarepl.client.JavaREPLClient;
import javarepl.completion.CompletionCandidate;
import javarepl.completion.CompletionResult;
import jline.Terminal;
import jline.TerminalFactory;
import jline.console.ConsoleReader;
import jline.console.CursorBuffer;
import jline.console.completer.CandidateListCompletionHandler;
Expand All @@ -24,8 +23,8 @@
import java.nio.file.Files;
import java.util.*;

import static com.googlecode.totallylazy.Exceptions.captureException;
import static com.googlecode.totallylazy.Files.fileOption;
import static com.googlecode.totallylazy.Lists.list;
import static com.googlecode.totallylazy.Option.none;
import static com.googlecode.totallylazy.Option.some;
import static com.googlecode.totallylazy.Sequences.empty;
Expand All @@ -38,11 +37,13 @@
import static com.googlecode.totallylazy.predicates.Not.not;
import static java.lang.String.format;
import static java.lang.System.getProperty;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static javarepl.Utils.applicationVersion;
import static javarepl.Utils.randomServerPort;
import static javarepl.client.EvaluationLog.Type.CONTROL;
import static javarepl.completion.CompletionResult.methods.fromJson;
import static javarepl.completion.CompletionResult.methods.toJson;
import static javarepl.console.commands.ClearScreen.CLEAR_SCREEN_CMD;
import static javax.tools.ToolProvider.getSystemJavaCompiler;

public class Main {
Expand All @@ -53,9 +54,10 @@ public class Main {
public static void main(String... args) throws Exception {
console = new ResultPrinter(printColors(args));

Sequence<String> initialExpressions = initialExpressionsFromFile().join(initialExpressionsFromArgs(args));
ConsoleReader consoleReader = new ConsoleReader(System.in, AnsiConsole.out);
JavaREPLClient client = clientFor(hostname(args), port(args));
ExpressionReader expressionReader = expressionReaderFor(client, initialExpressions);
Sequence<String> initialExpressions = initialExpressionsFromFile().join(initialExpressionsFromArgs(args));
ExpressionReader expressionReader = expressionReaderFor(consoleReader, client, initialExpressions);

Option<String> expression = none();
Option<EvaluationResult> result = none();
Expand All @@ -64,17 +66,48 @@ public static void main(String... args) throws Exception {

if (!expression.isEmpty()) {
result = client.execute(expression.get());
if (!result.isEmpty())
console.printEvaluationResult(result.get());
if (!result.isEmpty()) {
for (EvaluationLog log : result.get().logs()) {
if (!handleTerminalCommand(log)) {
handleTerminalMessage(log);
}
}
}
}
}
}

private static JavaREPLClient clientFor(Option<String> hostname, Option<Integer> port) throws Exception {
console.printInfo(format("Welcome to JavaREPL version %s (%s, Java %s)",
private static void handleTerminalMessage(EvaluationLog log) {
console.printEvaluationLog(log);
}

private static boolean handleTerminalCommand(EvaluationLog log) {
if (log.type().equals(CONTROL)){
switch (log.message()) {
case CLEAR_SCREEN_CMD: {
console.printInfo("\033c");
console.printInfo(welcomeMessage());
console.printInfo(welcomeInstructions());
} break;

default: return false;
}
return true;
}
return false;
}



private static String welcomeMessage() {
return format("Welcome to JavaREPL version %s (%s, Java %s)",
applicationVersion(),
getProperty("java.vm.name"),
getProperty("java.version")));
getProperty("java.version"));
}

private static JavaREPLClient clientFor(Option<String> hostname, Option<Integer> port) throws Exception {
console.printInfo(welcomeMessage());

if (hostname.isEmpty() && port.isEmpty()) {
return startNewLocalInstance("localhost", randomServerPort());
Expand Down Expand Up @@ -108,7 +141,7 @@ private static JavaREPLClient startNewLocalInstance(String hostname, Integer por
System.exit(0);
}

console.printInfo("Type expression to evaluate, \u001B[32m:help\u001B[0m for more options or press \u001B[32mtab\u001B[0m to auto-complete.");
console.printInfo(welcomeInstructions());

ProcessBuilder builder = new ProcessBuilder("java", "-cp", System.getProperty("java.class.path"), Repl.class.getCanonicalName(), "--port=" + port);
builder.redirectErrorStream(true);
Expand All @@ -130,6 +163,10 @@ public void run() {
return replClient;
}

private static String welcomeInstructions() {
return "Type expression to evaluate, \u001B[32m:help\u001B[0m for more options or press \u001B[32mtab\u001B[0m to auto-complete.";
}

private static boolean waitUntilInstanceStarted(JavaREPLClient client) throws Exception {
for (int i = 0; i < 500; i++) {
Thread.sleep(10);
Expand Down Expand Up @@ -169,15 +206,13 @@ private static Boolean printColors(String[] args) {
return !sequence(args).contains("--noColors");
}

private static ExpressionReader expressionReaderFor(final JavaREPLClient client, Sequence<String> initialExpressions) throws IOException {
private static ExpressionReader expressionReaderFor(ConsoleReader consoleReader, final JavaREPLClient client, Sequence<String> initialExpressions) throws IOException {
return new ExpressionReader(new Function1<Sequence<String>, String>() {
private static final char CTRL_C = (char) 3;
private static final char CTRL_D = (char) 4;
private final ConsoleReader consoleReader;
private Sequence<String> expressions = initialExpressions;

{
consoleReader = new ConsoleReader(System.in, AnsiConsole.out);
consoleReader.setCompletionHandler(new JlineCompletionHandler());
consoleReader.setHistoryEnabled(true);
consoleReader.setExpandEvents(false);
Expand Down Expand Up @@ -213,7 +248,7 @@ private jline.console.completer.Completer clientCompleter() {
return (expression, cursor, candidates) -> {
try {
CompletionResult result = client.completions(expression);
candidates.addAll(asList(toJson(result)));
candidates.addAll(singletonList(toJson(result)));
return result.candidates().isEmpty() ? -1 : result.position();
} catch (Exception e) {
return -1;
Expand Down
6 changes: 0 additions & 6 deletions src/javarepl/ResultPrinter.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,6 @@ public void printInfo(String message) {
AnsiConsole.out.println(ansiColored(message));
}

public void printEvaluationResult(EvaluationResult result) {
for (EvaluationLog log : result.logs()) {
printEvaluationLog(log);
}
}

public void printEvaluationLog(EvaluationLog log) {
switch (log.type()) {
case INFO:
Expand Down
2 changes: 1 addition & 1 deletion src/javarepl/client/EvaluationLog.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

public class EvaluationLog {
public static enum Type {
INFO, SUCCESS, ERROR;
INFO, SUCCESS, ERROR, CONTROL;

public static Type type(String type) {
return valueOf(type);
Expand Down
6 changes: 5 additions & 1 deletion src/javarepl/console/ConsoleLog.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

public class ConsoleLog {
public static enum Type {
INFO, SUCCESS, ERROR
INFO, SUCCESS, ERROR, CONTROL
}

private final Type type;
Expand All @@ -15,6 +15,10 @@ private ConsoleLog(Type type, String message) {
this.message = message;
}

public static ConsoleLog control(String message) {
return consoleLog(CONTROL, message);
}

public static ConsoleLog success(String message) {
return consoleLog(SUCCESS, message);
}
Expand Down
4 changes: 4 additions & 0 deletions src/javarepl/console/ConsoleLogger.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ public void info(String message) {
log(ConsoleLog.info(message));
}

public void control(String message) {
log(ConsoleLog.control(message));
}

public void success(String message) {
log(ConsoleLog.success(message));
}
Expand Down
12 changes: 5 additions & 7 deletions src/javarepl/console/commands/ClearScreen.java
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
package javarepl.console.commands;

import javarepl.Evaluator;
import javarepl.completion.CommandCompleter;
import javarepl.console.ConsoleLogger;

import static com.googlecode.totallylazy.predicates.Predicates.equalTo;
import static com.googlecode.totallylazy.Strings.startsWith;

public final class ClearScreen extends Command {
public static final String CLEAR_SCREEN_CMD = "CLEAR_SCREEN";
private static final String COMMAND = ":cls";
private final Evaluator evaluator;
private final ConsoleLogger logger;

public ClearScreen(Evaluator evaluator, ConsoleLogger logger) {
super(COMMAND + " - clear screen", equalTo(COMMAND).or(equalTo(null)), new CommandCompleter(COMMAND));
this.evaluator = evaluator;
public ClearScreen(ConsoleLogger logger) {
super(COMMAND + " - clears screen", startsWith(COMMAND), new CommandCompleter(COMMAND));
this.logger = logger;
}

public void execute(String expression) {
this.logger.reset();
this.logger.info("\033[2J");
this.logger.control(CLEAR_SCREEN_CMD);
}
}
4 changes: 2 additions & 2 deletions src/javarepl/console/rest/RestConsoleResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public Map<String, Object> execute(@FormParam("expression") String expr) {

return emptyMap(String.class, Object.class)
.insert("expression", result.expression())
.insert("logs", result.logs().map(commandResultToModel()));
.insert("logs", result.logs().map(toCommandResultMap()));
}

@POST
Expand Down Expand Up @@ -86,7 +86,7 @@ public Map<String, Object> history() {
.insert("history", console.history().items().toList());
}

private static Function1<ConsoleLog, Map<String, Object>> commandResultToModel() {
private static Function1<ConsoleLog, Map<String, Object>> toCommandResultMap() {
return consoleLog -> emptyMap(String.class, Object.class)
.insert("type", consoleLog.type())
.insert("message", consoleLog.message());
Expand Down
35 changes: 27 additions & 8 deletions src/javarepl/web/term.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,30 @@ function echoCompletionCandidates(term, candidates) {
term.echo(layoutCompletions(candidates, term.width() / 8));
}

function handleTerminalCommand(log, term) {
if (log.type == "CONTROL") {
switch (log.message) {
case "CLEAR_SCREEN":
term.clear();
term.echo(session.welcomeMessage);
term.echo(' ');
break;
}
return true;
}
return false;
}

function handleTerminalMessage(log, term) {
if (log.type != "CONTROL") {
var style = log.type == "ERROR" ? "terminal-message-error" : "terminal-message-success";
term.echo(log.message, messageStyle(style))
return log.type == "ERROR";
}
return false;
}


$(document).ready(function () {
jQuery(function ($, undefined) {
createNewSession(getParam("expression"), getParam("snap"));
Expand All @@ -146,16 +170,11 @@ $(document).ready(function () {
data: {id: session.clientId, expression: expression}
}).done(function (data) {
var hadError = false;

for (var i = 0; i < data.logs.length; i++) {
var style = data.logs[i].type == "ERROR" ? "terminal-message-error" : "terminal-message-success";

if (data.logs[i].type == "ERROR") {
hadError = true;

var log = data.logs[i];
if (!handleTerminalCommand(log, term)) {
hadError = handleTerminalMessage(log, term) || hadError;
}

term.echo(data.logs[i].message, messageStyle(style))
}

if (!hadError) {
Expand Down

0 comments on commit 55abe44

Please sign in to comment.