TextRange (final Project project, final Document document, @NotNull FindModel model, FindResult result, @NotNull String stringToReplace, boolean reallyReplace, List<? super Pair<TextRange, String>> rangesToChange) { final int startOffset = result.getStartOffset(); final int endOffset = result.getEndOffset(); int newOffset; if (reallyReplace) { newOffset = doReplace(project, document, startOffset, endOffset, stringToReplace); } else { final String converted = StringUtil.convertLineSeparators(stringToReplace); TextRange textRange = new TextRange(startOffset, endOffset); rangesToChange.add(Pair.create(textRange, converted)); newOffset = endOffset; } int start = startOffset; int end = newOffset; if (model.isRegularExpressions()) { String toFind = model.getStringToFind(); if (model.isForward()) { if (StringUtil.endsWithChar(toFind, '$')) { int i = 0; int length = toFind.length(); while (i + 2 <= length && toFind.charAt(length - i - 2) == '\\') i++; if (i % 2 == 0) end++; //This $ is a special symbol in regexp syntax } else if (StringUtil.startsWithChar(toFind, '^')) { while (end < document.getTextLength() && document.getCharsSequence().charAt(end) != '\n') end++; } } else { if (StringUtil.startsWithChar(toFind, '^')) { start--; } else if (StringUtil.endsWithChar(toFind, '$')) { while (start >= 0 && document.getCharsSequence().charAt(start) != '\n') start--; } } } return new TextRange(start, end); }