basex-lsp/bundles/cm6/lsp.js
2025-10-05 16:18:40 +01:00

136 lines
No EOL
3.9 KiB
JavaScript

import { EditorState, StateEffect, Compartment } from '@codemirror/state';
import {
lineNumbers, highlightActiveLineGutter, highlightSpecialChars,
drawSelection, rectangularSelection, crosshairCursor, highlightActiveLine,
keymap, dropCursor, EditorView
} from '@codemirror/view';
import { openSearchPanel, highlightSelectionMatches, searchKeymap } from '@codemirror/search';
import { openLintPanel, lintGutter, lintKeymap, linter } from "@codemirror/lint"
import { indentWithTab, history, defaultKeymap, historyKeymap } from '@codemirror/commands';
import {
foldGutter, indentOnInput, indentUnit, bracketMatching, foldKeymap,
syntaxHighlighting, defaultHighlightStyle, StreamLanguage
} from '@codemirror/language';
import { closeBrackets, autocompletion, closeBracketsKeymap, completionKeymap } from '@codemirror/autocomplete';
import {
LSPClient, LSPPlugin, languageServerSupport, languageServerExtensions,
formatDocument, formatKeymap
} from "@codemirror/lsp-client";
import { xQuery } from "@codemirror/legacy-modes/mode/xquery"
// Language
import { xml } from "@codemirror/lang-xml";
import { showMinimap } from "@replit/codemirror-minimap"
let create = (v) => {
const dom = document.createElement('div');
return { dom }
}
const compartment = new Compartment();
let curOpts = {
lineWrap: true,
minimap: true
}
// array of extensions reflecting opts
function optExts(opts) {
let exts = []
if (opts.lineWrap) exts.push(EditorView.lineWrapping)
if (opts.minimap) exts.push(
showMinimap.compute(['doc'], (state) => {
return {
create,
/* optional showOverlay: 'mouse-over' */
displayText: 'characters'
}
}));
return exts
}
function updateCompartment(opts) {
view.dispatch({
effects: [compartment.reconfigure(optExts(opts))]
});
}
// return promise with socket map or reject if no connect
function simpleWebSocketTransport(uri) {
let handlers = [];
return new Promise(function (resolve, reject) {
let sock = new WebSocket(uri);
sock.onmessage = e => { for (let h of handlers) h(e.data.toString()); };
sock.onerror = e => reject(e);
sock.onopen = () => resolve({
socket: sock,
send: (message) => sock.send(message),
subscribe: (handler) => handlers.push(handler),
unsubscribe: (handler) => handlers = handlers.filter(h => h != handler)
});
}
);
};
const baseExts = [
lineNumbers(),
highlightActiveLineGutter(),
highlightSpecialChars(),
history(),
foldGutter(),
lintGutter(),
drawSelection(),
dropCursor(),
EditorState.allowMultipleSelections.of(true),
keymap.of([indentWithTab]),
indentOnInput(),
syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
bracketMatching(),
closeBrackets(),
autocompletion(),
rectangularSelection(),
crosshairCursor(),
highlightActiveLine(),
highlightSelectionMatches(),
keymap.of([
...closeBracketsKeymap,
...defaultKeymap,
...searchKeymap,
...historyKeymap,
...foldKeymap,
...completionKeymap,
...lintKeymap
]),
StreamLanguage.define(xQuery),
compartment.of(optExts(curOpts))
];
// map cmd->{keybings,fn}
function listCommands(view) {
const commands = new Map();
const keymaps = view.state.facet(keymap);
for (let km of keymaps) {
for (let binding of km) {
if (binding.run && binding.run.name) {
commands.set(binding.run.name, { key: binding.key, fn: binding.run });
}
}
}
return commands;
};
export {
baseExts, EditorView, EditorState, StateEffect, LSPPlugin, LSPClient,
openSearchPanel, openLintPanel, languageServerSupport, languageServerExtensions,
simpleWebSocketTransport, linter, formatDocument, keymap, formatKeymap, listCommands, updateCompartment, curOpts
};