mirror of
https://github.com/hexedtech/codemp-vscode.git
synced 2024-11-22 07:24:49 +01:00
fix: resync if editor.edit fails
Co-authored-by: alemi <me@alemi.dev>
This commit is contained in:
parent
f4e0758fb9
commit
5832e19f8a
1 changed files with 47 additions and 25 deletions
|
@ -1,54 +1,64 @@
|
||||||
|
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as codemp from 'codemp';
|
import * as codemp from 'codemp';
|
||||||
import * as mapping from "../mapping";
|
import * as mapping from "../mapping";
|
||||||
import { workspace } from "./workspaces";
|
import { workspace } from "./workspaces";
|
||||||
import { LOGGER, provider } from '../extension';
|
import { LOGGER, provider } from '../extension';
|
||||||
|
|
||||||
let locks: Map<string, boolean> = new Map();
|
let singles: Map<string, boolean> = new Map();
|
||||||
|
let locks: Map<string, string> = new Map();
|
||||||
let autoResync = vscode.workspace.getConfiguration('codemp').get<string>("autoResync");
|
let autoResync = vscode.workspace.getConfiguration('codemp').get<string>("autoResync");
|
||||||
|
|
||||||
export async function apply_changes_to_buffer(path: string, controller: codemp.BufferController, force?: boolean) {
|
export async function apply_changes_to_buffer(path: string, controller: codemp.BufferController, force?: boolean) {
|
||||||
if (workspace === null) {
|
|
||||||
LOGGER.info(`left workspace, unregistering buffer controller '${path}' callback`);
|
|
||||||
controller.clear_callback();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let editor = mapping.bufferMapper.visible_by_buffer(path);
|
let editor = mapping.bufferMapper.visible_by_buffer(path);
|
||||||
if (editor === undefined) return;
|
if (editor === undefined) return;
|
||||||
|
|
||||||
if (locks.get(path) && !force) return;
|
if (singles.get(path) && !force) return;
|
||||||
locks.set(path, true);
|
|
||||||
|
singles.set(path, true);
|
||||||
while (true) {
|
while (true) {
|
||||||
|
if (workspace === null) {
|
||||||
|
LOGGER.info(`left workspace, unregistering buffer controller '${path}' callback`);
|
||||||
|
controller.clear_callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
let event = await controller.try_recv();
|
let event = await controller.try_recv();
|
||||||
if (event === null) break;
|
if (event === null) break;
|
||||||
LOGGER.debug(`buffer.callback(event: [${event.start}, ${event.content}, ${event.end}])`)
|
// LOGGER.info(`buffer.callback(event: [${event.start}, ${event.content}, ${event.end}])`)
|
||||||
|
|
||||||
let range = new vscode.Range(
|
let range = new vscode.Range(
|
||||||
editor.document.positionAt(event.start),
|
editor.document.positionAt(event.start),
|
||||||
editor.document.positionAt(event.end)
|
editor.document.positionAt(event.end)
|
||||||
)
|
)
|
||||||
|
|
||||||
await editor.edit(editBuilder => {
|
locks.set(path, event.content);
|
||||||
|
if (!await editor.edit(editBuilder => {
|
||||||
editBuilder
|
editBuilder
|
||||||
.replace(range, event.content)
|
.replace(range, event.content)
|
||||||
});
|
})) {
|
||||||
|
vscode.window.showWarningMessage("Couldn't apply changes");
|
||||||
|
await resync(path, workspace, editor, 20);
|
||||||
|
}
|
||||||
|
locks.delete(path);
|
||||||
|
|
||||||
if (event.hash !== undefined) {
|
if (event.hash !== undefined) {
|
||||||
if (codemp.hash(editor.document.getText()) !== event.hash) {
|
if (codemp.hash(editor.document.getText()) !== event.hash) {
|
||||||
if (autoResync) {
|
if (autoResync) {
|
||||||
vscode.window.showWarningMessage("Out of Sync, resynching...");
|
vscode.window.showWarningMessage("Out of Sync, resynching...");
|
||||||
await resync(path, workspace, editor);
|
await resync(path, workspace, editor, 20);
|
||||||
} else {
|
} else {
|
||||||
controller.clear_callback();
|
controller.clear_callback();
|
||||||
const selection = await vscode.window.showWarningMessage('Out of Sync', 'Resync');
|
const selection = await vscode.window.showWarningMessage('Out of Sync', 'Resync');
|
||||||
if (selection !== undefined && workspace) await resync(path, workspace, editor);
|
if (selection !== undefined && workspace) {
|
||||||
|
await resync(path, workspace, editor, 20);
|
||||||
|
controller.callback(async (controller: codemp.BufferController) =>
|
||||||
|
await apply_changes_to_buffer(controller.get_path(), controller)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
locks.set(path, false);
|
|
||||||
}
|
}
|
||||||
|
singles.set(path, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function attach_to_remote_buffer(buffer_name: string, set_content?: boolean): Promise<codemp.BufferController | undefined> {
|
export async function attach_to_remote_buffer(buffer_name: string, set_content?: boolean): Promise<codemp.BufferController | undefined> {
|
||||||
|
@ -106,17 +116,20 @@ export async function attach_to_remote_buffer(buffer_name: string, set_content?:
|
||||||
editor.document.positionAt(0),
|
editor.document.positionAt(0),
|
||||||
editor.document.positionAt(doc_len)
|
editor.document.positionAt(doc_len)
|
||||||
);
|
);
|
||||||
|
locks.set(buffer_name, `${0}..${doc_len}:${remoteContent}`);
|
||||||
await editor.edit(editBuilder => {
|
await editor.edit(editBuilder => {
|
||||||
editBuilder
|
editBuilder
|
||||||
.replace(range, remoteContent)
|
.replace(range, remoteContent)
|
||||||
});
|
});
|
||||||
|
locks.delete(buffer_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
let disposable = vscode.workspace.onDidChangeTextDocument(async (event: vscode.TextDocumentChangeEvent) => {
|
let disposable = vscode.workspace.onDidChangeTextDocument(async (event: vscode.TextDocumentChangeEvent) => {
|
||||||
if (locks.get(buffer_name)) { return }
|
if (!mapping.bufferMapper.by_editor(event.document.uri)) return;
|
||||||
if (event.document.uri !== file_uri) return; // ?
|
let skip_this = locks.get(buffer_name);
|
||||||
for (let change of event.contentChanges) {
|
for (let change of event.contentChanges) {
|
||||||
LOGGER.debug(`onDidChangeTextDocument(event: [${change.rangeOffset}, ${change.text}, ${change.rangeOffset + change.rangeLength}])`);
|
if (skip_this && change.text == skip_this) continue;
|
||||||
|
// LOGGER.info(`onDidChangeTextDocument(event: [${change.rangeOffset}, ${change.text}, ${change.rangeOffset + change.rangeLength}])`);
|
||||||
await buffer.send({
|
await buffer.send({
|
||||||
start: change.rangeOffset,
|
start: change.rangeOffset,
|
||||||
end: change.rangeOffset + change.rangeLength,
|
end: change.rangeOffset + change.rangeLength,
|
||||||
|
@ -208,13 +221,11 @@ export async function sync(selected: vscode.TreeItem | undefined) {
|
||||||
if (buffer_name === undefined) throw "No such buffer managed by codemp"
|
if (buffer_name === undefined) throw "No such buffer managed by codemp"
|
||||||
}
|
}
|
||||||
|
|
||||||
locks.set(buffer_name, true);
|
|
||||||
resync(buffer_name, workspace, editor);
|
resync(buffer_name, workspace, editor);
|
||||||
locks.set(buffer_name, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function resync(buffer_name: string, workspace: codemp.Workspace, editor: vscode.TextEditor) {
|
export async function resync(buffer_name: string, workspace: codemp.Workspace, editor: vscode.TextEditor, tries?: number) {
|
||||||
|
LOGGER.info(`resynching buffer ${buffer_name}`);
|
||||||
let controller = workspace.buffer_by_name(buffer_name);
|
let controller = workspace.buffer_by_name(buffer_name);
|
||||||
if (controller === null) throw "No such buffer controller"
|
if (controller === null) throw "No such buffer controller"
|
||||||
|
|
||||||
|
@ -225,6 +236,17 @@ export async function resync(buffer_name: string, workspace: codemp.Workspace, e
|
||||||
editor.document.positionAt(doc_len)
|
editor.document.positionAt(doc_len)
|
||||||
);
|
);
|
||||||
|
|
||||||
await editor.edit(editBuilder => editBuilder.replace(range, content));
|
if (!tries) { tries = 1 };
|
||||||
|
|
||||||
}
|
locks.set(buffer_name, content);
|
||||||
|
for (let i = 0; i < tries; i++) {
|
||||||
|
if (await editor.edit(editBuilder => editBuilder.replace(range, content))) {
|
||||||
|
console.log("attempts to sync", tries);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == tries-1) {
|
||||||
|
vscode.window.showErrorMessage(`Failed setting buffer content after ${tries} tries`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
locks.delete(buffer_name);
|
||||||
|
}
|
Loading…
Reference in a new issue