diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/BaseSingleTaskController.kt b/platform/vcs-log/impl/src/com/intellij/vcs/log/BaseSingleTaskController.kt index be1d51beeef1..10460e6cbb03 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/BaseSingleTaskController.kt +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/BaseSingleTaskController.kt @@ -69,4 +69,16 @@ fun ExecutorService.submitSafe(log: Logger, task: () -> Unit): Future<*> = this. catch (t: Throwable) { log.error(t) } +} + +fun SingleTaskController.sendRequests(vararg requests: R?): Boolean { + val notNullRequests = mutableListOf() + for (request in requests) { + if (request != null) notNullRequests.add(request) + } + if (notNullRequests.isNotEmpty()) { + request(notNullRequests) + return true + } + return false } \ No newline at end of file diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/SingleTaskController.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/SingleTaskController.java index 3ac9a70474ef..366e8882a1f7 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/SingleTaskController.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/SingleTaskController.java @@ -59,11 +59,15 @@ public abstract class SingleTaskController implements Disposabl * Otherwise just remembers requests in the queue. Later they can be retrieved by {@link #popRequests()}. */ public final void request(Request @NotNull ... requests) { + request(Arrays.asList(requests)); + } + + public void request(@NotNull List requestList) { synchronized (LOCK) { if (myIsClosed) return; - myAwaitingRequests.addAll(Arrays.asList(requests)); - debug("Added requests: " + Arrays.toString(requests)); - if (myRunningTask != null && cancelRunningTasks(requests)) { + myAwaitingRequests.addAll(requestList); + debug("Added requests: " + requestList); + if (myRunningTask != null && cancelRunningTasks(requestList)) { cancelTask(myRunningTask); } if (myRunningTask == null) { @@ -73,7 +77,7 @@ public abstract class SingleTaskController implements Disposabl } } - protected boolean cancelRunningTasks(Request @NotNull [] requests) { + protected boolean cancelRunningTasks(@NotNull List requests) { return false; } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/details/FullCommitDetailsListPanel.kt b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/details/FullCommitDetailsListPanel.kt index 995b0a8b9beb..f2f46fe1b924 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/details/FullCommitDetailsListPanel.kt +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/details/FullCommitDetailsListPanel.kt @@ -26,6 +26,7 @@ import com.intellij.vcs.log.data.SingleTaskController import com.intellij.vcs.log.ui.details.commit.CommitDetailsPanel import org.jetbrains.annotations.ApiStatus import org.jetbrains.annotations.CalledInBackground +import org.jetbrains.annotations.NotNull import java.awt.BorderLayout import javax.swing.JPanel import javax.swing.border.Border @@ -144,5 +145,5 @@ private class ChangesLoadingController( return SingleTaskImpl(future, indicator) } - override fun cancelRunningTasks(requests: Array>) = true + override fun cancelRunningTasks(requests: List>) = true } \ No newline at end of file diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/visible/VisiblePackRefresherImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/visible/VisiblePackRefresherImpl.java index e5ba479d50f4..b67398096057 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/visible/VisiblePackRefresherImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/visible/VisiblePackRefresherImpl.java @@ -77,7 +77,7 @@ public class VisiblePackRefresherImpl implements VisiblePackRefresher, Disposabl } @Override - protected boolean cancelRunningTasks(Request @NotNull [] requests) { + protected boolean cancelRunningTasks(@NotNull List requests) { return ContainerUtil.findInstance(requests, IndexingFinishedRequest.class) != null || ContainerUtil.findInstance(requests, FilterRequest.class) != null; } diff --git a/plugins/changeReminder/src/com/jetbrains/changeReminder/predict/PredictionController.kt b/plugins/changeReminder/src/com/jetbrains/changeReminder/predict/PredictionController.kt index 2ab8f27da162..0a213ed04529 100644 --- a/plugins/changeReminder/src/com/jetbrains/changeReminder/predict/PredictionController.kt +++ b/plugins/changeReminder/src/com/jetbrains/changeReminder/predict/PredictionController.kt @@ -20,7 +20,7 @@ internal abstract class PredictionController(private val project: Project, inProgressChanged(value) } - override fun cancelRunningTasks(requests: Array) = true + override fun cancelRunningTasks(requests: List) = true override fun startNewBackgroundTask(): SingleTask { val task: Task.Backgroundable = object : Task.Backgroundable( diff --git a/plugins/git4idea/src/git4idea/index/GitStageDiffUtil.kt b/plugins/git4idea/src/git4idea/index/GitStageDiffUtil.kt index 0e0a4c56d98f..db41df66585b 100644 --- a/plugins/git4idea/src/git4idea/index/GitStageDiffUtil.kt +++ b/plugins/git4idea/src/git4idea/index/GitStageDiffUtil.kt @@ -146,11 +146,17 @@ abstract class GitFileStatusNodeProducerBase(val statusNode: GitFileStatusNode) } private fun GitFileStatusNode.has(contentVersion: ContentVersion): Boolean { - return status.has(contentVersion) + return when (this) { + is GitFileStatusNode.Saved -> status.has(contentVersion) + is GitFileStatusNode.Unsaved -> true + } } private fun GitFileStatusNode.path(contentVersion: ContentVersion): FilePath { - return status.path(contentVersion) + return when (this) { + is GitFileStatusNode.Saved -> status.path(contentVersion) + is GitFileStatusNode.Unsaved -> filePath + } } private fun getTitle(statusNode: GitFileStatusNode): String { diff --git a/plugins/git4idea/src/git4idea/index/GitStageTracker.kt b/plugins/git4idea/src/git4idea/index/GitStageTracker.kt index 759a8f2c0894..5e128b57da66 100644 --- a/plugins/git4idea/src/git4idea/index/GitStageTracker.kt +++ b/plugins/git4idea/src/git4idea/index/GitStageTracker.kt @@ -1,7 +1,14 @@ // Copyright 2000-2020 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 git4idea.index +import com.intellij.AppTopics import com.intellij.openapi.Disposable +import com.intellij.openapi.editor.Document +import com.intellij.openapi.editor.EditorFactory +import com.intellij.openapi.editor.event.DocumentEvent +import com.intellij.openapi.editor.event.DocumentListener +import com.intellij.openapi.fileEditor.FileDocumentManager +import com.intellij.openapi.fileEditor.FileDocumentManagerListener import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.progress.util.ProgressIndicatorBase import com.intellij.openapi.project.Project @@ -18,7 +25,10 @@ import com.intellij.util.EventDispatcher import com.intellij.util.messages.MessageBusConnection import com.intellij.vcs.log.BaseSingleTaskController import com.intellij.vcs.log.runInEdt +import com.intellij.vcs.log.sendRequests import git4idea.GitVcs +import git4idea.index.vfs.GitIndexVirtualFile +import git4idea.index.vfs.filePath import git4idea.repo.GitRepositoryManager import git4idea.repo.GitUntrackedFilesHolder import java.util.* @@ -32,47 +42,77 @@ class GitStageTracker(val project: Project) : Disposable { private set @Volatile - var state: State = State(emptyMap()) + var state: State = State.EMPTY init { val connection: MessageBusConnection = project.messageBus.connect(this) connection.subscribe(VirtualFileManager.VFS_CHANGES, object : BulkFileListener { override fun after(events: List) { - val roots = GitRepositoryManager.getInstance(project).repositories.filter { repo -> - events.any { e -> GitUntrackedFilesHolder.totalRefreshNeeded(repo, e.path) } - }.map { it.root } - scheduleUpdateRoots(roots) + scheduleUpdateForEvents(events) } }) connection.subscribe(VcsDirtyScopeManagerListener.VCS_DIRTY_SCOPE_UPDATED, object : VcsDirtyScopeManagerListener { override fun everythingDirty() { - scheduleUpdateRoots(gitRoots()) + scheduleUpdateAll() } override fun filePathsDirty(filesConverted: Map>, dirsConverted: Map>) { val roots = filesConverted.keys.union(dirsConverted.keys).filter { it.vcs?.keyInstanceMethod == GitVcs.getKey() }.map { it.path } - scheduleUpdateRoots(roots) + singleTaskController.sendRequests(gitStateRequest(roots), unsavedFilesRequest(roots)) } }) connection.subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, VcsListener { - if (!scheduleUpdateRoots(gitRoots())) { + val roots = gitRoots() + if (!singleTaskController.sendRequests(gitStateRequest(roots), unsavedFilesRequest(roots))) { runInEdt(this) { - update(State(emptyMap())) + update(State.EMPTY) } } }) + connection.subscribe(AppTopics.FILE_DOCUMENT_SYNC, object : FileDocumentManagerListener { + override fun unsavedDocumentDropped(document: Document) { + scheduleUpdateUnsaved(document) + } + + override fun unsavedDocumentsDropped() { + scheduleUpdateUnsaved() + } + }) + + EditorFactory.getInstance().eventMulticaster.addDocumentListener(object : DocumentListener { + override fun documentChanged(event: DocumentEvent) { + scheduleUpdateUnsaved(event.document) + } + }, this) } fun scheduleUpdateAll() { - scheduleUpdateRoots(gitRoots()) + singleTaskController.sendRequests(gitStateRequest(gitRoots()), unsavedFilesRequest(gitRoots())) } - private fun scheduleUpdateRoots(roots: List): Boolean { - if (roots.isNotEmpty()) { - singleTaskController.request(Request(roots)) - return true + private fun scheduleUpdateUnsaved() { + singleTaskController.sendRequests(unsavedFilesRequest(gitRoots())) + } + + private fun scheduleUpdateUnsaved(document: Document) { + val file = FileDocumentManager.getInstance().getFile(document) ?: return + getRoot(file)?.let { singleTaskController.request(Request.Unsaved(listOf(it))) } + } + + private fun scheduleUpdateForEvents(events: List) { + val updateGitStateFor = GitRepositoryManager.getInstance(project).repositories.filter { repo -> + events.any { e -> GitUntrackedFilesHolder.totalRefreshNeeded(repo, e.path) } + }.map { it.root } + val updateAllFor = events.mapNotNull { it.file as? GitIndexVirtualFile }.mapTo(mutableSetOf()) { it.root } + singleTaskController.sendRequests(gitStateRequest(updateGitStateFor.union(updateAllFor)), unsavedFilesRequest(updateAllFor)) + } + + private fun getRoot(file: VirtualFile): VirtualFile? { + return when { + file is GitIndexVirtualFile -> file.root + file.isInLocalFileSystem -> ProjectLevelVcsManager.getInstance(project).getVcsRootFor(file) + else -> null } - return false } fun addListener(listener: GitStageTrackerListener, disposable: Disposable) { @@ -88,51 +128,104 @@ class GitStageTracker(val project: Project) : Disposable { eventDispatcher.multicaster.update() } + private fun gitStateRequest(roots: Collection): Request.GitState? { + if (roots.isEmpty()) return null + return Request.GitState(roots) + } + + private fun unsavedFilesRequest(roots: Collection): Request.Unsaved? { + if (roots.isEmpty()) return null + return Request.Unsaved(roots) + } + override fun dispose() { - state = State(emptyMap()) + state = State.EMPTY } - private data class Request(val roots: Collection) { - override fun toString(): String = "Request(roots=${roots.joinToString(",") { it.name }})" + private sealed class Request(val roots: Collection) { + class GitState(roots: Collection) : Request(roots) { + override fun toString(): String = "Request.GitState(roots=${roots.joinToString(",") { it.name }})" + } + + class Unsaved(roots: Collection) : Request(roots) { + override fun toString(): String = "Request.Unsaved(roots=${roots.joinToString(",") { it.name }})" + } } - data class State(val gitState: Map>) { + data class State(val gitState: Map>, + val unsavedIndex: Map>, + val unsavedWorkTree: Map>) { private val roots: Collection - get() = gitState.keys + get() = gitState.keys.union(unsavedIndex.keys).union(unsavedWorkTree.keys) val stagedRoots: Set get() { return gitState.filterValues { it.any { line -> line.getStagedStatus() != null } - }.keys + }.keys.union(unsavedIndex.filterValues { it.isNotEmpty() }.keys) } fun hasStagedRoots(): Boolean { - return gitState.values.flatten().any { it.getStagedStatus() != null } + return gitState.values.flatten().any { it.getStagedStatus() != null } || unsavedIndex.values.flatten().isNotEmpty() } fun updatedWith(newState: State, roots: Collection = this.roots.union(newState.roots)): State { val gitState = hashMapOf>() + val unsavedIndex = hashMapOf>() + val unsavedWorkTree = hashMapOf>() for (root in roots) { gitState[root] = newState.gitState[root] ?: this.gitState[root] ?: emptyList() + unsavedIndex[root] = newState.unsavedIndex[root] ?: this.unsavedIndex[root] ?: emptyList() + unsavedWorkTree[root] = newState.unsavedWorkTree[root] ?: this.unsavedWorkTree[root] ?: emptyList() } - return State(gitState) + return State(gitState, unsavedIndex, unsavedWorkTree) } override fun toString(): String { - return "State(gitState=$gitState)" + return "State(gitState=$gitState, unsavedIndex=$unsavedIndex, unsavedWorkTree=$unsavedWorkTree)" + } + + companion object { + internal val EMPTY = State(emptyMap(), emptyMap(), emptyMap()) } } private inner class MySingleTaskController : BaseSingleTaskController("Git Stage Tracker", this::update, this) { override fun process(requests: List, previousState: State?): State { - val gitStateRoots = requests.flatMapTo(HashSet()) { it.roots } + val gitStateRoots = requests.filterIsInstance().flatMapTo(HashSet()) { it.roots } val gitState = mutableMapOf>() for (root in gitStateRoots) { gitState[root] = getStatus(project, root, withIgnored = false).map { GitFileStatus(root, it) } } - val newState = State(gitState) + val unsavedRoots = requests.filterIsInstance().flatMapTo(HashSet()) { it.roots } + val index = unsavedRoots.associateWith { mutableListOf() } + val workTree = unsavedRoots.associateWith { mutableListOf() } + for (document in FileDocumentManager.getInstance().unsavedDocuments) { + val file = FileDocumentManager.getInstance().getFile(document) ?: continue + if (!file.isValid || !FileDocumentManager.getInstance().isFileModified(file)) continue + val root = getRoot(file) ?: continue + if (!unsavedRoots.contains(root)) continue + + val statusRecord: GitFileStatus? = if (gitStateRoots.contains(root)) { + gitState[root]?.find { it.path == file.filePath() } + } + else if (previousState?.gitState?.containsKey(root) == true) { + previousState.gitState[root]?.find { it.path == file.filePath() } + } + else { + state.gitState[root]?.find { it.path == file.filePath() } + } + if (statusRecord?.isTracked() == false) continue + if (file is GitIndexVirtualFile && statusRecord?.getStagedStatus() == null) { + index.getValue(root).add(file) + } + else if (file.isInLocalFileSystem && statusRecord?.getUnStagedStatus() == null) { + workTree.getValue(root).add(file) + } + } + + val newState = State(gitState, index, workTree) return previousState?.updatedWith(newState) ?: newState } diff --git a/plugins/git4idea/src/git4idea/index/ui/GitStageTree.kt b/plugins/git4idea/src/git4idea/index/ui/GitStageTree.kt index 33ee03e8ba47..3e2dd371e874 100644 --- a/plugins/git4idea/src/git4idea/index/ui/GitStageTree.kt +++ b/plugins/git4idea/src/git4idea/index/ui/GitStageTree.kt @@ -12,9 +12,9 @@ import com.intellij.openapi.vcs.changes.ui.* import com.intellij.openapi.vcs.impl.PlatformVcsPathPresenter import com.intellij.openapi.vfs.VirtualFile import git4idea.i18n.GitBundle -import git4idea.index.GitFileStatus -import git4idea.index.GitStageTracker -import git4idea.index.isRenamed +import git4idea.index.* +import git4idea.index.vfs.GitIndexVirtualFile +import git4idea.index.vfs.filePath import org.jetbrains.annotations.Nls import org.jetbrains.annotations.NonNls import org.jetbrains.annotations.PropertyKey @@ -38,12 +38,26 @@ abstract class GitStageTree(project: Project) : ChangesTree(project, false, true NodeKind.values().forEach { kind -> if (kind.`is`(status)) { val parentNode = parentNodes.getOrPut(kind) { ChangesBrowserKindNode(kind) } - val fileStatusInfo = GitFileStatusNode(root, status, kind) + val fileStatusInfo = GitFileStatusNode.Saved(root, status, kind) builder.insertPath(fileStatusInfo, parentNode) } } } } + state.unsavedIndex.forEach { (root, files) -> + files.forEach { file -> + val parentNode = parentNodes.getOrPut(NodeKind.STAGED) { ChangesBrowserKindNode(NodeKind.STAGED) } + val fileStatusInfo = GitFileStatusNode.Unsaved(root, file) + builder.insertPath(fileStatusInfo, parentNode) + } + } + state.unsavedWorkTree.forEach { (root, files) -> + files.forEach { file -> + val parentNode = parentNodes.getOrPut(NodeKind.UNSTAGED) { ChangesBrowserKindNode(NodeKind.UNSTAGED) } + val fileStatusInfo = GitFileStatusNode.Unsaved(root, file) + builder.insertPath(fileStatusInfo, parentNode) + } + } parentNodes.values.forEach { builder.insertIntoRootNode(it) } @@ -130,29 +144,63 @@ enum class NodeKind(@PropertyKey(resourceBundle = GitBundle.BUNDLE) @NonNls val open fun origPath(status: GitFileStatus): FilePath? = null } -class GitFileStatusNode(val root: VirtualFile, val status: GitFileStatus, val kind: NodeKind) { - val filePath: FilePath get() = status.path - val origPath: FilePath? get() = kind.origPath(status) - val fileStatus: FileStatus get() = kind.status(status) +sealed class GitFileStatusNode(val root: VirtualFile, val kind: NodeKind) { + abstract val filePath: FilePath + abstract val origPath: FilePath? + abstract val fileStatus: FileStatus - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false + class Saved(root: VirtualFile, val status: GitFileStatus, kind: NodeKind) : GitFileStatusNode(root, kind) { + override val filePath: FilePath get() = status.path + override val origPath: FilePath? get() = kind.origPath(status) + override val fileStatus: FileStatus get() = kind.status(status) - other as GitFileStatusNode + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false - if (root != other.root) return false - if (status != other.status) return false - if (kind != other.kind) return false + other as Saved - return true + if (root != other.root) return false + if (status != other.status) return false + if (kind != other.kind) return false + + return true + } + + override fun hashCode(): Int { + return Objects.hashCode(root, fileStatus, kind) + } + + override fun toString(): String { + return "GitFileStatusNode.Saved(root=$root, status=$fileStatus, kind=$kind)" + } } - override fun hashCode(): Int { - return Objects.hashCode(root, fileStatus, kind) - } + class Unsaved(root: VirtualFile, val file: VirtualFile) : GitFileStatusNode(root, file.kind()) { + override val filePath: FilePath get() = file.filePath() + override val origPath: FilePath? get() = null + override val fileStatus: FileStatus get() = FileStatus.MODIFIED - override fun toString(): String { - return "GitFileStatusNode.Saved(root=$root, status=$fileStatus, kind=$kind)" + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as Unsaved + + if (root != other.root) return false + if (file != other.file) return false + + return true + } + + override fun hashCode(): Int { + return Objects.hashCode(root, file) + } + + override fun toString(): String { + return "GitFileStatusNode.Unsaved(root=$root, file=$file" + } } -} \ No newline at end of file +} + +private fun VirtualFile.kind() = if (this is GitIndexVirtualFile) NodeKind.STAGED else NodeKind.UNSTAGED diff --git a/plugins/git4idea/src/git4idea/index/vfs/GitIndexVirtualFile.kt b/plugins/git4idea/src/git4idea/index/vfs/GitIndexVirtualFile.kt index 79e76b356064..75a619f3c4a9 100644 --- a/plugins/git4idea/src/git4idea/index/vfs/GitIndexVirtualFile.kt +++ b/plugins/git4idea/src/git4idea/index/vfs/GitIndexVirtualFile.kt @@ -203,4 +203,9 @@ class GitIndexVirtualFile(private val project: Project, } internal data class CachedData(val hash: Hash, val length: Long, val isExecutable: Boolean = false) +} + +internal fun VirtualFile.filePath(): FilePath { + return if (this is GitIndexVirtualFile) this.filePath + else VcsUtil.getFilePath(this) } \ No newline at end of file diff --git a/plugins/git4idea/src/git4idea/light/LightGitEditorHighlighterManager.kt b/plugins/git4idea/src/git4idea/light/LightGitEditorHighlighterManager.kt index 63b102350292..bc07cd929a00 100644 --- a/plugins/git4idea/src/git4idea/light/LightGitEditorHighlighterManager.kt +++ b/plugins/git4idea/src/git4idea/light/LightGitEditorHighlighterManager.kt @@ -19,6 +19,7 @@ import com.intellij.openapi.vfs.VirtualFile import com.intellij.vcs.log.BaseSingleTaskController import git4idea.index.isTracked import git4idea.index.repositoryPath +import org.jetbrains.annotations.NotNull private val LOG = Logger.getInstance("#git4idea.light.LightGitEditorHighlighterManager") @@ -114,7 +115,7 @@ class LightGitEditorHighlighterManager(val tracker: LightGitTracker) : Disposabl } } - override fun cancelRunningTasks(requests: Array?): Boolean = true + override fun cancelRunningTasks(requests: List): Boolean = true } private data class Request(val file: VirtualFile, val repositoryPath: String) diff --git a/plugins/git4idea/src/git4idea/light/LightGitTracker.kt b/plugins/git4idea/src/git4idea/light/LightGitTracker.kt index fd482f0be66b..d75acf6bf486 100644 --- a/plugins/git4idea/src/git4idea/light/LightGitTracker.kt +++ b/plugins/git4idea/src/git4idea/light/LightGitTracker.kt @@ -17,6 +17,7 @@ import com.intellij.openapi.vfs.newvfs.events.VFileEvent import com.intellij.util.EventDispatcher import com.intellij.vcs.log.BaseSingleTaskController import com.intellij.vcs.log.runInEdt +import com.intellij.vcs.log.sendRequests import com.intellij.vcsUtil.VcsUtil import git4idea.config.GitExecutableManager import git4idea.config.GitVersionIdentificationException @@ -59,8 +60,8 @@ class LightGitTracker : Disposable { singleTaskController.request(Request.CheckGit) runInEdt(this) { - sendRequests(locationRequest(lightEditService.selectedFile), - statusRequest(lightEditorManager.openFiles)) + singleTaskController.sendRequests(locationRequest(lightEditService.selectedFile), + statusRequest(lightEditorManager.openFiles)) } } @@ -124,15 +125,6 @@ class LightGitTracker : Disposable { return Request.Status(filesForRequest) } - private fun sendRequests(vararg requests: Request?): Boolean { - val notNullRequests = requests.filterNotNullTo(mutableListOf()) - if (notNullRequests.isNotEmpty()) { - singleTaskController.request(*notNullRequests.toTypedArray()) - return true - } - return false - } - fun addUpdateListener(listener: LightGitTrackerListener, parent: Disposable) { eventDispatcher.addListener(listener, parent) } @@ -145,15 +137,15 @@ class LightGitTracker : Disposable { if (!hasGit) return val targetFiles = events.filter { it.isFromSave || it.isFromRefresh }.mapNotNullTo(mutableSetOf()) { it.file } - sendRequests(statusRequest(lightEditorManager.openFiles.intersect(targetFiles))) + singleTaskController.sendRequests(statusRequest(lightEditorManager.openFiles.intersect(targetFiles))) } } private inner class MyFrameStateListener : FrameStateListener { override fun onFrameActivated() { - sendRequests(Request.CheckGit, - locationRequest(lightEditService.selectedFile), - statusRequest(lightEditorManager.openFiles)) + singleTaskController.sendRequests(Request.CheckGit, + locationRequest(lightEditService.selectedFile), + statusRequest(lightEditorManager.openFiles)) } } @@ -164,7 +156,7 @@ class LightGitTracker : Disposable { state = state.copy(location = null) val selectedFile = editorInfo?.file - if (!sendRequests(locationRequest(selectedFile), statusRequest(listOf(selectedFile)))) { + if (!singleTaskController.sendRequests(locationRequest(selectedFile), statusRequest(listOf(selectedFile)))) { runInEdt(this@LightGitTracker) { eventDispatcher.multicaster.update() } } }