package com.intellij.codeInsight.template.zencoding;
import com.intellij.codeInsight.template.CustomTemplateCallback;
-import com.intellij.codeInsight.template.TemplateInvokationListener;
import com.intellij.codeInsight.template.impl.TemplateImpl;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.application.ApplicationManager;
private static final String NUMBER_IN_ITERATION_PLACE_HOLDER = "$";
private final List<Token> myTokens;
- private final int myFromIndex;
private final CustomTemplateCallback myCallback;
- private final TemplateInvokationListener myListener;
private final String mySurroundedText;
private State myState;
private XmlZenCodingInterpreter(List<Token> tokens,
- int fromIndex,
CustomTemplateCallback callback,
State initialState,
- String surroundedText,
- TemplateInvokationListener listener) {
+ String surroundedText) {
myTokens = tokens;
- myFromIndex = fromIndex;
myCallback = callback;
mySurroundedText = surroundedText;
- myListener = listener;
myState = initialState;
}
- private void finish(boolean inSeparateEvent) {
+ private void finish() {
myCallback.gotoEndOffset();
- if (myListener != null) {
- myListener.finished(inSeparateEvent);
- }
}
private void gotoChild(Object templateBoundsKey) {
// returns if expanding finished
- public static boolean interpret(List<Token> tokens,
- int startIndex,
- CustomTemplateCallback callback,
- State initialState,
- String surroundedText,
- TemplateInvokationListener listener) {
+ public static void interpret(List<Token> tokens,
+ int startIndex,
+ CustomTemplateCallback callback,
+ State initialState,
+ String surroundedText) {
XmlZenCodingInterpreter interpreter =
- new XmlZenCodingInterpreter(tokens, startIndex, callback, initialState, surroundedText, listener);
- return interpreter.invoke(startIndex);
+ new XmlZenCodingInterpreter(tokens, callback, initialState, surroundedText);
+ interpreter.invoke(startIndex);
}
- private boolean invoke(int startIndex) {
+ private void invoke(int startIndex) {
final int n = myTokens.size();
TemplateToken templateToken = null;
int number = -1;
for (int i = startIndex; i < n; i++) {
- final int finalI = i;
Token token = myTokens.get(i);
switch (myState) {
case OPERATION:
if (sign == '+' || (mySurroundedText == null && sign == XmlZenCodingTemplate.MARKER)) {
final Object key = new Object();
myCallback.fixStartOfTemplate(key);
- TemplateInvokationListener listener = new TemplateInvokationListener() {
- public void finished(boolean inSeparateEvent) {
- myState = State.WORD;
- if (myCallback.getOffset() != myCallback.getEndOfTemplate(key)) {
- myCallback.fixEndOffset();
- }
- if (sign == '+') {
- myCallback.gotoEndOfTemplate(key);
- }
- if (inSeparateEvent) {
- invoke(finalI + 1);
- }
- }
- };
- if (!invokeTemplate(templateToken, myCallback, listener, 0)) {
- return false;
+ invokeTemplate(templateToken, myCallback, 0);
+ myState = State.WORD;
+ if (myCallback.getOffset() != myCallback.getEndOfTemplate(key)) {
+ myCallback.fixEndOffset();
+ }
+ if (sign == '+') {
+ myCallback.gotoEndOfTemplate(key);
}
templateToken = null;
}
else if (sign == '>' || (mySurroundedText != null && sign == XmlZenCodingTemplate.MARKER)) {
- if (!startTemplateAndGotoChild(templateToken, finalI)) {
- return false;
- }
+ startTemplateAndGotoChild(templateToken);
templateToken = null;
}
else if (sign == '*') {
if (token instanceof MarkerToken || token instanceof OperationToken) {
char sign = token instanceof OperationToken ? ((OperationToken)token).mySign : XmlZenCodingTemplate.MARKER;
if (sign == '+' || (mySurroundedText == null && sign == XmlZenCodingTemplate.MARKER)) {
- if (!invokeTemplateSeveralTimes(templateToken, 0, number, finalI)) {
- return false;
- }
+ invokeTemplateSeveralTimes(templateToken, 0, number);
templateToken = null;
}
else if (number > 1) {
- return invokeTemplateAndProcessTail(templateToken, 0, number, i + 1, startIndex != myFromIndex);
+ invokeTemplateAndProcessTail(templateToken, 0, number, i + 1);
+ return;
}
else {
assert number == 1;
- if (!startTemplateAndGotoChild(templateToken, finalI)) {
- return false;
- }
+ startTemplateAndGotoChild(templateToken);
templateToken = null;
}
myState = State.WORD;
if (mySurroundedText != null) {
insertText(myCallback, mySurroundedText);
}
- finish(startIndex != myFromIndex);
- return true;
+ finish();
}
- private boolean startTemplateAndGotoChild(TemplateToken templateToken, final int index) {
+ private void startTemplateAndGotoChild(TemplateToken templateToken) {
final Object key = new Object();
myCallback.fixStartOfTemplate(key);
- TemplateInvokationListener listener = new TemplateInvokationListener() {
- public void finished(boolean inSeparateEvent) {
- myState = State.WORD;
- gotoChild(key);
- if (inSeparateEvent) {
- invoke(index + 1);
- }
- }
- };
- if (!invokeTemplate(templateToken, myCallback, listener, 0)) {
- return false;
- }
- return true;
+ invokeTemplate(templateToken, myCallback, 0);
+ myState = State.WORD;
+ gotoChild(key);
}
- private boolean invokeTemplateSeveralTimes(final TemplateToken templateToken,
- final int startIndex,
- final int count,
- final int globalIndex) {
+ private void invokeTemplateSeveralTimes(final TemplateToken templateToken,
+ final int startIndex,
+ final int count) {
final Object key = new Object();
myCallback.fixStartOfTemplate(key);
for (int i = startIndex; i < count; i++) {
- final int finalI = i;
- TemplateInvokationListener listener = new TemplateInvokationListener() {
- public void finished(boolean inSeparateEvent) {
- myState = State.WORD;
- if (myCallback.getOffset() != myCallback.getEndOfTemplate(key)) {
- myCallback.fixEndOffset();
- }
- myCallback.gotoEndOfTemplate(key);
- if (inSeparateEvent) {
- if (finalI + 1 < count) {
- invokeTemplateSeveralTimes(templateToken, finalI + 1, count, globalIndex);
- }
- else {
- invoke(globalIndex + 1);
- }
- }
- }
- };
- if (!invokeTemplate(templateToken, myCallback, listener, i)) {
- return false;
+ invokeTemplate(templateToken, myCallback, i);
+ myState = State.WORD;
+ if (myCallback.getOffset() != myCallback.getEndOfTemplate(key)) {
+ myCallback.fixEndOffset();
}
+ myCallback.gotoEndOfTemplate(key);
}
- return true;
}
private static void insertText(CustomTemplateCallback callback, String text) {
callback.insertString(offset, text);
}
- private boolean invokeTemplateAndProcessTail(final TemplateToken templateToken,
- final int startIndex,
- final int count,
- final int tailStart,
- boolean separateEvent) {
+ private void invokeTemplateAndProcessTail(final TemplateToken templateToken,
+ final int startIndex,
+ final int count,
+ final int tailStart) {
final Object key = new Object();
myCallback.fixStartOfTemplate(key);
for (int i = startIndex; i < count; i++) {
- final int finalI = i;
- final boolean[] flag = new boolean[]{false};
- TemplateInvokationListener listener = new TemplateInvokationListener() {
- public void finished(boolean inSeparateEvent) {
- gotoChild(key);
- if (interpret(myTokens, tailStart, myCallback, State.WORD, mySurroundedText, new TemplateInvokationListener() {
- public void finished(boolean inSeparateEvent) {
- if (myCallback.getOffset() != myCallback.getEndOfTemplate(key)) {
- myCallback.fixEndOffset();
- }
- myCallback.gotoEndOfTemplate(key);
- if (inSeparateEvent) {
- invokeTemplateAndProcessTail(templateToken, finalI + 1, count, tailStart, true);
- }
- }
- })) {
- if (inSeparateEvent) {
- invokeTemplateAndProcessTail(templateToken, finalI + 1, count, tailStart, true);
- }
- }
- else {
- flag[0] = true;
- }
- }
- };
- if (!invokeTemplate(templateToken, myCallback, listener, i) || flag[0]) {
- return false;
+ invokeTemplate(templateToken, myCallback, i);
+ gotoChild(key);
+ interpret(myTokens, tailStart, myCallback, State.WORD, mySurroundedText);
+ if (myCallback.getOffset() != myCallback.getEndOfTemplate(key)) {
+ myCallback.fixEndOffset();
}
+ myCallback.gotoEndOfTemplate(key);
}
- finish(separateEvent);
- return true;
+ finish();
}
private static boolean containsAttrsVar(TemplateImpl template) {
return null;
}
- private static boolean invokeTemplate(TemplateToken token,
- final CustomTemplateCallback callback,
- final TemplateInvokationListener listener,
- int numberInIteration) {
+ private static void invokeTemplate(TemplateToken token,
+ final CustomTemplateCallback callback,
+ int numberInIteration) {
List<Pair<String, String>> attr2value = new ArrayList<Pair<String, String>>(token.myAttribute2Value);
if (callback.isLiveTemplateApplicable(token.myKey)) {
- return invokeExistingLiveTemplate(token, callback, listener, numberInIteration, attr2value);
+ invokeExistingLiveTemplate(token, callback, numberInIteration, attr2value);
}
else {
TemplateImpl template = new TemplateImpl("", "");
}
template.setToReformat(true);
Map<String, String> predefinedValues = buildPredefinedValues(attr2value, numberInIteration);
- return callback.startTemplate(template, predefinedValues, listener);
+ callback.startTemplate(template, predefinedValues);
}
}
- private static boolean invokeExistingLiveTemplate(TemplateToken token,
- CustomTemplateCallback callback,
- TemplateInvokationListener listener,
- int numberInIteration,
- List<Pair<String, String>> attr2value) {
+ private static void invokeExistingLiveTemplate(TemplateToken token,
+ CustomTemplateCallback callback,
+ int numberInIteration,
+ List<Pair<String, String>> attr2value) {
if (token.myTemplate != null) {
if (attr2value.size() > 0 || XmlZenCodingTemplate.isTrueXml(callback)) {
TemplateImpl modifiedTemplate = token.myTemplate.copy();
modifiedTemplate.setString(text);
removeVariablesWhichHasNoSegment(modifiedTemplate);
Map<String, String> predefinedValues = buildPredefinedValues(attr2value, numberInIteration);
- return callback.startTemplate(modifiedTemplate, predefinedValues, listener);
+ callback.startTemplate(modifiedTemplate, predefinedValues);
+ return;
}
}
- return callback.startTemplate(token.myTemplate, null, listener);
+ callback.startTemplate(token.myTemplate, null);
}
else {
Map<String, String> predefinedValues = buildPredefinedValues(attr2value, numberInIteration);
- return callback.startTemplate(token.myKey, predefinedValues, listener);
+ callback.startTemplate(token.myKey, predefinedValues);
}
}
return false;
}
- public void expand(String key, @NotNull CustomTemplateCallback callback, @Nullable TemplateInvokationListener listener) {
- expand(key, callback, null, listener);
+ public void expand(String key, @NotNull CustomTemplateCallback callback) {
+ expand(key, callback, null);
}
private static void expand(String key,
@NotNull CustomTemplateCallback callback,
- String surroundedText,
- @Nullable TemplateInvokationListener listener) {
+ String surroundedText) {
List<Token> tokens = parse(key, callback);
assert tokens != null;
- XmlZenCodingInterpreter.interpret(tokens, 0, callback, State.WORD, surroundedText, listener);
+ XmlZenCodingInterpreter.interpret(tokens, 0, callback, State.WORD, surroundedText);
}
public void wrap(final String selection,
EditorModificationUtil.deleteSelectedText(callback.getEditor());
PsiDocumentManager.getInstance(callback.getProject()).commitAllDocuments();
callback.fixInitialState();
- expand(abbreviation, callback, selection, listener);
+ expand(abbreviation, callback, selection);
+ if (listener != null) {
+ listener.finished();
+ }
}
}, CodeInsightBundle.message("insert.code.template.command"), null);
}
int caretAt = editor.getCaretModel().getOffset();
if (isApplicable(file, caretAt)) {
final CustomTemplateCallback callback = new CustomTemplateCallback(editor, file);
- TemplateInvokationListener listener = new TemplateInvokationListener() {
- public void finished(boolean inSeparateEvent) {
- callback.finish();
- }
- };
if (abbreviation != null) {
String selection = callback.getEditor().getSelectionModel().getSelectedText();
assert selection != null;
selection = selection.trim();
- doWrap(selection, abbreviation, callback, listener);
+ doWrap(selection, abbreviation, callback, new TemplateInvokationListener() {
+ public void finished() {
+ callback.finish();
+ }
+ });
}
else {
XmlZenCodingTemplate template = new XmlZenCodingTemplate();
if (key != null) {
int offsetBeforeKey = caretAt - key.length();
callback.getEditor().getDocument().deleteString(offsetBeforeKey, caretAt);
- template.expand(key, callback, listener);
+ template.expand(key, callback);
+ callback.finish();
return true;
}
// if it is simple live template invokation, we should start it using TemplateManager because template may be ambiguous