KT-33585: Add synchronization between scratch editor and preview
- fix problem with not working shortcuts in the preview window by passing more params into view editor creation
This commit is contained in:
committed by
Roman Golyshev
parent
d12d9d86bc
commit
f419d2eb30
+51
-31
@@ -7,15 +7,13 @@ package org.jetbrains.kotlin.idea.scratch.output
|
||||
|
||||
import com.intellij.diff.util.DiffUtil
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.TransactionGuard
|
||||
import com.intellij.openapi.application.TransactionGuard
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.FoldRegion
|
||||
import com.intellij.openapi.editor.FoldingModel
|
||||
import com.intellij.openapi.editor.markup.HighlighterLayer
|
||||
import com.intellij.openapi.editor.markup.HighlighterTargetArea
|
||||
import com.intellij.openapi.editor.markup.MarkupModel
|
||||
import com.intellij.openapi.editor.markup.*
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import org.jetbrains.kotlin.idea.scratch.ScratchExpression
|
||||
import org.jetbrains.kotlin.idea.scratch.ScratchFile
|
||||
@@ -71,6 +69,13 @@ class PreviewEditorScratchOutputHandler(
|
||||
|
||||
private val ScratchExpression.height: Int get() = lineEnd - lineStart + 1
|
||||
|
||||
interface ScratchOutputBlock {
|
||||
val sourceExpression: ScratchExpression
|
||||
val lineStart: Int
|
||||
val lineEnd: Int
|
||||
fun addOutput(output: ScratchOutput)
|
||||
}
|
||||
|
||||
class PreviewOutputBlocksManager(editor: Editor) {
|
||||
private val targetDocument: Document = editor.document
|
||||
private val foldingModel: FoldingModel = editor.foldingModel
|
||||
@@ -80,9 +85,9 @@ class PreviewOutputBlocksManager(editor: Editor) {
|
||||
|
||||
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): ScratchOutputBlock? = blocks[expression]
|
||||
|
||||
fun addBlockToTheEnd(expression: ScratchExpression): OutputBlock = OutputBlock(expression).also {
|
||||
fun addBlockToTheEnd(expression: ScratchExpression): ScratchOutputBlock = OutputBlock(expression).also {
|
||||
if (blocks.putIfAbsent(expression, it) != null) {
|
||||
error("There is already a cell for $expression!")
|
||||
}
|
||||
@@ -97,26 +102,34 @@ class PreviewOutputBlocksManager(editor: Editor) {
|
||||
}
|
||||
}
|
||||
|
||||
inner class OutputBlock(val sourceExpression: ScratchExpression) {
|
||||
private inner class OutputBlock(override val sourceExpression: ScratchExpression) : ScratchOutputBlock {
|
||||
private val outputs: MutableList<ScratchOutput> = mutableListOf()
|
||||
|
||||
var lineStart: Int = computeCellLineStart(sourceExpression)
|
||||
override var lineStart: Int = computeCellLineStart(sourceExpression)
|
||||
private set
|
||||
|
||||
val lineEnd: Int get() = lineStart + countNewLines(outputs)
|
||||
val height: Int get() = lineEnd - lineStart + 1
|
||||
override val lineEnd: Int get() = lineStart + countNewLines(outputs)
|
||||
|
||||
val height: Int get() = lineEnd - lineStart + 1
|
||||
private var foldRegion: FoldRegion? = null
|
||||
|
||||
fun addOutput(output: ScratchOutput) {
|
||||
override fun addOutput(output: ScratchOutput) {
|
||||
printAndSaveOutput(output)
|
||||
|
||||
blocks.lowerEntry(sourceExpression)?.value?.updateFolding()
|
||||
blocks.tailMap(sourceExpression).values.forEach {
|
||||
it.recalculatePosition()
|
||||
it.updateFolding()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We want to make sure that changes in document happen in single edit, because if they are not,
|
||||
* listeners may see inconsistent document, which may cause troubles if they will try to highlight it
|
||||
* in some way. That's why it is important that [insertStringAtLine] does only one insert in the document,
|
||||
* and [output] is inserted into the [outputs] before the edits, so [OutputBlock] can correctly see
|
||||
* all its output expressions and highlight the whole block.
|
||||
*/
|
||||
private fun printAndSaveOutput(output: ScratchOutput) {
|
||||
val beforeAdding = lineEnd
|
||||
val currentOutputStartLine = if (outputs.isEmpty()) lineStart else beforeAdding + 1
|
||||
@@ -129,21 +142,7 @@ class PreviewOutputBlocksManager(editor: Editor) {
|
||||
}
|
||||
}
|
||||
|
||||
val insertedTextStart = targetDocument.getLineStartOffset(currentOutputStartLine)
|
||||
val insertedTextEnd = targetDocument.getLineEndOffset(lineEnd)
|
||||
colorRange(insertedTextStart, insertedTextEnd, output.type)
|
||||
}
|
||||
|
||||
private fun colorRange(startOffset: Int, endOffset: Int, outputType: ScratchOutputType) {
|
||||
val textAttributes = getAttributesForOutputType(outputType)
|
||||
|
||||
markupModel.addRangeHighlighter(
|
||||
startOffset,
|
||||
endOffset,
|
||||
HighlighterLayer.SYNTAX,
|
||||
textAttributes,
|
||||
HighlighterTargetArea.EXACT_RANGE
|
||||
)
|
||||
markupModel.highlightLines(currentOutputStartLine, lineEnd, getAttributesForOutputType(output.type))
|
||||
}
|
||||
|
||||
private fun recalculatePosition() {
|
||||
@@ -181,6 +180,8 @@ class PreviewOutputBlocksManager(editor: Editor) {
|
||||
val compensation = max(differenceBetweenSourceAndOutputHeight, 0)
|
||||
return previous.lineEnd + compensation + distanceBetweenSources
|
||||
}
|
||||
|
||||
fun getBlockAtLine(line: Int): ScratchOutputBlock? = blocks.values.find { line in it.lineStart..it.lineEnd }
|
||||
}
|
||||
|
||||
private fun countNewLines(list: List<ScratchOutput>) = list.sumBy { StringUtil.countNewLines(it.text) } + max(list.size - 1, 0)
|
||||
@@ -188,10 +189,29 @@ private fun countNewLines(list: List<ScratchOutput>) = list.sumBy { StringUtil.c
|
||||
private fun Document.getLineContent(lineNumber: Int) =
|
||||
DiffUtil.getLinesContent(this, lineNumber, lineNumber + 1).toString()
|
||||
|
||||
fun Document.insertStringAtLine(lineNumber: Int, text: String) {
|
||||
while (DiffUtil.getLineCount(this) <= lineNumber) {
|
||||
insertString(textLength, "\n")
|
||||
private fun Document.insertStringAtLine(lineNumber: Int, text: String) {
|
||||
val missingNewLines = lineNumber - (DiffUtil.getLineCount(this) - 1)
|
||||
if (missingNewLines > 0) {
|
||||
insertString(textLength, "${"\n".repeat(missingNewLines)}$text")
|
||||
} else {
|
||||
insertString(getLineStartOffset(lineNumber), text)
|
||||
}
|
||||
|
||||
insertString(getLineStartOffset(lineNumber), text)
|
||||
}
|
||||
|
||||
fun MarkupModel.highlightLines(
|
||||
from: Int,
|
||||
to: Int,
|
||||
attributes: TextAttributes,
|
||||
targetArea: HighlighterTargetArea = HighlighterTargetArea.EXACT_RANGE
|
||||
): RangeHighlighter {
|
||||
val fromOffset = document.getLineStartOffset(from)
|
||||
val toOffset = document.getLineEndOffset(to)
|
||||
|
||||
return addRangeHighlighter(
|
||||
fromOffset,
|
||||
toOffset,
|
||||
HighlighterLayer.CARET_ROW,
|
||||
attributes,
|
||||
targetArea
|
||||
)
|
||||
}
|
||||
|
||||
+33
-7
@@ -13,7 +13,9 @@ import com.intellij.openapi.actionSystem.*
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.EditorFactory
|
||||
import com.intellij.openapi.editor.EditorKind
|
||||
import com.intellij.openapi.editor.event.VisibleAreaListener
|
||||
import com.intellij.openapi.editor.ex.EditorEx
|
||||
import com.intellij.openapi.fileEditor.FileEditor
|
||||
import com.intellij.openapi.fileEditor.FileEditorPolicy
|
||||
import com.intellij.openapi.fileEditor.FileEditorProvider
|
||||
@@ -28,6 +30,7 @@ import com.intellij.pom.Navigatable
|
||||
import com.intellij.psi.PsiManager
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.core.util.getLineNumber
|
||||
import org.jetbrains.kotlin.idea.scratch.*
|
||||
import org.jetbrains.kotlin.idea.scratch.output.*
|
||||
import org.jetbrains.kotlin.psi.UserDataProperty
|
||||
@@ -55,11 +58,13 @@ class KtScratchFileEditorProvider : FileEditorProvider, DumbAware {
|
||||
|
||||
class KtScratchFileEditorWithPreview private constructor(
|
||||
val scratchFile: ScratchFile,
|
||||
private val sourceTextEditor: TextEditor,
|
||||
sourceTextEditor: TextEditor,
|
||||
private val previewTextEditor: TextEditor
|
||||
) : TextEditorWithPreview(sourceTextEditor, previewTextEditor), TextEditor {
|
||||
) : TextEditorWithPreview(sourceTextEditor, previewTextEditor), TextEditor, ScratchEditorLinesTranslator {
|
||||
|
||||
private val previewOutputManager: PreviewOutputBlocksManager = PreviewOutputBlocksManager(previewTextEditor.editor)
|
||||
private val sourceEditor = sourceTextEditor.editor as EditorEx
|
||||
private val previewEditor = previewTextEditor.editor as EditorEx
|
||||
private val previewOutputManager: PreviewOutputBlocksManager = PreviewOutputBlocksManager(previewEditor)
|
||||
|
||||
private val toolWindowHandler: ScratchOutputHandler = requestToolWindowHandler()
|
||||
private val inlayScratchOutputHandler = InlayScratchOutputHandler(sourceTextEditor, toolWindowHandler)
|
||||
@@ -83,14 +88,26 @@ class KtScratchFileEditorWithPreview private constructor(
|
||||
scratchFile.replScratchExecutor?.addOutputHandler(commonPreviewOutputHandler)
|
||||
|
||||
configureSyncScrollForSourceAndPreview()
|
||||
configureSyncHighlighting(sourceEditor, previewEditor, translator = this)
|
||||
|
||||
ScratchFileAutoRunner.addListener(scratchFile.project, sourceTextEditor)
|
||||
}
|
||||
|
||||
private fun configureSyncScrollForSourceAndPreview() {
|
||||
val sourceEditor = sourceTextEditor.editor
|
||||
val previewEditor = previewTextEditor.editor
|
||||
override fun previewLineToSourceLines(previewLine: Int): Pair<Int, Int>? {
|
||||
val expressionUnderCaret = scratchFile.getExpressionAtLine(previewLine) ?: return null
|
||||
val outputBlock = previewOutputManager.getBlock(expressionUnderCaret) ?: return null
|
||||
|
||||
return outputBlock.lineStart to outputBlock.lineEnd
|
||||
}
|
||||
|
||||
override fun sourceLineToPreviewLines(sourceLine: Int): Pair<Int, Int>? {
|
||||
val block = previewOutputManager.getBlockAtLine(sourceLine) ?: return null
|
||||
if (!block.sourceExpression.linesInformationIsCorrect()) return null
|
||||
|
||||
return block.sourceExpression.lineStart to block.sourceExpression.lineEnd
|
||||
}
|
||||
|
||||
private fun configureSyncScrollForSourceAndPreview() {
|
||||
val scrollable = object : BaseSyncScrollable() {
|
||||
override fun processHelper(helper: ScrollHelper) {
|
||||
if (!helper.process(0, 0)) return
|
||||
@@ -189,7 +206,7 @@ class KtScratchFileEditorWithPreview private constructor(
|
||||
val mainEditor = textEditorProvider.createEditor(scratchFile.project, scratchFile.file) as TextEditor
|
||||
val editorFactory = EditorFactory.getInstance()
|
||||
|
||||
val viewer = editorFactory.createViewer(editorFactory.createDocument(""))
|
||||
val viewer = editorFactory.createViewer(editorFactory.createDocument(""), scratchFile.project, EditorKind.PREVIEW)
|
||||
Disposer.register(mainEditor, Disposable { editorFactory.releaseEditor(viewer) })
|
||||
|
||||
val previewEditor = textEditorProvider.getTextEditor(viewer)
|
||||
@@ -266,3 +283,12 @@ private class LayoutDependantOutputHandler(
|
||||
else -> previewOutputHandler
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if [ScratchExpression.element] is actually starts at the [ScratchExpression.lineStart]
|
||||
* and ends at the [ScratchExpression.lineEnd].
|
||||
*/
|
||||
private fun ScratchExpression.linesInformationIsCorrect(): Boolean {
|
||||
if (!element.isValid) return false
|
||||
return element.getLineNumber(start = true) == lineStart && element.getLineNumber(start = false) == lineEnd
|
||||
}
|
||||
|
||||
+234
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.scratch.ui
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.colors.EditorColors
|
||||
import com.intellij.openapi.editor.event.CaretEvent
|
||||
import com.intellij.openapi.editor.event.CaretListener
|
||||
import com.intellij.openapi.editor.event.DocumentEvent
|
||||
import com.intellij.openapi.editor.event.DocumentListener
|
||||
import com.intellij.openapi.editor.ex.EditorEx
|
||||
import com.intellij.openapi.editor.ex.FocusChangeListener
|
||||
import com.intellij.openapi.editor.markup.HighlighterTargetArea
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter
|
||||
import com.intellij.openapi.editor.markup.TextAttributes
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import org.jetbrains.kotlin.idea.scratch.output.highlightLines
|
||||
|
||||
interface ScratchEditorLinesTranslator {
|
||||
fun previewLineToSourceLines(previewLine: Int): Pair<Int, Int>?
|
||||
fun sourceLineToPreviewLines(sourceLine: Int): Pair<Int, Int>?
|
||||
}
|
||||
|
||||
fun configureSyncHighlighting(sourceEditor: EditorEx, previewEditor: EditorEx, translator: ScratchEditorLinesTranslator) {
|
||||
configureExclusiveCaretRowHighlighting(sourceEditor, previewEditor)
|
||||
configureSourceAndPreviewHighlighting(sourceEditor, previewEditor, translator)
|
||||
}
|
||||
|
||||
private fun configureSourceAndPreviewHighlighting(
|
||||
sourceEditor: EditorEx,
|
||||
previewEditor: EditorEx,
|
||||
translator: ScratchEditorLinesTranslator
|
||||
) {
|
||||
val syncHighlighter = ScratchEditorSyncHighlighter.create(sourceEditor, previewEditor, translator)
|
||||
|
||||
configureHighlightUpdateOnDocumentChange(sourceEditor, previewEditor, syncHighlighter)
|
||||
configureSourceToPreviewHighlighting(sourceEditor, syncHighlighter)
|
||||
configurePreviewToSourceHighlighting(previewEditor, syncHighlighter)
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures editors such that only one of them have caret row highlighting enabled.
|
||||
*/
|
||||
private fun configureExclusiveCaretRowHighlighting(sourceEditor: EditorEx, previewEditor: EditorEx) {
|
||||
val exclusiveCaretHighlightingListener = object : FocusChangeListener {
|
||||
override fun focusLost(editor: Editor) {}
|
||||
|
||||
override fun focusGained(editor: Editor) {
|
||||
sourceEditor.settings.isCaretRowShown = false
|
||||
previewEditor.settings.isCaretRowShown = false
|
||||
|
||||
editor.settings.isCaretRowShown = true
|
||||
}
|
||||
}
|
||||
|
||||
sourceEditor.addFocusListener(exclusiveCaretHighlightingListener)
|
||||
previewEditor.addFocusListener(exclusiveCaretHighlightingListener)
|
||||
}
|
||||
|
||||
/**
|
||||
* When source or preview documents change, we need to update highlighting, because
|
||||
* expression output may become bigger.
|
||||
*
|
||||
* We can do that only when document is fully committed, so [ScratchFile.getExpressions] will return correct expressions
|
||||
* with correct PSIs.
|
||||
*/
|
||||
private fun configureHighlightUpdateOnDocumentChange(
|
||||
sourceEditor: EditorEx,
|
||||
previewEditor: EditorEx,
|
||||
highlighter: ScratchEditorSyncHighlighter
|
||||
) {
|
||||
val updateHighlightOnDocumentChangeListener = object : DocumentListener {
|
||||
override fun documentChanged(event: DocumentEvent) {
|
||||
PsiDocumentManager.getInstance(sourceEditor.project!!).performWhenAllCommitted {
|
||||
highlighter.highlightByCurrentlyFocusedEditor()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
previewEditor.document.addDocumentListener(updateHighlightOnDocumentChangeListener)
|
||||
sourceEditor.document.addDocumentListener(updateHighlightOnDocumentChangeListener)
|
||||
}
|
||||
|
||||
/**
|
||||
* When caret in [sourceEditor] is moved, highlight is recalculated.
|
||||
*
|
||||
* When focus is switched to the [sourceEditor], highlight is recalculated,
|
||||
* because it is possible to switch focus without changing cursor position,
|
||||
* which would lead to the outdated highlighting.
|
||||
*/
|
||||
private fun configureSourceToPreviewHighlighting(sourceEditor: EditorEx, highlighter: ScratchEditorSyncHighlighter) {
|
||||
sourceEditor.caretModel.addCaretListener(object : CaretListener {
|
||||
override fun caretPositionChanged(event: CaretEvent) {
|
||||
highlighter.highlightPreviewBySource()
|
||||
}
|
||||
})
|
||||
|
||||
sourceEditor.addFocusListener(object : FocusChangeListener {
|
||||
override fun focusLost(editor: Editor) {}
|
||||
|
||||
override fun focusGained(editor: Editor) {
|
||||
highlighter.highlightPreviewBySource()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* When caret in [previewEditor] is moved, highlight is recalculated.
|
||||
*
|
||||
* When focus is switched to the [previewEditor], highlight is recalculated,
|
||||
* because it is possible to switch focus without changing cursor position,
|
||||
* which would lead to the outdated highlighting.
|
||||
*/
|
||||
private fun configurePreviewToSourceHighlighting(previewEditor: EditorEx, highlighter: ScratchEditorSyncHighlighter) {
|
||||
previewEditor.caretModel.addCaretListener(object : CaretListener {
|
||||
override fun caretPositionChanged(event: CaretEvent) {
|
||||
highlighter.highlightSourceByPreview()
|
||||
}
|
||||
})
|
||||
|
||||
previewEditor.addFocusListener(object : FocusChangeListener {
|
||||
override fun focusLost(editor: Editor) {}
|
||||
|
||||
override fun focusGained(editor: Editor) {
|
||||
highlighter.highlightSourceByPreview()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private class ScratchEditorsState(private val sourceEditor: EditorEx, private val previewEditor: EditorEx) : FocusChangeListener {
|
||||
private var lastFocusedEditor: Editor = sourceEditor
|
||||
|
||||
enum class FocusedEditor {
|
||||
SOURCE, PREVIEW
|
||||
}
|
||||
|
||||
init {
|
||||
sourceEditor.addFocusListener(this)
|
||||
previewEditor.addFocusListener(this)
|
||||
}
|
||||
|
||||
val sourceEditorCaretLine: Int? get() = sourceEditor.caretModel.allCarets.singleOrNull()?.logicalPosition?.line
|
||||
val previewEditorCaretLine: Int? get() = previewEditor.caretModel.allCarets.singleOrNull()?.logicalPosition?.line
|
||||
val focusedEditor: FocusedEditor get() = if (lastFocusedEditor === sourceEditor) FocusedEditor.SOURCE else FocusedEditor.PREVIEW
|
||||
|
||||
override fun focusLost(editor: Editor) {}
|
||||
|
||||
override fun focusGained(editor: Editor) {
|
||||
lastFocusedEditor = editor
|
||||
}
|
||||
}
|
||||
|
||||
private class ScratchEditorSyncHighlighter private constructor(
|
||||
private val state: ScratchEditorsState,
|
||||
private val sourceHighlighter: EditorLinesHighlighter,
|
||||
private val previewHighlighter: EditorLinesHighlighter,
|
||||
private val translator: ScratchEditorLinesTranslator
|
||||
) {
|
||||
fun highlightSourceByPreview() {
|
||||
clearAllHighlights()
|
||||
|
||||
state.previewEditorCaretLine?.let(::highlightSourceByPreviewLine)
|
||||
}
|
||||
|
||||
fun highlightPreviewBySource() {
|
||||
clearAllHighlights()
|
||||
|
||||
state.sourceEditorCaretLine?.let(::highlightPreviewBySourceLine)
|
||||
}
|
||||
|
||||
fun highlightByCurrentlyFocusedEditor() {
|
||||
when (state.focusedEditor) {
|
||||
ScratchEditorsState.FocusedEditor.SOURCE -> highlightPreviewBySource()
|
||||
ScratchEditorsState.FocusedEditor.PREVIEW -> highlightSourceByPreview()
|
||||
}
|
||||
}
|
||||
|
||||
private fun highlightSourceByPreviewLine(selectedPreviewLine: Int) {
|
||||
val (from, to) = translator.sourceLineToPreviewLines(selectedPreviewLine) ?: return
|
||||
|
||||
sourceHighlighter.highlightLines(from, to)
|
||||
}
|
||||
|
||||
private fun highlightPreviewBySourceLine(selectedSourceLine: Int) {
|
||||
val (from, to) = translator.previewLineToSourceLines(selectedSourceLine) ?: return
|
||||
|
||||
previewHighlighter.highlightLines(from, to)
|
||||
}
|
||||
|
||||
private fun clearAllHighlights() {
|
||||
sourceHighlighter.clearHighlights()
|
||||
previewHighlighter.clearHighlights()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun create(
|
||||
sourceEditor: EditorEx,
|
||||
previewEditor: EditorEx,
|
||||
translator: ScratchEditorLinesTranslator
|
||||
): ScratchEditorSyncHighlighter {
|
||||
return ScratchEditorSyncHighlighter(
|
||||
state = ScratchEditorsState(sourceEditor, previewEditor),
|
||||
sourceHighlighter = EditorLinesHighlighter(sourceEditor),
|
||||
previewHighlighter = EditorLinesHighlighter(previewEditor),
|
||||
translator = translator
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class EditorLinesHighlighter(private val targetEditor: Editor) {
|
||||
private var activeHighlight: RangeHighlighter? = null
|
||||
|
||||
fun clearHighlights() {
|
||||
activeHighlight?.let(targetEditor.markupModel::removeHighlighter)
|
||||
activeHighlight = null
|
||||
}
|
||||
|
||||
fun highlightLines(lineStart: Int, lineEnd: Int) {
|
||||
clearHighlights()
|
||||
|
||||
val highlightColor = targetEditor.colorsScheme.getColor(EditorColors.CARET_ROW_COLOR) ?: return
|
||||
|
||||
activeHighlight = targetEditor.markupModel.highlightLines(
|
||||
lineStart,
|
||||
lineEnd,
|
||||
TextAttributes().apply { backgroundColor = highlightColor },
|
||||
HighlighterTargetArea.LINES_IN_RANGE
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user