mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
fix lookup start marker invalidation when finishing completion with a char inside a live template
This commit is contained in:
@@ -1203,4 +1203,17 @@ class Foo {{
|
||||
assert myFixture.file.text.contains('FIS:')
|
||||
}
|
||||
|
||||
public void testSoutvTemplate() {
|
||||
((TemplateManagerImpl)TemplateManager.getInstance(getProject())).setTemplateTesting(true);
|
||||
try {
|
||||
myFixture.configureByText 'a.java', 'class Foo {{ <caret> }}'
|
||||
type 'soutv\tgetcl.'
|
||||
myFixture.checkResult '''class Foo {{
|
||||
System.out.println("getClass(). = " + getClass().<caret>); }}'''
|
||||
}
|
||||
finally {
|
||||
((TemplateManagerImpl)TemplateManager.getInstance(getProject())).setTemplateTesting(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -813,7 +813,7 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
|
||||
}
|
||||
}
|
||||
|
||||
public static Runnable rememberDocumentState(final Editor _editor) {
|
||||
private static Runnable rememberDocumentState(final Editor _editor) {
|
||||
final Editor editor = InjectedLanguageUtil.getTopLevelEditor(_editor);
|
||||
final String documentText = editor.getDocument().getText();
|
||||
final int caret = editor.getCaretModel().getOffset();
|
||||
|
||||
+47
-36
@@ -32,6 +32,7 @@ import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.command.CommandProcessorEx;
|
||||
import com.intellij.openapi.command.impl.EditorChangeAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorModificationUtil;
|
||||
@@ -42,15 +43,12 @@ import com.intellij.openapi.editor.ex.ScrollingModelEx;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.impl.DebugUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class LookupTypedHandler extends TypedHandlerDelegate {
|
||||
private static boolean inside = false;
|
||||
@@ -117,11 +115,7 @@ public class LookupTypedHandler extends TypedHandlerDelegate {
|
||||
inside = false;
|
||||
((CommandProcessorEx)CommandProcessor.getInstance()).enterModal();
|
||||
try {
|
||||
finishLookup(charTyped, lookup, new Runnable() {
|
||||
public void run() {
|
||||
EditorModificationUtil.typeInStringAtCaretHonorBlockSelection(editor, String.valueOf(charTyped), true);
|
||||
}
|
||||
});
|
||||
finishLookup(charTyped, lookup);
|
||||
}
|
||||
finally {
|
||||
((CommandProcessorEx)CommandProcessor.getInstance()).leaveModal();
|
||||
@@ -161,45 +155,22 @@ public class LookupTypedHandler extends TypedHandlerDelegate {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void finishLookup(final char charTyped, @NotNull final LookupImpl lookup, final Runnable baseChange) {
|
||||
Editor editor = lookup.getEditor();
|
||||
private static void finishLookup(final char charTyped, @NotNull final LookupImpl lookup) {
|
||||
final Editor editor = lookup.getEditor();
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EDITING_COMPLETION_FINISH_BY_DOT_ETC);
|
||||
CompletionProcess process = CompletionService.getCompletionService().getCurrentCompletion();
|
||||
SelectionModel sm = editor.getSelectionModel();
|
||||
final boolean smartUndo = !sm.hasSelection() && !sm.hasBlockSelection() && process != null && process.isAutopopupCompletion();
|
||||
final Runnable restore = CodeCompletionHandlerBase.rememberDocumentState(editor);
|
||||
final ScrollingModelEx scrollingModel = (ScrollingModelEx)editor.getScrollingModel();
|
||||
scrollingModel.accumulateViewportChanges();
|
||||
try {
|
||||
final List<Pair<DocumentEvent, String>> events = new ArrayList<Pair<DocumentEvent, String>>();
|
||||
final DocumentAdapter listener = new DocumentAdapter() {
|
||||
@Override
|
||||
public void documentChanged(DocumentEvent e) {
|
||||
events.add(Pair.create(e, DebugUtil.currentStackTrace()));
|
||||
}
|
||||
};
|
||||
editor.getDocument().addDocumentListener(listener);
|
||||
if (smartUndo) {
|
||||
CommandProcessor.getInstance().executeCommand(editor.getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
lookup.performGuardedChange(baseChange);
|
||||
}
|
||||
}, null, "Just insert the completion char");
|
||||
}
|
||||
editor.getDocument().removeDocumentListener(listener);
|
||||
final LinkedList<EditorChangeAction> events = smartUndo ? justTypeChar(charTyped, lookup, editor) : null;
|
||||
|
||||
CommandProcessor.getInstance().executeCommand(editor.getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (smartUndo) {
|
||||
AccessToken token = WriteAction.start();
|
||||
try {
|
||||
lookup.performGuardedChange(restore, events.toString());
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
undoEvents(lookup, events);
|
||||
}
|
||||
lookup.finishLookup(charTyped);
|
||||
}
|
||||
@@ -210,6 +181,46 @@ public class LookupTypedHandler extends TypedHandlerDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
private static void undoEvents(LookupImpl lookup, @NotNull final LinkedList<EditorChangeAction> events) {
|
||||
AccessToken token = WriteAction.start();
|
||||
try {
|
||||
lookup.performGuardedChange(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (EditorChangeAction event : events) {
|
||||
event.performUndo();
|
||||
}
|
||||
}
|
||||
}, events.toString());
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
}
|
||||
|
||||
private static LinkedList<EditorChangeAction> justTypeChar(final char charTyped, final LookupImpl lookup, final Editor editor) {
|
||||
final LinkedList<EditorChangeAction> events = new LinkedList<EditorChangeAction>();
|
||||
final DocumentAdapter listener = new DocumentAdapter() {
|
||||
@Override
|
||||
public void documentChanged(DocumentEvent e) {
|
||||
events.addFirst(new EditorChangeAction(e));
|
||||
}
|
||||
};
|
||||
editor.getDocument().addDocumentListener(listener);
|
||||
CommandProcessor.getInstance().executeCommand(editor.getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
lookup.performGuardedChange(new Runnable() {
|
||||
public void run() {
|
||||
EditorModificationUtil.typeInStringAtCaretHonorBlockSelection(editor, String.valueOf(charTyped), true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, null, "Just insert the completion char");
|
||||
editor.getDocument().removeDocumentListener(listener);
|
||||
return events;
|
||||
}
|
||||
|
||||
static CharFilter.Result getLookupAction(final char charTyped, final LookupImpl lookup) {
|
||||
final CharFilter.Result filtersDecision = getFiltersDecision(charTyped, lookup);
|
||||
|
||||
|
||||
+1
-6
@@ -27,7 +27,6 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.event.DocumentAdapter;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.editor.ex.DocumentEx;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
@@ -108,11 +107,7 @@ public class DocumentUndoProvider implements Disposable {
|
||||
}
|
||||
|
||||
private void registerUndoableAction(DocumentEvent e) {
|
||||
getUndoManager().undoableActionPerformed(new EditorChangeAction((DocumentEx)e.getDocument(),
|
||||
e.getOffset(),
|
||||
e.getOldFragment(),
|
||||
e.getNewFragment(),
|
||||
e.getOldTimeStamp()));
|
||||
getUndoManager().undoableActionPerformed(new EditorChangeAction(e));
|
||||
}
|
||||
|
||||
private void registerNonUndoableAction(final Document document) {
|
||||
|
||||
+11
-2
@@ -16,6 +16,7 @@
|
||||
package com.intellij.openapi.command.impl;
|
||||
|
||||
import com.intellij.openapi.command.undo.BasicUndoableAction;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.editor.ex.DocumentEx;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
@@ -25,13 +26,17 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
class EditorChangeAction extends BasicUndoableAction {
|
||||
public class EditorChangeAction extends BasicUndoableAction {
|
||||
private final int myOffset;
|
||||
private final CharSequence myOldString;
|
||||
private final CharSequence myNewString;
|
||||
private final long myOldTimeStamp;
|
||||
private final long myNewTimeStamp;
|
||||
|
||||
public EditorChangeAction(DocumentEvent e) {
|
||||
this((DocumentEx)e.getDocument(), e.getOffset(), e.getOldFragment(), e.getNewFragment(), e.getOldTimeStamp());
|
||||
}
|
||||
|
||||
public EditorChangeAction(DocumentEx document,
|
||||
int offset,
|
||||
CharSequence oldString,
|
||||
@@ -49,7 +54,7 @@ class EditorChangeAction extends BasicUndoableAction {
|
||||
public void undo() {
|
||||
DocumentUndoProvider.startDocumentUndo(getDocument());
|
||||
try {
|
||||
exchangeStrings(myNewString, myOldString);
|
||||
performUndo();
|
||||
}
|
||||
finally {
|
||||
DocumentUndoProvider.finishDocumentUndo(getDocument());
|
||||
@@ -59,6 +64,10 @@ class EditorChangeAction extends BasicUndoableAction {
|
||||
refreshFileStatus();
|
||||
}
|
||||
|
||||
public void performUndo() {
|
||||
exchangeStrings(myNewString, myOldString);
|
||||
}
|
||||
|
||||
public void redo() {
|
||||
DocumentUndoProvider.startDocumentUndo(getDocument());
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user