IJPL-846 remove virtual file preloading (quite questionable) and instead, compute document in a separate coroutine

GitOrigin-RevId: 491dc693a58478d916a819057d4e7fc7e98bb5f0
This commit is contained in:
Vladimir Krivosheev
2024-03-24 23:01:05 +00:00
committed by intellij-monorepo-bot
parent acc1a4af28
commit df12b53953
2 changed files with 68 additions and 55 deletions
@@ -18,6 +18,7 @@ import com.intellij.openapi.client.ClientSessionsManager
import com.intellij.openapi.components.serviceAsync
import com.intellij.openapi.components.serviceOrNull
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.editor.Document
import com.intellij.openapi.editor.colors.CodeInsightColors
import com.intellij.openapi.editor.colors.EditorColorsManager
import com.intellij.openapi.editor.markup.TextAttributes
@@ -29,7 +30,6 @@ import com.intellij.openapi.fileEditor.impl.text.FileDropHandler
import com.intellij.openapi.keymap.Keymap
import com.intellij.openapi.keymap.KeymapManagerListener
import com.intellij.openapi.keymap.KeymapUtil
import com.intellij.openapi.progress.blockingContext
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.Divider
import com.intellij.openapi.ui.OnePixelDivider
@@ -913,7 +913,7 @@ private class UiBuilder(private val splitters: EditorsSplitters) {
}
val fileEditorManager = splitters.manager
val fileDocumentManager = serviceAsync<FileDocumentManager>()
var fileDocumentManager: FileDocumentManager? = null
val fileEditorProviderManager = serviceAsync<FileEditorProviderManager>()
fun weight(item: FileEntry) = (if (item.currentInTab) 1 else 0)
@@ -930,27 +930,34 @@ private class UiBuilder(private val splitters: EditorsSplitters) {
span("opening editor") {
val file = resolveFileOrLogError(virtualFileManager, fileEntry) ?: return@span
file.putUserData(AsyncEditorLoader.OPENED_IN_BULK, true)
// preload filetype
splitters.coroutineScope.launch {
blockingContext {
file.fileType
}
}
if (isFirstInBulk) {
// Add the selected tab to EditorTabs without waiting for the other tabs to load on startup.
// This enables painting the first editor as soon as it's ready (IJPL-687).
file.putUserData(AsyncEditorLoader.FIRST_IN_BULK, true)
isFirstInBulk = false
}
try {
openFile(file = file,
fileEntry = fileEntry,
fileEditorProviderManager = fileEditorProviderManager,
fileEditorManager = fileEditorManager,
fileDocumentManager = fileDocumentManager,
windowDeferred = windowDeferred,
index = index)
if (isFirstInBulk) {
// Add the selected tab to EditorTabs without waiting for the other tabs to load on startup.
// This enables painting the first editor as soon as it's ready (IJPL-687).
file.putUserData(AsyncEditorLoader.FIRST_IN_BULK, true)
isFirstInBulk = false
}
val document = async {
var m = fileDocumentManager
if (m == null) {
m = serviceAsync<FileDocumentManager>()
fileDocumentManager = m
}
readAction {
m.getDocument(file)
}
}
openFile(
file = file,
fileEntry = fileEntry,
fileEditorProviderManager = fileEditorProviderManager,
fileEditorManager = fileEditorManager,
document = document,
windowDeferred = windowDeferred,
index = index,
)
if (fileEntry.currentInTab) {
focusedFile = file
}
@@ -990,13 +997,15 @@ private fun resolveFileOrLogError(virtualFileManager: VirtualFileManager, fileEn
return null
}
private suspend fun openFile(file: VirtualFile,
fileEntry: FileEntry,
fileEditorProviderManager: FileEditorProviderManager,
fileEditorManager: FileEditorManagerImpl,
fileDocumentManager: FileDocumentManager,
windowDeferred: Deferred<EditorWindow>,
index: Int) {
private suspend fun openFile(
file: VirtualFile,
fileEntry: FileEntry,
fileEditorProviderManager: FileEditorProviderManager,
fileEditorManager: FileEditorManagerImpl,
document: Deferred<Document?>,
windowDeferred: Deferred<EditorWindow>,
index: Int,
) {
coroutineScope {
val deferredProviders: Deferred<List<FileEditorProvider>> = if (fileEntry.ideFingerprint == ideFingerprint()) {
async(CoroutineName("editor provider resolving")) {
@@ -1039,10 +1048,6 @@ private suspend fun openFile(file: VirtualFile,
}
}
val document = readAction {
fileDocumentManager.getDocument(file)
}
val session = fileEditorManager.project.serviceAsync<ClientSessionsManager<ClientProjectSession>>().getSession(ClientId.current)
val options = FileEditorOpenOptions(
selectAsCurrent = false,
@@ -2101,12 +2101,14 @@ open class FileEditorManagerImpl(
}
}
internal suspend fun openFileOnStartup(windowDeferred: Deferred<EditorWindow>,
file: VirtualFile,
document: Document?,
fileEditorStateProvider: FileEditorStateProvider,
options: FileEditorOpenOptions,
providers: List<FileEditorProvider>) {
internal suspend fun openFileOnStartup(
windowDeferred: Deferred<EditorWindow>,
file: VirtualFile,
document: Deferred<Document?>,
fileEditorStateProvider: FileEditorStateProvider,
options: FileEditorOpenOptions,
providers: List<FileEditorProvider>,
) {
if (!canOpenFile(file = file, providers = providers)) {
return
}
@@ -2114,17 +2116,19 @@ open class FileEditorManagerImpl(
// the file is not opened yet - in this case we have to create editors and select the created EditorComposite
coroutineScope {
val providerWithBuilderList = async {
createBuilders(providers = providers, file = file, project = project, document = document)
createBuilders(providers = providers, file = file, project = project, document = document.await())
}
val window = windowDeferred.await()
val existingComposite = withContext(Dispatchers.EDT) { window.getComposite(file) }
openFileInEdt(existingComposite = existingComposite,
window = window,
file = file,
fileEditorStateProvider = fileEditorStateProvider,
options = options,
providerWithBuilderList = providerWithBuilderList.await())
openFileInEdt(
existingComposite = existingComposite,
window = window,
file = file,
fileEditorStateProvider = fileEditorStateProvider,
options = options,
providerWithBuilderList = providerWithBuilderList.await(),
)
}
}
@@ -2178,11 +2182,13 @@ open class FileEditorManagerImpl(
}
else {
for (editorWithProvider in composite.allEditorsWithProviders) {
restoreEditorState(file = file,
editorWithProvider = editorWithProvider,
storedState = fileEditorStateProvider?.getState(editorWithProvider.provider),
isNewEditor = isNewEditor,
exactState = options.isExactState)
restoreEditorState(
file = file,
editorWithProvider = editorWithProvider,
storedState = fileEditorStateProvider?.getState(editorWithProvider.provider),
isNewEditor = isNewEditor,
exactState = options.isExactState,
)
}
openInEdtImpl(
@@ -2389,10 +2395,12 @@ private fun getEffectiveOptions(options: FileEditorOpenOptions, entry: HistoryEn
return options
}
private suspend fun createBuilders(providers: List<FileEditorProvider>,
file: VirtualFile,
project: Project,
document: Document?): List<kotlin.Pair<FileEditorProvider, AsyncFileEditorProvider.Builder?>> {
private suspend fun createBuilders(
providers: List<FileEditorProvider>,
file: VirtualFile,
project: Project,
document: Document?,
): List<kotlin.Pair<FileEditorProvider, AsyncFileEditorProvider.Builder?>> {
return coroutineScope {
providers.map { provider ->
async {