From e53550eb32ba8c792e2b3d2a402af96c3b392382 Mon Sep 17 00:00:00 2001 From: Jarrio Date: Thu, 28 Aug 2025 18:18:56 +0100 Subject: [PATCH 1/2] add word boundary apis --- runtime/src/ceramic/SelectText.hx | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/runtime/src/ceramic/SelectText.hx b/runtime/src/ceramic/SelectText.hx index ce34d065b..292e64db8 100644 --- a/runtime/src/ceramic/SelectText.hx +++ b/runtime/src/ceramic/SelectText.hx @@ -147,6 +147,49 @@ class SelectText extends Entity implements Component implements Observable { } +/// Public apis + + public function findPreviousWordBoundary(fromPos:Int) { + var content = entity.content; + + if (fromPos <= 0) { + return 0; + } + + var leftPart = content.substring(0, fromPos); + var wordBoundaryRegex = ~/(\S+)\s*$/; + + if (wordBoundaryRegex.match(leftPart)) { + return wordBoundaryRegex.matchedPos().pos; + } + + return 0; + } + + public function findNextWordBoundary(fromPos:Int) { + var content = entity.content; + var contentLength = content.length; + + if (fromPos >= contentLength) { + return contentLength; + } + + var rightPart = content.substring(fromPos); + var nextWordRegex = ~/^\S*\s*(\S|$)/; + + if (nextWordRegex.match(rightPart)) { + var matchInfo = nextWordRegex.matchedPos(); + var pos = fromPos + matchInfo.pos + matchInfo.len - 1; + + if (pos > contentLength || rightPart.charAt(matchInfo.pos + matchInfo.len - 1) == '') { + pos = contentLength; + } + return pos; + } + + return contentLength; + } + function bindAsComponent() { entity.onGlyphQuadsChange(this, updateSelectionGraphics); From 3bbe3156aaa27d39a855a52c067c1478a82c1ba7 Mon Sep 17 00:00:00 2001 From: Jarrio Date: Thu, 28 Aug 2025 18:21:46 +0100 Subject: [PATCH 2/2] Add cursor navigation between words --- runtime/src/ceramic/EditText.hx | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/runtime/src/ceramic/EditText.hx b/runtime/src/ceramic/EditText.hx index 57337c3cc..28d157723 100644 --- a/runtime/src/ceramic/EditText.hx +++ b/runtime/src/ceramic/EditText.hx @@ -601,6 +601,28 @@ class EditText extends Entity implements Component implements TextInputDelegate emitUpdate(newText); }); + keyBindings.bind([CMD_OR_CTRL, KEY(KeyCode.LEFT)], function() { + // CMD/CTRL + LEFT Arrow Key + if (screen.focusedVisual != entity) + return; + + var pos = selectText.findPreviousWordBoundary(selectText.selectionStart); + + selectText.selectionStart = pos; + selectText.selectionEnd = pos; + }); + + keyBindings.bind([CMD_OR_CTRL, KEY(KeyCode.RIGHT)], function() { + // CMD/CTRL + RIGHT Arrow Key + if (screen.focusedVisual != entity) + return; + + var pos = selectText.findNextWordBoundary(selectText.selectionStart); + + selectText.selectionStart = pos; + selectText.selectionEnd = pos; + }); + onDestroy(keyBindings, function(_) { keyBindings.destroy(); keyBindings = null;