Try harder to be incremental in editContent
This commit is contained in:
parent
1f72baf3ad
commit
aafb654687
|
@ -232,20 +232,98 @@ const boot: tslib.server.PluginModuleFactory = ({ typescript: ts }) => {
|
||||||
ts.createSourceFile = createSourceFile;
|
ts.createSourceFile = createSourceFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const oldUpdateSourceFile = ts.updateSourceFile;
|
||||||
|
|
||||||
|
function commonPrefixLength(a: string, b: string): number {
|
||||||
|
const limit = Math.min(a.length, b.length);
|
||||||
|
for (let i = 0; i < limit; i++) {
|
||||||
|
if (a[i] !== b[i]) return i;
|
||||||
|
}
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
function commonSuffixLength(a: string, b: string): number {
|
||||||
|
const limit = Math.min(a.length, b.length);
|
||||||
|
for (let i = 0; i < limit; i++) {
|
||||||
|
if (a[a.length - i - 1] !== b[b.length - i - 1]) return i;
|
||||||
|
}
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSourceFile(
|
||||||
|
sourceFile: ts.SourceFile,
|
||||||
|
newText: string,
|
||||||
|
textChangeRange: ts.TextChangeRange,
|
||||||
|
aggressiveChecks?: boolean,
|
||||||
|
): ts.SourceFile {
|
||||||
|
return withFileName(
|
||||||
|
sourceFile.fileName,
|
||||||
|
() => oldUpdateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks),
|
||||||
|
(fx) => {
|
||||||
|
const oldInfo = fx.info;
|
||||||
|
return expandFile(
|
||||||
|
sourceFile.fileName,
|
||||||
|
oldInfo.originalSource,
|
||||||
|
(newExpandedText) => {
|
||||||
|
const oldExpandedText = oldInfo.sourceFile.text;
|
||||||
|
if (oldExpandedText === newExpandedText) {
|
||||||
|
// console.log('updateSourceFile', 'no change');
|
||||||
|
return oldInfo.sourceFile;
|
||||||
|
} else {
|
||||||
|
const prefix = commonPrefixLength(oldExpandedText, newExpandedText);
|
||||||
|
const suffix =
|
||||||
|
commonSuffixLength(oldExpandedText.substring(prefix),
|
||||||
|
newExpandedText.substring(prefix));
|
||||||
|
const newChangeRange = {
|
||||||
|
span: {
|
||||||
|
start: prefix,
|
||||||
|
length: oldExpandedText.length - prefix - suffix,
|
||||||
|
},
|
||||||
|
newLength: newExpandedText.length - prefix - suffix,
|
||||||
|
} satisfies ts.TextChangeRange;
|
||||||
|
// console.log('updateSourceFile', JSON.stringify({
|
||||||
|
// oldSyndicateText: oldInfo.originalSource,
|
||||||
|
// newSyndicateText: newText,
|
||||||
|
// oldExpandedText,
|
||||||
|
// newExpandedText,
|
||||||
|
// oldLength: oldExpandedText.length,
|
||||||
|
// newLength: newExpandedText.length,
|
||||||
|
// oldChangeRange: textChangeRange,
|
||||||
|
// newChangeRange,
|
||||||
|
// prefix,
|
||||||
|
// suffix,
|
||||||
|
// }, void 0, 2));
|
||||||
|
return oldUpdateSourceFile(
|
||||||
|
sourceFile, newExpandedText, newChangeRange, aggressiveChecks);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ts.updateSourceFile = updateSourceFile;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const oldEditContent = ts.server.ScriptInfo.prototype.editContent;
|
const oldEditContent = ts.server.ScriptInfo.prototype.editContent;
|
||||||
ts.server.ScriptInfo.prototype.editContent =
|
ts.server.ScriptInfo.prototype.editContent =
|
||||||
function (start: number, end: number, newText: string): void {
|
function (start: number, end: number, newText: string): void {
|
||||||
// console.log('SyndicateScriptInfo.editContent', this.fileName, start, end, newText);
|
// console.log('SyndicateScriptInfo.editContent', JSON.stringify({
|
||||||
|
// fileName: this.fileName,
|
||||||
|
// start,
|
||||||
|
// end,
|
||||||
|
// newText,
|
||||||
|
// oldText: (this as any).textStorage.text ?? ["MISSING"],
|
||||||
|
// }, void 0, 2));
|
||||||
withFileName(this.fileName,
|
withFileName(this.fileName,
|
||||||
() => oldEditContent(start, end, newText),
|
() => oldEditContent.call(this, start, end, newText),
|
||||||
(fx) => {
|
(fx) => {
|
||||||
const info = fx.info;
|
const info = fx.info;
|
||||||
const revised = info.originalSource.substring(0, start) +
|
const revised = info.originalSource.substring(0, start) +
|
||||||
newText +
|
newText +
|
||||||
info.originalSource.substring(end);
|
info.originalSource.substring(end);
|
||||||
info.originalSource = revised;
|
info.originalSource = revised;
|
||||||
this.open(revised);
|
oldEditContent.call(this, start, end, newText);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue