KT-33585: Refactor KtsScratchFileEditorWithPreview and its output handlers

- now `PreviewOutputBlocksManager` is injected into `PreviewEditorScratchOutputHandler`, so `KtsScratchFileEditorWithPreview` can use it too
This commit is contained in:
Roman Golyshev
2019-08-20 12:43:34 +03:00
committed by Roman Golyshev
parent edb700b898
commit d12d9d86bc
2 changed files with 31 additions and 32 deletions
@@ -6,7 +6,8 @@
package org.jetbrains.kotlin.idea.scratch.output package org.jetbrains.kotlin.idea.scratch.output
import com.intellij.diff.util.DiffUtil import com.intellij.diff.util.DiffUtil
import com.intellij.openapi.application.TransactionGuard import com.intellij.openapi.Disposable
import com.intellij.openapi.application.TransactionGuard
import com.intellij.openapi.application.runWriteAction import com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.editor.Document import com.intellij.openapi.editor.Document
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
@@ -15,7 +16,6 @@ import com.intellij.openapi.editor.FoldingModel
import com.intellij.openapi.editor.markup.HighlighterLayer import com.intellij.openapi.editor.markup.HighlighterLayer
import com.intellij.openapi.editor.markup.HighlighterTargetArea import com.intellij.openapi.editor.markup.HighlighterTargetArea
import com.intellij.openapi.editor.markup.MarkupModel import com.intellij.openapi.editor.markup.MarkupModel
import com.intellij.openapi.fileEditor.TextEditor
import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.idea.scratch.ScratchExpression import org.jetbrains.kotlin.idea.scratch.ScratchExpression
import org.jetbrains.kotlin.idea.scratch.ScratchFile import org.jetbrains.kotlin.idea.scratch.ScratchFile
@@ -23,20 +23,15 @@ import java.util.*
import kotlin.math.max import kotlin.math.max
/** /**
* Output handler to print scratch output to separate [previewTextEditor] window. * Output handler to print scratch output to separate window using [previewOutputBlocksManager].
* *
* Multiline outputs from single expressions are folded. * Multiline outputs from single expressions are folded.
*/ */
class PreviewEditorScratchOutputHandler( class PreviewEditorScratchOutputHandler(
private val previewTextEditor: TextEditor, private val previewOutputBlocksManager: PreviewOutputBlocksManager,
private val toolwindowHandler: ScratchOutputHandler private val toolwindowHandler: ScratchOutputHandler,
private val parentDisposable: Disposable
) : ScratchOutputHandler { ) : ScratchOutputHandler {
private val previewOutputBlocksManager: PreviewOutputBlocksManager = PreviewOutputBlocksManager(previewTextEditor.editor)
/**
* Returns pairs of line numbers which should be on the same visual positions during scrolling.
*/
val sourceToPreviewAlignments: Sequence<Pair<Int, Int>> get() = previewOutputBlocksManager.alignments
override fun onStart(file: ScratchFile) { override fun onStart(file: ScratchFile) {
toolwindowHandler.onStart(file) toolwindowHandler.onStart(file)
@@ -57,25 +52,19 @@ class PreviewEditorScratchOutputHandler(
override fun clear(file: ScratchFile) { override fun clear(file: ScratchFile) {
toolwindowHandler.clear(file) toolwindowHandler.clear(file)
previewOutputBlocksManager.clear() clearOutputManager()
clearPreviewEditor()
} }
private fun printToPreviewEditor(expression: ScratchExpression, output: ScratchOutput) { private fun printToPreviewEditor(expression: ScratchExpression, output: ScratchOutput) {
TransactionGuard.submitTransaction(previewTextEditor, Runnable { TransactionGuard.submitTransaction(parentDisposable, Runnable {
val targetCell = previewOutputBlocksManager.getBlock(expression) ?: previewOutputBlocksManager.addBlockToTheEnd(expression) val targetCell = previewOutputBlocksManager.getBlock(expression) ?: previewOutputBlocksManager.addBlockToTheEnd(expression)
targetCell.addOutput(output) targetCell.addOutput(output)
}) })
} }
private fun clearPreviewEditor() { private fun clearOutputManager() {
TransactionGuard.submitTransaction(previewTextEditor, Runnable { TransactionGuard.submitTransaction(parentDisposable, Runnable {
runWriteAction { previewOutputBlocksManager.clear()
executeCommand {
previewTextEditor.editor.document.setText("")
}
}
}) })
} }
} }
@@ -83,13 +72,13 @@ class PreviewEditorScratchOutputHandler(
private val ScratchExpression.height: Int get() = lineEnd - lineStart + 1 private val ScratchExpression.height: Int get() = lineEnd - lineStart + 1
class PreviewOutputBlocksManager(editor: Editor) { class PreviewOutputBlocksManager(editor: Editor) {
val targetDocument: Document = editor.document private val targetDocument: Document = editor.document
val foldingModel: FoldingModel = editor.foldingModel private val foldingModel: FoldingModel = editor.foldingModel
val markupModel: MarkupModel = editor.markupModel private val markupModel: MarkupModel = editor.markupModel
val blocks: NavigableMap<ScratchExpression, OutputBlock> = TreeMap(Comparator.comparingInt { it.lineStart }) private val blocks: NavigableMap<ScratchExpression, OutputBlock> = TreeMap(Comparator.comparingInt { it.lineStart })
val alignments: Sequence<Pair<Int, Int>> get() = blocks.values.asSequence().map { it.sourceExpression.lineStart to it.lineStart } fun computeSourceToPreviewAlignments(): List<Pair<Int, Int>> = blocks.values.map { it.sourceExpression.lineStart to it.lineStart }
fun getBlock(expression: ScratchExpression): OutputBlock? = blocks[expression] fun getBlock(expression: ScratchExpression): OutputBlock? = blocks[expression]
@@ -101,6 +90,11 @@ class PreviewOutputBlocksManager(editor: Editor) {
fun clear() { fun clear() {
blocks.clear() blocks.clear()
runWriteAction {
executeCommand {
targetDocument.setText("")
}
}
} }
inner class OutputBlock(val sourceExpression: ScratchExpression) { inner class OutputBlock(val sourceExpression: ScratchExpression) {
@@ -59,14 +59,19 @@ class KtScratchFileEditorWithPreview private constructor(
private val previewTextEditor: TextEditor private val previewTextEditor: TextEditor
) : TextEditorWithPreview(sourceTextEditor, previewTextEditor), TextEditor { ) : TextEditorWithPreview(sourceTextEditor, previewTextEditor), TextEditor {
private val previewOutputManager: PreviewOutputBlocksManager = PreviewOutputBlocksManager(previewTextEditor.editor)
private val toolWindowHandler: ScratchOutputHandler = requestToolWindowHandler() private val toolWindowHandler: ScratchOutputHandler = requestToolWindowHandler()
private val inlayScratchOutputHandler = InlayScratchOutputHandler(sourceTextEditor, toolWindowHandler) private val inlayScratchOutputHandler = InlayScratchOutputHandler(sourceTextEditor, toolWindowHandler)
private val previewEditorScratchOutputHandler = PreviewEditorScratchOutputHandler(previewTextEditor, toolWindowHandler) private val previewEditorScratchOutputHandler = PreviewEditorScratchOutputHandler(
previewOutputManager,
toolWindowHandler,
previewTextEditor as Disposable
)
private val commonPreviewOutputHandler = LayoutDependantOutputHandler( private val commonPreviewOutputHandler = LayoutDependantOutputHandler(
inlayScratchOutputHandler, noPreviewOutputHandler = inlayScratchOutputHandler,
previewEditorScratchOutputHandler, previewOutputHandler = previewEditorScratchOutputHandler,
::getLayout layoutProvider = ::getLayout
) )
private val scratchTopPanel = ScratchTopPanel(scratchFile) private val scratchTopPanel = ScratchTopPanel(scratchFile)
@@ -90,7 +95,7 @@ class KtScratchFileEditorWithPreview private constructor(
override fun processHelper(helper: ScrollHelper) { override fun processHelper(helper: ScrollHelper) {
if (!helper.process(0, 0)) return if (!helper.process(0, 0)) return
val alignments = previewEditorScratchOutputHandler.sourceToPreviewAlignments val alignments = previewOutputManager.computeSourceToPreviewAlignments()
for ((fromSource, fromPreview) in alignments) { for ((fromSource, fromPreview) in alignments) {
if (!helper.process(fromSource, fromPreview)) return if (!helper.process(fromSource, fromPreview)) return