int (@NotNull Document document, @Nullable Project project, int startOffset, int endOffset, int maxPreferredOffset, boolean allowToBeyondMaxPreferredOffset, boolean isSoftWrap) { if (endOffset <= startOffset) { return endOffset; } myOffset2weight.clear(); myOffset2weight.anchor = startOffset; CharSequence text = document.getCharsSequence(); // Normalization. int maxPreferredOffsetToUse = maxPreferredOffset >= endOffset ? endOffset - 1 : maxPreferredOffset; maxPreferredOffsetToUse = Math.max(maxPreferredOffsetToUse, startOffset); // Try to find out wrap position before preferred offset. for (int i = Math.min(maxPreferredOffsetToUse, text.length() - 1); i > startOffset; i--) { char c = text.charAt(i); if (c == '\n') { return i + 1; } if (!canUseOffset(document, i, isSoftWrap)) { continue; } Rule rule = myRules.get(c); if (rule != null) { if (rule.condition == WrapCondition.BOTH || rule.condition == WrapCondition.AFTER) { int target = i+1; if (rule.symbol != ' ') { while(target < maxPreferredOffsetToUse && text.charAt(target) == ' ') { target++; } } if (target <= maxPreferredOffsetToUse) { myOffset2weight.store(target, rule.weight); } } if (rule.condition == WrapCondition.BOTH || rule.condition == WrapCondition.BEFORE) { myOffset2weight.store(i, rule.weight); } continue; } // Don't wrap on a non-id symbol followed by non-id symbol, e.g. don't wrap between two pluses at i++. // Also don't wrap before non-id symbol preceded by a space - wrap on space instead; if (!isIdSymbol(c) && i > startOffset + 1 && isIdSymbol(text.charAt(i - 1)) && !myRules.containsKey(text.charAt(i - 1))) { myOffset2weight.store(i, NON_ID_WEIGHT); } } int result = chooseOffset(); if (result > 0) { return result; } if (!allowToBeyondMaxPreferredOffset) { return -1; } // Try to find target offset that is beyond preferred offset. // Note that we don't consider symbol weights here and just break on the first appropriate position. for (int i = Math.min(maxPreferredOffsetToUse + 1, text.length() - 1); i < endOffset; i++) { char c = text.charAt(i); if (c == '\n') { return i + 1; } if (!canUseOffset(document, i, isSoftWrap)) { continue; } Rule rule = myRules.get(c); if (rule != null) { switch (rule.condition) { case BOTH, BEFORE -> { return i; } case AFTER -> { if (i < endOffset - 1) return i + 1; } } } // Don't wrap on a non-id symbol followed by non-id symbol, e.g. don't wrap between two pluses at i++; if (!isIdSymbol(c) && i < endOffset - 1 && isIdSymbol(text.charAt(i + 1))) { return i; } } return -1; }