Files
window-axis-innovators-box/javascript/CCodeEditor.html
tzdwindows 7 e475e84851 feat(box): 升级版本号并优化代码执行功能
-将版本号从 0.0.2 修改为 0.1.2
- 移除了异常时抛出的 RuntimeException
- 新增了 C 语言和 Java代码的执行功能
- 优化了 Python 代码的执行方式- 添加了代码编辑器的前端界面
- 新增了 QQ音乐文件解密工具的 UI 界面
- 添加了 C++ 解密库的框架
2025-05-24 09:36:48 +08:00

364 lines
13 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<title>C语言编辑器</title>
<style>
body {
margin: 0;
height: 100vh;
background: #2B2B2B;
font-family: 'JetBrains Mono', 'Consolas', monospace;
}
#editor {
width: 100vw;
height: 100vh;
}
.mtk5.keyword { color: #CC7832; font-weight: bold; }
.mtk5.function { color: #FFC66D; }
.mtk5.variable { color: #9876AA; }
.mtk5.comment { color: #808080; }
.mtk5.string { color: #6A8759; }
.mtk5.number { color: #6897BB; }
.doxygen-tag { color: #CC7832; }
.doxygen-param { color: #9876AA; }
.monaco-editor.vs-dark .monaco-editor-background { background: #2B2B2B !important; }
.monaco-editor .margin { background: #313335 !important; }
#container {
display: flex;
flex-direction: column;
height: 100vh;
}
#toolbar {
background: #1E1E1E;
padding: 8px;
border-bottom: 1px solid #333;
}
#executeBtn {
background: #3276B1;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
font-family: 'JetBrains Mono';
}
#console {
height: 200px;
background: #1E1E1E;
border-top: 1px solid #333;
padding: 10px;
overflow-y: auto;
}
#output {
color: #B5B5B5;
margin: 0;
font-family: 'JetBrains Mono';
font-size: 14px;
white-space: pre-wrap;
}
</style>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono&display=swap" rel="stylesheet">
</head>
<body>
<div id="container">
<div id="toolbar">
<button id="executeBtn">▶ 执行</button>
</div>
<div id="editor"></div>
<div id="console">
<pre id="output"></pre>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.49.0/min/vs/loader.min.js"></script>
<script>
require.config({
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.49.0/min/vs' },
'vs/nls': {
availableLanguages: { '*': 'zh-cn' }
}
});
require(['vs/editor/editor.main'], function() {
// 输出内容到控制台
function appendOutput(text, isError = false) {
const output = document.getElementById('output');
const div = document.createElement('div');
div.style.color = isError ? '#FF6666' : '#B5B5B5';
div.textContent = text;
output.appendChild(div);
output.scrollTop = output.scrollHeight;
}
// 清空控制台
function clearOutput() {
document.getElementById('output').innerHTML = '';
}
document.getElementById('executeBtn').addEventListener('click', () => {
const code = editor.getValue();
// 发送执行请求到Java后端
window.cefQuery({
request: JSON.stringify({
type: "executeCode",
code: code,
language: "c"
}),
onSuccess: (response) => {
const result = JSON.parse(response);
appendOutput(result.output);
},
onFailure: (errorCode, errorMsg) => {
appendOutput(`执行错误 (${errorCode}): ${errorMsg}`, true);
}
});
});
monaco.languages.register({ id: 'c' });
// C语言关键字配置
const cKeywords = [
'auto', 'break', 'case', 'char', 'const', 'continue',
'default', 'do', 'double', 'else', 'enum', 'extern',
'float', 'for', 'goto', 'if', 'inline', 'int', 'long',
'register', 'return', 'short', 'signed', 'sizeof', 'static',
'struct', 'switch', 'typedef', 'union', 'unsigned', 'void',
'volatile', 'while', '_Alignas', '_Alignof', '_Atomic',
'_Bool', '_Complex', '_Generic', '_Imaginary', '_Noreturn',
'_Static_assert', '_Thread_local',"#include","#define"
];
// 语法高亮配置
monaco.languages.setMonarchTokensProvider('c', {
keywords: cKeywords,
tokenizer: {
root: [
[/for\s*\(/, {
cases: {
'@keywords': 'keyword',
'@default': 'keyword'
}
}],
[/if\s*\(/, 'keyword'],
[/\/\*\*/, 'comment.doxygen', '@doxygen'],
[/\/\*/, 'comment', '@comment'],
[/[a-zA-Z_]\w*(?=\s*\()/, 'function'],
[/[a-zA-Z_]\w*/, {
cases: {
'@keywords': 'keyword',
'@default': 'variable'
}
}],
{ include: '@whitespace' },
[/[{}()\[\]]/, '@brackets'],
[/[0-9]+/, 'number'],
[/"/, 'string', '@string'],
[/\/\/.*$/, 'comment'],
],
doxygen: [
[/\*\//, 'comment.doxygen', '@pop'],
[/@\w+/, 'doxygen-tag'],
[/\\[\w]+/, 'doxygen-param'],
[/[\s\S]/, 'comment.doxygen']
],
comment: [
[/\*\//, 'comment', '@pop'],
[/[\s\S]/, 'comment']
],
string: [
[/[^\\"]+/, 'string'],
[/\\["\\nrt]/, 'string.escape'],
[/"/, 'string', '@pop']
],
whitespace: [
[/[ \t\r\n]+/, 'white'],
],
}
});
// 定义跳转功能
monaco.languages.registerDefinitionProvider('c', {
provideDefinition: (model, position) => {
const word = model.getWordAtPosition(position);
if (!word) return [];
const funcMatches = model.findMatches(
`\\b(\\w+)\\s+${word.word}\\s*\\([^)]*\\)\\s*[;{]`,
true, true, false, null, true
);
const varMatches = model.findMatches(
`\\b(int|float|double|char|void|short|long|unsigned)\\s+${word.word}\\b`,
true, true, false, null, true
);
return [...funcMatches, ...varMatches].map(match => ({
uri: model.uri,
range: match.range
}));
}
});
// 自动补全配置
const systemFunctions = [
{
label: 'printf',
kind: monaco.languages.CompletionItemKind.Function,
insertText: 'printf("${1:format}", ${2:args});',
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
documentation: {
value: '**格式化输出函数**\n\n参数:\n- `format`: 格式字符串 (例: "%d")\n- `...`: 可变参数列表'
}
},
{
label: 'main',
kind: monaco.languages.CompletionItemKind.Function,
insertText: 'int main(int ${1:argc}, char* ${2:argv[]}){\n ${3://is code}\n}',
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
documentation: {
value: '**主函数**'
}
},
{
label: 'scanf',
kind: monaco.languages.CompletionItemKind.Function,
insertText: 'scanf("${1:format}", ${2:&var});',
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
documentation: {
value: '**格式化输入函数**\n\n参数:\n- `format`: 格式字符串\n- `...`: 变量地址列表'
}
}
];
const codeSnippets = [
{
label: 'if',
kind: monaco.languages.CompletionItemKind.Snippet,
insertText: 'if (${1:condition}) {\n\t${2:// code}\n}',
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
documentation: 'if条件语句'
},
{
label: 'for',
kind: monaco.languages.CompletionItemKind.Snippet,
insertText: 'for (int ${1:i} = 0; ${1:i} < ${2:count}; ${1:i}++) {\n\t${3:// code}\n}',
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
documentation: 'for循环语句'
},
{
label: 'while',
kind: monaco.languages.CompletionItemKind.Snippet,
insertText: 'while (${1:condition}) {\n\t${2:// code}\n}',
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
documentation: 'while循环语句'
},
{
label: 'switch',
kind: monaco.languages.CompletionItemKind.Snippet,
insertText: 'switch (${1:expression}) {\n\tcase ${2:value}:\n\t\t${3:// code}\n\t\tbreak;\n\tdefault:\n\t\t${4:// code}\n}',
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
documentation: 'switch语句'
}
];
monaco.languages.registerCompletionItemProvider('c', {
triggerCharacters: ['.', ':', '$', '/', '@', '*'],
provideCompletionItems: (model, position) => {
const word = model.getWordUntilPosition(position);
const range = new monaco.Range(
position.lineNumber,
word.startColumn,
position.lineNumber,
word.endColumn
);
return {
suggestions: [
...cKeywords.map(keyword => ({
label: keyword,
kind: monaco.languages.CompletionItemKind.Keyword,
insertText: keyword,
range: range
})),
...codeSnippets.map(snippet => ({
...snippet,
range: range
})),
...systemFunctions.map(func => ({
...func,
range: range
})),
...getCurrentVariables(model).map(v => ({
label: v.name,
kind: monaco.languages.CompletionItemKind.Variable,
detail: `类型: ${v.type}`,
insertText: v.name,
range: range
})),
...getCurrentFunctions(model).map(f => ({
label: f,
kind: monaco.languages.CompletionItemKind.Function,
detail: '用户定义函数',
insertText: f,
range: range
}))
]
};
}
});
// 创建编辑器实例
const editor = monaco.editor.create(document.getElementById('editor'), {
value: `#include <stdio.h>\n\nint main() {\n printf("Hello World\\n");\n return 0;\n}`,
language: 'c',
theme: 'vs-dark',
minimap: { enabled: true },
fontSize: 16,
lineNumbers: 'on',
roundedSelection: false,
scrollBeyondLastLine: false,
automaticLayout: true,
tabSize: 4,
suggest: {
showKeywords: true,
showSnippets: true
},
glyphMargin: true,
lightbulb: { enabled: true }
});
// 辅助函数
function getCurrentVariables(model) {
const varRegex = /\b(int|float|double|char|void|short|long|unsigned)\s+([a-zA-Z_][\w,\s*]*)/g;
const variables = [];
let match;
while ((match = varRegex.exec(model.getValue()))) {
const type = match[1];
const names = match[2].split(',').map(s => s.trim());
names.forEach(name => {
variables.push({
name: name.replace(/\*+/g, '').trim(),
type: type
});
});
}
return variables;
}
function getCurrentFunctions(model) {
const funcRegex = /(\w+)\s*\([^)]*\)\s*\{/g;
return Array.from(model.getValue().matchAll(funcRegex))
.map(m => m[1])
.filter(f => !['if','while','for','switch'].includes(f));
}
window.addEventListener('resize', () => editor.layout());
});
</script>
</body>
</html>