mirror of
https://github.com/gnh1201/welsonjs.git
synced 2025-05-09 13:16:05 +00:00
Merge pull request #185 from gnh1201/dev
Add the code completion with Monaco Editor #183
This commit is contained in:
commit
5ab1c97b79
|
@ -114,12 +114,12 @@ namespace WelsonJS.Launcher
|
||||||
|
|
||||||
CompletionItem[] completionItems = executables
|
CompletionItem[] completionItems = executables
|
||||||
.Where(exec => exec.IndexOf(word, 0, StringComparison.OrdinalIgnoreCase) > -1)
|
.Where(exec => exec.IndexOf(word, 0, StringComparison.OrdinalIgnoreCase) > -1)
|
||||||
.Take(100) // Limit results to prevent excessive response sizes
|
.Take(100) // Limit the number of results
|
||||||
.Select(exec => new CompletionItem
|
.Select(exec => new CompletionItem
|
||||||
{
|
{
|
||||||
Label = Path.GetFileName(exec),
|
Label = Path.GetFileName(exec),
|
||||||
Kind = "Text",
|
Kind = "Text",
|
||||||
Documentation = "An executable file",
|
Documentation = $"An executable file: {exec}",
|
||||||
InsertText = exec
|
InsertText = exec
|
||||||
})
|
})
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>WelsonJS Code Editor</title>
|
<title>WelsonJS Code Editor</title>
|
||||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.52.2/min/vs/editor/editor.main.css" />
|
<link rel="stylesheet" href="https://cdn.metroui.org.ua/dev/metro.css">
|
||||||
<link rel="stylesheet" href="https://cdn.metroui.org.ua/current/metro.css">
|
<link rel="stylesheet" href="https://cdn.metroui.org.ua/dev/icons.css">
|
||||||
<link rel="stylesheet" href="https://cdn.metroui.org.ua/current/icons.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.52.2/min/vs/editor/editor.main.css">
|
||||||
<style>
|
<style>
|
||||||
html, body {
|
html, body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -14,17 +14,27 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#container {
|
#container {
|
||||||
border: 1px solid grey;
|
border: 1px solid grey;
|
||||||
height: calc(100% - 139px);
|
height: calc(100% - 139px);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#fileInput {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.banner {
|
.banner {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background-color: #f1f1f1;
|
background-color: #f1f1f1;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.overflowingOverlayWidgets {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -35,15 +45,15 @@
|
||||||
</ul>
|
</ul>
|
||||||
<div class="content-holder">
|
<div class="content-holder">
|
||||||
<div class="section" id="editor-tab">
|
<div class="section" id="editor-tab">
|
||||||
<button class="ribbon-button" onclick="openFile()">
|
<button id="btnOpenFile" class="ribbon-button">
|
||||||
<span class="icon mif-folder-open"></span>
|
<span class="icon mif-folder-open"></span>
|
||||||
<span class="caption">Open File</span>
|
<span class="caption">Open File</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="ribbon-button" onclick="saveFile()">
|
<button id="btnSaveFile" class="ribbon-button">
|
||||||
<span class="icon mif-floppy-disk"></span>
|
<span class="icon mif-floppy-disks"></span>
|
||||||
<span class="caption">Save File</span>
|
<span class="caption">Save File</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="ribbon-button" onclick="navigate('https://github.com/sponsors/gnh1201')">
|
<button id="btnSponsor" class="ribbon-button">
|
||||||
<span class="icon mif-heart"></span>
|
<span class="icon mif-heart"></span>
|
||||||
<span class="caption">Sponsor</span>
|
<span class="caption">Sponsor</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -52,17 +62,22 @@
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div id="container"></div>
|
<div id="container"></div>
|
||||||
<input type="file" id="fileInput" style="display: none" onchange="handleFileSelect(event)">
|
<input type="file" id="fileInput">
|
||||||
|
|
||||||
<div class="banner"><a href="https://github.com/gnh1201/welsonjs">WelsonJS</a> Code Editor powered by <a href="https://github.com/microsoft/monaco-editor">Microsoft Monaco Editor</a>.</div>
|
<div class="banner"><a href="https://github.com/gnh1201/welsonjs">WelsonJS</a> Code Editor powered by <a href="https://github.com/microsoft/monaco-editor">Microsoft Monaco Editor</a>.</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var require = { paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.52.2/min/vs' } };
|
var require = {
|
||||||
|
paths: {
|
||||||
|
vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.52.2/min/vs'
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/fast-xml-parser/4.5.1/fxparser.min.js"></script>
|
||||||
|
<script src="https://cdn.metroui.org.ua/dev/metro.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.52.2/min/vs/loader.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.52.2/min/vs/loader.min.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.52.2/min/vs/editor/editor.main.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.52.2/min/vs/editor/editor.main.js"></script>
|
||||||
<script src="https://cdn.metroui.org.ua/current/metro.js"></script>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var editor;
|
var editor;
|
||||||
var currentFileName = "sayhello.js";
|
var currentFileName = "sayhello.js";
|
||||||
|
@ -77,19 +92,63 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
require(["vs/editor/editor.main"], function() {
|
function getSuggestions(word, range) {
|
||||||
|
return axios.get("http://localhost:3000/completion/" + encodeURIComponent(word))
|
||||||
|
.then(function (response) {
|
||||||
|
var parser = new XMLParser();
|
||||||
|
var result = parser.parse(response.data);
|
||||||
|
|
||||||
|
if (!result.suggestions || !result.suggestions.item) {
|
||||||
|
return {
|
||||||
|
suggestions: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = Array.isArray(result.suggestions.item) ? result.suggestions.item : [result.suggestions.item];
|
||||||
|
var suggestions = items.map(function (item) {
|
||||||
|
return {
|
||||||
|
label: item.label,
|
||||||
|
kind: monaco.languages.CompletionItemKind.Text,
|
||||||
|
documentation: item.documentation || "",
|
||||||
|
insertText: '"' + item.insertText + '"',
|
||||||
|
range: range
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
suggestions: suggestions
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.catch(function () {
|
||||||
|
return {
|
||||||
|
suggestions: []
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
require(["vs/editor/editor.main"], function () {
|
||||||
editor = monaco.editor.create(document.getElementById('container'), {
|
editor = monaco.editor.create(document.getElementById('container'), {
|
||||||
value: ['// lib/sayhello.js', 'function say() {', ' console.log("hello");', '}', '', 'exports.say = say;', '', 'exports.VERSIONINFO = "SayHello (sayhello.js) version 0.1";', 'exports.AUTHOR = "abuse@catswords.net";', 'exports.global = global;', 'exports.require = global.require;'].join('\n'),
|
value: ['// lib/sayhello.js', 'function say() {', ' console.log("hello");', '}', '', 'exports.say = say;', '', 'exports.VERSIONINFO = "SayHello (sayhello.js) version 0.1";', 'exports.AUTHOR = "abuse@catswords.net";', 'exports.global = global;', 'exports.require = global.require;'].join('\n'),
|
||||||
language: 'javascript'
|
language: 'javascript'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
monaco.languages.registerCompletionItemProvider('javascript', {
|
||||||
|
provideCompletionItems: function (model, position) {
|
||||||
|
var word = model.getWordUntilPosition(position);
|
||||||
|
var range = {
|
||||||
|
startLineNumber: position.lineNumber,
|
||||||
|
endLineNumber: position.lineNumber,
|
||||||
|
startColumn: word.startColumn,
|
||||||
|
endColumn: word.endColumn
|
||||||
|
};
|
||||||
|
|
||||||
|
return getSuggestions(word.word, range);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('resize', resizeEditor);
|
window.addEventListener('resize', resizeEditor);
|
||||||
|
|
||||||
function openFile() {
|
|
||||||
document.getElementById('fileInput').click();
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFileLanguage(fileName) {
|
function getFileLanguage(fileName) {
|
||||||
var extension = fileName.split('.').pop().toLowerCase();
|
var extension = fileName.split('.').pop().toLowerCase();
|
||||||
var languageMap = {
|
var languageMap = {
|
||||||
|
@ -111,21 +170,33 @@
|
||||||
return languageMap[extension] || 'plaintext';
|
return languageMap[extension] || 'plaintext';
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleFileSelect(event) {
|
function navigate(href) {
|
||||||
|
var a = document.createElement("a");
|
||||||
|
a.href = href;
|
||||||
|
a.target = "_blank";
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById("fileInput").onchange = function (event) {
|
||||||
var file = event.target.files[0];
|
var file = event.target.files[0];
|
||||||
if (!file) return;
|
if (!file) return;
|
||||||
|
|
||||||
currentFileName = file.name;
|
currentFileName = file.name;
|
||||||
var reader = new FileReader();
|
var reader = new FileReader();
|
||||||
reader.onload = function(e) {
|
reader.onload = function (e) {
|
||||||
var language = getFileLanguage(file.name);
|
var language = getFileLanguage(file.name);
|
||||||
monaco.editor.setModelLanguage(editor.getModel(), language);
|
monaco.editor.setModelLanguage(editor.getModel(), language);
|
||||||
editor.setValue(e.target.result);
|
editor.setValue(e.target.result);
|
||||||
};
|
};
|
||||||
reader.readAsText(file);
|
reader.readAsText(file);
|
||||||
}
|
};
|
||||||
|
|
||||||
function saveFile() {
|
document.getElementById("btnOpenFile").onclick = function () {
|
||||||
|
document.getElementById('fileInput').click();
|
||||||
|
};
|
||||||
|
|
||||||
|
document.getElementById("btnSaveFile").onclick = function () {
|
||||||
var text = editor.getValue();
|
var text = editor.getValue();
|
||||||
var fileName = prompt("Enter file name:", currentFileName);
|
var fileName = prompt("Enter file name:", currentFileName);
|
||||||
if (!fileName) return;
|
if (!fileName) return;
|
||||||
|
@ -138,15 +209,11 @@
|
||||||
document.body.appendChild(a);
|
document.body.appendChild(a);
|
||||||
a.click();
|
a.click();
|
||||||
document.body.removeChild(a);
|
document.body.removeChild(a);
|
||||||
}
|
};
|
||||||
|
|
||||||
function navigate(href) {
|
document.getElementById("btnSponsor").onclick = function () {
|
||||||
var a = document.createElement("a");
|
navigate('https://github.com/sponsors/gnh1201');
|
||||||
a.href = href;
|
};
|
||||||
a.target = "_blank";
|
|
||||||
document.body.appendChild(a);
|
|
||||||
a.click();
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user