void (@NotNull VirtualFile file, @NotNull VcsFileRevision fileRevision, @NotNull AbstractVcs vcs, @Nullable Editor editor, int annotatedLine) { final CharSequence oldContent = editor == null ? null : editor.getDocument().getImmutableCharSequence(); final AnnotationProvider annotationProvider = vcs.getAnnotationProvider(); assert annotationProvider != null; final Ref<FileAnnotation> fileAnnotationRef = new Ref<>(); final Ref<Integer> newLineRef = new Ref<>(); final Ref<VcsException> exceptionRef = new Ref<>(); final BackgroundableActionLock actionLock = VcsAnnotateUtil.getBackgroundableLock(vcs.getProject(), file); actionLock.lock(); Semaphore semaphore = new Semaphore(0); AtomicBoolean shouldOpenEditorInSync = new AtomicBoolean(true); ProgressManager.getInstance().run(new Task.Backgroundable(vcs.getProject(), VcsBundle.message("retrieving.annotations"), true) { @Override public void run(@NotNull ProgressIndicator indicator) { try { FileAnnotation fileAnnotation = annotationProvider.annotate(file, fileRevision); int newLine = annotatedLine < 0 ? -1 : translateLine(oldContent, fileAnnotation.getAnnotatedContent(), annotatedLine); fileAnnotationRef.set(fileAnnotation); newLineRef.set(newLine); shouldOpenEditorInSync.set(false); semaphore.release(); } catch (VcsException e) { exceptionRef.set(e); } } @Override public void onFinished() { actionLock.unlock(); } @Override public void onSuccess() { if (!exceptionRef.isNull()) { AbstractVcsHelper.getInstance(myProject).showError(exceptionRef.get(), VcsBundle.message("operation.name.annotate")); } if (fileAnnotationRef.isNull()) return; AbstractVcsHelper.getInstance(myProject).showAnnotation(fileAnnotationRef.get(), file, vcs, newLineRef.get()); } }); try { semaphore.tryAcquire(ProgressIndicatorWithDelayedPresentation.DEFAULT_PROGRESS_DIALOG_POSTPONE_TIME_MILLIS, TimeUnit.MILLISECONDS); // We want to let Backgroundable task open editor if it was fast enough. // This will remove blinking on editor opening (step 1 - editor opens, step 2 - annotations are shown). if (shouldOpenEditorInSync.get()) { CharSequence content = LoadTextUtil.loadText(file); int newLine = translateLine(oldContent, content, annotatedLine); OpenFileDescriptor openFileDescriptor = new OpenFileDescriptor(vcs.getProject(), file, newLine, 0); FileEditorManager.getInstance(vcs.getProject()).openTextEditor(openFileDescriptor, true); } } catch (InterruptedException ignore) { } }