Ich entwickle eine VS-Code-Erweiterung, die einen Streaming-Diff für einen ausgewählten Textbereich durchführt. Die Erweiterung empfängt neue Zeilen, die den ausgewählten Text ersetzen sollen, über eine WebSocket-Verbindung, generiert Diff-Zeilen („same“, „old“, „new“) und wendet sie in Echtzeit auf den aktiven Editor an.Problem:
Die Funktion editor.edit, die ich zum Einfügen neuer Zeilen verwende, blockiert die Hauptfunktion Der Thread wird während des Streaming-Vorgangs unerwartet lange (in manchen Fällen bis zu 40 Sekunden) unterbrochen. Dies geschieht, obwohl editor.edit asynchron sein soll. Das Problem scheint gegen Ende des Differenzierungsvorgangs beim Einfügen „neuer“ Zeilen stärker ausgeprägt zu sein. Ich habe die vscode-API auf editor.edit durchgesehen, um zu sehen, ob ich eine schlechte Implementierung oder ähnliches gemacht habe, aber keine Fortschritte dabei gemacht. Codestruktur:
Mein Code ist wie folgt aufgebaut:
Ein WebSocketClient empfängt Diff-Zeilen von einem Server .
Der setMessageCallback des Clients pusht neue Zeilen zu einerlinesQueue.
verwendet eine Generatorfunktion showInlineDiffForSelectedRangeV2, um DiffLine-Objekte basierend auf einer benutzerdefinierten matchLine-Funktion zu erzeugen (die den Levenshtein-Abstand für Fuzzy-Matching verwendet).
< li>
Ich entwickle eine VS-Code-Erweiterung, die einen Streaming-Diff für einen ausgewählten Textbereich durchführt. Die Erweiterung empfängt neue Zeilen, die den ausgewählten Text ersetzen sollen, über eine WebSocket-Verbindung, generiert Diff-Zeilen („same“, „old“, „new“) und wendet sie in Echtzeit auf den aktiven Editor an.[b]Problem:[/b] Die Funktion editor.edit, die ich zum Einfügen neuer Zeilen verwende, blockiert die Hauptfunktion Der Thread wird während des Streaming-Vorgangs unerwartet lange (in manchen Fällen bis zu 40 Sekunden) unterbrochen. Dies geschieht, obwohl editor.edit asynchron sein soll. Das Problem scheint gegen Ende des Differenzierungsvorgangs beim Einfügen „neuer“ Zeilen stärker ausgeprägt zu sein. Ich habe die vscode-API auf editor.edit durchgesehen, um zu sehen, ob ich eine schlechte Implementierung oder ähnliches gemacht habe, aber keine Fortschritte dabei gemacht. [b]Codestruktur: Mein Code ist wie folgt aufgebaut: [list] [*]Ein WebSocketClient empfängt Diff-Zeilen von einem Server . [*]Der setMessageCallback des Clients pusht neue Zeilen zu einerlinesQueue. [*][code]processLinesQueue[/code] verarbeitet die Zeilen in der Warteschlange und ruft handleStreamData für jede Zeile auf. [*][code]handleStreamData[/code] verwendet eine Generatorfunktion showInlineDiffForSelectedRangeV2, um DiffLine-Objekte basierend auf einer benutzerdefinierten matchLine-Funktion zu erzeugen (die den Levenshtein-Abstand für Fuzzy-Matching verwendet). < li>[code]insertLineAboveIndex[/code] verwendet editor.edit mit editBuilder.insert, um neue Zeilen in das Dokument einzufügen. [*][code]reapplyWithMeyersDiff[/code] wendet nach Abschluss des Streamings einen Myers-Diff an, um die Genauigkeit sicherzustellen. [/list] Relevante Codeausschnitte:[/b]
private async handleStreamData(newLine: string) { const editor = vscode.window.activeTextEditor; if (!editor || !this.oldRange) { return; } if (this.stopQueueProcessing) { this.processingQueue = false; return; // Exit immediately if stopped }
for await (const diffLine of this.showInlineDiffForSelectedRangeV2(newLine, this.showCodelens)) { console.log("Processing diffLine:", diffLine); if (this.stopQueueProcessing) { return; // Exit if processing is stopped }
switch (diffLine.type) { case "same": await this.insertDeletionBuffer(); this.incrementCurrentLineIndex(); break; case "old": this.deletionBuffer.push(diffLine.line); await this.deleteLinesAt(this.currentLineIndex); this.deletedLinesOffset++; break; case "new": console.time("insertLineAboveIndex"); await this.insertLineAboveIndex(this.currentLineIndex, diffLine.line); console.timeEnd("insertLineAboveIndex"); this.incrementCurrentLineIndex(); this.insertedInCurrentBlock++; this.addedLinesOffset++;
// Expand oldRange if necessary if (this.currentLineIndex >= this.oldRange!.end.line) { this.oldRange = new vscode.Selection( this.oldRange!.start.line, this.oldRange!.start.character, this.currentLineIndex, 0 ); } break; } } }
iterationCount++; if (iterationCount % yieldInterval === 0) { // Yield to the event loop without producing a value await new Promise(resolve => setTimeout(resolve, 0)); } }
// Yield any remaining lines as "new" if (!loadCodeLens) { yield { type: "new", line: newLine }; while (this.oldLinesCopy.length > 0) { yield { type: "old", line: this.oldLinesCopy.shift()! }; } } }
const isEndBracket = END_BRACKETS.includes(newLine.trim()); for (let i = 0; i < oldCodeCopy.length; i++) { if (i > 4 && isEndBracket) { return { matchIndex: -1, isPerfectMatch: false, newDiffedLine: newLine }; }
if (linesMatchPerfectly(newLine, oldCodeCopy[i])) { return { matchIndex: i, isPerfectMatch: true, newDiffedLine: newLine }; }
// Use cached distance if available const distanceKey = `${newLine}_${oldCodeCopy[i]}`; if (linesMatch(newLine, oldCodeCopy[i], i)) { // More permissive indentation handling const newTrimmed = newLine.trim(); const oldTrimmed = oldCodeCopy[i].trim();
if ( newTrimmed === oldTrimmed || (permissiveAboutIndentation && newTrimmed.length > 0 && (newLine.length - newTrimmed.length) - (oldCodeCopy[i].length - oldTrimmed.length) setTimeout(resolve, 0))“, um die Kontrolle über die Ereignisschleife zu erhalten. [*]Batchbearbeitung von Änderungen innerhalb von editor.edit< /code>. [*]setInterval verwenden, um Zeilen regelmäßig zu verarbeiten, statt einer while--Schleife. [*]Ich habe es versucht Worker-Threads, was funktioniert, aber ein Problem mit sich bringt diffLines folgen nicht der richtigen Reihenfolge [/list] [b]Wonach ich suche:[/b] [list] [*]Einblicke darüber, warum editor.edit trotz seiner asynchronen Natur möglicherweise blockiert. [*]Vorschläge für weitere Debugging- oder Profiling-Techniken. [*]Empfehlungen für alternative Ansätze oder Optimierungen, um die Verlangsamung bei gleichzeitiger Erhaltung zu vermeiden die Streaming-Diff-Funktionalität (falls möglich). [*]Alle relevanten Informationen zu bekannten Einschränkungen oder Leistungsüberlegungen im Zusammenhang mit editor.edit in der VS Code API. [/list]
Ich habe Schwierigkeiten, die Edit.ToggleLineComment-Tastenkombination in Visual Studio 2022 zu verwenden, wenn es um .xaml-Dateien geht.
Mein Tastenkürzel ist wie hier gezeigt richtig eingestellt...