feat: improved tree view

This commit is contained in:
əlemi 2024-09-07 01:11:28 +02:00
parent 045c0bddc8
commit 770758b8bf
Signed by: alemi
GPG key ID: A4895B84D311642C
4 changed files with 79 additions and 35 deletions

View file

@ -28,7 +28,7 @@
"viewsWelcome": [ "viewsWelcome": [
{ {
"view": "codemp-tree-view", "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": { "menus": {
"view/title": [ "view/title": [
{ {
"command": "codemp.connect", "command": "codemp.listWorkspaces",
"when": "view == codemp-tree-view", "when": "view == codemp-tree-view",
"group": "navigation", "group": "navigation",
"icon": "C" "icon": "C"
@ -53,12 +53,17 @@
"view/item/context": [ "view/item/context": [
{ {
"command": "codemp.join", "command": "codemp.join",
"when": "view == codemp-tree-view && viewItem.type == Workspace", "when": "view == codemp-tree-view && viewItem == workspace",
"group": "inline" "group": "inline"
}, },
{ {
"command": "codemp.attach", "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" "group": "inline"
} }
] ]
@ -69,49 +74,49 @@
"command": "codemp.connect", "command": "codemp.connect",
"title": "Connect", "title": "Connect",
"category": "codemp", "category": "codemp",
"icon": "$(extensions-refresh)" "icon": "$(debug-disconnect)"
}, },
{ {
"command": "codemp.join", "command": "codemp.join",
"title": "Join", "title": "Join",
"category": "codemp", "category": "codemp",
"icon": "$(extensions-refresh)" "icon": "$(testing-skipped-icon)"
}, },
{ {
"command": "codemp.attach", "command": "codemp.attach",
"title": "Attach", "title": "Attach",
"category": "codemp", "category": "codemp",
"icon": "$(extensions-refresh)" "icon": "$(ports-view-icon)"
}, },
{ {
"command": "codemp.createWorkspace", "command": "codemp.createWorkspace",
"title": "Create Workspace", "title": "Create Workspace",
"category": "codemp", "category": "codemp",
"icon": "$(extensions-refresh)" "icon": "$(diff-insert)"
}, },
{ {
"command": "codemp.listWorkspaces", "command": "codemp.listWorkspaces",
"title": "List Workspaces", "title": "List Workspaces",
"category": "codemp", "category": "codemp",
"icon": "$(extensions-refresh)" "icon": "$(extensions-view-icon)"
}, },
{ {
"command": "codemp.listBuffers", "command": "codemp.listBuffers",
"title": "List Buffers", "title": "List Buffers",
"category": "codemp", "category": "codemp",
"icon": "$(extensions-refresh)" "icon": "$(output-view-icon)"
}, },
{ {
"command": "codemp.createBuffer", "command": "codemp.createBuffer",
"title": "Create Buffer", "title": "Create Buffer",
"category": "codemp", "category": "codemp",
"icon": "$(extensions-refresh)" "icon": "$(diff-insert)"
}, },
{ {
"command": "codemp.disconnectBuffer", "command": "codemp.disconnectBuffer",
"title": "Disconnect Buffer", "title": "Disconnect Buffer",
"category": "codemp", "category": "codemp",
"icon": "$(extensions-refresh)" "icon": "$(testing-cancel-icon)"
}, },
{ {
"command": "codemp.sync", "command": "codemp.sync",

View file

@ -32,11 +32,19 @@ export async function connect() {
} }
export async function join() { export async function join(selected: vscode.TreeItem | undefined) {
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"
if (client === null) throw "connect first"; 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) workspace = await client.join_workspace(workspace_id)
let controller = workspace.cursor(); let controller = workspace.cursor();
controller.callback(async function (controller: codemp.CursorController) { controller.callback(async function (controller: codemp.CursorController) {
@ -82,7 +90,7 @@ export async function join() {
export async function createBuffer() { 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" if (workspace === null) throw "join a workspace first"
workspace.create(bufferName); workspace.create(bufferName);
vscode.window.showInformationMessage(`new buffer created :${bufferName}`); vscode.window.showInformationMessage(`new buffer created :${bufferName}`);
@ -90,21 +98,30 @@ export async function createBuffer() {
} }
export async function attach() { export async function attach(selected: vscode.TreeItem | undefined) {
let buffer_name: any = (await vscode.window.showInputBox({ prompt: "buffer to attach to" }))!;
if (workspace === null) throw "join a workspace first" 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); let buffer: codemp.BufferController = await workspace.attach(buffer_name);
LOGGER.info(`attached to buffer ${buffer_name}`); LOGGER.info(`attached to buffer ${buffer_name}`);
let editor = vscode.window.activeTextEditor; let editor = vscode.window.activeTextEditor;
if (editor === undefined) { if (editor === undefined) {
let fileUri = buffer_name;
let random = (Math.random() + 1).toString(36).substring(2); let random = (Math.random() + 1).toString(36).substring(2);
const fileName = '' + random; const fileName = '' + random;
const newFileUri = vscode.Uri.file(fileName).with({ scheme: 'untitled', path: "" }); const newFileUri = vscode.Uri.file(fileName).with({ scheme: 'untitled', path: "" });
await vscode.workspace.openTextDocument(newFileUri); await vscode.workspace.openTextDocument(newFileUri);
vscode.commands.executeCommand('vscode.open', 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}]`); vscode.window.showInformationMessage(`Connected to codemp workspace buffer @[${buffer_name}]`);
let file_uri: vscode.Uri = editor.document.uri; 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"; if (workspace === null) throw "join a workspace first";
let editor = vscode.window.activeTextEditor; let editor;
if (editor === undefined) throw "no active editor to sync"; let buffer_name;
let buffer_name = mapping.bufferMapper.by_editor(editor.document.uri); if (selected !== undefined && selected.label !== undefined) {
if (buffer_name === undefined) throw "No such buffer managed by codemp" if (typeof(selected.label) === 'string') {
let controller = await workspace.buffer_by_name(buffer_name); 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" if (controller === null) throw "No such buffer controller"
let content = await controller.content(); let content = await controller.content();
@ -185,7 +215,7 @@ export async function listBuffers() {
} }
export async function createWorkspace(){ export async function createWorkspace() {
if(client===null){ if(client===null){
vscode.window.showInformationMessage("Connect first"); vscode.window.showInformationMessage("Connect first");
return; return;
@ -199,7 +229,7 @@ export async function createWorkspace(){
provider.refresh(); provider.refresh();
} }
export async function listWorkspaces(){ export async function listWorkspaces() {
if(client===null){ if(client===null){
vscode.window.showInformationMessage("Connect first"); vscode.window.showInformationMessage("Connect first");
return; return;

View file

@ -33,7 +33,7 @@ export class UserDecoration {
public constructor(event: codemp.Cursor) { 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.color = colors[hash % colors.length];
this.decoration = null; this.decoration = null;
} }

View file

@ -1,5 +1,6 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { client, workspace, workspace_list } from './commands'; import { client, workspace, workspace_list } from './commands';
import { bufferMapper } from './mapping';
export class CodempTreeProvider implements vscode.TreeDataProvider<CodempTreeItem> { export class CodempTreeProvider implements vscode.TreeDataProvider<CodempTreeItem> {
@ -26,13 +27,17 @@ export class CodempTreeProvider implements vscode.TreeDataProvider<CodempTreeIte
// new CodempTreeItem("Buffers", Type.BufferContainer, true), // new CodempTreeItem("Buffers", Type.BufferContainer, true),
// new CodempTreeItem("Users", Type.UserContainer, true) // new CodempTreeItem("Users", Type.UserContainer, true)
// ]; // ];
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))
);
} else { } else {
return []; return [];
} }
case Type.BufferContainer: case Type.BufferContainer:
if (workspace === null) { return [] }; 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: case Type.UserContainer:
if (workspace === null) { return [] }; if (workspace === null) { return [] };
return [new CodempTreeItem("TODO", Type.User, false)]; // TODO keep track of users return [new CodempTreeItem("TODO", Type.User, false)]; // TODO keep track of users
@ -43,20 +48,24 @@ export class CodempTreeProvider implements vscode.TreeDataProvider<CodempTreeIte
} }
} else { } else {
if(client === null) return []; if(client === null) return [];
return workspace_list.map((x) => 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 { class CodempTreeItem extends vscode.TreeItem {
type: Type; 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; let state = expandable ? vscode.TreeItemCollapsibleState.Expanded : vscode.TreeItemCollapsibleState.None;
console.log(type.toString()); console.log(type.toString());
super(label, state); super(label, state);
this.type = type; this.type = type;
this.contextValue = 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");
} }
} }