Skip to content

Adding support for the new VSCode extension #1115

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ dependencies {
testImplementation(libs.junitJupiterParams)

implementation(libs.clikt)
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
}

tasks.test {
Expand Down Expand Up @@ -419,7 +420,6 @@ tasks.register<Copy>("renameWindres") {
}
tasks.register("includeProcessingResources"){
dependsOn(
"includeJdk",
"includeCore",
"includeJavaMode",
"includeSharedAssets",
Expand All @@ -428,6 +428,7 @@ tasks.register("includeProcessingResources"){
"includeJavaModeResources",
"renameWindres"
)
mustRunAfter("includeJdk")
finalizedBy("signResources")
}

Expand Down Expand Up @@ -534,6 +535,7 @@ afterEvaluate {
dependsOn("includeProcessingResources")
}
tasks.named("createDistributable").configure {
dependsOn("includeJdk")
finalizedBy("setExecutablePermissions")
}
}
12 changes: 0 additions & 12 deletions app/src/processing/app/Base.java
Original file line number Diff line number Diff line change
Expand Up @@ -166,18 +166,6 @@ static public void main(final String[] args) {
static private void createAndShowGUI(String[] args) {
// these times are fairly negligible relative to Base.<init>
// long t1 = System.currentTimeMillis();
var preferences = java.util.prefs.Preferences.userRoot().node("org/processing/app");
var installLocations = new ArrayList<>(List.of(preferences.get("installLocations", "").split(",")));
var installLocation = System.getProperty("user.dir") + "^" + Base.getVersionName();

// Check if the installLocation is already in the list
if (!installLocations.contains(installLocation)) {
// Add the installLocation to the list
installLocations.add(installLocation);

// Save the updated list back to preferences
preferences.put("installLocations", String.join(",", installLocations));
}
// TODO: Cleanup old locations if no longer installed
// TODO: Cleanup old locations if current version is installed in the same location

Expand Down
70 changes: 65 additions & 5 deletions app/src/processing/app/Processing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ import com.github.ajalt.clikt.parameters.arguments.multiple
import com.github.ajalt.clikt.parameters.options.flag
import com.github.ajalt.clikt.parameters.options.help
import com.github.ajalt.clikt.parameters.options.option
import processing.app.api.Contributions
import processing.app.api.Sketchbook
import processing.app.ui.Start
import java.io.File
import java.util.prefs.Preferences
import kotlin.concurrent.thread

class Processing: SuspendingCliktCommand("processing"){
val version by option("-v","--version")
Expand All @@ -29,6 +34,11 @@ class Processing: SuspendingCliktCommand("processing"){
return
}

thread {
// Update the install locations in preferences
updateInstallLocations()
}

val subcommand = currentContext.invokedSubcommand
if (subcommand == null) {
Start.main(sketches.toTypedArray())
Expand All @@ -40,7 +50,9 @@ suspend fun main(args: Array<String>){
Processing()
.subcommands(
LSP(),
LegacyCLI(args)
LegacyCLI(args),
Contributions(),
Sketchbook()
)
.main(args)
}
Expand All @@ -49,10 +61,13 @@ class LSP: SuspendingCliktCommand("lsp"){
override fun help(context: Context) = "Start the Processing Language Server"
override suspend fun run(){
try {
// run in headless mode
System.setProperty("java.awt.headless", "true")

// Indirect invocation since app does not depend on java mode
Class.forName("processing.mode.java.lsp.PdeLanguageServer")
.getMethod("main", Array<String>::class.java)
.invoke(null, *arrayOf<Any>(emptyList<String>()))
.invoke(null, arrayOf<String>())
} catch (e: Exception) {
throw InternalError("Failed to invoke main method", e)
}
Expand All @@ -76,9 +91,8 @@ class LegacyCLI(val args: Array<String>): SuspendingCliktCommand( "cli"){
override suspend fun run(){
val cliArgs = args.filter { it != "cli" }
try {
if(build){
System.setProperty("java.awt.headless", "true")
}
System.setProperty("java.awt.headless", "true")

// Indirect invocation since app does not depend on java mode
Class.forName("processing.mode.java.Commander")
.getMethod("main", Array<String>::class.java)
Expand All @@ -87,4 +101,50 @@ class LegacyCLI(val args: Array<String>): SuspendingCliktCommand( "cli"){
throw InternalError("Failed to invoke main method", e)
}
}
}

fun updateInstallLocations(){
val preferences = Preferences.userRoot().node("org/processing/app")
val installLocations = preferences.get("installLocations", "")
.split(",")
.dropLastWhile { it.isEmpty() }
.filter { install ->
try{
val (path, version) = install.split("^")
val file = File(path)
if(!file.exists() || file.isDirectory){
return@filter false
}
// call the path to check if it is a valid install location
val process = ProcessBuilder(path, "--version")
.redirectErrorStream(true)
.start()
val exitCode = process.waitFor()
if(exitCode != 0){
return@filter false
}
val output = process.inputStream.bufferedReader().readText()
return@filter output.contains(version)
} catch (e: Exception){
false
}
}
.toMutableList()
val command = ProcessHandle.current().info().command()
if(command.isEmpty) {
return
}
val installLocation = "${command.get()}^${Base.getVersionName()}"


// Check if the installLocation is already in the list
if (installLocations.contains(installLocation)) {
return
}

// Add the installLocation to the list
installLocations.add(installLocation)

// Save the updated list back to preferences
preferences.put("installLocations", java.lang.String.join(",", installLocations))
}
63 changes: 63 additions & 0 deletions app/src/processing/app/api/Contributions.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package processing.app.api

import com.github.ajalt.clikt.command.SuspendingCliktCommand
import com.github.ajalt.clikt.core.Context
import com.github.ajalt.clikt.core.subcommands
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import processing.app.Base
import processing.app.api.Sketch.Companion.getSketches
import java.io.File

class Contributions: SuspendingCliktCommand(){
override fun help(context: Context) = "Manage Processing contributions"
override suspend fun run() {
System.setProperty("java.awt.headless", "true")
}
init {
subcommands(Examples())
}

class Examples: SuspendingCliktCommand("examples") {
override fun help(context: Context) = "Manage Processing examples"
override suspend fun run() {
}
init {
subcommands(ExamplesList())
}
}

class ExamplesList: SuspendingCliktCommand("list") {


val serializer = Json {
prettyPrint = true
}

override fun help(context: Context) = "List all examples"
override suspend fun run() {

val examplesFolder = Base.getSketchbookExamplesFolder()

// TODO: Decouple modes listing from `Base` class, defaulting to Java mode for now
val resourcesDir = System.getProperty("compose.application.resources.dir")
val javaMode = "$resourcesDir/modes/java"
val javaModeExamples = "$javaMode/examples"

val javaExamples = getSketches(File(javaModeExamples))

val json = serializer.encodeToString(listOf(javaExamples))
println(json)

// Build-in examples for each mode
// Get examples for core libraries

// Examples downloaded in the sketchbook
// Library contributions
// Mode examples
}


}
}
48 changes: 48 additions & 0 deletions app/src/processing/app/api/Sketch.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package processing.app.api

import kotlinx.serialization.Serializable
import java.io.File

class Sketch {
companion object{
@Serializable
data class Sketch(
val type: String = "sketch",
val name: String,
val path: String,
val mode: String = "java",
)

@Serializable
data class Folder(
val type: String = "folder",
val name: String,
val path: String,
val mode: String = "java",
val children: List<Folder> = emptyList(),
val sketches: List<Sketch> = emptyList()
)

fun getSketches(file: File, filter: (File) -> Boolean = { true }): Folder {
val name = file.name
val (sketchesFolders, childrenFolders) = file.listFiles()?.partition { isSketchFolder(it) } ?: return Folder(
name = name,
path = file.absolutePath,
sketches = emptyList(),
children = emptyList()
)

val children = childrenFolders.filter(filter) .map { getSketches(it) }
val sketches = sketchesFolders.map { Sketch(name = it.name, path = it.absolutePath) }
return Folder(
name = name,
path = file.absolutePath,
children = children,
sketches = sketches
)
}
fun isSketchFolder(file: File): Boolean {
return file.isDirectory && file.listFiles().any { it.isFile && it.name.endsWith(".pde") }
}
}
}
42 changes: 42 additions & 0 deletions app/src/processing/app/api/Sketchbook.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package processing.app.api

import com.github.ajalt.clikt.command.SuspendingCliktCommand
import com.github.ajalt.clikt.core.Context
import com.github.ajalt.clikt.core.subcommands
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import processing.app.Platform
import processing.app.Preferences
import processing.app.api.Sketch.Companion.getSketches
import java.io.File

class Sketchbook: SuspendingCliktCommand() {


override fun help(context: Context) = "Manage the sketchbook"
override suspend fun run() {
System.setProperty("java.awt.headless", "true")
}
init {
subcommands(SketchbookList())
}


class SketchbookList: SuspendingCliktCommand("list") {
val serializer = Json {
prettyPrint = true
}

override fun help(context: Context) = "List all sketches"
override suspend fun run() {
Platform.init()
// TODO: Allow the user to change the sketchbook location
// TODO: Currently blocked since `Base.getSketchbookFolder()` is not available in headless mode
val sketchbookFolder = Platform.getDefaultSketchbookFolder()

val sketches = getSketches(sketchbookFolder.resolve("sketchbook"))
val json = serializer.encodeToString(listOf(sketches))
println(json)
}
}
}
Loading