This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch jline in repository https://gitbox.apache.org/repos/asf/camel.git
commit 1aa098357d205636f255158d0a2ba3c141b91cd5 Author: Claus Ibsen <[email protected]> AuthorDate: Wed Dec 10 13:13:01 2025 +0100 camel-jbang - camel get history use jline to make it mode better --- .../core/commands/action/CamelHistoryAction.java | 72 ++++++++++++++++------ .../core/commands/action/InteractiveTerminal.java | 12 ++++ 2 files changed, 66 insertions(+), 18 deletions(-) diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelHistoryAction.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelHistoryAction.java index 998c75386788..445df8e9a30d 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelHistoryAction.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelHistoryAction.java @@ -205,6 +205,7 @@ public class CamelHistoryAction extends ActionWatchCommand { private Integer doInteractiveCall(List<Row> rows) throws Exception { AtomicInteger index = new AtomicInteger(); + AtomicInteger index2 = new AtomicInteger(); AtomicBoolean quit = new AtomicBoolean(); tableHelper = new MessageTableHelper(); @@ -216,13 +217,17 @@ public class CamelHistoryAction extends ActionWatchCommand { try (InteractiveTerminal t = new InteractiveTerminal()) { t.sigint(() -> quit.set(true)); t.addKeyBinding("quit", KeyMap.ctrl('c'), "q"); - t.addKeyBinding("up", InfoCmp.Capability.key_up); - t.addKeyBinding("down", InfoCmp.Capability.key_down); t.addKeyBinding("refresh", InfoCmp.Capability.key_f5); + t.addKeyBinding("down", InfoCmp.Capability.key_down); + t.addKeyBinding("up", InfoCmp.Capability.key_up); + t.addKeyBinding("npage", InfoCmp.Capability.key_npage); + t.addKeyBinding("ppage", InfoCmp.Capability.key_ppage); + t.addKeyBinding("home", InfoCmp.Capability.key_home); + t.addKeyBinding("end", InfoCmp.Capability.key_end); t.start(); t.clearDisplay(); - t.updateDisplay(interactiveContent(rows, index)); + t.updateDisplay(interactiveContent(rows, index, index2)); t.flush(); do { @@ -238,6 +243,18 @@ public class CamelHistoryAction extends ActionWatchCommand { if (index.get() < rows.size() - 1) { index.addAndGet(1); } + } else if ("home".equals(operation)) { + index2.set(0); + } else if ("end".equals(operation)) { + index2.set(Integer.MAX_VALUE); + } else if ("npage".equals(operation)) { + index2.addAndGet(10); + // TODO: end of message content + } else if ("ppage".equals(operation)) { + index2.addAndGet(-10); + if (index2.get() < 0) { + index2.set(0); + } } else if ("refresh".equals(operation)) { var reloaded = loadRows(); if (reloaded.size() == 1) { @@ -246,7 +263,7 @@ public class CamelHistoryAction extends ActionWatchCommand { index.set(0); } t.clearDisplay(); - t.updateDisplay(interactiveContent(rows, index)); + t.updateDisplay(interactiveContent(rows, index, index2)); t.flush(); } } while (!quit.get()); @@ -255,7 +272,7 @@ public class CamelHistoryAction extends ActionWatchCommand { return 0; } - private List<AttributedString> interactiveContent(List<Row> rows, AtomicInteger index) { + private List<AttributedString> interactiveContent(List<Row> rows, AtomicInteger index, AtomicInteger index2) { List<AttributedString> answer = new ArrayList<>(); Row first = rows.get(0); @@ -264,11 +281,20 @@ public class CamelHistoryAction extends ActionWatchCommand { String status = last.failed ? "failed" : "success"; String s = String.format(" Message History of last completed (id:%s status:%s ago:%s pid:%d name:%s)", first.exchangeId, status, ago, first.pid, first.name); - answer.add(new AttributedString("")); answer.add(new AttributedString(s)); - answer.add(new AttributedString("")); + answer.add(new AttributedString("Pos: " + index.get())); + + int pos = index.get(); - String table = AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( + List<Row> copy = new ArrayList<>(rows); + + // ensure there are empty rows if we do not have 7 traces + while (copy.size() < 7) { + copy.add(new Row()); + } + + // build full table with all data so the table sizing are always the same when scrolling + String table = AsciiTable.getTable(AsciiTable.NO_BORDERS, copy, Arrays.asList( new Column().header("").dataAlign(HorizontalAlign.LEFT) .minWidth(6).maxWidth(6) .with(this::getDirection), @@ -280,7 +306,7 @@ public class CamelHistoryAction extends ActionWatchCommand { .with(this::getProcessor), new Column().header("ELAPSED").dataAlign(HorizontalAlign.RIGHT) .maxWidth(10, OverflowBehaviour.ELLIPSIS_RIGHT) - .with(r -> "" + r.elapsed), + .with(this::getElapsed), new Column().header("EXCHANGE").headerAlign(HorizontalAlign.RIGHT).dataAlign(HorizontalAlign.RIGHT) .maxWidth(12, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getExchangeId), @@ -288,14 +314,22 @@ public class CamelHistoryAction extends ActionWatchCommand { .maxWidth(60, OverflowBehaviour.NEWLINE) .with(this::getMessage))); + List<String> lines = new ArrayList<>(List.of(table.split(System.lineSeparator()))); + // header + answer.add(new AttributedString(lines.remove(0))); + + // slice table based on position + // 6 rows 1 empty + // pos = 0 + + + // print table var normal = AttributedStyle.DEFAULT; var select = AttributedStyle.DEFAULT .background(AttributedStyle.YELLOW) .bold(); - String[] lines = table.split(System.lineSeparator()); - int pos = index.get() + 1; - for (int i = 0; i < lines.length; i++) { - String line = lines[i]; + for (int i = 0; i < 7; i++) { + String line = lines.get(i); answer.add(new AttributedString(line, i == pos ? select : normal)); } answer.add(new AttributedString("")); @@ -307,9 +341,8 @@ public class CamelHistoryAction extends ActionWatchCommand { answer.add(new AttributedString("")); // table with message details table = getDataAsTable(r); - lines = table.split(System.lineSeparator()); - for (int i = 0; i < lines.length; i++) { - String line = lines[i]; + lines = List.of(table.split(System.lineSeparator())); + for (String line : lines) { answer.add(AttributedString.fromAnsi(line)); } answer.add(new AttributedString("")); @@ -401,7 +434,7 @@ public class CamelHistoryAction extends ActionWatchCommand { } private String getElapsed(Row r) { - if (!r.first) { + if (r.exchangeId != null && !r.first) { return TimeUtils.printDuration(r.elapsed, true); } return null; @@ -512,11 +545,14 @@ public class CamelHistoryAction extends ActionWatchCommand { } else if (r.last) { return "*<--"; } else { - return ""; + return null; } } private String getExchangeId(Row r) { + if (r.exchangeId == null) { + return null; + } String id = r.exchangeId.substring(r.exchangeId.length() - 4); String cid = r.correlationExchangeId; if (cid != null) { diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/InteractiveTerminal.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/InteractiveTerminal.java index a0910d071e2c..e7c6158f6e85 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/InteractiveTerminal.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/InteractiveTerminal.java @@ -31,6 +31,7 @@ import org.jline.terminal.TerminalBuilder; import org.jline.utils.AttributedString; import org.jline.utils.Display; import org.jline.utils.InfoCmp; +import org.jline.utils.Status; /** * Interactive terminal that runs in full screen and allows a more immersive user experience with Camel JBang CLI. @@ -44,6 +45,8 @@ public class InteractiveTerminal implements Closeable { private Size size; private BindingReader bindingReader; private Runnable sigint; + private Status status; + private Runnable statusTask; public InteractiveTerminal() throws Exception { terminal = TerminalBuilder.builder().build(); @@ -74,6 +77,7 @@ public class InteractiveTerminal implements Closeable { // resize display display.resize(size.getRows(), size.getColumns()); + status = Status.getStatus(terminal); bindingReader = new BindingReader(terminal.reader()); if (sigint != null) { @@ -87,6 +91,10 @@ public class InteractiveTerminal implements Closeable { this.sigint = task; } + public void status(Runnable task) { + this.statusTask = task; + } + public void addKeyBinding(String operation, String... key) { keys.bind(operation, key); } @@ -107,6 +115,10 @@ public class InteractiveTerminal implements Closeable { display.update(newLines, size.cursorPos(0, 0)); } + public void updateStatus(List<AttributedString> newLines) { + status.update(newLines); + } + public void flush() { terminal.flush(); }
