mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-01 23:06:24 +07:00
Merge branch 'master' of git@git.labs.intellij.net:idea/community
This commit is contained in:
+1
-1
@@ -54,7 +54,7 @@ public class ExtractedDirectoryPresentation extends PackagingElementPresentation
|
||||
commentAttributes = SimpleTextAttributes.ERROR_ATTRIBUTES;
|
||||
}
|
||||
}
|
||||
presentationData.addText("Unpacked '" + PathUtil.getFileName(myJarPath) + myPathInJar + "'", mainAttributes);
|
||||
presentationData.addText("Extracted '" + PathUtil.getFileName(myJarPath) + myPathInJar + "'", mainAttributes);
|
||||
presentationData.addText(" (" + parentPath + ")", commentAttributes);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.lang.refactoring;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import com.intellij.refactoring.changeSignature.ChangeSignatureHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
@@ -27,6 +28,14 @@ import org.jetbrains.annotations.Nullable;
|
||||
* @author ven
|
||||
*/
|
||||
public abstract class RefactoringSupportProvider {
|
||||
|
||||
/**
|
||||
* Allows several providers to be available for the same language
|
||||
* @param context refactoring context
|
||||
* @return true if refactoring support is available in given context
|
||||
*/
|
||||
public boolean isAvailable(@NotNull PsiElement context) { return true; }
|
||||
|
||||
/**
|
||||
* Checks if the Safe Delete refactoring can be applied to the specified element
|
||||
* in the language. The Safe Delete refactoring also requires the plugin to implement
|
||||
|
||||
@@ -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()]);
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -119,6 +119,7 @@ public class GeneralColorsPage implements ColorSettingsPage, InspectionColorSett
|
||||
new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.added.lines"), EditorColors.ADDED_LINES_COLOR, ColorDescriptor.Kind.BACKGROUND),
|
||||
new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.modified.lines"), EditorColors.MODIFIED_LINES_COLOR, ColorDescriptor.Kind.BACKGROUND),
|
||||
new ColorDescriptor(OptionsBundle.message("options.java.color.descriptor.method.separator.color"), CodeInsightColors.METHOD_SEPARATORS_COLOR, ColorDescriptor.Kind.FOREGROUND),
|
||||
new ColorDescriptor(OptionsBundle.message("options.general.color.soft.wrap.sign"), EditorColors.SOFT_WRAP_SIGN_COLOR, ColorDescriptor.Kind.FOREGROUND),
|
||||
|
||||
new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.console.background"), ConsoleViewContentType.CONSOLE_BACKGROUND_KEY, ColorDescriptor.Kind.BACKGROUND),
|
||||
};
|
||||
|
||||
+31
@@ -18,10 +18,17 @@ package com.intellij.refactoring.actions;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageRefactoringSupport;
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.openapi.extensions.ExtensionPointListener;
|
||||
import com.intellij.openapi.extensions.PluginDescriptor;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
@@ -40,6 +47,30 @@ public abstract class BasePlatformRefactoringAction extends BaseRefactoringActio
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final RefactoringActionHandler getHandler(DataContext dataContext) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected abstract RefactoringActionHandler getRefactoringHandler(@NotNull RefactoringSupportProvider provider);
|
||||
|
||||
@Override
|
||||
protected boolean isHidden() {
|
||||
if (myHidden == null) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.refactoring.actions;
|
||||
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ExtractInterfaceAction extends ExtractSuperActionBase {
|
||||
@@ -28,7 +29,7 @@ public class ExtractInterfaceAction extends ExtractSuperActionBase {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected RefactoringActionHandler getRefactoringHandler(RefactoringSupportProvider supportProvider) {
|
||||
protected RefactoringActionHandler getRefactoringHandler(@NotNull RefactoringSupportProvider supportProvider) {
|
||||
return supportProvider.getExtractInterfaceHandler();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,10 +18,10 @@ package com.intellij.refactoring.actions;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageRefactoringSupport;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ExtractMethodAction extends BasePlatformRefactoringAction {
|
||||
public ExtractMethodAction() {
|
||||
@@ -36,13 +36,9 @@ public class ExtractMethodAction extends BasePlatformRefactoringAction {
|
||||
return false;
|
||||
}
|
||||
|
||||
public RefactoringActionHandler getHandler(DataContext dataContext) {
|
||||
final Language language = LangDataKeys.LANGUAGE.getData(dataContext);
|
||||
if (language != null) {
|
||||
return LanguageRefactoringSupport.INSTANCE.forLanguage(language).getExtractMethodHandler();
|
||||
}
|
||||
|
||||
return null;
|
||||
@Override
|
||||
protected RefactoringActionHandler getRefactoringHandler(@NotNull RefactoringSupportProvider provider) {
|
||||
return provider.getExtractMethodHandler();
|
||||
}
|
||||
|
||||
protected boolean isAvailableForLanguage(final Language language) {
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.refactoring.actions;
|
||||
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Dennis.Ushakov
|
||||
@@ -25,7 +26,7 @@ import com.intellij.refactoring.RefactoringActionHandler;
|
||||
public class ExtractModuleAction extends ExtractSuperActionBase {
|
||||
|
||||
@Override
|
||||
protected RefactoringActionHandler getRefactoringHandler(RefactoringSupportProvider supportProvider) {
|
||||
protected RefactoringActionHandler getRefactoringHandler(@NotNull RefactoringSupportProvider supportProvider) {
|
||||
return supportProvider.getExtractModuleHandler();
|
||||
}
|
||||
}
|
||||
@@ -18,14 +18,9 @@ package com.intellij.refactoring.actions;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageRefactoringSupport;
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import com.intellij.refactoring.lang.ElementsHandler;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class ExtractSuperActionBase extends BasePlatformRefactoringAction {
|
||||
|
||||
@@ -42,17 +37,6 @@ public abstract class ExtractSuperActionBase extends BasePlatformRefactoringActi
|
||||
return false;
|
||||
}
|
||||
|
||||
public RefactoringActionHandler getHandler(DataContext dataContext) {
|
||||
PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext);
|
||||
if (file == null) return null;
|
||||
final RefactoringSupportProvider supportProvider =
|
||||
LanguageRefactoringSupport.INSTANCE.forLanguage(file.getViewProvider().getBaseLanguage());
|
||||
return supportProvider != null ? getRefactoringHandler(supportProvider) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected abstract RefactoringActionHandler getRefactoringHandler(RefactoringSupportProvider supportProvider);
|
||||
|
||||
protected boolean isAvailableForLanguage(final Language language) {
|
||||
return getRefactoringHandler(LanguageRefactoringSupport.INSTANCE.forLanguage(language)) != null;
|
||||
}
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@ package com.intellij.refactoring.actions;
|
||||
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ExtractSuperclassAction extends ExtractSuperActionBase {
|
||||
|
||||
@@ -26,7 +27,7 @@ public class ExtractSuperclassAction extends ExtractSuperActionBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RefactoringActionHandler getRefactoringHandler(RefactoringSupportProvider supportProvider) {
|
||||
protected RefactoringActionHandler getRefactoringHandler(@NotNull RefactoringSupportProvider supportProvider) {
|
||||
return supportProvider.getExtractSuperClassHandler();
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ package com.intellij.refactoring.actions;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.refactoring.InlineActionHandler;
|
||||
import com.intellij.lang.refactoring.InlineHandlers;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -32,6 +32,7 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.util.PsiUtilBase;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import com.intellij.refactoring.inline.InlineRefactoringActionHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class InlineAction extends BasePlatformRefactoringAction {
|
||||
@@ -64,7 +65,8 @@ public class InlineAction extends BasePlatformRefactoringAction {
|
||||
).size() > 0;
|
||||
}
|
||||
|
||||
public RefactoringActionHandler getHandler(DataContext dataContext) {
|
||||
@Override
|
||||
protected RefactoringActionHandler getRefactoringHandler(@NotNull RefactoringSupportProvider provider) {
|
||||
return new InlineRefactoringActionHandler();
|
||||
}
|
||||
|
||||
|
||||
+5
-9
@@ -18,23 +18,19 @@ package com.intellij.refactoring.actions;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageRefactoringSupport;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class IntroduceConstantAction extends BasePlatformRefactoringAction {
|
||||
public IntroduceConstantAction() {
|
||||
setInjectedContext(true);
|
||||
}
|
||||
|
||||
protected RefactoringActionHandler getHandler(DataContext dataContext) {
|
||||
final Language language = LangDataKeys.LANGUAGE.getData(dataContext);
|
||||
if (language != null) {
|
||||
return LanguageRefactoringSupport.INSTANCE.forLanguage(language).getIntroduceConstantHandler();
|
||||
}
|
||||
|
||||
return null;
|
||||
@Override
|
||||
protected RefactoringActionHandler getRefactoringHandler(@NotNull RefactoringSupportProvider provider) {
|
||||
return provider.getIntroduceConstantHandler();
|
||||
}
|
||||
|
||||
protected boolean isAvailableInEditorOnly() {
|
||||
|
||||
@@ -18,23 +18,19 @@ package com.intellij.refactoring.actions;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageRefactoringSupport;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class IntroduceFieldAction extends BasePlatformRefactoringAction {
|
||||
public IntroduceFieldAction() {
|
||||
setInjectedContext(true);
|
||||
}
|
||||
|
||||
protected RefactoringActionHandler getHandler(DataContext dataContext) {
|
||||
final Language language = LangDataKeys.LANGUAGE.getData(dataContext);
|
||||
if (language != null) {
|
||||
return LanguageRefactoringSupport.INSTANCE.forLanguage(language).getIntroduceFieldHandler();
|
||||
}
|
||||
|
||||
return null;
|
||||
@Override
|
||||
protected RefactoringActionHandler getRefactoringHandler(@NotNull RefactoringSupportProvider provider) {
|
||||
return provider.getIntroduceFieldHandler();
|
||||
}
|
||||
|
||||
protected boolean isAvailableInEditorOnly() {
|
||||
|
||||
+7
-11
@@ -24,12 +24,12 @@
|
||||
*/
|
||||
package com.intellij.refactoring.actions;
|
||||
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageRefactoringSupport;
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class IntroduceParameterAction extends BasePlatformRefactoringAction {
|
||||
protected boolean isAvailableInEditorOnly() {
|
||||
@@ -40,13 +40,9 @@ public class IntroduceParameterAction extends BasePlatformRefactoringAction {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected RefactoringActionHandler getHandler(DataContext dataContext) {
|
||||
final Language language = LangDataKeys.LANGUAGE.getData(dataContext);
|
||||
if (language != null) {
|
||||
return LanguageRefactoringSupport.INSTANCE.forLanguage(language).getIntroduceParameterHandler();
|
||||
}
|
||||
|
||||
return null;
|
||||
@Override
|
||||
protected RefactoringActionHandler getRefactoringHandler(@NotNull RefactoringSupportProvider provider) {
|
||||
return provider.getIntroduceParameterHandler();
|
||||
}
|
||||
|
||||
protected boolean isAvailableForLanguage(Language language) {
|
||||
|
||||
+5
-10
@@ -18,10 +18,10 @@ package com.intellij.refactoring.actions;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageRefactoringSupport;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -39,14 +39,9 @@ public class IntroduceVariableAction extends BasePlatformRefactoringAction {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected RefactoringActionHandler getHandler(DataContext dataContext) {
|
||||
final Language language = LangDataKeys.LANGUAGE.getData(dataContext);
|
||||
if (language != null) {
|
||||
return LanguageRefactoringSupport.INSTANCE.forLanguage(language).getIntroduceVariableHandler();
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@Override
|
||||
protected RefactoringActionHandler getRefactoringHandler(@NotNull RefactoringSupportProvider provider) {
|
||||
return provider.getIntroduceVariableHandler();
|
||||
}
|
||||
|
||||
protected boolean isAvailableForLanguage(Language language) {
|
||||
|
||||
@@ -19,12 +19,10 @@ package com.intellij.refactoring.actions;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageRefactoringSupport;
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import com.intellij.refactoring.lang.ElementsHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PullUpAction extends BasePlatformRefactoringAction {
|
||||
|
||||
@@ -45,11 +43,9 @@ public class PullUpAction extends BasePlatformRefactoringAction {
|
||||
return false;
|
||||
}
|
||||
|
||||
public RefactoringActionHandler getHandler(DataContext dataContext) {
|
||||
PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext);
|
||||
if (file == null) return null;
|
||||
final RefactoringSupportProvider supportProvider = LanguageRefactoringSupport.INSTANCE.forLanguage(file.getViewProvider().getBaseLanguage());
|
||||
return supportProvider != null ? supportProvider.getPullUpHandler() : null;
|
||||
@Override
|
||||
protected RefactoringActionHandler getRefactoringHandler(@NotNull RefactoringSupportProvider provider) {
|
||||
return provider.getPullUpHandler();
|
||||
}
|
||||
|
||||
protected boolean isAvailableForLanguage(final Language language) {
|
||||
|
||||
@@ -19,12 +19,10 @@ package com.intellij.refactoring.actions;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageRefactoringSupport;
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import com.intellij.refactoring.lang.ElementsHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
public class PushDownAction extends BasePlatformRefactoringAction {
|
||||
@@ -46,11 +44,9 @@ public class PushDownAction extends BasePlatformRefactoringAction {
|
||||
return false;
|
||||
}
|
||||
|
||||
public RefactoringActionHandler getHandler(DataContext dataContext) {
|
||||
PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext);
|
||||
if (file == null) return null;
|
||||
final RefactoringSupportProvider supportProvider = LanguageRefactoringSupport.INSTANCE.forLanguage(file.getViewProvider().getBaseLanguage());
|
||||
return supportProvider != null ? supportProvider.getPushDownHandler() : null;
|
||||
@Override
|
||||
protected RefactoringActionHandler getRefactoringHandler(@NotNull RefactoringSupportProvider provider) {
|
||||
return provider.getPushDownHandler();
|
||||
}
|
||||
|
||||
protected boolean isAvailableForLanguage(final Language language) {
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.ui;
|
||||
|
||||
import com.intellij.codeHighlighting.HighlightDisplayLevel;
|
||||
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
|
||||
import com.intellij.codeInsight.intention.IntentionManager;
|
||||
import com.intellij.codeInspection.InspectionProfile;
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.intellij.codeInspection.InspectionToolProvider;
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.ex.InspectionProfileImpl;
|
||||
import com.intellij.codeInspection.ex.InspectionProfileWrapper;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.editor.EditorSettings;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction;
|
||||
import com.intellij.openapi.editor.actions.TextComponentEditorAction;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.fileTypes.FileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since Aug 18, 2010 1:39:42 PM
|
||||
*/
|
||||
public class SpellCheckAwareEditorFieldProviderImpl implements SpellCheckAwareEditorFieldProvider {
|
||||
|
||||
/**
|
||||
* Encapsulates sorting rule that defines what editor actions have precedence to non-editor actions. Current approach is that
|
||||
* we want to process text processing-oriented editor actions with higher priority than non-editor actions and all
|
||||
* other editor actions with lower priority.
|
||||
* <p/>
|
||||
* Rationale: there is at least one commit-specific action that is mapped to the editor action by default
|
||||
* (<code>'show commit messages history'</code> vs <code>'scroll to center'</code>). We want to process the former on target
|
||||
* short key triggering. Another example is that {@code 'Ctrl+Shift+Right/Left Arrow'} shortcut is bound to
|
||||
* <code>'expand/reduce selection by word'</code> editor action and <code>'change dialog width'</code> non-editor action
|
||||
* and we want to use the first one.
|
||||
*/
|
||||
private static final Comparator<? super AnAction> ACTIONS_COMPARATOR = new Comparator<AnAction>() {
|
||||
@Override
|
||||
public int compare(AnAction o1, AnAction o2) {
|
||||
if (o1 instanceof EditorAction && o2 instanceof EditorAction) {
|
||||
return 0;
|
||||
}
|
||||
if (o1 instanceof TextComponentEditorAction) {
|
||||
return -1;
|
||||
}
|
||||
if (o2 instanceof TextComponentEditorAction) {
|
||||
return 1;
|
||||
}
|
||||
if (o1 instanceof EditorAction) {
|
||||
return 1;
|
||||
}
|
||||
if (o2 instanceof EditorAction) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Holds custom inspection profile wrapper.
|
||||
* <p/>
|
||||
* The general idea is that we want to use existing spell checking functionality within commit message all the time.
|
||||
* Unfortunately, we can't do that as-is because spell checking inspection may be disabled or specifically configured
|
||||
* (e.g. it fails to work with a 'plain text' if 'process code' option is not set).
|
||||
* <p/>
|
||||
* Hence, we define custom profile that is used during highlighting of commit area editor.
|
||||
*/
|
||||
@Nullable
|
||||
private static final InspectionProfileWrapper INSPECTION_PROFILE_WRAPPER = initProvider();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
private static InspectionProfileWrapper initProvider() {
|
||||
// We don't want to add explicit dependency to 'spellchecker' module, hence, use reflection for instantiating
|
||||
// target inspection object. It's assumed that its default settings are just fine for processing commit dialog editor.
|
||||
// Please perform corresponding settings tuning if that assumption is broken at future.
|
||||
InspectionToolProvider provider;
|
||||
try {
|
||||
provider =
|
||||
(InspectionToolProvider)Class.forName("com.intellij.spellchecker.inspections.SpellCheckerInspectionToolProvider").newInstance();
|
||||
}
|
||||
catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Map<String, LocalInspectionTool> tools = new HashMap<String, LocalInspectionTool>();
|
||||
Class<LocalInspectionTool>[] inspectionClasses = (Class<LocalInspectionTool>[])provider.getInspectionClasses();
|
||||
for (Class<LocalInspectionTool> inspectionClass : inspectionClasses) {
|
||||
try {
|
||||
LocalInspectionTool tool = inspectionClass.newInstance();
|
||||
tools.put(tool.getShortName(), tool);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
InspectionProfile profile = new InspectionProfileImpl("CommitMessage") {
|
||||
|
||||
private final LocalInspectionTool[] myToolsArray = tools.values().toArray(new LocalInspectionTool[tools.size()]);
|
||||
|
||||
@Override
|
||||
public HighlightDisplayLevel getErrorLevel(@NotNull HighlightDisplayKey inspectionToolKey, PsiElement element) {
|
||||
return HighlightDisplayLevel.WARNING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InspectionProfileEntry getInspectionTool(@NotNull String shortName, @NotNull PsiElement element) {
|
||||
return tools.get(shortName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public InspectionProfileEntry[] getInspectionTools(PsiElement element) {
|
||||
return myToolsArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isToolEnabled(HighlightDisplayKey key, PsiElement element) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
final List<LocalInspectionTool> toolsList = new ArrayList<LocalInspectionTool>(tools.values());
|
||||
|
||||
return new InspectionProfileWrapper(profile) {
|
||||
@Override
|
||||
public List<LocalInspectionTool> getHighlightingLocalInspectionTools(PsiElement element) {
|
||||
return toolsList;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public EditorTextField getEditorField(final Project project) {
|
||||
return new LanguageTextField(FileTypes.PLAIN_TEXT.getLanguage(), project, "") {
|
||||
@Override
|
||||
protected EditorEx createEditor() {
|
||||
final EditorEx ex = super.createEditor();
|
||||
ex.setOneLineMode(false);
|
||||
ex.getScrollPane().setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
|
||||
ex.setHorizontalScrollbarVisible(true);
|
||||
EditorSettings settings = ex.getSettings();
|
||||
settings.setUseSoftWraps(true);
|
||||
settings.setAdditionalColumnsCount(0);
|
||||
if (INSPECTION_PROFILE_WRAPPER != null) {
|
||||
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(getDocument());
|
||||
if (file != null) {
|
||||
file.putUserData(InspectionProfileWrapper.KEY, INSPECTION_PROFILE_WRAPPER);
|
||||
}
|
||||
}
|
||||
ex.putUserData(IntentionManager.SHOW_INTENTION_OPTIONS_KEY, false);
|
||||
return ex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getData(String dataId) {
|
||||
if (PlatformDataKeys.ACTIONS_SORTER.is(dataId)) {
|
||||
return ACTIONS_COMPARATOR;
|
||||
}
|
||||
return super.getData(dataId);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,7 @@ public interface Editor extends UserDataHolder {
|
||||
/**
|
||||
* Returns the component for the content area of the editor (the area displaying the document text).
|
||||
* The component can be used, for example, for converting logical to screen coordinates.
|
||||
* The instance is implementing {@link com.intellij.openapi.actionSystem.DataProvider}
|
||||
*
|
||||
* @return the component instance.
|
||||
*/
|
||||
|
||||
@@ -26,6 +26,7 @@ public interface EditorColors {
|
||||
ColorKey READONLY_FRAGMENT_BACKGROUND_COLOR = ColorKey.createColorKey("READONLY_FRAGMENT_BACKGROUND");
|
||||
ColorKey WHITESPACES_COLOR = ColorKey.createColorKey("WHITESPACES");
|
||||
ColorKey INDENT_GUIDE_COLOR = ColorKey.createColorKey("INDENT_GUIDE");
|
||||
ColorKey SOFT_WRAP_SIGN_COLOR = ColorKey.createColorKey("SOFT_WRAP_SIGN_COLOR");
|
||||
ColorKey SELECTED_INDENT_GUIDE_COLOR = ColorKey.createColorKey("SELECTED_INDENT_GUIDE");
|
||||
ColorKey SELECTION_BACKGROUND_COLOR = ColorKey.createColorKey("SELECTION_BACKGROUND");
|
||||
ColorKey SELECTION_FOREGROUND_COLOR = ColorKey.createColorKey("SELECTION_FOREGROUND");
|
||||
|
||||
@@ -19,8 +19,11 @@ import com.intellij.ui.ComponentWithExpandableItems;
|
||||
import com.intellij.ui.ExpandableItemsHandler;
|
||||
import com.intellij.ui.ExpandableItemsHandlerFactory;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.NotNullFunction;
|
||||
import com.intellij.util.ui.ComponentWithEmptyText;
|
||||
import com.intellij.util.ui.EmptyTextHelper;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -28,6 +31,10 @@ import java.awt.*;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author Anton Makeev
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public class JBList extends JList implements ComponentWithEmptyText, ComponentWithExpandableItems<Integer> {
|
||||
private EmptyTextHelper myEmptyTextHelper;
|
||||
private ExpandableItemsHandler<Integer> myExpandableItemsHandler;
|
||||
@@ -47,8 +54,7 @@ public class JBList extends JList implements ComponentWithEmptyText, ComponentWi
|
||||
}
|
||||
|
||||
public JBList(Collection items) {
|
||||
super(items.toArray(new Object[items.size()]));
|
||||
init();
|
||||
this(ArrayUtil.toObjectArray(items));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,6 +64,9 @@ public class JBList extends JList implements ComponentWithEmptyText, ComponentWi
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setSelectionBackground(UIUtil.getListSelectionBackground());
|
||||
setSelectionForeground(UIUtil.getListSelectionForeground());
|
||||
|
||||
myEmptyTextHelper = new EmptyTextHelper(this) {
|
||||
@Override
|
||||
protected boolean isEmpty() {
|
||||
@@ -105,4 +114,23 @@ public class JBList extends JList implements ComponentWithEmptyText, ComponentWi
|
||||
public ExpandableItemsHandler<Integer> getExpandableItemsHandler() {
|
||||
return myExpandableItemsHandler;
|
||||
}
|
||||
|
||||
public <T> void installCellRenderer(final @NotNull NotNullFunction<T, JComponent> fun) {
|
||||
setCellRenderer(new DefaultListCellRenderer() {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
@SuppressWarnings({"unchecked"})
|
||||
final JComponent comp = fun.fun((T)value);
|
||||
comp.setOpaque(true);
|
||||
if (isSelected) {
|
||||
comp.setBackground(list.getSelectionBackground());
|
||||
comp.setForeground(list.getSelectionForeground());
|
||||
} else {
|
||||
comp.setBackground(list.getBackground());
|
||||
comp.setForeground(list.getForeground());
|
||||
}
|
||||
return comp;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,4 +116,19 @@ public interface SoftWrapModelEx extends SoftWrapModel {
|
||||
* @return <code>true</code> if given listener was not registered before; <code>false</code> otherwise
|
||||
*/
|
||||
boolean addSoftWrapChangeListener(@NotNull SoftWrapChangeListener listener);
|
||||
|
||||
/**
|
||||
* Asks current model to define approximate soft wraps for the lines range defined by the given lines if necessary.
|
||||
* <p/>
|
||||
* The main idea is to calculate exact soft wraps positions during editor repainting because we have complete
|
||||
* information about font types used for text representation there. However, there is a possible case that we need to
|
||||
* perform intermediate soft wraps calculations. E.g. we may open big document and than may want to scroll to the middle
|
||||
* of it, hence, need to define vertical offset to apply to viewport position. However, vertical offset value depends on
|
||||
* soft wraps between current visible area and target logical line and that soft wraps are not applied yet. We may call this
|
||||
* method in order to define approximate soft wraps number and positions then in order to make scrolling more precise.
|
||||
*
|
||||
* @param line1 one of the target lines boundaries (not imposed to be greater or less than the other boundary)
|
||||
* @param line2 another boundary line (not imposed to be greater or less than the other boundary)
|
||||
*/
|
||||
void defineApproximateSoftWraps(int line1, int line2);
|
||||
}
|
||||
|
||||
@@ -769,7 +769,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JComponent getContentComponent() {
|
||||
public EditorComponentImpl getContentComponent() {
|
||||
return myEditorComponent;
|
||||
}
|
||||
|
||||
|
||||
+12
-5
@@ -142,6 +142,13 @@ public class ScrollingModelImpl implements ScrollingModel {
|
||||
}
|
||||
|
||||
private Point calcOffsetsToScroll(LogicalPosition pos, ScrollType scrollType, Rectangle viewRect) {
|
||||
// There is a possible case that the user opens huge document with many number of soft-wrapped line.
|
||||
// Suppose that he or she wants to move viewport to such a logical position that many document lines between current
|
||||
// viewport position and the target one are not displayed before. That means that we can't be sure about vertical offset
|
||||
// to be applied to the viewport. Hence, we ask soft wrap model to roughly define soft wraps on a trail.
|
||||
LogicalPosition firstVisibleLineStart = myEditor.xyToLogicalPosition(viewRect.getLocation());
|
||||
myEditor.getSoftWrapModel().defineApproximateSoftWraps(firstVisibleLineStart.line, pos.line);
|
||||
|
||||
Point targetLocation = myEditor.logicalPositionToXY(pos);
|
||||
|
||||
if (myEditor.getSettings().isRefrainFromScrolling() && viewRect.contains(targetLocation)) {
|
||||
@@ -424,9 +431,10 @@ public class ScrollingModelImpl implements ScrollingModel {
|
||||
return new Rectangle(myEndHOffset, myEndVOffset, viewRect.width, viewRect.height);
|
||||
}
|
||||
|
||||
public Runnable getStartCommand() {
|
||||
return myStartCommand;
|
||||
}
|
||||
// Commented as the method is not used
|
||||
//public Runnable getStartCommand() {
|
||||
// return myStartCommand;
|
||||
//}
|
||||
|
||||
private void tick() {
|
||||
double time = (myTicksCount + 1) / (double)myStepCount;
|
||||
@@ -496,9 +504,8 @@ public class ScrollingModelImpl implements ScrollingModel {
|
||||
double lineDist = myTotalDist / lineHeight;
|
||||
double part = (lineDist - 1) / 10;
|
||||
if (part > 1) part = 1;
|
||||
int duration = (int)(part * SCROLL_DURATION);
|
||||
//System.out.println("duration = " + duration);
|
||||
return duration;
|
||||
return (int)(part * SCROLL_DURATION);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -172,6 +172,28 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, DocumentListener {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defineApproximateSoftWraps(int line1, int line2) {
|
||||
if (!isSoftWrappingEnabled()) {
|
||||
return;
|
||||
}
|
||||
int startLine = line1;
|
||||
int endLine = line2;
|
||||
if (line1 > line2) {
|
||||
startLine = line2;
|
||||
endLine = line1;
|
||||
}
|
||||
|
||||
// Normalization.
|
||||
Document document = myEditor.getDocument();
|
||||
startLine = Math.max(0, startLine);
|
||||
endLine = Math.min(endLine, document.getLineCount() - 1);
|
||||
|
||||
myApplianceManager.registerSoftWrapIfNecessary(
|
||||
document.getCharsSequence(), document.getLineStartOffset(startLine), document.getLineEndOffset(endLine), 0, Font.PLAIN, true
|
||||
);
|
||||
}
|
||||
|
||||
public void registerSoftWrapIfNecessary(@NotNull CharSequence text, int start, int end, int x, int fontType) {
|
||||
if (!isSoftWrappingEnabled()) {
|
||||
return;
|
||||
@@ -180,7 +202,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, DocumentListener {
|
||||
|
||||
myActive++;
|
||||
try {
|
||||
myApplianceManager.registerSoftWrapIfNecessary(text, start, end, x, fontType);
|
||||
myApplianceManager.registerSoftWrapIfNecessary(text, start, end, x, fontType, false);
|
||||
}
|
||||
finally {
|
||||
myActive--;
|
||||
|
||||
+1
-1
@@ -108,7 +108,7 @@ public class CompositeSoftWrapPainter implements SoftWrapPainter {
|
||||
}
|
||||
if (++mySymbolsDrawingIndex < SYMBOLS.size()) {
|
||||
TextDrawingCallback callback = myEditor.getTextDrawingCallback();
|
||||
ColorProvider colorHolder = ColorProvider.byColorScheme(myEditor, EditorColors.RIGHT_MARGIN_COLOR, EditorColors.WHITESPACES_COLOR);
|
||||
ColorProvider colorHolder = ColorProvider.byColorScheme(myEditor, EditorColors.SOFT_WRAP_SIGN_COLOR);
|
||||
myDelegate = new TextBasedSoftWrapPainter(SYMBOLS.get(mySymbolsDrawingIndex), myEditor, callback, colorHolder);
|
||||
initDelegateIfNecessary();
|
||||
return;
|
||||
|
||||
+31
-16
@@ -16,8 +16,6 @@
|
||||
package com.intellij.openapi.editor.impl.softwrap;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.VisualPosition;
|
||||
import com.intellij.openapi.editor.actions.EditorActionUtil;
|
||||
import com.intellij.openapi.editor.event.DocumentListener;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.ex.util.EditorUtil;
|
||||
@@ -29,6 +27,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import gnu.trove.TIntArrayList;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.awt.*;
|
||||
@@ -103,7 +102,12 @@ public class DefaultSoftWrapApplianceManager implements SoftWrapApplianceManager
|
||||
SPECIAL_SYMBOLS_TO_WRAP_BEFORE.add('.');
|
||||
}
|
||||
|
||||
private final TIntHashSet myProcessedLogicalLines = new TIntHashSet();
|
||||
/**
|
||||
* Holds information about logical lines for which soft wrap is calculated as a set of
|
||||
* <code>(logical line number; temporary)</code> pairs.
|
||||
*/
|
||||
private final TIntObjectHashMap<Boolean> myProcessedLogicalLines = new TIntObjectHashMap<Boolean>();
|
||||
|
||||
private final DocumentListener myDocumentListener = new LineOrientedDocumentChangeAdapter() {
|
||||
@Override
|
||||
public void beforeDocumentChange(int startLine, int endLine, int symbolsDifference) {
|
||||
@@ -124,7 +128,7 @@ public class DefaultSoftWrapApplianceManager implements SoftWrapApplianceManager
|
||||
// Note: we don't update 'myProcessedLogicalLines' collection here, i.e. soft wraps will be recalculated precisely
|
||||
// during standard editor repainting iteration.
|
||||
if (i < document.getLineCount()) {
|
||||
processLogicalLine(document.getCharsSequence(), i, Font.PLAIN, IndentType.NONE);
|
||||
processLogicalLine(document.getCharsSequence(), i, Font.PLAIN, IndentType.NONE, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -150,7 +154,7 @@ public class DefaultSoftWrapApplianceManager implements SoftWrapApplianceManager
|
||||
|
||||
@SuppressWarnings({"AssignmentToForLoopParameter"})
|
||||
@Override
|
||||
public void registerSoftWrapIfNecessary(@NotNull CharSequence text, int start, int end, int x, int fontType) {
|
||||
public void registerSoftWrapIfNecessary(@NotNull CharSequence text, int start, int end, int x, int fontType, boolean temporary) {
|
||||
dropDataIfNecessary();
|
||||
|
||||
if (myVisibleAreaWidth <= 0 || start >= end) {
|
||||
@@ -161,13 +165,13 @@ public class DefaultSoftWrapApplianceManager implements SoftWrapApplianceManager
|
||||
int startLine = document.getLineNumber(start);
|
||||
int endLine = document.getLineNumber(end);
|
||||
for (int i = startLine; i <= endLine; i++) {
|
||||
if (!myProcessedLogicalLines.contains(i)) {
|
||||
if (!myProcessedLogicalLines.contains(i) || (!temporary && myProcessedLogicalLines.get(i))) {
|
||||
IndentType indent = IndentType.NONE;
|
||||
if (!myEditor.isViewer() && !document.isWritable()) {
|
||||
indent = IndentType.TO_PREV_LINE_NON_WS_START;
|
||||
}
|
||||
processLogicalLine(text, i, fontType, indent);
|
||||
myProcessedLogicalLines.add(i);
|
||||
processLogicalLine(text, i, fontType, indent, temporary);
|
||||
myProcessedLogicalLines.put(i, temporary);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -188,7 +192,7 @@ public class DefaultSoftWrapApplianceManager implements SoftWrapApplianceManager
|
||||
myVisibleAreaWidth = currentVisibleAreaWidth;
|
||||
}
|
||||
|
||||
private void processLogicalLine(CharSequence text, int line, int fontType, IndentType indentType) {
|
||||
private void processLogicalLine(CharSequence text, int line, int fontType, IndentType indentType, boolean temporary) {
|
||||
Document document = myEditor.getDocument();
|
||||
int startOffset = document.getLineStartOffset(line);
|
||||
int endOffset = document.getLineEndOffset(line);
|
||||
@@ -202,15 +206,26 @@ public class DefaultSoftWrapApplianceManager implements SoftWrapApplianceManager
|
||||
|
||||
if (indentType == IndentType.NONE) {
|
||||
TIntArrayList offsets = calculateSoftWrapOffsets(text, startOffset, endOffset, fontType, 0);
|
||||
registerSoftWraps(offsets, 0);
|
||||
registerSoftWraps(offsets, 0, temporary);
|
||||
return;
|
||||
}
|
||||
|
||||
// Understand if it's worth to define indent for soft wrap(s) to create and perform their actual construction and registration.
|
||||
int prevLineIndentInColumns = 0;
|
||||
|
||||
int firstNonSpaceSymbolIndex = startOffset;
|
||||
for (; firstNonSpaceSymbolIndex < endOffset; firstNonSpaceSymbolIndex++) {
|
||||
char c = text.charAt(firstNonSpaceSymbolIndex);
|
||||
if (c != ' ' && c != '\t') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (firstNonSpaceSymbolIndex > startOffset) {
|
||||
prevLineIndentInColumns = myTextRepresentationHelper.toVisualColumnSymbolsNumber(text, startOffset, firstNonSpaceSymbolIndex, 0);
|
||||
}
|
||||
|
||||
int spaceWidth = EditorUtil.getSpaceWidth(fontType, myEditor);
|
||||
int indentInColumns = getIndentSize();
|
||||
VisualPosition visual = myEditor.offsetToVisualPosition(startOffset);
|
||||
int prevLineIndentInColumns = EditorActionUtil.findFirstNonSpaceColumnOnTheLine(myEditor, visual.line);
|
||||
int indentInColumnsToUse = 0;
|
||||
TIntArrayList softWrapOffsetsToUse = null;
|
||||
for (; indentInColumns >= 0; indentInColumns--) {
|
||||
@@ -229,10 +244,10 @@ public class DefaultSoftWrapApplianceManager implements SoftWrapApplianceManager
|
||||
}
|
||||
|
||||
if (indentInColumnsToUse <= 0) {
|
||||
processLogicalLine(text, line, fontType, IndentType.NONE);
|
||||
processLogicalLine(text, line, fontType, IndentType.NONE, temporary);
|
||||
}
|
||||
else {
|
||||
registerSoftWraps(softWrapOffsetsToUse, indentInColumnsToUse + prevLineIndentInColumns);
|
||||
registerSoftWraps(softWrapOffsetsToUse, indentInColumnsToUse + prevLineIndentInColumns, temporary);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,10 +290,10 @@ public class DefaultSoftWrapApplianceManager implements SoftWrapApplianceManager
|
||||
return settings.getIndentSize(file.getFileType());
|
||||
}
|
||||
|
||||
private void registerSoftWraps(TIntArrayList offsets, int indentInColumns) {
|
||||
private void registerSoftWraps(TIntArrayList offsets, int indentInColumns, boolean temporary) {
|
||||
for (int i = 0; i < offsets.size(); i++) {
|
||||
int offset = offsets.getQuick(i);
|
||||
myStorage.storeOrReplace(new TextChangeImpl("\n" + StringUtil.repeatSymbol(' ', indentInColumns), offset));
|
||||
myStorage.storeOrReplace(new TextChangeImpl("\n" + StringUtil.repeatSymbol(' ', indentInColumns), offset), !temporary);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -44,6 +44,8 @@ public interface SoftWrapApplianceManager {
|
||||
* @param end end offset of the token to process within the given char array (exclusive)
|
||||
* @param x <code>'x'</code> coordinate within the given graphics buffer that will be used to start drawing the text
|
||||
* @param fontType font type used for the target text fragment representation
|
||||
* @param temporary defines type of the current call. <code>'Temporary'</code> means that soft wraps registered during
|
||||
* the processing should be recalculated on further invocations; they may be reused otherwise
|
||||
*/
|
||||
void registerSoftWrapIfNecessary(@NotNull CharSequence text, int start, int end, int x, int fontType);
|
||||
void registerSoftWrapIfNecessary(@NotNull CharSequence text, int start, int end, int x, int fontType, boolean temporary);
|
||||
}
|
||||
|
||||
+14
-14
@@ -579,16 +579,16 @@ public class SoftWrapDataMapper {
|
||||
|
||||
@Nullable
|
||||
public TextChange get() {
|
||||
if (myIndex < 0 || myIndex >= mySoftWraps.size()) {
|
||||
if (myIndex < 0) {
|
||||
return null;
|
||||
}
|
||||
TextChange result = mySoftWraps.get(myIndex++);
|
||||
if (isVisible(result)) {
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return get();
|
||||
while (myIndex < mySoftWraps.size()) {
|
||||
TextChange result = mySoftWraps.get(myIndex++);
|
||||
if (isVisible(result)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -603,16 +603,16 @@ public class SoftWrapDataMapper {
|
||||
|
||||
@Nullable
|
||||
public FoldRegion get() {
|
||||
if (myFoldRegions == null || myIndex < 0 || myIndex >= myFoldRegions.length) {
|
||||
if (myFoldRegions == null || myIndex < 0) {
|
||||
return null;
|
||||
}
|
||||
FoldRegion result = myFoldRegions[myIndex++];
|
||||
if (result.isExpanded()) {
|
||||
return get();
|
||||
}
|
||||
else {
|
||||
return result;
|
||||
while (myIndex < myFoldRegions.length) {
|
||||
FoldRegion result = myFoldRegions[myIndex++];
|
||||
if (result.isExpanded()) {
|
||||
return get();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-5
@@ -92,19 +92,23 @@ public class SoftWrapsStorage {
|
||||
/**
|
||||
* Inserts given soft wrap to {@link #myWraps} collection at the given index.
|
||||
*
|
||||
* @param softWrap soft wrap to store
|
||||
* @return previous soft wrap object stored for the same offset if any; <code>null</code> otherwise
|
||||
* @param softWrap soft wrap to store
|
||||
* @param notifyListeners flag that indicates if registered listeners should be notified about soft wrap registration
|
||||
* @return previous soft wrap object stored for the same offset if any; <code>null</code> otherwise
|
||||
*/
|
||||
@Nullable
|
||||
public TextChangeImpl storeOrReplace(TextChangeImpl softWrap) { int i = getSoftWrapIndex(softWrap.getStart());
|
||||
public TextChangeImpl storeOrReplace(TextChangeImpl softWrap, boolean notifyListeners) {
|
||||
int i = getSoftWrapIndex(softWrap.getStart());
|
||||
if (i >= 0) {
|
||||
return myWraps.set(i, softWrap);
|
||||
}
|
||||
|
||||
i = -i - 1;
|
||||
myWraps.add(i, softWrap);
|
||||
for (SoftWrapChangeListener listener : myListeners) {
|
||||
listener.softWrapAdded(softWrap);
|
||||
if (notifyListeners) {
|
||||
for (SoftWrapChangeListener listener : myListeners) {
|
||||
listener.softWrapAdded(softWrap);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ public class TextEditorImpl extends UserDataHolderBase implements TextEditor {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JComponent getComponent() {
|
||||
public TextEditorComponent getComponent() {
|
||||
return myComponent;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.ui;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
|
||||
/**
|
||||
* Defines common contract for building {@link EditorTextField} with spell checking support.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since Aug 18, 2010 1:37:55 PM
|
||||
*/
|
||||
public interface SpellCheckAwareEditorFieldProvider {
|
||||
|
||||
/**
|
||||
* @param project target project
|
||||
* @return {@link EditorTextField} with spell checking support.
|
||||
*/
|
||||
EditorTextField getEditorField(Project project);
|
||||
}
|
||||
+2
-2
@@ -111,7 +111,7 @@ public class DefaultSoftWrapApplianceManagerTest {
|
||||
allowing(myScrollingModel).getVisibleArea(); will(returnValue(new Rectangle(0, 0, context.visualWidth, Integer.MAX_VALUE)));
|
||||
allowing(myDocument).getLineEndOffset(0); will(returnValue(context.document.length()));
|
||||
}});
|
||||
myManager.registerSoftWrapIfNecessary(context.document, 0, context.document.length(), 0, Font.PLAIN);
|
||||
myManager.registerSoftWrapIfNecessary(context.document, 0, context.document.length(), 0, Font.PLAIN, true);
|
||||
}
|
||||
|
||||
private static TextChangeImpl createSoftWrap(int offset, int indent) {
|
||||
@@ -177,7 +177,7 @@ public class DefaultSoftWrapApplianceManagerTest {
|
||||
private void processWrap() {
|
||||
buffer.append(rawDocument.substring(index, wrapIndex));
|
||||
myMockery.checking(new Expectations() {{
|
||||
one(myStorage).storeOrReplace(createSoftWrap(buffer.length(), 0));
|
||||
one(myStorage).storeOrReplace(createSoftWrap(buffer.length(), 0), false);
|
||||
}});
|
||||
index = wrapIndex + WRAP_MARKER.length();
|
||||
wrapIndex = rawDocument.indexOf(WRAP_MARKER, index);
|
||||
|
||||
+1
-1
@@ -654,7 +654,7 @@ public class SoftWrapDataMapperTest {
|
||||
}
|
||||
|
||||
public void onSoftWrapEnd() {
|
||||
myStorage.storeOrReplace(new TextChangeImpl(mySoftWrapBuffer.toString(), softWrapStartOffset));
|
||||
myStorage.storeOrReplace(new TextChangeImpl(mySoftWrapBuffer.toString(), softWrapStartOffset), false);
|
||||
mySoftWrapBuffer.setLength(0);
|
||||
insideSoftWrap = false;
|
||||
x += SOFT_WRAP_DRAWING_WIDTH;
|
||||
|
||||
@@ -131,6 +131,7 @@ options.general.color.descriptor.console.system.output=Console system output
|
||||
options.general.color.descriptor.hyperlink.new=Hyperlink
|
||||
options.general.color.descriptor.hyperlink.followed=Followed hyperlink
|
||||
options.general.color.descriptor.todo.defaults=TODO defaults
|
||||
options.general.color.soft.wrap.sign=Soft wrap sign
|
||||
options.java.color.descriptor.full.coverage=Full line coverage
|
||||
options.java.color.descriptor.partial.coverage=Partial line coverage
|
||||
options.java.color.descriptor.none.coverage=Uncovered line
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
<option name="ANNOTATIONS_MERGED_COLOR" value="008080" />
|
||||
<option name="CARET_COLOR" value="0"/>
|
||||
<option name="RIGHT_MARGIN_COLOR" value="c0c0c0"/>
|
||||
<option name="SOFT_WRAP_SIGN_COLOR" value="c0c0c0"/>
|
||||
<option name="TEARLINE_COLOR" value="808080"/>
|
||||
<option name="SELECTED_TEARLINE_COLOR" value="000000"/>
|
||||
<option name="READONLY_FRAGMENT_BACKGROUND" value="cfe7ff"/>
|
||||
|
||||
@@ -131,6 +131,9 @@
|
||||
<applicationService serviceInterface="com.intellij.ide.PowerSaveMode"
|
||||
serviceImplementation="com.intellij.ide.PowerSaveMode"/>
|
||||
|
||||
<applicationService serviceInterface="com.intellij.ui.SpellCheckAwareEditorFieldProvider"
|
||||
serviceImplementation="com.intellij.ui.SpellCheckAwareEditorFieldProviderImpl"/>
|
||||
|
||||
<projectService serviceInterface="com.intellij.psi.codeStyle.ProjectCodeStyleSettingsManager"
|
||||
serviceImplementation="com.intellij.psi.codeStyle.ProjectCodeStyleSettingsManager"/>
|
||||
|
||||
|
||||
@@ -15,148 +15,21 @@
|
||||
*/
|
||||
package com.intellij.openapi.vcs.ui;
|
||||
|
||||
import com.intellij.codeHighlighting.HighlightDisplayLevel;
|
||||
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
|
||||
import com.intellij.codeInsight.intention.IntentionManager;
|
||||
import com.intellij.codeInspection.InspectionProfile;
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.intellij.codeInspection.InspectionToolProvider;
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.ex.*;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.editor.EditorSettings;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction;
|
||||
import com.intellij.openapi.editor.actions.TextComponentEditorAction;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.fileTypes.FileTypes;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.VcsBundle;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.ui.EditorTextField;
|
||||
import com.intellij.ui.LanguageTextField;
|
||||
import com.intellij.ui.SeparatorFactory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import com.intellij.ui.SpellCheckAwareEditorFieldProvider;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
public class CommitMessage extends JPanel implements Disposable {
|
||||
|
||||
/**
|
||||
* Encapsulates sorting rule that defines what editor actions have precedence to non-editor actions. Current approach is that
|
||||
* we want to process text processing-oriented editor actions with higher priority than non-editor actions and all
|
||||
* other editor actions with lower priority.
|
||||
* <p/>
|
||||
* Rationale: there is at least one commit-specific action that is mapped to the editor action by default
|
||||
* (<code>'show commit messages history'</code> vs <code>'scroll to center'</code>). We want to process the former on target
|
||||
* short key triggering. Another example is that {@code 'Ctrl+Shift+Right/Left Arrow'} shortcut is bound to
|
||||
* <code>'expand/reduce selection by word'</code> editor action and <code>'change dialog width'</code> non-editor action
|
||||
* and we want to use the first one.
|
||||
*/
|
||||
private static final Comparator<? super AnAction> ACTIONS_COMPARATOR = new Comparator<AnAction>() {
|
||||
@Override
|
||||
public int compare(AnAction o1, AnAction o2) {
|
||||
if (o1 instanceof EditorAction && o2 instanceof EditorAction) {
|
||||
return 0;
|
||||
}
|
||||
if (o1 instanceof TextComponentEditorAction) {
|
||||
return -1;
|
||||
}
|
||||
if (o2 instanceof TextComponentEditorAction) {
|
||||
return 1;
|
||||
}
|
||||
if (o1 instanceof EditorAction) {
|
||||
return 1;
|
||||
}
|
||||
if (o2 instanceof EditorAction) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Holds custom inspection profile wrapper.
|
||||
* <p/>
|
||||
* The general idea is that we want to use existing spell checking functionality within commit message all the time.
|
||||
* Unfortunately, we can't do that as-is because spell checking inspection may be disabled or specifically configured
|
||||
* (e.g. it fails to work with a 'plain text' if 'process code' option is not set).
|
||||
* <p/>
|
||||
* Hence, we define custom profile that is used during highlighting of commit area editor.
|
||||
*/
|
||||
@Nullable
|
||||
private static final InspectionProfileWrapper INSPECTION_PROFILE_WRAPPER = initProvider();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
private static InspectionProfileWrapper initProvider() {
|
||||
// We don't want to add explicit dependency to 'spellchecker' module, hence, use reflection for instantiating
|
||||
// target inspection object. It's assumed that its default settings are just fine for processing commit dialog editor.
|
||||
// Please perform corresponding settings tuning if that assumption is broken at future.
|
||||
InspectionToolProvider provider;
|
||||
try {
|
||||
provider =
|
||||
(InspectionToolProvider)Class.forName("com.intellij.spellchecker.inspections.SpellCheckerInspectionToolProvider").newInstance();
|
||||
}
|
||||
catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Map<String, LocalInspectionTool> tools = new HashMap<String, LocalInspectionTool>();
|
||||
Class<LocalInspectionTool>[] inspectionClasses = (Class<LocalInspectionTool>[])provider.getInspectionClasses();
|
||||
for (Class<LocalInspectionTool> inspectionClass : inspectionClasses) {
|
||||
try {
|
||||
LocalInspectionTool tool = inspectionClass.newInstance();
|
||||
tools.put(tool.getShortName(), tool);
|
||||
}
|
||||
catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
InspectionProfile profile = new InspectionProfileImpl("CommitMessage") {
|
||||
|
||||
private final LocalInspectionTool[] myToolsArray = tools.values().toArray(new LocalInspectionTool[tools.size()]);
|
||||
|
||||
@Override
|
||||
public HighlightDisplayLevel getErrorLevel(@NotNull HighlightDisplayKey inspectionToolKey, PsiElement element) {
|
||||
return HighlightDisplayLevel.WARNING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InspectionProfileEntry getInspectionTool(@NotNull String shortName, @NotNull PsiElement element) {
|
||||
return tools.get(shortName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public InspectionProfileEntry[] getInspectionTools(PsiElement element) {
|
||||
return myToolsArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isToolEnabled(HighlightDisplayKey key, PsiElement element) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
final List<LocalInspectionTool> toolsList = new ArrayList<LocalInspectionTool>(tools.values());
|
||||
final InspectionProfileWrapper profileWrapper = new InspectionProfileWrapper(profile) {
|
||||
@Override
|
||||
public List<LocalInspectionTool> getHighlightingLocalInspectionTools(PsiElement element) {
|
||||
return toolsList;
|
||||
}
|
||||
};
|
||||
|
||||
return profileWrapper;
|
||||
}
|
||||
|
||||
private final EditorTextField myEditorField;
|
||||
|
||||
public CommitMessage(Project project) {
|
||||
@@ -181,35 +54,8 @@ public class CommitMessage extends JPanel implements Disposable {
|
||||
setBorder(BorderFactory.createEmptyBorder());
|
||||
}
|
||||
|
||||
private static LanguageTextField createEditorField(final Project project) {
|
||||
return new LanguageTextField(FileTypes.PLAIN_TEXT.getLanguage(), project, "") {
|
||||
@Override
|
||||
protected EditorEx createEditor() {
|
||||
final EditorEx ex = super.createEditor();
|
||||
ex.setOneLineMode(false);
|
||||
ex.getScrollPane().setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
|
||||
ex.setHorizontalScrollbarVisible(true);
|
||||
EditorSettings settings = ex.getSettings();
|
||||
settings.setUseSoftWraps(true);
|
||||
settings.setAdditionalColumnsCount(0);
|
||||
if (INSPECTION_PROFILE_WRAPPER != null) {
|
||||
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(getDocument());
|
||||
if (file != null) {
|
||||
file.putUserData(InspectionProfileWrapper.KEY, INSPECTION_PROFILE_WRAPPER);
|
||||
}
|
||||
}
|
||||
ex.putUserData(IntentionManager.SHOW_INTENTION_OPTIONS_KEY, false);
|
||||
return ex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getData(String dataId) {
|
||||
if (PlatformDataKeys.ACTIONS_SORTER.is(dataId)) {
|
||||
return ACTIONS_COMPARATOR;
|
||||
}
|
||||
return super.getData(dataId);
|
||||
}
|
||||
};
|
||||
private static EditorTextField createEditorField(final Project project) {
|
||||
return ServiceManager.getService(SpellCheckAwareEditorFieldProvider.class).getEditorField(project);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
<orderEntry type="module" module-name="platform-api" />
|
||||
<orderEntry type="module" module-name="platform-impl" />
|
||||
<orderEntry type="library" name="commons-codec" level="project" />
|
||||
<orderEntry type="module" module-name="lang-impl" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -378,9 +378,11 @@ public class AntBuildFileImpl implements AntBuildFileBase {
|
||||
LOG.debug(e);
|
||||
}
|
||||
}
|
||||
|
||||
myCachedExternalProperties = result;
|
||||
}
|
||||
else {
|
||||
result = myCachedExternalProperties;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
+8
@@ -16,14 +16,22 @@
|
||||
package org.intellij.lang.xpath.xslt.refactoring;
|
||||
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import org.intellij.lang.xpath.xslt.XsltSupport;
|
||||
import org.intellij.lang.xpath.xslt.refactoring.introduceParameter.XsltIntroduceParameterAction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
public class XsltRefactoringSupportProvider extends RefactoringSupportProvider {
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull PsiElement context) {
|
||||
return XsltSupport.isXsltFile(context.getContainingFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RefactoringActionHandler getIntroduceParameterHandler() {
|
||||
return new XsltIntroduceParameterAction();
|
||||
|
||||
@@ -90,6 +90,7 @@
|
||||
|
||||
<inspectionToolProvider implementation="org.intellij.lang.xpath.xslt.impl.XsltStuffProvider" />
|
||||
<usageGroupingRuleProvider implementation="org.intellij.lang.xpath.xslt.impl.XsltStuffProvider" />
|
||||
<lang.refactoringSupport language="XML" implementationClass="org.intellij.lang.xpath.xslt.refactoring.XsltRefactoringSupportProvider" />
|
||||
|
||||
<intentionAction>
|
||||
<className>org.intellij.lang.xpath.xslt.intentions.AddOptionalArgumentsIntention</className>
|
||||
|
||||
Reference in New Issue
Block a user