From 4e36b88b45245d19723f120eb5b925e1ed77238a Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 10 Nov 2012 10:12:00 +0100 Subject: [PATCH] WI-14545 Live Template folowed by autocomplete doesn't work as expected --- .../JavaTemplateCompletionProcessor.java | 14 +------ .../template/LiveTemplateTest.groovy | 22 +++++++++++ .../template/ExpressionContext.java | 2 + .../template/macro/BaseCompleteMacro.java | 38 +++++++++++-------- .../DirectoryTemplateCompletionProcessor.java | 8 ++-- 5 files changed, 51 insertions(+), 33 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/template/macro/JavaTemplateCompletionProcessor.java b/java/java-impl/src/com/intellij/codeInsight/template/macro/JavaTemplateCompletionProcessor.java index a2fb89b7504a..75d4d7ec2cde 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/macro/JavaTemplateCompletionProcessor.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/macro/JavaTemplateCompletionProcessor.java @@ -31,18 +31,8 @@ public class JavaTemplateCompletionProcessor implements TemplateCompletionProces @Override public boolean nextTabOnItemSelected(final ExpressionContext context, final LookupElement item) { final List elements = JavaCompletionUtil.getAllPsiElements(item); - if (elements != null) { - if (elements.size() != 1) return false; - final PsiElement element = elements.get(0); - if (element instanceof PsiPackage) { - return false; - } - if (element instanceof PsiMethod) { - PsiMethod method = (PsiMethod)element; - if (method.getParameterList().getParametersCount() != 0) { - return false; - } - } + if (elements != null && elements.size() == 1 && elements.get(0) instanceof PsiPackage) { + return false; } return true; } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy index e187c32dfc93..978a78d105db 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy @@ -9,6 +9,7 @@ import com.intellij.codeInsight.CodeInsightSettings import com.intellij.codeInsight.lookup.LookupManager import com.intellij.codeInsight.lookup.impl.LookupImpl import com.intellij.codeInsight.lookup.impl.LookupManagerImpl +import com.intellij.codeInsight.template.macro.CompleteMacro import com.intellij.openapi.application.AccessToken import com.intellij.openapi.application.WriteAction import com.intellij.openapi.command.CommandProcessor @@ -134,6 +135,27 @@ public class LiveTemplateTest extends LightCodeInsightFixtureTestCase { checkResult(); } + public void "test honor custom completion caret placement"() { + myFixture.configureByText 'a.java', ''' +class Foo { + void foo(int a) {} + { } +} +''' + final TemplateManager manager = TemplateManager.getInstance(getProject()); + final Template template = manager.createTemplate("frm", "user", '$VAR$'); + template.addVariable('VAR', new MacroCallNode(new CompleteMacro()), new EmptyNode(), true) + manager.startTemplate(getEditor(), template); + myFixture.type('fo\n') + myFixture.checkResult ''' +class Foo { + void foo(int a) {} + { foo(); } +} +''' + assert !state.finished + } + private Editor getEditor() { return myFixture.getEditor(); } diff --git a/platform/lang-api/src/com/intellij/codeInsight/template/ExpressionContext.java b/platform/lang-api/src/com/intellij/codeInsight/template/ExpressionContext.java index 70840a1b243a..b86edbedbe1f 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/template/ExpressionContext.java +++ b/platform/lang-api/src/com/intellij/codeInsight/template/ExpressionContext.java @@ -27,6 +27,8 @@ public interface ExpressionContext { @NonNls Key SELECTION = Key.create("SELECTION"); Project getProject(); + + @Nullable Editor getEditor(); int getStartOffset(); int getTemplateStartOffset(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/macro/BaseCompleteMacro.java b/platform/lang-impl/src/com/intellij/codeInsight/template/macro/BaseCompleteMacro.java index 09c864269839..8e51819e8f89 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/macro/BaseCompleteMacro.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/macro/BaseCompleteMacro.java @@ -18,10 +18,10 @@ package com.intellij.codeInsight.template.macro; import com.intellij.codeInsight.lookup.*; import com.intellij.codeInsight.template.*; +import com.intellij.codeInsight.template.Result; import com.intellij.codeInsight.template.impl.TemplateManagerImpl; import com.intellij.codeInsight.template.impl.TemplateState; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.application.*; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Editor; @@ -88,13 +88,7 @@ public abstract class BaseCompleteMacro extends Macro { lookup.addLookupListener(new MyLookupListener(context)); } else { - TemplateState templateState = TemplateManagerImpl.getTemplateState(editor); - if (templateState != null) { - TextRange range = templateState.getCurrentVariableRange(); - if (range != null && range.getLength() > 0) { - templateState.nextTab(); - } - } + considerNextTab(editor); } } }, "", null); @@ -107,6 +101,16 @@ public abstract class BaseCompleteMacro extends Macro { } } + private static void considerNextTab(Editor editor) { + TemplateState templateState = TemplateManagerImpl.getTemplateState(editor); + if (templateState != null) { + TextRange range = templateState.getCurrentVariableRange(); + if (range != null && range.getLength() > 0 && editor.getCaretModel().getOffset() == range.getEndOffset()) { + templateState.nextTab(); + } + } + } + protected abstract void invokeCompletionHandler(Project project, Editor editor); private static class MyLookupListener extends LookupAdapter { @@ -133,23 +137,25 @@ public abstract class BaseCompleteMacro extends Macro { } final Project project = myContext.getProject(); - ApplicationManager.getApplication().invokeLater(new Runnable() { + Runnable runnable = new Runnable() { @Override public void run() { new WriteCommandAction(project) { @Override protected void run(com.intellij.openapi.application.Result result) throws Throwable { - final Editor editor = myContext.getEditor(); + Editor editor = myContext.getEditor(); if (editor != null) { - TemplateState templateState = TemplateManagerImpl.getTemplateState(editor); - if (templateState != null) { - templateState.nextTab(); - } + considerNextTab(editor); } } }.execute(); } - }, ModalityState.current(), project.getDisposed()); + }; + if (ApplicationManager.getApplication().isUnitTestMode()) { + runnable.run(); + } else { + ApplicationManager.getApplication().invokeLater(runnable, ModalityState.current(), project.getDisposed()); + } } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/macro/DirectoryTemplateCompletionProcessor.java b/platform/lang-impl/src/com/intellij/codeInsight/template/macro/DirectoryTemplateCompletionProcessor.java index 873e0abaa6e3..02160468f353 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/macro/DirectoryTemplateCompletionProcessor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/macro/DirectoryTemplateCompletionProcessor.java @@ -26,11 +26,9 @@ import com.intellij.psi.PsiFileSystemItem; public class DirectoryTemplateCompletionProcessor implements TemplateCompletionProcessor { @Override public boolean nextTabOnItemSelected(final ExpressionContext context, final LookupElement item) { - if (item.getObject() instanceof PsiFileSystemItem) { - final PsiFileSystemItem fileSystemItem = (PsiFileSystemItem)item.getObject(); - if (fileSystemItem.isDirectory()) { - return false; - } + Object object = item.getObject(); + if (object instanceof PsiFileSystemItem && ((PsiFileSystemItem)object).isDirectory()) { + return false; } return true; }