Skip to content

Commit

Permalink
Merge pull request #507 from mattirn/output-redirection
Browse files Browse the repository at this point in the history
Output redirection
  • Loading branch information
mattirn committed Feb 7, 2020
2 parents 58c3858 + 9bf0efe commit b471f94
Show file tree
Hide file tree
Showing 9 changed files with 562 additions and 207 deletions.
59 changes: 26 additions & 33 deletions builtins/src/main/java/org/jline/builtins/Builtins.java
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ public boolean hasCommand(String name) {
return false;
}

@Override
public SystemCompleter compileCompleters() {
SystemCompleter out = new SystemCompleter();
for (Map.Entry<Command, String> entry: commandName.entrySet()) {
Expand All @@ -163,31 +164,18 @@ private Command command(String name) {
}

@Override
public Object execute(String command, String[] args) throws Exception {
return execute(command, Arrays.asList(args));
}

private Object execute(String command, List<String> args) throws Exception {
execute(command, args, System.in, System.out, System.err);
return null;
}

public void execute(String command, List<String> args, InputStream in, PrintStream out, PrintStream err) throws Exception {
execute(command, args.toArray(new String[0]), in, out, err);
}

public void execute(String command, String[] args, InputStream in, PrintStream out, PrintStream err) throws Exception {
public Object execute(CommandRegistry.CommandSession session, String command, String[] args) throws Exception {
exception = null;
commandExecute.get(command(command)).execute().accept(new CommandInput(args, in, out, err));
commandExecute.get(command(command)).execute().accept(new CommandInput(args, session));
if (exception != null) {
throw exception;
}
return null;
}

private List<OptDesc> commandOptions(String command) {
List<String> args = Arrays.asList("--help");
try {
execute(command, args);
execute(new CommandRegistry.CommandSession(), command, new String[] {"--help"});
} catch (HelpException e) {
return compileCommandOptions(e.getMessage());
} catch (Exception e) {
Expand All @@ -196,21 +184,17 @@ private List<OptDesc> commandOptions(String command) {
return null;
}

private Terminal terminal() {
return reader.getTerminal();
}

private void less(CommandInput input) {
try {
Commands.less(terminal(), input.in(), input.out(), input.err(), workDir.get(), input.args());
Commands.less(input.terminal(), input.in(), input.out(), input.err(), workDir.get(), input.args());
} catch (Exception e) {
this.exception = e;
}
}

private void nano(CommandInput input) {
try {
Commands.nano(terminal(), input.out(), input.err(), workDir.get(), input.args(), configPath);
Commands.nano(input.terminal(), input.out(), input.err(), workDir.get(), input.args(), configPath);
} catch (Exception e) {
this.exception = e;
}
Expand Down Expand Up @@ -266,7 +250,7 @@ private void unsetopt(CommandInput input) {

private void ttop(CommandInput input) {
try {
TTop.ttop(terminal(), input.out(), input.err(), input.args());
TTop.ttop(input.terminal(), input.out(), input.err(), input.args());
} catch (Exception e) {
this.exception = e;
}
Expand Down Expand Up @@ -502,27 +486,32 @@ public static List<String> compileCommandInfo(String helpMessage) {
return out;
}

public static class CommandInput{
public static class CommandInput {
String[] args;
Object[] xargs;
Terminal terminal;
InputStream in;
PrintStream out;
PrintStream err;

public CommandInput(String[] args) {
this(args, null, null, null);
public CommandInput(String[] args, CommandRegistry.CommandSession session) {
this(args, null, session);
}

public CommandInput(Object[] xargs, boolean dumb) {
this.xargs = xargs;
this.args = new String[xargs.length];
for (int i = 0; i < xargs.length; i++) {
args[i] = xargs[i] != null ? xargs[i].toString() : "";
public CommandInput(String[] args, Object[] xargs, CommandRegistry.CommandSession session) {
this(args, session.terminal(), session.in(), session.out(), session.err());
if (xargs != null) {
this.xargs = xargs;
this.args = new String[xargs.length];
for (int i = 0; i < xargs.length; i++) {
this.args[i] = xargs[i] != null ? xargs[i].toString() : "";
}
}
}

public CommandInput(String[] args, InputStream in, PrintStream out, PrintStream err) {
public CommandInput(String[] args, Terminal terminal, InputStream in, PrintStream out, PrintStream err) {
this.args = args;
this.terminal = terminal;
this.in = in;
this.out = out;
this.err = err;
Expand All @@ -536,6 +525,10 @@ public Object[] xargs() {
return xargs;
}

public Terminal terminal() {
return terminal;
}

public InputStream in() {
return in;
}
Expand Down
78 changes: 63 additions & 15 deletions builtins/src/main/java/org/jline/builtins/CommandRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
import org.jline.builtins.Completers;
import org.jline.builtins.Widgets;
import org.jline.builtins.Options.HelpException;
import org.jline.terminal.Terminal;

import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
Expand All @@ -26,6 +29,7 @@ public interface CommandRegistry {

/**
* Aggregate SystemCompleters of commandRegisteries
* @param commandRegistries command registeries which completers is to be aggregated
* @return uncompiled SystemCompleter
*/
static Completers.SystemCompleter aggregateCompleters(CommandRegistry ... commandRegistries) {
Expand All @@ -38,6 +42,7 @@ static Completers.SystemCompleter aggregateCompleters(CommandRegistry ... comman

/**
* Aggregate and compile SystemCompleters of commandRegisteries
* @param commandRegistries command registeries which completers is to be aggregated and compile
* @return compiled SystemCompleter
*/
static Completers.SystemCompleter compileCompleters(CommandRegistry ... commandRegistries) {
Expand All @@ -48,7 +53,7 @@ static Completers.SystemCompleter compileCompleters(CommandRegistry ... commandR

/**
* Returns the name of this registry.
* @return name
* @return the name of the registry
*/
default String name() {
return this.getClass().getSimpleName();
Expand All @@ -71,7 +76,7 @@ default String name() {
*/
default List<String> commandInfo(String command) {
try {
invoke(command, new Object[] {"--help"});
invoke(new CommandSession(), command, new Object[] {"--help"});
} catch (HelpException e) {
return Builtins.compileCommandInfo(e.getMessage());
} catch (Exception e) {
Expand All @@ -90,7 +95,6 @@ default List<String> commandInfo(String command) {
/**
* Returns a {@code SystemCompleter} that can provide detailed completion
* information for all registered commands.
*
* @return a SystemCompleter that can provide command completion for all registered commands
*/
Completers.SystemCompleter compileCompleters();
Expand All @@ -103,7 +107,7 @@ default List<String> commandInfo(String command) {
*/
default Widgets.CmdDesc commandDescription(String command) {
try {
invoke(command, new Object[] {"--help"});
invoke(new CommandSession(), command, new Object[] {"--help"});
} catch (HelpException e) {
return Builtins.compileCommandDescription(e.getMessage());
} catch (Exception e) {
Expand All @@ -115,32 +119,76 @@ default Widgets.CmdDesc commandDescription(String command) {
/**
* Execute a command that have only string parameters and options. Implementation of the method is required
* when aggregating command registries using SystemRegistry.
* @param command
* @param args
* @return result
* @throws Exception
* @param session the data of the current command session
* @param command the name of the command
* @param args arguments of the command
* @return result of the command execution
* @throws Exception in case of error
*/
default Object execute(String command, String[] args) throws Exception {
default Object execute(CommandSession session, String command, String[] args) throws Exception {
throw new IllegalArgumentException("CommandRegistry method execute(String command, String[] args) is not implemented!");
}

/**
* Execute a command. If command has other than string parameters a custom implementation is required.
* This method will be called only when we have ConsoleEngine in SystemRegistry.
* @param command
* @param args
* @return result
* @throws Exception
* @param session the data of the current command session
* @param command the name of the command
* @param args arguments of the command
* @return result of the command execution
* @throws Exception in case of error
*/
default Object invoke(String command, Object... args) throws Exception {
default Object invoke(CommandSession session, String command, Object... args) throws Exception {
String[] _args = new String[args.length];
for (int i = 0; i < args.length; i++) {
if (!(args[i] instanceof String)) {
throw new IllegalArgumentException();
}
_args[i] = args[i].toString();
}
return execute(command, _args);
return execute(session, command, _args);
}

public static class CommandSession {
private final Terminal terminal;
private final InputStream in;
private final PrintStream out;
private final PrintStream err;

public CommandSession() {
this.in = System.in;
this.out = System.out;
this.err = System.err;
this.terminal = null;
}

public CommandSession(Terminal terminal) {
this(terminal, terminal.input(), new PrintStream(terminal.output()), new PrintStream(terminal.output()));
}

public CommandSession(Terminal terminal, InputStream in, PrintStream out, PrintStream err) {
this.terminal = terminal;
this.in = in;
this.out = out;
this.err = err;
}

public Terminal terminal() {
return terminal;
}

public InputStream in() {
return in;
}

public PrintStream out() {
return out;
}

public PrintStream err() {
return err;
}

}

}
Loading

0 comments on commit b471f94

Please sign in to comment.