diff --git a/plugins/settings-sync/git/src/com/intellij/settingsSync/git/record/ChangeRecord.kt b/plugins/settings-sync/git/src/com/intellij/settingsSync/git/record/ChangeRecord.kt index f58a606e14c8..38c048ef83d7 100644 --- a/plugins/settings-sync/git/src/com/intellij/settingsSync/git/record/ChangeRecord.kt +++ b/plugins/settings-sync/git/src/com/intellij/settingsSync/git/record/ChangeRecord.kt @@ -129,7 +129,7 @@ internal class ChangeRecord(commitId: Int, if (fileName == GitSettingsLog.PLUGINS_FILE) return SettingsCategory.PLUGINS //workaround empty category - return getCategory(fileName) ?: SettingsCategory.OTHER + return getCategory(fileName)?.first ?: SettingsCategory.OTHER } val changesCategories = changes.map { getChangeCategory(it) }.distinct().sortedBy { getCategoryOrder(it) }.map { toString(it) } diff --git a/plugins/settings-sync/src/com/intellij/settingsSync/SettingsSyncBridge.kt b/plugins/settings-sync/src/com/intellij/settingsSync/SettingsSyncBridge.kt index a154d149d59d..a14eec4e7f80 100644 --- a/plugins/settings-sync/src/com/intellij/settingsSync/SettingsSyncBridge.kt +++ b/plugins/settings-sync/src/com/intellij/settingsSync/SettingsSyncBridge.kt @@ -92,6 +92,9 @@ class SettingsSyncBridge( coroutineScope.launch { withProgressText(SettingsSyncBundle.message(initMode.messageKey)) { try { + // Always explicitly flush settings – if this is not done before sending sync events, then remotely synced settings + // might not contain the most up–to–date settings state (e.g. sync settings will be stale). + saveIdeSettings() settingsLog.initialize() // the queue is not activated initially => events will be collected but not processed until we perform all initialization tasks diff --git a/plugins/settings-sync/src/com/intellij/settingsSync/SettingsSyncFiltering.kt b/plugins/settings-sync/src/com/intellij/settingsSync/SettingsSyncFiltering.kt index fa83bc6a90fc..82c7606cac9b 100644 --- a/plugins/settings-sync/src/com/intellij/settingsSync/SettingsSyncFiltering.kt +++ b/plugins/settings-sync/src/com/intellij/settingsSync/SettingsSyncFiltering.kt @@ -10,20 +10,19 @@ import com.intellij.openapi.util.text.StringUtil import com.intellij.serviceContainer.ComponentManagerImpl import com.intellij.settingsSync.config.EDITOR_FONT_SUBCATEGORY_ID import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.ConcurrentMap internal fun isSyncCategoryEnabled(fileSpec: String): Boolean { val rawFileSpec = removeOsPrefix(fileSpec) if (rawFileSpec == SettingsSyncSettings.FILE_SPEC) return true - val category = getSchemeCategory(rawFileSpec) ?: getCategory(rawFileSpec) ?: return false + val (category, subCategory) = getSchemeCategory(rawFileSpec) ?: getCategory(rawFileSpec) ?: return false if (category != SettingsCategory.OTHER && SettingsSyncSettings.getInstance().isCategoryEnabled(category)) { - val subCategory = getSubCategory(fileSpec) if (subCategory != null) { return SettingsSyncSettings.getInstance().isSubcategoryEnabled(category, subCategory) } + return true } return false @@ -34,26 +33,22 @@ private fun removeOsPrefix(fileSpec: String): String { return if (fileSpec.startsWith(osPrefix)) StringUtil.trimStart(fileSpec, osPrefix) else fileSpec } -private fun getCategory(componentClasses: List>>): SettingsCategory { - when { - componentClasses.isEmpty() -> return SettingsCategory.OTHER - componentClasses.size == 1 -> return ComponentCategorizer.getCategory(componentClasses[0]) - else -> { - componentClasses.forEach { - val category = ComponentCategorizer.getCategory(it) - if (category != SettingsCategory.OTHER) { - // Once found, ignore any other possibly conflicting definitions - return category - } - } - return SettingsCategory.OTHER +private fun getCategory(fileName: String, componentClasses: List>>): Pair { + componentClasses.forEach { + val category = ComponentCategorizer.getCategory(it) + + if (category != SettingsCategory.OTHER) { + // Once found, ignore any other possibly conflicting definitions + return (category to getSubCategory(fileName)) } } + + return SettingsCategory.OTHER to null } -private val categoryCache: ConcurrentMap = ConcurrentHashMap() +private val categoryCache: ConcurrentHashMap> = ConcurrentHashMap() -fun getCategory(fileName: String): SettingsCategory? { +fun getCategory(fileName: String): Pair? { categoryCache[fileName]?.let { cachedCategory -> return cachedCategory } @@ -64,14 +59,14 @@ fun getCategory(fileName: String): SettingsCategory? { return null } - val category = getSchemeCategory(fileName) ?: getCategory(componentClasses) + val category = getSchemeCategory(fileName) ?: getCategory(fileName, componentClasses) categoryCache[fileName] = category return category } -private fun getSchemeCategory(fileSpec: String): SettingsCategory? { +private fun getSchemeCategory(fileSpec: String): Pair? { // fileSpec is e.g. keymaps/mykeymap.xml val separatorIndex = fileSpec.indexOf("/") val directoryName = if (separatorIndex >= 0) fileSpec.substring(0, separatorIndex) else fileSpec // e.g. 'keymaps' @@ -82,12 +77,13 @@ private fun getSchemeCategory(fileSpec: String): SettingsCategory? { settingsCategory = it.getSettingsCategory() } } - return settingsCategory + if (settingsCategory == null) { + return null + } + + return settingsCategory!! to null } -fun getFileSpec(path: String): String { - return removeOsPrefix(path) -} private fun getSubCategory(fileSpec: String): String? { if (fileSpec == AppEditorFontOptions.STORAGE_NAME) diff --git a/plugins/settings-sync/src/com/intellij/settingsSync/config/SyncPluginsGroup.kt b/plugins/settings-sync/src/com/intellij/settingsSync/config/SyncPluginsGroup.kt index d1f51c023cb8..ec71b05f4511 100644 --- a/plugins/settings-sync/src/com/intellij/settingsSync/config/SyncPluginsGroup.kt +++ b/plugins/settings-sync/src/com/intellij/settingsSync/config/SyncPluginsGroup.kt @@ -18,6 +18,7 @@ internal class SyncPluginsGroup : SyncSubcategoryGroup { PluginManagerCore.plugins.forEach { if (!it.isBundled && SettingsSyncPluginCategoryFinder.getPluginCategory(it) == SettingsCategory.PLUGINS) { bundledPluginsDescriptor.isSubGroupEnd = true + // NOTE: the code in `com.intellij.settingsSync.SettingsSyncFilteringKt.getSubCategory` relies on the value being plugin ID descriptors.add(getOrCreateDescriptor(it.name, it.pluginId.idString)) } }