mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git@git.labs.intellij.net:idea/community
This commit is contained in:
+1
-1
@@ -65,7 +65,7 @@ public class CreateConstructorFromCallFix extends CreateFromUsageBaseFix {
|
||||
editor.getCaretModel().moveToOffset(textRange.getStartOffset());
|
||||
|
||||
startTemplate(editor, template, project, new TemplateEditingAdapter() {
|
||||
public void templateFinished(Template template) {
|
||||
public void templateFinished(Template template, boolean brokenOff) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
|
||||
+1
-1
@@ -108,7 +108,7 @@ public abstract class CreateConstructorFromThisOrSuperFix extends CreateFromUsag
|
||||
editor.getCaretModel().moveToOffset(textRange.getStartOffset());
|
||||
|
||||
startTemplate(editor, template, project, new TemplateEditingAdapter() {
|
||||
public void templateFinished(Template template) {
|
||||
public void templateFinished(Template template, boolean brokenOff) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
|
||||
+1
-1
@@ -166,7 +166,7 @@ public class CreateLocalVarFromInstanceofAction extends BaseIntentionAction {
|
||||
newEditor.getDocument().deleteString(range.getStartOffset(), range.getEndOffset());
|
||||
|
||||
CreateFromUsageBaseFix.startTemplate(newEditor, template, project, new TemplateEditingAdapter() {
|
||||
public void templateFinished(Template template) {
|
||||
public void templateFinished(Template template, boolean brokenOff) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
|
||||
|
||||
+1
-1
@@ -231,7 +231,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
|
||||
|
||||
if (!shouldBeAbstract) {
|
||||
startTemplate(newEditor, template, project, new TemplateEditingAdapter() {
|
||||
public void templateFinished(Template template) {
|
||||
public void templateFinished(Template template, boolean brokenOff) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
PsiDocumentManager.getInstance(project).commitDocument(newEditor.getDocument());
|
||||
|
||||
+1
-1
@@ -145,7 +145,7 @@ public abstract class GenerateMembersHandlerBase implements CodeInsightActionHan
|
||||
editor.getCaretModel().moveToOffset(offset);
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.CENTER);
|
||||
TemplateManager.getInstance(myProject).startTemplate(editor, template, new TemplateEditingAdapter() {
|
||||
public void templateFinished(Template template) {
|
||||
public void templateFinished(Template template, boolean brokenOff) {
|
||||
if (index + 1 < templates.size()){
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
|
||||
@@ -141,7 +141,7 @@ public class TestIntegrationUtils {
|
||||
if (!automatic) {
|
||||
adapter = new TemplateEditingAdapter() {
|
||||
@Override
|
||||
public void templateFinished(Template template) {
|
||||
public void templateFinished(Template template, boolean brokenOff) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
|
||||
|
||||
@@ -153,6 +153,7 @@ public class ReformatCodeAction extends AnAction implements DumbAware {
|
||||
else {
|
||||
new ReformatCodeProcessor(project, dir, dialog.isIncludeSubdirectories()).run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ public abstract class TemplateInsertHandler implements InsertHandler {
|
||||
final RangeMarker offsetRangeMarker = document.createRangeMarker(templateStartOffset, templateStartOffset);
|
||||
|
||||
TemplateManager.getInstance(editor.getProject()).startTemplate(editor, template, new TemplateEditingAdapter() {
|
||||
public void templateFinished(Template template) {
|
||||
public void templateFinished(Template template, boolean brokenOff) {
|
||||
lookupItem.setAttribute(EXPANDED_TEMPLATE_ATTR, Boolean.TRUE);
|
||||
|
||||
if (!offsetRangeMarker.isValid()) return;
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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.template;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public interface CustomLiveTemplate {
|
||||
ExtensionPointName<CustomLiveTemplate> EP_NAME = ExtensionPointName.create("com.intellij.customLiveTemplate");
|
||||
|
||||
boolean isApplicable(@NotNull String key, @NotNull CustomTemplateCallback callback);
|
||||
|
||||
void execute(@NotNull String key, @NotNull CustomTemplateCallback callback, @Nullable TemplateInvokationListener listener);
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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.template;
|
||||
|
||||
import com.intellij.codeInsight.template.impl.TemplateImpl;
|
||||
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
|
||||
import com.intellij.codeInsight.template.impl.TemplateSettings;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public class CustomTemplateCallback {
|
||||
private final TemplateManager myTemplateManager;
|
||||
private final Editor myEditor;
|
||||
private final PsiFile myFile;
|
||||
private int myStartOffset;
|
||||
private int myStartLength;
|
||||
private Project myProject;
|
||||
|
||||
public CustomTemplateCallback(Editor editor, PsiFile file) {
|
||||
myEditor = editor;
|
||||
myFile = file;
|
||||
myProject = file.getProject();
|
||||
myTemplateManager = TemplateManagerImpl.getInstance(myProject);
|
||||
}
|
||||
|
||||
public void fixInitialEditorState() {
|
||||
myStartOffset = myEditor.getCaretModel().getOffset();
|
||||
myStartLength = myEditor.getDocument().getCharsSequence().length();
|
||||
}
|
||||
|
||||
public boolean isLiveTemplateApplicable(@NotNull String key) {
|
||||
List<TemplateImpl> templates = getMatchingTemplates(key);
|
||||
templates = TemplateManagerImpl.filterApplicableCandidates(myFile, myStartOffset, templates);
|
||||
return templates.size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @param listener
|
||||
* @return returns if template invokation is finished
|
||||
*/
|
||||
public boolean startTemplate(@NotNull String key, @Nullable TemplateInvokationListener listener) {
|
||||
int caretOffset = myEditor.getCaretModel().getOffset();
|
||||
List<TemplateImpl> templates = getMatchingTemplates(key);
|
||||
templates = TemplateManagerImpl.filterApplicableCandidates(myFile, caretOffset, templates);
|
||||
if (templates.size() == 1) {
|
||||
TemplateImpl template = templates.get(0);
|
||||
return startTemplate(template, listener);
|
||||
}
|
||||
else if (listener != null) {
|
||||
listener.finished(false, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param template
|
||||
* @param listener
|
||||
* @return returns if template invokation is finished
|
||||
*/
|
||||
public boolean startTemplate(@NotNull Template template, @Nullable final TemplateInvokationListener listener) {
|
||||
final boolean[] templateEnded = new boolean[]{false};
|
||||
final boolean[] templateFinished = new boolean[]{false};
|
||||
myTemplateManager.startTemplate(myEditor, template, new TemplateEditingAdapter() {
|
||||
|
||||
@Override
|
||||
public void templateExpanded(Template template) {
|
||||
int lengthAfter = myEditor.getDocument().getCharsSequence().length();
|
||||
CodeStyleManager style = CodeStyleManager.getInstance(myProject);
|
||||
style.reformatText(myFile, myStartOffset, myStartOffset + lengthAfter - myStartLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void templateFinished(Template template, boolean brokenOff) {
|
||||
if (brokenOff) return;
|
||||
templateFinished[0] = true;
|
||||
if (templateEnded[0] && listener != null) {
|
||||
listener.finished(true, true);
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
templateEnded[0] = true;
|
||||
if (templateFinished[0] && listener != null) {
|
||||
listener.finished(false, true);
|
||||
}
|
||||
return templateFinished[0];
|
||||
}
|
||||
|
||||
private static List<TemplateImpl> getMatchingTemplates(@NotNull String templateKey) {
|
||||
TemplateSettings settings = TemplateSettings.getInstance();
|
||||
return settings.collectMatchingCandidates(templateKey, settings.getDefaultShortcutChar(), false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Editor getEditor() {
|
||||
return myEditor;
|
||||
}
|
||||
|
||||
public PsiFile getFile() {
|
||||
return myFile;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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.template;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public abstract class Iteration {
|
||||
protected final int myMaxIndex;
|
||||
protected int myIndex;
|
||||
private final Iteration myParentIteration;
|
||||
|
||||
public Iteration(int index, int maxIndex, Iteration parentIteration) {
|
||||
myIndex = index;
|
||||
myMaxIndex = maxIndex;
|
||||
myParentIteration = parentIteration;
|
||||
}
|
||||
|
||||
protected void next() {
|
||||
myIndex++;
|
||||
if (myIndex < myMaxIndex) {
|
||||
iter();
|
||||
}
|
||||
else if (myIndex == myMaxIndex && myParentIteration != null) {
|
||||
myParentIteration.next();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return myIndex >= myMaxIndex;
|
||||
}
|
||||
|
||||
// returns if next() is going to be invoked
|
||||
protected abstract void iter();
|
||||
}
|
||||
+4
-1
@@ -26,7 +26,7 @@ public abstract class TemplateEditingAdapter implements TemplateEditingListener
|
||||
public void beforeTemplateFinished(final TemplateState state, final Template template) {
|
||||
}
|
||||
|
||||
public void templateFinished(Template template) {
|
||||
public void templateFinished(Template template, boolean brokenOff) {
|
||||
}
|
||||
|
||||
public void templateCancelled(Template template) {
|
||||
@@ -34,4 +34,7 @@ public abstract class TemplateEditingAdapter implements TemplateEditingListener
|
||||
|
||||
public void currentVariableChanged(TemplateState templateState, Template template, int oldIndex, int newIndex) {
|
||||
}
|
||||
|
||||
public void templateExpanded(Template template) {
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -23,7 +23,8 @@ import com.intellij.codeInsight.template.impl.TemplateState;
|
||||
*/
|
||||
public interface TemplateEditingListener {
|
||||
void beforeTemplateFinished(TemplateState state, Template template);
|
||||
void templateFinished(Template template);
|
||||
void templateFinished(Template template, boolean brokenOff);
|
||||
void templateCancelled(Template template);
|
||||
void currentVariableChanged(TemplateState templateState, Template template, int oldIndex, int newIndex);
|
||||
void templateExpanded(Template template);
|
||||
}
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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.template;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public interface TemplateInvokationListener {
|
||||
void finished(boolean inSeparateEvent, boolean success);
|
||||
}
|
||||
@@ -1,19 +1,18 @@
|
||||
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
* Copyright 2000-2009 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.template;
|
||||
|
||||
@@ -36,8 +35,15 @@ public abstract class TemplateManager {
|
||||
|
||||
public abstract void startTemplate(@NotNull Editor editor, @NotNull Template template, TemplateEditingListener listener);
|
||||
|
||||
public abstract void startTemplate(@NotNull Editor editor, @NotNull Template template, TemplateEditingListener listener,
|
||||
final PairProcessor<String, String> callback);
|
||||
public abstract void startTemplate(@NotNull final Editor editor,
|
||||
@NotNull final Template template,
|
||||
TemplateEditingListener listener,
|
||||
boolean inSeparateCommand);
|
||||
|
||||
public abstract void startTemplate(@NotNull Editor editor,
|
||||
@NotNull Template template,
|
||||
TemplateEditingListener listener,
|
||||
final PairProcessor<String, String> callback);
|
||||
|
||||
public abstract boolean startTemplate(@NotNull Editor editor, char shortcutChar);
|
||||
|
||||
|
||||
+63
-15
@@ -132,21 +132,22 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
|
||||
}
|
||||
|
||||
public void startTemplate(@NotNull Editor editor, String selectionString, @NotNull Template template) {
|
||||
startTemplate(editor, selectionString, template, null, null);
|
||||
startTemplate(editor, selectionString, template, null, null, true);
|
||||
}
|
||||
|
||||
public void startTemplate(@NotNull Editor editor,
|
||||
@NotNull Template template,
|
||||
TemplateEditingListener listener,
|
||||
final PairProcessor<String, String> processor) {
|
||||
startTemplate(editor, null, template, listener, processor);
|
||||
startTemplate(editor, null, template, listener, processor, true);
|
||||
}
|
||||
|
||||
private void startTemplate(final Editor editor,
|
||||
final String selectionString,
|
||||
final Template template,
|
||||
TemplateEditingListener listener,
|
||||
final PairProcessor<String, String> processor) {
|
||||
final PairProcessor<String, String> processor,
|
||||
boolean inSeparateCommand) {
|
||||
final TemplateState templateState = initTemplateState(editor);
|
||||
|
||||
templateState.getProperties().put(ExpressionContext.SELECTION, selectionString);
|
||||
@@ -154,7 +155,7 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
|
||||
if (listener != null) {
|
||||
templateState.addTemplateStateListener(listener);
|
||||
}
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
Runnable r = new Runnable() {
|
||||
public void run() {
|
||||
if (selectionString != null) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@@ -168,7 +169,13 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
|
||||
}
|
||||
templateState.start((TemplateImpl)template, processor, null);
|
||||
}
|
||||
}, CodeInsightBundle.message("insert.code.template.command"), null);
|
||||
};
|
||||
if (inSeparateCommand) {
|
||||
CommandProcessor.getInstance().executeCommand(myProject, r, CodeInsightBundle.message("insert.code.template.command"), null);
|
||||
}
|
||||
else {
|
||||
r.run();
|
||||
}
|
||||
|
||||
if (shouldSkipInTests()) {
|
||||
if (!templateState.isFinished()) templateState.gotoEnd();
|
||||
@@ -180,7 +187,14 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
|
||||
}
|
||||
|
||||
public void startTemplate(@NotNull final Editor editor, @NotNull final Template template, TemplateEditingListener listener) {
|
||||
startTemplate(editor, null, template, listener, null);
|
||||
startTemplate(editor, null, template, listener, null, false);
|
||||
}
|
||||
|
||||
public void startTemplate(@NotNull final Editor editor,
|
||||
@NotNull final Template template,
|
||||
TemplateEditingListener listener,
|
||||
boolean inSeparateCommand) {
|
||||
startTemplate(editor, null, template, listener, null, inSeparateCommand);
|
||||
}
|
||||
|
||||
private static int passArgumentBack(CharSequence text, int caretOffset) {
|
||||
@@ -200,12 +214,47 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
|
||||
}
|
||||
}
|
||||
|
||||
private static String getCurrentLineBeforeCaret(@NotNull Editor editor) {
|
||||
CaretModel caretModel = editor.getCaretModel();
|
||||
int line = caretModel.getLogicalPosition().line;
|
||||
int lineStart = editor.getDocument().getLineStartOffset(line);
|
||||
int offset = caretModel.getOffset();
|
||||
String s = editor.getDocument().getCharsSequence().subSequence(lineStart, offset).toString();
|
||||
int index = 0;
|
||||
while (index < s.length() && Character.isWhitespace(s.charAt(index))) {
|
||||
index++;
|
||||
}
|
||||
return index < s.length() ? s.substring(index) : s;
|
||||
}
|
||||
|
||||
public boolean startTemplate(final Editor editor, char shortcutChar, final PairProcessor<String, String> processor) {
|
||||
final Document document = editor.getDocument();
|
||||
PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, myProject);
|
||||
if (file == null) return false;
|
||||
|
||||
TemplateSettings templateSettings = TemplateSettings.getInstance();
|
||||
if (shortcutChar == templateSettings.getDefaultShortcutChar()) {
|
||||
for (final CustomLiveTemplate customLiveTemplate : CustomLiveTemplate.EP_NAME.getExtensions()) {
|
||||
final String currentLineBeforeCaret = getCurrentLineBeforeCaret(editor);
|
||||
final CustomTemplateCallback callback = new CustomTemplateCallback(editor, file);
|
||||
if (customLiveTemplate.isApplicable(currentLineBeforeCaret, callback)) {
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
final int startOffset = offset - currentLineBeforeCaret.length();
|
||||
editor.getDocument().deleteString(startOffset, offset);
|
||||
callback.fixInitialEditorState();
|
||||
customLiveTemplate.execute(currentLineBeforeCaret, callback, null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return startNonCustomTemplate(templateSettings, file, editor, shortcutChar, processor);
|
||||
}
|
||||
|
||||
private boolean startNonCustomTemplate(TemplateSettings templateSettings,
|
||||
PsiFile file,
|
||||
Editor editor,
|
||||
char shortcutChar,
|
||||
PairProcessor<String, String> processor) {
|
||||
final Document document = editor.getDocument();
|
||||
|
||||
CharSequence text = document.getCharsSequence();
|
||||
|
||||
final int caretOffset = editor.getCaretModel().getOffset();
|
||||
@@ -258,15 +307,14 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
|
||||
else {
|
||||
ListTemplatesHandler.showTemplatesLookup(myProject, editor, candidate2Argument);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static List<TemplateImpl> findMatchingTemplates(CharSequence text,
|
||||
int caretOffset,
|
||||
char shortcutChar,
|
||||
TemplateSettings settings,
|
||||
boolean hasArgument) {
|
||||
public static List<TemplateImpl> findMatchingTemplates(CharSequence text,
|
||||
int caretOffset,
|
||||
char shortcutChar,
|
||||
TemplateSettings settings,
|
||||
boolean hasArgument) {
|
||||
String key;
|
||||
List<TemplateImpl> candidates = Collections.emptyList();
|
||||
for (int i = settings.getMaxKeyLength(); i >= 1; i--) {
|
||||
@@ -318,7 +366,7 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
|
||||
}, CodeInsightBundle.message("insert.code.template.command"), null);
|
||||
}
|
||||
|
||||
private static List<TemplateImpl> filterApplicableCandidates(PsiFile file, int caretOffset, List<TemplateImpl> candidates) {
|
||||
public static List<TemplateImpl> filterApplicableCandidates(PsiFile file, int caretOffset, List<TemplateImpl> candidates) {
|
||||
List<TemplateImpl> result = new ArrayList<TemplateImpl>();
|
||||
for (TemplateImpl candidate : candidates) {
|
||||
if (isApplicable(file, caretOffset - candidate.getKey().length(), candidate)) {
|
||||
|
||||
@@ -318,9 +318,11 @@ public class TemplateState implements Disposable {
|
||||
calcResults(false); //Fixed SCR #[vk500] : all variables should be recalced twice on start.
|
||||
doReformat();
|
||||
|
||||
fireTemplateExpanded();
|
||||
|
||||
int nextVariableNumber = getNextVariableNumber(-1);
|
||||
if (nextVariableNumber == -1) {
|
||||
finishTemplateEditing();
|
||||
finishTemplateEditing(false);
|
||||
}
|
||||
else {
|
||||
setCurrentVariableNumber(nextVariableNumber);
|
||||
@@ -536,7 +538,7 @@ public class TemplateState implements Disposable {
|
||||
final TextResult value = getVariableValue(variableName);
|
||||
if (value != null && value.getText().length() > 0) {
|
||||
if (!myProcessor.process(variableName, value.getText())) {
|
||||
finishTemplateEditing(); // nextTab(); ?
|
||||
finishTemplateEditing(false); // nextTab(); ?
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -684,7 +686,7 @@ public class TemplateState implements Disposable {
|
||||
reformat();
|
||||
}
|
||||
});
|
||||
finishTemplateEditing();
|
||||
finishTemplateEditing(false);
|
||||
return;
|
||||
}
|
||||
focusCurrentHighlighter(false);
|
||||
@@ -733,13 +735,17 @@ public class TemplateState implements Disposable {
|
||||
};
|
||||
}
|
||||
|
||||
public void gotoEnd() {
|
||||
public void gotoEnd(boolean brokenOff) {
|
||||
calcResults(false);
|
||||
doReformat();
|
||||
finishTemplateEditing();
|
||||
finishTemplateEditing(brokenOff);
|
||||
}
|
||||
|
||||
private void finishTemplateEditing() {
|
||||
public void gotoEnd() {
|
||||
gotoEnd(false);
|
||||
}
|
||||
|
||||
private void finishTemplateEditing(boolean brokenOff) {
|
||||
if (myTemplate == null) return;
|
||||
|
||||
LookupManager.getInstance(myProject).hideActiveLookup();
|
||||
@@ -772,7 +778,7 @@ public class TemplateState implements Disposable {
|
||||
setCurrentVariableNumber(-1);
|
||||
currentVariableChanged(oldVar);
|
||||
((TemplateManagerImpl)TemplateManager.getInstance(myProject)).clearTemplateState(editor);
|
||||
fireTemplateFinished();
|
||||
fireTemplateFinished(brokenOff);
|
||||
myListeners.clear();
|
||||
myProject = null;
|
||||
}
|
||||
@@ -990,12 +996,12 @@ public class TemplateState implements Disposable {
|
||||
myListeners.add(listener);
|
||||
}
|
||||
|
||||
private void fireTemplateFinished() {
|
||||
private void fireTemplateFinished(boolean brokenOff) {
|
||||
if (myFinished) return;
|
||||
myFinished = true;
|
||||
TemplateEditingListener[] listeners = myListeners.toArray(new TemplateEditingListener[myListeners.size()]);
|
||||
for (TemplateEditingListener listener : listeners) {
|
||||
listener.templateFinished(myTemplate);
|
||||
listener.templateFinished(myTemplate, brokenOff);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1006,6 +1012,13 @@ public class TemplateState implements Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private void fireTemplateExpanded() {
|
||||
TemplateEditingListener[] listeners = myListeners.toArray(new TemplateEditingListener[myListeners.size()]);
|
||||
for (TemplateEditingListener listener : listeners) {
|
||||
listener.templateExpanded(myTemplate);
|
||||
}
|
||||
}
|
||||
|
||||
private void currentVariableChanged(int oldIndex) {
|
||||
TemplateEditingListener[] listeners = myListeners.toArray(new TemplateEditingListener[myListeners.size()]);
|
||||
for (TemplateEditingListener listener : listeners) {
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ public class EscapeHandler extends EditorActionHandler {
|
||||
final TemplateState templateState = TemplateManagerImpl.getTemplateState(editor);
|
||||
if (templateState != null && !templateState.isFinished()) {
|
||||
CommandProcessor.getInstance().setCurrentCommandName(CodeInsightBundle.message("finish.template.command"));
|
||||
templateState.gotoEnd();
|
||||
templateState.gotoEnd(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,4 +79,7 @@ public abstract class RunManagerEx extends RunManager {
|
||||
public abstract Collection<RunnerAndConfigurationSettingsImpl> getSortedConfigurations();
|
||||
|
||||
public abstract void removeConfiguration(RunnerAndConfigurationSettingsImpl settings);
|
||||
|
||||
public abstract void addRunManagerListener(RunManagerListener listener);
|
||||
public abstract void removeRunManagerListener(RunManagerListener listener);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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.execution;
|
||||
|
||||
public interface RunManagerListener {
|
||||
void beforeRunTasksChanged();
|
||||
}
|
||||
@@ -208,6 +208,7 @@ public abstract class BaseExecuteBeforeRunDialog<T extends BeforeRunTask> extend
|
||||
}
|
||||
}
|
||||
|
||||
((RunManagerImpl)RunManagerEx.getInstanceEx(myProject)).fireBeforeRunTasksUpdated();
|
||||
close(OK_EXIT_CODE);
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,8 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable,
|
||||
private List<Element> myUnloadedElements = null;
|
||||
private JDOMExternalizableStringList myOrder = new JDOMExternalizableStringList();
|
||||
|
||||
private final List<RunManagerListener> myListeners = ContainerUtil.createEmptyCOWList();
|
||||
|
||||
public RunManagerImpl(final Project project,
|
||||
PropertiesComponent propertiesComponent) {
|
||||
myConfig = new RunManagerConfig(propertiesComponent, this);
|
||||
@@ -468,6 +470,8 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable,
|
||||
|
||||
myOrder.readExternal(parentNode);
|
||||
mySelectedConfig = parentNode.getAttributeValue(SELECTED_ATTR);
|
||||
|
||||
fireBeforeRunTasksUpdated();
|
||||
}
|
||||
|
||||
public void readContext(Element parentNode) throws InvalidDataException {
|
||||
@@ -744,10 +748,12 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable,
|
||||
//}
|
||||
}
|
||||
myConfigurationToBeforeTasksMap.put(runConfiguration, taskMap);
|
||||
fireBeforeRunTasksUpdated();
|
||||
}
|
||||
|
||||
public final void resetBeforeRunTasks(final RunConfiguration runConfiguration) {
|
||||
myConfigurationToBeforeTasksMap.remove(runConfiguration);
|
||||
fireBeforeRunTasksUpdated();
|
||||
}
|
||||
|
||||
public void addConfiguration(final RunnerAndConfigurationSettingsImpl settings, final boolean isShared) {
|
||||
@@ -768,6 +774,22 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable,
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRunManagerListener(RunManagerListener listener) {
|
||||
myListeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRunManagerListener(RunManagerListener listener) {
|
||||
myListeners.remove(listener);
|
||||
}
|
||||
|
||||
public void fireBeforeRunTasksUpdated() {
|
||||
for (RunManagerListener each : myListeners) {
|
||||
each.beforeRunTasksChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Key<? extends BeforeRunTask>, BeforeRunTaskProvider> myBeforeStepsMap;
|
||||
private Map<String, Key<? extends BeforeRunTask>> myProviderKeysMap;
|
||||
|
||||
|
||||
@@ -252,7 +252,7 @@ public class PathReferenceManagerImpl extends PathReferenceManager {
|
||||
for (Iterator<PsiReference> it = set.iterator(); it.hasNext();) {
|
||||
PsiReference reference = it.next();
|
||||
final TextRange range = reference.getRangeInElement();
|
||||
if (endOffset == -1 || range.getStartOffset() < endOffset) {
|
||||
if (endOffset == -1 || range.getStartOffset() <= endOffset) {
|
||||
startOffset = Math.min(startOffset, range.getStartOffset());
|
||||
endOffset = Math.max(range.getEndOffset(), endOffset);
|
||||
toAdd.add(reference);
|
||||
|
||||
@@ -42,7 +42,7 @@ public class PsiDynaReference<T extends PsiElement> extends PsiReferenceBase<T>
|
||||
implements FileReferenceOwner, PsiPolyVariantReference, QuickFixProvider<PsiDynaReference>, LocalQuickFixProvider, EmptyResolveMessageProvider {
|
||||
|
||||
private final List<PsiReference> myReferences = new ArrayList<PsiReference>();
|
||||
private int myChoosenOne = -1;
|
||||
private int myChosenOne = -1;
|
||||
private ResolveResult[] myCachedResult;
|
||||
|
||||
public PsiDynaReference(final T psiElement) {
|
||||
@@ -170,23 +170,23 @@ public class PsiDynaReference<T extends PsiElement> extends PsiReferenceBase<T>
|
||||
|
||||
@Nullable
|
||||
private PsiReference chooseReference(){
|
||||
if(myChoosenOne != -1){
|
||||
return myReferences.get(myChoosenOne);
|
||||
if(myChosenOne != -1){
|
||||
return myReferences.get(myChosenOne);
|
||||
}
|
||||
boolean flag = false;
|
||||
for(int i = 0; i < myReferences.size(); i++){
|
||||
final PsiReference reference = myReferences.get(i);
|
||||
if(reference.isSoft() && flag) continue;
|
||||
if(!reference.isSoft() && !flag){
|
||||
myChoosenOne = i;
|
||||
myChosenOne = i;
|
||||
flag = true;
|
||||
continue;
|
||||
}
|
||||
if(reference.resolve() != null){
|
||||
myChoosenOne = i;
|
||||
myChosenOne = i;
|
||||
}
|
||||
}
|
||||
return myChoosenOne >= 0 ? myReferences.get(myChoosenOne) : null;
|
||||
return myChosenOne >= 0 ? myReferences.get(myChosenOne) : null;
|
||||
}
|
||||
|
||||
public void registerQuickfix(final HighlightInfo info, final PsiDynaReference reference) {
|
||||
|
||||
+1
@@ -192,6 +192,7 @@ public class FileReference implements FileReferenceOwner, PsiPolyVariantReferenc
|
||||
return _text;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Object[] getVariants() {
|
||||
final String s = getText();
|
||||
if (s != null && s.equals("/")) {
|
||||
|
||||
+2
-2
@@ -202,8 +202,8 @@ public class VariableInplaceRenamer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void templateFinished(Template template) {
|
||||
super.templateFinished(template);
|
||||
public void templateFinished(Template template, boolean brokenOff) {
|
||||
super.templateFinished(template, brokenOff);
|
||||
if (myNewName != null) {
|
||||
performAutomaticRename(myNewName, PsiTreeUtil.getParentOfType(containingFile.findElementAt(renameOffset), PsiNameIdentifierOwner.class));
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ actionSystem.keyGestures.enabled=false
|
||||
actionSystem.suspendFocusTransferIfApplicationInactive=true
|
||||
actionSystem.noContextComponentWhileFocusTransfer=true
|
||||
|
||||
ide.debugMode=true
|
||||
ide.debugMode=false
|
||||
ide.debugMode.description=Record additonal information to make bug reports more informative
|
||||
ide.forcedShowTooltip=alt
|
||||
ide.forcedShowTooltip.description=Shortcut for forced show tooltip
|
||||
|
||||
@@ -174,6 +174,7 @@
|
||||
<extensionPoint name="liveTemplateMacro" interface="com.intellij.codeInsight.template.Macro"/>
|
||||
<extensionPoint name="liveTemplateOptionalProcessor" interface="com.intellij.codeInsight.template.impl.TemplateOptionalProcessor"/>
|
||||
<extensionPoint name="liveTemplatePreprocessor" interface="com.intellij.codeInsight.template.impl.TemplatePreprocessor"/>
|
||||
<extensionPoint name="customLiveTemplate" interface="com.intellij.codeInsight.template.CustomLiveTemplate"/>
|
||||
|
||||
<extensionPoint name="fileTemplateGroup"
|
||||
interface="com.intellij.ide.fileTemplates.FileTemplateGroupDescriptorFactory"/>
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
implementationClass="com.intellij.codeInsight.hint.XmlImplementationTextSelectioner"/>
|
||||
<basicWordSelectionFilter implementation="com.intellij.codeInsight.editorActions.XmlBasicWordSelectionFilter"/>
|
||||
<defaultLiveTemplatesProvider implementation="com.intellij.codeInsight.template.XmlDefaultLiveTemplatesProvider"/>
|
||||
<customLiveTemplate implementation="com.intellij.codeInsight.template.XmlCustomLiveTemplate"/>
|
||||
<productivityFeaturesProvider implementation="com.intellij.featureStatistics.XmlProductivityFeatureProvider"/>
|
||||
|
||||
<idIndexer filetype="XML" implementationClass="com.intellij.psi.impl.cache.impl.idCache.XmlIdIndexer"/>
|
||||
|
||||
@@ -30,11 +30,12 @@ import java.util.Set;
|
||||
*/
|
||||
public class FileTreeAccessFilter implements VirtualFileFilter {
|
||||
protected final Set<VirtualFile> myAddedClasses = new THashSet<VirtualFile>();
|
||||
private boolean myTreeAccessAllowed;
|
||||
|
||||
public boolean accept(VirtualFile file) {
|
||||
if (file instanceof VirtualFileWindow) return false;
|
||||
|
||||
if (myAddedClasses.contains(file)) return false;
|
||||
if (myAddedClasses.contains(file) || myTreeAccessAllowed) return false;
|
||||
|
||||
FileType fileType = FileTypeManager.getInstance().getFileTypeByFile(file);
|
||||
return (fileType == StdFileTypes.JAVA || fileType == StdFileTypes.CLASS) && !file.getName().equals("package-info.java");
|
||||
@@ -43,4 +44,8 @@ public class FileTreeAccessFilter implements VirtualFileFilter {
|
||||
public void allowTreeAccessForFile(VirtualFile file) {
|
||||
myAddedClasses.add(file);
|
||||
}
|
||||
|
||||
public void allowTreeAccessForAllFiles() {
|
||||
myTreeAccessAllowed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,13 +438,17 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
|
||||
CompletionProgressIndicator.cleanupForNextTest();
|
||||
|
||||
if (checkForEditors) {
|
||||
final Editor[] allEditors = EditorFactory.getInstance().getAllEditors();
|
||||
if (allEditors.length > 0) {
|
||||
for (Editor allEditor : allEditors) {
|
||||
EditorFactory.getInstance().releaseEditor(allEditor);
|
||||
}
|
||||
fail("Unreleased editors: " + allEditors.length);
|
||||
checkEditorsReleased();
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkEditorsReleased() {
|
||||
final Editor[] allEditors = EditorFactory.getInstance().getAllEditors();
|
||||
if (allEditors.length > 0) {
|
||||
for (Editor allEditor : allEditors) {
|
||||
EditorFactory.getInstance().releaseEditor(allEditor);
|
||||
}
|
||||
fail("Unreleased editors: " + allEditors.length);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -279,7 +279,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
LightPlatformTestCase.doTearDown(getProject(), ourApplication, true);
|
||||
LightPlatformTestCase.doTearDown(getProject(), ourApplication, false);
|
||||
|
||||
try {
|
||||
checkForSettingsDamage();
|
||||
@@ -317,6 +317,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
|
||||
//cleanTheWorld();
|
||||
myEditorListenerTracker.checkListenersLeak();
|
||||
myThreadTracker.checkLeak();
|
||||
LightPlatformTestCase.checkEditorsReleased();
|
||||
}
|
||||
finally {
|
||||
myProjectManager = null;
|
||||
|
||||
+2
@@ -325,4 +325,6 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture {
|
||||
void renameElement(PsiElement element, String newName) throws Exception;
|
||||
|
||||
void allowTreeAccessForFile(VirtualFile file);
|
||||
|
||||
void allowTreeAccessForAllFiles();
|
||||
}
|
||||
|
||||
+4
@@ -1194,6 +1194,10 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
|
||||
myJavaFilesFilter.allowTreeAccessForFile(file);
|
||||
}
|
||||
|
||||
public void allowTreeAccessForAllFiles() {
|
||||
myJavaFilesFilter.allowTreeAccessForAllFiles();
|
||||
}
|
||||
|
||||
static class SelectionAndCaretMarkupLoader {
|
||||
final String newFileText;
|
||||
final RangeMarker caretMarker;
|
||||
|
||||
+1
@@ -118,6 +118,7 @@ class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTestFixtu
|
||||
|
||||
myEditorListenerTracker.checkListenersLeak();
|
||||
myThreadTracker.checkLeak();
|
||||
LightPlatformTestCase.checkEditorsReleased();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.intellij.lang.ant.config.explorer;
|
||||
|
||||
import com.intellij.execution.RunManagerEx;
|
||||
import com.intellij.execution.RunManagerListener;
|
||||
import com.intellij.ide.CommonActionsManager;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.ide.TreeExpander;
|
||||
@@ -140,6 +142,12 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider {
|
||||
setContent(new JScrollPane(myTree));
|
||||
ToolTipManager.sharedInstance().registerComponent(myTree);
|
||||
myKeymapListener = new KeymapListener();
|
||||
|
||||
RunManagerEx.getInstanceEx(myProject).addRunManagerListener(new RunManagerListener() {
|
||||
public void beforeRunTasksChanged() {
|
||||
myBuilder.refresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
@@ -621,7 +629,6 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider {
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final AntExecuteBeforeRunDialog dialog = new AntExecuteBeforeRunDialog(myProject, myTarget);
|
||||
dialog.show();
|
||||
myBuilder.refresh();
|
||||
}
|
||||
|
||||
public void update(AnActionEvent e) {
|
||||
|
||||
@@ -368,8 +368,6 @@ public class MavenIndex {
|
||||
}
|
||||
|
||||
private void updateData(ProgressIndicator progress) throws IOException, UnsupportedExistingLuceneIndexException {
|
||||
progress.setText2(IndicesBundle.message("maven.indices.updating.saving"));
|
||||
|
||||
String newDataDirName;
|
||||
IndexData newData;
|
||||
|
||||
@@ -391,7 +389,6 @@ public class MavenIndex {
|
||||
|
||||
synchronized (this) {
|
||||
IndexData oldData = myData;
|
||||
String oldDataDir = myDataDirName;
|
||||
|
||||
myData = newData;
|
||||
myDataDirName = newDataDirName;
|
||||
|
||||
+6
-5
@@ -89,11 +89,6 @@ public class MavenIndicesManager implements ApplicationComponent {
|
||||
}
|
||||
|
||||
public void initComponent() {
|
||||
ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
|
||||
public void run() {
|
||||
doShutdown();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
@@ -117,6 +112,12 @@ public class MavenIndicesManager implements ApplicationComponent {
|
||||
}
|
||||
});
|
||||
|
||||
ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
|
||||
public void run() {
|
||||
doShutdown();
|
||||
}
|
||||
});
|
||||
|
||||
loadUserArchetypes();
|
||||
}
|
||||
|
||||
|
||||
+46
-4
@@ -15,25 +15,33 @@
|
||||
*/
|
||||
package org.jetbrains.idea.maven.navigator;
|
||||
|
||||
import com.intellij.execution.RunManagerEx;
|
||||
import com.intellij.execution.RunManagerListener;
|
||||
import com.intellij.ide.util.treeView.TreeState;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.PersistentStateComponent;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.project.DumbAwareRunnable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.openapi.wm.ToolWindow;
|
||||
import com.intellij.openapi.wm.ToolWindowAnchor;
|
||||
import com.intellij.openapi.wm.ex.ToolWindowManagerAdapter;
|
||||
import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
|
||||
import com.intellij.ui.treeStructure.SimpleTree;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.idea.maven.project.*;
|
||||
import org.jetbrains.idea.maven.tasks.MavenShortcutsManager;
|
||||
import org.jetbrains.idea.maven.tasks.MavenTasksManager;
|
||||
import org.jetbrains.idea.maven.utils.MavenIcons;
|
||||
import org.jetbrains.idea.maven.utils.MavenLog;
|
||||
import org.jetbrains.idea.maven.utils.MavenUtil;
|
||||
import org.jetbrains.idea.maven.utils.SimpleProjectComponent;
|
||||
|
||||
@@ -43,7 +51,6 @@ import java.awt.*;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@State(name = "MavenProjectNavigator", storages = {@Storage(id = "default", file = "$WORKSPACE_FILE$")})
|
||||
public class MavenProjectsNavigator extends SimpleProjectComponent implements PersistentStateComponent<MavenProjectsNavigatorState> {
|
||||
@@ -52,8 +59,6 @@ public class MavenProjectsNavigator extends SimpleProjectComponent implements Pe
|
||||
private static final URL ADD_ICON_URL = MavenProjectsNavigator.class.getResource("/general/add.png");
|
||||
private static final URL SYNC_ICON_URL = MavenProjectsNavigator.class.getResource("/actions/sync.png");
|
||||
|
||||
private final AtomicBoolean myInitialized = new AtomicBoolean(false);
|
||||
|
||||
private MavenProjectsNavigatorState myState = new MavenProjectsNavigatorState();
|
||||
|
||||
private final MavenProjectsManager myProjectsManager;
|
||||
@@ -79,6 +84,17 @@ public class MavenProjectsNavigator extends SimpleProjectComponent implements Pe
|
||||
}
|
||||
|
||||
public MavenProjectsNavigatorState getState() {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
if (myStructure != null) {
|
||||
try {
|
||||
myState.treeState = new Element("root");
|
||||
TreeState.createOn(myTree).writeExternal(myState.treeState);
|
||||
}
|
||||
catch (WriteExternalException e) {
|
||||
MavenLog.LOG.warn(e);
|
||||
}
|
||||
|
||||
}
|
||||
return myState;
|
||||
}
|
||||
|
||||
@@ -169,6 +185,16 @@ public class MavenProjectsNavigator extends SimpleProjectComponent implements Pe
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
RunManagerEx.getInstanceEx(myProject).addRunManagerListener(new RunManagerListener() {
|
||||
public void beforeRunTasksChanged() {
|
||||
scheduleStructureRequest(new Runnable() {
|
||||
public void run() {
|
||||
myStructure.updateGoals();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initToolWindow() {
|
||||
@@ -254,10 +280,26 @@ public class MavenProjectsNavigator extends SimpleProjectComponent implements Pe
|
||||
MavenUtil.invokeLater(myProject, new Runnable() {
|
||||
public void run() {
|
||||
if (!myToolWindow.isVisible()) return;
|
||||
if (myStructure == null) {
|
||||
|
||||
boolean shouldCreate = myStructure == null;
|
||||
if (shouldCreate) {
|
||||
initStructure();
|
||||
}
|
||||
|
||||
r.run();
|
||||
|
||||
if (shouldCreate) {
|
||||
if (myState.treeState != null) {
|
||||
TreeState treeState = new TreeState();
|
||||
try {
|
||||
treeState.readExternal(myState.treeState);
|
||||
treeState.applyTo(myTree);
|
||||
}
|
||||
catch (InvalidDataException e) {
|
||||
MavenLog.LOG.info(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+6
@@ -15,8 +15,14 @@
|
||||
*/
|
||||
package org.jetbrains.idea.maven.navigator;
|
||||
|
||||
import com.intellij.util.xmlb.annotations.Tag;
|
||||
import org.jdom.Element;
|
||||
|
||||
public class MavenProjectsNavigatorState {
|
||||
public boolean groupStructurally = false;
|
||||
public boolean showIgnored = true;
|
||||
public boolean showBasicPhasesOnly = true;
|
||||
|
||||
@Tag("treeState")
|
||||
public Element treeState;
|
||||
}
|
||||
+1
-1
@@ -1004,7 +1004,7 @@ public class MavenProjectsStructure extends SimpleTreeStructure {
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
// show regardless absence of children
|
||||
return getDisplayKind() != DisplayKind.NEVER;
|
||||
return super.isVisible() || getDisplayKind() != DisplayKind.NEVER;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-2
@@ -94,8 +94,6 @@ public class MavenBeforeRunTasksProvider extends BeforeRunTaskProvider<MavenBefo
|
||||
|
||||
task.setProjectPath(dialog.getSelectedProjectPath());
|
||||
task.setGoal(dialog.getSelectedGoal());
|
||||
|
||||
MavenTasksManager.getInstance(myProject).fireTasksChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
-1
@@ -47,7 +47,6 @@ public class ToggleBeforeRunTaskAction extends MavenToggleAction {
|
||||
public void setSelected(final AnActionEvent e, boolean state) {
|
||||
Pair<MavenProject, String> desc = getTaskDesc(e);
|
||||
new MavenExecuteBeforeRunDialog(MavenActionUtil.getProject(e), desc.first, desc.second).show();
|
||||
MavenTasksManager.getInstance(MavenActionUtil.getProject(e)).fireTasksChanged();
|
||||
}
|
||||
|
||||
protected Pair<MavenProject, String> getTaskDesc(AnActionEvent e) {
|
||||
|
||||
@@ -55,7 +55,7 @@ public class MavenJDOMUtil {
|
||||
return doRead(text, handler);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nullable
|
||||
public static Element read(byte[] bytes, @Nullable ErrorHandler handler) {
|
||||
return doRead(CharsetToolkit.bytesToString(bytes), handler);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,5 @@ maven.index.updated.error=Error
|
||||
maven.indices.updating=Updating Maven Repository Indices...
|
||||
maven.indices.updating.index=Updating [{0}] {1}
|
||||
maven.indices.updating.processing=Processing indices...
|
||||
maven.indices.updating.saving=Saving indices...
|
||||
repository.plugin.corrupt={0} not a Maven 2 plugin file
|
||||
repository.plugin.title=Opening Maven plugin file
|
||||
@@ -127,6 +127,16 @@ public class MavenIndicesTest extends MavenIndicesTestCase {
|
||||
assertUnorderedElementsAreEqual(i.getGroupIds(), "jmock");
|
||||
}
|
||||
|
||||
public void testClearingUpdateDirAfterUpdate() throws Exception {
|
||||
ignore();
|
||||
//MavenIndex i = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
//
|
||||
//myIndices.updateOrRepair(i, myEmbedder, true, new EmptyProgressIndicator());
|
||||
//assertUnorderedElementsAreEqual(i.getGroupIds(), "junit");
|
||||
//
|
||||
//assertFalse(i.getUpdateDir().exists());
|
||||
}
|
||||
|
||||
public void testAddingRemote() throws Exception {
|
||||
MavenIndex i = myIndices.add("id", "file:///" + myRepositoryHelper.getTestDataPath("remote"), MavenIndex.Kind.REMOTE);
|
||||
myIndices.updateOrRepair(i, myEmbedder, true, new EmptyProgressIndicator());
|
||||
@@ -140,6 +150,7 @@ public class MavenIndicesTest extends MavenIndicesTestCase {
|
||||
|
||||
//shouldn't throw 'The existing index is for repository [remote] and not for repository [xxx]'
|
||||
myIndices.updateOrRepair(i, myEmbedder, true, new EmptyProgressIndicator());
|
||||
assertUnorderedElementsAreEqual(i.getGroupIds(), "junit");
|
||||
}
|
||||
|
||||
public void testDoNotAddSameIndexTwice() throws Exception {
|
||||
|
||||
@@ -98,7 +98,7 @@ public class ExtendedTagInsertHandler extends XmlTagInsertHandler {
|
||||
try {
|
||||
final String prefixByNamespace = getPrefixByNamespace(file, myNamespace);
|
||||
if (myNamespacePrefix != null || StringUtil.isEmpty(prefixByNamespace)) {
|
||||
final String nsPrefix = myNamespacePrefix == null ? suggestPrefix(file) : myNamespacePrefix;
|
||||
final String nsPrefix = myNamespacePrefix == null ? suggestPrefix(file, myNamespace) : myNamespacePrefix;
|
||||
extension.insertNamespaceDeclaration(file, editor, Collections.singleton(myNamespace), nsPrefix, runAfter);
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed(XmlCompletionContributor.TAG_NAME_COMPLETION_FEATURE);
|
||||
} else {
|
||||
@@ -130,12 +130,12 @@ public class ExtendedTagInsertHandler extends XmlTagInsertHandler {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String suggestPrefix(XmlFile file) {
|
||||
if (myNamespace == null) {
|
||||
public static String suggestPrefix(XmlFile file, @Nullable String namespace) {
|
||||
if (namespace == null) {
|
||||
return null;
|
||||
}
|
||||
for (XmlSchemaProvider provider : XmlSchemaProvider.getAvailableProviders(file)) {
|
||||
String prefix = provider.getDefaultPrefix(myNamespace, file);
|
||||
String prefix = provider.getDefaultPrefix(namespace, file);
|
||||
if (prefix != null) {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ public class XmlTagInsertHandler implements InsertHandler<LookupElement> {
|
||||
|
||||
final boolean weInsertedSomeCodeThatCouldBeInvalidated1 = weInsertedSomeCodeThatCouldBeInvalidated;
|
||||
templateManager.startTemplate(editor, template, new TemplateEditingAdapter() {
|
||||
public void templateFinished(final Template template) {
|
||||
public void templateFinished(final Template template, boolean brokenOff) {
|
||||
final int offset = editor.getCaretModel().getOffset();
|
||||
|
||||
if (weInsertedSomeCodeThatCouldBeInvalidated1 &&
|
||||
|
||||
+12
-5
@@ -131,19 +131,26 @@ public class CreateNSDeclarationIntentionFix implements HintAction, LocalQuickFi
|
||||
project,
|
||||
new StringToAttributeProcessor() {
|
||||
public void doSomethingWithGivenStringToProduceXmlAttributeNowPlease(@NotNull final String namespace) throws IncorrectOperationException {
|
||||
if (StringUtil.isEmpty(myNamespacePrefix)) {
|
||||
String prefix = myNamespacePrefix;
|
||||
if (StringUtil.isEmpty(prefix)) {
|
||||
final XmlExtension extension = XmlExtension.getExtension(myFile);
|
||||
final XmlFile xmlFile = extension.getContainingFile(myElement);
|
||||
final String prefixByNamespace = ExtendedTagInsertHandler.getPrefixByNamespace(xmlFile, namespace);
|
||||
if (prefixByNamespace != null) {
|
||||
ExtendedTagInsertHandler.qualifyWithPrefix(prefixByNamespace, myElement);
|
||||
prefix = ExtendedTagInsertHandler.getPrefixByNamespace(xmlFile, namespace);
|
||||
if (StringUtil.isNotEmpty(prefix)) {
|
||||
ExtendedTagInsertHandler.qualifyWithPrefix(prefix, myElement);
|
||||
return;
|
||||
} else {
|
||||
prefix = ExtendedTagInsertHandler.suggestPrefix(xmlFile, namespace);
|
||||
if (StringUtil.isNotEmpty(prefix)) {
|
||||
ExtendedTagInsertHandler.qualifyWithPrefix(prefix, myElement);
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument());
|
||||
}
|
||||
}
|
||||
}
|
||||
final int offset = editor.getCaretModel().getOffset();
|
||||
final RangeMarker marker = editor.getDocument().createRangeMarker(offset, offset);
|
||||
final XmlExtension extension = XmlExtension.getExtension(file);
|
||||
extension.insertNamespaceDeclaration((XmlFile)file, editor, Collections.singleton(namespace), myNamespacePrefix, new XmlExtension.Runner<String, IncorrectOperationException>() {
|
||||
extension.insertNamespaceDeclaration((XmlFile)file, editor, Collections.singleton(namespace), prefix, new XmlExtension.Runner<String, IncorrectOperationException>() {
|
||||
public void run(final String param) throws IncorrectOperationException {
|
||||
if (namespace.length() > 0) {
|
||||
editor.getCaretModel().moveToOffset(marker.getStartOffset());
|
||||
|
||||
@@ -0,0 +1,459 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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.template;
|
||||
|
||||
import com.intellij.codeInsight.template.impl.TemplateImpl;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public class XmlCustomLiveTemplate implements CustomLiveTemplate {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.template.XmlCustomLiveTemplate");
|
||||
|
||||
private static final String POSSIBLE_OPERATIONS = ">+*";
|
||||
private static final char MARKER = '$';
|
||||
|
||||
private static enum MyState {
|
||||
OPERATION, WORD, AFTER_NUMBER, NUMBER
|
||||
}
|
||||
|
||||
private static class MyToken {
|
||||
}
|
||||
|
||||
private static class MyMarkerToken extends MyToken {
|
||||
}
|
||||
|
||||
private static class MyTemplateToken extends MyToken {
|
||||
final String myKey;
|
||||
|
||||
MyTemplateToken(String key) {
|
||||
myKey = key;
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyNumberToken extends MyToken {
|
||||
final int myNumber;
|
||||
|
||||
MyNumberToken(int number) {
|
||||
myNumber = number;
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyOperationToken extends MyToken {
|
||||
final char mySign;
|
||||
|
||||
MyOperationToken(char sign) {
|
||||
mySign = sign;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isTemplateKeyPart(char c) {
|
||||
return !Character.isWhitespace(c) && POSSIBLE_OPERATIONS.indexOf(c) < 0;
|
||||
}
|
||||
|
||||
private static int parseNonNegativeInt(@NotNull String s) {
|
||||
try {
|
||||
return Integer.parseInt(s);
|
||||
}
|
||||
catch (Throwable ignored) {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static List<MyToken> parse(@NotNull String text, @NotNull CustomTemplateCallback callback) {
|
||||
text += MARKER;
|
||||
StringBuilder templateKeyBuilder = new StringBuilder();
|
||||
List<MyToken> result = new ArrayList<MyToken>();
|
||||
for (int i = 0, n = text.length(); i < n; i++) {
|
||||
char c = text.charAt(i);
|
||||
if (i == n - 1 || POSSIBLE_OPERATIONS.indexOf(c) >= 0) {
|
||||
String key = templateKeyBuilder.toString();
|
||||
templateKeyBuilder = new StringBuilder();
|
||||
int num = parseNonNegativeInt(key);
|
||||
if (num > 0) {
|
||||
result.add(new MyNumberToken(num));
|
||||
}
|
||||
else {
|
||||
if (key.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
if (!callback.isLiveTemplateApplicable(key) && key.indexOf('<') >= 0) {
|
||||
return null;
|
||||
}
|
||||
result.add(new MyTemplateToken(key));
|
||||
}
|
||||
result.add(i < n - 1 ? new MyOperationToken(c) : new MyMarkerToken());
|
||||
}
|
||||
else if (isTemplateKeyPart(c)) {
|
||||
templateKeyBuilder.append(c);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean check(@NotNull Collection<MyToken> tokens) {
|
||||
MyState state = MyState.WORD;
|
||||
for (MyToken token : tokens) {
|
||||
if (token instanceof MyMarkerToken) {
|
||||
break;
|
||||
}
|
||||
switch (state) {
|
||||
case OPERATION:
|
||||
if (token instanceof MyOperationToken) {
|
||||
state = ((MyOperationToken)token).mySign == '*' ? MyState.NUMBER : MyState.WORD;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case WORD:
|
||||
if (token instanceof MyTemplateToken) {
|
||||
state = MyState.OPERATION;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case NUMBER:
|
||||
if (token instanceof MyNumberToken) {
|
||||
state = MyState.AFTER_NUMBER;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case AFTER_NUMBER:
|
||||
if (token instanceof MyOperationToken && ((MyOperationToken)token).mySign != '*') {
|
||||
state = MyState.WORD;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return state == MyState.OPERATION || state == MyState.AFTER_NUMBER;
|
||||
}
|
||||
|
||||
public boolean isApplicable(@NotNull String key, @NotNull CustomTemplateCallback callback) {
|
||||
if (callback.getFile() instanceof XmlFile) {
|
||||
List<MyToken> tokens = parse(key, callback);
|
||||
if (tokens != null) {
|
||||
return check(tokens);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void execute(@NotNull String key, @NotNull CustomTemplateCallback callback, @Nullable TemplateInvokationListener listener) {
|
||||
List<MyToken> tokens = parse(key, callback);
|
||||
assert tokens != null;
|
||||
MyInterpreter interpreter = new MyInterpreter(tokens, 0, callback, MyState.WORD, listener);
|
||||
interpreter.iter();
|
||||
}
|
||||
|
||||
private static void fail() {
|
||||
LOG.error("Input string was checked incorrectly during isApplicable() invokation");
|
||||
}
|
||||
|
||||
private static boolean invokeTemplate(String key, CustomTemplateCallback callback, TemplateInvokationListener listener) {
|
||||
if (callback.isLiveTemplateApplicable(key)) {
|
||||
return callback.startTemplate(key, listener);
|
||||
}
|
||||
else {
|
||||
TemplateImpl template = new TemplateImpl("", "");
|
||||
template.addTextSegment('<' + key + '>');
|
||||
template.addVariableSegment(TemplateImpl.END);
|
||||
template.addTextSegment("</" + key + ">");
|
||||
return callback.startTemplate(template, listener);
|
||||
}
|
||||
}
|
||||
|
||||
private class MyInterpreter extends Iteration {
|
||||
private final List<MyToken> myTokens;
|
||||
private final CustomTemplateCallback myCallback;
|
||||
private final TemplateInvokationListener myListener;
|
||||
private MyState myState;
|
||||
private int myEndOffset = -1;
|
||||
|
||||
private MyInterpreter(List<MyToken> tokens,
|
||||
int startIndex,
|
||||
CustomTemplateCallback callback,
|
||||
MyState initialState,
|
||||
TemplateInvokationListener listener) {
|
||||
super(startIndex, tokens.size(), null);
|
||||
myTokens = tokens;
|
||||
myCallback = callback;
|
||||
myListener = listener;
|
||||
myState = initialState;
|
||||
}
|
||||
|
||||
private void fixEndOffset() {
|
||||
if (myEndOffset < 0) {
|
||||
myEndOffset = getOffset();
|
||||
}
|
||||
}
|
||||
|
||||
private int getOffset() {
|
||||
return myCallback.getEditor().getCaretModel().getOffset();
|
||||
}
|
||||
|
||||
private int getTextLength() {
|
||||
return myCallback.getEditor().getDocument().getCharsSequence().length();
|
||||
}
|
||||
|
||||
private void moveCaret(int delta) {
|
||||
myCallback.getEditor().getCaretModel().moveToOffset(delta);
|
||||
}
|
||||
|
||||
private void finish(boolean inSeparateEvent) {
|
||||
Editor editor = myCallback.getEditor();
|
||||
if (myEndOffset >= 0) {
|
||||
editor.getCaretModel().moveToOffset(myEndOffset);
|
||||
}
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
|
||||
if (myListener != null) {
|
||||
myListener.finished(inSeparateEvent, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void next() {
|
||||
if (myIndex == myMaxIndex - 1) {
|
||||
finish(true);
|
||||
}
|
||||
super.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void iter() {
|
||||
String templateKey = null;
|
||||
int number = -1;
|
||||
for (; myIndex < myMaxIndex; myIndex++) {
|
||||
MyToken token = myTokens.get(myIndex);
|
||||
switch (myState) {
|
||||
case OPERATION:
|
||||
if (templateKey != null) {
|
||||
if (token instanceof MyMarkerToken || token instanceof MyOperationToken) {
|
||||
final char sign = token instanceof MyOperationToken ? ((MyOperationToken)token).mySign : MARKER;
|
||||
if (sign == MARKER || sign == '+') {
|
||||
final int offsetBefore = getOffset();
|
||||
final int lengthBefore = getTextLength();
|
||||
TemplateInvokationListener listener = new TemplateInvokationListener() {
|
||||
public void finished(boolean inSeparateEvent, boolean success) {
|
||||
myState = MyState.WORD;
|
||||
fixEndOffset();
|
||||
if (sign == '+') {
|
||||
moveCaret(offsetBefore + getTextLength() - lengthBefore);
|
||||
}
|
||||
if (inSeparateEvent) {
|
||||
next();
|
||||
}
|
||||
}
|
||||
};
|
||||
if (!invokeTemplate(templateKey, myCallback, listener)) {
|
||||
return;
|
||||
}
|
||||
templateKey = null;
|
||||
}
|
||||
else if (sign == '>') {
|
||||
if (!startTemplate(templateKey)) {
|
||||
return;
|
||||
}
|
||||
templateKey = null;
|
||||
}
|
||||
else if (sign == '*') {
|
||||
myState = MyState.NUMBER;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WORD:
|
||||
if (token instanceof MyTemplateToken) {
|
||||
templateKey = ((MyTemplateToken)token).myKey;
|
||||
myState = MyState.OPERATION;
|
||||
}
|
||||
else {
|
||||
fail();
|
||||
}
|
||||
break;
|
||||
case NUMBER:
|
||||
if (token instanceof MyNumberToken) {
|
||||
number = ((MyNumberToken)token).myNumber;
|
||||
myState = MyState.AFTER_NUMBER;
|
||||
}
|
||||
else {
|
||||
fail();
|
||||
}
|
||||
break;
|
||||
case AFTER_NUMBER:
|
||||
if (token instanceof MyMarkerToken || token instanceof MyOperationToken) {
|
||||
char sign = token instanceof MyOperationToken ? ((MyOperationToken)token).mySign : MARKER;
|
||||
if (sign == MARKER || sign == '+') {
|
||||
ConsecutiveTemplateInvokation iteration = new ConsecutiveTemplateInvokation(templateKey, number);
|
||||
iteration.iter();
|
||||
if (!iteration.isFinished()) {
|
||||
return;
|
||||
}
|
||||
templateKey = null;
|
||||
}
|
||||
else if (number > 1) {
|
||||
ConsecutiveTemplateWithTailInvokation iteration =
|
||||
new ConsecutiveTemplateWithTailInvokation(templateKey, myTokens, myIndex + 1, number);
|
||||
iteration.iter();
|
||||
if (iteration.isFinished()) {
|
||||
myIndex = myMaxIndex;
|
||||
finish(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
assert number == 1;
|
||||
if (!startTemplate(templateKey)) {
|
||||
return;
|
||||
}
|
||||
templateKey = null;
|
||||
}
|
||||
myState = MyState.WORD;
|
||||
}
|
||||
else {
|
||||
fail();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
finish(false);
|
||||
}
|
||||
|
||||
private boolean startTemplate(String templateKey) {
|
||||
TemplateInvokationListener listener = new TemplateInvokationListener() {
|
||||
public void finished(boolean inSeparateEvent, boolean success) {
|
||||
myState = MyState.WORD;
|
||||
if (inSeparateEvent) {
|
||||
next();
|
||||
}
|
||||
}
|
||||
};
|
||||
if (!invokeTemplate(templateKey, myCallback, listener)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private class ConsecutiveTemplateInvokation extends Iteration {
|
||||
private final String myTemplateKey;
|
||||
|
||||
public ConsecutiveTemplateInvokation(String templateKey, int count) {
|
||||
super(0, count, MyInterpreter.this);
|
||||
myTemplateKey = templateKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void iter() {
|
||||
final int offsetBefore = getOffset();
|
||||
final int lengthBefore = getTextLength();
|
||||
for (; myIndex < myMaxIndex; myIndex++) {
|
||||
TemplateInvokationListener listener = new TemplateInvokationListener() {
|
||||
public void finished(boolean inSeparateEvent, boolean success) {
|
||||
myState = MyState.WORD;
|
||||
fixEndOffset();
|
||||
moveCaret(offsetBefore + getTextLength() - lengthBefore);
|
||||
if (inSeparateEvent) {
|
||||
next();
|
||||
}
|
||||
}
|
||||
};
|
||||
if (!invokeTemplate(myTemplateKey, myCallback, listener)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ConsecutiveTemplateWithTailInvokation extends Iteration {
|
||||
private final String myTemplateKey;
|
||||
private final List<MyToken> myTokens;
|
||||
private final int myTailStart;
|
||||
|
||||
public ConsecutiveTemplateWithTailInvokation(String templateKey, List<MyToken> tokens, int tailStart, int count) {
|
||||
super(0, count, null);
|
||||
assert count > 1;
|
||||
assert tailStart < tokens.size();
|
||||
myTemplateKey = templateKey;
|
||||
myTailStart = tailStart;
|
||||
myTokens = tokens;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void next() {
|
||||
if (myIndex == myMaxIndex - 1) {
|
||||
finish(true);
|
||||
}
|
||||
super.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void iter() {
|
||||
final int offsetBefore = getOffset();
|
||||
final int lengthBefore = getTextLength();
|
||||
for (; myIndex < myMaxIndex; myIndex++) {
|
||||
final boolean[] flag = new boolean[]{false};
|
||||
TemplateInvokationListener listener = new TemplateInvokationListener() {
|
||||
public void finished(boolean inSeparateEvent, boolean success) {
|
||||
MyInterpreter interpreter =
|
||||
new MyInterpreter(myTokens, myTailStart, myCallback, MyState.WORD, new TemplateInvokationListener() {
|
||||
public void finished(boolean inSeparateEvent, boolean success) {
|
||||
fixEndOffset();
|
||||
moveCaret(offsetBefore + getTextLength() - lengthBefore);
|
||||
if (inSeparateEvent) {
|
||||
next();
|
||||
}
|
||||
}
|
||||
});
|
||||
interpreter.iter();
|
||||
if (inSeparateEvent && interpreter.isFinished()) {
|
||||
next();
|
||||
}
|
||||
if (!interpreter.isFinished()) {
|
||||
flag[0] = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
if (!invokeTemplate(myTemplateKey, myCallback, listener) || flag[0]) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,7 +185,7 @@ public class DefaultXmlExtension extends XmlExtension {
|
||||
prefix = provider.getDefaultPrefix(namespace, file);
|
||||
}
|
||||
if (prefix == null) {
|
||||
prefix = "x";
|
||||
prefix = "";
|
||||
}
|
||||
final XmlElementFactory elementFactory = XmlElementFactory.getInstance(project);
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ public class XmlTagInplaceRenamer {
|
||||
|
||||
final Template t = buildTemplate(tag, pair);
|
||||
TemplateManager.getInstance(project).startTemplate(myEditor, t, new TemplateEditingAdapter() {
|
||||
public void templateFinished(final Template template) {
|
||||
public void templateFinished(final Template template, boolean brokenOff) {
|
||||
finish();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user