diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index aff5f20..ad7f54f 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -2,9 +2,14 @@ name: Publish docs via GitHub Pages on: pull_request: - types: [closed] + types: [ closed ] workflow_dispatch: +permissions: + contents: read + pages: write + id-token: write + jobs: deploy: runs-on: ubuntu-latest diff --git a/README.md b/README.md index 963065a..d3448ec 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,9 @@ CodeForge 是一款轻量级、高性能的桌面代码执行器,专为开发 - **AppleScript** - **C** - **Clojure** +- **C++** - **Go** +- **Groovy** - **Java** - **JavaScript (Browser)** - **JavaScript (jQuery)** diff --git a/public/icons/cpp.svg b/public/icons/cpp.svg new file mode 100644 index 0000000..3820f8c --- /dev/null +++ b/public/icons/cpp.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/icons/groovy.svg b/public/icons/groovy.svg new file mode 100644 index 0000000..83d4975 --- /dev/null +++ b/public/icons/groovy.svg @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src-tauri/src/examples/cpp.cpp b/src-tauri/src/examples/cpp.cpp new file mode 100644 index 0000000..a94a0be --- /dev/null +++ b/src-tauri/src/examples/cpp.cpp @@ -0,0 +1,245 @@ +#include +#include +#include +#include +#include +#include +#include + +// C++ 示例代码 - CodeForge 代码执行环境 + +// 类声明 +class Person { +private: + std::string name; + int age; + float height; + +public: + Person(const std::string& n, int a, float h); + void display() const; + std::string getName() const { return name; } + int getAge() const { return age; } +}; + +// 函数声明 +void greetUser(const std::string& name); +int addNumbers(int a, int b); +void printVector(const std::vector& vec); +int fibonacci(int n); +template +void printArray(const T& container); + +int main() { + std::cout << "🎉 欢迎使用 CodeForge!" << std::endl; + std::cout << "Welcome to CodeForge!" << std::endl; + std::cout << std::endl; + + std::cout << "=========================================" << std::endl; + std::cout << " CodeForge C++ " << std::endl; + std::cout << "=========================================" << std::endl; + std::cout << std::endl; + + // 基本输出示例 + std::cout << "✅ C++ 运行成功! (C++ is working!)" << std::endl; + std::cout << "⚡ 这是 C++ 程序 (This is C++ program)" << std::endl; + std::cout << std::endl; + + // 变量操作 + std::string name = "CodeForge"; + std::string version = "C++"; + int number1 = 10; + int number2 = 20; + int result = addNumbers(number1, number2); + + std::cout << "🔢 简单计算 (Simple calculation):" << std::endl; + std::cout << number1 << " + " << number2 << " = " << result << std::endl; + std::cout << std::endl; + + // 字符串操作 + std::cout << "📝 字符串操作 (String operations):" << std::endl; + std::cout << "平台名称 (Platform): " << name << std::endl; + std::cout << "语言版本 (Language): " << version << std::endl; + std::cout << "完整信息 (Full info): " << name << " - " << version << std::endl; + std::cout << std::endl; + + // 循环示例 + std::cout << "🔄 循环输出 (Loop output):" << std::endl; + for (int i = 1; i <= 5; i++) { + std::cout << "第 " << i << " 次输出 (Output #" << i << "): Hello from CodeForge!" << std::endl; + } + std::cout << std::endl; + + // 容器示例 (vector) + std::cout << "🍎 容器示例 (Container example):" << std::endl; + std::vector fruits = {"苹果", "香蕉", "橙子", "葡萄"}; + for (size_t i = 0; i < fruits.size(); i++) { + std::cout << i + 1 << ". " << fruits[i] << std::endl; + } + std::cout << std::endl; + + // 条件判断 + int score = 85; + std::cout << "📊 成绩评估 (Score evaluation):" << std::endl; + if (score >= 90) { + std::cout << "优秀! (Excellent!)" << std::endl; + } else if (score >= 80) { + std::cout << "良好! (Good!)" << std::endl; + } else if (score >= 60) { + std::cout << "及格 (Pass)" << std::endl; + } else { + std::cout << "需要努力 (Need improvement)" << std::endl; + } + std::cout << std::endl; + + // 引用示例 + std::cout << "🔍 引用示例 (Reference example):" << std::endl; + int value = 42; + int& ref = value; + std::cout << "值: " << value << " (Value: " << value << ")" << std::endl; + std::cout << "地址: " << &value << " (Address: " << &value << ")" << std::endl; + std::cout << "通过引用访问: " << ref << " (Access via reference: " << ref << ")" << std::endl; + ref = 50; + std::cout << "修改引用后的值: " << value << " (Value after modifying reference: " << value << ")" << std::endl; + std::cout << std::endl; + + // 函数示例 + std::cout << "🎭 函数示例 (Function example):" << std::endl; + greetUser("CodeForge用户"); + std::cout << std::endl; + + // 智能指针示例 + std::cout << "💾 智能指针示例 (Smart pointer example):" << std::endl; + auto dynamicArray = std::make_unique>(5); + for (int i = 0; i < 5; i++) { + (*dynamicArray)[i] = (i + 1) * 10; + } + std::cout << "智能指针管理的动态数组: "; + printVector(*dynamicArray); + std::cout << "内存自动释放" << std::endl; + std::cout << std::endl; + + // 类和对象示例 + std::cout << "👤 类和对象示例 (Class and object example):" << std::endl; + Person person("张三", 25, 175.5f); + person.display(); + std::cout << std::endl; + + // 递归示例 + std::cout << "🔄 递归示例 (Recursion example):" << std::endl; + int fib_n = 7; + int fib_result = fibonacci(fib_n); + std::cout << "斐波那契数列第" << fib_n << "项: " << fib_result << std::endl; + std::cout << std::endl; + + // 数学库示例 + std::cout << "📐 数学库示例 (Math library example):" << std::endl; + double angle = 45.0; + double radians = angle * M_PI / 180.0; + std::cout << "sin(" << angle << "°) = " << std::sin(radians) << std::endl; + std::cout << "cos(" << angle << "°) = " << std::cos(radians) << std::endl; + std::cout << "sqrt(16) = " << std::sqrt(16) << std::endl; + std::cout << std::endl; + + // 位操作示例 + std::cout << "🔧 位操作示例 (Bitwise operations):" << std::endl; + int a = 12; // 1100 in binary + int b = 10; // 1010 in binary + std::cout << a << " & " << b << " = " << (a & b) << " (AND)" << std::endl; + std::cout << a << " | " << b << " = " << (a | b) << " (OR)" << std::endl; + std::cout << a << " ^ " << b << " = " << (a ^ b) << " (XOR)" << std::endl; + std::cout << "~" << a << " = " << (~a) << " (NOT)" << std::endl; + std::cout << std::endl; + + // 枚举示例 + std::cout << "📋 枚举示例 (Enum example):" << std::endl; + enum class Weekday { + MONDAY = 1, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY + }; + Weekday today = Weekday::WEDNESDAY; + std::cout << "今天是星期" << static_cast(today) << std::endl; + std::cout << std::endl; + + // STL算法示例 + std::cout << "🚀 STL算法示例 (STL algorithm example):" << std::endl; + std::vector numbers = {5, 2, 8, 1, 9, 3}; + std::cout << "原始数组: "; + printVector(numbers); + + std::sort(numbers.begin(), numbers.end()); + std::cout << "排序后数组: "; + printVector(numbers); + + auto it = std::find(numbers.begin(), numbers.end(), 8); + if (it != numbers.end()) { + std::cout << "找到数字 8 在位置: " << (it - numbers.begin()) << std::endl; + } + std::cout << std::endl; + + // Map容器示例 + std::cout << "🗺️ Map容器示例 (Map container example):" << std::endl; + std::map scores = { + {"张三", 85}, + {"李四", 92}, + {"王五", 78} + }; + + for (const auto& pair : scores) { + std::cout << pair.first << ": " << pair.second << "分" << std::endl; + } + std::cout << std::endl; + + // Lambda表达式示例 + std::cout << "🔗 Lambda表达式示例 (Lambda expression example):" << std::endl; + auto multiply = [](int x, int y) -> int { + return x * y; + }; + std::cout << "Lambda计算 5 * 3 = " << multiply(5, 3) << std::endl; + std::cout << std::endl; + + std::cout << "🎯 CodeForge C++ 代码执行完成!" << std::endl; + std::cout << "🎯 CodeForge C++ execution completed!" << std::endl; + std::cout << std::endl; + std::cout << "感谢使用 CodeForge 代码执行环境! 🚀" << std::endl; + std::cout << "Thank you for using CodeForge! 🚀" << std::endl; + + return 0; +} + +// 类实现 +Person::Person(const std::string& n, int a, float h) : name(n), age(a), height(h) {} + +void Person::display() const { + std::cout << "姓名: " << name << ", 年龄: " << age << ", 身高: " << height << " cm" << std::endl; +} + +// 函数实现 +void greetUser(const std::string& name) { + std::cout << "Hello, " << name << "! 👋" << std::endl; +} + +int addNumbers(int a, int b) { + return a + b; +} + +void printVector(const std::vector& vec) { + for (const auto& element : vec) { + std::cout << element << " "; + } + std::cout << std::endl; +} + +int fibonacci(int n) { + if (n <= 1) { + return n; + } + return fibonacci(n - 1) + fibonacci(n - 2); +} + +template +void printArray(const T& container) { + for (const auto& element : container) { + std::cout << element << " "; + } + std::cout << std::endl; +} \ No newline at end of file diff --git a/src-tauri/src/examples/groovy.groovy b/src-tauri/src/examples/groovy.groovy new file mode 100644 index 0000000..64bfa98 --- /dev/null +++ b/src-tauri/src/examples/groovy.groovy @@ -0,0 +1,284 @@ +// Groovy 示例代码 - CodeForge 代码执行环境 + +// 类定义 +class Person { + String name + int age + float height + + Person(String name, int age, float height) { + this.name = name + this.age = age + this.height = height + } + + void display() { + println "姓名: ${name}, 年龄: ${age}, 身高: ${height} cm" + } + + String toString() { + return "Person(name: ${name}, age: ${age}, height: ${height})" + } +} + +// 函数定义 +def greetUser(name) { + println "Hello, ${name}! 👋" +} + +def addNumbers(a, b) { + return a + b +} + +def printList(list) { + list.each { element -> + print "${element} " + } + println "" +} + +def fibonacci(n) { + if (n <= 1) return n + return fibonacci(n - 1) + fibonacci(n - 2) +} + +// 主程序执行 +println "🎉 欢迎使用 CodeForge!" +println "Welcome to CodeForge!" +println "" + +println "=========================================" +println " CodeForge Groovy " +println "=========================================" +println "" + +// 基本输出示例 +println "✅ Groovy 运行成功! (Groovy is working!)" +println "⚡ 这是 Groovy 程序 (This is Groovy program)" +println "" + +// 变量操作 +def name = "CodeForge" +def version = "Groovy" +def number1 = 10 +def number2 = 20 +def result = addNumbers(number1, number2) + +println "🔢 简单计算 (Simple calculation):" +println "${number1} + ${number2} = ${result}" +println "" + +// 字符串操作和插值 +println "📝 字符串操作 (String operations):" +println "平台名称 (Platform): ${name}" +println "语言版本 (Language): ${version}" +println "完整信息 (Full info): ${name} - ${version}" +println "" + +// 循环示例 +println "🔄 循环输出 (Loop output):" +(1..5).each { i -> + println "第 ${i} 次输出 (Output #${i}): Hello from CodeForge!" +} +println "" + +// 列表示例 +println "🍎 列表示例 (List example):" +def fruits = ["苹果", "香蕉", "橙子", "葡萄"] +fruits.eachWithIndex { fruit, index -> + println "${index + 1}. ${fruit}" +} +println "" + +// 条件判断 +def score = 85 +println "📊 成绩评估 (Score evaluation):" +switch (score) { + case { it >= 90 }: + println "优秀! (Excellent!)" + break + case { it >= 80 }: + println "良好! (Good!)" + break + case { it >= 60 }: + println "及格 (Pass)" + break + default: + println "需要努力 (Need improvement)" +} +println "" + +// Groovy特有的属性访问 +println "🔍 动态属性示例 (Dynamic property example):" +def obj = [:] +obj.dynamicProperty = "动态值" +obj.number = 42 +println "动态属性: ${obj.dynamicProperty}" +println "数字属性: ${obj.number}" +println "对象内容: ${obj}" +println "" + +// 函数示例 +println "🎭 函数示例 (Function example):" +greetUser("CodeForge用户") +println "" + +// 集合操作示例 +println "💾 集合操作示例 (Collection operations):" +def numbers = [1, 2, 3, 4, 5] +def doubled = numbers.collect { it * 2 } +def evens = numbers.findAll { it % 2 == 0 } +def sum = numbers.sum() + +println "原始列表: ${numbers}" +println "每个数字乘以2: ${doubled}" +println "偶数: ${evens}" +println "总和: ${sum}" +println "" + +// 类和对象示例 +println "👤 类和对象示例 (Class and object example):" +def person = new Person("张三", 25, 175.5f) +person.display() +println "toString方法: ${person}" +println "" + +// 递归示例 +println "🔄 递归示例 (Recursion example):" +def fib_n = 7 +def fib_result = fibonacci(fib_n) +println "斐波那契数列第${fib_n}项: ${fib_result}" +println "" + +// 数学运算示例 +println "📐 数学运算示例 (Math operations):" +def angle = 45.0 +def radians = Math.toRadians(angle) +println "sin(${angle}°) = ${Math.sin(radians).round(4)}" +println "cos(${angle}°) = ${Math.cos(radians).round(4)}" +println "sqrt(16) = ${Math.sqrt(16)}" +println "" + +// 位操作示例 +println "🔧 位操作示例 (Bitwise operations):" +def a = 12 // 1100 in binary +def b = 10 // 1010 in binary +println "${a} & ${b} = ${a & b} (AND)" +println "${a} | ${b} = ${a | b} (OR)" +println "${a} ^ ${b} = ${a ^ b} (XOR)" +println "~${a} = ${~a} (NOT)" +println "" + +// 枚举示例 +println "📋 枚举示例 (Enum example):" +enum Weekday { + MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), + FRIDAY(5), SATURDAY(6), SUNDAY(7) + + final int value + + Weekday(int value) { + this.value = value + } +} + +def today = Weekday.WEDNESDAY +println "今天是星期${today.value}: ${today}" +println "" + +// 闭包示例 +println "🚀 闭包示例 (Closure example):" +def multiplier = { x, y -> x * y } +def greeter = { userName -> "Hello, ${userName}!" } +def calculator = { operation, num1, num2 -> + switch(operation) { + case 'add': return num1 + num2 + case 'multiply': return num1 * num2 + case 'subtract': return num1 - num2 + default: return 0 + } +} + +println "闭包乘法 5 * 3 = ${multiplier(5, 3)}" +println "闭包问候: ${greeter('Groovy')}" +println "闭包计算器 (add, 10, 5) = ${calculator('add', 10, 5)}" +println "" + +// Map操作示例 +println "🗺️ Map操作示例 (Map operations):" +def scores = [ + "张三": 85, + "李四": 92, + "王五": 78 +] + +scores.each { key, value -> + println "${key}: ${value}分" +} + +def highScores = scores.findAll { key, value -> value >= 85 } +println "高分学生: ${highScores}" +println "" + +// 正则表达式示例 +println "🔍 正则表达式示例 (Regex example):" +def text = "CodeForge 2025 是最好的代码执行平台!" +def pattern = ~/\d+/ +def matcher = text =~ pattern +if (matcher) { + println "找到数字: ${matcher[0]}" +} + +def emailPattern = ~/\w+@\w+\.\w+/ +def email = "test@codeforge.com" +println "邮箱验证 '${email}': ${email ==~ emailPattern}" +println "" + +// 异常处理示例 +println "⚠️ 异常处理示例 (Exception handling):" +try { + def divisionResult = 10 / 0 +} catch (ArithmeticException e) { + println "捕获异常: ${e.message}" +} finally { + println "finally块总是执行" +} +println "" + +// 文件操作示例 +println "📁 字符串操作示例 (String operations):" +def multilineString = """ +这是一个 +多行字符串 +示例 +""" +println "多行字符串长度: ${multilineString.trim().split('\n').size()} 行" + +def template = "Hello \${userName}, welcome to \${platformName}!" +def binding = [userName: 'User', platformName: 'CodeForge'] +def engine = new groovy.text.SimpleTemplateEngine() +def templateResult = engine.createTemplate(template).make(binding) +println "模板结果: ${templateResult}" +println "" + +// 元编程示例 +println "🎯 元编程示例 (Metaprogramming example):" +String.metaClass.reverseString = { + delegate.reverse() +} + +String.metaClass.addPrefix = { prefix -> + prefix + delegate +} + +def str = "CodeForge" +println "原字符串: ${str}" +println "反转字符串: ${str.reverseString()}" +println "添加前缀: ${str.addPrefix('Hello ')}" +println "" + +println "🎯 CodeForge Groovy 代码执行完成!" +println "🎯 CodeForge Groovy execution completed!" +println "" +println "感谢使用 CodeForge 代码执行环境! 🚀" +println "Thank you for using CodeForge! 🚀" \ No newline at end of file diff --git a/src-tauri/src/execution.rs b/src-tauri/src/execution.rs index 473e55c..726ca9d 100644 --- a/src-tauri/src/execution.rs +++ b/src-tauri/src/execution.rs @@ -130,8 +130,8 @@ pub async fn execute_code( { Ok(child) => child, Err(e) => { - let execution_time = start_time.elapsed().as_millis(); - let timestamp = SystemTime::now() + let _execution_time = start_time.elapsed().as_millis(); + let _timestamp = SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap() .as_secs(); @@ -146,17 +146,10 @@ pub async fn execute_code( ); error!("执行代码 -> 调用插件 [ {} ] 失败: {}", request.language, e); - return Ok(ExecutionResult { - success: false, - stdout: String::new(), - stderr: format!( - "{} interpreter not found. Please install {} and ensure it's in your PATH.\n\nError: {}", - request.language, request.language, e - ), - execution_time, - timestamp, - language: request.language, - }); + return Err(format!( + "{} interpreter not found. Please install {} and ensure it's in your PATH.\n\nError: {}", + request.language, request.language, e + )); } }; diff --git a/src-tauri/src/plugins/cpp.rs b/src-tauri/src/plugins/cpp.rs new file mode 100644 index 0000000..a2abff6 --- /dev/null +++ b/src-tauri/src/plugins/cpp.rs @@ -0,0 +1,77 @@ +use super::{LanguagePlugin, PluginConfig}; +use std::vec; + +pub struct CppPlugin; + +impl LanguagePlugin for CppPlugin { + fn get_order(&self) -> i32 { + 18 + } + + fn get_language_name(&self) -> &'static str { + "C++" + } + + fn get_language_key(&self) -> &'static str { + "cpp" + } + + fn get_file_extension(&self) -> String { + self.get_config() + .map(|config| config.extension.clone()) + .unwrap_or_else(|| "cpp".to_string()) + } + + fn get_version_args(&self) -> Vec<&'static str> { + vec!["--version"] + } + + fn get_path_command(&self) -> String { + "which g++".to_string() + } + + fn get_command( + &self, + _file_path: Option<&str>, + _is_version: bool, + _file_name: Option, + ) -> String { + if _is_version { + // 获取版本信息时,返回编译器命令 + return "g++".to_string(); + } + + // 执行代码时 + if let Some(config) = self.get_config() { + if let Some(run_cmd) = &config.run_command { + return if let Some(file_name) = _file_name { + run_cmd.replace("$filename", &file_name) + } else { + // 执行代码但没有文件名时,返回原始命令让框架处理 $filename 替换 + run_cmd.clone() + }; + } + } + self.get_default_command() + } + + fn get_default_config(&self) -> PluginConfig { + PluginConfig { + enabled: true, + language: String::from("cpp"), + before_compile: Some(String::from("g++ $filename -o $filename")), + extension: String::from("cpp"), + execute_home: None, + run_command: Some(String::from("$filename")), + after_compile: Some(String::from("rm -f $filename")), + template: Some(String::from("// 在这里输入 C++ 代码")), + timeout: Some(30), + } + } + + fn get_default_command(&self) -> String { + self.get_config() + .and_then(|config| config.run_command.clone()) + .unwrap_or_else(|| "g++".to_string()) + } +} diff --git a/src-tauri/src/plugins/groovy.rs b/src-tauri/src/plugins/groovy.rs new file mode 100644 index 0000000..9da9651 --- /dev/null +++ b/src-tauri/src/plugins/groovy.rs @@ -0,0 +1,87 @@ +use super::{LanguagePlugin, PluginConfig}; +use std::vec; + +pub struct GroovyPlugin; + +impl LanguagePlugin for GroovyPlugin { + fn get_order(&self) -> i32 { + 19 + } + + fn get_language_name(&self) -> &'static str { + "Groovy" + } + + fn get_language_key(&self) -> &'static str { + "groovy" + } + + fn get_file_extension(&self) -> String { + self.get_config() + .map(|config| config.extension.clone()) + .unwrap_or_else(|| "groovy".to_string()) + } + + fn get_version_args(&self) -> Vec<&'static str> { + vec!["--version"] + } + + fn get_path_command(&self) -> String { + "which groovy".to_string() + } + + fn get_command( + &self, + _file_path: Option<&str>, + _is_version: bool, + _file_name: Option, + ) -> String { + if _is_version { + // 获取版本信息时,返回解释器命令 + return "groovy".to_string(); + } + + // 执行代码时 + if let Some(config) = self.get_config() { + if let Some(run_cmd) = &config.run_command { + return if let Some(file_name) = _file_name { + run_cmd.replace("$filename", &file_name) + } else { + // 执行代码但没有文件名时,返回原始命令让框架处理 $filename 替换 + run_cmd.clone() + }; + } + } + self.get_default_command() + } + + fn get_execute_args(&self, file_path: &str) -> Vec { + let cmd = if self.get_execute_home().is_some() { + format!("./groovy {}", file_path) + } else { + format!("groovy {}", file_path) + }; + + vec!["-c".to_string(), cmd] + } + + fn get_default_config(&self) -> PluginConfig { + PluginConfig { + enabled: true, + language: String::from("groovy"), + before_compile: None, + extension: String::from("groovy"), + execute_home: None, + run_command: Some(String::from("bash")), + after_compile: None, + template: Some(String::from("// 在这里输入 Groovy 代码")), + timeout: Some(30), + } + } + + fn get_default_command(&self) -> String { + self.get_config() + .and_then(|config| config.run_command.clone()) + .unwrap_or_else(|| "groovy".to_string()) + } +} diff --git a/src-tauri/src/plugins/manager.rs b/src-tauri/src/plugins/manager.rs index 14cc9a3..3920833 100644 --- a/src-tauri/src/plugins/manager.rs +++ b/src-tauri/src/plugins/manager.rs @@ -2,7 +2,9 @@ use super::{LanguagePlugin, PluginConfig}; use crate::plugins::applescript::AppleScriptPlugin; use crate::plugins::c::CPlugin; use crate::plugins::clojure::ClojurePlugin; +use crate::plugins::cpp::CppPlugin; use crate::plugins::go::GoPlugin; +use crate::plugins::groovy::GroovyPlugin; use crate::plugins::java::JavaPlugin; use crate::plugins::javascript_browser::JavaScriptBrowserPlugin; use crate::plugins::javascript_jquery::JavaScriptJQueryPlugin; @@ -44,6 +46,8 @@ impl PluginManager { plugins.insert("ruby".to_string(), Box::new(RubyPlugin)); plugins.insert("applescript".to_string(), Box::new(AppleScriptPlugin)); plugins.insert("typescript".to_string(), Box::new(TypeScriptPlugin)); + plugins.insert("cpp".to_string(), Box::new(CppPlugin)); + plugins.insert("groovy".to_string(), Box::new(GroovyPlugin)); plugins.insert( "javascript-nodejs".to_string(), Box::new(JavaScriptNodeJsPlugin), diff --git a/src-tauri/src/plugins/mod.rs b/src-tauri/src/plugins/mod.rs index 175c1f5..528468a 100644 --- a/src-tauri/src/plugins/mod.rs +++ b/src-tauri/src/plugins/mod.rs @@ -371,7 +371,9 @@ pub trait LanguagePlugin: Send + Sync { pub mod applescript; pub mod c; pub mod clojure; +pub mod cpp; pub mod go; +pub mod groovy; pub mod java; pub mod javascript_browser; pub mod javascript_jquery; diff --git a/src/composables/useCodeMirrorEditor.ts b/src/composables/useCodeMirrorEditor.ts index 70c6b2e..c521dab 100644 --- a/src/composables/useCodeMirrorEditor.ts +++ b/src/composables/useCodeMirrorEditor.ts @@ -10,6 +10,7 @@ import {swift} from '@codemirror/legacy-modes/mode/swift' import {kotlin, scala} from '@codemirror/legacy-modes/mode/clike' import {clojure} from '@codemirror/legacy-modes/mode/clojure' import {ruby} from '@codemirror/legacy-modes/mode/ruby' +import {groovy} from '@codemirror/legacy-modes/mode/groovy' import { abcdef, abyss, @@ -175,6 +176,7 @@ export function useCodeMirrorEditor(props: Props) case 'rust': return rust() case 'c': + case 'cpp': return cpp() case 'shell': case 'applescript': @@ -193,6 +195,8 @@ export function useCodeMirrorEditor(props: Props) case 'typescript-browser': case 'typescript-nodejs': return javascript({typescript: true}) + case 'groovy': + return StreamLanguage.define(groovy) default: return null }