DiffRequestChain (@NotNull AnActionEvent e) { Project project = e.getProject(); DiffRequest diffRequest = getDiffRequest(e); if (diffRequest != null) { return new SimpleDiffRequestChain(diffRequest); } VirtualFile file1; VirtualFile file2; VirtualFile baseFile = null; VirtualFile[] files = e.getRequiredData(CommonDataKeys.VIRTUAL_FILE_ARRAY); if (files.length == 1) { file1 = files[0]; file2 = getOtherFile(project, file1); if (file2 == null || !hasContent(file2)) return null; } else if (files.length == 2) { file1 = files[0]; file2 = files[1]; } else { file1 = files[0]; baseFile = files[1]; file2 = files[2]; } // getOtherFile() shows dialog that can invalidate files if (!file1.isValid() || !file2.isValid() || (baseFile != null && !baseFile.isValid())) return null; Set<Type> types = ContainerUtil.map2Set(files, CompareFilesAction::getType); if (types.contains(Type.DIRECTORY)) FeatureUsageTracker.getInstance().triggerFeatureUsed("dir.diff"); if (types.contains(Type.ARCHIVE)) FeatureUsageTracker.getInstance().triggerFeatureUsed("jar.diff"); if ("ipynb".equals(file1.getExtension()) && "ipynb".equals(file2.getExtension())) { FeatureUsageTracker.getInstance().triggerFeatureUsed("jupyter.compare.notebooks"); } return createMutableChainFromFiles(project, file1, file2, baseFile); }