KT-32366: Refactor ScratchFileHook to make ScratchFile creation clear

- basically just move functions from `ScratchTopPanel` to `ScratchFileHook`
This commit is contained in:
Roman Golyshev
2019-08-16 17:41:05 +03:00
committed by Roman Golyshev
parent 70e6f738eb
commit ea3d070c98
3 changed files with 51 additions and 56 deletions
@@ -72,9 +72,4 @@ fun TextEditor.addScratchPanel(panel: ScratchTopPanel) {
panel.scratchFile.project.syncPublisherWithDisposeCheck(ScratchPanelListener.TOPIC).panelAdded(panel)
}
fun TextEditor.removeScratchPanel() {
scratchTopPanel?.let { FileEditorManager.getInstance(it.scratchFile.project).removeTopComponent(this, it.component) }
scratchTopPanel = null
}
private var TextEditor.scratchTopPanel: ScratchTopPanel? by UserDataProperty<TextEditor, ScratchTopPanel>(Key.create("scratch.panel"))
@@ -16,13 +16,18 @@
package org.jetbrains.kotlin.idea.scratch.ui
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.ProjectComponent
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.fileEditor.FileEditorManagerListener
import com.intellij.openapi.fileEditor.TextEditor
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiManager
import org.jetbrains.kotlin.idea.scratch.*
import org.jetbrains.kotlin.idea.scratch.output.InlayScratchOutputHandler
import org.jetbrains.kotlin.idea.scratch.output.ScratchOutputHandlerAdapter
class ScratchFileHook(val project: Project) : ProjectComponent {
@@ -30,17 +35,15 @@ class ScratchFileHook(val project: Project) : ProjectComponent {
project.messageBus.connect(project).subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, ScratchEditorListener())
}
override fun projectClosed() {
getAllEditorsWithScratchFiles(project).forEach { editor -> editor.removeScratchPanel() }
}
private inner class ScratchEditorListener : FileEditorManagerListener {
override fun fileOpened(source: FileEditorManager, file: VirtualFile) {
if (!isPluggable(file)) return
val editor = getEditorWithoutScratchFile(source, file) ?: return
ScratchTopPanel.createPanel(project, file, editor)
val scratchFile = createScratchFile(project, file, editor) ?: return
val panel = ScratchTopPanel(scratchFile)
editor.addScratchPanel(panel)
ScratchFileAutoRunner.addListener(project, editor)
}
@@ -55,3 +58,26 @@ class ScratchFileHook(val project: Project) : ProjectComponent {
return ScratchFileLanguageProvider.get(psiFile.fileType) != null
}
}
private fun createScratchFile(project: Project, file: VirtualFile, editor: TextEditor): ScratchFile? {
val psiFile = PsiManager.getInstance(project).findFile(file) ?: return null
val scratchFile = ScratchFileLanguageProvider.get(psiFile.language)?.newScratchFile(project, editor) ?: return null
setupReplRestartingOutputHandler(project, scratchFile)
return scratchFile
}
private fun setupReplRestartingOutputHandler(project: Project, scratchFile: ScratchFile) {
scratchFile.replScratchExecutor?.addOutputHandler(object : ScratchOutputHandlerAdapter() {
override fun onFinish(file: ScratchFile) {
ApplicationManager.getApplication().invokeLater {
if (!file.project.isDisposed) {
val scratch = file.getPsiFile()
if (scratch?.isValid == true) {
DaemonCodeAnalyzer.getInstance(project).restart(scratch)
}
}
}
}
})
}
@@ -17,67 +17,22 @@
package org.jetbrains.kotlin.idea.scratch.ui
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer
import com.intellij.openapi.Disposable
import com.intellij.openapi.actionSystem.*
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.fileEditor.TextEditor
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiManager
import com.intellij.util.messages.Topic
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.idea.scratch.ScratchFile
import org.jetbrains.kotlin.idea.scratch.ScratchFileLanguageProvider
import org.jetbrains.kotlin.idea.scratch.actions.ClearScratchAction
import org.jetbrains.kotlin.idea.scratch.actions.RunScratchAction
import org.jetbrains.kotlin.idea.scratch.actions.StopScratchAction
import org.jetbrains.kotlin.idea.scratch.addScratchPanel
import org.jetbrains.kotlin.idea.scratch.output.ScratchOutputHandlerAdapter
import org.jetbrains.kotlin.idea.scratch.removeScratchPanel
import javax.swing.JComponent
class ScratchTopPanel private constructor(val scratchFile: ScratchFile) : Disposable {
class ScratchTopPanel(val scratchFile: ScratchFile) : Disposable {
override fun dispose() {
scratchFile.replScratchExecutor?.stop()
scratchFile.compilingScratchExecutor?.stop()
scratchFile.editor.removeScratchPanel()
}
companion object {
fun createPanel(project: Project, virtualFile: VirtualFile, editor: TextEditor) {
val psiFile = PsiManager.getInstance(project).findFile(virtualFile) ?: return
val scratchFile = ScratchFileLanguageProvider.get(psiFile.language)?.newScratchFile(project, editor) ?: return
val panel = ScratchTopPanel(scratchFile)
val toolbarHandler = createUpdateToolbarHandler(panel)
scratchFile.replScratchExecutor?.addOutputHandler(object : ScratchOutputHandlerAdapter() {
override fun onFinish(file: ScratchFile) {
ApplicationManager.getApplication().invokeLater {
if (!file.project.isDisposed) {
val scratch = file.getPsiFile()
if (scratch?.isValid == true) {
DaemonCodeAnalyzer.getInstance(project).restart(scratch)
}
}
}
}
})
scratchFile.replScratchExecutor?.addOutputHandler(toolbarHandler)
scratchFile.compilingScratchExecutor?.addOutputHandler(toolbarHandler)
editor.addScratchPanel(panel)
}
private fun createUpdateToolbarHandler(panel: ScratchTopPanel) = object : ScratchOutputHandlerAdapter() {
override fun onStart(file: ScratchFile) {
panel.updateToolbar()
}
override fun onFinish(file: ScratchFile) {
panel.updateToolbar()
}
}
}
private val moduleChooserAction: ModulesComboBoxAction = ModulesComboBoxAction(scratchFile)
@@ -85,6 +40,7 @@ class ScratchTopPanel private constructor(val scratchFile: ScratchFile) : Dispos
init {
scratchFile.addModuleListener { _, _ -> updateToolbar() }
setupTopPanelUpdateHandlers()
val toolbarGroup = DefaultActionGroup().apply {
add(RunScratchAction())
@@ -105,6 +61,24 @@ class ScratchTopPanel private constructor(val scratchFile: ScratchFile) : Dispos
val component: JComponent = actionsToolbar.component
private fun setupTopPanelUpdateHandlers() {
val toolbarHandler = createUpdateToolbarHandler()
scratchFile.replScratchExecutor?.addOutputHandler(toolbarHandler)
scratchFile.compilingScratchExecutor?.addOutputHandler(toolbarHandler)
}
private fun createUpdateToolbarHandler(): ScratchOutputHandlerAdapter {
return object : ScratchOutputHandlerAdapter() {
override fun onStart(file: ScratchFile) {
updateToolbar()
}
override fun onFinish(file: ScratchFile) {
updateToolbar()
}
}
}
@TestOnly
fun setReplMode(isSelected: Boolean) {
scratchFile.saveOptions { copy(isRepl = isSelected) }