Skip to content
Merged
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
26 changes: 26 additions & 0 deletions public/icons/nodejs.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion src-tauri/src/plugins/manager.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use super::{LanguagePlugin, PluginConfig, python2::Python2Plugin, python3::Python3Plugin};
use super::{
LanguagePlugin, PluginConfig, nodejs::NodeJSPlugin, python2::Python2Plugin,
python3::Python3Plugin,
};
use std::collections::HashMap;

pub struct PluginManager {
Expand All @@ -11,6 +14,7 @@ impl PluginManager {

plugins.insert("python2".to_string(), Box::new(Python2Plugin));
plugins.insert("python3".to_string(), Box::new(Python3Plugin));
plugins.insert("nodejs".to_string(), Box::new(NodeJSPlugin));

Self { plugins }
}
Expand Down
2 changes: 2 additions & 0 deletions src-tauri/src/plugins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,8 @@ pub trait LanguagePlugin: Send + Sync {

// 重新导出子模块
pub mod manager;
pub mod nodejs;
pub mod python2;
pub mod python3;

pub use manager::PluginManager;
51 changes: 51 additions & 0 deletions src-tauri/src/plugins/nodejs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use super::{LanguagePlugin, PluginConfig};

pub struct NodeJSPlugin;

impl LanguagePlugin for NodeJSPlugin {
fn get_order(&self) -> i32 {
3
}

fn get_language_name(&self) -> &'static str {
"Node.js"
}

fn get_language_key(&self) -> &'static str {
"nodejs"
}

fn get_file_extension(&self) -> String {
self.get_config()
.map(|config| config.extension.clone())
.unwrap_or_else(|| "js".to_string())
}

fn get_version_args(&self) -> Vec<&'static str> {
vec!["--version"]
}

fn get_path_command(&self) -> String {
"console.log(process.execPath)".to_string()
}

fn get_default_config(&self) -> PluginConfig {
PluginConfig {
enabled: true,
language: String::from("nodejs"),
before_compile: None,
extension: String::from("js"),
execute_home: None,
run_command: Option::from(String::from("node $filename")),
after_compile: None,
template: None,
timeout: Some(30),
}
}

fn get_default_command(&self) -> String {
self.get_config()
.and_then(|config| config.run_command)
.unwrap_or_else(|| "node".to_string())
}
}
2 changes: 1 addition & 1 deletion src/components/Settings.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<Modal v-model:show="isVisible" title="设置" size="4xl" :close-on-backdrop="false" :close-on-esc="false" @close="closeSettings">
<Modal v-model:show="isVisible" title="设置" size="4xl" :content-class="['min-h-[60vh]']" :close-on-backdrop="false" :close-on-esc="false" @close="closeSettings">
<Tabs v-model="activeTab"
type="card"
size="md"
Expand Down
2 changes: 1 addition & 1 deletion src/components/setting/Language.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
{{ `语言 [ ${ tab.label } ] 配置` }}
</h3>

<Tabs v-model="activeTab" type="card" size="md" :tabs="tabsData">
<Tabs v-model="activeTab" type="card" size="md" :tabs="tabsData" :nav-class="['w-full', 'justify-center']">
<template #general>
<div class="space-y-4">
<div>
Expand Down
152 changes: 152 additions & 0 deletions src/utils/highlighter/languages/nodejs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import type { HighlightRule, LanguageHighlighter } from '../types'

