[mod] additions

This commit is contained in:
Andy Bunce 2025-07-31 15:02:27 +01:00
parent c59edb71a2
commit 2f54b3370e
19 changed files with 40083 additions and 16 deletions

View file

@ -3,14 +3,17 @@
: @author andy bunce
:)
module namespace lsprpc = 'lsprpc';
import module namespace lsp-text = 'lsp-text' at "lsp-text.xqm";
declare variable $lsprpc:methods:=map{
(: map methods to functions :)
declare variable $lsprpc:methods:=map:merge((
map{
"initialize" : lsprpc:method-initialize#1,
"initialized" : lsprpc:method-unknown#1,
"workspace/didChangeConfiguration" :lsprpc:method-unknown#1,
"textDocument/didOpen": lsprpc:method-unknown#1,
"textDocument/didClose" : lsprpc:method-unknown#1
};
"workspace/didChangeConfiguration" :lsprpc:method-unknown#1
},
$lsp-text:methods
));
(:~ return map if $msg is jsonrpc else empty :)
declare
@ -41,11 +44,28 @@ as empty-sequence() {
(:~ canned initialize response :)
declare
function lsprpc:method-initialize($json as map(*))
as map(*)?
as map(*)
{
``[{"jsonrpc":"2.0","id":0,
"result":{"capabilities":{"textDocumentSync":2,"completionProvider":{"resolveProvider":false,"triggerCharacters":["\"",":"]},"hoverProvider":true,"documentSymbolProvider":true,"documentRangeFormattingProvider":false,"colorProvider":{},"foldingRangeProvider":true,"selectionRangeProvider":true,"documentLinkProvider":{}}}}]``
=>parse-json()
{
"jsonrpc": "2.0",
"id": $json?id,
"result": {
"capabilities": {
"textDocumentSync": 2,
"completionProvider": {
"resolveProvider": false(),
"triggerCharacters": [ """", ":" ]
},
"hoverProvider": true(),
"documentSymbolProvider": true(),
"documentRangeFormattingProvider": false(),
"colorProvider": {},
"foldingRangeProvider": true(),
"selectionRangeProvider": true(),
"documentLinkProvider": {}
}
}
}
};
(:~ unknown method response :)

71
webapp/lsp/lsp-text.xqm Normal file
View file

@ -0,0 +1,71 @@
(:~ handle text messages
: @author andy bunce
:)
module namespace lsp-text = 'lsp-text';
import module namespace p="xq4" at "xq4.xqm";
declare variable $lsp-text:methods:=map{
"textDocument/didOpen": lsp-text:didOpen#1,
"textDocument/didClose" : lsp-text:method-unknown#1,
"textDocument/didChange": lsp-text:method-unknown#1,
"textDocument/hover": lsp-text:hover#1,
"textDocument/completion": lsp-text:completion#1
};
(:~ hover
{
"jsonrpc": "2.0",
"id": 2,
"method": "textDocument/hover",
"params": {
"textDocument": {
"uri": "file:///session1.json"
},
"position": {
"line": 2,
"character": 22
}
}
}
:)
declare
function lsp-text:hover($json as map(*))
as map(*)?
{
let $doc:=$json?params?textDocument?uri
return map{
"jsonrpc": "2.0",
"id": $json?id,
"value":"uri: " || $doc
}
};
declare
function lsp-text:completion($json as map(*))
as map(*)?
{
let $doc:=$json?params?textDocument?uri
return map{
"jsonrpc": "2.0",
"id": $json?id,
"result":()
}
};
(:~ didOpen method response :)
declare
function lsp-text:didOpen($json as map(*))
as map(*)?
{
let $textDoc:=$json?params?textDocument
let $text:=$textDoc?text=>trace("TXT")
return ()
};
(:~ unknown method response :)
declare
function lsp-text:method-unknown($json as map(*))
as map(*)?
{
let $_:=trace($json?method,"unknown")
return ()
};

View file

@ -19,9 +19,13 @@ function lsp-ws:error($error) {
declare
%ws:connect('/lsp')
function lsp-ws:connect() as empty-sequence() {
ws:set(ws:id()=>trace("CONNECT: "), $chat-util:id, "session:get($chat-util:id)")
(: ,chat-util:users() :)
let $id:=ws:id()=>trace("CONNECT: ")
return (
ws:set($id, "id", $id),
store:clear(),
store:put("id",$id),
store:write("lsp-store")
)
};
(:~

6570
webapp/lsp/xq4.xqm Normal file

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -0,0 +1,80 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Codemirror6 example using BaseX LSP</title>
<link rel="icon" type="image/png" href="favicon.png" />
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header>BaseX LSP client <button id="search">🔍</button>
<label for="symbols">Symbols:</label><select id="symbols" disabled="disabled"></select>
<div style="float:right">
<input id="iServer" type="text" value="ws://localhost:3000/ws/lsp" /><button id="connect">connect</button>
</div>
</header>
<div class="container">
<div class="item">stuff</div>
<!-- Editor goes in here -->
<div id="editor" class="item"></div>
</div>
<!-- CodeMirror 6 -->
<script src="./lsp.bundle.js"></script>
<script>
const server = "ws://localhost:3000/ws/lsp";
let doc = `/**
*
* @param {string[]} items
* @param nada
*/
function foo(items, nada) {
for (var i=0; i<items.length; i++) {
alert(items[i] + 'juhu');
} // Real Tab.
//
//
}`;
// Load saved content from localStorage when the page loads
window.addEventListener('load', () => {
const savedText = localStorage.getItem('code');
if (savedText) {
doc = savedText;
}
});
const view = lsp.createEditorView(undefined, document.getElementById("editor"));
view.setState(lsp.createEditorState(doc, lsp.baseExts));
// 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 => {
const v = document.getElementById("iServer").value;
alert(v)
};
document.getElementById("search").onclick = e => {
lsp.openSearchPanel(view);
};
lsp.simpleWebSocketTransport(server)
.then(transport => {
let link = lsp.lsp(transport, "file:///some/file.xml");
const state = lsp.createEditorState(doc, [...lsp.baseExts, link]);
view.setState(state);
})
.catch(r => alert("fail"));
</script>
</body>
</html>

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,27 @@
/* Set editor dimensions */
#editor {
height: 400px;
width: 50%;
}
/* Stretch editor to fit inside its containing div */
.cm-editor {
height: 100%;
width: 100%;
}
/* header */
header {
background-color: burlywood;
}
.container {
display: flex;
}
.item {
flex-grow: 1;
height: 100px;
}
.item + .item {
margin-left: 2%;
}