Skip to content

Commit

Permalink
Execute command inside code block
Browse files Browse the repository at this point in the history
  • Loading branch information
mattirn committed Jan 14, 2020
1 parent 5dbec17 commit 7be7b2b
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 19 deletions.
19 changes: 11 additions & 8 deletions builtins/src/main/java/org/jline/builtins/CommandRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@

import org.jline.builtins.Completers;
import org.jline.builtins.Widgets;
import org.jline.reader.*;

import java.util.List;
import java.util.Map;
import java.util.Set;

public interface CommandRegistry {

/**
* Aggregate SystemCompleters of commandRegisteries
* @return uncompiled SystemCompleter
Expand Down Expand Up @@ -51,7 +50,7 @@ static Completers.SystemCompleter compileCompleters(CommandRegistry ... commandR
* @return a map with alias keys and command name values
*/
Map<String, String> commandAliases();

/**
* Returns a short info about command known by this registry.
* @return a short info about command
Expand All @@ -68,24 +67,28 @@ static Completers.SystemCompleter compileCompleters(CommandRegistry ... commandR
/**
* 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();

/**
* Returns a command description for use in the JLine Widgets framework.
* @param command name of the command whose description to return
* @param command name of the command whose description to return
* @return command description for JLine TailTipWidgets to be displayed
* in the terminal status bar.
*/
Widgets.CmdDesc commandDescription(String command);

default Object execute(String command, String[] args) throws Exception {
throw new IllegalArgumentException("CommandRegistry has no implementation: execute(String command, String[] args)");
throw new IllegalArgumentException("CommandRegistry method execute(String command, String[] args) is not implemented!");
}

default Object invoke(String command, Object... args) throws Exception {
throw new IllegalArgumentException("CommandRegistry has no implementation: invoke(String command, Object... args)");
String[] _args = new String[args.length];
for (int i = 0; i < args.length; i++) {
_args[i] = args[i].toString();
}
return execute(command, _args);
}
}
38 changes: 28 additions & 10 deletions builtins/src/main/java/org/jline/builtins/ConsoleEngineImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public ConsoleEngineImpl(ScriptEngine engine, Parser parser, Terminal terminal)
commandExecute.put(Command.SHOW, new CommandMethods(this::show, this::defaultCompleter));
}

@Override
public void setSystemRegistry(SystemRegistry systemRegistry) {
this.systemRegistry = systemRegistry;
}
Expand All @@ -68,6 +69,7 @@ public ConsoleEngineImpl scriptExtension(String extension) {
return this;
}

@Override
public Set<String> commandNames() {
return nameCommand.keySet();
}
Expand All @@ -76,6 +78,7 @@ public Map<String, String> commandAliases() {
return aliasCommand;
}

