mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-298857 Command line "Idea diff" does not make Idea window focused (part 2 - "merge")
GitOrigin-RevId: 1af9be1ed0a5e6a46b0d56107d6061b7888fd9c8
This commit is contained in:
committed by
intellij-monorepo-bot
parent
1a17e44496
commit
b3d585e63a
@@ -1,131 +1,98 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.diff.applications;
|
||||
package com.intellij.diff.applications
|
||||
|
||||
import com.intellij.diff.DiffDialogHints;
|
||||
import com.intellij.diff.DiffManagerEx;
|
||||
import com.intellij.diff.DiffRequestFactory;
|
||||
import com.intellij.diff.chains.DiffRequestProducerException;
|
||||
import com.intellij.diff.merge.MergeRequest;
|
||||
import com.intellij.diff.merge.MergeRequestProducer;
|
||||
import com.intellij.diff.merge.MergeResult;
|
||||
import com.intellij.ide.CliResult;
|
||||
import com.intellij.idea.SplashManager;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ApplicationNamesInfo;
|
||||
import com.intellij.openapi.application.ApplicationStarterBase;
|
||||
import com.intellij.openapi.diff.DiffBundle;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.WindowWrapper;
|
||||
import com.intellij.openapi.util.UserDataHolder;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import com.intellij.diff.DiffDialogHints
|
||||
import com.intellij.diff.DiffManagerEx
|
||||
import com.intellij.diff.DiffRequestFactory
|
||||
import com.intellij.diff.chains.DiffRequestProducerException
|
||||
import com.intellij.diff.merge.MergeRequest
|
||||
import com.intellij.diff.merge.MergeRequestProducer
|
||||
import com.intellij.diff.merge.MergeResult
|
||||
import com.intellij.ide.CliResult
|
||||
import com.intellij.idea.SplashManager
|
||||
import com.intellij.openapi.application.ApplicationNamesInfo
|
||||
import com.intellij.openapi.application.ApplicationStarterBase
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.diff.DiffBundle
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.ui.WindowWrapper
|
||||
import com.intellij.openapi.util.UserDataHolder
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.ui.AppIcon
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
internal class MergeApplication : ApplicationStarterBase(3, 4) {
|
||||
override val commandName: String
|
||||
get() = "merge"
|
||||
|
||||
final class MergeApplication extends ApplicationStarterBase {
|
||||
MergeApplication() {
|
||||
super(3, 4);
|
||||
}
|
||||
override val usageMessage: String
|
||||
get() {
|
||||
val scriptName = ApplicationNamesInfo.getInstance().scriptName
|
||||
return DiffBundle.message("merge.application.usage.parameters.and.description", scriptName)
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "merge";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getUsageMessage() {
|
||||
final String scriptName = ApplicationNamesInfo.getInstance().getScriptName();
|
||||
return DiffBundle.message("merge.application.usage.parameters.and.description", scriptName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull CompletableFuture<CliResult> processCommand(@NotNull List<String> args, @Nullable String currentDirectory) throws Exception {
|
||||
List<String> filePaths = args.subList(1, 4);
|
||||
List<VirtualFile> files = DiffApplicationBase.findFilesOrThrow(filePaths, currentDirectory);
|
||||
Project project = DiffApplicationBase.guessProject(files);
|
||||
|
||||
List<VirtualFile> contents = Arrays.asList(files.get(0), files.get(2), files.get(1)); // left, base, right
|
||||
|
||||
VirtualFile outputFile;
|
||||
if (args.size() == 5) {
|
||||
String outputFilePath = args.get(4);
|
||||
outputFile = DiffApplicationBase.findOrCreateFile(outputFilePath, currentDirectory);
|
||||
DiffApplicationBase.refreshAndEnsureFilesValid(Collections.singletonList(outputFile));
|
||||
override suspend fun executeCommand(args: List<String>, currentDirectory: String?): CliResult {
|
||||
val filePaths = args.subList(1, 4)
|
||||
val files = DiffApplicationBase.findFilesOrThrow(filePaths, currentDirectory)
|
||||
val project = DiffApplicationBase.guessProject(files)
|
||||
val contents = listOf(files[0], files[2], files[1]) // left, base, right
|
||||
val outputFile: VirtualFile?
|
||||
if (args.size == 5) {
|
||||
val outputFilePath = args[4]
|
||||
outputFile = DiffApplicationBase.findOrCreateFile(outputFilePath, currentDirectory)
|
||||
DiffApplicationBase.refreshAndEnsureFilesValid(listOf(outputFile))
|
||||
}
|
||||
else {
|
||||
outputFile = files.get(2); // base
|
||||
outputFile = files[2] // base
|
||||
}
|
||||
if (outputFile == null) {
|
||||
throw Exception(DiffBundle.message("cannot.create.file.error", ContainerUtil.getLastItem(filePaths)))
|
||||
}
|
||||
if (outputFile == null) throw new Exception(DiffBundle.message("cannot.create.file.error", ContainerUtil.getLastItem(filePaths)));
|
||||
|
||||
CompletableFuture<CliResult> future = new CompletableFuture<>();
|
||||
AtomicReference<CliResult> resultRef = new AtomicReference<>(new CliResult(127, null));
|
||||
ApplicationManager.getApplication().invokeLater(() -> {
|
||||
MergeRequestProducer requestProducer = new MyMergeRequestProducer(project, outputFile, contents, resultRef);
|
||||
|
||||
WindowWrapper.Mode mode = project != null ? WindowWrapper.Mode.FRAME : WindowWrapper.Mode.MODAL;
|
||||
DiffDialogHints dialogHints = new DiffDialogHints(mode, null, wrapper -> {
|
||||
Window window = wrapper.getWindow();
|
||||
SplashManager.hideBeforeShow(window);
|
||||
|
||||
UIUtil.runWhenWindowClosed(window, () -> {
|
||||
future.complete(resultRef.get());
|
||||
});
|
||||
});
|
||||
DiffManagerEx.getInstance().showMergeBuiltin(project, requestProducer, dialogHints);
|
||||
});
|
||||
return future;
|
||||
val deferred = CompletableDeferred<CliResult>()
|
||||
withContext(Dispatchers.EDT) {
|
||||
val resultRef = AtomicReference(CliResult(127, null))
|
||||
val requestProducer = MyMergeRequestProducer(project, outputFile, contents, resultRef)
|
||||
val mode = if (project == null) WindowWrapper.Mode.MODAL else WindowWrapper.Mode.FRAME
|
||||
val dialogHints = DiffDialogHints(mode, null) { wrapper ->
|
||||
val window = wrapper.window
|
||||
SplashManager.hideBeforeShow(window)
|
||||
AppIcon.getInstance().requestFocus(window)
|
||||
UIUtil.runWhenWindowClosed(window) { deferred.complete(resultRef.get()) }
|
||||
}
|
||||
DiffManagerEx.getInstance().showMergeBuiltin(project, requestProducer, dialogHints)
|
||||
}
|
||||
return deferred.await()
|
||||
}
|
||||
|
||||
private static final class MyMergeRequestProducer implements MergeRequestProducer {
|
||||
private final Project myProject;
|
||||
private final VirtualFile myOutputFile;
|
||||
private final List<VirtualFile> myContents;
|
||||
private final AtomicReference<CliResult> myResultRef;
|
||||
private class MyMergeRequestProducer(private val project: Project?,
|
||||
private val outputFile: VirtualFile,
|
||||
private val contents: List<VirtualFile>,
|
||||
private val resultRef: AtomicReference<CliResult>) : MergeRequestProducer {
|
||||
override fun getName(): String = DiffBundle.message("merge.window.title.file", outputFile.presentableUrl)
|
||||
|
||||
private MyMergeRequestProducer(@Nullable Project project,
|
||||
@NotNull VirtualFile outputFile,
|
||||
@NotNull List<VirtualFile> contents,
|
||||
@NotNull AtomicReference<CliResult> resultRef) {
|
||||
myProject = project;
|
||||
myOutputFile = outputFile;
|
||||
myContents = contents;
|
||||
myResultRef = resultRef;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return DiffBundle.message("merge.window.title.file", myOutputFile.getPresentableUrl());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull MergeRequest process(@NotNull UserDataHolder context, @NotNull ProgressIndicator indicator)
|
||||
throws DiffRequestProducerException, ProcessCanceledException {
|
||||
try {
|
||||
List<VirtualFile> contents = DiffApplicationBase.replaceNullsWithEmptyFile(myContents);
|
||||
return DiffRequestFactory.getInstance().createMergeRequestFromFiles(myProject, myOutputFile, contents, result -> {
|
||||
override fun process(context: UserDataHolder, indicator: ProgressIndicator): MergeRequest {
|
||||
return try {
|
||||
val contents = DiffApplicationBase.replaceNullsWithEmptyFile(contents)
|
||||
DiffRequestFactory.getInstance().createMergeRequestFromFiles(project, outputFile, contents) { result ->
|
||||
try {
|
||||
saveIfNeeded(myOutputFile);
|
||||
saveIfNeeded(outputFile)
|
||||
}
|
||||
finally {
|
||||
int exitCode = result != MergeResult.CANCEL ? 0 : 1;
|
||||
myResultRef.set(new CliResult(exitCode, null));
|
||||
resultRef.set(CliResult(if (result == MergeResult.CANCEL) 1 else 0, null))
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
myResultRef.set(new CliResult(127, e.getMessage()));
|
||||
throw new DiffRequestProducerException(e);
|
||||
catch (e: Throwable) {
|
||||
resultRef.set(CliResult(127, e.message))
|
||||
throw DiffRequestProducerException(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user