mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Revert "Revert "VIM-547 Add timestamps to UndoManager""
This reverts commit 6a64d7fef4f38d5e5dc86916e63d0c4886bc505b. GitOrigin-RevId: bbb2d9de24615a9d99458f7afc797098fb37f8c9
This commit is contained in:
committed by
intellij-monorepo-bot
parent
f44ac9d622
commit
87694ae89c
@@ -9,6 +9,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class BasicUndoableAction implements UndoableAction {
|
||||
private final DocumentReference[] myRefs;
|
||||
private long myPerformedTimestamp = -1L;
|
||||
|
||||
public BasicUndoableAction() {
|
||||
myRefs = null;
|
||||
@@ -41,4 +42,14 @@ public abstract class BasicUndoableAction implements UndoableAction {
|
||||
public boolean isGlobal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getPerformedNanoTime() {
|
||||
return myPerformedTimestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPerformedNanoTime(long l) {
|
||||
myPerformedTimestamp = l;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.NlsActions;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -48,4 +49,16 @@ public abstract class UndoManager {
|
||||
public abstract @NotNull Pair<@NlsActions.ActionText String, @NlsActions.ActionDescription String> getUndoActionNameAndDescription(FileEditor editor);
|
||||
|
||||
public abstract @NotNull Pair<@NlsActions.ActionText String, @NlsActions.ActionDescription String> getRedoActionNameAndDescription(FileEditor editor);
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public abstract long getNextUndoNanoTime(@NotNull FileEditor editor);
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public abstract long getNextRedoNanoTime(@NotNull FileEditor editor);
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public abstract boolean isNextUndoAskConfirmation(@NotNull FileEditor editor);
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public abstract boolean isNextRedoAskConfirmation(@NotNull FileEditor editor);
|
||||
}
|
||||
|
||||
+15
-8
@@ -1,14 +1,21 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.command.undo;
|
||||
package com.intellij.openapi.command.undo
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
/**
|
||||
* @see UndoManager#undoableActionPerformed(UndoableAction)
|
||||
* @see UndoManager.undoableActionPerformed
|
||||
*/
|
||||
public interface UndoableAction {
|
||||
void undo() throws UnexpectedUndoException;
|
||||
void redo() throws UnexpectedUndoException;
|
||||
interface UndoableAction {
|
||||
@get:ApiStatus.Experimental
|
||||
@set:ApiStatus.Experimental
|
||||
var performedNanoTime: Long
|
||||
|
||||
@Throws(UnexpectedUndoException::class)
|
||||
fun undo()
|
||||
|
||||
@Throws(UnexpectedUndoException::class)
|
||||
fun redo()
|
||||
|
||||
/**
|
||||
* Returns the documents, affected by this action.
|
||||
@@ -16,10 +23,10 @@ public interface UndoableAction {
|
||||
* The action can be undone if all of its affected documents are either
|
||||
* not affected by any of further actions or all of such actions are undone.
|
||||
*/
|
||||
DocumentReference @Nullable [] getAffectedDocuments();
|
||||
val affectedDocuments: Array<DocumentReference>?
|
||||
|
||||
/**
|
||||
* Global actions are those, that can be undone not only from the document of the file, but also from the project tree view.
|
||||
*/
|
||||
boolean isGlobal();
|
||||
val isGlobal: Boolean
|
||||
}
|
||||
+4
-2
@@ -33,9 +33,11 @@ class SuggestedRefactoringUndoableAction private constructor(
|
||||
|
||||
private val documentReference = DocumentReferenceManager.getInstance().create(document)
|
||||
|
||||
override fun getAffectedDocuments(): Array<DocumentReference> = arrayOf(documentReference)
|
||||
override var performedNanoTime: Long = -1
|
||||
|
||||
override fun isGlobal(): Boolean = false
|
||||
override val affectedDocuments: Array<DocumentReference> = arrayOf(documentReference)
|
||||
|
||||
override val isGlobal: Boolean = false
|
||||
|
||||
override fun undo() {
|
||||
val document = documentReference.document ?: return
|
||||
|
||||
@@ -178,6 +178,26 @@ public abstract class UndoRedoAction extends DumbAwareAction implements LightEdi
|
||||
return getUndoOrRedoActionNameAndDescription( false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNextUndoNanoTime(@NotNull FileEditor editor) {
|
||||
return -1L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNextRedoNanoTime(@NotNull FileEditor editor) {
|
||||
return -1L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNextUndoAskConfirmation(@NotNull FileEditor editor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNextRedoAskConfirmation(@NotNull FileEditor editor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static @NotNull Pair<String, String> getUndoOrRedoActionNameAndDescription(boolean undo) {
|
||||
if (undo) {
|
||||
return Pair.create(
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.concurrency.ThreadingAssertions;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
+11
@@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
* Undo action can be available even if this Document is ReadOnly.
|
||||
*/
|
||||
final class MentionOnlyUndoableAction implements UndoableAction {
|
||||
private long myPerformedTimestamp = -1L;
|
||||
private final DocumentReference[] myRefs;
|
||||
|
||||
MentionOnlyUndoableAction(DocumentReference @NotNull [] refs) {
|
||||
@@ -33,4 +34,14 @@ final class MentionOnlyUndoableAction implements UndoableAction {
|
||||
public boolean isGlobal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getPerformedNanoTime() {
|
||||
return myPerformedTimestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPerformedNanoTime(long l) {
|
||||
myPerformedTimestamp = l;
|
||||
}
|
||||
}
|
||||
|
||||
+11
-1
@@ -8,7 +8,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
final class NonUndoableAction implements UndoableAction {
|
||||
private static final Logger LOG = Logger.getInstance(NonUndoableAction.class);
|
||||
|
||||
private long myPerformedTimestamp = -1;
|
||||
private final DocumentReference[] myRefs;
|
||||
private final boolean myGlobal;
|
||||
|
||||
@@ -39,4 +39,14 @@ final class NonUndoableAction implements UndoableAction {
|
||||
public boolean isGlobal() {
|
||||
return myGlobal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getPerformedNanoTime() {
|
||||
return myPerformedTimestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPerformedNanoTime(long l) {
|
||||
myPerformedTimestamp = l;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,6 +332,7 @@ public final class UndoManagerImpl extends UndoManager {
|
||||
return;
|
||||
}
|
||||
|
||||
action.setPerformedNanoTime(System.nanoTime());
|
||||
if (state.myCommandLevel == 0) {
|
||||
LOG.assertTrue(action instanceof NonUndoableAction,
|
||||
"Undoable actions allowed inside commands only (see com.intellij.openapi.command.CommandProcessor.executeCommand())");
|
||||
@@ -631,6 +632,58 @@ public final class UndoManagerImpl extends UndoManager {
|
||||
return getUndoOrRedoActionNameAndDescription(editor, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNextUndoNanoTime(@NotNull FileEditor editor) {
|
||||
return getNextNanoTime(editor, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNextRedoNanoTime(@NotNull FileEditor editor) {
|
||||
return getNextNanoTime(editor, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNextUndoAskConfirmation(@NotNull FileEditor editor) {
|
||||
return isNextAskConfirmation(editor, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNextRedoAskConfirmation(@NotNull FileEditor editor) {
|
||||
return isNextAskConfirmation(editor, false);
|
||||
}
|
||||
|
||||
private long getNextNanoTime(@NotNull FileEditor editor, boolean isUndo) {
|
||||
ClientState clientState = getClientState(editor);
|
||||
Collection<DocumentReference> references = getDocRefs(editor);
|
||||
if (clientState == null || references == null) {
|
||||
return -1L;
|
||||
}
|
||||
|
||||
if (isUndo) {
|
||||
clientState.myMerger.flushCurrentCommand();
|
||||
}
|
||||
|
||||
@NotNull UndoRedoStacksHolder stack = getStackHolder(clientState, isUndo);
|
||||
UndoableGroup lastAction = stack.getLastAction(references);
|
||||
return lastAction == null ? -1L : lastAction.getGroupStartPerformedTimestamp();
|
||||
}
|
||||
|
||||
private boolean isNextAskConfirmation(@NotNull FileEditor editor, boolean isUndo) {
|
||||
ClientState clientState = getClientState(editor);
|
||||
Collection<DocumentReference> references = getDocRefs(editor);
|
||||
if (clientState == null || references == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isUndo) {
|
||||
clientState.myMerger.flushCurrentCommand();
|
||||
}
|
||||
|
||||
@NotNull UndoRedoStacksHolder stack = getStackHolder(clientState, isUndo);
|
||||
UndoableGroup lastAction = stack.getLastAction(references);
|
||||
return lastAction != null && lastAction.shouldAskConfirmation(!isUndo);
|
||||
}
|
||||
|
||||
private @NotNull Pair<@NlsActions.ActionText String, @NlsActions.ActionDescription String> getUndoOrRedoActionNameAndDescription(@Nullable FileEditor editor, boolean undo) {
|
||||
String desc = isUndoOrRedoAvailable(editor, undo) ? doFormatAvailableUndoRedoAction(editor, undo) : null;
|
||||
if (desc == null) desc = "";
|
||||
|
||||
+2
-1
@@ -7,6 +7,7 @@ import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import java.util.*;
|
||||
@@ -26,7 +27,7 @@ final class UndoRedoStacksHolder extends UndoRedoStacksHolderBase<UndoableGroup>
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nullable
|
||||
UndoableGroup getLastAction(@NotNull Collection<? extends DocumentReference> refs) {
|
||||
if (refs.isEmpty()) return myGlobalStack.getLast();
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import com.intellij.openapi.util.NlsContexts;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -352,12 +353,18 @@ final class UndoableGroup implements Dumpable {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ApiStatus.Experimental
|
||||
boolean shouldAskConfirmation(boolean redo) {
|
||||
if (shouldAskConfirmationForStartFinishGroup(redo)) return true;
|
||||
return myConfirmationPolicy == UndoConfirmationPolicy.REQUEST_CONFIRMATION ||
|
||||
myConfirmationPolicy != UndoConfirmationPolicy.DO_NOT_REQUEST_CONFIRMATION && myGlobal;
|
||||
}
|
||||
|
||||
long getGroupStartPerformedTimestamp() {
|
||||
if (myActions.isEmpty()) return -1L;
|
||||
return Math.min(myActions.get(0).getPerformedNanoTime(), myActions.get(myActions.size() - 1).getPerformedNanoTime());
|
||||
}
|
||||
|
||||
void invalidateChangeRanges() {
|
||||
for (UndoableAction action : myActions) {
|
||||
if (action instanceof AdjustableUndoableAction) {
|
||||
|
||||
+12
@@ -338,6 +338,8 @@ public final class EditPropertyValueAction extends BaseRefactoringAction {
|
||||
new VisualPosition(regionStartPosition.line, regionStartPosition.column + placeholderColumn));
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
|
||||
UndoManager.getInstance(project).undoableActionPerformed(new UndoableAction() {
|
||||
private long myPerformedTimestamp = -1L;
|
||||
|
||||
@Override
|
||||
public void undo() {
|
||||
if (foldRegion.isValid()) {
|
||||
@@ -361,6 +363,16 @@ public final class EditPropertyValueAction extends BaseRefactoringAction {
|
||||
public boolean isGlobal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getPerformedNanoTime() {
|
||||
return myPerformedTimestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPerformedNanoTime(long performedTimestamp) {
|
||||
myPerformedTimestamp = performedTimestamp;
|
||||
}
|
||||
});
|
||||
}, targetPsiFile);
|
||||
editorComponent.paintImmediately(new Rectangle(editorComponent.getSize()));
|
||||
|
||||
Reference in New Issue
Block a user