Promise<TreePath> (Object element, boolean select, boolean requestFocus) { int editorOffset; if (myFileEditor instanceof TextEditor textEditor) { editorOffset = textEditor.getEditor().getCaretModel().getOffset(); } else { editorOffset = -1; } AsyncPromise<TreePath> result = myCurrentFocusPromise = new AsyncPromise<>(); var state = new StructureViewSelectVisitorState(); TreeVisitor visitor = new TreeVisitor() { @Override public @NotNull TreeVisitor.VisitThread visitThread() { return VisitThread.BGT; } @Override public @NotNull Action visit(@NotNull TreePath path) { if (myCurrentFocusPromise != result) { result.setError("rejected"); return TreeVisitor.Action.INTERRUPT; } return visitPathForElementSelection(path, element, editorOffset, state); } }; Function<TreePath, Promise<TreePath>> action = path -> { ThreadingAssertions.assertEventDispatchThread(); if (select) { TreeUtil.selectPath(myTree, path); } else { myTree.expandPath(path); } if (requestFocus) { IdeFocusManager.getInstance(myProject).requestFocus(myTree, false); } return Promises.resolvedPromise(path); }; Function<TreePath, Promise<TreePath>> fallback = new Function<>() { @Override public Promise<TreePath> fun(TreePath path) { if (myCurrentFocusPromise != result) { result.setError("rejected"); return Promises.rejectedPromise(); } else if (path == null && state.isOptimizationUsed()) { // Some structure views merge unrelated psi elements into a structure node (MarkdownStructureViewModel). // So turn off the isAncestor() optimization and retry once. state.disableOptimization(); return myAsyncTreeModel.accept(visitor).thenAsync(this); } else { TreePath adjusted = path == null ? state.getBestMatch() : path; return adjusted == null ? Promises.rejectedPromise() : action.fun(adjusted); } } }; myAsyncTreeModel.accept(visitor).thenAsync(fallback).processed(result); return myCurrentFocusPromise; }