fix: dont stop following when jumping across bufs

also refactor a bit globals

Co-authored-by: frelodev <frelodev@gmail.com>
This commit is contained in:
əlemi 2024-10-13 00:36:09 +02:00
parent 6bc6561769
commit 8586c07fe1
Signed by: alemi
GPG key ID: A4895B84D311642C
5 changed files with 67 additions and 73 deletions

View file

@ -1,7 +1,7 @@
import * as vscode from 'vscode';
import * as codemp from 'codemp';
import * as mapping from "../mapping";
import { workspace } from "./workspaces";
import { workspaceState } from "./workspaces";
import { LOGGER, provider } from '../extension';
let singles: Map<string, boolean> = new Map();
@ -16,7 +16,7 @@ export async function apply_changes_to_buffer(path: string, controller: codemp.B
singles.set(path, true);
while (true) {
if (workspace === null) {
if (workspaceState.workspace === null) {
LOGGER.info(`left workspace, unregistering buffer controller '${path}' callback`);
controller.clear_callback();
return;
@ -36,7 +36,7 @@ export async function apply_changes_to_buffer(path: string, controller: codemp.B
.replace(range, event.content)
})) {
vscode.window.showWarningMessage("Couldn't apply changes");
await resync(path, workspace, editor, 100);
await resync(path, workspaceState.workspace, editor, 100);
}
locks.delete(path);
@ -44,12 +44,12 @@ export async function apply_changes_to_buffer(path: string, controller: codemp.B
if (codemp.hash(editor.document.getText()) !== event.hash) {
if (autoResync) {
vscode.window.showWarningMessage("Out of Sync, resynching...");
await resync(path, workspace, editor, 20);
await resync(path, workspaceState.workspace, editor, 20);
} else {
controller.clear_callback();
const selection = await vscode.window.showWarningMessage('Out of Sync', 'Resync');
if (selection !== undefined && workspace) {
await resync(path, workspace, editor, 20);
if (selection !== undefined && workspaceState.workspace) {
await resync(path, workspaceState.workspace, editor, 20);
controller.callback(async (controller: codemp.BufferController) =>
await apply_changes_to_buffer(controller.get_path(), controller)
);
@ -62,7 +62,7 @@ export async function apply_changes_to_buffer(path: string, controller: codemp.B
}
export async function attach_to_remote_buffer(buffer_name: string, set_content?: boolean): Promise<codemp.BufferController | undefined> {
if (workspace === null) {
if (workspaceState.workspace === null) {
vscode.window.showErrorMessage("join a Workspace first");
return;
}
@ -86,7 +86,7 @@ export async function attach_to_remote_buffer(buffer_name: string, set_content?:
let doc = await vscode.workspace.openTextDocument(path);
let editor = await vscode.window.showTextDocument(doc, { preserveFocus: false })
await editor.edit((editor) => editor.setEndOfLine(vscode.EndOfLine.LF)); // set LF for EOL sequence
let buffer: codemp.BufferController = await workspace.attach(buffer_name);
let buffer: codemp.BufferController = await workspaceState.workspace.attach(buffer_name);
// wait for server changes
// TODO poll never unblocks, so this dirty fix is necessary
@ -148,7 +148,7 @@ export async function attach_to_remote_buffer(buffer_name: string, set_content?:
}
export async function attach(selected: vscode.TreeItem | undefined) {
if (workspace === null) return vscode.window.showWarningMessage("Join a workspace first");
if (workspaceState.workspace === null) return vscode.window.showWarningMessage("Join a workspace first");
let buffer_name: string | undefined;
if (selected !== undefined && selected.label !== undefined) {
if (typeof (selected.label) === 'string') {
@ -157,14 +157,14 @@ export async function attach(selected: vscode.TreeItem | undefined) {
buffer_name = selected.label.label; // TODO ughh what is this api?
}
} else {
buffer_name = await vscode.window.showQuickPick(workspace.filetree(null, false), { placeHolder: "buffer to attach to:" }, undefined);
buffer_name = await vscode.window.showQuickPick(workspaceState.workspace.filetree(null, false), { placeHolder: "buffer to attach to:" }, undefined);
}
if (!buffer_name) return;
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");
if (workspaceState.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') {
@ -173,12 +173,12 @@ export async function detach(selected: vscode.TreeItem | undefined) {
buffer_name = selected.label.label; // TODO ughh what is this api?
}
} else {
buffer_name = await vscode.window.showQuickPick(workspace.buffer_list(), { placeHolder: "buffer to detach from:" }, undefined);
buffer_name = await vscode.window.showQuickPick(workspaceState.workspace.buffer_list(), { placeHolder: "buffer to detach from:" }, undefined);
}
if (!buffer_name) return;
let controller = workspace.buffer_by_name(buffer_name);
let controller = workspaceState.workspace.buffer_by_name(buffer_name);
if (controller) controller.clear_callback();
workspace.detach(buffer_name);
workspaceState.workspace.detach(buffer_name);
mapping.bufferMapper.remove(buffer_name);
vscode.window.showInformationMessage(`Detached from buffer ${buffer_name}`)
provider.refresh();
@ -186,7 +186,7 @@ export async function detach(selected: vscode.TreeItem | undefined) {
export async function share() {
if (workspace === null) return vscode.window.showWarningMessage("Join a workspace first");
if (workspaceState.workspace === null) return vscode.window.showWarningMessage("Join a workspace first");
let buffer_name: string | undefined;
if (vscode.window.activeTextEditor !== null) {
buffer_name = vscode.window.activeTextEditor?.document.uri.toString();
@ -198,12 +198,12 @@ export async function share() {
let workspacePath: string = vscode.workspace.workspaceFolders[0].uri.toString();
buffer_name = buffer_name.replace(workspacePath, "").substring(1); //vscode.workspace.asRelativePath doesn't work properly with other extensions like ssh, substring(1) to remove "/"
console.log("After: " + buffer_name);
await workspace.create(buffer_name);
await workspaceState.workspace.create(buffer_name);
await attach_to_remote_buffer(buffer_name, true);
}
export async function sync(selected: vscode.TreeItem | undefined) {
if (workspace === null) return vscode.window.showWarningMessage("Join a workspace first");
if (workspaceState.workspace === null) return vscode.window.showWarningMessage("Join a workspace first");
let editor;
let buffer_name;
if (selected !== undefined && selected.label !== undefined) {
@ -221,7 +221,7 @@ export async function sync(selected: vscode.TreeItem | undefined) {
if (buffer_name === undefined) return vscode.window.showWarningMessage("Buffer not synched with codemp");
}
resync(buffer_name, workspace, editor);
resync(buffer_name, workspaceState.workspace, editor);
}
export async function resync(buffer_name: string, workspace: codemp.Workspace, editor: vscode.TextEditor, tries?: number) {

View file

@ -1,7 +1,7 @@
import * as vscode from 'vscode';
import * as codemp from 'codemp';
import * as mapping from "../mapping";
import { workspace, setWorkspace, follow, setFollow, executeJump } from "./workspaces";
import { executeJump, workspaceState } from "./workspaces";
import { LOGGER, provider } from '../extension';
@ -9,7 +9,6 @@ import { LOGGER, provider } from '../extension';
export let client: codemp.Client | null = null;
export let workspace_list: string[] = [];
export let cursor_disposable: vscode.Disposable | null;
let movedByFollow = false;
export async function connect() {
let config = vscode.workspace.getConfiguration('codemp');
@ -57,13 +56,12 @@ export async function join(selected: vscode.TreeItem | undefined) {
let ws = await vscode.window.showWorkspaceFolderPick({ placeHolder: "directory to open workspace into:" });
if (ws === undefined) return vscode.window.showErrorMessage("Open a Workspace folder first");
}
setWorkspace(await client.join_workspace(workspace_id));
if (!workspace) return;
let controller = workspace.cursor();
workspaceState.workspace = await client.join_workspace(workspace_id);
let controller = workspaceState.workspace.cursor();
controller.callback(async function (controller: codemp.CursorController) {
while (true) {
let event = await controller.try_recv();
if (workspace === null) {
if (workspaceState.workspace === null) {
controller.clear_callback();
LOGGER.info("left workspace, stopping cursor controller");
return;
@ -79,14 +77,11 @@ export async function join(selected: vscode.TreeItem | undefined) {
mapping.colors_cache.set(event.user, mapp);
provider.refresh();
}
if (follow === event.user) {
movedByFollow = true;
executeJump(event.user);
}
let editor = mapping.bufferMapper.visible_by_buffer(event.buffer);
let refresh = event.buffer != mapp.buffer;
mapp.update(event, editor);
if (workspaceState.follow === event.user) executeJump(event.user);
if (refresh) provider.refresh();
}
});
@ -94,8 +89,8 @@ export async function join(selected: vscode.TreeItem | undefined) {
let once = true;
cursor_disposable = vscode.window.onDidChangeTextEditorSelection(async (event: vscode.TextEditorSelectionChangeEvent) => {
if (event.kind == vscode.TextEditorSelectionChangeKind.Command) return; // TODO commands might move cursor too
if (!movedByFollow) setFollow(null);
else movedByFollow = false;
if (!workspaceState.justJumped) workspaceState.follow = null;
workspaceState.justJumped = false;
let buf = event.textEditor.document.uri;
let selection: vscode.Selection = event.selections[0];
let buffer = mapping.bufferMapper.by_editor(buf);
@ -128,8 +123,8 @@ export async function join(selected: vscode.TreeItem | undefined) {
let event_handler = async () => {
try {
while (true) {
if (workspace === null) break;
let event = await workspace.event();
if (workspaceState.workspace === null) break;
let event = await workspaceState.workspace.event();
if (event.type == "leave") {
mapping.colors_cache.get(event.value)?.clear()
mapping.colors_cache.delete(event.value);
@ -145,7 +140,7 @@ export async function join(selected: vscode.TreeItem | undefined) {
};
event_handler();
for (let user of workspace.user_list()) {
for (let user of workspaceState.workspace.user_list()) {
mapping.colors_cache.set(user, new mapping.UserDecoration(user));
}
@ -183,12 +178,12 @@ export async function inviteToWorkspace() {
export async function leave() {
if (!client) throw "can't leave while disconnected";
if (!workspace) throw "can't leave while not in a workspace";
workspace.cursor().clear_callback()
client.leave_workspace(workspace.id());
if (!workspaceState.workspace) throw "can't leave while not in a workspace";
workspaceState.workspace.cursor().clear_callback()
client.leave_workspace(workspaceState.workspace.id());
if (cursor_disposable !== null) cursor_disposable.dispose();
let workspace_id = workspace.id();
setWorkspace(null);
let workspace_id = workspaceState.workspace.id();
workspaceState.workspace = null;
provider.refresh();
vscode.window.showInformationMessage("Left workspace " + workspace_id);
}

View file

@ -5,17 +5,15 @@ import { client } from "./client"
import { LOGGER, provider } from '../extension';
export let workspace: codemp.Workspace | null = null;
export let follow: string | null = null;
export function setWorkspace(ws: codemp.Workspace | null) {
workspace = ws;
}
export function setFollow(doFollow: string | null) {
follow = doFollow;
}
export let workspaceState: {
workspace: codemp.Workspace | null,
follow: string | null,
justJumped: boolean,
} = {
workspace: null,
follow: null,
justJumped: false,
};
export async function jump(selected: vscode.TreeItem | undefined) {
@ -30,7 +28,7 @@ export async function jump(selected: vscode.TreeItem | undefined) {
}
if (!user) user = await vscode.window.showInputBox({ prompt: "username" });
if (!user) return; // user cancelled with ESC
setFollow(user);
workspaceState.follow=user;
executeJump(user);
}
@ -41,35 +39,36 @@ export async function executeJump(user: string) {
if (uri === undefined) {
return vscode.window.showWarningMessage("user is on an untracked buffer: " + user_hl.buffer);
}
let editor = await vscode.window.showTextDocument(uri, { preserveFocus: false });
let editor = vscode.window.activeTextEditor;
if (editor === undefined || editor.document.uri != uri) {
workspaceState.justJumped = true;
editor = await vscode.window.showTextDocument(uri, { preserveFocus: false });
}
let range_start: vscode.Position = new vscode.Position(user_hl.startRow, user_hl.startCol);
let range_end: vscode.Position = new vscode.Position(user_hl.endRow, user_hl.endCol);
let cursor_range = new vscode.Range(range_start, range_end);
editor.revealRange(cursor_range, vscode.TextEditorRevealType.InCenter);
}
export async function createBuffer() {
let bufferName: any = (await vscode.window.showInputBox({ prompt: "path of the buffer to create" }));
if (workspace === null) return vscode.window.showWarningMessage("Join a workspace first");
await workspace.create(bufferName);
if (workspaceState.workspace === null) return vscode.window.showWarningMessage("Join a workspace first");
await workspaceState.workspace.create(bufferName);
vscode.window.showInformationMessage(`new buffer created :${bufferName}`);
listBuffers();
//provider.refresh();
provider.refresh();
}
export async function listBuffers() {
if (workspace === null) return vscode.window.showWarningMessage("Join a workspace first");
let buffers = workspace.filetree(undefined, false);
if (workspaceState.workspace === null) return vscode.window.showWarningMessage("Join a workspace first");
let buffers = workspaceState.workspace.filetree(undefined, false);
vscode.window.showInformationMessage(buffers.join("\n"));
provider.refresh();
}
export async function deleteBuffer() {
let bufferName: any = (await vscode.window.showInputBox({ prompt: "path of the buffer to delete" }));
if (workspace === null) return vscode.window.showWarningMessage("Join a workspace first");
await workspace.delete(bufferName);
if (workspaceState.workspace === null) return vscode.window.showWarningMessage("Join a workspace first");
await workspaceState.workspace.delete(bufferName);
vscode.window.showInformationMessage(`Deleted buffer :${bufferName}`);
listBuffers();
provider.refresh();
}

View file

@ -3,7 +3,7 @@ import * as codemp from 'codemp';
import { client, connect, join, refresh, createWorkspace, inviteToWorkspace, listWorkspaces, leave } from './commands/client';
import { CodempTreeProvider } from './tree';
import * as mapping from './mapping';
import { workspace, jump, listBuffers, createBuffer, deleteBuffer } from './commands/workspaces'
import { workspaceState, jump, listBuffers, createBuffer, deleteBuffer } from './commands/workspaces'
import { attach, share, sync, apply_changes_to_buffer, detach } from './commands/buffers'
export let provider = new CodempTreeProvider();
@ -19,11 +19,11 @@ export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(sub);
vscode.window.onDidChangeVisibleTextEditors(async (editors: readonly vscode.TextEditor[]) => {
if (workspace === null) return;
if (workspaceState.workspace === null) return;
for (let editor of editors) {
let path = mapping.bufferMapper.by_editor(editor.document.uri);
if (!path) continue;
let controller = workspace.buffer_by_name(path);
let controller = workspaceState.workspace.buffer_by_name(path);
if (!controller) continue;
await apply_changes_to_buffer(path, controller, true);
}
@ -52,8 +52,8 @@ export function activate(context: vscode.ExtensionContext) {
}
export async function deactivate() {
if (client && workspace) {
await client.leave_workspace(workspace.id());
if (client && workspaceState.workspace) {
await client.leave_workspace(workspaceState.workspace.id());
}
}

View file

@ -1,6 +1,6 @@
import * as vscode from 'vscode';
import { client, workspace_list } from './commands/client';
import { workspace } from './commands/workspaces';
import { workspaceState } from './commands/workspaces';
import { bufferMapper, colors_cache } from './mapping';
export class CodempTreeProvider implements vscode.TreeDataProvider<CodempTreeItem> {
@ -22,9 +22,9 @@ export class CodempTreeProvider implements vscode.TreeDataProvider<CodempTreeIte
if (element) {
switch (element.type) {
case Type.Workspace:
if (workspace === null) return [];
else if (element.label == workspace.id()) {
return workspace.filetree(undefined, false).map((x) =>
if (workspaceState.workspace === null) return [];
else if (element.label == workspaceState.workspace.id()) {
return workspaceState.workspace.filetree(undefined, false).map((x) =>
new CodempTreeItem(x, Type.Buffer, { active: bufferMapper.bufferToEditorMapping.has(x) })
);
} else return [];
@ -48,9 +48,9 @@ export class CodempTreeProvider implements vscode.TreeDataProvider<CodempTreeIte
return []; // empty screen with [connect] button
}
let items = workspace_list.map((x) =>
new CodempTreeItem(x, Type.Workspace, { expandable: true, active: workspace === null })
new CodempTreeItem(x, Type.Workspace, { expandable: true, active: workspaceState.workspace === null })
);
if (workspace !== null) {
if (workspaceState.workspace !== null) {
items.push(new CodempTreeItem("", Type.Placeholder, {}));
items.push(new CodempTreeItem("Users", Type.UserList, { expandable: true }));
}