mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
emmet + live templates in tooltip preview: insert variables
- insert default variable value or variable name, so that preview text make sense (and be highlighted correctly) - test for the case emmet + vue related to WEB-29541
This commit is contained in:
@@ -19,13 +19,17 @@ import com.intellij.codeInsight.template.impl.TemplateImpl;
|
||||
import com.intellij.codeInsight.template.impl.Variable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
@@ -63,6 +67,23 @@ public class LiveTemplateBuilder {
|
||||
return myText;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getTextForPreview() {
|
||||
if (myVariables.isEmpty()) return myText.toString();
|
||||
final StringBuilder sb = new StringBuilder(myText);
|
||||
final Ref<Integer> offset = new Ref<>(0);
|
||||
final Map<String, Variable> map = myVariables.stream().collect(Collectors.toMap(Variable::getName, Function.identity()));
|
||||
myVariableOccurrences.forEach(vo -> {
|
||||
final Variable variable = map.get(vo.myName);
|
||||
if (variable == null) return;
|
||||
String varReplacement = StringUtil.unquoteString(variable.getDefaultValueString());
|
||||
varReplacement = StringUtil.isEmptyOrSpaces(varReplacement) ? vo.myName : varReplacement;
|
||||
sb.replace(vo.myOffset + offset.get(), vo.myOffset + offset.get(), varReplacement);
|
||||
offset.set(offset.get() + varReplacement.length());
|
||||
});
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static boolean isEndVariable(@NotNull String name) {
|
||||
return name.startsWith(END_PREFIX);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import com.intellij.ui.LightweightHint;
|
||||
import com.intellij.ui.components.JBPanel;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.DocumentUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.Producer;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -53,13 +54,16 @@ public class EmmetPreviewHint extends LightweightHint implements Disposable {
|
||||
@NotNull private final Editor myParentEditor;
|
||||
@NotNull private final Editor myEditor;
|
||||
@NotNull private final Alarm myAlarm = new Alarm(this);
|
||||
private boolean isDisposed = false;
|
||||
private volatile boolean isDisposed = false;
|
||||
|
||||
private EmmetPreviewHint(@NotNull JBPanel panel, @NotNull Editor editor, @NotNull Editor parentEditor) {
|
||||
super(panel);
|
||||
myParentEditor = parentEditor;
|
||||
myEditor = editor;
|
||||
|
||||
final Disposable parentDisposable = ObjectUtils.coalesce(ObjectUtils.tryCast(parentEditor, Disposable.class), parentEditor.getProject());
|
||||
Disposer.register(parentDisposable, this);
|
||||
|
||||
final Editor topLevelEditor = InjectedLanguageUtil.getTopLevelEditor(myParentEditor);
|
||||
EditorFactory.getInstance().addEditorFactoryListener(new EditorFactoryAdapter() {
|
||||
@Override
|
||||
@@ -199,6 +203,7 @@ public class EmmetPreviewHint extends LightweightHint implements Disposable {
|
||||
public void dispose() {
|
||||
isDisposed = true;
|
||||
myAlarm.cancelAllRequests();
|
||||
super.hide();
|
||||
EmmetPreviewHint existingBalloon = myParentEditor.getUserData(KEY);
|
||||
if (existingBalloon == this) {
|
||||
myParentEditor.putUserData(KEY, null);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.template.emmet;
|
||||
|
||||
import com.intellij.codeInsight.template.LiveTemplateBuilder;
|
||||
import com.intellij.codeInsight.template.emmet.generators.XmlZenCodingGenerator;
|
||||
import com.intellij.codeInsight.template.emmet.generators.ZenCodingGenerator;
|
||||
import com.intellij.codeInsight.template.impl.TemplateImpl;
|
||||
@@ -26,6 +27,7 @@ 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.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
@@ -51,12 +53,11 @@ public class EmmetPreviewUtil {
|
||||
final String templatePrefix = new ZenCodingTemplate().computeTemplateKeyWithoutContextChecking(callback);
|
||||
if (templatePrefix != null) {
|
||||
try {
|
||||
ZenCodingTemplate.expand(templatePrefix, callback, generator, Collections.emptyList(),
|
||||
expandPrimitiveAbbreviations, 0);
|
||||
TemplateImpl template = callback.getGeneratedTemplate();
|
||||
String templateText = template != null ? template.getTemplateText() : null;
|
||||
if (!StringUtil.isEmpty(templateText)) {
|
||||
return template.isToReformat() ? reformatTemplateText(file, templateText) : templateText;
|
||||
final int limit = Registry.intValue("emmet.segments.limit");
|
||||
ZenCodingTemplate.expand(templatePrefix, callback, generator, Collections.emptyList(), expandPrimitiveAbbreviations, limit);
|
||||
final TemplateImpl template = callback.getGeneratedTemplate();
|
||||
if (template != null) {
|
||||
return getFormattedText(template, file, limit);
|
||||
}
|
||||
}
|
||||
catch (EmmetException e) {
|
||||
@@ -68,6 +69,22 @@ public class EmmetPreviewUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getFormattedText(@NotNull final TemplateImpl template, @NotNull final PsiFile file, int limit) {
|
||||
final String templateText;
|
||||
if (template.getVariableCount() > 0 && template.getVariableCount() < limit/2) {
|
||||
final LiveTemplateBuilder builder = new LiveTemplateBuilder(false, limit);
|
||||
builder.insertTemplate(0, template, Collections.emptyMap());
|
||||
templateText = builder.getTextForPreview();
|
||||
} else {
|
||||
templateText = template.getTemplateText();
|
||||
}
|
||||
if (!StringUtil.isEmpty(templateText)) {
|
||||
return template.isToReformat() ? reformatTemplateText(file, templateText) : templateText;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void addEmmetPreviewListeners(@NotNull final Editor editor,
|
||||
@NotNull final PsiFile file,
|
||||
final boolean expandPrimitiveAbbreviations) {
|
||||
|
||||
Reference in New Issue
Block a user