diff --git a/core/deployment/src/main/java/io/quarkus/deployment/console/AeshConsole.java b/core/deployment/src/main/java/io/quarkus/deployment/console/AeshConsole.java index 3eb446e39c04ca..ec84aac3358d71 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/console/AeshConsole.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/console/AeshConsole.java @@ -1,7 +1,10 @@ package io.quarkus.deployment.console; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; import java.util.TreeMap; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.locks.Lock; @@ -564,11 +567,51 @@ public void run() { } catch (Exception e) { throw new RuntimeException(e); } + } + + @Override + public Map singleLetterAliases() { + try { + var manager = new AliasManager(Paths.get(System.getProperty("user.home")).resolve(ALIAS_FILE).toFile(), true); + Map ret = new HashMap<>(); + for (String alias : manager.getAllNames()) { + if (alias.length() == 1) { + ret.put(alias.charAt(0), manager.getAlias(alias).get().getValue()); + } + } + return ret; + } catch (IOException e) { + return Map.of(); + } + } + @Override + public void runAlias(char alias) { + try { + AeshCommandRegistryBuilder commandBuilder = AeshCommandRegistryBuilder.builder(); + ConsoleCliManager.commands.forEach(commandBuilder::command); + + CommandRegistry registry = commandBuilder + .create(); + Settings settings = SettingsBuilder + .builder() + .enableExport(false) + .inputStream(new ByteArrayInputStream(new byte[] { (byte) alias, '\n' })) + .enableAlias(true) + .aliasManager( + new AliasManager(Paths.get(System.getProperty("user.home")).resolve(ALIAS_FILE).toFile(), true)) + .connection(delegateConnection) + .commandRegistry(registry) + .build(); + aeshConsole = new ReadlineConsole(settings); + aeshConsole.start(); + } catch (IOException e) { + throw new RuntimeException(e); + } } public void exitCliMode() { - if (aeshConsole == null) { + if (aeshConsole == null || delegateConnection == null) { return; } aeshConsole.stop(); diff --git a/core/deployment/src/main/java/io/quarkus/deployment/console/ConsoleStateManager.java b/core/deployment/src/main/java/io/quarkus/deployment/console/ConsoleStateManager.java index e6671d5ae3516c..83afe02f07c2b9 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/console/ConsoleStateManager.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/console/ConsoleStateManager.java @@ -51,19 +51,20 @@ public class ConsoleStateManager { @Override public void accept(int[] ints) { for (int i : ints) { + char key = (char) i; if (readLineBuilder != null) { if (i == '\n' || i == '\r') { readLineConsumer.accept(readLineBuilder.toString()); readLineBuilder = null; readLineConsumer = null; } else { - readLineBuilder.append((char) i); + readLineBuilder.append(key); } } else { if (i == '\n') { System.out.println(""); } - Holder command = commands.get((char) i); + Holder command = commands.get(key); if (command != null) { if (command.consoleCommand.getReadLineHandler() != null) { QuarkusConsole.INSTANCE.doReadLine(); @@ -72,6 +73,10 @@ public void accept(int[] ints) { } else { command.consoleCommand.getRunnable().run(); } + } else { + if (QuarkusConsole.INSTANCE.singleLetterAliases().containsKey(key)) { + QuarkusConsole.INSTANCE.runAlias(key); + } } } } @@ -203,11 +208,16 @@ private void printHelp() { for (Holder i : commands.values()) { contexts.add(i.context); } + Set seen = new HashSet<>(); for (ConsoleContext ctx : contexts.stream().sorted(Comparator.comparing(ConsoleContext::getName)) .collect(Collectors.toList())) { System.out.println("\n" + RED + "==" + RESET + " " + UNDERLINE + ctx.name + NO_UNDERLINE + "\n"); for (var i : ctx.internal) { + if (seen.contains(i.getKey())) { + continue; + } + seen.add(i.getKey()); if (i.getDescription() != null) { if (i.getHelpState() == null) { System.out.println(helpOption(i.getKey(), i.getDescription())); @@ -220,7 +230,15 @@ private void printHelp() { } } } - + Map aliases = QuarkusConsole.INSTANCE.singleLetterAliases(); + if (!aliases.isEmpty()) { + System.out.println("\n" + RED + "==" + RESET + " " + UNDERLINE + "User Defined Aliases" + NO_UNDERLINE + "\n"); + for (Map.Entry entry : aliases.entrySet()) { + if (!seen.contains(entry.getKey())) { + System.out.println(helpOption(entry.getKey(), entry.getValue())); + } + } + } } static class Holder { diff --git a/core/devmode-spi/src/main/java/io/quarkus/dev/console/QuarkusConsole.java b/core/devmode-spi/src/main/java/io/quarkus/dev/console/QuarkusConsole.java index bc6b3766e88e59..5e439cdfd60725 100644 --- a/core/devmode-spi/src/main/java/io/quarkus/dev/console/QuarkusConsole.java +++ b/core/devmode-spi/src/main/java/io/quarkus/dev/console/QuarkusConsole.java @@ -3,6 +3,7 @@ import java.io.PrintStream; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.BiPredicate; import java.util.function.Consumer; @@ -141,6 +142,20 @@ public void exitCliMode() { //noop for the non-aesh console } + /** + * Exposes single character aliases so they can be displayed in the help screen + */ + public Map singleLetterAliases() { + return Map.of(); + } + + /** + * runs a single letter alias + */ + public void runAlias(char alias) { + + } + protected String stripAnsiCodes(String s) { if (s == null) { return null;