astro-ghostcms/.pnpm-store/v3/files/4c/519df59002367eedad67647bc05...

216 lines
8.4 KiB
Plaintext

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createDocuments = exports.combineContinuousChangeRanges = void 0;
const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
const vscode = require("vscode-languageserver");
const uriMap_1 = require("./utils/uriMap");
class IncrementalScriptSnapshot {
constructor(uri, languageId, version, text) {
this.uri = uri;
this.document = vscode_languageserver_textdocument_1.TextDocument.create(uri, languageId, version, text);
this.changes = [
{
applied: true,
changeRange: undefined,
version,
contentChange: undefined,
snapshot: undefined,
}
];
}
get version() {
return this.changes[this.changes.length - 1].version;
}
get languageId() {
return this.document.languageId;
}
update(params) {
vscode_languageserver_textdocument_1.TextDocument.update(this.document, params.contentChanges, params.textDocument.version);
this.changes = [
{
applied: true,
changeRange: undefined,
version: params.textDocument.version,
contentChange: undefined,
snapshot: undefined,
}
];
}
getSnapshot() {
this.clearUnReferenceVersions();
const lastChange = this.changes[this.changes.length - 1];
if (!lastChange.snapshot) {
this.applyVersionChanges(lastChange.version, false);
const text = this.document.getText();
const cache = new WeakMap();
const snapshot = {
getText: (start, end) => text.substring(start, end),
getLength: () => text.length,
getChangeRange: (oldSnapshot) => {
if (!cache.has(oldSnapshot)) {
const oldIndex = this.changes.findIndex(change => change.snapshot?.deref() === oldSnapshot);
if (oldIndex >= 0) {
const start = oldIndex + 1;
const end = this.changes.indexOf(lastChange) + 1;
const changeRanges = this.changes.slice(start, end).map(change => change.changeRange);
const result = combineContinuousChangeRanges.apply(null, changeRanges);
cache.set(oldSnapshot, result);
}
else {
cache.set(oldSnapshot, undefined);
}
}
return cache.get(oldSnapshot);
},
};
lastChange.snapshot = new WeakRef(snapshot);
}
return lastChange.snapshot.deref();
}
getDocument() {
this.clearUnReferenceVersions();
const lastChange = this.changes[this.changes.length - 1];
if (!lastChange.applied) {
this.applyVersionChanges(lastChange.version, false);
}
return this.document;
}
clearUnReferenceVersions() {
let versionToApply;
for (let i = 0; i <= this.changes.length - 2; i++) {
const change = this.changes[i];
const nextChange = this.changes[i + 1];
if (!change.snapshot?.deref()) {
if (change.version !== nextChange.version) {
versionToApply = change.version;
}
}
else {
break;
}
}
if (versionToApply !== undefined) {
this.applyVersionChanges(versionToApply, true);
}
}
applyVersionChanges(version, removeBeforeVersions) {
let removeEnd = -1;
for (let i = 0; i < this.changes.length; i++) {
const change = this.changes[i];
if (change.version > version) {
break;
}
if (!change.applied) {
if (change.contentChange) {
change.changeRange = {
span: {
start: this.document.offsetAt(change.contentChange.range.start),
length: this.document.offsetAt(change.contentChange.range.end) - this.document.offsetAt(change.contentChange.range.start),
},
newLength: change.contentChange.text.length,
};
vscode_languageserver_textdocument_1.TextDocument.update(this.document, [change.contentChange], change.version);
}
change.applied = true;
}
removeEnd = i + 1;
}
if (removeBeforeVersions && removeEnd >= 1) {
this.changes.splice(0, removeEnd);
}
}
}
function combineContinuousChangeRanges(...changeRanges) {
if (changeRanges.length === 1) {
return changeRanges[0];
}
let changeRange = changeRanges[0];
for (let i = 1; i < changeRanges.length; i++) {
const nextChangeRange = changeRanges[i];
changeRange = _combineContinuousChangeRanges(changeRange, nextChangeRange);
}
return changeRange;
}
exports.combineContinuousChangeRanges = combineContinuousChangeRanges;
// https://tsplay.dev/mMldVN - @browsnet
function _combineContinuousChangeRanges(a, b) {
const aStart = a.span.start;
const aEnd = a.span.start + a.span.length;
const aDiff = a.newLength - a.span.length;
const changeBegin = aStart + Math.min(a.span.length, a.newLength);
const rollback = (start) => start > changeBegin ? Math.max(aStart, start - aDiff) : start;
const bStart = rollback(b.span.start);
const bEnd = rollback(b.span.start + b.span.length);
const bDiff = b.newLength - b.span.length;
const start = Math.min(aStart, bStart);
const end = Math.max(aEnd, bEnd);
const length = end - start;
const newLength = aDiff + bDiff + length;
return { span: { start, length }, newLength };
}
function createDocuments(env, connection) {
const snapshots = (0, uriMap_1.createUriMap)(env.fileNameToUri);
const onDidChangeContents = new Set();
const onDidCloses = new Set();
connection.onDidOpenTextDocument(params => {
if (params.textDocument.uri.startsWith('git:/'))
return;
snapshots.uriSet(params.textDocument.uri, new IncrementalScriptSnapshot(params.textDocument.uri, params.textDocument.languageId, params.textDocument.version, params.textDocument.text));
for (const cb of onDidChangeContents) {
cb({ textDocument: params.textDocument, contentChanges: [{ text: params.textDocument.text }] });
}
});
connection.onDidChangeTextDocument(params => {
if (params.textDocument.uri.startsWith('git:/'))
return;
const incrementalSnapshot = snapshots.uriGet(params.textDocument.uri);
if (incrementalSnapshot) {
if (params.contentChanges.every(vscode.TextDocumentContentChangeEvent.isIncremental)) {
for (const contentChange of params.contentChanges) {
incrementalSnapshot.changes.push({
applied: false,
changeRange: undefined,
contentChange,
version: params.textDocument.version,
snapshot: undefined,
});
}
}
else {
incrementalSnapshot.update(params);
}
}
for (const cb of onDidChangeContents) {
cb(params);
}
});
connection.onDidCloseTextDocument(params => {
if (params.textDocument.uri.startsWith('git:/'))
return;
snapshots.uriDelete(params.textDocument.uri);
for (const cb of onDidCloses) {
cb(params);
}
});
return {
data: snapshots,
onDidChangeContent: (cb) => {
onDidChangeContents.add(cb);
return {
dispose() {
onDidChangeContents.delete(cb);
},
};
},
onDidClose: (cb) => {
onDidCloses.add(cb);
return {
dispose() {
onDidCloses.delete(cb);
},
};
},
};
}
exports.createDocuments = createDocuments;
//# sourceMappingURL=documents.js.map