mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
context languages
This commit is contained in:
@@ -39,6 +39,7 @@ public class LangDataKeys extends PlatformDataKeys {
|
||||
public static final DataKey<PsiElement> PSI_ELEMENT = DataKey.create("psi.Element");
|
||||
public static final DataKey<PsiFile> PSI_FILE = DataKey.create("psi.File");
|
||||
public static final DataKey<Language> LANGUAGE = DataKey.create("Language");
|
||||
public static final DataKey<Language[]> CONTEXT_LANGUAGES = DataKey.create("context.Languages");
|
||||
public static final DataKey<PsiElement[]> PSI_ELEMENT_ARRAY = DataKey.create("psi.Element.array");
|
||||
|
||||
/**
|
||||
|
||||
+44
-20
@@ -20,9 +20,6 @@ import com.intellij.codeInsight.TargetElementUtilBase;
|
||||
import com.intellij.ide.IdeView;
|
||||
import com.intellij.ide.util.EditorHelper;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.fileEditor.EditorDataProvider;
|
||||
@@ -35,12 +32,18 @@ import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
|
||||
import com.intellij.psi.util.PsiUtilBase;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
|
||||
import static com.intellij.openapi.actionSystem.AnActionEvent.injectedId;
|
||||
import static com.intellij.openapi.actionSystem.LangDataKeys.*;
|
||||
import static com.intellij.util.containers.ContainerUtil.addIfNotNull;
|
||||
|
||||
public class TextEditorPsiDataProvider implements EditorDataProvider {
|
||||
@Nullable
|
||||
public Object getData(final String dataId, final Editor e, final VirtualFile file) {
|
||||
if (!file.isValid()) return null;
|
||||
|
||||
if (dataId.equals(AnActionEvent.injectedId(PlatformDataKeys.EDITOR.getName()))) {
|
||||
if (dataId.equals(injectedId(EDITOR.getName()))) {
|
||||
if (PsiDocumentManager.getInstance(e.getProject()).isUncommited(e.getDocument())) {
|
||||
return e;
|
||||
}
|
||||
@@ -48,30 +51,30 @@ public class TextEditorPsiDataProvider implements EditorDataProvider {
|
||||
return InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(e, getPsiFile(e, file));
|
||||
}
|
||||
}
|
||||
if (dataId.equals(AnActionEvent.injectedId(LangDataKeys.PSI_ELEMENT.getName()))) {
|
||||
return getPsiElementIn((Editor)getData(AnActionEvent.injectedId(PlatformDataKeys.EDITOR.getName()), e, file), file);
|
||||
if (dataId.equals(injectedId(PSI_ELEMENT.getName()))) {
|
||||
return getPsiElementIn((Editor)getData(injectedId(EDITOR.getName()), e, file), file);
|
||||
}
|
||||
if (LangDataKeys.PSI_ELEMENT.is(dataId)){
|
||||
if (PSI_ELEMENT.is(dataId)){
|
||||
return getPsiElementIn(e, file);
|
||||
}
|
||||
if (dataId.equals(AnActionEvent.injectedId(LangDataKeys.LANGUAGE.getName()))) {
|
||||
PsiFile psiFile = (PsiFile)getData(AnActionEvent.injectedId(LangDataKeys.PSI_FILE.getName()), e, file);
|
||||
Editor editor = (Editor)getData(AnActionEvent.injectedId(PlatformDataKeys.EDITOR.getName()), e, file);
|
||||
if (dataId.equals(injectedId(LANGUAGE.getName()))) {
|
||||
PsiFile psiFile = (PsiFile)getData(injectedId(PSI_FILE.getName()), e, file);
|
||||
Editor editor = (Editor)getData(injectedId(EDITOR.getName()), e, file);
|
||||
if (psiFile == null || editor == null) return null;
|
||||
return getLanguageAtCurrentPositionInEditor(editor, psiFile);
|
||||
}
|
||||
if (LangDataKeys.LANGUAGE.is(dataId)) {
|
||||
if (LANGUAGE.is(dataId)) {
|
||||
final PsiFile psiFile = getPsiFile(e, file);
|
||||
if (psiFile == null) return null;
|
||||
return getLanguageAtCurrentPositionInEditor(e, psiFile);
|
||||
}
|
||||
if (dataId.equals(AnActionEvent.injectedId(PlatformDataKeys.VIRTUAL_FILE.getName()))) {
|
||||
PsiFile psiFile = (PsiFile)getData(AnActionEvent.injectedId(LangDataKeys.PSI_FILE.getName()), e, file);
|
||||
if (dataId.equals(injectedId(VIRTUAL_FILE.getName()))) {
|
||||
PsiFile psiFile = (PsiFile)getData(injectedId(PSI_FILE.getName()), e, file);
|
||||
if (psiFile == null) return null;
|
||||
return psiFile.getVirtualFile();
|
||||
}
|
||||
if (dataId.equals(AnActionEvent.injectedId(LangDataKeys.PSI_FILE.getName()))) {
|
||||
Editor editor = (Editor)getData(AnActionEvent.injectedId(PlatformDataKeys.EDITOR.getName()), e, file);
|
||||
if (dataId.equals(injectedId(PSI_FILE.getName()))) {
|
||||
Editor editor = (Editor)getData(injectedId(EDITOR.getName()), e, file);
|
||||
if (editor == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -81,10 +84,10 @@ public class TextEditorPsiDataProvider implements EditorDataProvider {
|
||||
}
|
||||
return PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
|
||||
}
|
||||
if (LangDataKeys.PSI_FILE.is(dataId)) {
|
||||
if (PSI_FILE.is(dataId)) {
|
||||
return getPsiFile(e, file);
|
||||
}
|
||||
if (LangDataKeys.IDE_VIEW.is(dataId)) {
|
||||
if (IDE_VIEW.is(dataId)) {
|
||||
final PsiFile psiFile = PsiManager.getInstance(e.getProject()).findFile(file);
|
||||
final PsiDirectory psiDirectory = psiFile != null ? psiFile.getParent() : null;
|
||||
if (psiDirectory != null && psiDirectory.isPhysical()) {
|
||||
@@ -107,18 +110,25 @@ public class TextEditorPsiDataProvider implements EditorDataProvider {
|
||||
};
|
||||
}
|
||||
}
|
||||
if (CONTEXT_LANGUAGES.is(dataId)) {
|
||||
return computeLanguages(e, file);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Language getLanguageAtCurrentPositionInEditor(final Editor editor, final PsiFile psiFile) {
|
||||
int mostProbablyCorrectLanguageOffset = getOffset(editor);
|
||||
|
||||
return PsiUtilBase.getLanguageAtOffset(psiFile, mostProbablyCorrectLanguageOffset);
|
||||
}
|
||||
|
||||
private static int getOffset(Editor editor) {
|
||||
final SelectionModel selectionModel = editor.getSelectionModel();
|
||||
int caretOffset = editor.getCaretModel().getOffset();
|
||||
int mostProbablyCorrectLanguageOffset = caretOffset == selectionModel.getSelectionStart() ||
|
||||
return caretOffset == selectionModel.getSelectionStart() ||
|
||||
caretOffset == selectionModel.getSelectionEnd()
|
||||
? selectionModel.getSelectionStart()
|
||||
: caretOffset;
|
||||
|
||||
return PsiUtilBase.getLanguageAtOffset(psiFile, mostProbablyCorrectLanguageOffset);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -134,6 +144,7 @@ public class TextEditorPsiDataProvider implements EditorDataProvider {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiFile getPsiFile(Editor e, VirtualFile file) {
|
||||
if (!file.isValid()) {
|
||||
return null; // fix for SCR 40329
|
||||
@@ -145,4 +156,17 @@ public class TextEditorPsiDataProvider implements EditorDataProvider {
|
||||
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
|
||||
return psiFile != null && psiFile.isValid() ? psiFile : null;
|
||||
}
|
||||
|
||||
private Language[] computeLanguages(Editor editor, VirtualFile file) {
|
||||
LinkedHashSet<Language> set = new LinkedHashSet<Language>(4);
|
||||
Language injectedLanguage = (Language)getData(injectedId(LANGUAGE.getName()), editor, file);
|
||||
addIfNotNull(injectedLanguage, set);
|
||||
Language language = (Language)getData(LANGUAGE.getName(), editor, file);
|
||||
addIfNotNull(language, set);
|
||||
PsiFile psiFile = (PsiFile)getData(PSI_FILE.getName(), editor, file);
|
||||
if (psiFile != null) {
|
||||
addIfNotNull(psiFile.getViewProvider().getBaseLanguage(), set);
|
||||
}
|
||||
return set.toArray(new Language[set.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
+12
-10
@@ -49,16 +49,18 @@ public abstract class BasePlatformRefactoringAction extends BaseRefactoringActio
|
||||
|
||||
@Override
|
||||
protected final RefactoringActionHandler getHandler(DataContext dataContext) {
|
||||
final Language language = LangDataKeys.LANGUAGE.getData(dataContext);
|
||||
if (language != null) {
|
||||
List<RefactoringSupportProvider> providers = LanguageRefactoringSupport.INSTANCE.allForLanguage(language);
|
||||
if (providers.isEmpty()) return null;
|
||||
if (providers.size() == 1) return getRefactoringHandler(providers.get(0));
|
||||
PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataContext);
|
||||
if (element != null) {
|
||||
for (RefactoringSupportProvider provider : providers) {
|
||||
if (provider.isAvailable(element)) {
|
||||
return getRefactoringHandler(provider);
|
||||
final Language[] languages = LangDataKeys.CONTEXT_LANGUAGES.getData(dataContext);
|
||||
if (languages != null) {
|
||||
for (Language language : languages) {
|
||||
List<RefactoringSupportProvider> providers = LanguageRefactoringSupport.INSTANCE.allForLanguage(language);
|
||||
if (providers.isEmpty()) continue;
|
||||
if (providers.size() == 1) return getRefactoringHandler(providers.get(0));
|
||||
PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataContext);
|
||||
if (element != null) {
|
||||
for (RefactoringSupportProvider provider : providers) {
|
||||
if (provider.isAvailable(element)) {
|
||||
return getRefactoringHandler(provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,11 +23,12 @@ import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtilBase;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -36,6 +37,13 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BaseRefactoringAction extends AnAction {
|
||||
private final Condition<Language> myLanguageCondition = new Condition<Language>() {
|
||||
@Override
|
||||
public boolean value(Language language) {
|
||||
return isAvailableForLanguage(language);
|
||||
}
|
||||
};
|
||||
|
||||
protected abstract boolean isAvailableInEditorOnly();
|
||||
|
||||
protected abstract boolean isEnabledOnElements(PsiElement[] elements);
|
||||
@@ -117,9 +125,13 @@ public abstract class BaseRefactoringAction extends AnAction {
|
||||
}
|
||||
element = getElementAtCaret(editor, file);
|
||||
}
|
||||
boolean isVisible = element != null &&
|
||||
!(element instanceof SyntheticElement) &&
|
||||
isAvailableForLanguage(PsiUtilBase.getLanguageInEditor(editor, project));
|
||||
Language[] languages = e.getData(LangDataKeys.CONTEXT_LANGUAGES);
|
||||
if (element == null || element instanceof SyntheticElement || languages == null) {
|
||||
hideAction(e);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isVisible = ContainerUtil.find(languages, myLanguageCondition) != null;
|
||||
if (isVisible) {
|
||||
boolean isEnabled = isAvailableOnElementInEditorAndFile(element, editor, file);
|
||||
if (!isEnabled) {
|
||||
|
||||
Reference in New Issue
Block a user