registry option to keep completion hints even longer

(until they move out of sight)
This commit is contained in:
Dmitry Batrak
2018-01-16 12:26:36 +03:00
parent bdb86162aa
commit b8743f08d1
5 changed files with 86 additions and 10 deletions
@@ -13,7 +13,6 @@ import com.intellij.codeInsight.completion.JavaMethodCallElement;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.codeInsight.daemon.impl.ParameterHintsPresentationManager;
import com.intellij.codeInsight.hints.ParameterHintsPass;
import com.intellij.codeInsight.hints.ParameterHintsPassFactory;
import com.intellij.codeInsight.javadoc.JavaDocInfoGenerator;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.lang.parameterInfo.*;
@@ -47,7 +46,9 @@ import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.util.*;
import java.util.List;
/**
* @author Maxim.Mossienko
@@ -116,7 +117,6 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
@Override
public PsiExpressionList findElementForUpdatingParameterInfo(@NotNull final UpdateParameterInfoContext context) {
if (context.isPreservedOnHintHidden() && isOutsideOfCompletedInvocation(context)) {
ParameterHintsPassFactory.forceHintsUpdateOnNextPass(context.getEditor());
context.setPreservedOnHintHidden(false);
return null;
}
@@ -178,7 +178,7 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
private static boolean isOutsideOfCompletedInvocation(UpdateParameterInfoContext context) {
PsiElement owner = context.getParameterOwner();
if (owner != null && owner.isValid()) {
TextRange ownerTextRange = getRelatedRange(owner, context.getEditor().getDocument());
TextRange ownerTextRange = getRelatedRange(owner, context.getEditor());
int caretOffset = context.getOffset();
if (ownerTextRange != null) {
if (caretOffset >= ownerTextRange.getStartOffset() && caretOffset <= ownerTextRange.getEndOffset()) {
@@ -205,9 +205,17 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
return true;
}
private static TextRange getRelatedRange(PsiElement owner, Document document) {
private static TextRange getRelatedRange(PsiElement owner, Editor editor) {
TextRange range = owner.getTextRange();
if (range == null || !Registry.is("editor.keep.completion.hints.longer")) return range;
if (range == null) return null;
Document document = editor.getDocument();
if (Registry.is("editor.keep.completion.hints.even.longer")) {
int startY = editor.visualPositionToXY(editor.offsetToVisualPosition(range.getStartOffset())).y;
int endY = editor.visualPositionToXY(editor.offsetToVisualPosition(range.getEndOffset())).y;
Rectangle visibleArea = editor.getScrollingModel().getVisibleArea();
return startY > visibleArea.getMaxY() || endY < visibleArea.getMinY() ? null : new TextRange(0, document.getTextLength());
}
if (!Registry.is("editor.keep.completion.hints.longer")) return range;
return new TextRange(DocumentUtil.getLineStartOffset(range.getStartOffset(), document),
DocumentUtil.getLineEndOffset(range.getEndOffset(), document));
}
@@ -431,6 +439,11 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
@Override
public void dispose(@NotNull DeleteParameterInfoContext context) {
resetHints(context.getCustomContext());
PsiElement parameterOwner = context.getParameterOwner();
Editor editor = context.getEditor();
if (!editor.isDisposed() && parameterOwner != null && parameterOwner.isValid()) {
ParameterHintsPass.syncUpdate(parameterOwner.getParent(), editor);
}
}
private static PsiSubstitutor getCandidateInfoSubstitutor(PsiElement argList, CandidateInfo candidate, boolean resolveResult) {
@@ -23,6 +23,7 @@ import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.registry.RegistryValue;
import com.intellij.psi.JavaCodeFragmentFactory;
import com.intellij.psi.PsiExpressionCodeFragment;
import com.intellij.testFramework.EditorTestUtil;
import com.intellij.testFramework.fixtures.EditorHintFixture;
import com.intellij.util.ui.UIUtil;
@@ -881,6 +882,43 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase {
}
}
public void testKeepHintsEvenLonger() throws Exception {
RegistryValue setting = Registry.get("editor.keep.completion.hints.even.longer");
boolean oldValue = setting.asBoolean();
try {
setting.setValue(true);
configureJava("class C {\n\n\n\n\n\n" +
" void m() { System.setPro<caret> }\n" +
"}");
EditorTestUtil.setEditorVisibleSize(getEditor(), 1000, 3);
complete("setProperty");
checkResultWithInlays("class C {\n\n\n\n\n\n" +
" void m() { System.setProperty(<HINT text=\"key:\"/><caret>, <Hint text=\"value:\"/>) }\n" +
"}");
type("\"a");
next();
type("\"b");
home();
waitForAllAsyncStuff();
checkResultWithInlays("class C {\n\n\n\n\n\n" +
" <caret>void m() { System.setProperty(<hint text=\"key:\"/>\"a\", <hint text=\"value:\"/>\"b\") }\n" +
"}");
up();
waitForAllAsyncStuff();
checkResultWithInlays("class C {\n\n\n\n\n<caret>\n" +
" void m() { System.setProperty(<hint text=\"key:\"/>\"a\", <hint text=\"value:\"/>\"b\") }\n" +
"}");
textStart();
waitForAllAsyncStuff();
checkResultWithInlays("<caret>class C {\n\n\n\n\n\n" +
" void m() { System.setProperty(\"a\", \"b\") }\n" +
"}");
}
finally {
setting.setValue(oldValue);
}
}
private void enableConstructorVariantsCompletion() {
Registry.get("java.completion.show.constructors").setValue(true);
Disposer.register(myFixture.getTestRootDisposable(), () -> Registry.get("java.completion.show.constructors").setValue(false));
@@ -914,6 +952,10 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase {
myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT);
}
private void up() {
myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP);
}
private void methodOverloadDown() {
myFixture.performEditorAction(IdeActions.ACTION_METHOD_OVERLOAD_SWITCH_DOWN);
}
@@ -3,8 +3,12 @@
*/
package com.intellij.lang.parameterInfo;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.UserDataHolderEx;
import com.intellij.psi.PsiElement;
public interface DeleteParameterInfoContext {
PsiElement getParameterOwner();
Editor getEditor();
UserDataHolderEx getCustomContext();
}
@@ -17,10 +17,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.event.CaretEvent;
import com.intellij.openapi.editor.event.CaretListener;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.editor.event.*;
import com.intellij.openapi.editor.impl.EditorImpl;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.IndexNotReadyException;
@@ -57,7 +54,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.LockSupport;
public class ParameterInfoController extends UserDataHolderBase implements Disposable {
public class ParameterInfoController extends UserDataHolderBase implements VisibleAreaListener, Disposable {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.hint.ParameterInfoController");
private static final String WHITESPACE = " \t";
private final Project myProject;
@@ -152,6 +149,7 @@ public class ParameterInfoController extends UserDataHolderBase implements Dispo
}
};
myEditor.getCaretModel().addCaretListener(myEditorCaretListener);
myEditor.getScrollingModel().addVisibleAreaListener(this);
myEditor.getDocument().addDocumentListener(new DocumentListener() {
@Override
@@ -204,6 +202,12 @@ public class ParameterInfoController extends UserDataHolderBase implements Dispo
List<ParameterInfoController> allControllers = getAllControllers(myEditor);
allControllers.remove(this);
myEditor.getCaretModel().removeCaretListener(myEditorCaretListener);
myEditor.getScrollingModel().removeVisibleAreaListener(this);
}
@Override
public void visibleAreaChanged(VisibleAreaEvent e) {
if (Registry.is("editor.keep.completion.hints.even.longer")) rescheduleUpdate();
}
public void showHint(boolean requestFocus, boolean singleParameterInfo) {
@@ -743,6 +747,16 @@ public class ParameterInfoController extends UserDataHolderBase implements Dispo
}
private class MyDeleteParameterInfoContext implements DeleteParameterInfoContext {
@Override
public PsiElement getParameterOwner() {
return myComponent.getParameterOwner();
}
@Override
public Editor getEditor() {
return myEditor;
}
@Override
public UserDataHolderEx getCustomContext() {
return ParameterInfoController.this;
@@ -1409,6 +1409,9 @@ ext.project.data.serializer.description=select serialization format for external
editor.keep.completion.hints.longer=false
editor.keep.completion.hints.longer.description=Don't remove hints for parameter names added on method call completion until caret moves \
to another line
editor.keep.completion.hints.even.longer=false
editor.keep.completion.hints.even.longer.description=Remove hints for parameter names added on method call completion only when \
corresponding method call becomes invisible (due to scrolling or switching to a different file)
run.anything.rake.tasks=true
run.anything.generators=true