(dead, as opposed to live) templates navigation with tab/shift-tab a-la AppCode/Xcode now in platform

This commit is contained in:
Maxim Shafirov
2012-02-09 15:10:31 +04:00
parent abfc786aa1
commit 31b8e5d993
7 changed files with 171 additions and 6 deletions
@@ -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);
}
}
}
@@ -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<TemplateParameterTraversalPolicy> EP_NAME = new ExtensionPointName<TemplateParameterTraversalPolicy>("com.intellij.templateParameterTraversalPolicy");
boolean isValidForFile(Editor editor, PsiFile file);
void invoke(Editor editor, PsiFile file, boolean next);
}
@@ -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;
}
}
@@ -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);
}
}
}
@@ -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();
}
@@ -72,6 +72,9 @@
<extensionPoint name="implicitUsageProvider"
interface="com.intellij.codeInsight.daemon.ImplicitUsageProvider"/>
<extensionPoint name="templateParameterTraversalPolicy"
interface="com.intellij.codeInsight.completion.TemplateParameterTraversalPolicy"/>
<!-- com.intellij.psi.PsiElement -->
<extensionPoint name="cantBeStatic"
interface="com.intellij.openapi.util.Condition"/>
@@ -21,6 +21,15 @@
<action id="Switcher" class="com.intellij.ide.actions.Switcher" text="Switcher"/>
<action id="QuickDocCopy" class="com.intellij.codeInsight.documentation.actions.CopyQuickDocAction" use-shortcut-of="$Copy"/>
<group id="TemplateParametersNavigation">
<action id="NextTemplateParameter" class="com.intellij.codeInsight.completion.NextPrevParameterAction$Next" text="Next Parameter">
<keyboard-shortcut first-keystroke="TAB" keymap="$default"/>
</action>
<action id="PrevTemplateParameter" class="com.intellij.codeInsight.completion.NextPrevParameterAction$Prev" text="Previous Parameter">
<keyboard-shortcut first-keystroke="shift TAB" keymap="$default"/>
</action>
</group>
<group id="EditorActions">
<action id="EditorPageUp" class="com.intellij.openapi.editor.actions.PageUpAction"/>
<action id="EditorPageDown" class="com.intellij.openapi.editor.actions.PageDownAction"/>
@@ -213,6 +222,7 @@
<action id="ConvertIndentsToTabs" class="com.intellij.openapi.editor.actions.ConvertIndentsToTabsAction"/>
</group>
</group>
<reference ref="TemplateParametersNavigation"/>
</group>
<!-- View -->