107 lines
No EOL
3.5 KiB
JavaScript
107 lines
No EOL
3.5 KiB
JavaScript
import { EditorState } from '@codemirror/state';
|
|
import { openSearchPanel, highlightSelectionMatches, searchKeymap } from '@codemirror/search';
|
|
import { openLintPanel, lintGutter, lintKeymap, linter, setDiagnostics, } from "@codemirror/lint"
|
|
import { indentWithTab, history, defaultKeymap, historyKeymap } from '@codemirror/commands';
|
|
import { foldGutter, indentOnInput, indentUnit, bracketMatching, foldKeymap, syntaxHighlighting, defaultHighlightStyle } from '@codemirror/language';
|
|
import { closeBrackets, autocompletion, closeBracketsKeymap, completionKeymap } from '@codemirror/autocomplete';
|
|
import { lineNumbers, highlightActiveLineGutter, highlightSpecialChars, drawSelection, dropCursor, rectangularSelection, crosshairCursor, highlightActiveLine, keymap, EditorView } from '@codemirror/view';
|
|
|
|
// Theme
|
|
import { oneDark } from "@codemirror/theme-one-dark";
|
|
import { LSPClient, LSPPlugin, languageServerSupport } from "@codemirror/lsp-client";
|
|
// Language
|
|
import { xml } from "@codemirror/lang-xml";
|
|
|
|
// 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(),
|
|
indentUnit.of(" "),
|
|
EditorState.allowMultipleSelections.of(true),
|
|
EditorView.lineWrapping,
|
|
indentOnInput(),
|
|
bracketMatching(),
|
|
closeBrackets(),
|
|
autocompletion(),
|
|
rectangularSelection(),
|
|
crosshairCursor(),
|
|
highlightActiveLine(),
|
|
highlightSelectionMatches(),
|
|
keymap.of([
|
|
indentWithTab,
|
|
...closeBracketsKeymap,
|
|
...defaultKeymap,
|
|
...historyKeymap,
|
|
...foldKeymap,
|
|
...completionKeymap,
|
|
...searchKeymap,
|
|
...lintKeymap
|
|
]),
|
|
xml(),
|
|
syntaxHighlighting(defaultHighlightStyle, { fallback: true })
|
|
];
|
|
|
|
function createEditorState(initialContents, extensions, options = {}) {
|
|
|
|
if (options.oneDark)
|
|
extensions.push(oneDark);
|
|
|
|
return EditorState.create({
|
|
doc: initialContents,
|
|
extensions
|
|
});
|
|
}
|
|
|
|
function createEditorView(state, parent) {
|
|
return new EditorView({ state, parent });
|
|
}
|
|
|
|
class xqLinter {
|
|
constructor(parameters) {
|
|
this.fred = parameters;
|
|
}
|
|
}
|
|
function debouncedChangeListener({ delay = 750, onChange }) {
|
|
let timeoutId = null;
|
|
let lastContent = '';
|
|
|
|
return EditorView.updateListener.of(update => {
|
|
if (update.docChanged) {
|
|
const currentContent = update.state.doc.toString();
|
|
|
|
if (timeoutId) {
|
|
clearTimeout(timeoutId);
|
|
}
|
|
|
|
timeoutId = setTimeout(() => {
|
|
if (currentContent !== lastContent) {
|
|
lastContent = currentContent;
|
|
onChange(currentContent, update.state);
|
|
}
|
|
}, delay);
|
|
}
|
|
});
|
|
}
|
|
|
|
export { createEditorState, createEditorView, openSearchPanel, openLintPanel, languageServerSupport, baseExts, simpleWebSocketTransport, linter, LSPPlugin, setDiagnostics, xqLinter, LSPClient,debouncedChangeListener }; |