feat: leave and detach

This commit is contained in:
frelodev 2024-10-01 19:44:55 +02:00
parent 509240838b
commit 05a7638761
6 changed files with 72 additions and 16 deletions

View file

@ -6,7 +6,7 @@
"homepage": "https://code.mp",
"repository": "https://github.com/hexedtech/codemp-vscode",
"publisher": "hexedtech",
"version": "0.1.2",
"version": "0.1.3",
"engines": {
"vscode": "^1.81.0"
},
@ -173,7 +173,14 @@
"title": "Jump",
"category": "codemp",
"icon": "$(debug-console-evaluation-input)"
},
{
"command": "codemp.forceDesync",
"title": "Desync",
"category": "codemp"
}
],
"configuration": {
"title": "codemp",
@ -236,6 +243,6 @@
"typescript": "^5.1.6"
},
"dependencies": {
"codemp": "^0.7.2"
"codemp": "^0.7.3"
}
}

View file

@ -8,10 +8,13 @@ import { LOGGER, provider } from '../extension';
let locks: Map<string, boolean> = new Map();
let autoResync = vscode.workspace.getConfiguration('codemp').get<string>("autoResync");
export async function apply_changes_to_buffer(path: string, controller: codemp.BufferController | undefined | null, force?: boolean) {
if (workspace === null) throw "can't apply changes while not in a workspace";
if (!controller) controller = workspace.buffer_by_name(path);
if (!controller) return;
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);
if (editor === undefined) return;
@ -88,7 +91,6 @@ export async function attach_to_remote_buffer(buffer_name: string, set_content?:
LOGGER.info(`attached to buffer ${buffer_name}`);
let file_uri: vscode.Uri = editor.document.uri;
mapping.bufferMapper.register(buffer.get_path(), file_uri);
let remoteContent = await buffer.content();
let localContent = editor.document.getText();
@ -110,7 +112,7 @@ export async function attach_to_remote_buffer(buffer_name: string, set_content?:
});
}
vscode.workspace.onDidChangeTextDocument(async (event: vscode.TextDocumentChangeEvent) => {
let disposable = vscode.workspace.onDidChangeTextDocument(async (event: vscode.TextDocumentChangeEvent) => {
if (locks.get(buffer_name)) { return }
if (event.document.uri !== file_uri) return; // ?
for (let change of event.contentChanges) {
@ -127,6 +129,8 @@ export async function attach_to_remote_buffer(buffer_name: string, set_content?:
await apply_changes_to_buffer(controller.get_path(), controller)
);
mapping.bufferMapper.register(buffer.get_path(), file_uri, disposable);
provider.refresh();
}
@ -146,6 +150,26 @@ export async function attach(selected: vscode.TreeItem | undefined) {
await attach_to_remote_buffer(buffer_name);
}
export async function detach(selected: vscode.TreeItem | undefined) {
if (workspace === null) return vscode.window.showWarningMessage("Not in a workspace");
let buffer_name: string | undefined;
if (selected !== undefined && selected.label !== undefined) {
if (typeof (selected.label) === 'string') {
buffer_name = selected.label;
} else {
buffer_name = selected.label.label; // TODO ughh what is this api?
}
} else {
buffer_name = await vscode.window.showInputBox({ prompt: "path of buffer to attach to" });
}
if (!buffer_name) return;
let controller = workspace.buffer_by_name(buffer_name);
if (controller) controller.clear_callback();
workspace.detach(buffer_name);
mapping.bufferMapper.remove(buffer_name);
vscode.window.showInformationMessage(`Detached from buffer ${buffer_name}`)
}
export async function share(selected: vscode.TreeItem | undefined) {
if (workspace === null) return vscode.window.showWarningMessage("Join a workspace first");

View file

@ -8,6 +8,7 @@ import { LOGGER, provider } from '../extension';
// TODO this "global state" should probably live elsewher but we need lo update it from these commands
export let client: codemp.Client | null = null;
export let workspace_list: string[] = [];
export let cursor_disposable : vscode.Disposable | null;
export async function connect() {
let config = vscode.workspace.getConfiguration('codemp');
@ -61,6 +62,11 @@ export async function join(selected: vscode.TreeItem | undefined) {
controller.callback(async function(controller: codemp.CursorController) {
while (true) {
let event = await controller.try_recv();
if (workspace === null) {
controller.clear_callback();
LOGGER.info("left workspace, stopping cursor controller");
return;
}
if (event === null) break;
if (event.user === undefined) {
LOGGER.warn(`Skipping cursor event without user: ${event}`)
@ -80,7 +86,7 @@ export async function join(selected: vscode.TreeItem | undefined) {
});
let once = true;
vscode.window.onDidChangeTextEditorSelection(async (event: vscode.TextEditorSelectionChangeEvent) => {
cursor_disposable = vscode.window.onDidChangeTextEditorSelection(async (event: vscode.TextEditorSelectionChangeEvent) => {
if (event.kind == vscode.TextEditorSelectionChangeKind.Command) return; // TODO commands might move cursor too
let buf = event.textEditor.document.uri;
let selection: vscode.Selection = event.selections[0]
@ -138,9 +144,14 @@ export async function join(selected: vscode.TreeItem | undefined) {
provider.refresh();
}
export async function leave() {
if (!client) throw "can't leave while disconnected";
if (!workspace) return vscode.window.showWarningMessage("Not in a workspace");
client.leave_workspace(workspace.id());
if (cursor_disposable !== null) cursor_disposable.dispose();
cursor_disposable = null;
setWorkspace(null);
}
export async function listWorkspaces() {

View file

@ -8,7 +8,7 @@ import { LOGGER, provider } from '../extension';
export let workspace: codemp.Workspace | null = null;
export function setWorkspace(ws: codemp.Workspace) {
export function setWorkspace(ws: codemp.Workspace | null) {
workspace = ws;
}

View file

@ -22,8 +22,10 @@ export function activate(context: vscode.ExtensionContext) {
if (workspace === null) return;
for (let editor of editors) {
let path = mapping.bufferMapper.by_editor(editor.document.uri);
if (path === undefined) continue;
await apply_changes_to_buffer(path, undefined, true);
if (!path) continue;
let controller = workspace.buffer_by_name(path);
if (!controller) continue;
await apply_changes_to_buffer(path, controller, true);
}
});

View file

@ -3,11 +3,13 @@ import * as codemp from 'codemp';
class BufferMapper {
bufferToEditorMapping: Map<string, vscode.Uri> = new Map();
bufferToDisposableMapping: Map<string, vscode.Disposable> = new Map();
editorToBufferMapping: Map<vscode.Uri, string> = new Map();
public register(buffer: string, uri: vscode.Uri) {
public register(buffer: string, uri: vscode.Uri, disposable: vscode.Disposable) {
this.bufferToEditorMapping.set(buffer, uri);
this.editorToBufferMapping.set(uri, buffer);
this.bufferToDisposableMapping.set(buffer, disposable);
}
public uri_by_buffer(name: string): vscode.Uri | undefined {
@ -24,6 +26,16 @@ class BufferMapper {
return this.editorToBufferMapping.get(name);
}
public remove(name: string) {
let uri = this.bufferToEditorMapping.get(name);
let disposable = this.bufferToDisposableMapping.get(name);
if (disposable) disposable.dispose();
if (!uri) return;
this.bufferToEditorMapping.delete(name);
this.editorToBufferMapping.delete(uri);
this.bufferToDisposableMapping.delete(name);
}
private constructor() { }
public static instance = new BufferMapper();