@Override public int compareTo(@NotNull UsageGroup usageGroup) { if (!(usageGroup instanceof MethodUsageGroup)) { LOG.error("MethodUsageGroup expected but " + usageGroup.getClass() + " found"); } MethodUsageGroup other = (MethodUsageGroup)usageGroup; if (SmartPointerManager.getInstance(myProject).pointToTheSameElement(myMethodPointer, other.myMethodPointer)) { return 0; } if (!UsageViewSettings.getInstance().IS_SORT_MEMBERS_ALPHABETICALLY) { Segment segment1 = myMethodPointer.getRange(); Segment segment2 = other.myMethodPointer.getRange(); if (segment1 != null && segment2 != null) { return segment1.getStartOffset() - segment2.getStartOffset(); } } return myName.compareToIgnoreCase(other.myName); }
public void testEqualPointerRangesWhenCreatedFromStubAndAST() { final PsiFile file = configureByText(JavaFileType.INSTANCE, "class S {\n" + "}"); PsiClass aClass = ((PsiJavaFile)file).getClasses()[0]; assertNotNull(((PsiFileImpl)file).getStubTree()); final SmartPointerManager manager = getPointerManager(); final SmartPsiElementPointer<PsiClass> pointer1 = createPointer(aClass); Segment range1 = pointer1.getRange(); manager.removePointer(pointer1); final FileASTNode node = file.getNode(); final SmartPsiElementPointer<PsiClass> pointer2 = createPointer(aClass); assertEquals(range1, pointer2.getRange()); assertNotNull(node); }
private static void flashUsageScriptaculously(@NotNull final Usage usage) { if (!(usage instanceof UsageInfo2UsageAdapter)) { return; } UsageInfo2UsageAdapter usageInfo = (UsageInfo2UsageAdapter)usage; Editor editor = usageInfo.openTextEditor(true); if (editor == null) return; TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.BLINKING_HIGHLIGHTS_ATTRIBUTES); RangeBlinker rangeBlinker = new RangeBlinker(editor, attributes, 6); List<Segment> segments = new ArrayList<Segment>(); CommonProcessors.CollectProcessor<Segment> processor = new CommonProcessors.CollectProcessor<Segment>(segments); usageInfo.processRangeMarkers(processor); rangeBlinker.resetMarkers(segments); rangeBlinker.startBlinking(); }
/** * @return range in element */ @Nullable("null means range is invalid") public ProperTextRange getRangeInElement() { PsiElement element = getElement(); if (element == null) return null; TextRange elementRange = element.getTextRange(); ProperTextRange result; if (myPsiFileRange == null) { int startOffset = element.getTextOffset(); result = ProperTextRange.create(startOffset, elementRange.getEndOffset()); } else { Segment rangeInFile = myPsiFileRange.getRange(); if (rangeInFile == null) return null; result = ProperTextRange.create(rangeInFile); } int delta = elementRange.getStartOffset(); return result.getStartOffset() < delta ? null : result.shiftRight(-delta); }
public ReplacementPreviewDialog(final Project project, UsageInfo info, String replacementString) { super(project,true); setTitle(SSRBundle.message("structural.replace.preview.dialog.title")); setOKButtonText(SSRBundle.message("replace.preview.oktext")); this.project = project; final PsiElement element = info.getElement(); final VirtualFile virtualFile = PsiUtilCore.getVirtualFile(element); myFileType = virtualFile != null ? virtualFile.getFileType() : FileTypes.PLAIN_TEXT; init(); Segment range = info.getSegment(); hilight(virtualFile, range.getStartOffset(), range.getEndOffset()); UIUtil.setContent(replacement, replacementString,0,-1,project); final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByPsiElement(element); if (profile != null) { UIUtil.updateHighlighter(replacement, profile); } }
@Nullable static Pair<ProperTextRange, LinesCols> applyChange(DocumentEvent event, Segment range, int intervalStart, int intervalEnd, boolean greedyLeft, boolean greedyRight, LinesCols linesCols) { final boolean shouldTranslateViaDiff = PersistentRangeMarkerUtil.shouldTranslateViaDiff(event, range); Pair<ProperTextRange, LinesCols> translated = null; if (shouldTranslateViaDiff) { translated = translateViaDiff((DocumentEventImpl)event, linesCols); } if (translated == null) { ProperTextRange fallback = applyChange(event, intervalStart, intervalEnd, greedyLeft, greedyRight); if (fallback == null) return null; LinesCols lc = storeLinesAndCols(fallback, event.getDocument()); if (lc == null) return null; translated = Pair.create(fallback, lc); } if (translated.first.getEndOffset() > event.getDocument().getTextLength() || translated.second.myEndLine < translated.second.myStartLine || translated.second.myStartLine == translated.second.myEndLine && translated.second.myEndColumn < translated.second.myStartColumn || event.getDocument().getLineCount() < translated.second.myEndLine) { return null; } return translated; }
@Override public PsiElement restoreElement() { PsiFile hostFile = myHostContext.getContainingFile(); if (hostFile == null || !hostFile.isValid()) return null; PsiElement hostContext = myHostContext.getElement(); if (hostContext == null) return null; Segment segment = myInjectedFileRangeInHostFile.getPsiRange(); if (segment == null) return null; PsiFile injectedPsi = getInjectedFileIn(hostContext, hostFile, TextRange.create(segment)); ProperTextRange rangeInInjected = hostToInjected(true, segment, injectedPsi, myAffixOffsets); if (rangeInInjected == null) return null; return SelfElementInfo.findElementInside(injectedPsi, rangeInInjected.getStartOffset(), rangeInInjected.getEndOffset(), anchorClass, anchorLanguage); }
@NotNull @Override public List<TextRange> getNonEditableFragments(@NotNull DocumentWindow window) { List<TextRange> result = ContainerUtil.newArrayList(); int offset = 0; for (PsiLanguageInjectionHost.Shred shred : ((DocumentWindowImpl)window).getShreds()) { Segment hostRange = shred.getHostRangeMarker(); if (hostRange == null) continue; offset = appendRange(result, offset, shred.getPrefix().length()); offset += hostRange.getEndOffset() - hostRange.getStartOffset(); offset = appendRange(result, offset, shred.getSuffix().length()); } return result; }
@Override @NotNull public TextRange getRangeInsideHost() { PsiLanguageInjectionHost host = getHost(); Segment psiRange = relevantRangeInHost.getPsiRange(); TextRange textRange = psiRange == null ? null : TextRange.create(psiRange); if (host == null) { if (textRange != null) return textRange; Segment fromSP = hostElementPointer.getPsiRange(); if (fromSP != null) return TextRange.create(fromSP); return new TextRange(0,0); } TextRange hostTextRange = host.getTextRange(); textRange = textRange == null ? null : textRange.intersection(hostTextRange); if (textRange == null) return new ProperTextRange(0, hostTextRange.getLength()); return textRange.shiftRight(-hostTextRange.getStartOffset()); }
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; PsiLanguageInjectionHost.Shred shred = (PsiLanguageInjectionHost.Shred)o; PsiLanguageInjectionHost host = getHost(); Segment hostRangeMarker = getHostRangeMarker(); Segment hostRangeMarker2 = shred.getHostRangeMarker(); return host != null && host.equals(shred.getHost()) && prefix.equals(shred.getPrefix()) && suffix.equals(shred.getSuffix()) && range.equals(shred.getRange()) && hostRangeMarker != null && hostRangeMarker2 != null && TextRange.create(hostRangeMarker).equals(TextRange.create(hostRangeMarker2)); }
@Override public int compareTo(UsageGroup usageGroup) { if (!(usageGroup instanceof MethodUsageGroup)) { LOG.error("MethodUsageGroup expected but " + usageGroup.getClass() + " found"); } MethodUsageGroup other = (MethodUsageGroup)usageGroup; if (SmartPointerManager.getInstance(myProject).pointToTheSameElement(myMethodPointer, other.myMethodPointer)) { return 0; } if (!UsageViewSettings.getInstance().IS_SORT_MEMBERS_ALPHABETICALLY) { Segment segment1 = myMethodPointer.getRange(); Segment segment2 = other.myMethodPointer.getRange(); if (segment1 != null && segment2 != null) { return segment1.getStartOffset() - segment2.getStartOffset(); } } return myName.compareToIgnoreCase(other.myName); }
@Override public int compareTo(final UsageInfo2UsageAdapter o) { VirtualFile containingFile = getFile(); int shift1 = 0; if (containingFile instanceof VirtualFileWindow) { shift1 = ((VirtualFileWindow)containingFile).getDocumentWindow().injectedToHost(0); containingFile = ((VirtualFileWindow)containingFile).getDelegate(); } VirtualFile oContainingFile = o.getFile(); int shift2 = 0; if (oContainingFile instanceof VirtualFileWindow) { shift2 = ((VirtualFileWindow)oContainingFile).getDocumentWindow().injectedToHost(0); oContainingFile = ((VirtualFileWindow)oContainingFile).getDelegate(); } if (containingFile == null && oContainingFile == null || !Comparing.equal(containingFile, oContainingFile)) { return 0; } Segment s1 = getFirstSegment(); Segment s2 = o.getFirstSegment(); if (s1 == null || s2 == null) return 0; return s1.getStartOffset() + shift1 - s2.getStartOffset() - shift2; }
@Override @NotNull public TextRange getRangeInsideHost() { PsiLanguageInjectionHost host = getHost(); ProperTextRange textRange = relevantRangeInHost.isValid() ? new ProperTextRange(relevantRangeInHost.getStartOffset(), relevantRangeInHost.getEndOffset()) : null; if (host == null) { if (textRange != null) return textRange; Segment fromSP = hostElementPointer.getRange(); if (fromSP != null) return TextRange.create(fromSP); return new TextRange(0,0); } TextRange hostTextRange = host.getTextRange(); textRange = textRange == null ? null : textRange.intersection(hostTextRange); if (textRange == null) return new ProperTextRange(0, hostTextRange.getLength()); return textRange.shiftRight(-hostTextRange.getStartOffset()); }
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; PsiLanguageInjectionHost.Shred shred = (PsiLanguageInjectionHost.Shred)o; PsiLanguageInjectionHost host = getHost(); Segment hostRangeMarker = shred.getHostRangeMarker(); return host != null && host.equals(shred.getHost()) && prefix.equals(shred.getPrefix()) && suffix.equals(shred.getSuffix()) && range.equals(shred.getRange()) && hostRangeMarker != null && TextRange.create(relevantRangeInHost).equals(TextRange.create(hostRangeMarker)); }
private static void flashUsageScriptaculously(@Nonnull final Usage usage) { if (!(usage instanceof UsageInfo2UsageAdapter)) { return; } UsageInfo2UsageAdapter usageInfo = (UsageInfo2UsageAdapter)usage; Editor editor = usageInfo.openTextEditor(true); if (editor == null) return; TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.BLINKING_HIGHLIGHTS_ATTRIBUTES); RangeBlinker rangeBlinker = new RangeBlinker(editor, attributes, 6); List<Segment> segments = new ArrayList<>(); Processor<Segment> processor = Processors.cancelableCollectProcessor(segments); usageInfo.processRangeMarkers(processor); rangeBlinker.resetMarkers(segments); rangeBlinker.startBlinking(); }
@Nullable private static Pair<TextRange, LinesCols> applyChange(DocumentEvent event, Segment range, int intervalStart, int intervalEnd, boolean greedyLeft, boolean greedyRight, boolean stickingToRight, LinesCols linesCols) { final boolean shouldTranslateViaDiff = PersistentRangeMarkerUtil.shouldTranslateViaDiff(event, range.getStartOffset(), range.getEndOffset()); Pair<TextRange, LinesCols> translated = null; if (shouldTranslateViaDiff) { translated = translateViaDiff((DocumentEventImpl)event, linesCols); } if (translated == null) { TextRange fallback = applyChange(event, intervalStart, intervalEnd, greedyLeft, greedyRight, stickingToRight); if (fallback == null) return null; LinesCols lc = storeLinesAndCols(event.getDocument(), fallback.getStartOffset(), fallback.getEndOffset()); if (lc == null) return null; translated = Pair.create(fallback, lc); } return translated; }
private static <E extends PsiElement> void updatePointerTarget(@Nonnull SmartPsiElementPointerImpl<E> pointer, @Nullable Segment pointerRange) { E cachedElement = pointer.getCachedElement(); if (cachedElement == null) { return; } if (cachedElement.isValid()) { if (pointerRange == null) { // document change could be damaging, but if PSI survived after reparse, let's point to it ((SelfElementInfo)pointer.getElementInfo()).switchToAnchor(cachedElement); return; } // after reparse and its complex tree diff, the element might have "moved" to other range // but if an element of the same type can still be found at the old range, let's point there if (pointerRange.equals(cachedElement.getTextRange())) { return; } } pointer.cacheElement(pointer.doRestoreElement()); }
@Override PsiElement restoreElement() { PsiFile hostFile = myHostContext.getContainingFile(); if (hostFile == null || !hostFile.isValid()) return null; PsiElement hostContext = myHostContext.getElement(); if (hostContext == null) return null; Segment segment = myInjectedFileRangeInHostFile.getPsiRange(); if (segment == null) return null; PsiFile injectedPsi = getInjectedFileIn(hostContext, hostFile, TextRange.create(segment)); ProperTextRange rangeInInjected = hostToInjected(true, segment, injectedPsi, myAffixOffsets); if (rangeInInjected == null) return null; return myType.findPsiElement(injectedPsi, rangeInInjected.getStartOffset(), rangeInInjected.getEndOffset()); }
@Nonnull @Override public List<TextRange> getNonEditableFragments(@Nonnull DocumentWindow window) { List<TextRange> result = ContainerUtil.newArrayList(); int offset = 0; for (PsiLanguageInjectionHost.Shred shred : ((DocumentWindowImpl)window).getShreds()) { Segment hostRange = shred.getHostRangeMarker(); if (hostRange == null) continue; offset = appendRange(result, offset, shred.getPrefix().length()); offset += hostRange.getEndOffset() - hostRange.getStartOffset(); offset = appendRange(result, offset, shred.getSuffix().length()); } return result; }
@Nonnull private TextRange calcRangeInsideHostElement(boolean usePsiRange) { PsiLanguageInjectionHost host = getHost(); Segment psiRange = usePsiRange ? relevantRangeInHost.getPsiRange() : relevantRangeInHost.getRange(); TextRange textRange = psiRange == null ? null : TextRange.create(psiRange); if (host == null) { if (textRange != null) return textRange; Segment fromSP = usePsiRange ? hostElementPointer.getPsiRange() : hostElementPointer.getRange(); if (fromSP != null) return TextRange.create(fromSP); return new TextRange(0, 0); } TextRange hostTextRange = host.getTextRange(); textRange = textRange == null ? null : textRange.intersection(hostTextRange); if (textRange == null) return new ProperTextRange(0, hostTextRange.getLength()); return textRange.shiftLeft(hostTextRange.getStartOffset()); }
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; PsiLanguageInjectionHost.Shred shred = (PsiLanguageInjectionHost.Shred)o; PsiLanguageInjectionHost host = getHost(); Segment hostRangeMarker = getHostRangeMarker(); Segment hostRangeMarker2 = shred.getHostRangeMarker(); return host != null && host.equals(shred.getHost()) && prefix.equals(shred.getPrefix()) && suffix.equals(shred.getSuffix()) && rangeInDecodedPSI.equals(shred.getRange()) && hostRangeMarker != null && hostRangeMarker2 != null && TextRange.areSegmentsEqual(hostRangeMarker, hostRangeMarker2); }
@Override public Segment getRange() { ImplicitVariable myVar = (ImplicitVariable)super.restoreElement(); PsiIdentifier psiIdentifier = myVar.getNameIdentifier(); if (psiIdentifier == null || !psiIdentifier.isValid()) return null; return psiIdentifier.getTextRange(); }
private void processIntersectingRange(@NotNull UsageInfo2UsageAdapter usageInfo2UsageAdapter, @NotNull final CharSequence chars, int hiStart, final int hiEnd, @NotNull final TextAttributesKey[] tokenHighlights, final boolean selectUsageWithBold, @NotNull final List<TextChunk> result) { final TextAttributes originalAttrs = convertAttributes(tokenHighlights); if (selectUsageWithBold) { originalAttrs.setFontType(Font.PLAIN); } final int[] lastOffset = {hiStart}; usageInfo2UsageAdapter.processRangeMarkers(new Processor<Segment>() { @Override public boolean process(Segment segment) { int usageStart = segment.getStartOffset(); int usageEnd = segment.getEndOffset(); if (rangeIntersect(lastOffset[0], hiEnd, usageStart, usageEnd)) { addChunk(chars, lastOffset[0], Math.max(lastOffset[0], usageStart), originalAttrs, false, null, result); UsageType usageType = isHighlightedAsString(tokenHighlights) ? UsageType.LITERAL_USAGE : isHighlightedAsComment(tokenHighlights) ? UsageType.COMMENT_USAGE : null; addChunk(chars, Math.max(lastOffset[0], usageStart), Math.min(hiEnd, usageEnd), originalAttrs, selectUsageWithBold, usageType, result); lastOffset[0] = usageEnd; if (usageEnd > hiEnd) { return false; } } return true; } }); if (lastOffset[0] < hiEnd) { addChunk(chars, lastOffset[0], hiEnd, originalAttrs, false, null, result); } }
public void resetMarkers(final List<Segment> markers) { removeHighlights(); myMarkers.clear(); stopBlinking(); myMarkers.addAll(markers); show = true; }
public void startBlinking() { Project project = myEditor.getProject(); if (ApplicationManager.getApplication().isDisposed() || myEditor.isDisposed() || project != null && project.isDisposed()) { return; } MarkupModel markupModel = myEditor.getMarkupModel(); if (show) { for (Segment segment : myMarkers) { if (segment.getEndOffset() > myEditor.getDocument().getTextLength()) continue; RangeHighlighter highlighter = markupModel.addRangeHighlighter(segment.getStartOffset(), segment.getEndOffset(), HighlighterLayer.ADDITIONAL_SYNTAX, myAttributes, HighlighterTargetArea.EXACT_RANGE); myAddedHighlighters.add(highlighter); } } else { removeHighlights(); } stopBlinking(); myBlinkingAlarm.addRequest(new Runnable() { @Override public void run() { if (myTimeToLive > 0 || show) { myTimeToLive--; show = !show; startBlinking(); } } }, 400); }
@Nullable("null means could not copy because info is no longer valid") public UsageInfo copy() { PsiElement element = mySmartPointer.getElement(); SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(getProject()); PsiFile containingFile = myPsiFileRange == null ? null : myPsiFileRange.getContainingFile(); Segment segment = containingFile == null ? null : myPsiFileRange.getRange(); TextRange range = segment == null ? null : TextRange.create(segment); SmartPsiFileRange psiFileRange = range == null ? null : smartPointerManager.createSmartPsiFileRangePointer(containingFile, range); SmartPsiElementPointer<PsiElement> pointer = element == null || !isValid() ? null : smartPointerManager.createSmartPsiElementPointer(element); return pointer == null ? null : new UsageInfo(pointer, psiFileRange, isDynamicUsage(), isNonCodeUsage()); }
/** * Answers if document region identified by the given range marker should be translated via diff algorithm on document change * identified by the given event. * * @param e event that describes document change * @param rangeMarker target range marker which update strategy should be selected * @return <code>true</code> if target document range referenced by the given range marker should be translated via * diff algorithm; <code>false</code> otherwise */ static boolean shouldTranslateViaDiff(@NotNull DocumentEvent e, @NotNull Segment rangeMarker) { if (e.isWholeTextReplaced()) { // Perform translation if the whole text is replaced. return true; } if (e.getOffset() >= rangeMarker.getEndOffset() || e.getOffset() + e.getOldLength() <= rangeMarker.getStartOffset()) { // Don't perform complex processing if the change doesn't affect target range. return false; } // Perform complex processing only if significant document part is updated. return (Math.max(e.getNewLength(), e.getOldLength()) * 1.0) / e.getDocument().getTextLength() >= 0.8; }
@Nullable static LinesCols storeLinesAndCols(Segment range, Document myDocument) { int myStartLine; int myStartColumn; int myEndLine; int myEndColumn; // document might have been changed already int startOffset = range.getStartOffset(); if (startOffset <= myDocument.getTextLength()) { myStartLine = myDocument.getLineNumber(startOffset); myStartColumn = startOffset - myDocument.getLineStartOffset(myStartLine); if (myStartColumn < 0) { return null; } } else { return null; } int endOffset = range.getEndOffset(); if (endOffset <= myDocument.getTextLength()) { myEndLine = myDocument.getLineNumber(endOffset); myEndColumn = endOffset - myDocument.getLineStartOffset(myEndLine); if (myEndColumn < 0) { return null; } } else { return null; } return new LinesCols(myStartLine, myStartColumn, myEndLine, myEndColumn); }
@Nullable @Override public Segment getPsiRange() { Document currentDoc = FileDocumentManager.getInstance().getCachedDocument(myVirtualFile); Document committedDoc = currentDoc == null ? null : ((PsiDocumentManagerBase)PsiDocumentManager.getInstance(myProject)).getLastCommittedDocument(currentDoc); return committedDoc == null ? getRange() : new TextRange(0, committedDoc.getTextLength()); }
@Override public PsiFile restoreFile() { PsiFile hostFile = myHostContext.getContainingFile(); if (hostFile == null || !hostFile.isValid()) return null; PsiElement hostContext = myHostContext.getElement(); if (hostContext == null) return null; Segment segment = myInjectedFileRangeInHostFile.getPsiRange(); if (segment == null) return null; final TextRange rangeInHostFile = TextRange.create(segment); return getInjectedFileIn(hostContext, hostFile, rangeInHostFile); }
@Nullable private ProperTextRange getInjectedRange(boolean psi) { PsiElement hostContext = myHostContext.getElement(); if (hostContext == null) return null; Segment hostElementRange = psi ? myInjectedFileRangeInHostFile.getPsiRange() : myInjectedFileRangeInHostFile.getRange(); if (hostElementRange == null) return null; return hostToInjected(psi, hostElementRange, restoreFile(), myAffixOffsets); }
private void setupSpots(Document document) { List<Segment> markers = new ArrayList<Segment>(); while (true) { String text = document.getText(); final int spotStart = text.indexOf("<" + SPOT_MARKER + ">"); if (spotStart < 0) break; final int spotEnd = text.indexOf("</" + SPOT_MARKER + ">", spotStart); if (spotEnd < 0) break; document.deleteString(spotEnd, spotEnd + SPOT_MARKER.length() + 3); document.deleteString(spotStart, spotStart + SPOT_MARKER.length() + 2); Segment spotMarker = new Segment() { @Override public int getStartOffset() { return spotStart; } @Override public int getEndOffset() { return spotEnd - SPOT_MARKER.length() - 2; } }; markers.add(spotMarker); } myRangeBlinker.resetMarkers(markers); if (!markers.isEmpty()) { myRangeBlinker.startBlinking(); } }
@Override @SuppressWarnings({"HardCodedStringLiteral"}) public String toString() { PsiLanguageInjectionHost host = getHost(); Segment hostRange = getHostRangeMarker(); return "Shred " + (host == null ? null : host.getTextRange()) + ": " + host + " In host range: " + (hostRange != null ? "(" + hostRange.getStartOffset() + "," + hostRange.getEndOffset() + ");" : "invalid;") + " PSI range: " + this.range; }
private void processIntersectingRange(@NotNull UsageInfo2UsageAdapter usageInfo2UsageAdapter, @NotNull final CharSequence chars, int hiStart, final int hiEnd, @NotNull TextAttributesKey[] tokenHighlights, final boolean selectUsageWithBold, @NotNull final List<TextChunk> result) { final TextAttributes originalAttrs = convertAttributes(tokenHighlights); if (selectUsageWithBold) { originalAttrs.setFontType(Font.PLAIN); } final int[] lastOffset = {hiStart}; usageInfo2UsageAdapter.processRangeMarkers(new Processor<Segment>() { @Override public boolean process(Segment segment) { int usageStart = segment.getStartOffset(); int usageEnd = segment.getEndOffset(); if (rangeIntersect(lastOffset[0], hiEnd, usageStart, usageEnd)) { addChunk(chars, lastOffset[0], Math.max(lastOffset[0], usageStart), originalAttrs, false, result); addChunk(chars, Math.max(lastOffset[0], usageStart), Math.min(hiEnd, usageEnd), originalAttrs, selectUsageWithBold, result); lastOffset[0] = usageEnd; if (usageEnd > hiEnd) { return false; } } return true; } }); if (lastOffset[0] < hiEnd) { addChunk(chars, lastOffset[0], hiEnd, originalAttrs, false, result); } }
@Override @Nullable public FileEditorLocation getLocation() { VirtualFile virtualFile = getFile(); if (virtualFile == null) return null; FileEditor editor = FileEditorManager.getInstance(getProject()).getSelectedEditor(virtualFile); if (!(editor instanceof TextEditor)) return null; Segment segment = getUsageInfo().getSegment(); if (segment == null) return null; return new TextEditorLocation(segment.getStartOffset(), (TextEditor)editor); }
@Override public void selectInEditor() { if (!isValid()) return; Editor editor = openTextEditor(true); Segment marker = getFirstSegment(); editor.getSelectionModel().setSelection(marker.getStartOffset(), marker.getEndOffset()); }
@Override public void highlightInEditor() { if (!isValid()) return; Segment marker = getFirstSegment(); SelectInEditorManager.getInstance(getProject()).selectInEditor(getFile(), marker.getStartOffset(), marker.getEndOffset(), false, false); }