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

davsclaus pushed a commit to branch feature/CAMEL-24372-tui-yaml-editor
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 54f6329b53544e06e6aaf3d6ef15c957013e33bd
Author: Cursor Agent <[email protected]>
AuthorDate: Sat Aug 8 03:28:13 2026 +0000

    CAMEL-24372: Fix edit-mode key bindings and find-in-edit behavior
    
    Use isKey(KeyCode.*) with modifiers for Alt/Ctrl chords (tamboui only
    matches unmodified keys on isUp/isLeft/isDelete*). Align find n/N with
    view mode, jump to nearest match on confirm, clear find on Esc, route
    paste to find input, and fix moveBlockUp cursor placement.
    
    Co-authored-by: Omar Atie <[email protected]>
---
 .../jbang/core/commands/tui/SearchHighlighter.java | 12 +++++-----
 .../dsl/jbang/core/commands/tui/SourceViewer.java  | 27 ++++++++++++++--------
 .../jbang/core/commands/tui/YamlBlockEditor.java   |  6 ++++-
 .../commands/tui/SourceViewerEditorOpsTest.java    | 17 +++++++++++---
 4 files changed, 42 insertions(+), 20 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 b23e95e273d1..c40adefada92 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
@@ -333,16 +333,16 @@ class SearchHighlighter {
         if (findInputActive || highlightInputActive) {
             return handleSearchInput(ke);
         }
-        if (ke.hasCtrl() && ke.isChar('f')) {
+        if (ke.hasCtrl() && ke.isCharIgnoreCase('f')) {
             openFindInput();
             return true;
         }
         if (findTerm != null && ke.isChar('n') && !ke.hasCtrl() && 
!ke.hasAlt()) {
-            if (ke.hasShift()) {
-                navigateToPrevMatch();
-            } else {
-                navigateToNextMatch();
-            }
+            navigateToNextMatch();
+            return true;
+        }
+        if (findTerm != null && ke.isChar('N') && !ke.hasCtrl() && 
!ke.hasAlt()) {
+            navigateToPrevMatch();
             return true;
         }
         return false;
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java
index efbc6066c622..c73b30fdc531 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java
@@ -547,7 +547,7 @@ class SourceViewer {
     }
 
     private void jumpEditToCurrentFindMatch() {
-        int line = search.currentMatchLine();
+        int line = search.jumpToNearestMatch(editState.cursorRow());
         if (line >= 0) {
             SourceEditHistory.positionCursor(editState, line, 0);
         }
@@ -592,14 +592,14 @@ class SourceViewer {
             }
             return true;
         }
-        if (ke.hasCtrl() && ke.isChar('z') && !ke.hasShift()) {
+        if (ke.hasCtrl() && ke.isCharIgnoreCase('z') && !ke.hasShift()) {
             if (editHistory.undo(editState)) {
                 dirty = true;
                 refreshEditFindMatches();
             }
             return true;
         }
-        if (ke.hasCtrl() && (ke.isChar('y') || (ke.isChar('z') && 
ke.hasShift()))) {
+        if (ke.hasCtrl() && (ke.isCharIgnoreCase('y') || 
(ke.isCharIgnoreCase('z') && ke.hasShift()))) {
             if (editHistory.redo(editState)) {
                 dirty = true;
                 refreshEditFindMatches();
@@ -607,15 +607,15 @@ class SourceViewer {
             return true;
         }
         boolean yamlListBlocks = isCamelYamlFile();
-        if (ke.hasAlt() && ke.isUp() && !ke.hasShift()) {
+        if (ke.isKey(KeyCode.UP) && ke.hasAlt() && !ke.hasShift()) {
             applyBlockEdit(YamlBlockEditor.moveBlockUp(editLines(), 
editState.cursorRow(), yamlListBlocks));
             return true;
         }
-        if (ke.hasAlt() && ke.isDown() && !ke.hasShift()) {
+        if (ke.isKey(KeyCode.DOWN) && ke.hasAlt() && !ke.hasShift()) {
             applyBlockEdit(YamlBlockEditor.moveBlockDown(editLines(), 
editState.cursorRow(), yamlListBlocks));
             return true;
         }
-        if (ke.hasCtrl() && ke.isChar('d') && !ke.hasShift()) {
+        if (ke.hasCtrl() && ke.isCharIgnoreCase('d') && !ke.hasShift()) {
             applyBlockEdit(YamlBlockEditor.duplicateBlock(editLines(), 
editState.cursorRow(), yamlListBlocks));
             return true;
         }
@@ -633,20 +633,20 @@ class SourceViewer {
                     
YamlBlockEditor.leadingSpaces(toggled.get(block.startRow())));
             return true;
         }
-        if (ke.hasCtrl() && ke.isLeft()) {
+        if (ke.isKey(KeyCode.LEFT) && ke.hasCtrl()) {
             SourceEditorNavigation.moveWordLeft(editState);
             return true;
         }
-        if (ke.hasCtrl() && ke.isRight()) {
+        if (ke.isKey(KeyCode.RIGHT) && ke.hasCtrl()) {
             SourceEditorNavigation.moveWordRight(editState);
             return true;
         }
-        if (ke.hasCtrl() && ke.isDeleteBackward()) {
+        if (ke.isKey(KeyCode.BACKSPACE) && ke.hasCtrl()) {
             recordEditChange();
             SourceEditorNavigation.deleteWordBackward(editState);
             return true;
         }
-        if (ke.hasCtrl() && ke.isDeleteForward()) {
+        if (ke.isKey(KeyCode.DELETE) && ke.hasCtrl()) {
             recordEditChange();
             SourceEditorNavigation.deleteWordForward(editState);
             return true;
@@ -661,6 +661,9 @@ class SourceViewer {
             return true;
         }
         if (ke.isCancel()) {
+            if (search.handleEscape()) {
+                return true;
+            }
             if (dirty) {
                 pendingDiscard = true;
                 return true;
@@ -1971,6 +1974,10 @@ class SourceViewer {
 
     void handlePaste(String text) {
         if (editMode) {
+            if (search.isSearchInputActive()) {
+                search.handlePaste(text);
+                return;
+            }
             if (text != null && !text.isEmpty()) {
                 recordEditChange();
                 editState.insert(text);
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/YamlBlockEditor.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/YamlBlockEditor.java
index 425179c66d48..6c31c0f69502 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/YamlBlockEditor.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/YamlBlockEditor.java
@@ -94,7 +94,11 @@ final class YamlBlockEditor {
         if (previous == null || previous.isEmpty()) {
             return null;
         }
-        return swapBlocks(lines, previous, block);
+        EditResult swapped = swapBlocks(lines, previous, block);
+        List<String> answer = swapped.lines();
+        int cursorRow = previous.startRow();
+        int cursorCol = answer.isEmpty() ? 0 : 
YamlBlockEditor.leadingSpaces(answer.get(cursorRow));
+        return new EditResult(answer, cursorRow, cursorCol);
     }
 
     static EditResult moveBlockDown(List<String> lines, int row, boolean 
yamlListBlocks) {
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewerEditorOpsTest.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewerEditorOpsTest.java
index dbfb5a9b5a14..2181378d9174 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewerEditorOpsTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewerEditorOpsTest.java
@@ -22,6 +22,7 @@ import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.List;
 
+import dev.tamboui.tui.event.KeyCode;
 import dev.tamboui.tui.event.KeyEvent;
 import dev.tamboui.tui.event.KeyModifiers;
 import org.junit.jupiter.api.BeforeEach;
@@ -36,6 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 class SourceViewerEditorOpsTest {
 
     private static final KeyModifiers CTRL = KeyModifiers.of(true, false, 
false);
+    private static final KeyModifiers ALT = KeyModifiers.of(false, true, 
false);
     private static final KeyModifiers CTRL_SHIFT = KeyModifiers.of(true, 
false, true);
 
     @TempDir
@@ -130,14 +132,23 @@ class SourceViewerEditorOpsTest {
     }
 
     @Test
-    void ctrlLeftAndRightMoveByWord() {
+    void altDownMovesBlockDown() {
+        moveCursorToLineContaining("log:info");
+
+        viewer.handleKeyEvent(KeyEvent.ofKey(KeyCode.DOWN, KeyModifiers.ALT));
+
+        
assertThat(viewer.editText().indexOf("log:warn")).isLessThan(viewer.editText().indexOf("log:info"));
+    }
+
+    @Test
+    void ctrlLeftAndRightMoveByWordViaKeyBindings() {
         moveCursorToLineContaining("uri:");
         SourceEditHistory.positionCursor(viewer.editState(), 
viewer.editState().cursorRow(), 0);
 
-        SourceEditorNavigation.moveWordRight(viewer.editState());
+        viewer.handleKeyEvent(KeyEvent.ofKey(KeyCode.RIGHT, CTRL));
         assertThat(viewer.editState().cursorCol()).isEqualTo(9);
 
-        SourceEditorNavigation.moveWordLeft(viewer.editState());
+        viewer.handleKeyEvent(KeyEvent.ofKey(KeyCode.LEFT, CTRL));
         assertThat(viewer.editState().cursorCol()).isEqualTo(6);
     }
 

Reply via email to