[textmate] do not lose bundle name from the loading context (IDEA-326758)

GitOrigin-RevId: e614e81669a92b7c0f9889d21ebf4486a9fd2462
This commit is contained in:
Alexander Zolotov
2023-07-31 21:10:22 +00:00
committed by intellij-monorepo-bot
parent 2ea935cfb5
commit 274e0b3e9b
4 changed files with 47 additions and 40 deletions
@@ -94,34 +94,29 @@ public final class TextMateServiceImpl extends TextMateService {
TextMateBuiltinBundlesSettings builtinBundlesSettings = TextMateBuiltinBundlesSettings.getInstance();
if (builtinBundlesSettings != null) {
Set<String> turnedOffBundleNames = builtinBundlesSettings.getTurnedOffBundleNames();
List<Path> builtInBundles = discoverBuiltinBundles(builtinBundlesSettings);
List<Path> bundlesToEnable = turnedOffBundleNames.isEmpty()
? builtInBundles
: ContainerUtil.filter(builtInBundles, bundlePath -> !turnedOffBundleNames.contains(bundlePath.getFileName().toString()));
List<TextMateBundleToLoad> builtInBundles = discoverBuiltinBundles(builtinBundlesSettings);
List<TextMateBundleToLoad> bundlesToEnable = turnedOffBundleNames.isEmpty()
? builtInBundles
: ContainerUtil.filter(builtInBundles,
bundleToLoad -> !turnedOffBundleNames.contains(bundleToLoad.getName()));
TextMateBundlesLoader.registerBundlesInParallel(myScope,
bundlesToEnable,
bundlePath -> registerBundle(bundlePath, newExtensionsMapping));
bundleToLoad -> registerBundle(Path.of(bundleToLoad.getPath()), newExtensionsMapping));
}
}
Map<String, TextMatePersistentBundle> userBundles = settings.getBundles();
if (!userBundles.isEmpty()) {
List<@NotNull Path> paths = ContainerUtil.mapNotNull(userBundles.entrySet(), entry -> {
if (!entry.getValue().getEnabled()) return null;
try {
return Path.of(entry.getKey());
}
catch (InvalidPathException e) {
return null;
}
List<@NotNull TextMateBundleToLoad> paths = ContainerUtil.mapNotNull(userBundles.entrySet(), entry -> {
return entry.getValue().getEnabled() ? new TextMateBundleToLoad(entry.getValue().getName(), entry.getKey()) : null;
});
TextMateBundlesLoader.registerBundlesInParallel(myScope, paths, bundlePath -> {
return registerBundle(bundlePath, newExtensionsMapping);
}, path -> {
String bundleName = path.getFileName().toString();
TextMateBundlesLoader.registerBundlesInParallel(myScope, paths, bundleToLoad -> {
return registerBundle(Path.of(bundleToLoad.getPath()), newExtensionsMapping);
}, bundleToLoad -> {
String bundleName = bundleToLoad.getName();
String errorMessage = TextMateBundle.message("textmate.cant.register.bundle", bundleName);
new Notification("TextMate Bundles", TextMateBundle.message("textmate.bundle.load.error", bundleName), errorMessage, NotificationType.ERROR)
.addAction(NotificationAction.createSimpleExpiring(TextMateBundle.message("textmate.disable.bundle.notification.action", bundleName), () -> settings.disableBundle(path.toString())))
.addAction(NotificationAction.createSimpleExpiring(TextMateBundle.message("textmate.disable.bundle.notification.action", bundleName), () -> settings.disableBundle(bundleToLoad.getPath())))
.notify(null);
});
}
@@ -150,12 +145,15 @@ public final class TextMateServiceImpl extends TextMateService {
}, ModalityState.nonModal());
}
private static List<Path> discoverBuiltinBundles(@NotNull TextMateBuiltinBundlesSettings builtinBundlesSettings) {
List<Path> builtinBundles = builtinBundlesSettings.getBuiltinBundles();
private static List<TextMateBundleToLoad> discoverBuiltinBundles(@NotNull TextMateBuiltinBundlesSettings builtinBundlesSettings) {
List<TextMateBundleToLoad> builtinBundles = builtinBundlesSettings.getBuiltinBundles();
if (builtinBundles.isEmpty()) {
Path builtinBundlesPath = getBundledBundlePath();
try (Stream<Path> files = Files.list(builtinBundlesPath)) {
List<Path> bundles = files.filter(file -> !StringUtil.startsWithChar(file.getFileName().toString(), '.')).toList();
List<TextMateBundleToLoad> bundles = files
.filter(file -> !StringUtil.startsWithChar(file.getFileName().toString(), '.'))
.map(file -> new TextMateBundleToLoad(file.getFileName().toString(), file.toString()))
.toList();
builtinBundlesSettings.setBuiltinBundles(bundles);
return bundles;
}
@@ -8,31 +8,42 @@ import com.intellij.openapi.util.IntellijInternalApi
import com.intellij.util.io.blockingDispatcher
import kotlinx.coroutines.*
import kotlinx.coroutines.future.asCompletableFuture
import java.nio.file.Path
import java.util.function.Consumer
@OptIn(DelicateCoroutinesApi::class)
@IntellijInternalApi
@JvmOverloads
internal fun registerBundlesInParallel(scope: CoroutineScope,
bundlePaths: List<Path>,
registrar: (Path) -> Boolean,
registrationFailed: Consumer<Path>? = null) {
bundlesToLoad: List<TextMateBundleToLoad>,
registrar: (TextMateBundleToLoad) -> Boolean,
registrationFailed: Consumer<TextMateBundleToLoad>? = null) {
suspend fun handleError(bundleToLoad: TextMateBundleToLoad, t: Throwable? = null) {
if (registrationFailed == null) {
TextMateService.LOG.error("Cannot load builtin textmate bundle", t, bundleToLoad.toString())
}
else {
withContext(Dispatchers.EDT) {
registrationFailed.accept(bundleToLoad)
}
}
}
val initializationJob = scope.launch(blockingDispatcher) {
bundlePaths.map { bundlePath ->
bundlesToLoad.map { bundleToLoad ->
launch {
if (!registrar(bundlePath)) {
if (registrationFailed == null) {
TextMateService.LOG.error("Cannot load builtin textmate bundle", bundlePath.toString())
}
else {
withContext(Dispatchers.EDT) {
registrationFailed.accept(bundlePath)
}
runCatching {
registrar(bundleToLoad)
}.onFailure { t ->
handleError(bundleToLoad, t)
}.onSuccess { registered ->
if (!registered) {
handleError(bundleToLoad)
}
}
}
}
}
ProgressIndicatorUtils.awaitWithCheckCanceled(initializationJob.asCompletableFuture())
}
}
data class TextMateBundleToLoad(val name: String, val path: String)
@@ -5,6 +5,7 @@ import com.intellij.openapi.components.SerializablePersistentStateComponent
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.State
import com.intellij.openapi.components.Storage
import org.jetbrains.plugins.textmate.TextMateBundleToLoad
import java.nio.file.Path
@State(name = "TextMateBuiltinBundlesSettings", storages = [Storage(value = "textmateBuiltinBundles.xml")])
@@ -16,7 +17,7 @@ class TextMateBuiltinBundlesSettings : SerializablePersistentStateComponent<Text
get() = ApplicationManager.getApplication().getService(TextMateBuiltinBundlesSettings::class.java)
}
var builtinBundles: List<Path> = emptyList()
var builtinBundles: List<TextMateBundleToLoad> = emptyList()
fun setTurnedOffBundleNames(names: Collection<String>) {
updateState { State(names.sorted()) }
@@ -1,8 +1,5 @@
package org.jetbrains.plugins.textmate.configuration
import kotlin.io.path.name
import kotlin.io.path.pathString
class TextMateConfigurableData(private val builtinBundlesSettings: TextMateBuiltinBundlesSettings,
private val userBundlesSettings: TextMateUserBundlesSettings) {
companion object {
@@ -28,7 +25,7 @@ class TextMateConfigurableData(private val builtinBundlesSettings: TextMateBuilt
return buildSet {
val turnedOffBundleNames = builtinBundlesSettings.getTurnedOffBundleNames()
addAll(builtinBundlesSettings.builtinBundles.map { path ->
TextMateConfigurableBundle(path.name, path.pathString, enabled = !turnedOffBundleNames.contains(path.name), builtin = true)
TextMateConfigurableBundle(path.name, path.path, enabled = !turnedOffBundleNames.contains(path.name), builtin = true)
})
addAll(userBundlesSettings.bundles.map { (path, bundle) ->
TextMateConfigurableBundle(bundle.name, path, enabled = bundle.enabled, builtin = false)