void (@NotNull Project project, @NotNull ModRenameSymbol rename, PsiNameIdentifierOwner element, Editor finalEditor) { SmartPsiElementPointer<PsiNameIdentifierOwner> pointer = SmartPointerManager.createPointer(element); record RenameData(Collection<PsiReference> references, PsiElement scope, PsiNameIdentifierOwner nameOwner) { static RenameData create(SmartPsiElementPointer<? extends PsiNameIdentifierOwner> pointer) { PsiNameIdentifierOwner owner = pointer.getElement(); if (owner == null) return null; PsiFile psiFile = owner.getContainingFile(); Collection<PsiReference> references = ReferencesSearch.search(owner, new LocalSearchScope(psiFile)).findAll(); PsiElement scope = PsiTreeUtil.findCommonParent(ContainerUtil.map(references, ref -> ref.getElement())); if (scope != null) { scope = PsiTreeUtil.findCommonParent(scope, owner); } if (scope == null) { scope = psiFile; } return new RenameData(references, scope, owner); } } ReadAction.nonBlocking(() -> RenameData.create(pointer)).expireWhen(() -> finalEditor.isDisposed()) .finishOnUiThread(ModalityState.defaultModalityState(), renameData -> { final TextRange textRange = renameData.scope().getTextRange(); final int startOffset = textRange.getStartOffset(); final TemplateBuilderImpl builder = new TemplateBuilderImpl(renameData.scope()); final Expression nameExpression = new NameExpression(element.getName(), rename.nameSuggestions()); final PsiElement identifier = renameData.nameOwner().getNameIdentifier(); builder.replaceElement(identifier, "PATTERN", nameExpression, true); for (PsiReference reference : renameData.references()) { builder.replaceElement(reference, "PATTERN", "PATTERN", false); } CommandProcessor.getInstance().executeCommand(project, () -> { final Template template = WriteAction.compute(builder::buildInlineTemplate); finalEditor.getCaretModel().moveToOffset(startOffset); final TemplateManager templateManager = TemplateManager.getInstance(project); templateManager.startTemplate(finalEditor, template); }, LangBundle.message("action.rename.text"), null); }) .submit(AppExecutorUtil.getAppExecutorService()); }