mirror of
https://github.com/hexedtech/codemp-vscode.git
synced 2024-11-22 15:34:49 +01:00
chore: refactor
This commit is contained in:
parent
777f8bb0b2
commit
9f44b9ef61
6 changed files with 339 additions and 293 deletions
|
@ -1,134 +1,14 @@
|
||||||
|
|
||||||
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, provider } from './extension';
|
import {client} from "./client"
|
||||||
|
import {workspace} from "./workspaces";
|
||||||
|
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: codemp.Workspace | null = null;
|
|
||||||
export let workspace_list: string[] = [];
|
|
||||||
let locks : Map<string, boolean> = new Map();
|
let locks : Map<string, boolean> = new Map();
|
||||||
|
|
||||||
export async function connect() {
|
|
||||||
let config = vscode.workspace.getConfiguration('codemp');
|
|
||||||
|
|
||||||
let username = config.get<string>("username");
|
|
||||||
if (!username) {
|
|
||||||
return vscode.window.showErrorMessage("missing username in settings: configure it first!");
|
|
||||||
}
|
|
||||||
|
|
||||||
let password = config.get<string>("password");
|
|
||||||
if (!password) {
|
|
||||||
return vscode.window.showErrorMessage("missing password in settings: configure it first!");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
client = await codemp.connect({
|
|
||||||
username: username,
|
|
||||||
password: password,
|
|
||||||
host: config.get<string>("server"),
|
|
||||||
port: config.get<number>("port"),
|
|
||||||
tls: config.get<boolean>("tls"),
|
|
||||||
});
|
|
||||||
vscode.window.showInformationMessage("Connected to codemp");
|
|
||||||
provider.refresh();
|
|
||||||
listWorkspaces(); // dont await, run in background
|
|
||||||
} catch (e) {
|
|
||||||
vscode.window.showErrorMessage("could not connect: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function join(selected: vscode.TreeItem | undefined) {
|
|
||||||
if (client === null) return vscode.window.showWarningMessage("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
|
|
||||||
if(vscode.workspace.workspaceFolders === undefined) {
|
|
||||||
vscode.window.showErrorMessage("Open a Workspace folder first");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
workspace = await client.join_workspace(workspace_id)
|
|
||||||
let controller = workspace.cursor();
|
|
||||||
controller.callback(async function (controller: codemp.CursorController) {
|
|
||||||
while (true) {
|
|
||||||
let event = await controller.try_recv();
|
|
||||||
if (event === null) break;
|
|
||||||
if (event.user === undefined) {
|
|
||||||
LOGGER.warn(`Skipping cursor event without user: ${event}`)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let mapp = mapping.colors_cache.get(event.user);
|
|
||||||
if (mapp === undefined) { // first time we see this user
|
|
||||||
mapp = new mapping.UserDecoration(event.user);
|
|
||||||
mapping.colors_cache.set(event.user, mapp);
|
|
||||||
provider.refresh();
|
|
||||||
}
|
|
||||||
let editor = mapping.bufferMapper.visible_by_buffer(event.buffer);
|
|
||||||
let refresh = event.buffer != mapp.buffer;
|
|
||||||
mapp.update(event, editor);
|
|
||||||
if (refresh) provider.refresh();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
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]
|
|
||||||
let buffer = mapping.bufferMapper.by_editor(buf)
|
|
||||||
if (buffer === undefined) return;
|
|
||||||
let cursor: codemp.Cursor = {
|
|
||||||
startRow: selection.anchor.line,
|
|
||||||
startCol: selection.anchor.character,
|
|
||||||
endRow: selection.active.line,
|
|
||||||
endCol: selection.active.character + 1,
|
|
||||||
buffer: buffer,
|
|
||||||
user: undefined,
|
|
||||||
}
|
|
||||||
await controller.send(cursor);
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO waiting for https://github.com/hexedtech/codemp/pull/19 to reach npm
|
|
||||||
// let event_handler = async () => {
|
|
||||||
// try {
|
|
||||||
// while (true) {
|
|
||||||
// if (workspace === null) break;
|
|
||||||
// let event = await workspace.event();
|
|
||||||
// if (event.type == "leave") {
|
|
||||||
// mapping.colors_cache.get(event.value)?.clear()
|
|
||||||
// mapping.colors_cache.delete(event.value);
|
|
||||||
// }
|
|
||||||
// if (event.type == "join") {
|
|
||||||
// mapping.colors_cache.set(event.value, new mapping.UserDecoration(event.value));
|
|
||||||
// }
|
|
||||||
// provider.refresh();
|
|
||||||
// }
|
|
||||||
// } catch (e) {
|
|
||||||
// console.log(`stopping event handler for workspace: ${e}`);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// event_handler();
|
|
||||||
|
|
||||||
vscode.window.showInformationMessage("Connected to workspace");
|
|
||||||
provider.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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");
|
|
||||||
workspace.create(bufferName);
|
|
||||||
vscode.window.showInformationMessage(`new buffer created :${bufferName}`);
|
|
||||||
provider.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function apply_changes_to_buffer(path: string, controller: codemp.BufferController | undefined | null, force?: boolean) {
|
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 (workspace === null) throw "can't apply changes while not in a workspace";
|
||||||
|
@ -162,80 +42,6 @@ export async function apply_changes_to_buffer(path: string, controller: codemp.B
|
||||||
locks.set(path, false);
|
locks.set(path, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function share(selected: vscode.TreeItem | undefined) {
|
|
||||||
if (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') {
|
|
||||||
buffer_name = selected.label;
|
|
||||||
} else {
|
|
||||||
buffer_name = selected.label.label; // TODO ughh what is this api?
|
|
||||||
}
|
|
||||||
} else if (vscode.window.activeTextEditor !== null) {
|
|
||||||
buffer_name = vscode.window.activeTextEditor?.document.uri.toString();
|
|
||||||
} else {
|
|
||||||
buffer_name = await vscode.window.showInputBox({ prompt: "path of buffer to attach to" });
|
|
||||||
}
|
|
||||||
if (!buffer_name) return; // action cancelled by user
|
|
||||||
if (mapping.bufferMapper.uri_by_buffer(buffer_name) !== undefined) {
|
|
||||||
return vscode.window.showWarningMessage("buffer already attached");
|
|
||||||
}
|
|
||||||
if (vscode.workspace.workspaceFolders === undefined) {
|
|
||||||
throw "no active vscode workspace";
|
|
||||||
}
|
|
||||||
let cwd = vscode.workspace.workspaceFolders[0].uri; // TODO picking the first one is a bit arbitrary
|
|
||||||
let path = vscode.Uri.file(cwd.path + '/' + buffer_name);
|
|
||||||
try {
|
|
||||||
await vscode.workspace.fs.stat(path);
|
|
||||||
} catch {
|
|
||||||
path = path.with({ scheme: 'untitled' });
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
//wait for server changes
|
|
||||||
// TODO poll never unblocks
|
|
||||||
let done = false;
|
|
||||||
buffer.poll().then(() => done = true);
|
|
||||||
for(let i=0; i< 20; i++){
|
|
||||||
if(done) break;
|
|
||||||
await new Promise(r => setTimeout(r,100))
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGGER.info(`attached to buffer ${buffer_name}`);
|
|
||||||
let file_uri: vscode.Uri = editor.document.uri;
|
|
||||||
mapping.bufferMapper.register(buffer.get_path(), file_uri);
|
|
||||||
let bufferContent = await buffer.content();
|
|
||||||
let doc_text = editor.document.getText();
|
|
||||||
|
|
||||||
if (doc_text != bufferContent) {
|
|
||||||
await buffer.send({
|
|
||||||
start: 0, end: bufferContent.length,
|
|
||||||
content: doc_text,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
console.log(event.contentChanges);
|
|
||||||
LOGGER.debug(`onDidChangeTextDocument(event: [${change.rangeOffset}, ${change.text}, ${change.rangeOffset + change.rangeLength}])`);
|
|
||||||
await buffer.send({
|
|
||||||
start: change.rangeOffset,
|
|
||||||
end: change.rangeOffset + change.rangeLength,
|
|
||||||
content: change.text
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
buffer.callback(async (controller: codemp.BufferController) =>
|
|
||||||
await apply_changes_to_buffer(controller.get_path(), controller)
|
|
||||||
);
|
|
||||||
provider.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export async function attach(selected: vscode.TreeItem | undefined) {
|
export async function attach(selected: vscode.TreeItem | undefined) {
|
||||||
if (workspace === null) return vscode.window.showWarningMessage("Join a workspace first");
|
if (workspace === null) return vscode.window.showWarningMessage("Join a workspace first");
|
||||||
let buffer_name: string | undefined;
|
let buffer_name: string | undefined;
|
||||||
|
@ -311,6 +117,80 @@ export async function attach(selected: vscode.TreeItem | undefined) {
|
||||||
provider.refresh();
|
provider.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export async function share(selected: vscode.TreeItem | undefined) {
|
||||||
|
if (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') {
|
||||||
|
buffer_name = selected.label;
|
||||||
|
} else {
|
||||||
|
buffer_name = selected.label.label; // TODO ughh what is this api?
|
||||||
|
}
|
||||||
|
} else if (vscode.window.activeTextEditor !== null) {
|
||||||
|
buffer_name = vscode.window.activeTextEditor?.document.uri.toString();
|
||||||
|
} else {
|
||||||
|
buffer_name = await vscode.window.showInputBox({ prompt: "path of buffer to attach to" });
|
||||||
|
}
|
||||||
|
if (!buffer_name) return; // action cancelled by user
|
||||||
|
if (mapping.bufferMapper.uri_by_buffer(buffer_name) !== undefined) {
|
||||||
|
return vscode.window.showWarningMessage("buffer already attached");
|
||||||
|
}
|
||||||
|
if (vscode.workspace.workspaceFolders === undefined) {
|
||||||
|
throw "no active vscode workspace";
|
||||||
|
}
|
||||||
|
let cwd = vscode.workspace.workspaceFolders[0].uri; // TODO picking the first one is a bit arbitrary
|
||||||
|
let path = vscode.Uri.file(cwd.path + '/' + buffer_name);
|
||||||
|
try {
|
||||||
|
await vscode.workspace.fs.stat(path);
|
||||||
|
} catch {
|
||||||
|
path = path.with({ scheme: 'untitled' });
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
//wait for server changes
|
||||||
|
// TODO poll never unblocks
|
||||||
|
let done = false;
|
||||||
|
buffer.poll().then(() => done = true);
|
||||||
|
for(let i=0; i< 20; i++){
|
||||||
|
if(done) break;
|
||||||
|
await new Promise(r => setTimeout(r,100))
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.info(`attached to buffer ${buffer_name}`);
|
||||||
|
let file_uri: vscode.Uri = editor.document.uri;
|
||||||
|
mapping.bufferMapper.register(buffer.get_path(), file_uri);
|
||||||
|
let bufferContent = await buffer.content();
|
||||||
|
let doc_text = editor.document.getText();
|
||||||
|
|
||||||
|
if (doc_text != bufferContent) {
|
||||||
|
await buffer.send({
|
||||||
|
start: 0, end: bufferContent.length,
|
||||||
|
content: doc_text,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
console.log(event.contentChanges);
|
||||||
|
LOGGER.debug(`onDidChangeTextDocument(event: [${change.rangeOffset}, ${change.text}, ${change.rangeOffset + change.rangeLength}])`);
|
||||||
|
await buffer.send({
|
||||||
|
start: change.rangeOffset,
|
||||||
|
end: change.rangeOffset + change.rangeLength,
|
||||||
|
content: change.text
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
buffer.callback(async (controller: codemp.BufferController) =>
|
||||||
|
await apply_changes_to_buffer(controller.get_path(), controller)
|
||||||
|
);
|
||||||
|
provider.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
export async function sync(selected: vscode.TreeItem | undefined) {
|
export async function sync(selected: vscode.TreeItem | undefined) {
|
||||||
if (workspace === null) return vscode.window.showWarningMessage("Join a workspace first");
|
if (workspace === null) return vscode.window.showWarningMessage("Join a workspace first");
|
||||||
let editor;
|
let editor;
|
||||||
|
@ -344,77 +224,3 @@ export async function sync(selected: vscode.TreeItem | undefined) {
|
||||||
|
|
||||||
locks.set(buffer_name, false);
|
locks.set(buffer_name, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function listBuffers() {
|
|
||||||
if (workspace === null) return vscode.window.showWarningMessage("Join a workspace first");
|
|
||||||
let buffers = workspace.filetree(undefined, false);
|
|
||||||
vscode.window.showInformationMessage(buffers.join("\n"));
|
|
||||||
provider.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export async function createWorkspace() {
|
|
||||||
if (client === null) return vscode.window.showWarningMessage("Connect first");
|
|
||||||
let workspace_id = await vscode.window.showInputBox({ prompt: "Enter name for workspace" });
|
|
||||||
if (workspace_id === undefined) return;
|
|
||||||
await client.create_workspace(workspace_id);
|
|
||||||
vscode.window.showInformationMessage("Created new workspace " + workspace_id);
|
|
||||||
provider.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function inviteToWorkspace() {
|
|
||||||
if (client === null) return vscode.window.showWarningMessage("Connect first");
|
|
||||||
let workspace_id = await vscode.window.showInputBox({ prompt: "Enter name of the workspace you want to invite the user into" });
|
|
||||||
if (workspace_id === undefined) return;
|
|
||||||
let user_id = await vscode.window.showInputBox({ prompt: "Enter name of the user you want to invite" });
|
|
||||||
if (user_id === undefined) return;
|
|
||||||
await client.invite_to_workspace(workspace_id,user_id);
|
|
||||||
vscode.window.showInformationMessage("Invited " + user_id + "into workspace " + workspace_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function listWorkspaces() {
|
|
||||||
if (client === null) return vscode.window.showWarningMessage("Connect first");
|
|
||||||
workspace_list = await client.list_workspaces(true, true);
|
|
||||||
provider.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function leaveWorkspace() {
|
|
||||||
if (client === null) return vscode.window.showWarningMessage("Connect first");
|
|
||||||
let workspace_id = await vscode.window.showInputBox({ prompt: "Enter name for workspace you want to leave" });
|
|
||||||
if (workspace_id === undefined) return;
|
|
||||||
await client.leave_workspace(workspace_id);
|
|
||||||
vscode.window.showInformationMessage("Left workspace " + workspace_id);
|
|
||||||
provider.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function refresh() {
|
|
||||||
if (client === null) return vscode.window.showWarningMessage("Connect first");
|
|
||||||
await client.refresh();
|
|
||||||
vscode.window.showInformationMessage("Refreshed Session token");
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function jump(selected: vscode.TreeItem | undefined){
|
|
||||||
if (client === null) return vscode.window.showWarningMessage("Connect first");
|
|
||||||
let user;
|
|
||||||
if (selected !== undefined && selected.label !== undefined) {
|
|
||||||
if (typeof(selected.label) === 'string') {
|
|
||||||
user = selected.label;
|
|
||||||
} else {
|
|
||||||
user = selected.label.label;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!user) user = await vscode.window.showInputBox({ prompt: "username"});
|
|
||||||
if (!user) return; // user cancelled with ESC
|
|
||||||
|
|
||||||
let user_hl = mapping.colors_cache.get(user);
|
|
||||||
if (user_hl === undefined) return vscode.window.showWarningMessage("unknown position of such user");
|
|
||||||
let uri = mapping.bufferMapper.uri_by_buffer(user_hl.buffer);
|
|
||||||
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 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);
|
|
||||||
}
|
|
||||||
|
|
175
src/commands/client.ts
Normal file
175
src/commands/client.ts
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
import * as vscode from 'vscode';
|
||||||
|
import * as codemp from 'codemp';
|
||||||
|
import * as mapping from "../mapping";
|
||||||
|
import {workspace,setWorkspace} from "./workspaces";
|
||||||
|
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 async function connect() {
|
||||||
|
let config = vscode.workspace.getConfiguration('codemp');
|
||||||
|
|
||||||
|
let username = config.get<string>("username");
|
||||||
|
if (!username) {
|
||||||
|
return vscode.window.showErrorMessage("missing username in settings: configure it first!");
|
||||||
|
}
|
||||||
|
|
||||||
|
let password = config.get<string>("password");
|
||||||
|
if (!password) {
|
||||||
|
return vscode.window.showErrorMessage("missing password in settings: configure it first!");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await codemp.connect({
|
||||||
|
username: username,
|
||||||
|
password: password,
|
||||||
|
host: config.get<string>("server"),
|
||||||
|
port: config.get<number>("port"),
|
||||||
|
tls: config.get<boolean>("tls"),
|
||||||
|
});
|
||||||
|
vscode.window.showInformationMessage("Connected to codemp");
|
||||||
|
provider.refresh();
|
||||||
|
listWorkspaces(); // dont await, run in background
|
||||||
|
} catch (e) {
|
||||||
|
vscode.window.showErrorMessage("could not connect: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function join(selected: vscode.TreeItem | undefined) {
|
||||||
|
if (client === null) return vscode.window.showWarningMessage("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
|
||||||
|
if(vscode.workspace.workspaceFolders === undefined) {
|
||||||
|
vscode.window.showErrorMessage("Open a Workspace folder first");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setWorkspace(await client.join_workspace(workspace_id));
|
||||||
|
if(!workspace) return;
|
||||||
|
let controller = workspace.cursor();
|
||||||
|
controller.callback(async function (controller: codemp.CursorController) {
|
||||||
|
while (true) {
|
||||||
|
let event = await controller.try_recv();
|
||||||
|
if (event === null) break;
|
||||||
|
if (event.user === undefined) {
|
||||||
|
LOGGER.warn(`Skipping cursor event without user: ${event}`)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let mapp = mapping.colors_cache.get(event.user);
|
||||||
|
if (mapp === undefined) { // first time we see this user
|
||||||
|
mapp = new mapping.UserDecoration(event.user);
|
||||||
|
mapping.colors_cache.set(event.user, mapp);
|
||||||
|
provider.refresh();
|
||||||
|
}
|
||||||
|
let editor = mapping.bufferMapper.visible_by_buffer(event.buffer);
|
||||||
|
let refresh = event.buffer != mapp.buffer;
|
||||||
|
mapp.update(event, editor);
|
||||||
|
if (refresh) provider.refresh();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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]
|
||||||
|
let buffer = mapping.bufferMapper.by_editor(buf)
|
||||||
|
if (buffer === undefined) return;
|
||||||
|
let cursor: codemp.Cursor = {
|
||||||
|
startRow: selection.anchor.line,
|
||||||
|
startCol: selection.anchor.character,
|
||||||
|
endRow: selection.active.line,
|
||||||
|
endCol: selection.active.character + 1,
|
||||||
|
buffer: buffer,
|
||||||
|
user: undefined,
|
||||||
|
}
|
||||||
|
await controller.send(cursor);
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO waiting for https://github.com/hexedtech/codemp/pull/19 to reach npm
|
||||||
|
// let event_handler = async () => {
|
||||||
|
// try {
|
||||||
|
// while (true) {
|
||||||
|
// if (workspace === null) break;
|
||||||
|
// let event = await workspace.event();
|
||||||
|
// if (event.type == "leave") {
|
||||||
|
// mapping.colors_cache.get(event.value)?.clear()
|
||||||
|
// mapping.colors_cache.delete(event.value);
|
||||||
|
// }
|
||||||
|
// if (event.type == "join") {
|
||||||
|
// mapping.colors_cache.set(event.value, new mapping.UserDecoration(event.value));
|
||||||
|
// }
|
||||||
|
// provider.refresh();
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// console.log(`stopping event handler for workspace: ${e}`);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// event_handler();
|
||||||
|
|
||||||
|
vscode.window.showInformationMessage("Connected to workspace");
|
||||||
|
provider.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export async function listWorkspaces() {
|
||||||
|
if (client === null) return vscode.window.showWarningMessage("Connect first");
|
||||||
|
workspace_list = await client.list_workspaces(true, true);
|
||||||
|
provider.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export async function createWorkspace() {
|
||||||
|
if (client === null) return vscode.window.showWarningMessage("Connect first");
|
||||||
|
let workspace_id = await vscode.window.showInputBox({ prompt: "Enter name for workspace" });
|
||||||
|
if (workspace_id === undefined) return;
|
||||||
|
await client.create_workspace(workspace_id);
|
||||||
|
vscode.window.showInformationMessage("Created new workspace " + workspace_id);
|
||||||
|
provider.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function inviteToWorkspace() {
|
||||||
|
if (client === null) return vscode.window.showWarningMessage("Connect first");
|
||||||
|
let workspace_id = await vscode.window.showInputBox({ prompt: "Enter name of the workspace you want to invite the user into" });
|
||||||
|
if (workspace_id === undefined) return;
|
||||||
|
let user_id = await vscode.window.showInputBox({ prompt: "Enter name of the user you want to invite" });
|
||||||
|
if (user_id === undefined) return;
|
||||||
|
await client.invite_to_workspace(workspace_id,user_id);
|
||||||
|
vscode.window.showInformationMessage("Invited " + user_id + "into workspace " + workspace_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function leaveWorkspace() {
|
||||||
|
if (client === null) return vscode.window.showWarningMessage("Connect first");
|
||||||
|
let workspace_id = await vscode.window.showInputBox({ prompt: "Enter name for workspace you want to leave" });
|
||||||
|
if (workspace_id === undefined) return;
|
||||||
|
await client.leave_workspace(workspace_id);
|
||||||
|
vscode.window.showInformationMessage("Left workspace " + workspace_id);
|
||||||
|
provider.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function refresh() {
|
||||||
|
if (client === null) return vscode.window.showWarningMessage("Connect first");
|
||||||
|
await client.refresh();
|
||||||
|
vscode.window.showInformationMessage("Refreshed Session token");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
57
src/commands/workspaces.ts
Normal file
57
src/commands/workspaces.ts
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
import * as vscode from 'vscode';
|
||||||
|
import * as codemp from 'codemp';
|
||||||
|
import * as mapping from "../mapping";
|
||||||
|
import {client} from "./client"
|
||||||
|
import { LOGGER, provider } from '../extension';
|
||||||
|
|
||||||
|
|
||||||
|
export let workspace: codemp.Workspace | null = null;
|
||||||
|
|
||||||
|
|
||||||
|
export function setWorkspace(ws : codemp.Workspace){
|
||||||
|
workspace = ws;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export async function jump(selected: vscode.TreeItem | undefined){
|
||||||
|
if (client === null) return vscode.window.showWarningMessage("Connect first");
|
||||||
|
let user;
|
||||||
|
if (selected !== undefined && selected.label !== undefined) {
|
||||||
|
if (typeof(selected.label) === 'string') {
|
||||||
|
user = selected.label;
|
||||||
|
} else {
|
||||||
|
user = selected.label.label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!user) user = await vscode.window.showInputBox({ prompt: "username"});
|
||||||
|
if (!user) return; // user cancelled with ESC
|
||||||
|
|
||||||
|
let user_hl = mapping.colors_cache.get(user);
|
||||||
|
if (user_hl === undefined) return vscode.window.showWarningMessage("unknown position of such user");
|
||||||
|
let uri = mapping.bufferMapper.uri_by_buffer(user_hl.buffer);
|
||||||
|
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 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");
|
||||||
|
workspace.create(bufferName);
|
||||||
|
vscode.window.showInformationMessage(`new buffer created :${bufferName}`);
|
||||||
|
provider.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listBuffers() {
|
||||||
|
if (workspace === null) return vscode.window.showWarningMessage("Join a workspace first");
|
||||||
|
let buffers = workspace.filetree(undefined, false);
|
||||||
|
vscode.window.showInformationMessage(buffers.join("\n"));
|
||||||
|
provider.refresh();
|
||||||
|
}
|
|
@ -1,8 +1,10 @@
|
||||||
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 {client,connect,join,refresh,createWorkspace,inviteToWorkspace,listWorkspaces,leaveWorkspace} from './commands/client';
|
||||||
import { CodempTreeProvider } from './tree';
|
import { CodempTreeProvider } from './tree';
|
||||||
import * as mapping from './mapping';
|
import * as mapping from './mapping';
|
||||||
|
import {workspace,jump,listBuffers,createBuffer} from './commands/workspaces'
|
||||||
|
import {attach,share,sync,apply_changes_to_buffer} from './commands/buffers'
|
||||||
|
|
||||||
export let provider = new CodempTreeProvider();
|
export let provider = new CodempTreeProvider();
|
||||||
|
|
||||||
|
@ -17,37 +19,37 @@ export function activate(context: vscode.ExtensionContext) {
|
||||||
context.subscriptions.push(sub);
|
context.subscriptions.push(sub);
|
||||||
|
|
||||||
vscode.window.onDidChangeVisibleTextEditors(async (editors : readonly vscode.TextEditor[]) => {
|
vscode.window.onDidChangeVisibleTextEditors(async (editors : readonly vscode.TextEditor[]) => {
|
||||||
if(commands.workspace===null) return;
|
if(workspace===null) return;
|
||||||
for(let editor of editors){
|
for(let editor of editors){
|
||||||
let path = mapping.bufferMapper.by_editor(editor.document.uri);
|
let path = mapping.bufferMapper.by_editor(editor.document.uri);
|
||||||
if (path===undefined) continue;
|
if (path===undefined) continue;
|
||||||
await commands.apply_changes_to_buffer(path, undefined, true);
|
await apply_changes_to_buffer(path, undefined, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 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 [
|
||||||
vscode.commands.registerCommand('codemp.connect', commands.connect),
|
vscode.commands.registerCommand('codemp.connect', connect),
|
||||||
vscode.commands.registerCommand('codemp.join', commands.join),
|
vscode.commands.registerCommand('codemp.join', join),
|
||||||
vscode.commands.registerCommand('codemp.attach', commands.attach),
|
vscode.commands.registerCommand('codemp.attach', attach),
|
||||||
vscode.commands.registerCommand('codemp.share', commands.share),
|
vscode.commands.registerCommand('codemp.share', share),
|
||||||
vscode.commands.registerCommand('codemp.createWorkspace', commands.createWorkspace),
|
vscode.commands.registerCommand('codemp.createWorkspace', createWorkspace),
|
||||||
vscode.commands.registerCommand('codemp.inviteWorkspace', commands.inviteToWorkspace),
|
vscode.commands.registerCommand('codemp.inviteWorkspace', inviteToWorkspace),
|
||||||
vscode.commands.registerCommand('codemp.listWorkspaces', commands.listWorkspaces),
|
vscode.commands.registerCommand('codemp.listWorkspaces', listWorkspaces),
|
||||||
vscode.commands.registerCommand('codemp.leaveWorkspace', commands.leaveWorkspace),
|
vscode.commands.registerCommand('codemp.leaveWorkspace', leaveWorkspace),
|
||||||
vscode.commands.registerCommand('codemp.createBuffer', commands.createBuffer),
|
vscode.commands.registerCommand('codemp.createBuffer', createBuffer),
|
||||||
vscode.commands.registerCommand('codemp.listBuffers', commands.listBuffers),
|
vscode.commands.registerCommand('codemp.listBuffers', listBuffers),
|
||||||
vscode.commands.registerCommand('codemp.sync', commands.sync),
|
vscode.commands.registerCommand('codemp.sync', sync),
|
||||||
vscode.commands.registerCommand('codemp.refresh', commands.refresh),
|
vscode.commands.registerCommand('codemp.refresh', refresh),
|
||||||
vscode.commands.registerCommand('codemp.jump', commands.jump),
|
vscode.commands.registerCommand('codemp.jump', jump),
|
||||||
]) {
|
]) {
|
||||||
context.subscriptions.push(cmd);
|
context.subscriptions.push(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deactivate() {
|
export async function deactivate() {
|
||||||
if (commands.client && commands.workspace) {
|
if (client && workspace) {
|
||||||
await commands.client.leave_workspace(commands.workspace.id());
|
await client.leave_workspace(workspace.id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,12 @@ export class UserDecoration {
|
||||||
borderStyle: 'solid',
|
borderStyle: 'solid',
|
||||||
borderColor: this.color,
|
borderColor: this.color,
|
||||||
backgroundColor: this.color + '44', // add alpha
|
backgroundColor: this.color + '44', // add alpha
|
||||||
overviewRulerColor: this.color,
|
after: {contentText: event.user, margin: "1px", color: colors[2], },
|
||||||
|
border: "1px",
|
||||||
|
//isWholeLine: true
|
||||||
|
overviewRulerLane: vscode.OverviewRulerLane.Right,
|
||||||
|
rangeBehavior: vscode.DecorationRangeBehavior.ClosedClosed
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { client, workspace, workspace_list } from './commands';
|
import { client, workspace_list } from './commands/client';
|
||||||
|
import { workspace} from './commands/workspaces';
|
||||||
import { bufferMapper, colors_cache } from './mapping';
|
import { bufferMapper, colors_cache } from './mapping';
|
||||||
|
|
||||||
export class CodempTreeProvider implements vscode.TreeDataProvider<CodempTreeItem> {
|
export class CodempTreeProvider implements vscode.TreeDataProvider<CodempTreeItem> {
|
||||||
|
|
Loading…
Reference in a new issue