diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/NextPrevParameterAction.java b/platform/lang-api/src/com/intellij/codeInsight/completion/NextPrevParameterAction.java new file mode 100644 index 000000000000..859da99d24af --- /dev/null +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/NextPrevParameterAction.java @@ -0,0 +1,92 @@ +/* + * Copyright 2000-2012 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. + */ + +/* + * @author max + * @author Evgeny Gerashchenko + */ +package com.intellij.codeInsight.completion; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.actions.CodeInsightAction; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public abstract class NextPrevParameterAction extends CodeInsightAction { + private boolean myNext; + + protected NextPrevParameterAction(boolean next) { + myNext = next; + } + + @Override + protected CodeInsightActionHandler getHandler() { + return new Handler(); + } + + @Override + protected boolean isValidForFile(Project project, Editor editor, PsiFile file) { + return hasSutablePolicy(editor, file); + } + + public static boolean hasSutablePolicy(Editor editor, PsiFile file) { + return findSuitableTraversalPolicy(editor, file) != null; + } + + @Nullable + private static TemplateParameterTraversalPolicy findSuitableTraversalPolicy(Editor editor, PsiFile file) { + for (TemplateParameterTraversalPolicy policy : Extensions.getExtensions(TemplateParameterTraversalPolicy.EP_NAME)) { + if (policy.isValidForFile(editor, file)) { + return policy; + } + } + return null; + } + + private class Handler implements CodeInsightActionHandler { + @Override + public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { + TemplateParameterTraversalPolicy policy = findSuitableTraversalPolicy(editor, file); + if (policy != null) { + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + policy.invoke(editor, file, myNext); + } + } + + @Override + public boolean startInWriteAction() { + return false; + } + } + + public static class Next extends NextPrevParameterAction { + public Next() { + super(true); + } + } + + public static class Prev extends NextPrevParameterAction { + public Prev() { + super(false); + } + } +} diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/TemplateParameterTraversalPolicy.java b/platform/lang-api/src/com/intellij/codeInsight/completion/TemplateParameterTraversalPolicy.java new file mode 100644 index 000000000000..341bf6d24401 --- /dev/null +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/TemplateParameterTraversalPolicy.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2012 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.codeInsight.completion; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.psi.PsiFile; + +/** + * @author Evgeny Gerashchenko + * @since 2/1/12 + */ +public interface TemplateParameterTraversalPolicy { + ExtensionPointName EP_NAME = new ExtensionPointName("com.intellij.templateParameterTraversalPolicy"); + + boolean isValidForFile(Editor editor, PsiFile file); + void invoke(Editor editor, PsiFile file, boolean next); +} diff --git a/platform/lang-impl/src/com/intellij/openapi/editor/actions/LangIndentSelectionAction.java b/platform/lang-impl/src/com/intellij/openapi/editor/actions/LangIndentSelectionAction.java index db2601a7c1bb..5ba19c00ce4a 100644 --- a/platform/lang-impl/src/com/intellij/openapi/editor/actions/LangIndentSelectionAction.java +++ b/platform/lang-impl/src/com/intellij/openapi/editor/actions/LangIndentSelectionAction.java @@ -15,8 +15,12 @@ */ package com.intellij.openapi.editor.actions; +import com.intellij.codeInsight.completion.NextPrevParameterAction; import com.intellij.codeInsight.lookup.LookupManager; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.editor.Editor; +import com.intellij.psi.PsiFile; /** * @author peter @@ -24,7 +28,13 @@ import com.intellij.openapi.editor.Editor; public class LangIndentSelectionAction extends IndentSelectionAction { @Override - protected boolean isEnabled(Editor editor) { - return super.isEnabled(editor) && LookupManager.getActiveLookup(editor) == null; + protected boolean isEnabled(Editor editor, DataContext dataContext) { + if (!super.isEnabled(editor, dataContext)) return false; + if (LookupManager.getActiveLookup(editor) != null) return false; + + PsiFile psiFile = LangDataKeys.PSI_FILE.getData(dataContext); + if (psiFile != null && NextPrevParameterAction.hasSutablePolicy(editor, psiFile)) return false; + + return true; } } diff --git a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java index 7e7b46a4ca1b..5cd3a7812d9f 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java @@ -23,6 +23,8 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.DumbAware; import org.jetbrains.annotations.Nullable; +import java.awt.event.KeyEvent; + public abstract class EditorAction extends AnAction implements DumbAware { private EditorActionHandler myHandler; private boolean myHandlersLoaded; @@ -97,6 +99,10 @@ public abstract class EditorAction extends AnAction implements DumbAware { presentation.setEnabled(getHandler().isEnabled(editor, dataContext)); } + public void updateForKeyboardAccess(Editor editor, Presentation presentation, DataContext dataContext) { + update(editor, presentation, dataContext); + } + public void update(AnActionEvent e) { Presentation presentation = e.getPresentation(); DataContext dataContext = e.getDataContext(); @@ -105,7 +111,12 @@ public abstract class EditorAction extends AnAction implements DumbAware { presentation.setEnabled(false); } else { - update(editor, presentation, dataContext); + if (e.getInputEvent() instanceof KeyEvent) { + updateForKeyboardAccess(editor, presentation, dataContext); + } + else { + update(editor, presentation, dataContext); + } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/IndentSelectionAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/IndentSelectionAction.java index 91864d5548c1..d67c6db555f7 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/IndentSelectionAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/IndentSelectionAction.java @@ -33,7 +33,6 @@ import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler; import com.intellij.openapi.editor.ex.DocumentEx; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileTypes.FileType; -import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; @@ -52,10 +51,19 @@ public class IndentSelectionAction extends EditorAction { @Override public void update(Editor editor, Presentation presentation, DataContext dataContext) { - presentation.setEnabled(isEnabled(editor)); + presentation.setEnabled(originalIsEnabled(editor)); } - protected boolean isEnabled(Editor editor) { + @Override + public void updateForKeyboardAccess(Editor editor, Presentation presentation, DataContext dataContext) { + presentation.setEnabled(isEnabled(editor, dataContext)); + } + + protected boolean isEnabled(Editor editor, DataContext dataContext) { + return originalIsEnabled(editor); + } + + private static boolean originalIsEnabled(Editor editor) { return editor.getSelectionModel().hasSelection() && !editor.isOneLineMode(); } diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index 6d199ff55fb9..4962f74e369f 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -72,6 +72,9 @@ + + diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index 21075aa6d238..dd30603f1365 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -21,6 +21,15 @@ + + + + + + + + + @@ -213,6 +222,7 @@ +