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

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git

commit e51e314e88cffaa5669a814c49691faeef2d02ba
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Jul 10 16:37:57 2026 +0200

    TUI: Fix search + highlight rendering corruption in SearchHighlighter
    
    Sort highlight and find ranges by start position before emitting spans,
    and clamp overlapping ranges to the running cursor to prevent backwards
    cursor movement and duplicated text when both patterns match on the
    same line.
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../jbang/core/commands/tui/SearchHighlighter.java  | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SearchHighlighter.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SearchHighlighter.java
index 29419447cffd..9bdae7aa3b97 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SearchHighlighter.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SearchHighlighter.java
@@ -214,6 +214,13 @@ class SearchHighlighter {
             return line;
         }
 
+        // sort ranges by start position so the emit loop can assume ascending 
order
+        Integer[] order = new Integer[ranges.size()];
+        for (int i = 0; i < order.length; i++) {
+            order[i] = i;
+        }
+        java.util.Arrays.sort(order, (a, b) -> 
Integer.compare(ranges.get(a)[0], ranges.get(b)[0]));
+
         List<Span> original = line.spans();
         List<Span> result = new ArrayList<>();
         int charPos = 0;
@@ -223,18 +230,24 @@ class SearchHighlighter {
             int spanStart = charPos;
             int spanEnd = charPos + content.length();
             int cursor = 0;
-            for (int r = 0; r < ranges.size(); r++) {
-                int matchStart = ranges.get(r)[0];
-                int matchEnd = ranges.get(r)[1];
+            for (int idx : order) {
+                int matchStart = ranges.get(idx)[0];
+                int matchEnd = ranges.get(idx)[1];
                 if (matchEnd <= spanStart || matchStart >= spanEnd) {
                     continue;
                 }
                 int localStart = Math.max(0, matchStart - spanStart);
                 int localEnd = Math.min(content.length(), matchEnd - 
spanStart);
+                if (localStart < cursor) {
+                    localStart = cursor;
+                }
+                if (localStart >= localEnd) {
+                    continue;
+                }
                 if (localStart > cursor) {
                     result.add(Span.styled(content.substring(cursor, 
localStart), baseStyle));
                 }
-                result.add(Span.styled(content.substring(localStart, 
localEnd), rangeStyles.get(r)));
+                result.add(Span.styled(content.substring(localStart, 
localEnd), rangeStyles.get(idx)));
                 cursor = localEnd;
             }
             if (cursor < content.length()) {

Reply via email to