export class NodeJSHighlighter
implements LanguageHighlighter
{
getLanguageName(): string
{
return 'nodejs'
}

getDisplayName(): string
{
return 'Node.js'
}

getOrder(): number
{
return 3
}

getRules(): HighlightRule[]
{
return [
// 1. 注释 (最高优先级)
{
pattern: /\/\/.*$/gm,
className: 'text-gray-500 italic',
priority: 1
},
{
pattern: /\/\*[\s\S]*?\*\//g,
className: 'text-gray-500 italic',
priority: 1
},

// 2. 字符串 (高优先级)
{
pattern: /`(?:[^`\\]|\\.)*`/g,
className: 'text-green-600',
priority: 2
},
{
pattern: /"(?:[^"\\]|\\.)*"/g,
className: 'text-green-600',
priority: 2
},
{
pattern: /'(?:[^'\\]|\\.)*'/g,
className: 'text-green-600',
priority: 2
},

// 3. JavaScript/Node.js 关键字
{
pattern: /\b(const|let|var|function|class|if|else|for|while|do|switch|case|default|break|continue|return|try|catch|finally|throw|new|this|super|extends|import|export|from|as|async|await|yield|typeof|instanceof|in|of|delete|void|null|undefined|true|false)\b/g,
className: 'text-purple-600 font-semibold',
priority: 3
},

// 4. Node.js 特定关键字和全局对象
{
pattern: /\b(require|module|exports|process|global|__dirname|__filename|Buffer|console|setTimeout|setInterval|clearTimeout|clearInterval)\b/g,
className: 'text-indigo-600 font-semibold',
priority: 3
},

// 5. 数字
{
pattern: /\b\d+(?:\.\d+)?(?:[eE][+-]?\d+)?\b/g,
className: 'text-blue-600',
priority: 4
},

// 6. 函数调用
{
pattern: /\b([a-zA-Z_$]\w*)(?=\s*\()/g,
className: 'text-orange-600',
priority: 5
},

// 7. 类名定义
{
pattern: /\bclass\s+([A-Z]\w*)/g,
className: 'text-yellow-600 font-semibold',
priority: 6
},

// 8. 对象属性
{
pattern: /\b([a-zA-Z_$]\w*)\s*:/g,
className: 'text-cyan-600',
priority: 7
},

// 9. 箭头函数
{
pattern: /=>/g,
className: 'text-pink-600 font-bold',
priority: 8
},

// 10. 模板字符串插值
{
pattern: /\$\{[^}]*\}/g,
className: 'text-red-600 bg-yellow-100',
priority: 9
},

// 11. require 路径
{
pattern: /require\s*\(\s*(['"`])([^'"`]+)\1\s*\)/g,
className: 'text-emerald-600',
priority: 10
},

// 12. 常见的 Node.js 模块名
{
pattern: /\b(fs|path|http|https|url|crypto|util|events|stream|os|cluster|child_process|readline|querystring|zlib|assert|buffer|domain|punycode|string_decoder|tls|tty|dgram|dns|net|vm|repl)\b/g,
className: 'text-teal-600 font-medium',
priority: 11
},

// 13. 正则表达式
{
pattern: /\/(?:[^\/\\\r\n]|\\.)+\/[gimuy]*/g,
className: 'text-rose-600',
priority: 12
},

// 14. 装饰器 (如果使用 TypeScript)
{
pattern: /@[a-zA-Z_$]\w*/g,
className: 'text-violet-600',
priority: 13
}
]
}

preProcess(code: string): string
{
// Node.js 特定的预处理
// 可以在这里处理一些特殊的语法转换
return code
}

postProcess(highlighted: string): string
{
// Node.js 特定的后处理
// 可以在这里添加一些额外的样式处理
return highlighted
}
}
8 changes: 5 additions & 3 deletions src/utils/highlighter/manager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { HighlightMatch, LanguageHighlighter } from './types'
import { Python2Highlighter } from './languages/python2'
import { Python3Highlighter } from './languages/python3'
import { NodeJSHighlighter } from './languages/nodejs.ts'

export class HighlightManager
{
Expand All @@ -18,6 +19,7 @@ export class HighlightManager
{
this.register(new Python2Highlighter())
this.register(new Python3Highlighter())
this.register(new NodeJSHighlighter())
}

/**
Expand Down Expand Up @@ -171,9 +173,9 @@ export class HighlightManager
private escapeHtml(text: string): string
{
return text
// .replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
// .replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
// .replace(/"/g, '&quot;')
// .replace(/'/g, '&#39;')
}
Expand Down
Loading