Skip to content

Commit

Permalink
Command output redirection to file, step II
Browse files Browse the repository at this point in the history
  • Loading branch information
mattirn committed Feb 5, 2020
1 parent abdd432 commit a78b234
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 31 deletions.
28 changes: 18 additions & 10 deletions builtins/src/main/java/org/jline/builtins/ConsoleEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import org.jline.builtins.CommandRegistry;
import org.jline.reader.Completer;
import org.jline.reader.LineReader;
import org.jline.reader.ParsedLine;
import org.jline.reader.Widget;

/**
Expand Down Expand Up @@ -87,14 +86,16 @@ static String plainCommand(String command) {
List<Completer> scriptCompleters();

/**
* Executes parsed line that does not contain known command by the system registry.
* If parsed line is neither JLine or ScriptEngine script it will be evaluated
* Executes command line that does not contain known command by the system registry.
* If the line is neither JLine or ScriptEngine script it will be evaluated
* as ScriptEngine statement.
* @param parsedLine parsed command line
* @param name parsed command/script name
* @param rawLine raw command line
* @param args parsed arguments of the command
* @return command line execution result
* @throws Exception in case of error
*/
Object execute(ParsedLine parsedLine) throws Exception;
Object execute(String name, String rawLine, String[] args) throws Exception;

/**
* Executes either JLine or ScriptEngine script.
Expand All @@ -109,12 +110,12 @@ default Object execute(File script) throws Exception {
/**
* Executes either JLine or ScriptEngine script.
* @param script script file
* @param cmdLine complete command line
* @param rawLine raw command line
* @param args script arguments
* @return script execution result
* @throws Exception in case of error
*/
Object execute(File script, String cmdLine, String[] args) throws Exception;
Object execute(File script, String rawLine, String[] args) throws Exception;

/**
* Post processes execution result. If result is to be assigned to the console variable
Expand All @@ -127,18 +128,25 @@ default Object execute(File script) throws Exception {
Object postProcess(String line, Object result, String output);

/**
* Displays object.
* Print object.
* @param object object to print
*/
void println(Object object);

/**
* Displays object.
* Print object.
* @param options println options
* @param object object to print
*/
void println(Map<String, Object> options, Object object);

/**
* Create console variable
* @param name name of the variable
* @param value value of the variable
*/
void putVariable(String name, Object value);

/**
* Get variable value
* @param name name of the variable
Expand All @@ -150,7 +158,7 @@ default Object execute(File script) throws Exception {
* Delete temporary console variables
*/
void purge();

/**
* Execute widget function
* @param function to execute
Expand Down
39 changes: 29 additions & 10 deletions builtins/src/main/java/org/jline/builtins/ConsoleEngineImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public enum Command {SHOW
, ALIAS
, UNALIAS
, SLURP};
private static final String VAR_CONSOLE_OPTIONS = "CONSOLE_OPTIONS";
private static final String VAR_PRNT_OPTIONS = "PRNT_OPTIONS";
private static final String VAR_PATH = "PATH";
private static final String VAR_NANORC = "NANORC";
Expand Down Expand Up @@ -526,18 +527,16 @@ public Object execute(File script, String cmdLine, String[] args) throws Excepti
}

@Override
public Object execute(ParsedLine pl) throws Exception {
if (pl.line().trim().startsWith("#")) {
public Object execute(String cmd, String line, String[] args) throws Exception {
if (line.trim().startsWith("#")) {
return null;
}
String[] args = pl.words().subList(1, pl.words().size()).toArray(new String[0]);
String cmd = ConsoleEngine.plainCommand(Parser.getCommand(pl.word()));
Object out = null;
ScriptFile file = new ScriptFile(cmd, pl.line(), args);
ScriptFile file = new ScriptFile(cmd, line, args);
if (file.execute()) {
out = file.getResult();
} else {
String line = pl.line().trim();
line = line.trim();
if (isCodeBlock(line)) {
StringBuilder sb = new StringBuilder();
for (String s: line.split("\n|\n\r")) {
Expand Down Expand Up @@ -585,12 +584,17 @@ public Object execute(ParsedLine pl) throws Exception {
}
return out;
}

@Override
public void purge() {
engine.del("_*");
}

@Override
public void putVariable(String name, Object value) {
engine.put(name, value);
}

@Override
public Object getVariable(String name) {
if (!engine.hasVariable(name)) {
Expand All @@ -616,17 +620,32 @@ public boolean executeWidget(Object function) {
return true;
}

@SuppressWarnings("unchecked")
private boolean splitCommandOutput() {
boolean out = true;
try {
if (engine.hasVariable(VAR_CONSOLE_OPTIONS)) {
out = (boolean) ((Map<String, Object>) engine.get(VAR_CONSOLE_OPTIONS)).getOrDefault("splitOutput", true);
}
} catch (Exception e) {
println(new Exception("Bad CONSOLE_OPTION value: " + e.getMessage()));
}
return out;
}


@Override
public Object postProcess(String line, Object result, String output) {
Object out = result;
Object _output = output != null && splitCommandOutput() ? output.split("\n") : output;
if (Parser.getVariable(line) != null && result != null) {
engine.put("output", output);
engine.put("output", _output);
}
if (systemRegistry.hasCommand(Parser.getCommand(line))) {
out = postProcess(line, Parser.getVariable(line) != null && result == null ? output : result);
out = postProcess(line, Parser.getVariable(line) != null && result == null ? _output : result);
} else if (Parser.getVariable(line) != null) {
if (result == null) {
engine.put(Parser.getVariable(line), output);
engine.put(Parser.getVariable(line), _output);
}
out = null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,14 @@ public interface SystemRegistry extends CommandRegistry {
* Delete temporary console variables and reset output streams
*/
void cleanUp();

