From b38f193d082a1c6d52372a7a56c6545170a2dddf Mon Sep 17 00:00:00 2001 From: bigguy345 Date: Thu, 25 Dec 2025 11:35:39 +0200 Subject: [PATCH] Improved CTRL + Left/Right logic --- .../client/gui/util/GuiScriptTextArea.java | 49 ++++++++++--------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/src/main/java/noppes/npcs/client/gui/util/GuiScriptTextArea.java b/src/main/java/noppes/npcs/client/gui/util/GuiScriptTextArea.java index 18ab07b84..34b49d075 100644 --- a/src/main/java/noppes/npcs/client/gui/util/GuiScriptTextArea.java +++ b/src/main/java/noppes/npcs/client/gui/util/GuiScriptTextArea.java @@ -1249,16 +1249,21 @@ public class GuiScriptTextArea extends GuiNpcTextField { if (i == Keyboard.KEY_LEFT) { int j = 1; // default: move one character if (isCtrlKeyDown()) { - // When Ctrl is down, compute distance to previous word boundary. - // We match words in the text slice before the cursor and pick - // the last match start as the new boundary. - Matcher m = container.regexWord.matcher(text.substring(0, selection.getCursorPosition())); - while (m.find()) { - if (m.start() == m.end()) - continue; // skip empty matches - // j becomes the number of chars to move left to reach word start - j = selection.getCursorPosition() - m.start(); + int pos = selection.getCursorPosition(); + int g = pos; + java.util.function.IntPredicate isWordChar = ch -> Character.isLetterOrDigit(ch) || ch == '_'; + + if (pos > 0) { + char left = text.charAt(pos - 1); + if (Character.isWhitespace(left)) { + while (g - 1 >= 0 && Character.isWhitespace(text.charAt(g - 1))) g--; + } else if (isWordChar.test(left)) { + while (g - 1 >= 0 && isWordChar.test(text.charAt(g - 1))) g--; + } else { + while (g - 1 >= 0 && !Character.isWhitespace(text.charAt(g - 1)) && !isWordChar.test(text.charAt(g - 1))) g--; + } } + j = Math.max(1, pos - g); } int newPos = Math.max(selection.getCursorPosition() - j, 0); // If Shift is held, extend selection; otherwise place caret. @@ -1270,23 +1275,21 @@ public class GuiScriptTextArea extends GuiNpcTextField { if (i == Keyboard.KEY_RIGHT) { int j = 1; // default: move one character if (isCtrlKeyDown()) { - String after = text.substring(selection.getCursorPosition()); - Matcher m = container.regexWord.matcher(after); - if (m.find()) { - if (m.start() == 0) { - // If the first match starts at 0 (cursor at word start), - // try to find the next match so we advance past the current word. - if (m.find()) - j = m.start(); - else - j = Math.max(1, after.length()); + int pos = selection.getCursorPosition(); + int end = pos; + java.util.function.IntPredicate isWordChar = ch -> Character.isLetterOrDigit(ch) || ch == '_'; + + if (pos < text.length()) { + char first = text.charAt(pos); + if (Character.isWhitespace(first)) { + while (end < text.length() && Character.isWhitespace(text.charAt(end))) end++; + } else if (isWordChar.test(first)) { + while (end < text.length() && isWordChar.test(text.charAt(end))) end++; } else { - j = m.start(); + while (end < text.length() && !Character.isWhitespace(text.charAt(end)) && !isWordChar.test(text.charAt(end))) end++; } - } else { - // No word match found after cursor -> jump to end - j = Math.max(1, after.length()); } + j = Math.max(1, end - pos); } int newPos = Math.min(selection.getCursorPosition() + j, text.length()); setCursor(newPos, GuiScreen.isShiftKeyDown());