mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 14:23:28 +07:00
[diff] Enable history navigation through diffs
Currently limited only to those history points that are generated by the text editors present in (some) diff viewers. Also limited in the sense that diff previews do not change upon navigation. GitOrigin-RevId: fffb97e2c12131c686f119af5eb1407956a282ee
This commit is contained in:
committed by
intellij-monorepo-bot
parent
5d3e39e290
commit
5377efd5c8
7
platform/diff-impl/resources/META-INF/diff-impl.xml
Normal file
7
platform/diff-impl/resources/META-INF/diff-impl.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<registryKey defaultValue="false"
|
||||
description="Try to include navigation within a diff in the editor's navigation history."
|
||||
key="include.diffs.in.navigation.history"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
@@ -25,6 +25,7 @@ abstract class DiffEditorBase(
|
||||
) : FileEditorBase() {
|
||||
companion object {
|
||||
private val LOG = logger<DiffEditorBase>()
|
||||
const val DIFF_IN_NAVIGATION_HISTORY_KEY = "include.diffs.in.navigation.history"
|
||||
}
|
||||
|
||||
private val panel = MyPanel(component)
|
||||
|
||||
@@ -6,9 +6,13 @@ import com.intellij.diff.impl.DiffRequestProcessorListener
|
||||
import com.intellij.diff.tools.combined.editors
|
||||
import com.intellij.diff.util.DiffUserDataKeysEx
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.fileEditor.FileEditorState
|
||||
import com.intellij.openapi.fileEditor.FileEditorStateLevel
|
||||
import com.intellij.openapi.fileEditor.FileEditorWithTextEditors
|
||||
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
|
||||
import com.intellij.openapi.fileEditor.impl.text.TextEditorState
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import javax.swing.JComponent
|
||||
|
||||
@@ -36,6 +40,20 @@ open class DiffRequestProcessorEditor(
|
||||
super.dispose()
|
||||
}
|
||||
|
||||
override fun getState(level: FileEditorStateLevel): FileEditorState {
|
||||
if (!Registry.`is`(DIFF_IN_NAVIGATION_HISTORY_KEY)) {
|
||||
return FileEditorState.INSTANCE
|
||||
}
|
||||
|
||||
return processor.getState(level)
|
||||
}
|
||||
|
||||
override fun setState(state: FileEditorState) {
|
||||
if (!Registry.`is`(DIFF_IN_NAVIGATION_HISTORY_KEY) || state !is DiffRequestProcessorEditorState) return
|
||||
|
||||
processor.setState(state)
|
||||
}
|
||||
|
||||
override fun getPreferredFocusedComponent(): JComponent? = processor.preferredFocusedComponent
|
||||
|
||||
override fun selectNotify() {
|
||||
@@ -55,3 +73,13 @@ open class DiffRequestProcessorEditor(
|
||||
return processor.activeViewer?.editors.orEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
data class DiffRequestProcessorEditorState(
|
||||
val embeddedEditorStates: List<TextEditorState>
|
||||
) : FileEditorState {
|
||||
override fun canBeMergedWith(otherState: FileEditorState, level: FileEditorStateLevel): Boolean =
|
||||
otherState is DiffRequestProcessorEditorState &&
|
||||
embeddedEditorStates.zip(otherState.embeddedEditorStates).all { (l, r) -> l.canBeMergedWith(r, level) }
|
||||
|
||||
override fun toString(): String = embeddedEditorStates.joinToString()
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import com.intellij.codeInsight.hint.HintUtil;
|
||||
import com.intellij.diff.*;
|
||||
import com.intellij.diff.FrameDiffTool.DiffViewer;
|
||||
import com.intellij.diff.actions.impl.*;
|
||||
import com.intellij.diff.editor.DiffRequestProcessorEditor;
|
||||
import com.intellij.diff.editor.DiffRequestProcessorEditorState;
|
||||
import com.intellij.diff.impl.DiffSettingsHolder.DiffSettings;
|
||||
import com.intellij.diff.impl.ui.DiffToolChooser;
|
||||
import com.intellij.diff.lang.DiffIgnoredRangeProvider;
|
||||
@@ -38,6 +40,9 @@ import com.intellij.openapi.diff.DiffBundle;
|
||||
import com.intellij.openapi.diff.impl.DiffUsageTriggerCollector;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.LogicalPosition;
|
||||
import com.intellij.openapi.fileEditor.FileEditorState;
|
||||
import com.intellij.openapi.fileEditor.FileEditorStateLevel;
|
||||
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
@@ -678,6 +683,30 @@ public abstract class DiffRequestProcessor implements CheckedDisposable {
|
||||
return myContext;
|
||||
}
|
||||
|
||||
public void setState(@NotNull DiffRequestProcessorEditorState state) {
|
||||
DiffViewer viewer = getActiveViewer();
|
||||
if (!(viewer instanceof EditorDiffViewer)) return;
|
||||
|
||||
var editors = ((EditorDiffViewer)viewer).getEditors();
|
||||
var editorStates = state.getEmbeddedEditorStates();
|
||||
|
||||
TextEditorProvider textEditorProvider = TextEditorProvider.getInstance();
|
||||
for (int i = 0; i < Math.min(editorStates.size(), editors.size()); i++) {
|
||||
textEditorProvider.setStateImpl(myProject, editors.get(i), editorStates.get(i), true);
|
||||
}
|
||||
}
|
||||
|
||||
public @NotNull FileEditorState getState(@NotNull FileEditorStateLevel level) {
|
||||
DiffViewer viewer = getActiveViewer();
|
||||
if (!(viewer instanceof EditorDiffViewer)) return FileEditorState.INSTANCE;
|
||||
|
||||
List<? extends Editor> editors = ((EditorDiffViewer)viewer).getEditors();
|
||||
|
||||
TextEditorProvider textEditorProvider = TextEditorProvider.getInstance();
|
||||
return new DiffRequestProcessorEditorState(ContainerUtil.map(editors, (editor) ->
|
||||
textEditorProvider.getStateImpl(null, editor, level)));
|
||||
}
|
||||
|
||||
public @Nullable DiffViewer getActiveViewer() {
|
||||
if (myState instanceof DefaultState) {
|
||||
return ((DefaultState)myState).myViewer;
|
||||
|
||||
@@ -11,6 +11,9 @@ import com.intellij.diff.util.DiffUserDataKeysEx
|
||||
import com.intellij.diff.util.DiffUtil
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.fileEditor.FileEditorState
|
||||
import com.intellij.openapi.fileEditor.FileEditorStateLevel
|
||||
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.util.concurrency.annotations.RequiresEdt
|
||||
import java.awt.Dimension
|
||||
@@ -48,6 +51,31 @@ open class CombinedDiffComponentFactory(val model: CombinedDiffModel) {
|
||||
|
||||
internal fun getMainComponent() = mainUi.getComponent()
|
||||
|
||||
internal fun getState(level: FileEditorStateLevel): FileEditorState {
|
||||
val viewer = combinedViewer
|
||||
if (viewer == null) return FileEditorState.INSTANCE
|
||||
|
||||
val textEditorProvider = TextEditorProvider.getInstance()
|
||||
return CombinedDiffEditorState(
|
||||
model.requests.map { it.id }.toSet(),
|
||||
viewer.getCurrentBlockId(),
|
||||
viewer.getCurrentDiffViewer()?.editors?.map { textEditorProvider.getStateImpl(null, it, level) } ?: listOf()
|
||||
)
|
||||
}
|
||||
|
||||
internal fun setState(state: CombinedDiffEditorState) {
|
||||
val viewer = combinedViewer ?: return
|
||||
if (model.requests.map { it.id }.toSet() != state.currentBlockIds) return
|
||||
|
||||
val textEditorProvider = TextEditorProvider.getInstance()
|
||||
state.activeEditorStates.zip(viewer.getDiffViewerForId(state.activeBlockId)?.editors ?: listOf()) { st, editor ->
|
||||
textEditorProvider.setStateImpl(null, editor, st, true)
|
||||
}
|
||||
|
||||
viewer.selectDiffBlock(state.activeBlockId, true)
|
||||
viewer.scrollToCaret()
|
||||
}
|
||||
|
||||
private fun createMainUI(): CombinedDiffMainUI {
|
||||
return CombinedDiffMainUI(model, createGoToChangeAction()).also { ui ->
|
||||
Disposer.register(ourDisposable, ui)
|
||||
|
||||
@@ -3,8 +3,12 @@ package com.intellij.diff.tools.combined
|
||||
|
||||
import com.intellij.diff.editor.DiffEditorBase
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.fileEditor.FileEditorState
|
||||
import com.intellij.openapi.fileEditor.FileEditorStateLevel
|
||||
import com.intellij.openapi.fileEditor.FileEditorWithTextEditors
|
||||
import com.intellij.openapi.fileEditor.impl.text.TextEditorState
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import javax.swing.JComponent
|
||||
|
||||
class CombinedDiffEditor(file: CombinedDiffVirtualFile, val factory: CombinedDiffComponentFactory) :
|
||||
@@ -15,9 +19,34 @@ class CombinedDiffEditor(file: CombinedDiffVirtualFile, val factory: CombinedDif
|
||||
super.dispose()
|
||||
}
|
||||
|
||||
override fun getState(level: FileEditorStateLevel): FileEditorState {
|
||||
if (!Registry.`is`(DIFF_IN_NAVIGATION_HISTORY_KEY)) return FileEditorState.INSTANCE
|
||||
|
||||
return factory.getState(level)
|
||||
}
|
||||
|
||||
override fun setState(state: FileEditorState) {
|
||||
if (state !is CombinedDiffEditorState) return
|
||||
|
||||
factory.setState(state)
|
||||
}
|
||||
|
||||
override fun getPreferredFocusedComponent(): JComponent? = factory.getPreferredFocusedComponent()
|
||||
|
||||
override fun getEmbeddedEditors(): List<Editor> {
|
||||
return factory.model.context.getUserData(COMBINED_DIFF_VIEWER_KEY)?.editors.orEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
data class CombinedDiffEditorState(
|
||||
val currentBlockIds: Set<CombinedBlockId>,
|
||||
val activeBlockId: CombinedBlockId,
|
||||
val activeEditorStates: List<TextEditorState>
|
||||
) : FileEditorState {
|
||||
override fun canBeMergedWith(otherState: FileEditorState, level: FileEditorStateLevel): Boolean {
|
||||
return otherState is CombinedDiffEditorState &&
|
||||
(currentBlockIds != otherState.currentBlockIds ||
|
||||
(activeBlockId == otherState.activeBlockId &&
|
||||
activeEditorStates.zip(otherState.activeEditorStates).all { (l, r) -> l.canBeMergedWith(r, level) } ))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,6 +148,9 @@
|
||||
<applicationInitializedListener implementation="com.intellij.openapi.fileTypes.impl.associate.OSFileAssociationStartupConfigurator"/>
|
||||
</extensions>
|
||||
|
||||
<xi:include href="/META-INF/diff-impl.xml">
|
||||
<xi:fallback/>
|
||||
</xi:include>
|
||||
<xi:include href="/META-INF/VCS.xml">
|
||||
<xi:fallback/>
|
||||
</xi:include>
|
||||
|
||||
Reference in New Issue
Block a user