@gdquest/gd-exercise
Version:
Core package that handles logic for the GDExercise project.
272 lines (270 loc) • 8.42 kB
JavaScript
import "./chunk-MJPHVYKR.mjs";
// ../codemirror-freeze/dist/index.mjs
import { Facet } from "@codemirror/state";
import { EditorView } from "@codemirror/view";
import {
EditorSelection as EditorSelection2,
EditorState
} from "@codemirror/state";
import { syntaxTree } from "@codemirror/language";
import {
EditorSelection
} from "@codemirror/state";
import { RangeSetBuilder } from "@codemirror/state";
import {
Decoration,
ViewPlugin
} from "@codemirror/view";
var startFreezeComment = Facet.define({
combine: (values) => {
if (values.length > 0) {
return values[values.length - 1];
}
return "start-freeze";
}
});
var endFreezeComment = Facet.define({
combine: (values) => {
if (values.length > 0) {
return values[values.length - 1];
}
return "end-freeze";
}
});
var freezeTheme = EditorView.theme({
".cm-frozen": {
opacity: 0.75,
fontStyle: "italic"
}
});
function getFreezeRanges(state, startFreezeComment2, endFreezeComment2) {
const tree = syntaxTree(state);
const cursor = tree.cursor();
const commentTokens = state.languageDataAt("commentTokens", 0);
const freezeRanges = [];
let currentRangeFrom = 0;
do {
if (cursor.name !== "Comment") {
continue;
}
let fromOffset = 0;
let toOffset = 0;
const text = state.sliceDoc(cursor.from, cursor.to);
let comment = "";
for (const commentToken of commentTokens) {
if (commentToken.line != null) {
if (!text.startsWith(commentToken.line)) {
continue;
}
fromOffset = commentToken.line.length;
} else if (commentToken.block != null) {
if (!(text.startsWith(commentToken.block.open) && text.endsWith(commentToken.block.close))) {
continue;
}
fromOffset = commentToken.block.open.length;
toOffset = -commentToken.block.close.length;
}
}
comment = text.slice(fromOffset, text.length + toOffset).trim();
if (comment === startFreezeComment2) {
currentRangeFrom = cursor.from;
} else if (comment === endFreezeComment2) {
freezeRanges.push(EditorSelection.range(currentRangeFrom, cursor.to));
currentRangeFrom = 0;
}
} while (cursor.next());
if (currentRangeFrom > 0) {
freezeRanges.push(
EditorSelection.range(currentRangeFrom, state.doc.toString().length)
);
}
return freezeRanges;
}
function createSetRangeFromSelectionRange(range) {
const setRange = /* @__PURE__ */ new Set();
for (let i = range.from; i <= range.to; i++) {
setRange.add(i);
}
return setRange;
}
function removeFromSetRange(rangeToRemove, setRange) {
const numbersToRemove = Array.from(
createSetRangeFromSelectionRange(rangeToRemove)
);
for (const numberToRemove of numbersToRemove) {
setRange.delete(numberToRemove);
}
}
function createSelectionRangesFromSetRange(range) {
const elements = Array.from(range).sort((a, b) => a - b);
const min = elements.reduce((previousValue, currentValue, currentIndex) => {
if (currentIndex === 0) {
return currentValue;
}
return Math.min(previousValue, currentValue);
}, 0);
const max = elements.reduce((previousValue, currentValue, currentIndex) => {
if (currentIndex === 0) {
return currentValue;
}
return Math.max(previousValue, currentValue);
}, 0);
const selectionRanges = [];
let selectionRange = null;
for (let i = min; i < max; i++) {
const element = elements.find((element2) => element2 === i);
if (element == null && selectionRange != null) {
selectionRanges.push(selectionRange);
selectionRange = null;
continue;
}
if (selectionRange == null) {
selectionRange = EditorSelection.range(i, i);
} else {
selectionRange = EditorSelection.range(selectionRange.from, i);
}
}
if (selectionRange != null) {
selectionRanges.push(selectionRange);
selectionRange = null;
}
return selectionRanges;
}
function getFreezeTransactionFilter() {
return EditorState.transactionFilter.of((transaction) => {
if (!(transaction.selection != null || transaction.docChanged)) {
return transaction;
}
const freezeRanges = getFreezeRanges(
transaction.startState,
transaction.startState.facet(startFreezeComment),
transaction.startState.facet(endFreezeComment)
);
let ignoreChanges = false;
if (transaction.docChanged) {
transaction.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
const diff = Math.max(toA - fromA, toB - fromB);
for (let i = 0; i < freezeRanges.length; i++) {
let range = freezeRanges[i];
if (diff > 0) {
if (fromB < range.from) {
range = EditorSelection2.range(range.from + diff, range.to + diff);
freezeRanges[i] = range;
}
}
}
});
for (const freezeRange of freezeRanges) {
const touchesRange = transaction.changes.desc.touchesRange(
freezeRange.from,
freezeRange.to
);
switch (touchesRange) {
case "cover":
case true:
ignoreChanges = true;
break;
case false:
default:
}
if (ignoreChanges) {
break;
}
}
}
let ranges = [];
if (transaction.selection != null) {
let selection = transaction.newSelection;
if (ignoreChanges) {
selection = transaction.startState.selection;
}
for (const selectionRange of selection.ranges) {
const selectionRangeSet = createSetRangeFromSelectionRange(selectionRange);
for (const freezeRange of freezeRanges) {
removeFromSetRange(freezeRange, selectionRangeSet);
}
ranges.push(...createSelectionRangesFromSetRange(selectionRangeSet));
}
const findHasFromZero = (selectionRange) => {
return selectionRange.from === 0;
};
const fromZeroFreezeRange = freezeRanges.find(findHasFromZero);
if (fromZeroFreezeRange != null) {
const fromZeroRange = ranges.find(findHasFromZero);
if (fromZeroRange != null) {
ranges = ranges.filter((range) => range !== fromZeroRange);
}
}
}
const returnedTransaction = {
...transaction,
...ranges.length > 0 ? { selection: EditorSelection2.create(ranges) } : {},
...ignoreChanges ? {
changes: [],
selection: transaction.startState.selection
} : {}
};
return returnedTransaction;
});
}
var frozenDecoration = Decoration.line({
attributes: { class: "cm-frozen" }
});
function freezeDecoration(view) {
const builder = new RangeSetBuilder();
const freezeRanges = getFreezeRanges(
view.state,
view.state.facet(startFreezeComment),
view.state.facet(endFreezeComment)
);
for (const { from, to } of view.visibleRanges) {
for (let pos = from; pos <= to; ) {
const line = view.state.doc.lineAt(pos);
for (const freezeRange of freezeRanges) {
if (freezeRange.from < line.from && line.from < freezeRange.to || freezeRange.from < line.to && line.to < freezeRange.to) {
builder.add(line.from, line.from, frozenDecoration);
}
}
pos = line.to + 1;
}
}
return builder.finish();
}
var FreezeViewPlugin = class {
constructor(view) {
this.decorations = freezeDecoration(view);
}
update(update) {
if (!(update.docChanged || update.viewportChanged)) {
return;
}
this.decorations = freezeDecoration(update.view);
}
};
function getFreezeViewPlugin() {
const plugin = ViewPlugin.fromClass(FreezeViewPlugin, {
decorations: (value) => value.decorations
});
return plugin;
}
var _startFreezeComment = startFreezeComment;
var _endFreezeComment = endFreezeComment;
function freeze(startFreezeComment2 = "start-freeze", endFreezeComment2 = "end-freeze") {
const startFreezeCommentOf = _startFreezeComment.of(startFreezeComment2);
const endFreezeCommentOf = _endFreezeComment.of(endFreezeComment2);
const freezeTransactionFilter = getFreezeTransactionFilter();
const freezeViewPlugin = getFreezeViewPlugin();
return [
freezeTransactionFilter,
freezeViewPlugin,
startFreezeCommentOf,
endFreezeCommentOf,
freezeTheme
];
}
export {
endFreezeComment,
freeze,
startFreezeComment
};
//# sourceMappingURL=dist-SFRFRGE3.mjs.map