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 1ed86e4d4..93e29db37 100644 --- a/src/main/java/noppes/npcs/client/gui/util/GuiScriptTextArea.java +++ b/src/main/java/noppes/npcs/client/gui/util/GuiScriptTextArea.java @@ -129,6 +129,9 @@ public class GuiScriptTextArea extends GuiNpcTextField { // ==================== SEARCH/REPLACE ==================== public static final SearchReplaceBar searchBar = new SearchReplaceBar(); + + // ==================== PASTE SETTINGS ==================== + private static final int PASTE_TRAILING_WS_TRIM_THRESHOLD = 16; // ==================== GO TO LINE ==================== private final GoToLineDialog goToLineDialog = new GoToLineDialog(); @@ -1311,9 +1314,12 @@ public class GuiScriptTextArea extends GuiNpcTextField { if (!e.isPress() || !isActive.get()) return; - String clipboard = NoppesStringUtils.getClipboardContents(); - if (clipboard == null) - clipboard = ""; + String clipboardRaw = NoppesStringUtils.getClipboardContents(); + if (clipboardRaw == null) + clipboardRaw = ""; + + boolean isLinePaste = lastCopyWasLine && lastCopiedLineText != null && clipboardRaw.equals(lastCopiedLineText); + String clipboard = FormatHelper.sanitizeClipboard(clipboardRaw, PASTE_TRAILING_WS_TRIM_THRESHOLD); if (selection.hasSelection()) { addText(clipboard); @@ -1323,7 +1329,6 @@ public class GuiScriptTextArea extends GuiNpcTextField { return; } - boolean isLinePaste = lastCopyWasLine && lastCopiedLineText != null && clipboard.equals(lastCopiedLineText); if (isLinePaste && container != null && container.lines != null) { LineData currentLine = selection.findCurrentLine(container.lines); if (currentLine != null) { diff --git a/src/main/java/noppes/npcs/client/gui/util/script/FormatHelper.java b/src/main/java/noppes/npcs/client/gui/util/script/FormatHelper.java index c2eb5592a..cf95e9026 100644 --- a/src/main/java/noppes/npcs/client/gui/util/script/FormatHelper.java +++ b/src/main/java/noppes/npcs/client/gui/util/script/FormatHelper.java @@ -894,6 +894,63 @@ public class FormatHelper { return new FormatHelper(settings).format(code); } + /** + * Sanitize clipboard text for paste into the script editor. + *

+ * This is a paste-only cleanup intended to prevent large trailing + * whitespace runs from causing misleading soft-wrap splits in the editor. + *

+ * Processing: + *

+ * The threshold avoids clobbering intentional minor trailing spaces while still + * removing the large padding blocks that confuse soft-wrap layout. + * + * @param clipboard the raw clipboard text (may be {@code null} or empty) + * @param trimThreshold minimum trailing whitespace run length to trigger trimming; + * runs shorter than this are left intact + * @return sanitized text, or the original reference if {@code null}/empty + */ + public static String sanitizeClipboard(String clipboard, int trimThreshold) { + if (clipboard == null || clipboard.isEmpty()) { + return clipboard; + } + + // Normalize line separators: \r\n -> \n, then bare \r -> \n + String normalized = clipboard.replace("\r\n", "\n").replace("\r", "\n"); + + String[] lines = normalized.split("\n", -1); + StringBuilder result = new StringBuilder(normalized.length()); + + for (int i = 0; i < lines.length; i++) { + String line = lines[i]; + + // Measure trailing whitespace run length + int end = line.length(); + while (end > 0 && (line.charAt(end - 1) == ' ' || line.charAt(end - 1) == '\t')) { + end--; + } + int trailingLen = line.length() - end; + + if (trailingLen >= trimThreshold) { + result.append(line, 0, end); + } else { + result.append(line); + } + + if (i < lines.length - 1) { + result.append('\n'); + } + } + + return result.toString(); + } + // ==================== LINE WRAPPING ==================== /**