feat: tree for workspaces and buffers

This commit is contained in:
frelodev 2024-09-06 18:45:25 +02:00
parent d302a6be68
commit d66900710d
4 changed files with 119 additions and 10 deletions

View file

@ -16,6 +16,25 @@
], ],
"main": "./out/extension.js", "main": "./out/extension.js",
"contributes": { "contributes": {
"viewsContainers": {
"activitybar": [
{
"id": "codemp-tree-container",
"title": "codemp",
"icon": "resources/codemp.svg"
}
]
},
"views": {
"codemp-tree-container": [
{
"id": "codemp-tree-view",
"name": "tree"
}
]
},
"commands": [ "commands": [
{ {
"command": "codemp.connect", "command": "codemp.connect",

View file

@ -1,13 +1,16 @@
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 { LOGGER } from './extension'; import { LOGGER, provider } from './extension';
let CACHE = new codemp.OpCache(); // TODO this "global state" should probably live elsewher but we need lo update it from these commands
let client: codemp.Client | null = null; export let client: codemp.Client | null = null;
let workspace: codemp.Workspace | null = null; export let workspace: codemp.Workspace | null = null;
let mine : boolean; export let workspace_list: string[] = [];
let CACHE = new codemp.OpCache(); // TODO do we still need this after "mine" flag?
export async function connect() { export async function connect() {
let config = vscode.workspace.getConfiguration('codemp'); let config = vscode.workspace.getConfiguration('codemp');
@ -22,8 +25,10 @@ export async function connect() {
if (!password) { if (!password) {
return vscode.window.showErrorMessage("missing password in settings: configure it first!"); return vscode.window.showErrorMessage("missing password in settings: configure it first!");
} }
vscode.window.showInformationMessage("Connected to codemp");
client = await codemp.connect(server, username, password); client = await codemp.connect(server, username, password);
provider.refresh();
listWorkspaces(); // dont await, run in background
} }
@ -72,6 +77,7 @@ export async function join() {
await controller.send(cursor); await controller.send(cursor);
}); });
vscode.window.showInformationMessage("Connected to workspace"); vscode.window.showInformationMessage("Connected to workspace");
provider.refresh();
} }
@ -80,6 +86,7 @@ export async function createBuffer() {
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}`);
provider.refresh();
} }
@ -114,6 +121,7 @@ export async function attach() {
editBuilder editBuilder
.replace(range, bufferContent) .replace(range, bufferContent)
}); });
let mine = false; // this toggles off send callback while we're updating the buffer TODO does it work? is it reliable?
vscode.workspace.onDidChangeTextDocument(async (event: vscode.TextDocumentChangeEvent) => { vscode.workspace.onDidChangeTextDocument(async (event: vscode.TextDocumentChangeEvent) => {
if(mine) { return } if(mine) { return }
if (event.document.uri !== file_uri) return; // ? if (event.document.uri !== file_uri) return; // ?
@ -147,7 +155,6 @@ export async function attach() {
} }
}); });
} }
export async function sync() { export async function sync() {
@ -173,7 +180,8 @@ export async function sync() {
export async function listBuffers() { export async function listBuffers() {
if (workspace === null) throw "join a workspace first" if (workspace === null) throw "join a workspace first"
let buffers = workspace.filetree(); let buffers = workspace.filetree();
vscode.window.showInformationMessage(buffers.join("\n")) vscode.window.showInformationMessage(buffers.join("\n"));
provider.refresh();
} }
@ -188,6 +196,7 @@ export async function createWorkspace(){
return; return;
} }
await client.create_workspace(workspace_id); await client.create_workspace(workspace_id);
provider.refresh();
} }
export async function listWorkspaces(){ export async function listWorkspaces(){
@ -195,8 +204,8 @@ export async function listWorkspaces(){
vscode.window.showInformationMessage("Connect first"); vscode.window.showInformationMessage("Connect first");
return; return;
} }
let result = await client.list_workspaces(true, true); workspace_list = await client.list_workspaces(true, true);
vscode.window.showInformationMessage(result.join("\n")) provider.refresh();
} }

View file

@ -1,6 +1,9 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as codemp from 'codemp'; import * as codemp from 'codemp';
import * as commands from './commands'; import * as commands from './commands';
import { CodempTreeProvider } from './tree';
export let provider = new CodempTreeProvider();
export let LOGGER = vscode.window.createOutputChannel("codemp", { log: true }); export let LOGGER = vscode.window.createOutputChannel("codemp", { log: true });
@ -8,6 +11,8 @@ export let LOGGER = vscode.window.createOutputChannel("codemp", { log: true });
export function activate(context: vscode.ExtensionContext) { export function activate(context: vscode.ExtensionContext) {
// start codemp log poller // start codemp log poller
log_poller_task(new codemp.JsLogger()); // don't await it! run it in background forever log_poller_task(new codemp.JsLogger()); // don't await it! run it in background forever
let sub = vscode.window.registerTreeDataProvider('codemp-tree-view', provider);
context.subscriptions.push(sub);
// register commands: the commandId parameter must match the command field in package.json // register commands: the commandId parameter must match the command field in package.json
for (let cmd of [ for (let cmd of [

76
src/tree.ts Normal file
View file

@ -0,0 +1,76 @@
import * as vscode from 'vscode';
import * as codemp from 'codemp';
import { client, workspace, workspace_list } from './commands';
export class CodempTreeProvider implements vscode.TreeDataProvider<CodempTreeItem> {
constructor() {}
private _emitter: vscode.EventEmitter<CodempTreeItem | undefined | null | void> = new vscode.EventEmitter<CodempTreeItem | undefined | null | void>();
readonly onDidChangeTreeData: vscode.Event<CodempTreeItem | undefined | null | void> = this._emitter.event;
refresh(): void {
this._emitter.fire();
}
getTreeItem(element: CodempTreeItem): vscode.TreeItem {
return element;
}
async getChildren(element?: CodempTreeItem): Promise<CodempTreeItem[]> {
if (element) {
switch (element.type) {
case Type.Root:
if (client === null) { return [] };
return workspace_list.map((x) => new CodempTreeItem(x, Type.Workspace));
case Type.Workspace:
if (workspace === null) { return [] };
if (element.label == workspace.id()) {
return [
new CodempTreeItem("Buffers", Type.BufferContainer),
new CodempTreeItem("Users", Type.UserContainer)
];
} else {
return [];
}
case Type.BufferContainer:
if (workspace === null) { return [] };
return workspace.filetree().map((x) => new CodempTreeItem(x, Type.Buffer));
case Type.UserContainer:
if (workspace === null) { return [] };
return [new CodempTreeItem("TODO", Type.User)]; // TODO keep track of users
case Type.Buffer:
return [];
case Type.User:
return [];
}
} else {
if(client === null) {
return [
new CodempTreeItem("Connect", Type.Root)
];
}
return [
new CodempTreeItem("Codemp", Type.Root)
];
}
}
}
class CodempTreeItem extends vscode.TreeItem {
type: Type;
constructor(label: string | vscode.TreeItemLabel, type: Type){
super(label, vscode.TreeItemCollapsibleState.Expanded);
this.type=type;
}
}
enum Type{
Root,
Workspace,
BufferContainer,
UserContainer,
Buffer,
User,
}