mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Preview in the editor of the approximate insertion result of the currently selected lookup suggestion
This commit is contained in:
@@ -105,6 +105,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
|
||||
|
||||
private final List<LookupListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
|
||||
private PrefixChangeListener myPrefixChangeListener = new PrefixChangeListener.Adapter() {};
|
||||
private final LookupPreview myPreview = new LookupPreview(this);
|
||||
|
||||
private long myStampShown = 0;
|
||||
private boolean myShown = false;
|
||||
@@ -853,6 +854,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
|
||||
listener.currentItemChanged(event);
|
||||
}
|
||||
}
|
||||
myPreview.updatePreview(currentItem);
|
||||
}
|
||||
|
||||
public boolean fillInCommonPrefix(boolean explicitlyInvoked) {
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.lookup.impl;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementPresentation;
|
||||
import com.intellij.openapi.editor.*;
|
||||
import com.intellij.openapi.editor.colors.EditorColors;
|
||||
import com.intellij.openapi.editor.colors.EditorFontType;
|
||||
import com.intellij.openapi.editor.impl.EditorImpl;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.FList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
class LookupPreview {
|
||||
private final List<Inlay> myInlays = new ArrayList<>();
|
||||
private final LookupImpl myLookup;
|
||||
|
||||
LookupPreview(LookupImpl lookup) {
|
||||
myLookup = lookup;
|
||||
}
|
||||
|
||||
void updatePreview(@Nullable LookupElement item) {
|
||||
if (!Registry.is("ide.lookup.preview.insertion")) return;
|
||||
|
||||
myInlays.forEach(Disposer::dispose);
|
||||
myInlays.clear();
|
||||
|
||||
String suffix = getSuffixText(item);
|
||||
if (!suffix.isEmpty() && myLookup.getTopLevelEditor() instanceof EditorImpl) {
|
||||
myLookup.getTopLevelEditor().getCaretModel().runForEachCaret(caret -> {
|
||||
ensureCaretBeforeInlays(caret);
|
||||
addInlay(suffix, caret.getOffset());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static void ensureCaretBeforeInlays(Caret caret) {
|
||||
LogicalPosition position = caret.getLogicalPosition();
|
||||
if (position.leansForward) {
|
||||
caret.moveToLogicalPosition(position.leanForward(false));
|
||||
}
|
||||
}
|
||||
|
||||
private String getSuffixText(@Nullable LookupElement item) {
|
||||
if (item != null) {
|
||||
String itemText = StringUtil.notNullize(LookupElementPresentation.renderElement(item).getItemText());
|
||||
FList<TextRange> fragments = LookupCellRenderer.getMatchingFragments(myLookup.itemPattern(item), itemText);
|
||||
if (fragments != null && !fragments.isEmpty()) {
|
||||
List<TextRange> list = ContainerUtil.newArrayList(fragments);
|
||||
return itemText.substring(list.get(list.size() - 1).getEndOffset(), itemText.length());
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private void addInlay(String suffix, int caretOffset) {
|
||||
Inlay inlay = myLookup.getTopLevelEditor().getInlayModel().addInlineElement(caretOffset, createGrayRenderer(suffix));
|
||||
if (inlay != null) {
|
||||
myInlays.add(inlay);
|
||||
Disposer.register(myLookup, inlay);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static EditorCustomElementRenderer createGrayRenderer(final String suffix) {
|
||||
return new EditorCustomElementRenderer() {
|
||||
@Override
|
||||
public int calcWidthInPixels(@NotNull Editor editor) {
|
||||
return editor.getContentComponent().getFontMetrics(getFont(editor)).stringWidth(suffix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(@NotNull Editor editor, @NotNull Graphics g, @NotNull Rectangle r) {
|
||||
g.setColor(editor.getColorsScheme().getColor(EditorColors.CARET_ROW_COLOR));
|
||||
g.fillRect(r.x, r.y, r.width, r.height);
|
||||
g.setColor(JBColor.GRAY);
|
||||
g.setFont(getFont(editor));
|
||||
g.drawString(suffix, r.x, r.y + ((EditorImpl)editor).getAscent());
|
||||
}
|
||||
|
||||
private Font getFont(@NotNull Editor editor) {
|
||||
return editor.getColorsScheme().getFont(EditorFontType.PLAIN);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -381,6 +381,9 @@ ide.completion.show.lower.case.classes.description=Show non-imported classes sta
|
||||
ide.completion.delay.autopopup.until.completed=false
|
||||
ide.completion.delay.autopopup.until.completed.description=Controls if completion autopopup is shown immediately and populated in background, or delayed until all suggestion are calculated
|
||||
|
||||
ide.lookup.preview.insertion=false
|
||||
ide.lookup.preview.insertion.description=Preview in the editor of the approximate insertion result of the currently selected lookup suggestion
|
||||
|
||||
ide.completion.middle.matching=true
|
||||
ide.completion.middle.matching.description=Suggest items in completion that contain the entered string somewhere in the middle.
|
||||
|
||||
@@ -888,4 +891,4 @@ ide.projectView.globalOptions.description=Make Project View options such as auto
|
||||
|
||||
compiler.ref.index=false
|
||||
compiler.ref.index.description=Enables find usages using references from compiler indices
|
||||
compiler.ref.index.restartRequired=true
|
||||
compiler.ref.index.restartRequired=true
|
||||
|
||||
Reference in New Issue
Block a user