This is an automated email from the ASF dual-hosted git repository. gnodet pushed a commit to branch spiced-path in repository https://gitbox.apache.org/repos/asf/camel.git
commit f954f4e7079f731a286deb32cc018ab25ec30e7d Author: Guillaume Nodet <[email protected]> AuthorDate: Tue Mar 24 09:23:31 2026 +0100 CAMEL-23237: camel-jbang - Adapt CLI table output to terminal width - Add TerminalWidthHelper utility that detects terminal width via JLine and provides methods for proportional column width scaling - Add terminalWidth() method to CamelCommand base class - Update all 33 command files that produce AsciiTable output to adapt their column widths based on the detected terminal width - CatalogDoc tables use proportional scaling across all columns for FANCY_ASCII bordered tables (most visible in demos) - Process/action commands scale their flexible columns (URI, DESCRIPTION, MESSAGE, etc.) while keeping small fixed columns unchanged Co-Authored-By: Claude Opus 4.6 <[email protected]> --- .../dsl/jbang/core/commands/CamelCommand.java | 5 + .../jbang/core/commands/action/CamelBeanDump.java | 31 ++++- .../core/commands/action/CamelBrowseAction.java | 10 +- .../core/commands/action/CamelHistoryAction.java | 19 +++- .../core/commands/action/CamelReceiveAction.java | 10 +- .../action/CamelStartupRecorderAction.java | 8 +- .../core/commands/action/CamelThreadDump.java | 20 +++- .../jbang/core/commands/action/LoggerAction.java | 12 +- .../core/commands/action/MessageTableHelper.java | 42 ++++--- .../commands/action/RouteControllerAction.java | 13 ++- .../core/commands/catalog/CatalogBaseCommand.java | 15 ++- .../jbang/core/commands/catalog/CatalogDoc.java | 126 +++++++++++---------- .../core/commands/catalog/CatalogKamelet.java | 10 +- .../core/commands/infra/InfraBaseCommand.java | 12 +- .../core/commands/process/CamelContextStatus.java | 7 +- .../commands/process/CamelProcessorStatus.java | 13 ++- .../core/commands/process/CamelRouteStatus.java | 25 +++- .../jbang/core/commands/process/CamelRouteTop.java | 7 +- .../jbang/core/commands/process/ListConsumer.java | 10 +- .../jbang/core/commands/process/ListEndpoint.java | 10 +- .../jbang/core/commands/process/ListGroovy.java | 7 +- .../jbang/core/commands/process/ListHealth.java | 13 ++- .../core/commands/process/ListInternalTask.java | 7 +- .../dsl/jbang/core/commands/process/ListKafka.java | 13 ++- .../jbang/core/commands/process/ListMetric.java | 15 ++- .../jbang/core/commands/process/ListProcess.java | 9 +- .../jbang/core/commands/process/ListProducer.java | 10 +- .../core/commands/process/ListProperties.java | 21 +++- .../dsl/jbang/core/commands/process/ListRest.java | 7 +- .../jbang/core/commands/process/ListService.java | 10 +- .../jbang/core/commands/process/ListVariable.java | 14 ++- .../dsl/jbang/core/commands/process/ListVault.java | 10 +- .../dsl/jbang/core/commands/update/UpdateList.java | 9 +- .../dsl/jbang/core/common/TerminalWidthHelper.java | 114 +++++++++++++++++++ 34 files changed, 525 insertions(+), 139 deletions(-) diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelCommand.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelCommand.java index da95a5257e4e..f1b9b1a4002b 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelCommand.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelCommand.java @@ -28,6 +28,7 @@ import java.util.concurrent.Callable; import org.apache.camel.dsl.jbang.core.common.CommandLineHelper; import org.apache.camel.dsl.jbang.core.common.Printer; import org.apache.camel.dsl.jbang.core.common.RuntimeUtil; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.util.StringHelper; import picocli.CommandLine; import picocli.CommandLine.IParameterConsumer; @@ -140,6 +141,10 @@ public abstract class CamelCommand implements Callable<Integer> { return out; } + protected int terminalWidth() { + return TerminalWidthHelper.getTerminalWidth(); + } + protected void printConfigurationValues(String header) { if (spec != null) { final Properties configProperties = new Properties(); diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelBeanDump.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelBeanDump.java index d622682c1c50..d83e833cfac6 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelBeanDump.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelBeanDump.java @@ -28,6 +28,7 @@ import com.github.freva.asciitable.HorizontalAlign; import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.PathUtils; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; import picocli.CommandLine; @@ -175,23 +176,41 @@ public class CamelBeanDump extends ActionBaseCommand { } protected void singleTable(List<Row> rows) { + int tw = terminalWidth(); + int borderOverhead = TerminalWidthHelper.noBorderOverhead(2); + int nameWidth = TerminalWidthHelper.flexWidth(tw, 100, borderOverhead, 20, 60); + int typeWidth = TerminalWidthHelper.flexWidth(tw, nameWidth, borderOverhead, 20, 100); + printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( - new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).maxWidth(60, OverflowBehaviour.ELLIPSIS_RIGHT) + new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) + .maxWidth(nameWidth, OverflowBehaviour.ELLIPSIS_RIGHT) .with(r -> r.name), - new Column().header("TYPE").dataAlign(HorizontalAlign.LEFT).maxWidth(100, OverflowBehaviour.CLIP_LEFT) + new Column().header("TYPE").dataAlign(HorizontalAlign.LEFT).maxWidth(typeWidth, OverflowBehaviour.CLIP_LEFT) .with(r -> r.type)))); } protected void propertiesTable(List<PropertyRow> rows) { + int tw = terminalWidth(); + int colCount = dsl ? 4 : 3; + int borderOverhead = TerminalWidthHelper.noBorderOverhead(colCount); + int propWidth = TerminalWidthHelper.flexWidth(tw, 40 + 80 + (dsl ? 80 : 0), borderOverhead, 15, 40); + int propTypeWidth = TerminalWidthHelper.flexWidth(tw, propWidth + 80 + (dsl ? 80 : 0), borderOverhead, 15, 40); + int valueWidth = TerminalWidthHelper.flexWidth(tw, propWidth + propTypeWidth + (dsl ? 80 : 0), borderOverhead, 20, 80); + int configWidth = dsl + ? TerminalWidthHelper.flexWidth(tw, propWidth + propTypeWidth + valueWidth, borderOverhead, 20, 80) + : 80; + printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( - new Column().header("PROPERTY").dataAlign(HorizontalAlign.LEFT).maxWidth(40, OverflowBehaviour.ELLIPSIS_RIGHT) + new Column().header("PROPERTY").dataAlign(HorizontalAlign.LEFT) + .maxWidth(propWidth, OverflowBehaviour.ELLIPSIS_RIGHT) .with(r -> r.name), - new Column().header("TYPE").dataAlign(HorizontalAlign.LEFT).maxWidth(40, OverflowBehaviour.ELLIPSIS_RIGHT) + new Column().header("TYPE").dataAlign(HorizontalAlign.LEFT) + .maxWidth(propTypeWidth, OverflowBehaviour.ELLIPSIS_RIGHT) .with(r -> r.type), new Column().header("CONFIGURATION").visible(dsl).dataAlign(HorizontalAlign.LEFT) - .maxWidth(80, OverflowBehaviour.NEWLINE) + .maxWidth(configWidth, OverflowBehaviour.NEWLINE) .with(r -> r.configValue), - new Column().header("VALUE").dataAlign(HorizontalAlign.LEFT).maxWidth(80, OverflowBehaviour.NEWLINE) + new Column().header("VALUE").dataAlign(HorizontalAlign.LEFT).maxWidth(valueWidth, OverflowBehaviour.NEWLINE) .with(this::getValue)))); } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelBrowseAction.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelBrowseAction.java index 6d7c85a1a1e8..6bfa60a2375a 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelBrowseAction.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelBrowseAction.java @@ -30,6 +30,7 @@ import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.PathUtils; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.util.TimeUtils; import org.apache.camel.util.URISupport; import org.apache.camel.util.json.JsonArray; @@ -255,6 +256,11 @@ public class CamelBrowseAction extends ActionBaseCommand { } protected void tableStatus(List<Row> rows) { + int tw = terminalWidth(); + int fixedWidth = 10 + 40 + 10 + 8 + 15; // PID + NAME + AGE + SIZE + SINCE (approx) + int borderOverhead = TerminalWidthHelper.noBorderOverhead(6); + int endpointWidth = TerminalWidthHelper.flexWidth(tw, fixedWidth, borderOverhead, 20, wideUri ? 140 : 90); + printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) @@ -265,10 +271,10 @@ public class CamelBrowseAction extends ActionBaseCommand { new Column().header("SINCE").headerAlign(HorizontalAlign.CENTER).dataAlign(HorizontalAlign.LEFT) .with(this::getMessageAgo), new Column().header("ENDPOINT").visible(!wideUri).dataAlign(HorizontalAlign.LEFT) - .maxWidth(90, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(endpointWidth, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getEndpointUri), new Column().header("ENDPOINT").visible(wideUri).dataAlign(HorizontalAlign.LEFT) - .maxWidth(140, OverflowBehaviour.NEWLINE) + .maxWidth(endpointWidth, OverflowBehaviour.NEWLINE) .with(r -> r.uri)))); } 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 c887530e8ed7..5d9b64cd3c78 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 @@ -37,6 +37,7 @@ import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.catalog.CamelCatalog; import org.apache.camel.catalog.DefaultCamelCatalog; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.support.LoggerHelper; import org.apache.camel.tooling.model.ComponentModel; import org.apache.camel.tooling.model.EipModel; @@ -165,6 +166,13 @@ public class CamelHistoryAction extends ActionWatchCommand { first.exchangeId, status, elapsed, ago, first.pid, first.name); printer().println(s); + int tw = terminalWidth(); + int fixedWidth = 6 + 20 + 10 + 12; // direction + ID + ELAPSED + EXCHANGE + int borderOverhead = TerminalWidthHelper.noBorderOverhead(6); + int flexTotal = tw - fixedWidth - borderOverhead; + int processorWidth = TerminalWidthHelper.flexWidth(tw, fixedWidth + 60, borderOverhead, 20, 55); + int messageWidth = TerminalWidthHelper.flexWidth(tw, fixedWidth + processorWidth, borderOverhead, 20, 60); + printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("").dataAlign(HorizontalAlign.LEFT) .minWidth(6).maxWidth(6) @@ -173,7 +181,7 @@ public class CamelHistoryAction extends ActionWatchCommand { .minWidth(10).maxWidth(20, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getId), new Column().header("PROCESSOR").dataAlign(HorizontalAlign.LEFT) - .minWidth(40).maxWidth(55, OverflowBehaviour.ELLIPSIS_RIGHT) + .minWidth(20).maxWidth(processorWidth, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getProcessor), new Column().header("ELAPSED").dataAlign(HorizontalAlign.RIGHT) .maxWidth(10, OverflowBehaviour.ELLIPSIS_RIGHT) @@ -182,7 +190,7 @@ public class CamelHistoryAction extends ActionWatchCommand { .maxWidth(12, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getExchangeId), new Column().header("").dataAlign(HorizontalAlign.LEFT) - .maxWidth(60, OverflowBehaviour.NEWLINE) + .maxWidth(messageWidth, OverflowBehaviour.NEWLINE) .with(this::getMessage)))); JsonObject cause = last.exception; @@ -313,6 +321,11 @@ public class CamelHistoryAction extends ActionWatchCommand { answer.add(new AttributedString("")); // build full table with all data so the table sizing are always the same when scrolling + int tw = terminalWidth(); + int itFixedWidth = 6 + 20 + 10 + 12; // direction + ID + ELAPSED + EXCHANGE + int itBorderOverhead = TerminalWidthHelper.noBorderOverhead(6); + int itProcessorWidth = TerminalWidthHelper.flexWidth(tw, itFixedWidth, itBorderOverhead, 20, 55); + String table = AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("").dataAlign(HorizontalAlign.LEFT) .minWidth(6).maxWidth(6) @@ -321,7 +334,7 @@ public class CamelHistoryAction extends ActionWatchCommand { .minWidth(10).maxWidth(20, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getId), new Column().header("PROCESSOR").dataAlign(HorizontalAlign.LEFT) - .minWidth(40).maxWidth(55, OverflowBehaviour.ELLIPSIS_RIGHT) + .minWidth(20).maxWidth(itProcessorWidth, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getProcessor), new Column().header("ELAPSED").dataAlign(HorizontalAlign.RIGHT) .maxWidth(10, OverflowBehaviour.ELLIPSIS_RIGHT) diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelReceiveAction.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelReceiveAction.java index 90e441403b2c..eea76f25b01a 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelReceiveAction.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelReceiveAction.java @@ -49,6 +49,7 @@ import org.apache.camel.dsl.jbang.core.commands.Run; import org.apache.camel.dsl.jbang.core.common.PathUtils; import org.apache.camel.dsl.jbang.core.common.PidNameAgeCompletionCandidates; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.main.KameletMain; import org.apache.camel.util.StopWatch; import org.apache.camel.util.StringHelper; @@ -455,6 +456,11 @@ public class CamelReceiveAction extends ActionBaseCommand { rows.sort(this::sortStatusRow); if (!rows.isEmpty()) { + int tw = terminalWidth(); + int fixedWidth = 10 + 30 + 10 + 10 + 8 + 10; // PID + NAME + AGE + STATUS + TOTAL + SINCE (approx) + int borderOverhead = TerminalWidthHelper.noBorderOverhead(7); + int endpointWidth = TerminalWidthHelper.flexWidth(tw, fixedWidth, borderOverhead, 20, wideUri ? 140 : 90); + printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).maxWidth(30, OverflowBehaviour.ELLIPSIS_RIGHT) @@ -465,10 +471,10 @@ public class CamelReceiveAction extends ActionBaseCommand { new Column().header("SINCE").headerAlign(HorizontalAlign.CENTER) .with(this::getMessageAgo), new Column().header("ENDPOINT").visible(!wideUri).dataAlign(HorizontalAlign.LEFT) - .maxWidth(90, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(endpointWidth, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getEndpointUri), new Column().header("ENDPOINT").visible(wideUri).dataAlign(HorizontalAlign.LEFT) - .maxWidth(140, OverflowBehaviour.NEWLINE) + .maxWidth(endpointWidth, OverflowBehaviour.NEWLINE) .with(r -> r.uri)))); } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelStartupRecorderAction.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelStartupRecorderAction.java index 48039860faf5..dcc11d48e366 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelStartupRecorderAction.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelStartupRecorderAction.java @@ -29,6 +29,7 @@ import com.github.freva.asciitable.HorizontalAlign; import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.PathUtils; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.util.StringHelper; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; @@ -100,11 +101,16 @@ public class CamelStartupRecorderAction extends ActionWatchCommand { rows.sort(this::sortRow); if (!rows.isEmpty()) { + int tw = terminalWidth(); + int fixedWidth = 10 + 15; // DURATION + TYPE (approx) + int borderOverhead = TerminalWidthHelper.noBorderOverhead(3); + int stepWidth = TerminalWidthHelper.flexWidth(tw, fixedWidth, borderOverhead, 20, 80); + printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("DURATION").dataAlign(HorizontalAlign.RIGHT).with(this::getDuration), new Column().header("TYPE").dataAlign(HorizontalAlign.LEFT).with(r -> r.type), new Column().header("STEP (END)").dataAlign(HorizontalAlign.LEFT) - .maxWidth(80, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(stepWidth, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getStep)))); } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelThreadDump.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelThreadDump.java index fd3975e5e03f..6f89b164e758 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelThreadDump.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelThreadDump.java @@ -29,6 +29,7 @@ import com.github.freva.asciitable.HorizontalAlign; import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.PathUtils; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.support.PatternHelper; import org.apache.camel.util.StringHelper; import org.apache.camel.util.json.JsonArray; @@ -190,22 +191,35 @@ public class CamelThreadDump extends ActionWatchCommand { } protected void singleTable(List<Row> rows) { + int tw = terminalWidth(); + int fixedWidth = 8 + 15 + 10 + 10; // ID + STATE + BLOCK + WAIT (approx) + int borderOverhead = TerminalWidthHelper.noBorderOverhead(6); + int nameWidth = TerminalWidthHelper.flexWidth(tw, fixedWidth + 70, borderOverhead, 20, 60); + int stackWidth = TerminalWidthHelper.flexWidth(tw, fixedWidth + nameWidth, borderOverhead, 20, 70); + printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("ID").headerAlign(HorizontalAlign.CENTER).with(r -> Long.toString(r.id)), - new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).maxWidth(60, OverflowBehaviour.ELLIPSIS_RIGHT) + new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) + .maxWidth(nameWidth, OverflowBehaviour.ELLIPSIS_RIGHT) .with(r -> r.name), new Column().header("STATE").headerAlign(HorizontalAlign.RIGHT).with(r -> r.state), new Column().header("BLOCK").with(this::getBlocked), new Column().header("WAIT").with(this::getWaited), new Column().header("STACKTRACE").headerAlign(HorizontalAlign.RIGHT) - .maxWidth(70, OverflowBehaviour.ELLIPSIS_LEFT).with(this::getStackTrace)))); + .maxWidth(stackWidth, OverflowBehaviour.ELLIPSIS_LEFT).with(this::getStackTrace)))); } protected void tableAndStackTrace(List<Row> rows) { + int tw = terminalWidth(); + int fixedWidth = 8 + 15 + 10 + 10; // ID + STATE + BLOCK + WAIT (approx) + int borderOverhead = TerminalWidthHelper.noBorderOverhead(5); + int nameWidth = TerminalWidthHelper.flexWidth(tw, fixedWidth, borderOverhead, 20, 60); + for (Row row : rows) { printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, List.of(row), Arrays.asList( new Column().header("ID").headerAlign(HorizontalAlign.CENTER).with(r -> Long.toString(r.id)), - new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).maxWidth(60, OverflowBehaviour.ELLIPSIS_RIGHT) + new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) + .maxWidth(nameWidth, OverflowBehaviour.ELLIPSIS_RIGHT) .with(r -> r.name), new Column().header("STATE").headerAlign(HorizontalAlign.RIGHT).with(r -> r.state), new Column().header("BLOCK").with(this::getBlocked), diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/LoggerAction.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/LoggerAction.java index e81b23c164d2..443e8f2fbde7 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/LoggerAction.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/LoggerAction.java @@ -31,6 +31,7 @@ import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.LoggingLevelCompletionCandidates; import org.apache.camel.dsl.jbang.core.common.PidNameAgeCompletionCandidates; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.util.TimeUtils; import org.apache.camel.util.json.JsonObject; import picocli.CommandLine; @@ -124,13 +125,20 @@ public class LoggerAction extends ActionBaseCommand { rows.sort(this::sortRow); if (!rows.isEmpty()) { + int tw = terminalWidth(); + int fixedWidth = 10 + 10 + 10; // PID + AGE + LEVEL (approx) + int borderOverhead = TerminalWidthHelper.noBorderOverhead(5); + int nameWidth = TerminalWidthHelper.flexWidth(tw, fixedWidth + 60, borderOverhead, 15, 40); + int loggerWidth = TerminalWidthHelper.flexWidth(tw, fixedWidth + nameWidth, borderOverhead, 20, 60); + printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) - .maxWidth(40, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(nameWidth, OverflowBehaviour.ELLIPSIS_RIGHT) .with(r -> r.name), new Column().header("AGE").headerAlign(HorizontalAlign.CENTER).with(r -> r.ago), - new Column().header("LOGGER").dataAlign(HorizontalAlign.LEFT).with(r -> r.logger), + new Column().header("LOGGER").dataAlign(HorizontalAlign.LEFT) + .maxWidth(loggerWidth, OverflowBehaviour.ELLIPSIS_RIGHT).with(r -> r.logger), new Column().header("LEVEL").dataAlign(HorizontalAlign.RIGHT).with(r -> r.level)))); } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/MessageTableHelper.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/MessageTableHelper.java index 87d29ae8b0bf..78fc1970f657 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/MessageTableHelper.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/MessageTableHelper.java @@ -29,6 +29,7 @@ import com.github.freva.asciitable.Column; import com.github.freva.asciitable.HorizontalAlign; import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.common.CamelCommandHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.util.TimeUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; @@ -105,6 +106,21 @@ public class MessageTableHelper { JsonObject aggregate, JsonObject endpoint, JsonObject endpointService, JsonObject root, JsonObject cause) { + int tw = TerminalWidthHelper.getTerminalWidth(); + int kindWidth = showExchangeProperties || showExchangeVariables ? 12 : 10; + // Compute flexible widths for the 4-column tables (kind + type + key + value) + int fixed4 = kindWidth + 25 + 25; // kind + type(min) + key(min) + int border4 = TerminalWidthHelper.noBorderOverhead(4); + int valueWidth = TerminalWidthHelper.flexWidth(tw, fixed4, border4, 20, 80); + int typeWidth = TerminalWidthHelper.flexWidth(tw, kindWidth + 25 + valueWidth, border4, 20, 50); + int keyWidth = TerminalWidthHelper.flexWidth(tw, kindWidth + typeWidth + valueWidth, border4, 15, 40); + // Body/stacktrace spans full width (single column table) + int bodyWidth = TerminalWidthHelper.flexWidth(tw, 0, TerminalWidthHelper.noBorderOverhead(1), 40, 160); + // Exception table: kind + type + value (3 columns) + int border3 = TerminalWidthHelper.noBorderOverhead(3); + int excValueWidth = TerminalWidthHelper.flexWidth(tw, kindWidth + 40, border3, 20, 80); + int excTypeWidth = TerminalWidthHelper.flexWidth(tw, kindWidth + excValueWidth, border3, 15, 40); + List<TableRow> rows = new ArrayList<>(); TableRow eRow; String tab0 = null; @@ -205,14 +221,14 @@ public class MessageTableHelper { if (!rows.isEmpty()) { tab2 = AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().dataAlign(HorizontalAlign.LEFT) - .minWidth(showExchangeProperties || showExchangeVariables ? 12 : 10) + .minWidth(kindWidth) .with(TableRow::kindAsString), new Column().dataAlign(HorizontalAlign.LEFT) - .minWidth(25).maxWidth(50, OverflowBehaviour.CLIP_LEFT).with(TableRow::typeAsString), + .minWidth(25).maxWidth(typeWidth, OverflowBehaviour.CLIP_LEFT).with(TableRow::typeAsString), new Column().dataAlign(HorizontalAlign.RIGHT) - .minWidth(25).maxWidth(40, OverflowBehaviour.NEWLINE).with(TableRow::keyAsString), + .minWidth(25).maxWidth(keyWidth, OverflowBehaviour.NEWLINE).with(TableRow::keyAsString), new Column().dataAlign(HorizontalAlign.LEFT) - .maxWidth(80, OverflowBehaviour.NEWLINE).with(TableRow::valueAsString))); + .maxWidth(valueWidth, OverflowBehaviour.NEWLINE).with(TableRow::valueAsString))); } rows.clear(); @@ -255,14 +271,14 @@ public class MessageTableHelper { // headers tab4 = AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().dataAlign(HorizontalAlign.LEFT) - .minWidth(showExchangeProperties || showExchangeVariables ? 12 : 10) + .minWidth(kindWidth) .with(TableRow::kindAsString), new Column().dataAlign(HorizontalAlign.LEFT) - .minWidth(25).maxWidth(50, OverflowBehaviour.CLIP_LEFT).with(TableRow::typeAsString), + .minWidth(25).maxWidth(typeWidth, OverflowBehaviour.CLIP_LEFT).with(TableRow::typeAsString), new Column().dataAlign(HorizontalAlign.RIGHT) - .minWidth(25).maxWidth(40, OverflowBehaviour.NEWLINE).with(TableRow::keyAsString), + .minWidth(25).maxWidth(keyWidth, OverflowBehaviour.NEWLINE).with(TableRow::keyAsString), new Column().dataAlign(HorizontalAlign.LEFT) - .maxWidth(80, OverflowBehaviour.NEWLINE).with(TableRow::valueAsString))); + .maxWidth(valueWidth, OverflowBehaviour.NEWLINE).with(TableRow::valueAsString))); } rows.clear(); @@ -279,7 +295,7 @@ public class MessageTableHelper { // body value only (span) if (bodyRow.value != null) { tab6 = AsciiTable.getTable(AsciiTable.NO_BORDERS, List.of(bodyRow), Collections.singletonList( - new Column().dataAlign(HorizontalAlign.LEFT).maxWidth(160, OverflowBehaviour.NEWLINE) + new Column().dataAlign(HorizontalAlign.LEFT).maxWidth(bodyWidth, OverflowBehaviour.NEWLINE) .with(b -> pretty ? bodyRow.valueAsStringPretty() : bodyRow.valueAsString()))); } } @@ -290,12 +306,12 @@ public class MessageTableHelper { eRow = new TableRow("Exception", cause.getString("type"), null, cause.get("message")); tab7 = AsciiTable.getTable(AsciiTable.NO_BORDERS, List.of(eRow), Arrays.asList( new Column().dataAlign(HorizontalAlign.LEFT) - .minWidth(showExchangeProperties || showExchangeVariables ? 12 : 10) + .minWidth(kindWidth) .with(TableRow::kindAsStringRed), new Column().dataAlign(HorizontalAlign.LEFT) - .maxWidth(40, OverflowBehaviour.CLIP_LEFT).with(TableRow::typeAsString), + .maxWidth(excTypeWidth, OverflowBehaviour.CLIP_LEFT).with(TableRow::typeAsString), new Column().dataAlign(HorizontalAlign.LEFT) - .maxWidth(80, OverflowBehaviour.NEWLINE).with(TableRow::valueAsStringRed))); + .maxWidth(excValueWidth, OverflowBehaviour.NEWLINE).with(TableRow::valueAsStringRed))); } // stacktrace only (span) String tab8 = null; @@ -305,7 +321,7 @@ public class MessageTableHelper { value = Jsoner.unescape(value); eRow = new TableRow("Stacktrace", null, null, value); tab8 = AsciiTable.getTable(AsciiTable.NO_BORDERS, List.of(eRow), Collections.singletonList( - new Column().dataAlign(HorizontalAlign.LEFT).maxWidth(160, OverflowBehaviour.NEWLINE) + new Column().dataAlign(HorizontalAlign.LEFT).maxWidth(bodyWidth, OverflowBehaviour.NEWLINE) .with(TableRow::valueAsStringRed))); } } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/RouteControllerAction.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/RouteControllerAction.java index 7c5fa1fb64b4..b8970c07541d 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/RouteControllerAction.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/RouteControllerAction.java @@ -30,6 +30,7 @@ import com.github.freva.asciitable.HorizontalAlign; import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.PathUtils; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.util.StringHelper; import org.apache.camel.util.TimeUtils; import org.apache.camel.util.json.JsonArray; @@ -197,10 +198,18 @@ public class RouteControllerAction extends ActionWatchCommand { } protected void dumpTable(List<Row> rows, boolean supervised) { + int tw = terminalWidth(); + int fixedWidth = 25 + 12 + (supervised ? 10 + 10 + 10 : 0); // ID + STATE + ATTEMPT + ELAPSED + LAST-AGO + int colCount = supervised ? 7 : 3; + int borderOverhead = TerminalWidthHelper.noBorderOverhead(colCount); + int uriWidth = TerminalWidthHelper.flexWidth(tw, fixedWidth + (supervised ? 80 : 0), borderOverhead, 20, 60); + int errorWidth = supervised + ? TerminalWidthHelper.flexWidth(tw, fixedWidth + uriWidth, borderOverhead, 20, 80) : 80; + printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("ID").dataAlign(HorizontalAlign.LEFT).maxWidth(25, OverflowBehaviour.ELLIPSIS_RIGHT) .with(r -> r.routeId), - new Column().header("URI").dataAlign(HorizontalAlign.LEFT).maxWidth(60, OverflowBehaviour.ELLIPSIS_RIGHT) + new Column().header("URI").dataAlign(HorizontalAlign.LEFT).maxWidth(uriWidth, OverflowBehaviour.ELLIPSIS_RIGHT) .with(r -> r.uri), new Column().header("STATE").headerAlign(HorizontalAlign.RIGHT).with(this::getSupervising), new Column().visible(supervised).header("ATTEMPT").headerAlign(HorizontalAlign.CENTER) @@ -209,7 +218,7 @@ public class RouteControllerAction extends ActionWatchCommand { new Column().visible(supervised).header("LAST-AGO").headerAlign(HorizontalAlign.CENTER).with(this::getLast), new Column().visible(supervised).header("ERROR-MESSAGE").headerAlign(HorizontalAlign.LEFT) .dataAlign(HorizontalAlign.LEFT) - .maxWidth(80, OverflowBehaviour.ELLIPSIS_RIGHT).with(r -> r.error)))); + .maxWidth(errorWidth, OverflowBehaviour.ELLIPSIS_RIGHT).with(r -> r.error)))); if (supervised && trace) { rows = rows.stream().filter(r -> r.error != null && !r.error.isEmpty()).collect(Collectors.toList()); diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogBaseCommand.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogBaseCommand.java index 288d7ad3defb..9d84eccac320 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogBaseCommand.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogBaseCommand.java @@ -25,6 +25,7 @@ import java.util.stream.Collectors; import com.github.freva.asciitable.AsciiTable; import com.github.freva.asciitable.Column; import com.github.freva.asciitable.HorizontalAlign; +import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.catalog.CamelCatalog; import org.apache.camel.catalog.DefaultCamelCatalog; import org.apache.camel.dsl.jbang.core.commands.CamelCommand; @@ -33,6 +34,7 @@ import org.apache.camel.dsl.jbang.core.common.CatalogLoader; import org.apache.camel.dsl.jbang.core.common.RuntimeCompletionCandidates; import org.apache.camel.dsl.jbang.core.common.RuntimeType; import org.apache.camel.dsl.jbang.core.common.RuntimeTypeConverter; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.dsl.jbang.core.common.VersionHelper; import org.apache.camel.dsl.jbang.core.model.CatalogBaseDTO; import org.apache.camel.tooling.maven.MavenGav; @@ -156,6 +158,15 @@ public abstract class CatalogBaseCommand extends CamelCommand { .map(CatalogBaseDTO::toMap) .collect(Collectors.toList()))); } else { + // Compute description width: terminal minus fixed columns and border overhead + int fixedWidth = nameWidth() + 12 + 8; // LEVEL ~12 chars, SINCE ~8 chars + if (RuntimeType.quarkus == runtime) { + fixedWidth += 8; // NATIVE column + } + int descWidth = TerminalWidthHelper.flexWidth( + terminalWidth(), fixedWidth, TerminalWidthHelper.noBorderOverhead( + RuntimeType.quarkus == runtime ? 5 : 4), + 20, 80); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("NAME").visible(!displayGav).dataAlign(HorizontalAlign.LEFT).maxWidth(nameWidth()) .with(r -> r.name), @@ -165,7 +176,9 @@ public abstract class CatalogBaseCommand extends CamelCommand { new Column().header("NATIVE").dataAlign(HorizontalAlign.CENTER) .visible(RuntimeType.quarkus == runtime).with(this::nativeSupported), new Column().header("SINCE").dataAlign(HorizontalAlign.RIGHT).with(r -> r.since), - new Column().header("DESCRIPTION").dataAlign(HorizontalAlign.LEFT).with(this::shortDescription)))); + new Column().header("DESCRIPTION").dataAlign(HorizontalAlign.LEFT) + .maxWidth(descWidth, OverflowBehaviour.ELLIPSIS_RIGHT) + .with(this::shortDescription)))); } } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogDoc.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogDoc.java index 2416a4ab6952..fd3b9fdad533 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogDoc.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogDoc.java @@ -36,6 +36,7 @@ import org.apache.camel.dsl.jbang.core.common.CatalogLoader; import org.apache.camel.dsl.jbang.core.common.RuntimeCompletionCandidates; import org.apache.camel.dsl.jbang.core.common.RuntimeType; import org.apache.camel.dsl.jbang.core.common.RuntimeTypeConverter; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.main.util.SuggestSimilarHelper; import org.apache.camel.tooling.maven.MavenGav; import org.apache.camel.tooling.model.BaseOptionModel; @@ -275,17 +276,22 @@ public class CatalogDoc extends CamelCommand { printer().printf("The %s kamelet supports (total: %s match-filter: %s) options, which are listed below.%n%n", km.name, total1, total2); } + int[] kw = docColumnWidths5(35, 80, 25, 25, 40); printer().println(AsciiTable.getTable(AsciiTable.FANCY_ASCII, filtered, Arrays.asList( - new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).minWidth(20) - .maxWidth(35, OverflowBehaviour.NEWLINE) + new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) + .maxWidth(kw[0], OverflowBehaviour.NEWLINE) .with(r -> r.name), - new Column().header("DESCRIPTION").dataAlign(HorizontalAlign.LEFT).maxWidth(80, OverflowBehaviour.NEWLINE) + new Column().header("DESCRIPTION").dataAlign(HorizontalAlign.LEFT) + .maxWidth(kw[1], OverflowBehaviour.NEWLINE) .with(this::getDescription), - new Column().header("DEFAULT").dataAlign(HorizontalAlign.LEFT).maxWidth(25, OverflowBehaviour.NEWLINE) + new Column().header("DEFAULT").dataAlign(HorizontalAlign.LEFT) + .maxWidth(kw[2], OverflowBehaviour.NEWLINE) .with(r -> r.defaultValue), - new Column().header("TYPE").dataAlign(HorizontalAlign.LEFT).maxWidth(25, OverflowBehaviour.NEWLINE) + new Column().header("TYPE").dataAlign(HorizontalAlign.LEFT) + .maxWidth(kw[3], OverflowBehaviour.NEWLINE) .with(r -> r.type), - new Column().header("EXAMPLE").dataAlign(HorizontalAlign.LEFT).maxWidth(40, OverflowBehaviour.NEWLINE) + new Column().header("EXAMPLE").dataAlign(HorizontalAlign.LEFT) + .maxWidth(kw[4], OverflowBehaviour.NEWLINE) .with(r -> r.example)))); printer().println(""); } @@ -338,16 +344,19 @@ public class CatalogDoc extends CamelCommand { } else { printer().printf("%s options (total: %s match-filter: %s):%n", g.getDescription(), total1, total2); } + int[] mw = docColumnWidths(40, 80, 25, 25); printer().println(AsciiTable.getTable(AsciiTable.FANCY_ASCII, filtered, Arrays.asList( - new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).minWidth(20) - .maxWidth(40, OverflowBehaviour.NEWLINE) + new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) + .maxWidth(mw[0], OverflowBehaviour.NEWLINE) .with(this::getName), new Column().header("DESCRIPTION").dataAlign(HorizontalAlign.LEFT) - .maxWidth(80, OverflowBehaviour.NEWLINE) + .maxWidth(mw[1], OverflowBehaviour.NEWLINE) .with(this::getDescription), - new Column().header("DEFAULT").dataAlign(HorizontalAlign.LEFT).maxWidth(25, OverflowBehaviour.NEWLINE) - .with(r -> r.getShortDefaultValue(25)), - new Column().header("TYPE").dataAlign(HorizontalAlign.LEFT).maxWidth(25, OverflowBehaviour.NEWLINE) + new Column().header("DEFAULT").dataAlign(HorizontalAlign.LEFT) + .maxWidth(mw[2], OverflowBehaviour.NEWLINE) + .with(r -> r.getShortDefaultValue(mw[2])), + new Column().header("TYPE").dataAlign(HorizontalAlign.LEFT) + .maxWidth(mw[3], OverflowBehaviour.NEWLINE) .with(BaseOptionModel::getShortJavaType)))); printer().println(""); printer().println(""); @@ -406,15 +415,7 @@ public class CatalogDoc extends CamelCommand { printer().println("with the following path and query parameters:"); printer().println(""); printer().printf("Path parameters (%s):%n", cm.getEndpointPathOptions().size()); - printer().println(AsciiTable.getTable(AsciiTable.FANCY_ASCII, cm.getEndpointPathOptions(), Arrays.asList( - new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).minWidth(20).maxWidth(35, OverflowBehaviour.NEWLINE) - .with(this::getName), - new Column().header("DESCRIPTION").dataAlign(HorizontalAlign.LEFT).maxWidth(80, OverflowBehaviour.NEWLINE) - .with(this::getDescription), - new Column().header("DEFAULT").dataAlign(HorizontalAlign.LEFT).maxWidth(25, OverflowBehaviour.NEWLINE) - .with(r -> r.getShortDefaultValue(25)), - new Column().header("TYPE").dataAlign(HorizontalAlign.LEFT).maxWidth(25, OverflowBehaviour.NEWLINE) - .with(BaseOptionModel::getShortJavaType)))); + printer().println(optionTable(cm.getEndpointPathOptions())); printer().println(""); var filtered = filter(filter, cm.getEndpointParameterOptions()); var total1 = cm.getEndpointParameterOptions().size(); @@ -424,15 +425,7 @@ public class CatalogDoc extends CamelCommand { } else { printer().printf("Query parameters (total: %s match-filter: %s):%n", total1, total2); } - printer().println(AsciiTable.getTable(AsciiTable.FANCY_ASCII, filtered, Arrays.asList( - new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).minWidth(20).maxWidth(35, OverflowBehaviour.NEWLINE) - .with(this::getName), - new Column().header("DESCRIPTION").dataAlign(HorizontalAlign.LEFT).maxWidth(80, OverflowBehaviour.NEWLINE) - .with(this::getDescription), - new Column().header("DEFAULT").dataAlign(HorizontalAlign.LEFT).maxWidth(25, OverflowBehaviour.NEWLINE) - .with(r -> r.getShortDefaultValue(25)), - new Column().header("TYPE").dataAlign(HorizontalAlign.LEFT).maxWidth(25, OverflowBehaviour.NEWLINE) - .with(BaseOptionModel::getShortJavaType)))); + printer().println(optionTable(filtered)); printer().println(""); if (headers && !cm.getEndpointHeaders().isEmpty()) { @@ -444,16 +437,7 @@ public class CatalogDoc extends CamelCommand { } else { printer().printf("Message headers (total: %s match-filter: %s):%n", total1, total2); } - printer().println(AsciiTable.getTable(AsciiTable.FANCY_ASCII, filtered, Arrays.asList( - new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).minWidth(20) - .maxWidth(35, OverflowBehaviour.NEWLINE) - .with(this::getName), - new Column().header("DESCRIPTION").dataAlign(HorizontalAlign.LEFT).maxWidth(80, OverflowBehaviour.NEWLINE) - .with(this::getDescription), - new Column().header("DEFAULT").dataAlign(HorizontalAlign.LEFT).maxWidth(25, OverflowBehaviour.NEWLINE) - .with(r -> r.getShortDefaultValue(25)), - new Column().header("TYPE").dataAlign(HorizontalAlign.LEFT).maxWidth(25, OverflowBehaviour.NEWLINE) - .with(BaseOptionModel::getShortJavaType)))); + printer().println(optionTable(filtered)); printer().println(""); } @@ -503,15 +487,7 @@ public class CatalogDoc extends CamelCommand { printer().printf("The %s dataformat supports (total: %s match-filter: %s) options, which are listed below.%n%n", dm.getName(), total1, total2); } - printer().println(AsciiTable.getTable(AsciiTable.FANCY_ASCII, filtered, Arrays.asList( - new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).minWidth(20).maxWidth(35, OverflowBehaviour.NEWLINE) - .with(this::getName), - new Column().header("DESCRIPTION").dataAlign(HorizontalAlign.LEFT).maxWidth(80, OverflowBehaviour.NEWLINE) - .with(this::getDescription), - new Column().header("DEFAULT").dataAlign(HorizontalAlign.LEFT).maxWidth(25, OverflowBehaviour.NEWLINE) - .with(r -> r.getShortDefaultValue(25)), - new Column().header("TYPE").dataAlign(HorizontalAlign.LEFT).maxWidth(25, OverflowBehaviour.NEWLINE) - .with(BaseOptionModel::getShortJavaType)))); + printer().println(optionTable(filtered)); printer().println(""); if (link != null) { @@ -560,15 +536,7 @@ public class CatalogDoc extends CamelCommand { printer().printf("The %s language supports (total: %s match-filter: %s) options, which are listed below.%n%n", lm.getName(), total1, total2); } - printer().println(AsciiTable.getTable(AsciiTable.FANCY_ASCII, filtered, Arrays.asList( - new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).minWidth(20).maxWidth(35, OverflowBehaviour.NEWLINE) - .with(this::getName), - new Column().header("DESCRIPTION").dataAlign(HorizontalAlign.LEFT).maxWidth(80, OverflowBehaviour.NEWLINE) - .with(this::getDescription), - new Column().header("DEFAULT").dataAlign(HorizontalAlign.LEFT).maxWidth(25, OverflowBehaviour.NEWLINE) - .with(r -> r.getShortDefaultValue(25)), - new Column().header("TYPE").dataAlign(HorizontalAlign.LEFT).maxWidth(25, OverflowBehaviour.NEWLINE) - .with(BaseOptionModel::getShortJavaType)))); + printer().println(optionTable(filtered)); printer().println(""); if (link != null) { @@ -614,6 +582,48 @@ public class CatalogDoc extends CamelCommand { } } + private int[] docColumnWidths(int nameMax, int descMax, int defaultMax, int typeMax) { + int tw = terminalWidth(); + int borders = TerminalWidthHelper.fancyBorderOverhead(4); + int totalPreferred = nameMax + descMax + defaultMax + typeMax; + return new int[] { + TerminalWidthHelper.scaleWidth(tw, borders, nameMax, 12, totalPreferred), + TerminalWidthHelper.scaleWidth(tw, borders, descMax, 15, totalPreferred), + TerminalWidthHelper.scaleWidth(tw, borders, defaultMax, 8, totalPreferred), + TerminalWidthHelper.scaleWidth(tw, borders, typeMax, 8, totalPreferred) + }; + } + + private String optionTable(List<? extends BaseOptionModel> options) { + int[] w = docColumnWidths(35, 80, 25, 25); + return AsciiTable.getTable(AsciiTable.FANCY_ASCII, options, Arrays.asList( + new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) + .maxWidth(w[0], OverflowBehaviour.NEWLINE) + .with(this::getName), + new Column().header("DESCRIPTION").dataAlign(HorizontalAlign.LEFT) + .maxWidth(w[1], OverflowBehaviour.NEWLINE) + .with(this::getDescription), + new Column().header("DEFAULT").dataAlign(HorizontalAlign.LEFT) + .maxWidth(w[2], OverflowBehaviour.NEWLINE) + .with(r -> r.getShortDefaultValue(w[2])), + new Column().header("TYPE").dataAlign(HorizontalAlign.LEFT) + .maxWidth(w[3], OverflowBehaviour.NEWLINE) + .with(BaseOptionModel::getShortJavaType))); + } + + private int[] docColumnWidths5(int nameMax, int descMax, int defaultMax, int typeMax, int exampleMax) { + int tw = terminalWidth(); + int borders = TerminalWidthHelper.fancyBorderOverhead(5); + int totalPreferred = nameMax + descMax + defaultMax + typeMax + exampleMax; + return new int[] { + TerminalWidthHelper.scaleWidth(tw, borders, nameMax, 12, totalPreferred), + TerminalWidthHelper.scaleWidth(tw, borders, descMax, 15, totalPreferred), + TerminalWidthHelper.scaleWidth(tw, borders, defaultMax, 8, totalPreferred), + TerminalWidthHelper.scaleWidth(tw, borders, typeMax, 8, totalPreferred), + TerminalWidthHelper.scaleWidth(tw, borders, exampleMax, 8, totalPreferred) + }; + } + String getName(BaseOptionModel o) { String l = o.getShortGroup(); if (l != null && !"common".equals(l)) { diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogKamelet.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogKamelet.java index 304ba8d84f28..b6fd263d6b33 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogKamelet.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogKamelet.java @@ -30,6 +30,7 @@ import com.github.freva.asciitable.HorizontalAlign; import org.apache.camel.dsl.jbang.core.commands.CamelCommand; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.RuntimeType; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.dsl.jbang.core.common.VersionHelper; import org.apache.camel.main.download.DependencyDownloaderClassLoader; import org.apache.camel.main.download.MavenDependencyDownloader; @@ -109,11 +110,18 @@ public class CatalogKamelet extends CamelCommand { rows.sort(this::sortRow); if (!rows.isEmpty()) { + int tw = terminalWidth(); + // Fixed columns: NAME (~30), TYPE (10), LEVEL (12) + int fixedWidth = 30 + 10 + 12; + int descWidth = TerminalWidthHelper.flexWidth( + tw, fixedWidth, TerminalWidthHelper.noBorderOverhead(4), + 20, 80); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).with(r -> r.name), new Column().header("TYPE").dataAlign(HorizontalAlign.LEFT).minWidth(10).with(r -> r.type), new Column().header("LEVEL").dataAlign(HorizontalAlign.LEFT).minWidth(12).with(r -> r.supportLevel), - new Column().header("DESCRIPTION").dataAlign(HorizontalAlign.LEFT).with(this::getDescription)))); + new Column().header("DESCRIPTION").dataAlign(HorizontalAlign.LEFT).maxWidth(descWidth) + .with(this::getDescription)))); } return 0; diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraBaseCommand.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraBaseCommand.java index e23f41cf8a74..bcba428d72ea 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraBaseCommand.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraBaseCommand.java @@ -48,6 +48,7 @@ import org.apache.camel.catalog.DefaultCamelCatalog; import org.apache.camel.dsl.jbang.core.commands.CamelCommand; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.CommandLineHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.dsl.jbang.core.model.InfraBaseDTO; import org.apache.camel.support.PatternHelper; import org.apache.camel.util.FileUtil; @@ -178,11 +179,20 @@ public abstract class InfraBaseCommand extends CamelCommand { .map(InfraBaseDTO::toMap) .collect(Collectors.toList()))); } else { + int tw = terminalWidth(); + // Fixed columns: PID (~8), ALIAS (width+2), SERVICE_DATA (~30), DESCRIPTION (~30) + int fixedWidth = (width + 2) + 30 + 30; + if (showPidColumn()) { + fixedWidth += 8; + } + int implWidth = TerminalWidthHelper.flexWidth( + tw, fixedWidth, TerminalWidthHelper.noBorderOverhead(showPidColumn() ? 5 : 4), + 20, 35); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").visible(showPidColumn()).headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("ALIAS").minWidth(width + 2).dataAlign(HorizontalAlign.LEFT) .with(Row::alias), - new Column().header("IMPLEMENTATION").maxWidth(35, OverflowBehaviour.NEWLINE) + new Column().header("IMPLEMENTATION").maxWidth(implWidth, OverflowBehaviour.NEWLINE) .dataAlign(HorizontalAlign.LEFT).with(Row::aliasImplementation), new Column().header("DESCRIPTION").dataAlign(HorizontalAlign.LEFT).with(Row::description), new Column().header("SERVICE_DATA").dataAlign(HorizontalAlign.LEFT).with(Row::serviceData)))); diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java index e2955e86e36a..e27000a72ee5 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java @@ -29,6 +29,7 @@ import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.PidNameAgeCompletionCandidates; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.dsl.jbang.core.common.VersionHelper; import org.apache.camel.util.TimeUtils; import org.apache.camel.util.json.JsonArray; @@ -191,6 +192,10 @@ public class CamelContextStatus extends ProcessWatchCommand { return jo; }).collect(Collectors.toList()))); } else { + // Flexible column: error description (70) + // Fixed columns: PID(8)+NAME(30)+CAMEL(8)+PLATFORM(12)+PROFILE(8)+READY(5)+STATUS(8)+RELOAD(6)+AGE(8)+ROUTE(5)+MSG/S(5)+TOTAL(5)+FAIL(4)+INFLIGHT(8)+LAST(4)+SINCE-LAST(10) ~= 134 + int tw = terminalWidth(); + int errW = TerminalWidthHelper.flexWidth(tw, 134, TerminalWidthHelper.noBorderOverhead(17), 15, 70); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) @@ -213,7 +218,7 @@ public class CamelContextStatus extends ProcessWatchCommand { new Column().header("SINCE-LAST").with(this::getSinceLast), new Column().header("") // empty header as we only show info when there is an error .headerAlign(HorizontalAlign.LEFT).dataAlign(HorizontalAlign.LEFT) - .maxWidth(70, OverflowBehaviour.NEWLINE) + .maxWidth(errW, OverflowBehaviour.NEWLINE) .with(this::getDescription)))); } } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelProcessorStatus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelProcessorStatus.java index 3b9d8b877aa4..420cb02b4359 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelProcessorStatus.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelProcessorStatus.java @@ -29,6 +29,7 @@ import com.github.freva.asciitable.HorizontalAlign; import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.support.PatternHelper; import org.apache.camel.tooling.model.Strings; import org.apache.camel.util.StringHelper; @@ -326,6 +327,12 @@ public class CamelProcessorStatus extends ProcessWatchCommand { }).collect(Collectors.toList()))); return; } + // Flexible columns: ID (40), ID desc (60), PROCESSOR (45) + // Fixed columns: PID(8)+NAME(30)+GROUP(20)+STATUS(8)+TOTAL(5)+FAIL(4)+INFLIGHT(8)+MEAN(4)+MIN(3)+MAX(3)+LAST(4)+DELTA(5)+SINCE-LAST(10) ~= 112 + int tw = terminalWidth(); + int idW = TerminalWidthHelper.flexWidth(tw, 112 + 45, TerminalWidthHelper.noBorderOverhead(15), 15, 40); + int idDescW = TerminalWidthHelper.flexWidth(tw, 112 + 45, TerminalWidthHelper.noBorderOverhead(15), 20, 60); + int procW = TerminalWidthHelper.flexWidth(tw, 112 + 40, TerminalWidthHelper.noBorderOverhead(15), 20, 45); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(this::getPid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).maxWidth(30, OverflowBehaviour.ELLIPSIS_RIGHT) @@ -334,13 +341,13 @@ public class CamelProcessorStatus extends ProcessWatchCommand { .maxWidth(20, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getGroup), new Column().header("ID").visible(!description && !note).dataAlign(HorizontalAlign.LEFT) - .maxWidth(40, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(idW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getId), new Column().header("ID").visible(description || note).dataAlign(HorizontalAlign.LEFT) - .maxWidth(60, OverflowBehaviour.NEWLINE) + .maxWidth(idDescW, OverflowBehaviour.NEWLINE) .with(this::getIdAndNoteDescription), new Column().header("PROCESSOR").dataAlign(HorizontalAlign.LEFT).minWidth(25) - .maxWidth(45, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(procW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getProcessor), new Column().header("STATUS").dataAlign(HorizontalAlign.LEFT).headerAlign(HorizontalAlign.CENTER) .with(this::getStatus), diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java index 0ace6069aedb..a4106f65f550 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java @@ -30,6 +30,7 @@ import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.PidNameAgeCompletionCandidates; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.support.PatternHelper; import org.apache.camel.tooling.model.Strings; import org.apache.camel.util.StringHelper; @@ -285,6 +286,12 @@ public class CamelRouteStatus extends ProcessWatchCommand { }).collect(Collectors.toList()))); return; } + // Flexible columns: FROM (45/140), ID with description (45) + // Fixed columns: PID(8)+NAME(30)+GROUP(20)+ID(20)+REMOTE(6)+STATUS(8)+AGE(8)+COVER(5)+MSG/S(5)+TOTAL(5)+FAIL(4)+INFLIGHT(8)+MEAN(4)+MIN(3)+MAX(3)+LAST(4)+DELTA(5)+SINCE-LAST(10) ~= 156 + int tw = terminalWidth(); + int fromW = TerminalWidthHelper.flexWidth(tw, 156, TerminalWidthHelper.noBorderOverhead(21), 20, 45); + int fromWideW = TerminalWidthHelper.flexWidth(tw, 156, TerminalWidthHelper.noBorderOverhead(21), 20, 140); + int idDescW = TerminalWidthHelper.flexWidth(tw, 156, TerminalWidthHelper.noBorderOverhead(21), 20, 45); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).maxWidth(30, OverflowBehaviour.ELLIPSIS_RIGHT) @@ -296,13 +303,13 @@ public class CamelRouteStatus extends ProcessWatchCommand { .maxWidth(20, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getId), new Column().header("ID").visible(description || note).dataAlign(HorizontalAlign.LEFT) - .maxWidth(45, OverflowBehaviour.NEWLINE) + .maxWidth(idDescW, OverflowBehaviour.NEWLINE) .with(this::getIdAndNoteDescription), new Column().header("FROM").visible(!wideUri).dataAlign(HorizontalAlign.LEFT) - .maxWidth(45, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(fromW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getFrom), new Column().header("FROM").visible(wideUri).dataAlign(HorizontalAlign.LEFT) - .maxWidth(140, OverflowBehaviour.NEWLINE) + .maxWidth(fromWideW, OverflowBehaviour.NEWLINE) .with(r -> r.from), new Column().header("REMOTE").visible(remoteVisible).headerAlign(HorizontalAlign.CENTER) .dataAlign(HorizontalAlign.CENTER) @@ -324,6 +331,12 @@ public class CamelRouteStatus extends ProcessWatchCommand { } protected void printErrorTable(Row er, boolean remoteVisible) { + // Flexible columns: FROM (45), ID desc (45), MESSAGE (80) + // Fixed columns: PID(8)+NAME(30)+ID(20)+REMOTE(6)+STATUS(8)+PHASE(8)+AGO(8) ~= 88 + int tw2 = terminalWidth(); + int errFromW = TerminalWidthHelper.flexWidth(tw2, 88, TerminalWidthHelper.noBorderOverhead(11), 20, 45); + int errIdDescW = TerminalWidthHelper.flexWidth(tw2, 88, TerminalWidthHelper.noBorderOverhead(11), 20, 45); + int msgW = TerminalWidthHelper.flexWidth(tw2, 88 + errFromW, TerminalWidthHelper.noBorderOverhead(11), 20, 80); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, List.of(er), Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).maxWidth(30, OverflowBehaviour.ELLIPSIS_RIGHT) @@ -332,10 +345,10 @@ public class CamelRouteStatus extends ProcessWatchCommand { .maxWidth(20, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getId), new Column().header("ID").visible(description).dataAlign(HorizontalAlign.LEFT) - .maxWidth(45, OverflowBehaviour.NEWLINE) + .maxWidth(errIdDescW, OverflowBehaviour.NEWLINE) .with(this::getIdAndNoteDescription), new Column().header("FROM").visible(!wideUri).dataAlign(HorizontalAlign.LEFT) - .maxWidth(45, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(errFromW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getFrom), new Column().header("FROM").visible(wideUri).dataAlign(HorizontalAlign.LEFT) .with(r -> r.from), @@ -349,7 +362,7 @@ public class CamelRouteStatus extends ProcessWatchCommand { new Column().header("AGO").headerAlign(HorizontalAlign.CENTER) .with(this::getErrorAgo), new Column().header("MESSAGE").dataAlign(HorizontalAlign.LEFT) - .maxWidth(80, OverflowBehaviour.NEWLINE) + .maxWidth(msgW, OverflowBehaviour.NEWLINE) .with(r -> r.lastErrorMessage)))); if (!er.stackTrace.isEmpty()) { printer().println(); diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteTop.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteTop.java index fbbd4fa714e4..63587c506663 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteTop.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteTop.java @@ -24,6 +24,7 @@ import com.github.freva.asciitable.Column; import com.github.freva.asciitable.HorizontalAlign; import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import picocli.CommandLine.Command; @Command(name = "route", description = "Top performing routes", @@ -36,6 +37,10 @@ public class CamelRouteTop extends CamelRouteStatus { @Override protected void printTable(List<Row> rows, boolean remoteVisible) { + // Flexible column: FROM (40) + // Fixed columns: PID(8)+NAME(30)+GROUP(20)+ID(25)+REMOTE(6)+STATUS(8)+AGE(8)+LOAD(12)+TOTAL(5)+FAIL(4)+INFLIGHT(8)+MEAN(4)+MIN(3)+MAX(3)+SINCE-LAST(10) ~= 154 + int tw = terminalWidth(); + int fromW = TerminalWidthHelper.flexWidth(tw, 154, TerminalWidthHelper.noBorderOverhead(16), 20, 40); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).maxWidth(30, OverflowBehaviour.ELLIPSIS_RIGHT) @@ -45,7 +50,7 @@ public class CamelRouteTop extends CamelRouteStatus { .with(this::getGroup), new Column().header("ID").dataAlign(HorizontalAlign.LEFT).maxWidth(25, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getId), - new Column().header("FROM").dataAlign(HorizontalAlign.LEFT).maxWidth(40, OverflowBehaviour.ELLIPSIS_RIGHT) + new Column().header("FROM").dataAlign(HorizontalAlign.LEFT).maxWidth(fromW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getFrom), new Column().header("REMOTE").visible(remoteVisible).headerAlign(HorizontalAlign.CENTER) .dataAlign(HorizontalAlign.CENTER) diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListConsumer.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListConsumer.java index 5b5ec2a2b501..beebcb197fa5 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListConsumer.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListConsumer.java @@ -29,6 +29,7 @@ import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.PidNameAgeCompletionCandidates; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.support.PatternHelper; import org.apache.camel.util.TimeUtils; import org.apache.camel.util.json.JsonArray; @@ -186,6 +187,11 @@ public class ListConsumer extends ProcessWatchCommand { }).collect(Collectors.toList()))); return; } + // Flexible column: URI (90/140) + // Fixed columns: PID(8)+NAME(30)+AGE(8)+ID(20)+STATUS(8)+TYPE(20)+INFLIGHT(8)+POLL(4)+PERIOD(6)+SINCE-LAST(10) ~= 122 + int tw = terminalWidth(); + int uriW = TerminalWidthHelper.flexWidth(tw, 122, TerminalWidthHelper.noBorderOverhead(12), 20, 90); + int uriWideW = TerminalWidthHelper.flexWidth(tw, 122, TerminalWidthHelper.noBorderOverhead(12), 20, 140); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).maxWidth(30, OverflowBehaviour.ELLIPSIS_RIGHT) @@ -201,10 +207,10 @@ public class ListConsumer extends ProcessWatchCommand { new Column().header("PERIOD").visible(scheduled).with(this::getPeriod), new Column().header("SINCE-LAST").with(this::getSinceLast), new Column().header("URI").visible(!wideUri).dataAlign(HorizontalAlign.LEFT) - .maxWidth(90, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(uriW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getUri), new Column().header("URI").visible(wideUri).dataAlign(HorizontalAlign.LEFT) - .maxWidth(140, OverflowBehaviour.NEWLINE) + .maxWidth(uriWideW, OverflowBehaviour.NEWLINE) .with(this::getUri)))); } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListEndpoint.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListEndpoint.java index bb85f9afa337..3ea7020087c8 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListEndpoint.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListEndpoint.java @@ -28,6 +28,7 @@ import com.github.freva.asciitable.HorizontalAlign; import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.support.PatternHelper; import org.apache.camel.util.TimeUtils; import org.apache.camel.util.json.JsonArray; @@ -178,6 +179,11 @@ public class ListEndpoint extends ProcessWatchCommand { }).collect(Collectors.toList()))); return; } + // Flexible column: URI (90/140) + // Fixed columns: PID(8)+NAME(30)+AGE(8)+DIR(3)+TOTAL(5)+STUB(4)+REMOTE(6) ~= 64 + int tw = terminalWidth(); + int uriW = TerminalWidthHelper.flexWidth(tw, 64, TerminalWidthHelper.noBorderOverhead(9), 20, 90); + int uriWideW = TerminalWidthHelper.flexWidth(tw, 64, TerminalWidthHelper.noBorderOverhead(9), 20, 140); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).maxWidth(30, OverflowBehaviour.ELLIPSIS_RIGHT) @@ -188,10 +194,10 @@ public class ListEndpoint extends ProcessWatchCommand { new Column().header("STUB").dataAlign(HorizontalAlign.CENTER).with(r -> r.stub ? "x" : ""), new Column().header("REMOTE").dataAlign(HorizontalAlign.CENTER).with(r -> r.remote ? "x" : ""), new Column().header("URI").visible(!wideUri).dataAlign(HorizontalAlign.LEFT) - .maxWidth(90, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(uriW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getUri), new Column().header("URI").visible(wideUri).dataAlign(HorizontalAlign.LEFT) - .maxWidth(140, OverflowBehaviour.NEWLINE) + .maxWidth(uriWideW, OverflowBehaviour.NEWLINE) .with(this::getUri)))); } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListGroovy.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListGroovy.java index fdc34ae24b4d..78eec51969a7 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListGroovy.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListGroovy.java @@ -27,6 +27,7 @@ import com.github.freva.asciitable.HorizontalAlign; import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.util.TimeUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; @@ -109,6 +110,10 @@ public class ListGroovy extends ProcessWatchCommand { return jo; }).collect(Collectors.toList()))); } else { + // Flexible column: CLASSES (60) + // Fixed columns: PID(8)+NAME(30)+PRELOAD(7)+COMPILE(7)+TIME(8)+SINCE(8) ~= 68 + int tw = terminalWidth(); + int classesW = TerminalWidthHelper.flexWidth(tw, 68, TerminalWidthHelper.noBorderOverhead(7), 15, 60); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) @@ -121,7 +126,7 @@ public class ListGroovy extends ProcessWatchCommand { new Column().header("TIME").headerAlign(HorizontalAlign.CENTER).with(this::getTime), new Column().header("SINCE").headerAlign(HorizontalAlign.CENTER).with(this::getLast), new Column().header("CLASSES").headerAlign(HorizontalAlign.LEFT).dataAlign(HorizontalAlign.LEFT) - .maxWidth(60, OverflowBehaviour.ELLIPSIS_LEFT).with(this::getClasses)))); + .maxWidth(classesW, OverflowBehaviour.ELLIPSIS_LEFT).with(this::getClasses)))); } } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListHealth.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListHealth.java index 508e04c1aff6..aaf70735aaa0 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListHealth.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListHealth.java @@ -32,6 +32,7 @@ import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.PidNameAgeCompletionCandidates; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.health.HealthCheckHelper; import org.apache.camel.util.StringHelper; import org.apache.camel.util.TimeUtils; @@ -205,14 +206,20 @@ public class ListHealth extends ProcessWatchCommand { return jo; }).collect(Collectors.toList()))); } else { + // Flexible columns: NAME (40), ID (40), MESSAGE (80) + // Fixed columns: PID(8)+AGE(8)+RL(4)+STATUS(6)+RATE(10)+SINCE(10) ~= 46 + int tw = terminalWidth(); + int nameW = TerminalWidthHelper.flexWidth(tw, 46 + 40 + 80, TerminalWidthHelper.noBorderOverhead(9), 15, 40); + int idW = TerminalWidthHelper.flexWidth(tw, 46 + 40 + 80, TerminalWidthHelper.noBorderOverhead(9), 15, 40); + int msgW = TerminalWidthHelper.flexWidth(tw, 46 + nameW + idW, TerminalWidthHelper.noBorderOverhead(9), 20, 80); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) - .maxWidth(40, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(nameW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(r -> r.name), new Column().header("AGE").headerAlign(HorizontalAlign.CENTER).with(r -> r.ago), new Column().header("ID").dataAlign(HorizontalAlign.LEFT) - .maxWidth(40, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(idW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getId), new Column().header("RL").minWidth(4).maxWidth(4).with(this::getLR), new Column().header("STATUS").headerAlign(HorizontalAlign.CENTER) @@ -225,7 +232,7 @@ public class ListHealth extends ProcessWatchCommand { .dataAlign(HorizontalAlign.RIGHT) .with(this::getSince), new Column().header("MESSAGE").dataAlign(HorizontalAlign.LEFT) - .maxWidth(80, OverflowBehaviour.NEWLINE) + .maxWidth(msgW, OverflowBehaviour.NEWLINE) .with(r -> r.message)))); } } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListInternalTask.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListInternalTask.java index 8260ac6afd81..900aa50190da 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListInternalTask.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListInternalTask.java @@ -28,6 +28,7 @@ import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.PidNameAgeCompletionCandidates; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.util.TimeUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; @@ -116,6 +117,10 @@ public class ListInternalTask extends ProcessWatchCommand { return jo; }).collect(Collectors.toList()))); } else { + // Flexible column: FAILURE (140) + // Fixed columns: PID(8)+NAME(30)+TASK(10)+STATUS(8)+ATTEMPT(7)+DELAY(5)+ELAPSED(7)+FIRST(8)+LAST(8)+NEXT(8) ~= 99 + int tw = terminalWidth(); + int failW = TerminalWidthHelper.flexWidth(tw, 99, TerminalWidthHelper.noBorderOverhead(11), 20, 140); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) @@ -130,7 +135,7 @@ public class ListInternalTask extends ProcessWatchCommand { new Column().header("LAST").dataAlign(HorizontalAlign.LEFT).with(this::getLast), new Column().header("NEXT").dataAlign(HorizontalAlign.LEFT).with(this::getNext), new Column().header("FAILURE").dataAlign(HorizontalAlign.LEFT) - .maxWidth(140, OverflowBehaviour.NEWLINE) + .maxWidth(failW, OverflowBehaviour.NEWLINE) .with(r -> r.error)))); } } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListKafka.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListKafka.java index 490a994c30fb..e4ee014b0d2e 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListKafka.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListKafka.java @@ -32,6 +32,7 @@ import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.PathUtils; import org.apache.camel.dsl.jbang.core.common.PidNameAgeCompletionCandidates; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.util.StopWatch; import org.apache.camel.util.StringHelper; import org.apache.camel.util.TimeUtils; @@ -199,6 +200,12 @@ public class ListKafka extends ProcessWatchCommand { return jo; }).collect(Collectors.toList()))); } else { + // Flexible columns: ERROR (60), ENDPOINT (90/140) + // Fixed columns: PID(8)+NAME(30)+ROUTE(8)+STATUS(8)+GROUP-ID(10)+TOPIC(10)+PARTITION(9)+OFFSET(6)+COMMITTED(10) ~= 99 + int tw = terminalWidth(); + int errW = TerminalWidthHelper.flexWidth(tw, 99 + 90, TerminalWidthHelper.noBorderOverhead(12), 15, 60); + int epW = TerminalWidthHelper.flexWidth(tw, 99 + 60, TerminalWidthHelper.noBorderOverhead(12), 20, 90); + int epWideW = TerminalWidthHelper.flexWidth(tw, 99 + 60, TerminalWidthHelper.noBorderOverhead(12), 20, 140); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) @@ -213,13 +220,13 @@ public class ListKafka extends ProcessWatchCommand { new Column().header("COMMITTED").visible(committed).dataAlign(HorizontalAlign.RIGHT) .with(this::getCommitted), new Column().header("ERROR").dataAlign(HorizontalAlign.LEFT) - .maxWidth(60, OverflowBehaviour.NEWLINE) + .maxWidth(errW, OverflowBehaviour.NEWLINE) .with(this::getLastError), new Column().header("ENDPOINT").visible(!wideUri).dataAlign(HorizontalAlign.LEFT) - .maxWidth(90, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(epW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getUri), new Column().header("ENDPOINT").visible(wideUri).dataAlign(HorizontalAlign.LEFT) - .maxWidth(140, OverflowBehaviour.NEWLINE) + .maxWidth(epWideW, OverflowBehaviour.NEWLINE) .with(this::getUri)))); } } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListMetric.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListMetric.java index f7c6f1269ade..422944c07c2b 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListMetric.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListMetric.java @@ -29,6 +29,7 @@ import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.PidNameAgeCompletionCandidates; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.util.TimeUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; @@ -221,6 +222,14 @@ public class ListMetric extends ProcessWatchCommand { return jo; }).collect(Collectors.toList()))); } else { + // Flexible columns: METRIC (40), ID (40), TAGS (60) + // Fixed columns: PID(8)+NAME(30)+TYPE(12)+VALUE(8)+MEAN(6)+MAX(6)+TOTAL(6) ~= 76 + int tw = terminalWidth(); + int metricW = TerminalWidthHelper.flexWidth(tw, 76 + 40 + 60, TerminalWidthHelper.noBorderOverhead(10), 15, 40); + int metricIdW + = TerminalWidthHelper.flexWidth(tw, 76 + 40 + 60, TerminalWidthHelper.noBorderOverhead(10), 15, 40); + int tagsW = TerminalWidthHelper.flexWidth(tw, 76 + metricW + metricIdW, + TerminalWidthHelper.noBorderOverhead(10), 15, 60); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) @@ -228,10 +237,10 @@ public class ListMetric extends ProcessWatchCommand { .with(r -> r.name), new Column().header("TYPE").dataAlign(HorizontalAlign.LEFT).with(r -> r.type), new Column().header("METRIC").dataAlign(HorizontalAlign.LEFT) - .maxWidth(40, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(metricW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(r -> r.metricName), new Column().header("ID").dataAlign(HorizontalAlign.LEFT) - .maxWidth(40, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(metricIdW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(r -> r.metricId), new Column().header("VALUE").headerAlign(HorizontalAlign.RIGHT).dataAlign(HorizontalAlign.RIGHT) .with(r -> getNumber(r.count)), @@ -242,7 +251,7 @@ public class ListMetric extends ProcessWatchCommand { new Column().header("TOTAL").headerAlign(HorizontalAlign.RIGHT).dataAlign(HorizontalAlign.RIGHT) .with(r -> getNumber(r.total)), new Column().header("TAGS").visible(tags).dataAlign(HorizontalAlign.LEFT) - .maxWidth(60, OverflowBehaviour.NEWLINE) + .maxWidth(tagsW, OverflowBehaviour.NEWLINE) .with(r -> r.tags)))); } } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProcess.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProcess.java index d1d68372ec82..2746cab92513 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProcess.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProcess.java @@ -29,6 +29,7 @@ import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.PidNameAgeCompletionCandidates; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.dsl.jbang.core.model.ListProcessDTO; import org.apache.camel.util.TimeUtils; import org.apache.camel.util.json.JsonObject; @@ -140,10 +141,14 @@ public class ListProcess extends ProcessWatchCommand { .map(ListProcessDTO::toMap) .collect(Collectors.toList()))); } else { + // Fixed columns: PID(~8) + NAME(up to nameW) + READY(5) + STATUS(8) + AGE(8) + TOTAL(6) + FAIL(5) + INFLIGHT(10) + int tw = terminalWidth(); + int nameW = TerminalWidthHelper.flexWidth(tw, 56, TerminalWidthHelper.noBorderOverhead(9), 15, 40); + int errW = TerminalWidthHelper.flexWidth(tw, nameW + 56, TerminalWidthHelper.noBorderOverhead(9), 10, 70); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) - .maxWidth(40, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(nameW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(r -> r.name), new Column().header("READY").dataAlign(HorizontalAlign.CENTER).with(r -> r.ready), new Column().header("STATUS").headerAlign(HorizontalAlign.CENTER) @@ -154,7 +159,7 @@ public class ListProcess extends ProcessWatchCommand { new Column().header("INFLIGHT").with(this::getInflight), new Column().header("") // empty header as we only show info when there is an error .headerAlign(HorizontalAlign.LEFT).dataAlign(HorizontalAlign.LEFT) - .maxWidth(70, OverflowBehaviour.NEWLINE) + .maxWidth(errW, OverflowBehaviour.NEWLINE) .with(this::getDescription)))); } } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProducer.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProducer.java index 98bb30161abe..bd433098b8fe 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProducer.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProducer.java @@ -28,6 +28,7 @@ import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.PidNameAgeCompletionCandidates; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.support.PatternHelper; import org.apache.camel.util.TimeUtils; import org.apache.camel.util.json.JsonArray; @@ -152,6 +153,11 @@ public class ListProducer extends ProcessWatchCommand { }).collect(Collectors.toList()))); return; } + // Flexible column: URI (90/140) + // Fixed columns: PID(8)+NAME(30)+AGE(8)+ID(20)+STATUS(8)+TYPE(20) ~= 94 + int tw = terminalWidth(); + int uriW = TerminalWidthHelper.flexWidth(tw, 94, TerminalWidthHelper.noBorderOverhead(8), 20, 90); + int uriWideW = TerminalWidthHelper.flexWidth(tw, 94, TerminalWidthHelper.noBorderOverhead(8), 20, 140); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).maxWidth(30, OverflowBehaviour.ELLIPSIS_RIGHT) @@ -163,10 +169,10 @@ public class ListProducer extends ProcessWatchCommand { new Column().header("TYPE").dataAlign(HorizontalAlign.LEFT).maxWidth(20, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getType), new Column().header("URI").visible(!wideUri).dataAlign(HorizontalAlign.LEFT) - .maxWidth(90, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(uriW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getUri), new Column().header("URI").visible(wideUri).dataAlign(HorizontalAlign.LEFT) - .maxWidth(140, OverflowBehaviour.NEWLINE) + .maxWidth(uriWideW, OverflowBehaviour.NEWLINE) .with(this::getUri)))); } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProperties.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProperties.java index c2130dd622a6..d22c4067f0fc 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProperties.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProperties.java @@ -28,6 +28,7 @@ import com.github.freva.asciitable.HorizontalAlign; import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.util.SensitiveUtils; import org.apache.camel.util.StringHelper; import org.apache.camel.util.json.JsonArray; @@ -148,25 +149,35 @@ public class ListProperties extends ProcessWatchCommand { return jo; }).collect(Collectors.toList()))); } else { + // Flexible columns: LOCATION (80), KEY (50), VALUE (80), FUNCTION (50), ORIGINAL VALUE (80) + // Fixed columns: PID(8)+NAME(30) ~= 38 + int tw = terminalWidth(); + int locW = TerminalWidthHelper.flexWidth(tw, 38 + 50 + 80, TerminalWidthHelper.noBorderOverhead(7), 20, 80); + int keyW = TerminalWidthHelper.flexWidth(tw, 38 + 80 + 80, TerminalWidthHelper.noBorderOverhead(7), 15, 50); + int valW = TerminalWidthHelper.flexWidth(tw, 38 + 80 + 50, TerminalWidthHelper.noBorderOverhead(7), 20, 80); + int funcW = TerminalWidthHelper.flexWidth(tw, 38 + 80 + 50 + 80 + 80, TerminalWidthHelper.noBorderOverhead(7), + 15, 50); + int origW = TerminalWidthHelper.flexWidth(tw, 38 + 80 + 50 + 80 + 50, TerminalWidthHelper.noBorderOverhead(7), + 20, 80); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) .maxWidth(30, OverflowBehaviour.ELLIPSIS_RIGHT) .with(r -> r.name), new Column().header("LOCATION").dataAlign(HorizontalAlign.LEFT) - .maxWidth(80, OverflowBehaviour.NEWLINE) + .maxWidth(locW, OverflowBehaviour.NEWLINE) .with(r -> r.loc), new Column().header("KEY").dataAlign(HorizontalAlign.LEFT) - .maxWidth(50, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(keyW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(r -> r.key), new Column().header("VALUE").dataAlign(HorizontalAlign.LEFT) - .maxWidth(80, OverflowBehaviour.NEWLINE) + .maxWidth(valW, OverflowBehaviour.NEWLINE) .with(r -> "" + r.value), new Column().header("FUNCTION").visible(verbose).dataAlign(HorizontalAlign.LEFT) - .maxWidth(50, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(funcW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getFunction), new Column().header("ORIGINAL VALUE").visible(verbose).dataAlign(HorizontalAlign.LEFT) - .maxWidth(80, OverflowBehaviour.NEWLINE) + .maxWidth(origW, OverflowBehaviour.NEWLINE) .with(r -> "" + r.originalValue)))); } } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListRest.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListRest.java index 5c277debad0b..1d22ef3fa39c 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListRest.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListRest.java @@ -30,6 +30,7 @@ import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.PidNameAgeCompletionCandidates; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.util.TimeUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; @@ -117,6 +118,10 @@ public class ListRest extends ProcessWatchCommand { return jo; }).collect(Collectors.toList()))); } else { + // Flexible column: DESCRIPTION (40) + // Fixed columns: PID(8)+NAME(30)+URL(10)+METHOD(6)+FIRST(8)+CONTENT-TYPE(20) ~= 82 + int tw = terminalWidth(); + int descW = TerminalWidthHelper.flexWidth(tw, 82, TerminalWidthHelper.noBorderOverhead(7), 15, 40); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) @@ -125,7 +130,7 @@ public class ListRest extends ProcessWatchCommand { new Column().header("URL").dataAlign(HorizontalAlign.LEFT).with(r -> r.url), new Column().header("METHOD").dataAlign(HorizontalAlign.LEFT).with(r -> r.method), new Column().header("FIRST").visible(verbose).dataAlign(HorizontalAlign.LEFT).with(this::getKind), - new Column().header("DESCRIPTION").visible(verbose).maxWidth(40, OverflowBehaviour.NEWLINE) + new Column().header("DESCRIPTION").visible(verbose).maxWidth(descW, OverflowBehaviour.NEWLINE) .dataAlign(HorizontalAlign.LEFT).with(r -> r.description), new Column().header("CONTENT-TYPE").dataAlign(HorizontalAlign.LEFT).with(this::getContent)))); } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListService.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListService.java index 4a70bed96302..a5c45a4d4f15 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListService.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListService.java @@ -29,6 +29,7 @@ import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.PidNameAgeCompletionCandidates; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.util.TimeUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; @@ -129,6 +130,11 @@ public class ListService extends ProcessWatchCommand { return jo; }).collect(Collectors.toList()))); } else { + // Flexible column: ENDPOINT (90/140) + // Fixed columns: PID(8)+NAME(30)+COMPONENT(10)+DIR(3)+ROUTE(8)+PROTOCOL(8)+SERVICE(10)+METADATA(10)+TOTAL(5) ~= 92 + int tw = terminalWidth(); + int epW = TerminalWidthHelper.flexWidth(tw, 92, TerminalWidthHelper.noBorderOverhead(11), 20, 90); + int epWideW = TerminalWidthHelper.flexWidth(tw, 92, TerminalWidthHelper.noBorderOverhead(11), 20, 140); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) @@ -143,10 +149,10 @@ public class ListService extends ProcessWatchCommand { .with(this::getMetadata), new Column().header("TOTAL").dataAlign(HorizontalAlign.RIGHT).with(r -> "" + r.hits), new Column().header("ENDPOINT").visible(!wideUri).dataAlign(HorizontalAlign.LEFT) - .maxWidth(90, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(epW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getUri), new Column().header("ENDPOINT").visible(wideUri).dataAlign(HorizontalAlign.LEFT) - .maxWidth(140, OverflowBehaviour.NEWLINE) + .maxWidth(epWideW, OverflowBehaviour.NEWLINE) .with(this::getUri)))); } } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVariable.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVariable.java index 5efda04fe33b..b3ba18e420ae 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVariable.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVariable.java @@ -28,6 +28,7 @@ import com.github.freva.asciitable.HorizontalAlign; import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; import org.apache.camel.util.json.Jsoner; @@ -118,6 +119,12 @@ public class ListVariable extends ProcessWatchCommand { return jo; }).collect(Collectors.toList()))); } else { + // Flexible columns: TYPE (40), KEY (50), VALUE (80) + // Fixed columns: PID(8)+NAME(30)+REPO(8) ~= 46 + int tw = terminalWidth(); + int typeW = TerminalWidthHelper.flexWidth(tw, 46 + 50 + 80, TerminalWidthHelper.noBorderOverhead(6), 15, 40); + int keyW = TerminalWidthHelper.flexWidth(tw, 46 + 40 + 80, TerminalWidthHelper.noBorderOverhead(6), 15, 50); + int valW = TerminalWidthHelper.flexWidth(tw, 46 + 40 + 50, TerminalWidthHelper.noBorderOverhead(6), 20, 80); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) @@ -125,11 +132,12 @@ public class ListVariable extends ProcessWatchCommand { .with(r -> r.name), new Column().header("REPO").headerAlign(HorizontalAlign.CENTER).with(r -> r.id), new Column().header("TYPE").headerAlign(HorizontalAlign.CENTER) - .maxWidth(40, OverflowBehaviour.ELLIPSIS_LEFT).with(r -> r.type), + .maxWidth(typeW, OverflowBehaviour.ELLIPSIS_LEFT).with(r -> r.type), new Column().header("KEY").dataAlign(HorizontalAlign.LEFT) - .maxWidth(50, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(keyW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(r -> r.key), - new Column().header("VALUE").headerAlign(HorizontalAlign.RIGHT).maxWidth(80, OverflowBehaviour.NEWLINE) + new Column().header("VALUE").headerAlign(HorizontalAlign.RIGHT) + .maxWidth(valW, OverflowBehaviour.NEWLINE) .with(this::getValue)))); } } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVault.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVault.java index 8acb4a6ba2b6..02f7285cd567 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVault.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVault.java @@ -28,6 +28,7 @@ import com.github.freva.asciitable.HorizontalAlign; import com.github.freva.asciitable.OverflowBehaviour; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.ProcessHelper; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.util.TimeUtils; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; @@ -203,15 +204,20 @@ public class ListVault extends ProcessWatchCommand { return jo; }).collect(Collectors.toList()))); } else { + // Flexible columns: NAME (40), SECRET (40) + // Fixed columns: PID(8)+VAULT(10)+REGION(10)+AGE(8)+UPDATE(8)+CHECK(8) ~= 52 + int tw = terminalWidth(); + int nameW = TerminalWidthHelper.flexWidth(tw, 52 + 40, TerminalWidthHelper.noBorderOverhead(8), 15, 40); + int secretW = TerminalWidthHelper.flexWidth(tw, 52 + nameW, TerminalWidthHelper.noBorderOverhead(8), 15, 40); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("NAME").dataAlign(HorizontalAlign.LEFT) - .maxWidth(40, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(nameW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(r -> r.name), new Column().header("VAULT").dataAlign(HorizontalAlign.LEFT).with(r -> r.vault), new Column().header("REGION").dataAlign(HorizontalAlign.LEFT).with(r -> r.region), new Column().header("SECRET").dataAlign(HorizontalAlign.LEFT) - .maxWidth(40, OverflowBehaviour.ELLIPSIS_RIGHT) + .maxWidth(secretW, OverflowBehaviour.ELLIPSIS_RIGHT) .with(r -> r.secret), new Column().header("AGE").headerAlign(HorizontalAlign.CENTER).with(this::getAgo), new Column().header("UPDATE").headerAlign(HorizontalAlign.LEFT).with(this::getReloadAgo), diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/update/UpdateList.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/update/UpdateList.java index ccbc6470c144..70fa469ea396 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/update/UpdateList.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/update/UpdateList.java @@ -38,6 +38,7 @@ import com.github.freva.asciitable.HorizontalAlign; import org.apache.camel.dsl.jbang.core.commands.CamelCommand; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.RuntimeType; +import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; import org.apache.camel.dsl.jbang.core.common.VersionHelper; import org.apache.camel.dsl.jbang.core.model.UpdateListDTO; import org.apache.camel.main.download.MavenDependencyDownloader; @@ -179,6 +180,12 @@ public class UpdateList extends CamelCommand { .map(UpdateListDTO::toMap) .collect(Collectors.toList()))); } else { + int tw = terminalWidth(); + // Fixed columns: VERSION (10), RUNTIME (~18), RUNTIME VERSION (~17) + int fixedWidth = 10 + 18 + 17; + int descWidth = TerminalWidthHelper.flexWidth( + tw, fixedWidth, TerminalWidthHelper.noBorderOverhead(4), + 20, 80); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("VERSION").minWidth(10).dataAlign(HorizontalAlign.LEFT) .with(r -> r.version().toString()), @@ -186,7 +193,7 @@ public class UpdateList extends CamelCommand { .dataAlign(HorizontalAlign.LEFT).with(r -> r.runtime()), new Column().header("RUNTIME VERSION") .dataAlign(HorizontalAlign.LEFT).with(r -> r.runtimeVersion()), - new Column().header("DESCRIPTION") + new Column().header("DESCRIPTION").maxWidth(descWidth) .dataAlign(HorizontalAlign.LEFT).with(r -> r.description())))); } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/TerminalWidthHelper.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/TerminalWidthHelper.java new file mode 100644 index 000000000000..dd723f38390e --- /dev/null +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/TerminalWidthHelper.java @@ -0,0 +1,114 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.dsl.jbang.core.common; + +import org.jline.terminal.Terminal; +import org.jline.terminal.TerminalBuilder; + +/** + * Helper for detecting the terminal width to adapt table and command output. + * + * <p> + * Uses JLine to query the actual terminal size. Falls back to a default width when the terminal size cannot be + * determined (e.g., when output is piped or redirected). + */ +public final class TerminalWidthHelper { + + private static final int DEFAULT_WIDTH = 120; + private static final int MIN_WIDTH = 40; + + private TerminalWidthHelper() { + } + + /** + * Returns the current terminal width in columns. + * + * <p> + * Attempts to detect the terminal width using JLine. Returns {@value #DEFAULT_WIDTH} if detection fails or if the + * output is not connected to a terminal. + */ + public static int getTerminalWidth() { + try (Terminal terminal = TerminalBuilder.builder() + .system(true) + .dumb(true) + .build()) { + int width = terminal.getWidth(); + if (width > 0) { + return Math.max(width, MIN_WIDTH); + } + } catch (Exception e) { + // ignore + } + return DEFAULT_WIDTH; + } + + /** + * Computes the available width for a flexible column (e.g., DESCRIPTION), given the total terminal width, the sum + * of other fixed column widths, and the border overhead. + * + * @param terminalWidth total terminal width in columns + * @param fixedColumnsWidth sum of max widths of all other (non-flexible) columns + * @param borderOverhead overhead from table borders and padding (use {@link #noBorderOverhead(int)} or + * {@link #fancyBorderOverhead(int)}) + * @param minFlexWidth minimum width for the flexible column + * @param maxFlexWidth maximum width for the flexible column (used when terminal is wide) + * @return the computed width for the flexible column + */ + public static int flexWidth( + int terminalWidth, int fixedColumnsWidth, int borderOverhead, + int minFlexWidth, int maxFlexWidth) { + int available = terminalWidth - fixedColumnsWidth - borderOverhead; + return Math.max(minFlexWidth, Math.min(maxFlexWidth, available)); + } + + /** + * Scales a column width proportionally based on available terminal width. All columns with the given preferred + * widths are scaled proportionally to fit within the terminal. + * + * @param terminalWidth total terminal width in columns + * @param borderOverhead overhead from table borders and padding + * @param preferred the preferred (maximum) width for this column + * @param minWidth the minimum width for this column + * @param allPreferred the sum of all columns' preferred widths + * @return the scaled width for this column + */ + public static int scaleWidth( + int terminalWidth, int borderOverhead, + int preferred, int minWidth, int allPreferred) { + int available = terminalWidth - borderOverhead; + if (available >= allPreferred) { + return preferred; + } + int scaled = available * preferred / allPreferred; + return Math.max(minWidth, Math.min(preferred, scaled)); + } + + /** + * Border overhead for NO_BORDERS tables: 2 spaces between each column pair. + */ + public static int noBorderOverhead(int columnCount) { + return (columnCount - 1) * 2; + } + + /** + * Border overhead for FANCY_ASCII tables: | col1 | col2 | ... | colN | + */ + public static int fancyBorderOverhead(int columnCount) { + // 1 left border + 1 right border + (columnCount * 2 padding) + (columnCount - 1) separators + return 2 + columnCount * 2 + (columnCount - 1); + } +}
