From 413ce9c3bdec4ac8314f4c8c393b66344eaba8e2 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Tue, 3 Oct 2017 16:02:45 +0300 Subject: [PATCH] make Tab navigate to next parameter, if completion changes nothing --- .../completion/CompletionHintsTest.java | 11 ++++ .../NextParameterAfterCompletionHandler.java | 56 +++++++++++++++++++ resources/src/idea/RichPlatformPlugin.xml | 3 + 3 files changed, 70 insertions(+) create mode 100644 platform/lang-impl/src/com/intellij/codeInsight/hint/NextParameterAfterCompletionHandler.java diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java index 7d80a9c64d3b..7bdaae2f67cc 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java @@ -691,6 +691,17 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { checkHintContents(null); } + public void testNextParameterWorksWhenTabCompletionDoesntChangeAnything() throws Exception { + configureJava("class C { void m() { String local = \"a\"; String local2 = \"b\"; System.getPro } }"); + complete("getProperty(String key, String def)"); + type("local"); + complete(); + assertEquals("local", myFixture.getLookupElements()[0].getLookupString()); + myFixture.performEditorAction(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM_REPLACE); + waitForAllAsyncStuff(); + checkResultWithInlays("class C { void m() { String local = \"a\"; String local2 = \"b\"; System.getProperty(local, ) } }"); + } + private void checkResult(String text) { myFixture.checkResult(text); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/NextParameterAfterCompletionHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/NextParameterAfterCompletionHandler.java new file mode 100644 index 000000000000..1b67f0dd9b66 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/NextParameterAfterCompletionHandler.java @@ -0,0 +1,56 @@ +// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.codeInsight.hint; + +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.actionSystem.KeyboardShortcut; +import com.intellij.openapi.editor.Caret; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.editor.actionSystem.EditorActionManager; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.event.DocumentListener; +import com.intellij.openapi.util.Ref; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class NextParameterAfterCompletionHandler extends EditorActionHandler { + private final EditorActionHandler myOriginalHandler; + + public NextParameterAfterCompletionHandler(EditorActionHandler originalHandler) { + myOriginalHandler = originalHandler; + } + + @Override + protected boolean isEnabledForCaret(@NotNull Editor editor, @NotNull Caret caret, DataContext dataContext) { + return myOriginalHandler.isEnabled(editor, caret, dataContext); + } + + @Override + protected void doExecute(@NotNull Editor editor, @Nullable Caret caret, DataContext dataContext) { + Ref documentChanged = new Ref<>(); + DocumentListener listener = new DocumentListener() { + @Override + public void documentChanged(DocumentEvent event) { + if (event.getOldLength() > 0 || event.getNewLength() > 0) documentChanged.set(Boolean.TRUE); + } + }; + editor.getDocument().addDocumentListener(listener); + try { + myOriginalHandler.execute(editor, caret, dataContext); + } + finally { + editor.getDocument().removeDocumentListener(listener); + } + if (documentChanged.isNull()) { + ActionManager actionManager = ActionManager.getInstance(); + KeyboardShortcut completionShortcut = actionManager.getKeyboardShortcut(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM_REPLACE); + KeyboardShortcut parameterShortcut = actionManager.getKeyboardShortcut(IdeActions.ACTION_EDITOR_NEXT_PARAMETER); + if (completionShortcut != null && completionShortcut.equals(parameterShortcut)) { + EditorActionHandler parameterHandler = EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_NEXT_PARAMETER); + if (parameterHandler.isEnabled(editor, caret, dataContext)) parameterHandler.execute(editor, caret, dataContext); + } + } + } +} diff --git a/resources/src/idea/RichPlatformPlugin.xml b/resources/src/idea/RichPlatformPlugin.xml index 175e6dc0e1f5..6924f8bae965 100644 --- a/resources/src/idea/RichPlatformPlugin.xml +++ b/resources/src/idea/RichPlatformPlugin.xml @@ -387,6 +387,9 @@ New implementation based on AsyncTreeModel + StructureTreeModel + +