void (Editor editor, PerHintSearchData data, boolean nothingIfFailed, boolean searchBack) { final String prefix = data.label.getText(); int matchLength = prefix.length(); int index; if (matchLength == 0) { index = data.searchStart; } else { final Document document = editor.getDocument(); final CharSequence text = document.getCharsSequence(); final int length = document.getTextLength(); final boolean caseSensitive = detectSmartCaseSensitive(prefix); if (acceptableRegExp(prefix)) { @NonNls final StringBuilder buf = new StringBuilder(prefix.length()); final int len = prefix.length(); for (int i = 0; i < len; ++i) { final char ch = prefix.charAt(i); // bother only * withing text if (ch == '*' && i != 0 && i != len - 1) { buf.append("\\w"); } else if ("{}[].+^$*()?".indexOf(ch) != -1) { // do not bother with other metachars buf.append('\\'); } buf.append(ch); } try { Pattern pattern = Pattern.compile(buf.toString(), caseSensitive ? 0 : Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(text); if (searchBack) { int lastStart = -1; int lastEnd = -1; while (matcher.find() && matcher.start() < data.searchStart) { lastStart = matcher.start(); lastEnd = matcher.end(); } index = lastStart; matchLength = lastEnd - lastStart; } else if (matcher.find(data.searchStart) || !nothingIfFailed && matcher.find(0)) { index = matcher.start(); matchLength = matcher.end() - matcher.start(); } else { index = -1; } } catch (PatternSyntaxException ex) { index = -1; // let the user to make the garbage pattern } } else { StringSearcher searcher = new StringSearcher(prefix, caseSensitive, !searchBack); if (searchBack) { index = searcher.scan(text, 0, data.searchStart); } else { index = searcher.scan(text, data.searchStart, length); index = index < 0 ? -1 : index; } if (index < 0 && !nothingIfFailed) { index = searcher.scan(text); } } } if (nothingIfFailed && index < 0) return; if (data.segmentHighlighter != null) { data.segmentHighlighter.dispose(); data.segmentHighlighter = null; } if (index < 0) { data.label.setForeground(JBColor.RED); } else { data.label.setForeground(JBColor.foreground()); if (matchLength > 0) { data.segmentHighlighter = editor.getMarkupModel() .addRangeHighlighter(EditorColors.SEARCH_RESULT_ATTRIBUTES, index, index + matchLength, HighlighterLayer.LAST + 1, HighlighterTargetArea.EXACT_RANGE); } data.ignoreCaretMove = true; editor.getCaretModel().moveToOffset(index); editor.getSelectionModel().removeSelection(); editor.getScrollingModel().scrollToCaret(ScrollType.CENTER); data.ignoreCaretMove = false; IdeDocumentHistory.getInstance(data.project).includeCurrentCommandAsNavigation(); } }