mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-89020 Disappears value of the variables standing next in Live templates
IDEA-121634 Live Template: template is broken with 3+ variables and leading space
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 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.
|
||||
@@ -29,6 +29,7 @@ import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.impl.DocumentImpl
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings
|
||||
@@ -74,15 +75,50 @@ public class LiveTemplateTest extends LightCodeInsightFixtureTestCase {
|
||||
String group = "user";
|
||||
final Template template = manager.createTemplate(templateName, group, templateText);
|
||||
template.addVariable("ARG", "", "", false);
|
||||
final TemplateContextType contextType =
|
||||
ContainerUtil.findInstance(TemplateContextType.EP_NAME.getExtensions(), JavaCodeContextType.class);
|
||||
TemplateContextType contextType = contextType(JavaCodeContextType.class);
|
||||
((TemplateImpl)template).getTemplateContext().setEnabled(contextType, true);
|
||||
addTemplate(template, testRootDisposable)
|
||||
final Editor editor = getEditor();
|
||||
|
||||
manager.startTemplate(editor, (char)'\t');
|
||||
checkResultByText(expected);
|
||||
}
|
||||
|
||||
public void testTemplateWithSegmentsAtTheSamePosition_1() {
|
||||
doTestTemplateWithThreeVariables("", "", "", "class A { void test() { for(TestValue1TestValue2TestValue3) {} } }")
|
||||
}
|
||||
|
||||
public void testTemplateWithSegmentsAtTheSamePosition_2() {
|
||||
doTestTemplateWithThreeVariables("Def1", "Def2", "DefaultValue", "class A { void test() { for(Def1Def2DefaultValue) {} } }")
|
||||
}
|
||||
|
||||
public void testTemplateWithSegmentsAtTheSamePosition_3() {
|
||||
doTestTemplateWithThreeVariables("", "DefaultValue", "", "class A { void test() { for(TestValue1DefaultValueTestValue3) {} } }")
|
||||
}
|
||||
|
||||
private void doTestTemplateWithThreeVariables(String firstDefaultValue, String secondDefaultValue, String thirdDefaultValue,
|
||||
String expectedText) {
|
||||
configureFromFileText("dummy.java", "class A { void test() { <caret> } }")
|
||||
|
||||
TemplateManager manager = TemplateManager.getInstance(getProject())
|
||||
def templateName = "tst_template"
|
||||
def templateGroup = "user"
|
||||
final Template template = manager.createTemplate(templateName, templateGroup, 'for($TEST1$$TEST2$$TEST3$) {}')
|
||||
template.addVariable("TEST1", "", StringUtil.wrapWithDoubleQuote(firstDefaultValue), true)
|
||||
template.addVariable("TEST2", "", StringUtil.wrapWithDoubleQuote(secondDefaultValue), true)
|
||||
template.addVariable("TEST3", "", StringUtil.wrapWithDoubleQuote(thirdDefaultValue), true)
|
||||
((TemplateImpl)template).templateContext.setEnabled(contextType(JavaCodeContextType.class), true)
|
||||
addTemplate(template, testRootDisposable)
|
||||
|
||||
startTemplate(templateName, templateGroup)
|
||||
if (firstDefaultValue.empty) myFixture.type("TestValue1")
|
||||
myFixture.type("\t")
|
||||
if (secondDefaultValue.empty) myFixture.type("TestValue2")
|
||||
myFixture.type("\t")
|
||||
if (thirdDefaultValue.empty) myFixture.type("TestValue3")
|
||||
myFixture.type("\t")
|
||||
assert state == null
|
||||
checkResultByText(expectedText);
|
||||
}
|
||||
|
||||
public void testTemplateWithArg1() throws IOException {
|
||||
doTestTemplateWithArg("tst", 'wrap($ARG$)', "tst arg<caret>", "wrap(arg)");
|
||||
@@ -245,6 +281,10 @@ class Foo {
|
||||
TemplateManager.getInstance(getProject()).startTemplate(getEditor(), TemplateSettings.getInstance().getTemplate(name, group));
|
||||
}
|
||||
|
||||
private static <T extends TemplateContextType> T contextType(Class<T> clazz) {
|
||||
ContainerUtil.findInstance(TemplateContextType.EP_NAME.getExtensions(), clazz)
|
||||
}
|
||||
|
||||
private void configure() {
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
}
|
||||
@@ -549,8 +589,7 @@ class Foo {
|
||||
public void testTemplateExpandingWithSelection() {
|
||||
final TemplateManager manager = TemplateManager.getInstance(getProject());
|
||||
final Template template = manager.createTemplate("tpl", "user", 'expanded');
|
||||
final JavaStringContextType contextType =
|
||||
ContainerUtil.findInstance(TemplateContextType.EP_NAME.getExtensions(), JavaStringContextType.class);
|
||||
final JavaStringContextType contextType = contextType(JavaStringContextType.class);
|
||||
((TemplateImpl)template).getTemplateContext().setEnabled(contextType, true);
|
||||
|
||||
myFixture.configureByText("a.java", "class A { void f() { Stri<selection>ng s = \"tpl</selection><caret>\"; } }")
|
||||
@@ -750,4 +789,4 @@ class Foo {
|
||||
}
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 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.
|
||||
@@ -73,12 +73,19 @@ public class TemplateSegments {
|
||||
}
|
||||
|
||||
public void replaceSegmentAt(int index, int start, int end) {
|
||||
replaceSegmentAt(index, start, end, false);
|
||||
}
|
||||
|
||||
public void replaceSegmentAt(int index, int start, int end, boolean preserveGreediness) {
|
||||
RangeMarker rangeMarker = mySegments.get(index);
|
||||
boolean greedyToLeft = rangeMarker.isGreedyToLeft();
|
||||
boolean greedyToRight = rangeMarker.isGreedyToRight();
|
||||
rangeMarker.dispose();
|
||||
|
||||
Document doc = myEditor.getDocument();
|
||||
rangeMarker = doc.createRangeMarker(start, end);
|
||||
rangeMarker.setGreedyToLeft(true);
|
||||
rangeMarker.setGreedyToRight(true);
|
||||
rangeMarker.setGreedyToLeft(greedyToLeft || !preserveGreediness);
|
||||
rangeMarker.setGreedyToRight(greedyToRight || !preserveGreediness);
|
||||
mySegments.set(index, rangeMarker);
|
||||
}
|
||||
|
||||
|
||||
@@ -631,6 +631,8 @@ public class TemplateState implements Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
fixOverlappedSegments(myCurrentSegmentNumber);
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -682,6 +684,19 @@ public class TemplateState implements Disposable {
|
||||
});
|
||||
}
|
||||
|
||||
private void fixOverlappedSegments(int currentSegment) {
|
||||
if (currentSegment >= 0) {
|
||||
int currentSegmentStart = mySegments.getSegmentStart(currentSegment);
|
||||
int currentSegmentEnd = mySegments.getSegmentEnd(currentSegment);
|
||||
for (int i = currentSegment + 1; i < mySegments.getSegmentsCount(); i++) {
|
||||
final int startOffset = mySegments.getSegmentStart(i);
|
||||
if (currentSegmentStart <= startOffset && startOffset < currentSegmentEnd) {
|
||||
mySegments.replaceSegmentAt(i, currentSegmentEnd, Math.max(mySegments.getSegmentEnd(i), currentSegmentEnd), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getVariableValueText(String variableName) {
|
||||
TextResult value = getVariableValue(variableName);
|
||||
@@ -726,18 +741,13 @@ public class TemplateState implements Disposable {
|
||||
String oldText = myDocument.getCharsSequence().subSequence(start, end).toString();
|
||||
|
||||
if (!oldText.equals(newValue)) {
|
||||
int segmentNumberWithTheSameStart = mySegments.getSegmentWithTheSameStart(segmentNumber, start);
|
||||
mySegments.setNeighboursGreedy(segmentNumber, false);
|
||||
myDocument.replaceString(start, end, newValue);
|
||||
int newEnd = start + newValue.length();
|
||||
mySegments.replaceSegmentAt(segmentNumber, start, newEnd);
|
||||
mySegments.setNeighboursGreedy(segmentNumber, true);
|
||||
|
||||
if (segmentNumberWithTheSameStart != -1) {
|
||||
mySegments.replaceSegmentAt(segmentNumberWithTheSameStart, newEnd,
|
||||
newEnd + mySegments.getSegmentEnd(segmentNumberWithTheSameStart) -
|
||||
mySegments.getSegmentStart(segmentNumberWithTheSameStart));
|
||||
}
|
||||
fixOverlappedSegments(segmentNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -998,10 +1008,7 @@ public class TemplateState implements Disposable {
|
||||
if (e instanceof MacroCallNode) {
|
||||
marker = ((MacroCallNode)e).getMacro().getDefaultValue();
|
||||
}
|
||||
int start = mySegments.getSegmentStart(i);
|
||||
int end = start + marker.length();
|
||||
myDocument.insertString(start, marker);
|
||||
mySegments.replaceSegmentAt(i, start, end);
|
||||
replaceString(marker, mySegments.getSegmentStart(i), mySegments.getSegmentEnd(i), i);
|
||||
indices.add(i);
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user