239 lines
No EOL
7 KiB
JavaScript
239 lines
No EOL
7 KiB
JavaScript
const view = new lsp.EditorView({
|
|
extensions: lsp.baseExts,
|
|
parent: document.getElementById("editor")
|
|
});
|
|
let doc = "xquery version '3.1';\n(:~ comment:)\nmodule namespace pdfbox='ns';\n";
|
|
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;
|
|
let svr = localStorage.getItem('lsp');
|
|
if (!svr) {
|
|
let x = new URL(window.location.href);
|
|
x.protocol = "ws";
|
|
x.pathname = "ws/lsp"
|
|
svr = x.href;
|
|
}
|
|
$("iServer").value = svr;
|
|
formFromStore('fSettings');
|
|
view.setState(lsp.EditorState.create({ doc: doc, extensions: lsp.baseExts }));
|
|
lsp.updateCompartment(objectFromForm('fSettings'))
|
|
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);
|
|
localStorage.setItem('lsp', $("iServer").value);
|
|
});
|
|
|
|
$("connect").onclick = e => { e.preventDefault(); connect() };
|
|
|
|
$("search").onclick = e => lsp.openSearchPanel(view);
|
|
|
|
$("fullscreen").onclick = e => $("editor").requestFullscreen();
|
|
|
|
|
|
$("wordAt").onclick = e => {
|
|
let pos = view.state.selection.main.head;
|
|
let w = view.state.wordAt(pos);
|
|
alert("wordAt " + JSON.stringify(w));
|
|
};
|
|
|
|
$("symbols2").onclick = e => {
|
|
client.sync();
|
|
client.request("textDocument/documentSymbol", { "textDocument": { "uri": $("iFile").value } })
|
|
.then(r => {
|
|
console.log("symbols", r)
|
|
$("symPanel").open = true;
|
|
const icons = [
|
|
'symbol-file',
|
|
'symbol-class',
|
|
'symbol-namespace',
|
|
'symbol-structure',
|
|
'symbol-class',
|
|
'symbol-method',
|
|
'symbol-property',
|
|
'symbol-field',
|
|
'symbol-method-arrow',
|
|
'symbol-enum',
|
|
'symbol-interface',
|
|
'symbol-method',
|
|
'symbol-variable',
|
|
'symbol-constant',
|
|
'symbol-string',
|
|
'symbol-numeric',
|
|
'symbol-boolean',
|
|
'symbol-array',
|
|
'symbol-structure',
|
|
'symbol-key',
|
|
'dash',
|
|
'symbol-enum-member',
|
|
'symbol-misc',
|
|
'symbol-event',
|
|
'symbol-operator',
|
|
'symbol-parameter'
|
|
];
|
|
$("symList").setData(r, icons);
|
|
});
|
|
};
|
|
|
|
$("cmdList").onclick = e => {
|
|
let cmds = lsp.listCommands(view);
|
|
let result="";
|
|
[...cmds.keys()].sort().forEach(key => {
|
|
result+=`<li>${key} ${cmds.get(key).key}</li>`
|
|
});
|
|
$("popHelpInfo").innerHTML=`<ul>${result}</ul>`
|
|
$("popCmds").showPopover()
|
|
|
|
};
|
|
|
|
$("symList").addEventListener("itemSelected", e => {
|
|
const sel=e.detail.selectionRange;
|
|
console.log("SYM selection range",sel);
|
|
const an=17*e.detail.kind
|
|
view.dispatch({selection: {anchor: an,head:an+34},scrollIntoView:true});
|
|
});
|
|
|
|
$("lint").onclick = async e => {
|
|
console.log("word", view.state.wordAt(1));
|
|
lsp.openLintPanel(view);
|
|
};
|
|
|
|
$("sync").onclick = e => { client.sync(); console.log("XXXsync"); };
|
|
|
|
$("format").onclick = e => {
|
|
console.log("FMT", lsp.formatDocument(view));
|
|
};
|
|
|
|
$("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");
|
|
});
|
|
$("load").value = "";
|
|
};
|
|
|
|
function updateSettings(event) {
|
|
event.preventDefault();
|
|
|
|
console.log("COPTS", lsp.curOpts);
|
|
const opts = {
|
|
lineWrap: $("lineWrap").checked,
|
|
minimap: $("minimap").checked
|
|
}
|
|
console.log(opts)
|
|
lsp.updateCompartment(opts);
|
|
$('popSettings').hidePopover();
|
|
formToStore("fSettings");
|
|
};
|
|
|
|
$("fSettings").addEventListener("submit", updateSettings);
|
|
|
|
function connect() {
|
|
const server = $("iServer").value;
|
|
const file = $("iFile").value;
|
|
lsp.simpleWebSocketTransport(server)
|
|
.then(transport => {
|
|
transport.socket.onclose = (event) => connectStatus(false);
|
|
transport.socket.oneror = (event) => $("msg").innerText = "sock error!";
|
|
transport.subscribe(incoming);
|
|
client = new lsp.LSPClient({ extensions: lsp.languageServerExtensions() });
|
|
client.connect(transport);
|
|
$("popConnect").hidePopover();
|
|
connectStatus(true);
|
|
let extLsp = client.plugin(file, "xquery");
|
|
|
|
view.dispatch({
|
|
effects: lsp.StateEffect.appendConfig.of(
|
|
[lsp.linter(null, { autoPanel: true }), ...extLsp,
|
|
lsp.keymap.of([...lsp.formatKeymap])])
|
|
})
|
|
})
|
|
.catch(e => {
|
|
console.log(e);
|
|
connectStatus(false);
|
|
alert("connection failed: " + server)
|
|
});
|
|
|
|
};
|
|
|
|
function connectStatus(bool) {
|
|
if (bool) {
|
|
$("popcon").querySelector("i").classList.value = "codicon codicon-vm-active";
|
|
$("popcon").classList.remove("btn-danger")
|
|
$("popcon").classList.add("btn-success")
|
|
} else {
|
|
$("popcon").querySelector("i").classList.value = "codicon codicon-vm-outline";
|
|
$("popcon").classList.add("btn-danger")
|
|
$("popcon").classList.remove("btn-success")
|
|
}
|
|
};
|
|
|
|
function incoming(msg) {
|
|
const rpc = JSON.parse(msg);
|
|
log(rpc);
|
|
};
|
|
|
|
|
|
function log(rpc) {
|
|
console.log("<-", rpc)
|
|
if (rpc.id) return
|
|
const text = rpc.method;
|
|
const li = document.createElement("li");
|
|
const n = $("traffic").childElementCount + " ";
|
|
li.appendChild(document.createTextNode(n + text));
|
|
$("traffic").insertBefore(li, $("traffic").firstChild)
|
|
};
|
|
|
|
function formFromStore(name) {
|
|
let v = localStorage.getItem(name)
|
|
if (!!v) formDeserialize($(name), v);
|
|
};
|
|
|
|
function formToStore(name) {
|
|
localStorage.setItem(name, formSerialize($(name)));
|
|
};
|
|
|
|
function objectFromForm(name) {
|
|
const data = new FormData($(name));
|
|
//https://stackabuse.com/convert-form-data-to-javascript-object/
|
|
return Object.fromEntries(data.entries());
|
|
}
|
|
function formSerialize(form) {
|
|
const data = new FormData(form);
|
|
//https://stackoverflow.com/a/44033425/1869660
|
|
return new URLSearchParams(data).toString();
|
|
}
|
|
|
|
function formDeserialize(form, data) {
|
|
const entries = (new URLSearchParams(data)).entries();
|
|
for (const [key, val] of entries) {
|
|
//http://javascript-coder.com/javascript-form/javascript-form-value.phtml
|
|
const input = form.elements[key];
|
|
switch (input.type) {
|
|
case 'checkbox': input.checked = !!val; break;
|
|
default: input.value = val; break;
|
|
}
|
|
}
|
|
} |