@dodona/papyros
Version:
Scratchpad for multiple programming languages in the browser.
204 lines (199 loc) • 8.41 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { customElement } from "lit/decorators.js";
import { CodeMirrorEditor } from "./CodeMirrorEditor";
import { drawSelection, EditorView, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, keymap, lineNumbers, rectangularSelection, } from "@codemirror/view";
import { defaultKeymap, history, historyKeymap, indentWithTab } from "@codemirror/commands";
import { bracketMatching, foldGutter, indentOnInput, indentUnit } from "@codemirror/language";
import { EditorState } from "@codemirror/state";
import { acceptCompletion, autocompletion, closeBrackets, closeBracketsKeymap, completionKeymap, } from "@codemirror/autocomplete";
import { highlightSelectionMatches, searchKeymap } from "@codemirror/search";
import { linter, lintGutter, lintKeymap } from "@codemirror/lint";
import { css } from "lit";
import { javascript } from "@codemirror/lang-javascript";
import { python } from "@codemirror/lang-python";
import { debugLineExtension, setDebugLines, setTestLines, testCodeWidgetExtension, testLineExtension, } from "./Extensions";
import readOnlyRangesExtension from "codemirror-readonly-ranges";
const tabCompletionKeyMap = [{ key: "Tab", run: acceptCompletion }];
const languageExtensions = {
JavaScript: javascript(),
Python: python(),
};
let CodeEditor = class CodeEditor extends CodeMirrorEditor {
static get styles() {
return css `
:host {
width: 100%;
height: 100%;
}
.papyros-test-line {
background-color: var(--md-sys-color-surface-variant);
}
.papyros-test-code-widget {
background-color: var(--md-sys-color-surface-variant);
color: var(--md-sys-color-on-surface-variant);
padding: 0 2px 0 6px;
position: relative;
}
.papyros-test-code-buttons {
position: absolute;
top: 0;
left: -50px;
z-index: 220;
width: 50px;
padding-left: 4px;
}
.papyros-icon-link {
font-size: 16px;
padding: 0 4px;
cursor: pointer;
}
.papyros-icon-link:hover {
color: var(--md-sys-color-primary);
}
`;
}
set debug(value) {
this.configure({
debugging: value ? debugLineExtension : [highlightActiveLineGutter(), lintGutter(), highlightActiveLine()],
});
this.readonly = value;
}
set debugLine(value) {
if (!this.view)
return;
const effects = [setDebugLines.of(value ? [value] : [])];
if (value && value >= 1 && value <= this.view.state.doc.lines) {
const line = this.view.state.doc.line(value);
effects.push(EditorView.scrollIntoView(line.from, { y: "center" }));
}
this.view.dispatch({ effects });
}
set testLines(value) {
var _a;
(_a = this.view) === null || _a === void 0 ? void 0 : _a.dispatch({
effects: setTestLines.of(value),
});
}
/**
* Override the value setter to temporarily disable read-only ranges
*/
dispatchChange() {
var _a;
const oldReadOnlyExtensions = (_a = this.extensions.get("testReadOnlyRanges")) !== null && _a !== void 0 ? _a : [];
this.configure({
testReadOnlyRanges: [],
});
super.dispatchChange();
this.configure({
testReadOnlyRanges: oldReadOnlyExtensions,
});
}
set testLineCount(value) {
this.configure({
testReadOnlyRanges: value
? readOnlyRangesExtension((state) => {
const line = state.doc.lines - value;
return [{ from: state.doc.line(line).from, to: state.doc.length }];
})
: [],
});
}
set testTranslations(value) {
this.configure({
test: [
testLineExtension,
testCodeWidgetExtension(value, () => {
this.dispatchEvent(new CustomEvent("edit-test-code"));
}, () => {
this.dispatchEvent(new CustomEvent("remove-test-code"));
}),
],
});
}
set programmingLanguage(value) {
if (!(value in languageExtensions)) {
console.warn(`Language ${value} not supported, defaulting to javascript`);
this.configure({
language: languageExtensions.JavaScript,
});
return;
}
this.configure({
language: languageExtensions[value],
});
}
set lintingSource(lintSource) {
this.configure({
linting: linter((view) => __awaiter(this, void 0, void 0, function* () {
const workerDiagnostics = yield lintSource();
if (workerDiagnostics.some((d) => d.lineNr > view.state.doc.lines || d.endLineNr > view.state.doc.lines)) {
// if the diagnostics are out of range, the document has changed since the linting was requested
// these diagnostics are no longer valid
return [];
}
return workerDiagnostics.map((d) => {
const fromline = view.state.doc.line(d.lineNr);
const toLine = view.state.doc.line(d.endLineNr);
const from = Math.min(fromline.from + d.columnNr, fromline.to);
const to = Math.min(toLine.from + d.endColumnNr, toLine.to);
return Object.assign(Object.assign({}, d), { from: from, to: to });
});
})),
});
}
set indentLength(length) {
this.configure({
indentUnit: indentUnit.of(" ".repeat(length)),
});
}
constructor() {
super();
this.configure({
language: [],
codingExtensions: [
lineNumbers(),
highlightSpecialChars(),
history(),
foldGutter(),
drawSelection(),
EditorState.allowMultipleSelections.of(true),
indentOnInput(),
bracketMatching(),
closeBrackets(),
autocompletion(),
rectangularSelection(),
highlightSelectionMatches(),
keymap.of([
...closeBracketsKeymap,
...defaultKeymap,
...searchKeymap,
...historyKeymap,
...completionKeymap,
...tabCompletionKeyMap,
...lintKeymap,
indentWithTab,
]),
],
debugging: [highlightActiveLineGutter(), lintGutter(), highlightActiveLine()],
});
}
};
CodeEditor = __decorate([
customElement("p-code-editor")
], CodeEditor);
export { CodeEditor };
//# sourceMappingURL=CodeEditor.js.map