From 74a89fa7083dedc6455a16e10cf779d191d79633 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Mon, 27 Mar 2017 18:48:36 +0300 Subject: [PATCH] move caret outside of parenthesis after Tab on last method parameter --- .../completion/CompletionHintsTest.java | 18 +++++++++++++ .../hint/ParameterInfoController.java | 27 ++++++++++++++----- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/CompletionHintsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/CompletionHintsTest.java index 7f114a9f8d26..d2899a772cb6 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/CompletionHintsTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/CompletionHintsTest.java @@ -134,6 +134,24 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { myFixture.checkResult("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); } + public void testTabWithNestedCompletion() { + myFixture.configureByText(JavaFileType.INSTANCE, "class C { void m() { System.setPro } }"); + complete("setProperty"); + myFixture.doHighlighting(); + myFixture.type("System.getPro"); + complete("getProperty(String key, String def)"); + myFixture.doHighlighting(); + myFixture.checkResult("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); + myFixture.performEditorAction("NextParameter"); + myFixture.checkResult("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); + myFixture.performEditorAction("NextParameter"); + myFixture.checkResult("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); + myFixture.performEditorAction("NextParameter"); + myFixture.checkResult("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); + myFixture.performEditorAction("NextParameter"); + myFixture.checkResult("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); + } + private void showParameterInfo() { myFixture.performEditorAction("ParameterInfo"); UIUtil.dispatchAllInvocationEvents(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoController.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoController.java index dcad40ef8587..ccfb61cc6e94 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoController.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoController.java @@ -40,6 +40,7 @@ import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.util.PsiUtilBase; @@ -362,14 +363,16 @@ public class ParameterInfoController implements Disposable { private void moveToParameterAtOffset(int offset) { PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(myEditor.getDocument()); PsiElement argsList = findArgumentList(file, offset, -1); - if (argsList == null) return; + if (argsList == null && !Registry.is("java.completion.argument.hints")) return; offset = adjustOffsetToInlay(offset); myEditor.getCaretModel().moveToLogicalPosition(myEditor.offsetToLogicalPosition(offset).leanForward(true)); myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); myEditor.getSelectionModel().removeSelection(); - myHandler.updateParameterInfo(argsList, new MyUpdateParameterInfoContext(offset, file)); + if (argsList != null) { + myHandler.updateParameterInfo(argsList, new MyUpdateParameterInfoContext(offset, file)); + } } private int adjustOffsetToInlay(int offset) { @@ -400,10 +403,22 @@ public class ParameterInfoController implements Disposable { int currentParameterIndex = noDelimiter ? JBIterable.of(parameters).indexOf((o) -> o.getTextRange().containsOffset(offset)) : ParameterInfoUtils.getCurrentParameterIndex(argList.getNode(), offset, handler.getActualParameterDelimiterType()); - - int prevOrNextParameterIndex = isNext && currentParameterIndex < parameters.length - 1 ? currentParameterIndex + 1 : - !isNext && currentParameterIndex > 0 ? currentParameterIndex - 1 : -1; - return prevOrNextParameterIndex != -1 ? parameters[prevOrNextParameterIndex].getTextRange().getStartOffset() : -1; + if (Registry.is("java.completion.argument.hints")) { + if (currentParameterIndex < 0 || currentParameterIndex >= parameters.length) return -1; + int prevOrNextParameterIndex = currentParameterIndex + (isNext ? 1 : -1); + if (prevOrNextParameterIndex < 0 || prevOrNextParameterIndex >= parameters.length) { + PsiElement parameterOwner = myComponent.getParameterOwner(); + return (parameterOwner != null && parameterOwner.isValid()) ? parameterOwner.getTextRange().getEndOffset() : -1; + } + else { + return parameters[prevOrNextParameterIndex].getTextRange().getStartOffset(); + } + } + else { + int prevOrNextParameterIndex = isNext && currentParameterIndex < parameters.length - 1 ? currentParameterIndex + 1 : + !isNext && currentParameterIndex > 0 ? currentParameterIndex - 1 : -1; + return prevOrNextParameterIndex != -1 ? parameters[prevOrNextParameterIndex].getTextRange().getStartOffset() : -1; + } } @Nullable