basex-lsp/webapp/static/clients/codemirror/script.js
2025-08-22 15:50:39 +01:00

146 lines
4.5 KiB
JavaScript

const view = lsp.createEditorView(undefined, document.getElementById("editor"));
let doc = `3+1`;
var client;
var extLint;
function $(id) { return document.getElementById(id) };
// Load saved content from localStorage when the page loads
window.addEventListener('load', () => {
const savedText = localStorage.getItem('code');
if (savedText) {
doc = savedText;
}
view.setState(lsp.createEditorState(doc, lsp.baseExts));
connect();
});
// Save content to localStorage when the page is about to unload
window.addEventListener('beforeunload', () => {
const doc = view.state.doc.toString();
localStorage.setItem('code', doc);
});
document.getElementById("connect").onclick = e => {
e.preventDefault()
connect()
};
document.getElementById("search").onclick = e => {
lsp.openSearchPanel(view);
};
document.getElementById("lint").onclick = async e => {
console.log("word", view.state.wordAt(1));
const ser = document.getElementById("iServer").value;
//const transport = new WebTransport(ser);
// The connection can be used once ready fulfills
//await transport.ready;
lsp.openLintPanel(view);
};
document.getElementById("sync").onclick = e => {
client.sync();
console.log("XXXsync");
};
document.getElementById("load").onchange = e => {
const url = e.target.value;
if (url.length == 0) return
fetch(url)
.then(response => response.text())
.then(t => {
view.dispatch({
changes: {
from: 0,
to: view.state.doc.length,
insert: t
}
})
client.sync();
console.log("SYNC");
});
document.getElementById("load").value = "";
};
function connect() {
const server = document.getElementById("iServer").value;
const file = document.getElementById("iFile").value;
lsp.simpleWebSocketTransport(server)
.then(transport => {
transport.subscribe(incoming);
transport.socket.onclose = (event) => connectStatus(false);
transport.socket.oneror = (event) => $("msg").innerText = "sock error!";
client = new lsp.LSPClient().connect(transport);
$("mypopover").hidePopover();
connectStatus(true);
let extLsp = lsp.languageServerSupport(client, file, "xquery");
extLint = lsp.linter(
view => { client.sync(); return []; },
{ autoPanel: true });
const doc = view.state.doc.toString();
const state = lsp.createEditorState(doc, [...lsp.baseExts, extLsp, extLint]);
view.setState(state);
})
.catch(r => { connectStatus(false); alert("connection failed: " + server) });
};
function connectStatus(bool) {
if (bool) {
$("popcon").classList.remove("btn-danger")
$("popcon").classList.add("btn-success")
} else {
$("popcon").classList.add("btn-danger")
$("popcon").classList.remove("btn-success")
}
};
function incoming(msg) {
const rpc = JSON.parse(msg);
log(rpc);
switch (rpc.method) {
case "textDocument/publishDiagnostics":
diags(rpc.params);
break;
default:
return;
}
};
function log(rpc) {
if (rpc.id) return
const text = rpc.method;
const li = document.createElement("li");
li.appendChild(document.createTextNode(text));
$("traffic").insertBefore(li, $("traffic").firstChild)
};
function diags(params) {
console.log("--", params)
let plugin = lsp.LSPPlugin.get(view);
const severities = ["error", "warning", "info", "hint"]
//
const diagnostics = params.diagnostics
.map(({ range, message, severity, code }) => ({
from: plugin.fromPosition(range.start, view.state.doc),
to: plugin.fromPosition(range.end, view.state.doc),
severity: severities[severity - 1],
message: ((typeof code === 'undefined') ? "" : `[${code}] `) + message,
}))
.filter(
({ from, to }) =>
from !== null &&
to !== null &&
from !== undefined &&
to !== undefined,
)
.sort((a, b) => {
switch (true) {
case a.from < b.from:
return -1;
case a.from > b.from:
return 1;
}
return 0;
});
view.dispatch(lsp.setDiagnostics(view.state, diagnostics));
};