/**
* Print exception on terminal
* @param exception exception to print on terminal
*/
void println(Exception exception);

/**
*
* @return terminal
*/
Terminal terminal();
Expand Down
40 changes: 32 additions & 8 deletions builtins/src/main/java/org/jline/builtins/SystemRegistryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,6 @@ public CommandOutputStream(Terminal terminal) {

public void redirect() throws IOException {
byteOutputStream = new ByteArrayOutputStream();
doTerminal(byteOutputStream);
}

public void redirect(File file, boolean append) throws IOException {
Expand All @@ -345,10 +344,13 @@ public void redirect(File file, boolean append) throws IOException {
}
}
fileOutputStream = new FileOutputStream(file, append);
doTerminal(fileOutputStream);
}

void doTerminal(OutputStream outputStream) throws IOException {
public void open() throws IOException {
if (redirecting || (byteOutputStream == null && fileOutputStream == null)) {
return;
}
OutputStream outputStream = byteOutputStream != null ? byteOutputStream : fileOutputStream;
out = new PrintStream(outputStream);
System.setOut(out);
System.setErr(out);
Expand All @@ -357,7 +359,7 @@ void doTerminal(OutputStream outputStream) throws IOException {
this.commandSession = new CommandRegistry.CommandSession(terminal, terminal.input(), out, out);
redirecting = true;
}

public void flush() {
if (out == null) {
return;
Expand Down Expand Up @@ -404,6 +406,14 @@ public String getOutput() {
return output;
}

public boolean isRedirecting() {
return redirecting;
}

public boolean isByteStream() {
return redirecting && byteOutputStream != null;
}

public void reset() {
if (redirecting) {
out = null;
Expand Down Expand Up @@ -444,16 +454,19 @@ public Object execute(String line) throws Exception {
break;
}
}
String rawLine = lastArg < words.size() ? words.subList(0, lastArg).stream().collect(Collectors.joining(" ")) : pl.line();
String[] argv = words.subList(1, lastArg).toArray(new String[0]);
Object out = null;
exception = null;
boolean statement = false;
try {
if ((var != null || toFile != null) && consoleId != null && !consoleEngine().isExecuting()) {
if (toFile != null) {
outputStream.redirect(toFile, append);
} else {
outputStream.redirect();
}
outputStream.open();
}
if (isLocalCommand(cmd)) {
out = localExecute(cmd, argv);
Expand All @@ -467,20 +480,25 @@ public Object execute(String line) throws Exception {
out = commandRegistries[id].execute(outputStream.getCommandSession(), cmd, argv);
}
} else if (consoleId != null) {
out = consoleEngine().execute(pl);
if (outputStream.isByteStream() && !consoleEngine().scripts().contains(cmd)) {
outputStream.close();
outputStream.reset();
statement = true;
}
out = consoleEngine().execute(cmd, rawLine, argv);
}
}
} catch (HelpException e) {
println(e);
} finally {
if (consoleId != null && !consoleEngine().isExecuting()) {
if (consoleId != null && !consoleEngine().isExecuting() && !statement) {
outputStream.flush();
out = consoleEngine().postProcess(pl.line(), out, outputStream.getOutput());
}
}
return out;
}

public void cleanUp() {
if (consoleId == null) {
return;
Expand All @@ -490,8 +508,14 @@ public void cleanUp() {
consoleEngine().purge();
}

private void println(Exception exception) {
@Override
public void println(Exception exception) {
if (consoleId != null) {
if (outputStream.isRedirecting()) {
outputStream.close();
outputStream.reset();
}
consoleEngine().putVariable("exception", exception);
consoleEngine().println(exception);
} else {
SystemRegistry.println(false, terminal(), exception);
Expand Down
3 changes: 1 addition & 2 deletions demo/src/main/java/org/jline/demo/Repl.java
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,7 @@ public static void main(String[] args) {
break;
}
catch (Exception e) {
consoleEngine.println(e);
scriptEngine.put("exception", e); // save exception to console variable
systemRegistry.println(e); // print exception and save it to console variable
}
}
}
Expand Down

0 comments on commit a78b234

Please sign in to comment.