From 770758b8bfb92c119212d8762bf8bc146aaed627 Mon Sep 17 00:00:00 2001 From: alemi Date: Sat, 7 Sep 2024 01:11:28 +0200 Subject: [PATCH] feat: improved tree view --- package.json | 29 ++++++++++++---------- src/commands.ts | 64 ++++++++++++++++++++++++++++++++++++------------- src/mapping.ts | 2 +- src/tree.ts | 19 +++++++++++---- 4 files changed, 79 insertions(+), 35 deletions(-) diff --git a/package.json b/package.json index a604df9..65a856a 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "viewsWelcome": [ { "view": "codemp-tree-view", - "contents": "[codemp](https://codemp.dev) -- code multiplexer\n[Connect](command:codemp.connect)" + "contents": "codemp -- [code multiplexer](https://codemp.dev)\n[Connect](command:codemp.connect)" } ], @@ -44,7 +44,7 @@ "menus": { "view/title": [ { - "command": "codemp.connect", + "command": "codemp.listWorkspaces", "when": "view == codemp-tree-view", "group": "navigation", "icon": "C" @@ -53,12 +53,17 @@ "view/item/context": [ { "command": "codemp.join", - "when": "view == codemp-tree-view && viewItem.type == Workspace", + "when": "view == codemp-tree-view && viewItem == workspace", "group": "inline" }, { "command": "codemp.attach", - "when": "view == codemp-tree-view && viewItem.type == Buffer", + "when": "view == codemp-tree-view && viewItem == buffer", + "group": "inline" + }, + { + "command": "codemp.sync", + "when": "view == codemp-tree-view && viewItem == buffer_active", "group": "inline" } ] @@ -69,49 +74,49 @@ "command": "codemp.connect", "title": "Connect", "category": "codemp", - "icon": "$(extensions-refresh)" + "icon": "$(debug-disconnect)" }, { "command": "codemp.join", "title": "Join", "category": "codemp", - "icon": "$(extensions-refresh)" + "icon": "$(testing-skipped-icon)" }, { "command": "codemp.attach", "title": "Attach", "category": "codemp", - "icon": "$(extensions-refresh)" + "icon": "$(ports-view-icon)" }, { "command": "codemp.createWorkspace", "title": "Create Workspace", "category": "codemp", - "icon": "$(extensions-refresh)" + "icon": "$(diff-insert)" }, { "command": "codemp.listWorkspaces", "title": "List Workspaces", "category": "codemp", - "icon": "$(extensions-refresh)" + "icon": "$(extensions-view-icon)" }, { "command": "codemp.listBuffers", "title": "List Buffers", "category": "codemp", - "icon": "$(extensions-refresh)" + "icon": "$(output-view-icon)" }, { "command": "codemp.createBuffer", "title": "Create Buffer", "category": "codemp", - "icon": "$(extensions-refresh)" + "icon": "$(diff-insert)" }, { "command": "codemp.disconnectBuffer", "title": "Disconnect Buffer", "category": "codemp", - "icon": "$(extensions-refresh)" + "icon": "$(testing-cancel-icon)" }, { "command": "codemp.sync", diff --git a/src/commands.ts b/src/commands.ts index fa676a6..596082f 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -32,11 +32,19 @@ export async function connect() { } -export async function join() { - let workspace_id = await vscode.window.showInputBox({ prompt: "workspace to attach (default to default)" }); - if (workspace_id === undefined) return // user cancelled with ESC - if (workspace_id.length == 0) workspace_id = "diamond" +export async function join(selected: vscode.TreeItem | undefined) { if (client === null) throw "connect first"; + let workspace_id: string | undefined; + if (selected !== undefined && selected.label !== undefined) { + if (typeof(selected.label) === 'string') { + workspace_id = selected.label; + } else { + workspace_id = selected.label.label; // TODO ughh what is this api? + } + } else { + workspace_id = await vscode.window.showInputBox({ prompt: "name of workspace to attach to" }); + } + if (!workspace_id) return; // user cancelled with ESC workspace = await client.join_workspace(workspace_id) let controller = workspace.cursor(); controller.callback(async function (controller: codemp.CursorController) { @@ -82,7 +90,7 @@ export async function join() { export async function createBuffer() { - let bufferName: any = (await vscode.window.showInputBox({ prompt: "path of the buffer to create" }))!; + let bufferName: any = (await vscode.window.showInputBox({ prompt: "path of the buffer to create" })); if (workspace === null) throw "join a workspace first" workspace.create(bufferName); vscode.window.showInformationMessage(`new buffer created :${bufferName}`); @@ -90,21 +98,30 @@ export async function createBuffer() { } -export async function attach() { - let buffer_name: any = (await vscode.window.showInputBox({ prompt: "buffer to attach to" }))!; +export async function attach(selected: vscode.TreeItem | undefined) { if (workspace === null) throw "join a workspace first" + 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; // action cancelled by user let buffer: codemp.BufferController = await workspace.attach(buffer_name); LOGGER.info(`attached to buffer ${buffer_name}`); let editor = vscode.window.activeTextEditor; if (editor === undefined) { - let fileUri = buffer_name; let random = (Math.random() + 1).toString(36).substring(2); const fileName = '' + random; const newFileUri = vscode.Uri.file(fileName).with({ scheme: 'untitled', path: "" }); await vscode.workspace.openTextDocument(newFileUri); vscode.commands.executeCommand('vscode.open', newFileUri); + editor = vscode.window.activeTextEditor!; } - editor = vscode.window.activeTextEditor!; vscode.window.showInformationMessage(`Connected to codemp workspace buffer @[${buffer_name}]`); let file_uri: vscode.Uri = editor.document.uri; @@ -155,15 +172,28 @@ export async function attach() { } }); + provider.refresh(); } -export async function sync() { +export async function sync(selected: vscode.TreeItem | undefined) { if (workspace === null) throw "join a workspace first"; - let editor = vscode.window.activeTextEditor; - if (editor === undefined) throw "no active editor to sync"; - let buffer_name = mapping.bufferMapper.by_editor(editor.document.uri); - if (buffer_name === undefined) throw "No such buffer managed by codemp" - let controller = await workspace.buffer_by_name(buffer_name); + let editor; + let buffer_name; + 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? + } + editor = mapping.bufferMapper.by_buffer(buffer_name); + if (editor === undefined) throw "no active editor to sync"; + } else { + editor = vscode.window.activeTextEditor; + if (editor === undefined) throw "no active editor to sync"; + buffer_name = mapping.bufferMapper.by_editor(editor.document.uri); + if (buffer_name === undefined) throw "No such buffer managed by codemp" + } + let controller = workspace.buffer_by_name(buffer_name); if (controller === null) throw "No such buffer controller" let content = await controller.content(); @@ -185,7 +215,7 @@ export async function listBuffers() { } -export async function createWorkspace(){ +export async function createWorkspace() { if(client===null){ vscode.window.showInformationMessage("Connect first"); return; @@ -199,7 +229,7 @@ export async function createWorkspace(){ provider.refresh(); } -export async function listWorkspaces(){ +export async function listWorkspaces() { if(client===null){ vscode.window.showInformationMessage("Connect first"); return; diff --git a/src/mapping.ts b/src/mapping.ts index 279e2a7..adddba2 100644 --- a/src/mapping.ts +++ b/src/mapping.ts @@ -33,7 +33,7 @@ export class UserDecoration { public constructor(event: codemp.Cursor) { - let hash = codemp.hash(event.user!); + let hash = codemp.hash(event.user || "anon"); this.color = colors[hash % colors.length]; this.decoration = null; } diff --git a/src/tree.ts b/src/tree.ts index 97f0e09..d29b84f 100644 --- a/src/tree.ts +++ b/src/tree.ts @@ -1,5 +1,6 @@ import * as vscode from 'vscode'; import { client, workspace, workspace_list } from './commands'; +import { bufferMapper } from './mapping'; export class CodempTreeProvider implements vscode.TreeDataProvider { @@ -26,13 +27,17 @@ export class CodempTreeProvider implements vscode.TreeDataProvider new CodempTreeItem(x, Type.Buffer, false)); + return workspace.filetree().map((x) => + new CodempTreeItem(x, Type.Buffer, false, bufferMapper.bufferToEditorMapping.has(x)) + ); } else { return []; } case Type.BufferContainer: if (workspace === null) { return [] }; - return workspace.filetree().map((x) => new CodempTreeItem(x, Type.Buffer, false)); + return workspace.filetree().map((x) => + new CodempTreeItem(x, Type.Buffer, false, bufferMapper.bufferToEditorMapping.has(x)) + ); case Type.UserContainer: if (workspace === null) { return [] }; return [new CodempTreeItem("TODO", Type.User, false)]; // TODO keep track of users @@ -43,20 +48,24 @@ export class CodempTreeProvider implements vscode.TreeDataProvider new CodempTreeItem(x, Type.Workspace, true)); + return workspace_list.map((x) => + new CodempTreeItem(x, Type.Workspace, true, workspace !== null && workspace.id() == x) + ); } - } } class CodempTreeItem extends vscode.TreeItem { type: Type; - constructor(label: string | vscode.TreeItemLabel, type: Type, expandable: boolean){ + constructor(label: string | vscode.TreeItemLabel, type: Type, expandable: boolean, active?: boolean){ let state = expandable ? vscode.TreeItemCollapsibleState.Expanded : vscode.TreeItemCollapsibleState.None; console.log(type.toString()); super(label, state); this.type = type; this.contextValue = type; + if (active) this.contextValue += "_active"; + if (type === Type.Workspace) this.iconPath = new vscode.ThemeIcon(active ? "timeline-pin" : "extensions-remote"); + else if (type === Type.Buffer) this.iconPath = new vscode.ThemeIcon(active ? "debug-restart-frame" : "debug-console-clear-all"); } }