[Editor] Improve opening code editor on compilation error location click
This commit is contained in:
@@ -9,7 +9,7 @@ import tornadofx.FX
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
class JavaCompiler : ScriptCompiler {
|
class JaninoCompiler : ScriptCompiler {
|
||||||
private val compilerFactory = CompilerFactory()
|
private val compilerFactory = CompilerFactory()
|
||||||
|
|
||||||
override fun compile(sourceDirectory: FileSystemNode) {
|
override fun compile(sourceDirectory: FileSystemNode) {
|
||||||
@@ -21,14 +21,15 @@ class JavaCompiler : ScriptCompiler {
|
|||||||
// syntax errors. The only way to catch it is just catching CompileExceptions
|
// syntax errors. The only way to catch it is just catching CompileExceptions
|
||||||
try {
|
try {
|
||||||
compiler.compile(files.toTypedArray())
|
compiler.compile(files.toTypedArray())
|
||||||
|
FX.eventbus.fire(UpdateCompilationLogEvent(UpdateCompilationLogEvent.Severity.INFO, "Compilation success"))
|
||||||
} catch (e: CompileException) {
|
} catch (e: CompileException) {
|
||||||
|
|
||||||
// Because the Janino compiler assemblies the message with the location
|
// Because the Janino compiler assemblies the message with the location
|
||||||
// in the LocatedException.getMessage() method, we just need to remove it
|
// in the LocatedException.getMessage() method, we just need to remove it
|
||||||
// to have a plain message along with the plain location as separated objects
|
// to have a plain message along with the plain location as separated objects
|
||||||
FX.eventbus.fire(
|
val locationIndex = e.location?.toString()?.length ?: 0
|
||||||
UpdateCompilationLogEvent(e.message?.substring(e.location.toString().length) ?: "", e.location)
|
val message = e.message?.substring(locationIndex) ?: ""
|
||||||
)
|
FX.eventbus.fire(UpdateCompilationLogEvent(UpdateCompilationLogEvent.Severity.ERROR, message, e.location))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,6 +55,12 @@ class CodeEditor(private val highlighter: ObservableValue<out SyntaxHighlighter>
|
|||||||
fun shutdownHighlighterThread() {
|
fun shutdownHighlighterThread() {
|
||||||
highlightingSubscription.unsubscribe()
|
highlightingSubscription.unsubscribe()
|
||||||
executor.shutdownNow()
|
executor.shutdownNow()
|
||||||
|
editor.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setCaretPosition(line: Int, column: Int) {
|
||||||
|
editor.moveTo(line - 1, column - 1)
|
||||||
|
editor.requestFollowCaret()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initAutoIndents() {
|
private fun initAutoIndents() {
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.bartlomiejpluta.base.editor.code.model
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.base.editor.command.context.UndoableScope
|
||||||
|
import tornadofx.toProperty
|
||||||
|
|
||||||
|
class CodeScope(line: Int, column: Int) : UndoableScope() {
|
||||||
|
private val requestCaretPositionProperty = (line to column).toProperty()
|
||||||
|
|
||||||
|
fun setCaretPosition(line: Int, column: Int) {
|
||||||
|
requestCaretPositionProperty.value = line to column
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addCaretDisplacementRequestListener(listener: (line: Int, column: Int) -> Unit) {
|
||||||
|
requestCaretPositionProperty.addListener { _, _, position -> listener(position.first, position.second) }
|
||||||
|
listener(requestCaretPositionProperty.value.first, requestCaretPositionProperty.value.second)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,16 +2,16 @@ package com.bartlomiejpluta.base.editor.code.view
|
|||||||
|
|
||||||
import com.bartlomiejpluta.base.editor.code.component.CodeEditor
|
import com.bartlomiejpluta.base.editor.code.component.CodeEditor
|
||||||
import com.bartlomiejpluta.base.editor.code.highlighting.JavaSyntaxHighlighter
|
import com.bartlomiejpluta.base.editor.code.highlighting.JavaSyntaxHighlighter
|
||||||
|
import com.bartlomiejpluta.base.editor.code.model.CodeScope
|
||||||
import com.bartlomiejpluta.base.editor.code.model.CodeType
|
import com.bartlomiejpluta.base.editor.code.model.CodeType
|
||||||
import com.bartlomiejpluta.base.editor.code.viewmodel.CodeVM
|
import com.bartlomiejpluta.base.editor.code.viewmodel.CodeVM
|
||||||
import com.bartlomiejpluta.base.editor.command.context.UndoableScope
|
|
||||||
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
|
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
|
||||||
import javafx.beans.binding.Bindings
|
import javafx.beans.binding.Bindings
|
||||||
import org.kordamp.ikonli.javafx.FontIcon
|
import org.kordamp.ikonli.javafx.FontIcon
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
|
|
||||||
class CodeEditorView : View() {
|
class CodeEditorView : View() {
|
||||||
override val scope = super.scope as UndoableScope
|
override val scope = super.scope as CodeScope
|
||||||
|
|
||||||
private val projectContext: ProjectContext by di()
|
private val projectContext: ProjectContext by di()
|
||||||
|
|
||||||
@@ -27,6 +27,12 @@ class CodeEditorView : View() {
|
|||||||
|
|
||||||
private val editor = CodeEditor(highlighter, codeVM.codeProperty)
|
private val editor = CodeEditor(highlighter, codeVM.codeProperty)
|
||||||
|
|
||||||
|
init {
|
||||||
|
scope.addCaretDisplacementRequestListener { line, column ->
|
||||||
|
editor.setCaretPosition(line, column)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun shutdown() {
|
fun shutdown() {
|
||||||
editor.shutdownHighlighterThread()
|
editor.shutdownHighlighterThread()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import javafx.scene.paint.Color
|
|||||||
import javafx.scene.text.Text
|
import javafx.scene.text.Text
|
||||||
import org.codehaus.commons.compiler.Location
|
import org.codehaus.commons.compiler.Location
|
||||||
import org.fxmisc.richtext.StyledTextArea
|
import org.fxmisc.richtext.StyledTextArea
|
||||||
import tornadofx.View
|
import org.kordamp.ikonli.javafx.FontIcon
|
||||||
|
import tornadofx.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
@@ -16,7 +17,12 @@ class CompilerLogsView : View() {
|
|||||||
private val projectContext: ProjectContext by di()
|
private val projectContext: ProjectContext by di()
|
||||||
private val mainController: MainController by di()
|
private val mainController: MainController by di()
|
||||||
|
|
||||||
private val editor = StyledTextArea(null, { _, _ -> }, LocationRef.NO_LINK, { text, style -> style.apply(text) })
|
private val editor = StyledTextArea(
|
||||||
|
null,
|
||||||
|
{ _, _ -> },
|
||||||
|
LocationRef.NO_LINK,
|
||||||
|
{ text, style -> style.apply(text) }
|
||||||
|
).apply { isEditable = false }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
subscribe<UpdateCompilationLogEvent> { event ->
|
subscribe<UpdateCompilationLogEvent> { event ->
|
||||||
@@ -24,16 +30,24 @@ class CompilerLogsView : View() {
|
|||||||
|
|
||||||
val locationRef = LocationRef(event.location) { loc ->
|
val locationRef = LocationRef(event.location) { loc ->
|
||||||
projectContext.project?.codeFSNode?.findByFile(File(loc.fileName))?.let {
|
projectContext.project?.codeFSNode?.findByFile(File(loc.fileName))?.let {
|
||||||
mainController.openScript(it)
|
mainController.openScript(it, loc.lineNumber, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
editor.insert(editor.length, event.location.toString(), locationRef)
|
editor.insert(editor.length, event.location?.toString() ?: "", locationRef)
|
||||||
editor.insert(editor.length, event.message, LocationRef.NO_LINK)
|
editor.insert(editor.length, event.message, LocationRef.NO_LINK)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val root = editor
|
override val root = borderpane {
|
||||||
|
left = hbox {
|
||||||
|
button(graphic = FontIcon("fa-trash")) {
|
||||||
|
action { editor.clear() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
center = editor
|
||||||
|
}
|
||||||
|
|
||||||
class LocationRef(private val location: Location?, private val onClick: (Location) -> Unit = {}) {
|
class LocationRef(private val location: Location?, private val onClick: (Location) -> Unit = {}) {
|
||||||
private constructor() : this(null)
|
private constructor() : this(null)
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ package com.bartlomiejpluta.base.editor.command.context
|
|||||||
|
|
||||||
import tornadofx.Scope
|
import tornadofx.Scope
|
||||||
|
|
||||||
class UndoableScope : UndoableContext, Scope()
|
open class UndoableScope : UndoableContext, Scope()
|
||||||
@@ -4,5 +4,12 @@ import org.codehaus.commons.compiler.Location
|
|||||||
import tornadofx.EventBus
|
import tornadofx.EventBus
|
||||||
import tornadofx.FXEvent
|
import tornadofx.FXEvent
|
||||||
|
|
||||||
data class UpdateCompilationLogEvent(val message: String, val location: Location) :
|
data class UpdateCompilationLogEvent(val severity: Severity, val message: String, val location: Location? = null) :
|
||||||
FXEvent(EventBus.RunOn.ApplicationThread)
|
FXEvent(EventBus.RunOn.ApplicationThread) {
|
||||||
|
|
||||||
|
enum class Severity {
|
||||||
|
INFO,
|
||||||
|
WARNING,
|
||||||
|
ERROR
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package com.bartlomiejpluta.base.editor.main.controller
|
|||||||
|
|
||||||
import com.bartlomiejpluta.base.editor.asset.model.Asset
|
import com.bartlomiejpluta.base.editor.asset.model.Asset
|
||||||
import com.bartlomiejpluta.base.editor.code.model.Code
|
import com.bartlomiejpluta.base.editor.code.model.Code
|
||||||
|
import com.bartlomiejpluta.base.editor.code.model.CodeScope
|
||||||
import com.bartlomiejpluta.base.editor.code.model.FileSystemNode
|
import com.bartlomiejpluta.base.editor.code.model.FileSystemNode
|
||||||
import com.bartlomiejpluta.base.editor.code.viewmodel.CodeVM
|
import com.bartlomiejpluta.base.editor.code.viewmodel.CodeVM
|
||||||
import com.bartlomiejpluta.base.editor.command.context.UndoableScope
|
import com.bartlomiejpluta.base.editor.command.context.UndoableScope
|
||||||
@@ -85,11 +86,11 @@ class MainController : Controller() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun openScript(fsNode: FileSystemNode) {
|
fun openScript(fsNode: FileSystemNode, line: Int = 1, column: Int = 1) {
|
||||||
if (openItems.count { (_, item) -> item is Code && item.file.absolutePath == fsNode.file.absolutePath } == 0) {
|
if (openItems.count { (_, item) -> item is Code && item.file.absolutePath == fsNode.file.absolutePath } == 0) {
|
||||||
val code = projectContext.loadScript(fsNode.fileProperty)
|
val code = projectContext.loadScript(fsNode.fileProperty)
|
||||||
val vm = CodeVM(code)
|
val vm = CodeVM(code)
|
||||||
val scope = UndoableScope()
|
val scope = CodeScope(line, column)
|
||||||
setInScope(vm, scope)
|
setInScope(vm, scope)
|
||||||
|
|
||||||
openItems[scope] = code
|
openItems[scope] = code
|
||||||
|
|||||||
Reference in New Issue
Block a user