Skip to content

Commit 0f7b4fb

Browse files
committed
feat (core): 支持语言选择
1 parent af334a8 commit 0f7b4fb

6 files changed

Lines changed: 163 additions & 31 deletions

File tree

src-tauri/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ async fn get_info(
192192
#[tauri::command]
193193
async fn get_supported_languages(
194194
plugin_manager: State<'_, PluginManagerState>,
195-
) -> Result<Vec<String>, String> {
195+
) -> Result<Vec<serde_json::Value>, String> {
196196
let manager = plugin_manager.lock().await;
197197
Ok(manager.get_supported_languages())
198198
}

src-tauri/src/plugins/manager.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,16 @@ impl PluginManager {
1919
self.plugins.get(language).map(|plugin| plugin.as_ref())
2020
}
2121

22-
pub fn get_supported_languages(&self) -> Vec<String> {
23-
self.plugins.keys().cloned().collect()
22+
pub fn get_supported_languages(&self) -> Vec<serde_json::Value> {
23+
self.plugins
24+
.iter()
25+
.map(|(key, plugin)| {
26+
serde_json::json!({
27+
"name": plugin.get_language_name(),
28+
"value": key
29+
})
30+
})
31+
.collect()
2432
}
2533

2634
#[allow(dead_code)]

src-tauri/src/plugins/python2.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ impl LanguagePlugin for Python2Plugin {
4040
fn post_execute_hook(&self, result: &mut ExecutionResult) -> Result<(), String> {
4141
// Python 特定的后处理
4242
if result.success && result.stdout.is_empty() && result.stderr.is_empty() {
43-
result.stdout = "Code executed successfully (no output)".to_string();
43+
result.stdout = "代码执行成功 (无输出)".to_string();
4444
}
4545

4646
// 清理 Python 特定的错误信息

src-tauri/src/plugins/python3.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ impl LanguagePlugin for Python3Plugin {
4040
fn post_execute_hook(&self, result: &mut ExecutionResult) -> Result<(), String> {
4141
// Python 特定的后处理
4242
if result.success && result.stdout.is_empty() && result.stderr.is_empty() {
43-
result.stdout = "Code executed successfully (no output)".to_string();
43+
result.stdout = "代码执行成功 (无输出)".to_string();
4444
}
4545

4646
// 清理 Python 特定的错误信息

src/App.vue

Lines changed: 110 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,24 @@
22
<div class="h-screen flex flex-col bg-gray-50">
33
<AppHeader :is-running="isRunning"
44
:env-installed="envInfo.installed"
5+
:supported-languages="supportedLanguages"
6+
:current-language="currentLanguage"
57
@run-code="runCode"
68
@clear-output="clearOutput"
9+
@language-change="handleLanguageChange"
710
@show-settings="showSettings = true">
811
</AppHeader>
912

1013
<div class="flex-1 flex overflow-hidden">
1114
<!-- 代码编辑器 -->
1215
<div class="flex-1 flex flex-col">
1316
<div class="bg-gray-100 px-4 py-2 border-b border-gray-200 flex items-center justify-between">
14-
<h2 class="text-sm font-medium text-gray-700">Python 代码编辑器</h2>
17+
<h2 class="text-sm font-medium text-gray-700">{{ getLanguageDisplayName(currentLanguage) }} 代码编辑器</h2>
1518
<div class="text-xs text-gray-500">
1619
<strong>{{ code.length }}</strong> 字符, <strong>{{ code.split('\n').length }}</strong> 行
1720
</div>
1821
</div>
19-
<CodeEditor v-model="code"
20-
language="python"
21-
class="flex-1">
22-
</CodeEditor>
22+
<CodeEditor v-model="code" class="flex-1" :language="currentLanguage"/>
2323
</div>
2424

2525
<!-- 输出 -->
@@ -35,10 +35,7 @@
3535
</div>
3636

3737
<!-- 状态栏 -->
38-
<StatusBar :env-info="envInfo"
39-
:execution-time="lastExecutionTime"
40-
:code-length="code.length">
41-
</StatusBar>
38+
<StatusBar :env-info="envInfo" :execution-time="lastExecutionTime" :code-length="code.length"/>
4239

4340
<!-- 通知信息 -->
4441
<Toast v-if="toast.show"
@@ -87,7 +84,15 @@ interface EnvInfo
8784
language: string
8885
}
8986
90-
const code = ref(`# Welcome to CodeForge!
87+
interface Language
88+
{
89+
name: string
90+
value: string
91+
}
92+
93+
// 代码模板
94+
const codeTemplates: Record<string, string> = {
95+
python: `# Welcome to CodeForge!
9196
# Write your Python code here and click Run to execute
9297
9398
print("Hello, CodeForge!")
@@ -102,14 +107,52 @@ print(f"The result of {x} + {y} = {result}")
102107
numbers = [1, 2, 3, 4, 5]
103108
squared = [n**2 for n in numbers]
104109
print(f"Original: {numbers}")
105-
print(f"Squared: {squared}")`)
110+
print(f"Squared: {squared}")`,
111+
112+
python2: `# Welcome to CodeForge - Python 2!
113+
# Write your Python 2 code here and click Run to execute
114+
115+
print "Hello, CodeForge from Python 2!"
116+
117+
# Example: Simple calculation
118+
x = 10
119+
y = 20
120+
result = x + y
121+
print "The result of %d + %d = %d" % (x, y, result)
122+
123+
# Example: List operations
124+
numbers = [1, 2, 3, 4, 5]
125+
squared = [n**2 for n in numbers]
126+
print "Original:", numbers
127+
print "Squared:", squared`,
128+
129+
python3: `# Welcome to CodeForge - Python 3!
130+
# Write your Python 3 code here and click Run to execute
106131
132+
print("Hello, CodeForge from Python 3!")
133+
134+
# Example: Simple calculation
135+
x = 10
136+
y = 20
137+
result = x + y
138+
print(f"The result of {x} + {y} = {result}")
139+
140+
# Example: List operations
141+
numbers = [1, 2, 3, 4, 5]
142+
squared = [n**2 for n in numbers]
143+
print(f"Original: {numbers}")
144+
print(f"Squared: {squared}")`
145+
}
146+
147+
const code = ref('')
148+
const currentLanguage = ref('python')
107149
const output = ref('')
108150
const isRunning = ref(false)
109151
const isSuccess = ref(false)
110152
const lastExecutionTime = ref(0)
111153
const activeTab = ref('output')
112154
const showSettings = ref(false)
155+
const supportedLanguages = ref<Language[]>([])
113156
114157
const envInfo = ref<EnvInfo>({
115158
installed: false,
@@ -126,15 +169,17 @@ const toast = ref({
126169
127170
const showToast = (message: string, type: 'success' | 'error' | 'info' = 'success') => {
128171
toast.value = { show: true, message, type }
129-
setTimeout(() => {
130-
toast.value.show = false
131-
}, 3000)
172+
}
173+
174+
const getLanguageDisplayName = (languageValue: string) => {
175+
const language = supportedLanguages.value.find(lang => lang.value === languageValue)
176+
return language ? language.name : languageValue
132177
}
133178
134179
const refreshEnvInfo = async () => {
135180
try {
136181
const info: LanguageInfo = await invoke('get_info', {
137-
language: 'python2'
182+
language: currentLanguage.value
138183
})
139184
140185
envInfo.value = {
@@ -150,11 +195,48 @@ const refreshEnvInfo = async () => {
150195
installed: false,
151196
version: 'Error',
152197
path: 'Error',
153-
language: 'python2'
198+
language: currentLanguage.value
154199
}
155200
}
156201
}
157202
203+
const getSupportedLanguages = async () => {
204+
try {
205+
const languages = await invoke<Language[]>('get_supported_languages')
206+
supportedLanguages.value = languages.map((language) => ({
207+
name: language.name,
208+
value: language.value
209+
}))
210+
211+
// 设置默认语言
212+
if (supportedLanguages.value.length > 0 && !currentLanguage.value) {
213+
currentLanguage.value = supportedLanguages.value[0].value
214+
}
215+
}
216+
catch (error) {
217+
console.error('Error getting supported languages:', error)
218+
supportedLanguages.value = []
219+
}
220+
}
221+
222+
const handleLanguageChange = async (newLanguage: string) => {
223+
currentLanguage.value = newLanguage
224+
225+
// 更新代码模板
226+
code.value = codeTemplates[newLanguage] || `# ${ getLanguageDisplayName(newLanguage) } Code
227+
# Write your code here...
228+
229+
print("Hello from ${ getLanguageDisplayName(newLanguage) }!")`
230+
231+
// 清空输出
232+
output.value = ''
233+
234+
// 刷新环境信息
235+
await refreshEnvInfo()
236+
237+
showToast(`已切换到 ${ getLanguageDisplayName(newLanguage) }`, 'info')
238+
}
239+
158240
const runCode = async () => {
159241
if (!envInfo.value.installed) {
160242
showToast(`${ envInfo.value.language } 环境未安装`, 'error')
@@ -168,7 +250,7 @@ const runCode = async () => {
168250
const result: ExecutionResult = await invoke('execute_code', {
169251
request: {
170252
code: code.value,
171-
language: 'python2'
253+
language: currentLanguage.value
172254
}
173255
})
174256
@@ -202,6 +284,17 @@ const clearOutput = () => {
202284
}
203285
204286
onMounted(async () => {
287+
await getSupportedLanguages()
288+
289+
// 设置初始代码模板
290+
if (supportedLanguages.value.length > 0) {
291+
currentLanguage.value = supportedLanguages.value[0].value
292+
code.value = codeTemplates[currentLanguage.value] || codeTemplates.python
293+
}
294+
else {
295+
code.value = codeTemplates.python
296+
}
297+
205298
await refreshEnvInfo()
206299
})
207300
</script>

src/components/AppHeader.vue

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
<template>
22
<div class="bg-white border-b border-gray-200 px-4 py-3 flex items-center justify-between">
33
<div class="flex items-center space-x-3">
4-
<div class="w-12 h-12 bg-gradient-to-br rounded-lg flex items-center justify-center">
5-
<img src="/codeforge.svg" alt="CodeForge">
6-
</div>
7-
<div>
8-
<h1 class="text-lg font-bold text-gray-800">CodeForge</h1>
9-
<p class="text-xs text-gray-500">轻量级、高性能的桌面代码执行器,专为开发者、学生和编程爱好者设计。</p>
4+
<div class="relative">
5+
<!-- 自定义下拉选择器 -->
6+
<div class="relative">
7+
<select v-model="selectedLanguage"
8+
class="w-32 h-10 backdrop-blur-sm appearance-none bg-white/90 text-gray-800 text-sm font-medium border border-gray-200 rounded-lg px-2.5 pr-8 cursor-pointer focus:outline-none hover:bg-white/95 transition-all duration-200"
9+
:class="{ 'opacity-50 cursor-not-allowed': isRunning }"
10+
:disabled="isRunning"
11+
@change="handleLanguageChange">
12+
<option v-for="language in supportedLanguages"
13+
class="text-gray-800 bg-white py-3 px-3 text-sm font-medium hover:bg-blue-50 hover:text-blue-800 focus:bg-blue-100 focus:text-blue-900 border-b border-gray-100 last:border-b-0"
14+
:key="language.value"
15+
:value="language.value">
16+
{{ language.name }}
17+
</option>
18+
</select>
19+
</div>
1020
</div>
1121
</div>
1222

@@ -33,16 +43,37 @@
3343
</template>
3444

3545
<script setup lang="ts">
46+
import { ref, watch } from 'vue'
3647
import { Play, Square, Trash2 } from 'lucide-vue-next'
3748
38-
defineProps<{
49+
interface Language
50+
{
51+
name: string
52+
value: string
53+
}
54+
55+
const props = defineProps<{
3956
isRunning: boolean
4057
envInstalled: boolean
58+
supportedLanguages: Language[]
59+
currentLanguage: string
4160
}>()
4261
43-
defineEmits<{
62+
const emit = defineEmits<{
4463
'run-code': []
4564
'clear-output': []
4665
'show-settings': []
66+
'language-change': [language: string]
4767
}>()
48-
</script>
68+
69+
const selectedLanguage = ref(props.currentLanguage)
70+
71+
// 监听外部语言变化
72+
watch(() => props.currentLanguage, (newLanguage) => {
73+
selectedLanguage.value = newLanguage
74+
})
75+
76+
const handleLanguageChange = () => {
77+
emit('language-change', selectedLanguage.value)
78+
}
79+
</script>

0 commit comments

Comments
 (0)