This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch CAMEL-23226-shell-improvements
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 5942dc417fd7eb960252e0a163b8aec71bde1541
Author: Guillaume Nodet <[email protected]>
AuthorDate: Sat Mar 21 18:02:11 2026 +0100

    CAMEL-23226: Enhance Shell with rich prompt, banner, and auto-suggestions
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
 .../camel/dsl/jbang/core/commands/Shell.java       | 85 +++++++++++++++++++++-
 1 file changed, 84 insertions(+), 1 deletion(-)

diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Shell.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Shell.java
index c550f328fbce..340e79dc245b 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Shell.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Shell.java
@@ -20,12 +20,16 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 
+import org.apache.camel.dsl.jbang.core.common.VersionHelper;
 import org.apache.camel.util.HomeHelper;
 import org.jline.builtins.InteractiveCommandGroup;
 import org.jline.builtins.PosixCommandGroup;
 import org.jline.picocli.PicocliCommandRegistry;
 import org.jline.reader.LineReader;
 import org.jline.shell.impl.DefaultAliasManager;
+import org.jline.utils.AttributedStringBuilder;
+import org.jline.utils.AttributedStyle;
+import org.jline.widget.AutosuggestionWidgets;
 import picocli.CommandLine;
 
 @CommandLine.Command(name = "shell",
@@ -33,6 +37,9 @@ import picocli.CommandLine;
                      footer = "Press Ctrl-C to exit.")
 public class Shell extends CamelCommand {
 
+    // Camel orange color (packed RGB)
+    private static final int CAMEL_ORANGE = 0xF69123;
+
     public Shell(CamelJBangMain main) {
         super(main);
     }
@@ -51,8 +58,12 @@ public class Shell extends CamelCommand {
         // Init script: if ~/.camel-jbang-init exists, it will be executed on 
shell startup
         Path initScript = Paths.get(homeDir, ".camel-jbang-init");
 
+        String camelVersion = VersionHelper.extractCamelVersion();
+        boolean colorEnabled = isColorEnabled();
+
         org.jline.shell.ShellBuilder builder = org.jline.shell.Shell.builder()
-                .prompt("camel> ")
+                .prompt(() -> buildPrompt(camelVersion, colorEnabled))
+                .rightPrompt(() -> buildRightPrompt(colorEnabled))
                 .groups(registry, new PosixCommandGroup(), new 
InteractiveCommandGroup())
                 .historyFile(history)
                 .historyCommands(true)
@@ -60,6 +71,10 @@ public class Shell extends CamelCommand {
                 .variableCommands(true)
                 .commandHighlighter(true)
                 .aliasManager(aliasManager)
+                .onReaderReady(reader -> {
+                    // Enable fish-style auto-suggestions from history
+                    new AutosuggestionWidgets(reader).enable();
+                })
                 // scriptCommands(true) requires a scriptRunner to be set;
                 // omitting for now until a DefaultScriptRunner is available
                 .variable(LineReader.LIST_MAX, 50)
@@ -70,8 +85,76 @@ public class Shell extends CamelCommand {
         }
 
         try (org.jline.shell.Shell shell = builder.build()) {
+            printBanner(shell, camelVersion, colorEnabled);
             shell.run();
         }
         return 0;
     }
+
+    private static String buildPrompt(String camelVersion, boolean 
colorEnabled) {
+        if (!colorEnabled) {
+            return camelVersion != null ? "camel " + camelVersion + "> " : 
"camel> ";
+        }
+        AttributedStringBuilder sb = new AttributedStringBuilder();
+        sb.append("camel", 
AttributedStyle.DEFAULT.bold().foregroundRgb(CAMEL_ORANGE));
+        if (camelVersion != null) {
+            sb.append(" ");
+            sb.append(camelVersion, 
AttributedStyle.DEFAULT.foreground(AttributedStyle.GREEN));
+        }
+        sb.append("> ", AttributedStyle.DEFAULT);
+        return sb.toAnsi();
+    }
+
+    private static String buildRightPrompt(boolean colorEnabled) {
+        String cwd = System.getProperty("user.dir");
+        String home = System.getProperty("user.home");
+        if (cwd != null && home != null && cwd.startsWith(home)) {
+            cwd = "~" + cwd.substring(home.length());
+        }
+        if (cwd == null) {
+            return null;
+        }
+        if (!colorEnabled) {
+            return cwd;
+        }
+        return new AttributedStringBuilder()
+                .append(cwd, AttributedStyle.DEFAULT.faint())
+                .toAnsi();
+    }
+
+    private static void printBanner(org.jline.shell.Shell shell, String 
camelVersion, boolean colorEnabled) {
+        var writer = shell.terminal().writer();
+        if (colorEnabled) {
+            AttributedStringBuilder sb = new AttributedStringBuilder();
+            sb.append("Apache Camel", 
AttributedStyle.DEFAULT.bold().foregroundRgb(CAMEL_ORANGE));
+            sb.append(" JBang Shell", AttributedStyle.DEFAULT.bold());
+            if (camelVersion != null) {
+                sb.append(" v" + camelVersion, 
AttributedStyle.DEFAULT.foreground(AttributedStyle.GREEN));
+            }
+            writer.println(sb.toAnsi(shell.terminal()));
+        } else {
+            String banner = "Apache Camel JBang Shell";
+            if (camelVersion != null) {
+                banner += " v" + camelVersion;
+            }
+            writer.println(banner);
+        }
+        writer.println("Type 'help' for available commands, 'exit' to quit.");
+        writer.println();
+        writer.flush();
+    }
+
+    private static boolean isColorEnabled() {
+        // Respect NO_COLOR (https://no-color.org/)
+        String noColor = System.getenv("NO_COLOR");
+        if (noColor != null) {
+            return false;
+        }
+        // Respect FORCE_COLOR
+        String forceColor = System.getenv("FORCE_COLOR");
+        if (forceColor != null) {
+            return true;
+        }
+        return System.console() != null;
+    }
 }

Reply via email to