[mod-commands] RenameTo: ModCommand

Also fixes IDEA-338334 "Rename to" from one split window renames variable from other window

GitOrigin-RevId: 91aa00e94293486bd55673a5da7c37b8c10b7489
This commit is contained in:
Tagir Valeev
2023-11-17 16:50:08 +01:00
committed by intellij-monorepo-bot
parent 7d779bbbe9
commit 59074e21c9
2 changed files with 23 additions and 96 deletions

View File

@@ -1,97 +1,43 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.spellchecker.quickfixes;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.injected.editor.EditorWindow;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.impl.SimpleDataContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.impl.text.TextEditorPsiDataProvider;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.modcommand.PsiUpdateModCommandQuickFix;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Iconable;
import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.util.PsiEditorUtil;
import com.intellij.refactoring.actions.RenameElementAction;
import com.intellij.refactoring.rename.NameSuggestionProvider;
import com.intellij.refactoring.rename.RenameHandlerRegistry;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.rename.RenameUtil;
import com.intellij.spellchecker.SpellCheckerManager;
import com.intellij.spellchecker.util.SpellCheckerBundle;
import icons.SpellcheckerIcons;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.List;
import static com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil.findInjectionHost;
public class RenameTo extends LazySuggestions implements SpellCheckerQuickFix {
public RenameTo(String wordWithTypo) {
super(wordWithTypo);
}
public class RenameTo extends PsiUpdateModCommandQuickFix implements Iconable {
@Override
@NotNull
public String getFamilyName() {
return getFixName();
}
@Nullable
private static DictionarySuggestionProvider findProvider() {
for (Object extension : NameSuggestionProvider.EP_NAME.getExtensionList()) {
if (extension instanceof DictionarySuggestionProvider) {
return (DictionarySuggestionProvider)extension;
}
}
return null;
}
@Override
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
DictionarySuggestionProvider provider = findProvider();
if (provider != null) {
provider.setActive(true);
}
PsiElement psiElement = descriptor.getPsiElement();
if (psiElement == null) return;
final Editor editor = getEditor(psiElement, project);
if (editor == null) return;
SimpleDataContext.Builder builder = SimpleDataContext.builder();
if (editor instanceof EditorWindow) {
builder.add(CommonDataKeys.EDITOR, editor);
builder.add(CommonDataKeys.PSI_ELEMENT, psiElement);
}
else if (ApplicationManager.getApplication().isUnitTestMode()) {
// TextEditorComponent / FiledEditorManagerImpl give away the data in real life
PsiElement data = (PsiElement)new TextEditorPsiDataProvider()
.getData(CommonDataKeys.PSI_ELEMENT.getName(), editor, editor.getCaretModel().getCurrentCaret());
builder.add(CommonDataKeys.PSI_ELEMENT, data);
}
final Boolean selectAll = editor.getUserData(RenameHandlerRegistry.SELECT_ALL);
try {
editor.putUserData(RenameHandlerRegistry.SELECT_ALL, true);
DataContext dataContext = builder.setParent(EditorUtil.getEditorDataContext(editor)).build();
AnAction action = new RenameElementAction();
AnActionEvent event = AnActionEvent.createFromAnAction(action, null, "", dataContext);
action.actionPerformed(event);
if (provider != null) {
provider.setActive(false);
}
}
finally {
editor.putUserData(RenameHandlerRegistry.SELECT_ALL, selectAll);
}
protected void applyFix(@NotNull Project project, @NotNull PsiElement psiElement, @NotNull ModPsiUpdater updater) {
PsiNamedElement named = PsiTreeUtil.getNonStrictParentOfType(psiElement, PsiNamedElement.class);
if (named == null) return;
String name = named.getName();
if (name == null) return;
List<String> names = SpellCheckerManager.getInstance(project).getSuggestions(name)
.stream()
.filter(suggestion -> RenameUtil.isValidName(project, psiElement, suggestion))
.toList();
updater.rename(named, psiElement, names);
}
@Nls
public static String getFixName() {
return SpellCheckerBundle.message("rename.to");
@@ -101,24 +47,4 @@ public class RenameTo extends LazySuggestions implements SpellCheckerQuickFix {
public Icon getIcon(int flags) {
return SpellcheckerIcons.Spellcheck;
}
@Nullable
protected Editor getEditor(PsiElement element, @NotNull Project project) {
Editor editor = null;
if (findInjectionHost(element) != null) {
editor = InjectedLanguageUtil.openEditorFor(element.getContainingFile(), project);
}
if (editor == null) {
editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
}
if (editor == null) {
editor = PsiEditorUtil.findEditor(element);
}
return editor;
}
@Override
public boolean startInWriteAction() {
return false;
}
}

View File

@@ -9,6 +9,7 @@ import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.spellchecker.DictionaryLevel;
import com.intellij.spellchecker.inspections.PlainTextSplitter;
import com.intellij.spellchecker.quickfixes.ChangeTo;
@@ -98,8 +99,8 @@ public class SpellcheckingStrategy {
@NotNull TextRange range) {
ArrayList<LocalQuickFix> result = new ArrayList<>();
if (useRename) {
result.add(new RenameTo(typo));
if (useRename && PsiTreeUtil.getNonStrictParentOfType(element, PsiNamedElement.class) != null) {
result.add(new RenameTo());
} else if (element != null) {
result.addAll(new ChangeTo(typo, element, range).getAllAsFixes());
}