mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'denofevil/rd-param-info'
This commit is contained in:
@@ -13,6 +13,7 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.util.Function;
|
||||
@@ -28,6 +29,7 @@ import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -86,7 +88,7 @@ public class ParameterInfoComponent extends JPanel {
|
||||
super(new BorderLayout());
|
||||
myRequestFocus = requestFocus;
|
||||
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode() && !ApplicationManager.getApplication().isHeadlessEnvironment()) {
|
||||
JComponent editorComponent = editor.getComponent();
|
||||
JLayeredPane layeredPane = editorComponent.getRootPane().getLayeredPane();
|
||||
myWidthLimit = layeredPane.getWidth();
|
||||
@@ -169,6 +171,7 @@ public class ParameterInfoComponent extends JPanel {
|
||||
private final boolean mySingleParameterInfo;
|
||||
private int i;
|
||||
private Function<String, String> myEscapeFunction;
|
||||
private final ParameterInfoController.Model result = new ParameterInfoController.Model();
|
||||
|
||||
public MyParameterContext(boolean singleParameterInfo) {
|
||||
mySingleParameterInfo = singleParameterInfo;
|
||||
@@ -182,6 +185,29 @@ public class ParameterInfoComponent extends JPanel {
|
||||
boolean strikeout,
|
||||
boolean isDisabledBeforeHighlight,
|
||||
Color background) {
|
||||
List<String> split = StringUtil.split(text, ",", false);
|
||||
StringBuilder plainLine = new StringBuilder();
|
||||
final List<Integer> startOffsets = new ArrayList<>();
|
||||
final List<Integer> endOffsets = new ArrayList<>();
|
||||
|
||||
TextRange highlightRange = highlightStartOffset >=0 && highlightEndOffset >= highlightStartOffset ?
|
||||
new TextRange(highlightStartOffset, highlightEndOffset) :
|
||||
null;
|
||||
for (int j = 0; j < split.size(); j++) {
|
||||
String line = split.get(j);
|
||||
int startOffset = plainLine.length();
|
||||
startOffsets.add(startOffset);
|
||||
plainLine.append(line);
|
||||
int endOffset = plainLine.length();
|
||||
endOffsets.add(endOffset);
|
||||
if (highlightRange != null && highlightRange.intersects(new TextRange(startOffset, endOffset))) {
|
||||
result.current = j;
|
||||
}
|
||||
}
|
||||
ParameterInfoController.SignatureItem item = new ParameterInfoController.SignatureItem(plainLine.toString(), strikeout, isDisabled,
|
||||
startOffsets, endOffsets);
|
||||
result.signatures.add(item);
|
||||
|
||||
final String resultedText =
|
||||
myPanels[i].setup(text, myEscapeFunction, highlightStartOffset, highlightEndOffset, isDisabled, strikeout, isDisabledBeforeHighlight, background);
|
||||
myPanels[i].setBorder(isLastParameterOwner() || isSingleParameterInfo() ? EMPTY_BORDER : BOTTOM_BORDER);
|
||||
@@ -196,7 +222,7 @@ public class ParameterInfoComponent extends JPanel {
|
||||
|
||||
@Override
|
||||
public String setupUIComponentPresentation(final String[] texts, final EnumSet<Flag>[] flags, final Color background) {
|
||||
final String resultedText = myPanels[i].setup(texts, myEscapeFunction, flags, background);
|
||||
final String resultedText = myPanels[i].setup(result, texts, myEscapeFunction, flags, background);
|
||||
myPanels[i].setBorder(isLastParameterOwner() || isSingleParameterInfo() ? EMPTY_BORDER : BOTTOM_BORDER);
|
||||
return resultedText;
|
||||
}
|
||||
@@ -252,7 +278,7 @@ public class ParameterInfoComponent extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
public void update(boolean singleParameterInfo) {
|
||||
public ParameterInfoController.Model update(boolean singleParameterInfo) {
|
||||
MyParameterContext context = new MyParameterContext(singleParameterInfo);
|
||||
|
||||
for (int i = 0; i < myObjects.length; i++) {
|
||||
@@ -270,6 +296,7 @@ public class ParameterInfoComponent extends JPanel {
|
||||
}
|
||||
|
||||
if (myShortcutLabel != null) myShortcutLabel.setVisible(!singleParameterInfo);
|
||||
return context.result;
|
||||
}
|
||||
|
||||
public Object[] getObjects() {
|
||||
@@ -388,7 +415,8 @@ public class ParameterInfoComponent extends JPanel {
|
||||
return escapeFunction == null ? line : escapeFunction.fun(line);
|
||||
}
|
||||
|
||||
public String setup(final String[] texts,
|
||||
public String setup(final ParameterInfoController.Model result,
|
||||
final String[] texts,
|
||||
Function<String, String> escapeFunction,
|
||||
final EnumSet<ParameterInfoUIContextEx.Flag>[] flags,
|
||||
final Color background) {
|
||||
@@ -398,16 +426,24 @@ public class ParameterInfoComponent extends JPanel {
|
||||
int index = 0;
|
||||
int curOffset = 0;
|
||||
final ArrayList<OneLineComponent> components = new ArrayList<>();
|
||||
final List<Integer> startOffsets = new ArrayList<>();
|
||||
final List<Integer> endOffsets = new ArrayList<>();
|
||||
|
||||
|
||||
Map<TextRange, ParameterInfoUIContextEx.Flag> flagsMap = new TreeMap<>(TEXT_RANGE_COMPARATOR);
|
||||
|
||||
String line = "";
|
||||
StringBuilder fullLine = new StringBuilder();
|
||||
StringBuilder line = new StringBuilder();
|
||||
for (int i = 0; i < texts.length; i++) {
|
||||
String paramText = escapeString(texts[i], escapeFunction);
|
||||
if (paramText == null) break;
|
||||
line += texts[i];
|
||||
startOffsets.add(fullLine.length());
|
||||
fullLine.append(texts[i]);
|
||||
endOffsets.add(fullLine.length());
|
||||
line.append(texts[i]);
|
||||
final EnumSet<ParameterInfoUIContextEx.Flag> flag = flags[i];
|
||||
if (flag.contains(ParameterInfoUIContextEx.Flag.HIGHLIGHT)) {
|
||||
result.current = i;
|
||||
flagsMap.put(TextRange.create(curOffset, curOffset + paramText.trim().length()), ParameterInfoUIContextEx.Flag.HIGHLIGHT);
|
||||
}
|
||||
|
||||
@@ -422,18 +458,21 @@ public class ParameterInfoComponent extends JPanel {
|
||||
curOffset += paramText.length();
|
||||
if (line.length() >= 50) {
|
||||
final OneLineComponent component = new OneLineComponent();
|
||||
buf.append(component.setup(escapeString(line, escapeFunction), flagsMap, background));
|
||||
buf.append(component.setup(escapeString(line.toString(), escapeFunction), flagsMap, background));
|
||||
add(component, new GridBagConstraints(0, index, 1, 1, 1, 0, GridBagConstraints.WEST,
|
||||
GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
|
||||
index += 1;
|
||||
flagsMap.clear();
|
||||
curOffset = 0;
|
||||
line = "";
|
||||
line = new StringBuilder();
|
||||
components.add(component);
|
||||
}
|
||||
}
|
||||
ParameterInfoController.SignatureItem item = new ParameterInfoController.SignatureItem(fullLine.toString(), false, false,
|
||||
startOffsets, endOffsets);
|
||||
result.signatures.add(item);
|
||||
final OneLineComponent component = new OneLineComponent();
|
||||
buf.append(component.setup(escapeString(line, escapeFunction), flagsMap, background));
|
||||
buf.append(component.setup(escapeString(line.toString(), escapeFunction), flagsMap, background));
|
||||
add(component, new GridBagConstraints(0, index, 1, 1, 1, 0, GridBagConstraints.WEST,
|
||||
GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
|
||||
components.add(component);
|
||||
|
||||
@@ -67,6 +67,7 @@ public class ParameterInfoController extends UserDataHolderBase implements Visib
|
||||
private final CaretListener myEditorCaretListener;
|
||||
@NotNull private final ParameterInfoHandler<Object, Object> myHandler;
|
||||
private final MyBestLocationPointProvider myProvider;
|
||||
private final ParameterInfoListener[] myListeners;
|
||||
|
||||
private final Alarm myAlarm = new Alarm();
|
||||
private static final int DELAY = 200;
|
||||
@@ -129,6 +130,7 @@ public class ParameterInfoController extends UserDataHolderBase implements Visib
|
||||
myEditor = editor;
|
||||
myHandler = handler;
|
||||
myProvider = new MyBestLocationPointProvider(editor);
|
||||
myListeners = ParameterInfoListener.EP_NAME.getExtensions();
|
||||
myLbraceMarker = editor.getDocument().createRangeMarker(lbraceOffset, lbraceOffset);
|
||||
myComponent = new ParameterInfoComponent(descriptors, editor, handler, requestFocus, true);
|
||||
myHint = createHint();
|
||||
@@ -197,7 +199,7 @@ public class ParameterInfoController extends UserDataHolderBase implements Visib
|
||||
public void dispose(){
|
||||
if (myDisposed) return;
|
||||
myDisposed = true;
|
||||
myHint.hide();
|
||||
hideHint();
|
||||
myHandler.dispose(new MyDeleteParameterInfoContext());
|
||||
List<ParameterInfoController> allControllers = getAllControllers(myEditor);
|
||||
allControllers.remove(this);
|
||||
@@ -213,7 +215,7 @@ public class ParameterInfoController extends UserDataHolderBase implements Visib
|
||||
public void showHint(boolean requestFocus, boolean singleParameterInfo) {
|
||||
if (myHint.isVisible()) {
|
||||
myHint.getComponent().remove(myComponent);
|
||||
myHint.hide();
|
||||
hideHint();
|
||||
myHint = createHint();
|
||||
}
|
||||
|
||||
@@ -291,7 +293,7 @@ public class ParameterInfoController extends UserDataHolderBase implements Visib
|
||||
}
|
||||
|
||||
public void updateComponent(){
|
||||
if (!myKeepOnHintHidden && !myHint.isVisible() || myEditor instanceof EditorWindow && !((EditorWindow)myEditor).isValid()) {
|
||||
if (!myKeepOnHintHidden && !myHint.isVisible() && !ApplicationManager.getApplication().isHeadlessEnvironment() || myEditor instanceof EditorWindow && !((EditorWindow)myEditor).isValid()) {
|
||||
Disposer.dispose(this);
|
||||
return;
|
||||
}
|
||||
@@ -310,14 +312,22 @@ public class ParameterInfoController extends UserDataHolderBase implements Visib
|
||||
boolean knownParameter = (myComponent.getObjects().length == 1 || myComponent.getHighlighted() != null) &&
|
||||
myComponent.getCurrentParameterIndex() != -1;
|
||||
if (mySingleParameterInfo && !knownParameter && myHint.isVisible()) {
|
||||
myHint.hide();
|
||||
hideHint();
|
||||
}
|
||||
if (myKeepOnHintHidden && knownParameter && !myHint.isVisible()) {
|
||||
AutoPopupController.getInstance(myProject).autoPopupParameterInfo(myEditor, null);
|
||||
}
|
||||
if (!myDisposed && myHint.isVisible() && !myEditor.isDisposed() &&
|
||||
(myEditor.getComponent().getRootPane() != null || ApplicationManager.getApplication().isUnitTestMode())) {
|
||||
myComponent.update(mySingleParameterInfo);
|
||||
if (!myDisposed && (myHint.isVisible() && !myEditor.isDisposed() &&
|
||||
(myEditor.getComponent().getRootPane() != null || ApplicationManager.getApplication().isUnitTestMode()) ||
|
||||
ApplicationManager.getApplication().isHeadlessEnvironment())) {
|
||||
Model result = myComponent.update(mySingleParameterInfo);
|
||||
result.project = myProject;
|
||||
result.range = myComponent.getParameterOwner().getTextRange();
|
||||
result.editor = myEditor;
|
||||
for (ParameterInfoListener listener : myListeners) {
|
||||
listener.hintUpdated(result);
|
||||
}
|
||||
if (ApplicationManager.getApplication().isHeadlessEnvironment()) return;
|
||||
IdeTooltip tooltip = myHint.getCurrentIdeTooltip();
|
||||
short position = tooltip != null
|
||||
? toShort(tooltip.getPreferredPosition())
|
||||
@@ -329,7 +339,7 @@ public class ParameterInfoController extends UserDataHolderBase implements Visib
|
||||
}
|
||||
}
|
||||
else {
|
||||
myHint.hide();
|
||||
hideHint();
|
||||
if (!myKeepOnHintHidden) {
|
||||
Disposer.dispose(this);
|
||||
}
|
||||
@@ -499,7 +509,8 @@ public class ParameterInfoController extends UserDataHolderBase implements Visib
|
||||
VisualPosition pos,
|
||||
LightweightHint hint,
|
||||
short preferredPosition, boolean showLookupHint) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) return Pair.pair(new Point(), HintManager.DEFAULT);
|
||||
if (ApplicationManager.getApplication().isUnitTestMode() ||
|
||||
ApplicationManager.getApplication().isHeadlessEnvironment()) return Pair.pair(new Point(), HintManager.DEFAULT);
|
||||
|
||||
HintManagerImpl hintManager = HintManagerImpl.getInstanceImpl();
|
||||
Dimension hintSize = hint.getComponent().getPreferredSize();
|
||||
@@ -580,7 +591,7 @@ public class ParameterInfoController extends UserDataHolderBase implements Visib
|
||||
|
||||
@Override
|
||||
public void removeHint() {
|
||||
myHint.hide();
|
||||
hideHint();
|
||||
if (!myKeepOnHintHidden) Disposer.dispose(ParameterInfoController.this);
|
||||
}
|
||||
|
||||
@@ -659,6 +670,41 @@ public class ParameterInfoController extends UserDataHolderBase implements Visib
|
||||
}
|
||||
}
|
||||
|
||||
protected void hideHint() {
|
||||
myHint.hide();
|
||||
for (ParameterInfoListener listener : myListeners) {
|
||||
listener.hintHidden(myProject);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SignatureItem {
|
||||
public final String text;
|
||||
public final boolean deprecated;
|
||||
public final boolean disabled;
|
||||
public final List<Integer> startOffsets;
|
||||
public final List<Integer> endOffsets;
|
||||
|
||||
public SignatureItem(String text,
|
||||
boolean deprecated,
|
||||
boolean disabled,
|
||||
List<Integer> startOffsets,
|
||||
List<Integer> endOffsets) {
|
||||
this.text = text;
|
||||
this.deprecated = deprecated;
|
||||
this.disabled = disabled;
|
||||
this.startOffsets = startOffsets;
|
||||
this.endOffsets = endOffsets;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Model {
|
||||
public final List<SignatureItem> signatures = new ArrayList<>();
|
||||
public int current = -1;
|
||||
public TextRange range;
|
||||
public Editor editor;
|
||||
public Project project;
|
||||
}
|
||||
|
||||
private static class MyBestLocationPointProvider {
|
||||
private final Editor myEditor;
|
||||
private int previousOffset = -1;
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright 2000-2018 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.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.project.Project;
|
||||
|
||||
public interface ParameterInfoListener {
|
||||
ExtensionPointName<ParameterInfoListener> EP_NAME = new ExtensionPointName<>("com.intellij.codeInsight.parameterInfo.listener");
|
||||
|
||||
/**
|
||||
* This method is invoked when parameter info hint content is updated (including first time show) and there are some signatures to show
|
||||
* @param result model describing signatures shown and current context
|
||||
*/
|
||||
void hintUpdated(ParameterInfoController.Model result);
|
||||
|
||||
/**
|
||||
* This method is invoked when parameter info hint is hidden due to closing the hint, leaving parameters range area or because there are
|
||||
* no signatures to show
|
||||
* @param project for which hint was shown originally
|
||||
*/
|
||||
void hintHidden(Project project);
|
||||
}
|
||||
@@ -118,7 +118,9 @@ public class ShowParameterInfoContext implements CreateParameterInfoContext {
|
||||
|
||||
PsiDocumentManager.getInstance(project).performLaterWhenAllCommitted(() -> {
|
||||
if (editor.isDisposed() || DumbService.isDumb(project) ||
|
||||
(!ApplicationManager.getApplication().isUnitTestMode() && !editor.getComponent().isShowing())) return;
|
||||
(!ApplicationManager.getApplication().isUnitTestMode() &&
|
||||
!ApplicationManager.getApplication().isHeadlessEnvironment() &&
|
||||
!editor.getComponent().isShowing())) return;
|
||||
|
||||
final Document document = editor.getDocument();
|
||||
if (document.getTextLength() < elementStart) return;
|
||||
|
||||
@@ -620,6 +620,7 @@
|
||||
<extensionPoint name="codeInsight.parameterInfo" beanClass="com.intellij.lang.LanguageExtensionPoint">
|
||||
<with attribute="implementationClass" implements="com.intellij.lang.parameterInfo.ParameterInfoHandler"/>
|
||||
</extensionPoint>
|
||||
<extensionPoint name="codeInsight.parameterInfo.listener" interface="com.intellij.codeInsight.hint.ParameterInfoListener" />
|
||||
<extensionPoint name="codeInsight.parameterNameHints" beanClass="com.intellij.lang.LanguageExtensionPoint">
|
||||
<with attribute="implementationClass" implements="com.intellij.codeInsight.hints.InlayParameterHintsProvider"/>
|
||||
</extensionPoint>
|
||||
|
||||
Reference in New Issue
Block a user