[ide-console][bug-fixes] Disable process on closed dialog window
Fix history bugs (lost completion focus, occasional flush) Faster incomplete icon change Correct console window title Other small gui decorations
This commit is contained in:
committed by
Pavel V. Talanov
parent
b19010184a
commit
3152792860
@@ -16,12 +16,18 @@
|
||||
|
||||
package org.jetbrains.kotlin.console
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupManager
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.openapi.editor.ex.EditorEx
|
||||
import com.intellij.openapi.editor.ex.util.EditorUtil
|
||||
import org.jetbrains.kotlin.console.highlight.ReplOutputType
|
||||
import java.awt.event.KeyAdapter
|
||||
import java.awt.event.KeyEvent
|
||||
|
||||
public class KotlinConsoleHistoryManager(private val ktConsole: KotlinConsoleRunner) : KeyAdapter() {
|
||||
public class KotlinConsoleHistoryManager(private val runner: KotlinConsoleRunner) : KeyAdapter() {
|
||||
private val project = runner.project
|
||||
private val consoleEditor: EditorEx by lazy { runner.consoleView.consoleEditor } // [consoleEditor] is null at the moment if instantiation
|
||||
|
||||
private val history = arrayListOf<String>()
|
||||
|
||||
private var historyPos = 0
|
||||
@@ -52,14 +58,15 @@ public class KotlinConsoleHistoryManager(private val ktConsole: KotlinConsoleRun
|
||||
override fun keyReleased(e: KeyEvent): Unit = when (e.keyCode) {
|
||||
KeyEvent.VK_UP -> moveHistoryCursor(HistoryMove.UP)
|
||||
KeyEvent.VK_DOWN -> moveHistoryCursor(HistoryMove.DOWN)
|
||||
KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT -> prevCaretOffset = ktConsole.consoleView.consoleEditor.caretModel.offset
|
||||
KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT -> prevCaretOffset = consoleEditor.caretModel.offset
|
||||
}
|
||||
|
||||
private fun moveHistoryCursor(move: HistoryMove) {
|
||||
if (history.isEmpty()) return
|
||||
if (LookupManager.getInstance(project).activeLookup != null) return
|
||||
|
||||
val caret = ktConsole.consoleView.consoleEditor.caretModel
|
||||
val document = ktConsole.consoleView.editorDocument
|
||||
val caret = consoleEditor.caretModel
|
||||
val document = consoleEditor.document
|
||||
|
||||
val curOffset = caret.offset
|
||||
val curLine = document.getLineNumber(curOffset)
|
||||
@@ -78,23 +85,27 @@ public class KotlinConsoleHistoryManager(private val ktConsole: KotlinConsoleRun
|
||||
}
|
||||
|
||||
historyPos = Math.max(historyPos - 1, 0)
|
||||
WriteCommandAction.runWriteCommandAction(ktConsole.project) {
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
document.setText(history[historyPos].trim())
|
||||
caret.moveToOffset(0)
|
||||
EditorUtil.scrollToTheEnd(consoleEditor)
|
||||
prevCaretOffset = 0
|
||||
caret.moveToOffset(0)
|
||||
}
|
||||
}
|
||||
HistoryMove.DOWN -> {
|
||||
if (historyPos == history.size()) return
|
||||
|
||||
if (curLine != totalLines - 1 || (isMultiline && prevCaretOffset != document.textLength)) {
|
||||
prevCaretOffset = curOffset
|
||||
return
|
||||
}
|
||||
|
||||
historyPos = Math.min(historyPos + 1, history.size())
|
||||
WriteCommandAction.runWriteCommandAction(ktConsole.project) {
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
document.setText(if (historyPos == history.size()) unfinishedCommand else history[historyPos].trim())
|
||||
caret.moveToOffset(document.textLength)
|
||||
prevCaretOffset = document.textLength
|
||||
EditorUtil.scrollToTheEnd(consoleEditor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@ import org.jetbrains.kotlin.utils.PathUtil
|
||||
import java.io.File
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
private val REPL_TITLE = "Kotlin REPL"
|
||||
|
||||
public class KotlinConsoleKeeper(val project: Project) {
|
||||
private val consoleMap: MutableMap<VirtualFile, KotlinConsoleRunner> = ConcurrentHashMap()
|
||||
|
||||
@@ -46,7 +48,7 @@ public class KotlinConsoleKeeper(val project: Project) {
|
||||
val path = module.moduleFilePath
|
||||
val cmdLine = createCommandLine(module) ?: return errorNotification(project, "Module SDK not found") let { null }
|
||||
|
||||
val consoleRunner = KotlinConsoleRunner(path, cmdLine, module, project, REPL_TITLE)
|
||||
val consoleRunner = KotlinConsoleRunner(cmdLine, module, project, REPL_TITLE, path)
|
||||
consoleRunner.initAndRun()
|
||||
consoleRunner.setupGutters()
|
||||
|
||||
@@ -110,8 +112,6 @@ public class KotlinConsoleKeeper(val project: Project) {
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val REPL_TITLE = "Kotlin REPL"
|
||||
|
||||
jvmStatic fun getInstance(project: Project) = ServiceManager.getService(project, javaClass<KotlinConsoleKeeper>())
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import com.intellij.execution.process.*
|
||||
import com.intellij.execution.runners.AbstractConsoleRunnerWithHistory
|
||||
import com.intellij.execution.ui.RunContentDescriptor
|
||||
import com.intellij.openapi.actionSystem.*
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.openapi.editor.colors.EditorColors
|
||||
import com.intellij.openapi.editor.ex.EditorEx
|
||||
import com.intellij.openapi.editor.markup.*
|
||||
@@ -47,13 +48,13 @@ import java.util.concurrent.ConcurrentHashMap
|
||||
import javax.swing.Icon
|
||||
|
||||
public class KotlinConsoleRunner(
|
||||
private val title: String,
|
||||
private val cmdLine: GeneralCommandLine,
|
||||
private val module: Module,
|
||||
myProject: Project,
|
||||
title: String,
|
||||
path: String?
|
||||
) : AbstractConsoleRunnerWithHistory<LanguageConsoleView>(myProject, title, path) {
|
||||
private val editorToIndicator = ConcurrentHashMap<EditorEx, KotlinConsoleIndicatorRenderer>()
|
||||
private val editorToIndicator = ConcurrentHashMap<EditorEx, RangeHighlighter>()
|
||||
private val historyManager = KotlinConsoleHistoryManager(this)
|
||||
val executor = KotlinConsoleExecutor(this, historyManager)
|
||||
|
||||
@@ -119,6 +120,8 @@ public class KotlinConsoleRunner(
|
||||
}
|
||||
}
|
||||
|
||||
override fun constructConsoleTitle(title: String) = "$title (in module ${module.name})"
|
||||
|
||||
private fun setupPlaceholder(editor: EditorEx) {
|
||||
editor.setPlaceholder("<Ctrl+Enter> to execute")
|
||||
editor.setShowPlaceholderWhenFocused(true)
|
||||
@@ -147,10 +150,16 @@ public class KotlinConsoleRunner(
|
||||
addGutterIndicator(editor, icon)
|
||||
}
|
||||
|
||||
configureEditorGutter(consoleView.historyViewer, ReplColors.HISTORY_GUTTER_COLOR, ReplIcons.HISTORY_INDICATOR)
|
||||
configureEditorGutter(consoleView.consoleEditor, ReplColors.EDITOR_GUTTER_COLOR, ReplIcons.EDITOR_INDICATOR)
|
||||
val historyEditor = consoleView.historyViewer
|
||||
val consoleEditor = consoleView.consoleEditor
|
||||
|
||||
consoleView.consoleEditor.settings.isCaretRowShown = true
|
||||
configureEditorGutter(historyEditor, ReplColors.HISTORY_GUTTER_COLOR, ReplIcons.HISTORY_INDICATOR)
|
||||
configureEditorGutter(consoleEditor, ReplColors.EDITOR_GUTTER_COLOR, ReplIcons.EDITOR_INDICATOR)
|
||||
|
||||
historyEditor.settings.isUseSoftWraps = true
|
||||
|
||||
consoleEditor.settings.isCaretRowShown = true
|
||||
consoleEditor.settings.additionalLinesCount = 2
|
||||
}
|
||||
|
||||
fun addGutterIndicator(editor: EditorEx, icon: Icon) {
|
||||
@@ -161,10 +170,11 @@ public class KotlinConsoleRunner(
|
||||
)
|
||||
|
||||
indicatorHighlighter.gutterIconRenderer = indicator
|
||||
editorToIndicator[editor] = indicator
|
||||
editorToIndicator[editor] = indicatorHighlighter
|
||||
}
|
||||
|
||||
fun changeEditorIndicatorIcon(editor: EditorEx, newIcon: Icon) {
|
||||
editorToIndicator[editor]?.indicatorIcon = newIcon
|
||||
val oldHighlighter = editorToIndicator[editor] ?: return
|
||||
WriteCommandAction.runWriteCommandAction(project) { oldHighlighter.gutterIconRenderer = KotlinConsoleIndicatorRenderer(newIcon) }
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,8 @@ public class KotlinReplOutputHandler(
|
||||
|
||||
private val dBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
|
||||
|
||||
override fun isSilentlyDestroyOnClose() = true
|
||||
|
||||
override fun notifyTextAvailable(text: String, key: Key<*>?) {
|
||||
// skip "/usr/lib/jvm/java-8-oracle/bin/java -cp ..." intro
|
||||
if (!text.startsWith(XML_PREFIX)) return super.notifyTextAvailable(text, key)
|
||||
|
||||
+3
-3
@@ -19,8 +19,8 @@ package org.jetbrains.kotlin.console.gutter
|
||||
import com.intellij.openapi.editor.markup.GutterIconRenderer
|
||||
import javax.swing.Icon
|
||||
|
||||
public class KotlinConsoleIndicatorRenderer(var indicatorIcon: Icon) : GutterIconRenderer() {
|
||||
public class KotlinConsoleIndicatorRenderer(private val indicatorIcon: Icon) : GutterIconRenderer() {
|
||||
override fun getIcon() = indicatorIcon
|
||||
override fun hashCode() = System.identityHashCode(this)
|
||||
override fun equals(other: Any?) = this === other
|
||||
override fun hashCode() = indicatorIcon.hashCode()
|
||||
override fun equals(other: Any?) = indicatorIcon == (other as? KotlinConsoleIndicatorRenderer)?.indicatorIcon ?: null
|
||||
}
|
||||
+5
-4
@@ -47,6 +47,7 @@ public class KotlinReplOutputHighlighter(
|
||||
private val runner: KotlinConsoleRunner,
|
||||
private val historyManager: KotlinConsoleHistoryManager
|
||||
) {
|
||||
private val project = runner.project
|
||||
private val consoleView = runner.consoleView
|
||||
private val historyEditor = consoleView.historyViewer
|
||||
private val historyDocument = historyEditor.document
|
||||
@@ -70,7 +71,7 @@ public class KotlinReplOutputHighlighter(
|
||||
consoleView.print(command, ReplColors.USER_OUTPUT_CONTENT_TYPE)
|
||||
}
|
||||
|
||||
fun printResultWithGutterIcon(result: String) = WriteCommandAction.runWriteCommandAction(runner.project) {
|
||||
fun printResultWithGutterIcon(result: String) = WriteCommandAction.runWriteCommandAction(project) {
|
||||
resetConsoleEditorIndicator()
|
||||
historyManager.lastCommandType = ReplOutputType.RESULT
|
||||
|
||||
@@ -85,7 +86,7 @@ public class KotlinReplOutputHighlighter(
|
||||
runner.changeEditorIndicatorIcon(consoleView.consoleEditor, ReplIcons.INCOMPLETE_INDICATOR)
|
||||
}
|
||||
|
||||
fun highlightCompilerErrors(compilerMessages: List<SeverityDetails>) = WriteCommandAction.runWriteCommandAction(runner.project) {
|
||||
fun highlightCompilerErrors(compilerMessages: List<SeverityDetails>) = WriteCommandAction.runWriteCommandAction(project) {
|
||||
resetConsoleEditorIndicator()
|
||||
historyManager.lastCommandType = ReplOutputType.ERROR
|
||||
|
||||
@@ -137,8 +138,8 @@ public class KotlinReplOutputHighlighter(
|
||||
): TextAttributes {
|
||||
val highlightInfo = HighlightInfo.newHighlightInfo(infoType).range(start, end).severity(severity).textAttributes(insightColors).create()
|
||||
|
||||
val psiFile = PsiDocumentManager.getInstance(runner.project).getPsiFile(runner.consoleView.consoleEditor.document)
|
||||
val colorScheme = runner.consoleView.consoleEditor.colorsScheme
|
||||
val psiFile = PsiDocumentManager.getInstance(project).getPsiFile(consoleView.consoleEditor.document)
|
||||
val colorScheme = consoleView.consoleEditor.colorsScheme
|
||||
|
||||
return highlightInfo?.getTextAttributes(psiFile, colorScheme) ?: TextAttributes()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user