diff --git a/package.json b/package.json index b94bdb21..8260682b 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dependencies": { "@babel/runtime": "^7.28.2", "@codemirror/lang-go": "^6.0.1", + "@codemirror/lang-java": "^6.0.2", "@codemirror/lang-javascript": "^6.2.4", "@codemirror/lang-python": "^6.2.1", "@codemirror/state": "^6.5.2", diff --git a/public/icons/java.svg b/public/icons/java.svg new file mode 100644 index 00000000..9dbba1ec --- /dev/null +++ b/public/icons/java.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src-tauri/src/plugin.rs b/src-tauri/src/plugin.rs index 78904093..b9f645ce 100644 --- a/src-tauri/src/plugin.rs +++ b/src-tauri/src/plugin.rs @@ -32,6 +32,11 @@ pub async fn get_info( debug!("获取环境 -> 插件 [ {} ] 命令 {}", language, cmd); let version_output = Command::new(&cmd).args(plugin.get_version_args()).output(); + debug!( + "获取环境 -> 插件 [ {} ] 版本, 结果 {:?}", + plugin.get_language_key(), + version_output + ); if let Ok(version_out) = version_output { if version_out.status.success() { let path_result = Command::new(&cmd) @@ -39,10 +44,20 @@ pub async fn get_info( .arg(plugin.get_path_command()) .output(); - let version = String::from_utf8_lossy(&version_out.stdout) + let mut version = String::from_utf8_lossy(&version_out.stdout) .trim() .to_string(); + if version.is_empty() { + info!( + "获取环境 -> 调用插件 [ {} ] 版本为空,通过 stderr 获取", + language + ); + version = String::from_utf8_lossy(&version_out.stderr) + .trim() + .to_string(); + } + let path = if let Ok(path_out) = path_result { if path_out.status.success() { String::from_utf8_lossy(&path_out.stdout).trim().to_string() diff --git a/src-tauri/src/plugins/java.rs b/src-tauri/src/plugins/java.rs new file mode 100644 index 00000000..5e124963 --- /dev/null +++ b/src-tauri/src/plugins/java.rs @@ -0,0 +1,54 @@ +use super::{LanguagePlugin, PluginConfig}; +use std::vec; + +pub struct JavaPlugin; + +impl LanguagePlugin for JavaPlugin { + fn get_order(&self) -> i32 { + 5 + } + + fn get_language_name(&self) -> &'static str { + "Java" + } + + fn get_language_key(&self) -> &'static str { + "java" + } + + fn get_file_extension(&self) -> String { + self.get_config() + .map(|config| config.extension.clone()) + .unwrap_or_else(|| "java".to_string()) + } + + fn get_version_args(&self) -> Vec<&'static str> { + vec!["-version"] + } + + fn get_path_command(&self) -> String { + "System.out.println(System.getProperty(\"java.home\"));".to_string() + } + + fn get_default_config(&self) -> PluginConfig { + PluginConfig { + enabled: true, + language: String::from("java"), + before_compile: None, + extension: String::from("java"), + execute_home: None, + run_command: Some(String::from("java $filename")), + after_compile: Some(String::from("rm -f *.class")), + template: Some(String::from( + "public class Main {\n public static void main(String[] args) {\n System.out.println(\"Hello, World!\");\n }\n}", + )), + timeout: Some(30), + } + } + + fn get_default_command(&self) -> String { + self.get_config() + .and_then(|config| config.run_command.clone()) + .unwrap_or_else(|| "java".to_string()) + } +} diff --git a/src-tauri/src/plugins/manager.rs b/src-tauri/src/plugins/manager.rs index a55c180b..fa746616 100644 --- a/src-tauri/src/plugins/manager.rs +++ b/src-tauri/src/plugins/manager.rs @@ -2,6 +2,7 @@ use super::{ LanguagePlugin, PluginConfig, go::GoPlugin, nodejs::NodeJSPlugin, python2::Python2Plugin, python3::Python3Plugin, }; +use crate::plugins::java::JavaPlugin; use std::collections::HashMap; pub struct PluginManager { @@ -16,6 +17,7 @@ impl PluginManager { plugins.insert("python3".to_string(), Box::new(Python3Plugin)); plugins.insert("nodejs".to_string(), Box::new(NodeJSPlugin)); plugins.insert("go".to_string(), Box::new(GoPlugin)); + plugins.insert("java".to_string(), Box::new(JavaPlugin)); Self { plugins } } diff --git a/src-tauri/src/plugins/mod.rs b/src-tauri/src/plugins/mod.rs index 7c9ee409..6c204437 100644 --- a/src-tauri/src/plugins/mod.rs +++ b/src-tauri/src/plugins/mod.rs @@ -1,6 +1,7 @@ use crate::config::get_app_config_internal; use log::{debug, info}; use serde::{Deserialize, Serialize}; +use std::format; use std::path::PathBuf; // 通用结构定义 @@ -329,6 +330,7 @@ pub trait LanguagePlugin: Send + Sync { // 重新导出子模块 pub mod go; +pub mod java; pub mod manager; pub mod nodejs; pub mod python2; diff --git a/src/App.vue b/src/App.vue index fba64584..b9cfd72d 100644 --- a/src/App.vue +++ b/src/App.vue @@ -82,7 +82,12 @@ const { lastExecutionTime, runCode, stopCode, - clearOutput + clearOutput, + handleRealtimeOutput, + handleExecutionComplete, + handleExecutionStopped, + handleExecutionTimeout, + handleExecutionError } = useCodeExecution(toast) const { @@ -113,7 +118,12 @@ const { initializeEventListeners, cleanupEventListeners } = useEventManager({ isSuccess, lastExecutionTime, currentLanguage, - toast + toast, + handleRealtimeOutput, + handleExecutionComplete, + handleExecutionStopped, + handleExecutionTimeout, + handleExecutionError }) // 禁用右键菜单 diff --git a/src/components/CodeEditor.vue b/src/components/CodeEditor.vue index 25851c0a..7a781bbb 100644 --- a/src/components/CodeEditor.vue +++ b/src/components/CodeEditor.vue @@ -29,7 +29,7 @@ const { extensions, editorConfig, initializeEditor -} = useCodeMirrorEditor(props, emit) +} = useCodeMirrorEditor(props) const handleInput = (value: string) => { emit('update:modelValue', value) diff --git a/src/components/setting/Language.vue b/src/components/setting/Language.vue index 54389be2..9fa60851 100644 --- a/src/components/setting/Language.vue +++ b/src/components/setting/Language.vue @@ -1,13 +1,23 @@