From 26c27472a31573138ab45814cd12a87cc7d351f3 Mon Sep 17 00:00:00 2001 From: Claus Ibsen Date: Sat, 24 Oct 2026 17:17:20 +0200 Subject: [PATCH] chore: camel-jbang - the routes the Source view lists before a file is opened move to a class of their own SourceTab.java grew to 2007 lines on main, over the 2000 of SourceSizeTest, which fails the build of every PR. Co-Authored-By: Claude Opus 5.5 (1M context) Signed-off-by: Claus Ibsen --- .../core/commands/tui/SourceEmptyLines.java | 83 +++++++++++++++++++ .../jbang/core/commands/tui/SourceTab.java | 51 +----------- .../commands/tui/OpenedProjectViewsTest.java | 4 +- 3 files changed, 86 insertions(+), 52 deletions(-) create mode 100644 dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceEmptyLines.java diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceEmptyLines.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceEmptyLines.java new file mode 100644 index 0000000000000..192d8b7c2ef7e --- /dev/null +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceEmptyLines.java @@ -0,0 +1,83 @@ +/* + * 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.commands.tui; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import dev.tamboui.style.Style; +import dev.tamboui.text.Line; +import dev.tamboui.text.Span; + +/** + * The routes of the project, shown in the Source pane of {@link SourceTab} before a file is opened. + */ +final class SourceEmptyLines { + + private SourceEmptyLines() { + } + + /** + * What the Source pane shows before a file is opened: the routes of the project and where they are, so a Maven + * project (whose routes are folders deep) shows what it holds and how to open one. + */ + static List of(List routes, Path root) { + List lines = new ArrayList<>(); + lines.add(Line.from(Span.raw(""))); + if (routes.isEmpty()) { + lines.add(Line.from(Span.styled(" Select a file and press Enter to view source", Style.EMPTY.dim()))); + return lines; + } + lines.add(Line.from(Span.styled(" " + routes.size() + (routes.size() == 1 ? " route" : " routes") + + " in this project", + Theme.label()))); + lines.add(Line.from(Span.raw(""))); + int idWidth = 4; + for (SourceTab.RouteEntry re : routes) { + idWidth = Math.max(idWidth, label(re).length()); + } + idWidth = Math.min(idWidth, 30); + for (SourceTab.RouteEntry re : routes) { + String where = re.filePath(); + if (root != null && where != null) { + try { + where = root.relativize(Path.of(where)).toString(); + } catch (IllegalArgumentException e) { + // not under the project: keep the full path + } + } + lines.add(Line.from( + Span.styled(" " + String.format("%-" + idWidth + "s", TuiHelper.truncate(label(re), idWidth)), + Theme.info()), + Span.styled(" " + where + ":" + re.fromLine(), Style.EMPTY.dim()))); + } + lines.add(Line.from(Span.raw(""))); + lines.add(Line.from( + Span.styled(" ", Style.EMPTY), + Span.styled(" g ", Theme.hintKey()), + Span.styled(" opens a route, or select a file and press Enter", Style.EMPTY.dim()))); + return lines; + } + + private static String label(SourceTab.RouteEntry re) { + if (re.routeId() != null && !re.routeId().isBlank()) { + return re.routeId(); + } + return re.fromUri() != null ? re.fromUri() : ""; + } +} diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceTab.java index 1031a67a5b69d..af9f5b566109f 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceTab.java @@ -1145,55 +1145,6 @@ private void renderInfoPanel(Frame frame, Rect area) { area); } - /** - * What the Source pane shows before a file is opened: the routes of the project and where they are, so a Maven - * project (whose routes are folders deep) shows what it holds and how to open one. - */ - static List emptySourceLines(List routes, Path root) { - List lines = new ArrayList<>(); - lines.add(Line.from(Span.raw(""))); - if (routes.isEmpty()) { - lines.add(Line.from(Span.styled(" Select a file and press Enter to view source", Style.EMPTY.dim()))); - return lines; - } - lines.add(Line.from(Span.styled(" " + routes.size() + (routes.size() == 1 ? " route" : " routes") - + " in this project", - Theme.label()))); - lines.add(Line.from(Span.raw(""))); - int idWidth = 4; - for (RouteEntry re : routes) { - idWidth = Math.max(idWidth, label(re).length()); - } - idWidth = Math.min(idWidth, 30); - for (RouteEntry re : routes) { - String where = re.filePath(); - if (root != null && where != null) { - try { - where = root.relativize(Path.of(where)).toString(); - } catch (IllegalArgumentException e) { - // not under the project: keep the full path - } - } - lines.add(Line.from( - Span.styled(" " + String.format("%-" + idWidth + "s", TuiHelper.truncate(label(re), idWidth)), - Theme.info()), - Span.styled(" " + where + ":" + re.fromLine(), Style.EMPTY.dim()))); - } - lines.add(Line.from(Span.raw(""))); - lines.add(Line.from( - Span.styled(" ", Style.EMPTY), - Span.styled(" g ", Theme.hintKey()), - Span.styled(" opens a route, or select a file and press Enter", Style.EMPTY.dim()))); - return lines; - } - - private static String label(RouteEntry re) { - if (re.routeId() != null && !re.routeId().isBlank()) { - return re.routeId(); - } - return re.fromUri() != null ? re.fromUri() : ""; - } - // the Route Tree setting last given to the editor: it is given again only when it changes, so Ctrl+T holds private Boolean routeTreeDefault; @@ -1217,7 +1168,7 @@ private void renderSourcePanel(Frame frame, Rect area) { runState.render(frame, area); } else { runState.shown(null, false); - List lines = emptySourceLines(routeIndex, rootDir); + List lines = SourceEmptyLines.of(routeIndex, rootDir); frame.renderWidget( Paragraph.builder() diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/OpenedProjectViewsTest.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/OpenedProjectViewsTest.java index 7bfa9cf9fac64..27735d32af5f8 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/OpenedProjectViewsTest.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/OpenedProjectViewsTest.java @@ -47,7 +47,7 @@ void theSourcePaneListsTheRoutesOfTheProject() { "src/main/java/org/acme/TimerRoute.java").toString(), 27)); - List text = text(SourceTab.emptySourceLines(routes, dir)); + List text = text(SourceEmptyLines.of(routes, dir)); assertThat(text).anyMatch(l -> l.contains("2 routes in this project")); assertThat(text).anyMatch(l -> l.contains("yaml-route") && l.contains("src/main/resources/camel/my-routes.yaml:20")); // a route without an id by its endpoint @@ -57,7 +57,7 @@ void theSourcePaneListsTheRoutesOfTheProject() { @Test void withoutRoutesTheHintStays() { - assertThat(text(SourceTab.emptySourceLines(List.of(), dir))) + assertThat(text(SourceEmptyLines.of(List.of(), dir))) .anyMatch(l -> l.contains("Select a file and press Enter")); }