String (Project project, Collection<? extends PsiElement> navigableElements) { MultiMap<VirtualFile, Pair<Integer, Integer>> filesToNumbersAndOffsets = new MultiMap<>(); int refNumber = 1; for (PsiElement navigationElement : navigableElements) { Pair<Integer, Integer> numberAndOffset = new Pair<>(refNumber++, navigationElement.getTextOffset()); filesToNumbersAndOffsets.putValue(navigationElement.getContainingFile().getVirtualFile(), numberAndOffset); } if (filesToNumbersAndOffsets.isEmpty()) { return "<no references>"; } List<VirtualFile> files = new ArrayList<>(filesToNumbersAndOffsets.keySet()); files.sort(Comparator.comparing(VirtualFile::getName)); StringBuilder result = new StringBuilder(); for (VirtualFile file : files) { List<Pair<Integer, Integer>> numbersAndOffsets = new ArrayList<>(filesToNumbersAndOffsets.get(file)); numbersAndOffsets.sort(Collections.reverseOrder( Comparator.comparingInt((Pair<Integer, Integer> t) -> t.second).thenComparingInt(t -> t.first))); Document document = FileDocumentManager.getInstance().getDocument(file); TestCase.assertNotNull(document); StringBuilder resultForFile = new StringBuilder(document.getText()); for (Pair<Integer, Integer> numberOffset : numbersAndOffsets) { resultForFile.insert(numberOffset.second, String.format("<%d>", numberOffset.first)); } int minLine = Integer.MAX_VALUE; int maxLine = Integer.MIN_VALUE; for (Pair<Integer, Integer> numberOffset : numbersAndOffsets) { int lineNumber = document.getLineNumber(numberOffset.second); minLine = Math.min(minLine, lineNumber); maxLine = Math.max(maxLine, lineNumber); } Document annotated = EditorFactory.getInstance().createDocument(resultForFile); String filePart = annotated.getText().substring(annotated.getLineStartOffset(minLine), annotated.getLineEndOffset(maxLine)); result.append(" ").append(file.getName()).append("\n"); result.append(filePart).append("\n"); } return result.toString(); }