mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 13:02:30 +07:00
IJPL-157219 SE - use IdeNavigationService, fire fileOpened for remote dev
GitOrigin-RevId: b027948a20e7872e5d16de5e534357836eaab1e3
This commit is contained in:
committed by
intellij-monorepo-bot
parent
aa6061cd40
commit
39afeda85c
@@ -3,7 +3,7 @@
|
||||
|
||||
package com.intellij.ide.actions.searcheverywhere
|
||||
|
||||
import com.intellij.codeInsight.navigation.activateFileWithPsiElement
|
||||
import com.intellij.codeWithMe.ClientId
|
||||
import com.intellij.ide.actions.GotoActionBase
|
||||
import com.intellij.ide.actions.OpenInRightSplitAction.Companion.openInRightSplit
|
||||
import com.intellij.ide.actions.QualifiedNameProviderUtil
|
||||
@@ -24,6 +24,7 @@ import com.intellij.openapi.actionSystem.impl.SimpleDataContext
|
||||
import com.intellij.openapi.application.*
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.components.serviceAsync
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
@@ -33,6 +34,8 @@ import com.intellij.openapi.project.DumbService.Companion.isDumbAware
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.platform.backend.navigation.NavigationRequests
|
||||
import com.intellij.platform.ide.navigation.NavigationService
|
||||
import com.intellij.platform.util.coroutines.childScope
|
||||
import com.intellij.pom.Navigatable
|
||||
import com.intellij.psi.PsiElement
|
||||
@@ -371,7 +374,7 @@ abstract class AbstractGotoSEContributor protected constructor(event: AnActionEv
|
||||
return true
|
||||
}
|
||||
|
||||
myProject.service<SearchEverywhereContributorCoroutineScopeHolder>().coroutineScope.launch {
|
||||
myProject.service<SearchEverywhereContributorCoroutineScopeHolder>().coroutineScope.launch(ClientId.coroutineContext()) {
|
||||
val command = readAction {
|
||||
val psiElement = preparePsi(selected, searchText)
|
||||
val extNavigatable = createExtendedNavigatable(psi = psiElement, searchText = searchText, modifiers = modifiers)
|
||||
@@ -379,16 +382,28 @@ abstract class AbstractGotoSEContributor protected constructor(event: AnActionEv
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
if ((modifiers and InputEvent.SHIFT_MASK) != 0 && file != null) {
|
||||
Runnable { openInRightSplit(project = myProject, file = file, element = extNavigatable, requestFocus = true) }
|
||||
suspend {
|
||||
withContext(Dispatchers.EDT + ModalityState.nonModal().asContextElement()) {
|
||||
openInRightSplit(project = myProject, file = file, element = extNavigatable, requestFocus = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Runnable { doNavigate(psiElement, extNavigatable) }
|
||||
suspend {
|
||||
if (extNavigatable == null) {
|
||||
val navigationRequests = serviceAsync<NavigationRequests>()
|
||||
readAction { navigationRequests.sourceNavigationRequest(myProject, file!!, -1, null) }?.let {
|
||||
myProject.serviceAsync<NavigationService>().navigate(it)
|
||||
}
|
||||
}
|
||||
else {
|
||||
myProject.serviceAsync<NavigationService>().navigate(extNavigatable)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
withContext(Dispatchers.EDT + ModalityState.nonModal().asContextElement()) {
|
||||
command.run()
|
||||
}
|
||||
command()
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -475,15 +490,6 @@ private fun getSelectedScopes(project: Project): MutableMap<String, String?> {
|
||||
return map
|
||||
}
|
||||
|
||||
private fun doNavigate(psiElement: PsiElement, extNavigatable: Navigatable?) {
|
||||
if (extNavigatable != null && extNavigatable.canNavigate()) {
|
||||
extNavigatable.navigate(true)
|
||||
}
|
||||
else {
|
||||
activateFileWithPsiElement(element = psiElement, searchForOpen = true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getLineAndColumnRegexpGroup(text: String, groupNumber: Int): Int {
|
||||
val matcher = ourPatternToDetectLinesAndColumns.matcher(text)
|
||||
if (matcher.matches()) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.ide.actions.searcheverywhere
|
||||
|
||||
import com.intellij.codeWithMe.ClientId
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker
|
||||
import com.intellij.ide.IdeBundle
|
||||
import com.intellij.ide.actions.OpenInRightSplitAction.Companion.openInRightSplit
|
||||
@@ -16,6 +17,7 @@ import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.application.readAction
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.components.serviceAsync
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
@@ -23,6 +25,8 @@ import com.intellij.openapi.fileEditor.OpenFileDescriptor
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.io.FileUtilRt
|
||||
import com.intellij.platform.backend.navigation.NavigationRequests
|
||||
import com.intellij.platform.ide.navigation.NavigationService
|
||||
import com.intellij.psi.PsiDirectory
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiFileSystemItem
|
||||
@@ -115,20 +119,30 @@ open class FileSearchEverywhereContributor(event: AnActionEvent) : AbstractGotoS
|
||||
}
|
||||
|
||||
val lineAndColumn = getLineAndColumn(searchText)
|
||||
val descriptor = OpenFileDescriptor(myProject, file, lineAndColumn.first, lineAndColumn.second)
|
||||
if (descriptor.canNavigate()) {
|
||||
myProject.service<SearchEverywhereContributorCoroutineScopeHolder>().coroutineScope.launch {
|
||||
withContext(Dispatchers.EDT) {
|
||||
@Suppress("DEPRECATION")
|
||||
if ((modifiers and InputEvent.SHIFT_MASK) != 0) {
|
||||
openInRightSplit(project = myProject, file = file, element = descriptor, requestFocus = true)
|
||||
}
|
||||
else {
|
||||
descriptor.navigate(true)
|
||||
if (file.isValid) {
|
||||
if (lineAndColumn.first == -1 && lineAndColumn.second == -1) {
|
||||
myProject.service<SearchEverywhereContributorCoroutineScopeHolder>().coroutineScope.launch(ClientId.coroutineContext()) {
|
||||
val navigationRequests = serviceAsync<NavigationRequests>()
|
||||
readAction { navigationRequests.sourceNavigationRequest(myProject, file, -1, null) }?.let {
|
||||
myProject.serviceAsync<NavigationService>().navigate(it)
|
||||
}
|
||||
}
|
||||
if (lineAndColumn.first > 0) {
|
||||
serviceAsync<FeatureUsageTracker>().triggerFeatureUsed("navigation.goto.file.line")
|
||||
}
|
||||
else {
|
||||
val descriptor = OpenFileDescriptor(myProject, file, lineAndColumn.first, lineAndColumn.second)
|
||||
myProject.service<SearchEverywhereContributorCoroutineScopeHolder>().coroutineScope.launch(ClientId.coroutineContext()) {
|
||||
@Suppress("DEPRECATION")
|
||||
if ((modifiers and InputEvent.SHIFT_MASK) != 0) {
|
||||
withContext(Dispatchers.EDT) {
|
||||
openInRightSplit(project = myProject, file = file, element = descriptor, requestFocus = true)
|
||||
}
|
||||
}
|
||||
else {
|
||||
myProject.serviceAsync<NavigationService>().navigate(descriptor)
|
||||
}
|
||||
if (lineAndColumn.first > 0) {
|
||||
serviceAsync<FeatureUsageTracker>().triggerFeatureUsed("navigation.goto.file.line")
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
||||
@@ -27,5 +27,5 @@ interface NavigationService {
|
||||
suspend fun navigate(navigatables: List<Navigatable>, options: NavigationOptions): Boolean
|
||||
|
||||
@Internal // compatibility function
|
||||
suspend fun navigate(navigatable: Navigatable, options: NavigationOptions): Boolean
|
||||
suspend fun navigate(navigatable: Navigatable, options: NavigationOptions = NavigationOptions.defaultOptions()): Boolean
|
||||
}
|
||||
|
||||
@@ -76,7 +76,10 @@ data class EditorCompositeModel internal constructor(
|
||||
|
||||
// workaround for remote dev, where we cannot yet implement correctly
|
||||
@Internal
|
||||
class PrecomputedFlow(@JvmField val model: EditorCompositeModel) : Flow<EditorCompositeModel> {
|
||||
class PrecomputedFlow(
|
||||
@JvmField internal val model: EditorCompositeModel,
|
||||
@JvmField internal val fireFileOpened: Boolean,
|
||||
) : Flow<EditorCompositeModel> {
|
||||
override suspend fun collect(collector: FlowCollector<EditorCompositeModel>) {
|
||||
error("Must not be called")
|
||||
}
|
||||
@@ -135,7 +138,12 @@ open class EditorComposite internal constructor(
|
||||
EDT.assertIsEdt()
|
||||
|
||||
if (model is PrecomputedFlow) {
|
||||
blockingHandleModel(model.model)
|
||||
if (model.fireFileOpened) {
|
||||
blockingHandleModel(model.model)
|
||||
}
|
||||
else {
|
||||
blockingHandleModel2(model.model)
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ApplicationManager.getApplication().isHeadlessEnvironment) {
|
||||
@@ -277,18 +285,67 @@ open class EditorComposite internal constructor(
|
||||
}
|
||||
}
|
||||
|
||||
val states = oldBadForRemoteDevGetStates(fileEditorWithProviders = fileEditorWithProviders, state = model.state)
|
||||
applyFileEditorsInEdt(fileEditorWithProviders = fileEditorWithProviders, selectedFileEditorProvider = null, states = states)
|
||||
}
|
||||
|
||||
private fun oldBadForRemoteDevGetStates(
|
||||
fileEditorWithProviders: List<FileEditorWithProvider>,
|
||||
state: FileEntry?,
|
||||
): List<FileEditorState?> {
|
||||
val states = fileEditorWithProviders.map { (_, provider) ->
|
||||
if (model.state == null) {
|
||||
if (state == null) {
|
||||
// We have to try to get state from the history only in case of the editor is not opened.
|
||||
// Otherwise, history entry might have a state out of sync with the current editor state.
|
||||
EditorHistoryManager.getInstance(project).getState(file, provider)
|
||||
}
|
||||
else {
|
||||
model.state.providers.get(provider.editorTypeId)?.let { provider.readState(it, project, file) }
|
||||
state.providers.get(provider.editorTypeId)?.let { provider.readState(it, project, file) }
|
||||
}
|
||||
}
|
||||
return states
|
||||
}
|
||||
|
||||
// for remote dev - we don't care about performance for now
|
||||
@RequiresEdt
|
||||
private fun blockingHandleModel2(model: EditorCompositeModel) {
|
||||
val fileEditorWithProviders = model.fileEditorAndProviderList
|
||||
|
||||
for (editorWithProvider in fileEditorWithProviders) {
|
||||
val editor = editorWithProvider.fileEditor
|
||||
FileEditor.FILE_KEY.set(editor, file)
|
||||
if (!clientId.isLocal) {
|
||||
assignClientId(editor, clientId)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO comment this and log a warning or log something
|
||||
if (fileEditorWithProviders.isEmpty()) {
|
||||
compositePanel.removeAll()
|
||||
_selectedEditorWithProvider.value = null
|
||||
return
|
||||
}
|
||||
|
||||
val messageBus = project.messageBus
|
||||
val deferredPublishers = messageBus.syncAndPreloadPublisher(FileOpenedSyncListener.TOPIC) to
|
||||
messageBus.syncAndPreloadPublisher(FileEditorManagerListener.FILE_EDITOR_MANAGER)
|
||||
|
||||
val beforePublisher = project.messageBus.syncAndPreloadPublisher(FileEditorManagerListener.Before.FILE_EDITOR_MANAGER)
|
||||
|
||||
val fileEditorManager = FileEditorManager.getInstance(project)
|
||||
|
||||
beforePublisher!!.beforeFileOpened(fileEditorManager, file)
|
||||
|
||||
val states = oldBadForRemoteDevGetStates(fileEditorWithProviders = fileEditorWithProviders, state = model.state)
|
||||
applyFileEditorsInEdt(fileEditorWithProviders = fileEditorWithProviders, selectedFileEditorProvider = null, states = states)
|
||||
|
||||
val (goodPublisher, deprecatedPublisher) = deferredPublishers
|
||||
goodPublisher.fileOpenedSync(fileEditorManager, file, fileEditorWithProviders)
|
||||
@Suppress("DEPRECATION")
|
||||
deprecatedPublisher.fileOpenedSync(fileEditorManager, file, fileEditorWithProviders)
|
||||
|
||||
val publisher = project.messageBus.syncAndPreloadPublisher(FileEditorManagerListener.FILE_EDITOR_MANAGER)
|
||||
publisher.fileOpened(fileEditorManager, file)
|
||||
}
|
||||
|
||||
@RequiresEdt
|
||||
@@ -930,7 +987,8 @@ internal fun focusEditorOnComposite(
|
||||
splitters: EditorsSplitters,
|
||||
toFront: Boolean = true,
|
||||
): Boolean {
|
||||
val currentSelectedComposite = splitters.currentCompositeFlow.value
|
||||
val currentWindow = splitters.currentWindow
|
||||
val currentSelectedComposite = currentWindow?.selectedComposite
|
||||
// while the editor was loading, the user switched to another editor - don't steal focus
|
||||
if (currentSelectedComposite === composite) {
|
||||
val preferredFocusedComponent = composite.preferredFocusedComponent
|
||||
@@ -939,10 +997,14 @@ internal fun focusEditorOnComposite(
|
||||
return false
|
||||
}
|
||||
else {
|
||||
preferredFocusedComponent.requestFocusInWindow()
|
||||
if (toFront) {
|
||||
IdeFocusManager.getGlobalInstance().toFront(splitters)
|
||||
IdeFocusManager.getGlobalInstance().toFront(preferredFocusedComponent)
|
||||
preferredFocusedComponent.requestFocus()
|
||||
}
|
||||
else {
|
||||
preferredFocusedComponent.requestFocusInWindow()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,9 +150,12 @@ internal class EditorCompositeModelManager(
|
||||
|
||||
fun blockingFileEditorWithProviderFlow(
|
||||
editorsWithProviders: List<FileEditorWithProvider>,
|
||||
): PrecomputedFlow {
|
||||
): Flow<EditorCompositeModel> {
|
||||
postProcessFileEditorWithProviderList(editorsWithProviders)
|
||||
return PrecomputedFlow(EditorCompositeModel(fileEditorAndProviderList = editorsWithProviders, state = null))
|
||||
return PrecomputedFlow(
|
||||
model = EditorCompositeModel(fileEditorAndProviderList = editorsWithProviders, state = null),
|
||||
fireFileOpened = true,
|
||||
)
|
||||
}
|
||||
|
||||
private fun postProcessFileEditorWithProviderList(editorsWithProviders: List<FileEditorWithProvider>) {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
package com.intellij.openapi.fileEditor.impl
|
||||
|
||||
import com.intellij.codeWithMe.ClientId
|
||||
import com.intellij.featureStatistics.fusCollectors.FileEditorCollector
|
||||
import com.intellij.featureStatistics.fusCollectors.FileEditorCollector.EmptyStateCause
|
||||
import com.intellij.icons.AllIcons
|
||||
@@ -396,7 +397,7 @@ class EditorWindow internal constructor(
|
||||
owner.setCurrentWindow(window = this@EditorWindow)
|
||||
}
|
||||
|
||||
composite.coroutineScope.launch(Dispatchers.EDT) {
|
||||
composite.coroutineScope.launch(Dispatchers.EDT + ClientId.coroutineContext() + ModalityState.any().asContextElement()) {
|
||||
if (!isHeadless) {
|
||||
owner.setCurrentWindow(window = this@EditorWindow)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.openapi.wm.impl;
|
||||
|
||||
import com.intellij.concurrency.ContextAwareRunnable;
|
||||
|
||||
Reference in New Issue
Block a user