@Override
public boolean hasCommand(String name) {
if (nameCommand.containsKey(name) || aliasCommand.containsKey(name)) {
return true;
Expand Down Expand Up @@ -122,10 +125,12 @@ public void alias(String alias, String command) {
aliasCommand.put(alias, command);
}

@Override
public List<String> commandInfo(String command) {
return new ArrayList<>();
}

@Override
public Completers.SystemCompleter compileCompleters() {
SystemCompleter out = new SystemCompleter();
for (Map.Entry<Command, String> entry: commandName.entrySet()) {
Expand All @@ -135,6 +140,7 @@ public Completers.SystemCompleter compileCompleters() {
return out;
}

@Override
public Widgets.CmdDesc commandDescription(String command) {
return null;
}
Expand Down Expand Up @@ -181,12 +187,13 @@ private String quote(String var) {
|| (var.startsWith("'") && var.endsWith("'"))) {
return var;
}
if (var.contains("\\\"")) {
if (!var.contains("\\\"")) {
return "'" + var + "'";
}
return "\\\"" + var + "\\\"";
}

@Override
public Object execute(ParsedLine pl) throws Exception {
if (pl.line().trim().startsWith("#")) {
return null;
Expand Down Expand Up @@ -239,20 +246,31 @@ public Object execute(ParsedLine pl) throws Exception {
String line = pl.line();
if (isCodeBlock(line)) {
StringBuilder sb = new StringBuilder();
boolean copyRegistry = false;
String registry = "_systemRegistry";
for (String s: line.split("\n|\n\r")) {
if (isCommandLine(s)) {
copyRegistry = true;
List<String> ws = parser.parse(s, 0, ParseContext.COMPLETE).words();
int idx = ws.get(0).lastIndexOf(":");
if (idx > 0) {
sb.append(ws.get(0).substring(0, idx - 1));
sb.append(ws.get(0).substring(0, idx));
}
sb.append(registry + ".invoke('" + ws.get(0).substring(idx + 1) + "'");
String[] argv = new String[ws.size()];
for (int i = 1; i < ws.size(); i++) {
argv[i] = ws.get(i);
if (argv[i].startsWith("${")) {
Matcher argvMatcher = Pattern.compile("\\$\\{(.*)}").matcher(argv[i]);
if (argvMatcher.find()) {
argv[i] = argv[i].replace(argv[i], argvMatcher.group(1));
}
} else if (argv[i].startsWith("$")) {
argv[i] = argv[i].substring(1);
} else {
argv[i] = quote(argv[i]);
}
}
sb.append("org.jline.builtins.SystemRegistry.get().invoke('" + ws.get(0).substring(idx + 1) + "'");
for (int i = 1; i < argv.length; i++) {
sb.append(", ");
sb.append(ws.get(i));
sb.append(argv[i]);
}
sb.append(")");
} else {
Expand All @@ -261,9 +279,6 @@ public Object execute(ParsedLine pl) throws Exception {
sb.append("\n");
}
line = sb.toString();
if (copyRegistry && !engine.hasVariable(registry)) {
engine.put(registry, systemRegistry);
}
}
if (engine.hasVariable(line)) {
out = engine.get(line);
Expand All @@ -276,6 +291,7 @@ public Object execute(ParsedLine pl) throws Exception {
return out;
}

@Override
public Object postProcess(String line, Object result) {
Object out = result;
if (Parser.getVariable(line) != null) {
Expand All @@ -285,6 +301,7 @@ public Object postProcess(String line, Object result) {
return out;
}

@Override
public Object execute(String command, String[] args) throws Exception {
exception = null;
Object out = commandExecute.get(command(command)).executeFunction().apply(new Builtins.CommandInput(args));
Expand All @@ -294,6 +311,7 @@ public Object execute(String command, String[] args) throws Exception {
return out;
}

@Override
public void println(Map<String, Object> options, Object object) {
options.putIfAbsent("width", terminal.getSize().getColumns());
for (AttributedString as : engine.format(options, object)) {
Expand Down
32 changes: 32 additions & 0 deletions builtins/src/main/java/org/jline/builtins/SystemRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,41 @@
*/
package org.jline.builtins;

import java.util.HashMap;
import java.util.Map;

import org.jline.reader.ParsedLine;

public interface SystemRegistry extends CommandRegistry {

Object execute(ParsedLine parsedLine) throws Exception;

static SystemRegistry get() {
return Registeries.getInstance().getSystemRegistry();
}

static void put(SystemRegistry systemRegistry) {
Registeries.getInstance().addRegistry(systemRegistry);
}

public class Registeries {
private static Registeries instance = new Registeries();
private Map<Long, SystemRegistry> systemRegisteries = new HashMap<>();

private Registeries () {}

public static Registeries getInstance() {
return instance;
}

public void addRegistry(SystemRegistry systemRegistry) {
systemRegisteries.put(Thread.currentThread().getId(), systemRegistry);
}

public SystemRegistry getSystemRegistry() {
return systemRegisteries.getOrDefault(Thread.currentThread().getId(), null);
}

}

}
14 changes: 14 additions & 0 deletions builtins/src/main/java/org/jline/builtins/SystemRegistryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public SystemRegistryImpl(CommandRegistry... commandRegistries) {
throw new IllegalArgumentException();
}
}
SystemRegistry.put(this);
}

public Set<String> commandNames() {
Expand Down Expand Up @@ -75,6 +76,19 @@ public Widgets.CmdDesc commandDescription(String command) {
return id > -1 ? commandRegistries[id].commandDescription(command) : new Widgets.CmdDesc(false);
}

public Object execute(String command, String[] args) throws Exception {
return null;
}

public Object invoke(String command, Object... args) throws Exception {
Object out = null;
int id = registryId(command);
if (id > -1) {
out = commandRegistries[id].invoke(command, args);
}
return out;
}

public Object execute(ParsedLine pl) throws Exception {
String[] argv = pl.words().subList(1, pl.words().size()).toArray(new String[0]);
String cmd = Parser.getCommand(pl.word());
Expand Down
2 changes: 1 addition & 1 deletion reader/src/main/java/org/jline/reader/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

public interface Parser {
static final String REGEX_VARIABLE = "[a-zA-Z]{1,}[a-zA-Z0-9_-]*";
static final String REGEX_COMMAND = REGEX_VARIABLE;
static final String REGEX_COMMAND = "[:]{0,1}" + REGEX_VARIABLE;

ParsedLine parse(String line, int cursor, ParseContext context) throws SyntaxError;

Expand Down

0 comments on commit 7be7b2b

Please sign in to comment.