vcs: non-modal: Update commit message based on current change list on "Commit" invocation (IDEA-215941)

GitOrigin-RevId: 2ff205f75ab132b535f8c6c56450bf897f3c169c
This commit is contained in:
Konstantin Kolosovsky
2019-10-13 15:02:11 +00:00
committed by intellij-monorepo-bot
parent a5cf11ff2b
commit c224531062
5 changed files with 82 additions and 37 deletions
@@ -0,0 +1,44 @@
// Copyright 2000-2019 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.vcs.commit
import com.intellij.openapi.project.Project
import com.intellij.openapi.vcs.AbstractVcs
import com.intellij.openapi.vcs.VcsConfiguration
import com.intellij.openapi.vcs.changes.Change
import com.intellij.openapi.vcs.changes.ChangeListManager
import com.intellij.openapi.vcs.changes.ChangesUtil
import com.intellij.openapi.vcs.changes.ChangesUtil.processChangesByVcs
import com.intellij.openapi.vcs.changes.LocalChangeList
import com.intellij.openapi.vcs.changes.ui.CommitMessageProvider
internal abstract class AbstractCommitMessagePolicy(protected val project: Project) {
protected val vcsConfiguration: VcsConfiguration get() = VcsConfiguration.getInstance(project)
protected val changeListManager: ChangeListManager get() = ChangeListManager.getInstance(project)
protected fun save(changeListName: String, commitMessage: String) {
changeListManager.editComment(changeListName, commitMessage)
}
protected fun getCommitMessageFor(changeList: LocalChangeList): String? {
CommitMessageProvider.EXTENSION_POINT_NAME.extensionList.forEach { provider ->
val providerMessage = provider.getCommitMessage(changeList, project)
if (providerMessage != null) return providerMessage
}
val changeListDescription = changeList.comment
if (!changeListDescription.isNullOrBlank()) return changeListDescription
return if (!changeList.hasDefaultName()) changeList.name else null
}
protected fun getCommitMessageFromVcs(changes: List<Change>): String? {
var result: String? = null
processChangesByVcs(project, changes) { vcs, vcsChanges ->
if (result == null) result = getCommitMessageFromVcs(vcs, vcsChanges)
}
return result
}
private fun getCommitMessageFromVcs(vcs: AbstractVcs, changes: List<Change>): String? =
vcs.checkinEnvironment?.getDefaultMessageFor(ChangesUtil.getPaths(changes).toTypedArray())
}
@@ -0,0 +1,19 @@
// Copyright 2000-2019 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.vcs.commit
import com.intellij.openapi.project.Project
import com.intellij.openapi.vcs.changes.Change
import com.intellij.openapi.vcs.changes.LocalChangeList
internal class ChangesViewCommitMessagePolicy(project: Project) : AbstractCommitMessagePolicy(project) {
fun getCommitMessage(changeList: LocalChangeList, changesSupplier: () -> List<Change>): String? =
if (vcsConfiguration.CLEAR_INITIAL_COMMIT_MESSAGE) null
else getCommitMessageFor(changeList)?.takeIf { it.isNotBlank() }
?: getCommitMessageFromVcs(changesSupplier())
?: vcsConfiguration.LAST_COMMIT_MESSAGE
fun save(changeList: LocalChangeList?, commitMessage: String, saveToHistory: Boolean) {
if (saveToHistory) vcsConfiguration.saveCommitMessage(commitMessage)
changeList?.let { save(it.name, commitMessage) }
}
}
@@ -6,7 +6,6 @@ import com.intellij.openapi.actionSystem.*
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.vcs.CheckinProjectPanel
import com.intellij.openapi.vcs.FilePath
import com.intellij.openapi.vcs.VcsConfiguration
import com.intellij.openapi.vcs.VcsDataKeys.COMMIT_WORKFLOW_HANDLER
import com.intellij.openapi.vcs.VcsException
import com.intellij.openapi.vcs.changes.*
@@ -16,6 +15,7 @@ import com.intellij.util.EventDispatcher
import com.intellij.vcs.commit.AbstractCommitWorkflow.Companion.getCommitExecutors
import gnu.trove.THashSet
import java.util.*
import kotlin.properties.Delegates.observable
private fun Collection<Change>.toPartialAwareSet() = THashSet(this, ChangeListChange.HASHING_STRATEGY)
@@ -37,6 +37,10 @@ class ChangesViewCommitWorkflowHandler(
private val inclusionModel = PartialCommitInclusionModel(project)
private var areCommitOptionsCreated = false
private val commitMessagePolicy = ChangesViewCommitMessagePolicy(project)
private var currentChangeList by observable<LocalChangeList?>(null) { _, oldValue, newValue ->
if (oldValue != newValue) changeListChanged(oldValue, newValue)
}
init {
Disposer.register(this, Disposable { workflow.disposeCommitOptions() })
@@ -125,6 +129,8 @@ class ChangesViewCommitWorkflowHandler(
val inclusion = inclusionModel.getInclusion()
val isChangeListFullyIncluded = changeList.changes.run { isNotEmpty() && all { it in inclusion } }
if (isChangeListFullyIncluded) ui.select(changeList) else ui.selectFirst(inclusion)
currentChangeList = workflow.getAffectedChangeList(inclusion.filterIsInstance<Change>())
}
private fun setInclusion(items: Collection<Any>, force: Boolean) {
@@ -164,6 +170,13 @@ class ChangesViewCommitWorkflowHandler(
fun showCommitOptions(isFromToolbar: Boolean, dataContext: DataContext) =
ui.showCommitOptions(ensureCommitOptions(), getCommitActionName(), isFromToolbar, dataContext)
private fun changeListChanged(oldChangeList: LocalChangeList?, newChangeList: LocalChangeList?) {
oldChangeList?.let { commitMessagePolicy.save(it, getCommitMessage(), false) }
val newCommitMessage = newChangeList?.let { commitMessagePolicy.getCommitMessage(it) { getIncludedChanges() } }
setCommitMessage(newCommitMessage)
}
override fun inclusionChanged() {
val inclusion = inclusionModel.getInclusion()
val activeChanges = changeListManager.defaultChangeList.changes
@@ -192,7 +205,7 @@ class ChangesViewCommitWorkflowHandler(
return super.saveCommitOptions()
}
override fun saveCommitMessage(success: Boolean) = VcsConfiguration.getInstance(project).saveCommitMessage(getCommitMessage())
override fun saveCommitMessage(success: Boolean) = commitMessagePolicy.save(currentChangeList, getCommitMessage(), success)
interface ActivityListener : EventListener {
fun activityStateChanged()
@@ -2,18 +2,11 @@
package com.intellij.vcs.commit
import com.intellij.openapi.project.Project
import com.intellij.openapi.vcs.AbstractVcs
import com.intellij.openapi.vcs.VcsConfiguration
import com.intellij.openapi.vcs.changes.Change
import com.intellij.openapi.vcs.changes.ChangeListManager
import com.intellij.openapi.vcs.changes.ChangesUtil
import com.intellij.openapi.vcs.changes.ChangesUtil.processChangesByVcs
import com.intellij.openapi.vcs.changes.LocalChangeList
import com.intellij.openapi.vcs.changes.ui.CommitMessageProvider
class SingleChangeListCommitMessagePolicy(private val project: Project, private val initialCommitMessage: String?) {
private val vcsConfiguration = VcsConfiguration.getInstance(project)
private val changeListManager = ChangeListManager.getInstance(project)
internal class SingleChangeListCommitMessagePolicy(project: Project, private val initialCommitMessage: String?) :
AbstractCommitMessagePolicy(project) {
var defaultNameChangeListMessage: String? = null
private var lastChangeListName: String? = null
@@ -66,33 +59,9 @@ class SingleChangeListCommitMessagePolicy(private val project: Project, private
saveMessages()
}
private fun getCommitMessageFor(changeList: LocalChangeList): String? {
CommitMessageProvider.EXTENSION_POINT_NAME.extensionList.forEach { provider ->
val providerMessage = provider.getCommitMessage(changeList, project)
if (providerMessage != null) return providerMessage
}
val changeListDescription = changeList.comment
if (!changeListDescription.isNullOrBlank()) return changeListDescription
return if (!changeList.hasDefaultName()) changeList.name else null
}
private fun getCommitMessageFromVcs(changes: List<Change>): String? {
var result: String? = null
processChangesByVcs(project, changes) { vcs, vcsChanges ->
if (result == null) result = getCommitMessageFromVcs(vcs, vcsChanges)
}
return result
}
private fun getCommitMessageFromVcs(vcs: AbstractVcs, changes: List<Change>): String? =
vcs.checkinEnvironment?.getDefaultMessageFor(ChangesUtil.getPaths(changes).toTypedArray())
private fun rememberMessage(message: String) = lastChangeListName?.let { messagesToSave[it] = message }
private fun forgetMessage() = lastChangeListName?.let { messagesToSave -= it }
private fun saveMessages() =
messagesToSave.forEach { changeListName, commitMessage -> changeListManager.editComment(changeListName, commitMessage) }
private fun saveMessages() = messagesToSave.forEach { (changeListName, commitMessage) -> save(changeListName, commitMessage) }
}
@@ -48,7 +48,7 @@ open class SingleChangeListCommitWorkflow(
val isPartialCommitEnabled: Boolean =
vcses.any { it.arePartialChangelistsSupported() } && (isDefaultCommitEnabled || commitExecutors.any { it.supportsPartialCommit() })
val commitMessagePolicy: SingleChangeListCommitMessagePolicy = SingleChangeListCommitMessagePolicy(project, initialCommitMessage)
internal val commitMessagePolicy: SingleChangeListCommitMessagePolicy = SingleChangeListCommitMessagePolicy(project, initialCommitMessage)
internal lateinit var commitState: ChangeListCommitState