Merge branch 'master' of git@git.labs.intellij.net:idea/community

This commit is contained in:
Eugene Kudelevsky
2010-08-18 15:54:37 +04:00
44 changed files with 536 additions and 320 deletions
@@ -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");
/**
@@ -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()]);
}
}
@@ -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),
};
@@ -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;
}
@@ -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();
}
@@ -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() {
@@ -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) {
@@ -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;
}
@@ -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--;
@@ -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;
@@ -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);
}
}
@@ -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);
}
@@ -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;
}
}
}
@@ -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;
}
@@ -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);
}
@@ -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);
@@ -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
-1
View File
@@ -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;
@@ -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>