@Nullable("null means the file is clean") public static TextRange getDirtyTextRange(@NotNull Editor editor, int passId) { Document document = editor.getDocument(); FileStatusMap me = DaemonCodeAnalyzerEx.getInstanceEx(editor.getProject()).getFileStatusMap(); TextRange dirtyScope = me.getFileDirtyScope(document, passId); if (dirtyScope == null) return null; TextRange documentRange = TextRange.from(0, document.getTextLength()); return documentRange.intersection(dirtyScope); }
private boolean isWhiteSpaceOrComment(@NotNull PsiElement element, @NotNull TextRange range) { final TextRange textRange = element.getTextRange(); TextRange intersection = range.intersection(textRange); if (intersection == null) { return false; } intersection = TextRange.create( Math.max(intersection.getStartOffset() - textRange.getStartOffset(), 0), Math.min( intersection.getEndOffset() - textRange.getStartOffset(), textRange.getLength())); return isWhiteSpaceOrComment(element) || intersection.substring(element.getText()).trim().length() == 0; }
/** * intersection may spread over several injected fragments * * @param rangeToEdit range in encoded(raw) PSI * @return list of ranges in encoded (raw) PSI */ @Override @SuppressWarnings({"ConstantConditions", "unchecked"}) @NotNull public List<TextRange> intersectWithAllEditableFragments( @NotNull PsiFile injectedPsi, @NotNull TextRange rangeToEdit) { Place shreds = InjectedLanguageUtil.getShreds(injectedPsi); if (shreds == null) return Collections.emptyList(); Object result = null; // optimization: TextRange or ArrayList int count = 0; int offset = 0; for (PsiLanguageInjectionHost.Shred shred : shreds) { TextRange encodedRange = TextRange.from( offset + shred.getPrefix().length(), shred.getRangeInsideHost().getLength()); TextRange intersection = encodedRange.intersection(rangeToEdit); if (intersection != null) { count++; if (count == 1) { result = intersection; } else if (count == 2) { TextRange range = (TextRange) result; if (range.isEmpty()) { result = intersection; count = 1; } else if (intersection.isEmpty()) { count = 1; } else { List<TextRange> list = new ArrayList<TextRange>(); list.add(range); list.add(intersection); result = list; } } else if (intersection.isEmpty()) { count--; } else { ((List<TextRange>) result).add(intersection); } } offset += shred.getPrefix().length() + shred.getRangeInsideHost().getLength() + shred.getSuffix().length(); } return count == 0 ? Collections.<TextRange>emptyList() : count == 1 ? Collections.singletonList((TextRange) result) : (List<TextRange>) result; }
@NotNull private static RangeMarker combineScopes( RangeMarker old, @NotNull TextRange scope, int textLength, @NotNull Document document) { if (old == null) { if (scope.equalsToRange(0, textLength)) return WHOLE_FILE_DIRTY_MARKER; return document.createRangeMarker(scope); } if (old == WHOLE_FILE_DIRTY_MARKER) return old; TextRange oldRange = TextRange.create(old); TextRange union = scope.union(oldRange); if (old.isValid() && union.equals(oldRange)) { return old; } if (union.getEndOffset() > textLength) { union = union.intersection(new TextRange(0, textLength)); } assert union != null; return document.createRangeMarker(union); }
private String setup( String text, Function<String, String> escapeFunction, int highlightStartOffset, int highlightEndOffset, boolean isDisabled, boolean strikeout, boolean isDisabledBeforeHighlight, Color background) { StringBuilder buf = new StringBuilder(); removeAll(); String[] lines = UIUtil.splitText(text, getFontMetrics(BOLD_FONT), myWidthLimit, ','); myOneLineComponents = new OneLineComponent[lines.length]; int lineOffset = 0; boolean hasHighlighting = highlightStartOffset >= 0 && highlightEndOffset > highlightStartOffset; TextRange highlightingRange = hasHighlighting ? new TextRange(highlightStartOffset, highlightEndOffset) : null; for (int i = 0; i < lines.length; i++) { String line = lines[i]; myOneLineComponents[i] = new OneLineComponent(); TextRange lRange = new TextRange(lineOffset, lineOffset + line.length()); TextRange hr = highlightingRange == null ? null : lRange.intersection(highlightingRange); hr = hr == null ? null : hr.shiftRight(-lineOffset); String before = escapeString( hr == null ? line : line.substring(0, hr.getStartOffset()), escapeFunction); String in = hr == null ? "" : escapeString(hr.substring(line), escapeFunction); String after = hr == null ? "" : escapeString(line.substring(hr.getEndOffset(), line.length()), escapeFunction); TextRange escapedHighlightingRange = in.isEmpty() ? null : TextRange.create(before.length(), before.length() + in.length()); buf.append( myOneLineComponents[i].setup( before + in + after, isDisabled, strikeout, background, escapedHighlightingRange)); if (isDisabledBeforeHighlight) { if (highlightStartOffset < 0 || highlightEndOffset > lineOffset) { myOneLineComponents[i].setDisabledBeforeHighlight(); } } add( myOneLineComponents[i], new GridBagConstraints( 0, i, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); lineOffset += line.length(); } return buf.toString(); }