2024-02-21 23:59:49 +01:00
|
|
|
from __future__ import annotations
|
2024-08-21 21:35:57 +02:00
|
|
|
from typing import Optional
|
2023-08-17 18:39:47 +02:00
|
|
|
|
2024-02-23 13:25:01 +01:00
|
|
|
import sublime
|
2024-08-09 19:20:58 +02:00
|
|
|
import logging
|
2023-08-25 14:29:11 +02:00
|
|
|
|
2024-08-21 21:35:57 +02:00
|
|
|
import codemp
|
2024-08-09 15:54:12 +02:00
|
|
|
from Codemp.src import globals as g
|
|
|
|
from Codemp.src.workspace import VirtualWorkspace
|
2024-08-09 19:20:58 +02:00
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
2024-02-21 23:59:49 +01:00
|
|
|
|
|
|
|
|
|
|
|
class VirtualClient:
|
2024-08-21 21:35:57 +02:00
|
|
|
handle: Optional[codemp.Client]
|
|
|
|
|
2024-08-04 19:57:59 +02:00
|
|
|
def __init__(self):
|
2024-08-21 21:35:57 +02:00
|
|
|
self.driver = codemp.init(lambda msg: logger.log(logger.level, msg), False)
|
2024-02-23 13:25:01 +01:00
|
|
|
self.workspaces: dict[str, VirtualWorkspace] = {}
|
2024-08-21 21:35:57 +02:00
|
|
|
self.active_workspace: Optional[None] = None
|
2024-02-21 23:59:49 +01:00
|
|
|
|
2024-02-23 17:49:26 +01:00
|
|
|
def __getitem__(self, key: str):
|
|
|
|
return self.workspaces.get(key)
|
|
|
|
|
2024-08-21 21:35:57 +02:00
|
|
|
def disconnect(self):
|
|
|
|
if self.handle is None:
|
|
|
|
return
|
|
|
|
logger.info("disconnecting from the current client")
|
|
|
|
for vws in self.workspaces.values():
|
|
|
|
vws.cleanup()
|
|
|
|
|
|
|
|
self.handle = None
|
|
|
|
|
2024-08-09 09:17:38 +02:00
|
|
|
def connect(self, host: str, user: str, password: str):
|
2024-08-21 21:35:57 +02:00
|
|
|
if self.handle is not None:
|
|
|
|
logger.info("Disconnecting from previous client.")
|
|
|
|
return self.disconnect()
|
|
|
|
|
2024-08-09 19:20:58 +02:00
|
|
|
logger.info(f"Connecting to {host} with user {user}")
|
2024-08-09 09:17:38 +02:00
|
|
|
try:
|
2024-08-21 21:35:57 +02:00
|
|
|
self.handle = codemp.Client(host, user, password)
|
|
|
|
|
|
|
|
if self.handle is not None:
|
|
|
|
id = self.handle.user_id()
|
|
|
|
logger.debug(f"Connected to '{host}' with user {user} and id: {id}")
|
|
|
|
|
2024-08-09 09:17:38 +02:00
|
|
|
except Exception as e:
|
2024-08-09 19:20:58 +02:00
|
|
|
logger.error(f"Could not connect: {e}")
|
2024-08-09 09:17:38 +02:00
|
|
|
sublime.error_message(
|
2024-08-09 19:20:58 +02:00
|
|
|
"Could not connect:\n Make sure the server is up.\n\
|
|
|
|
or your credentials are correct."
|
2024-08-09 09:17:38 +02:00
|
|
|
)
|
2024-08-21 21:35:57 +02:00
|
|
|
raise
|
2024-08-09 09:17:38 +02:00
|
|
|
|
2024-08-20 12:06:46 +02:00
|
|
|
def join_workspace(
|
2024-08-09 09:17:38 +02:00
|
|
|
self,
|
|
|
|
workspace_id: str,
|
2024-08-21 21:35:57 +02:00
|
|
|
) -> VirtualWorkspace:
|
2024-08-09 09:17:38 +02:00
|
|
|
if self.handle is None:
|
2024-08-21 21:35:57 +02:00
|
|
|
sublime.error_message("Connect to a server first.")
|
|
|
|
raise
|
2024-08-09 09:17:38 +02:00
|
|
|
|
2024-08-09 19:20:58 +02:00
|
|
|
logger.info(f"Joining workspace: '{workspace_id}'")
|
2024-08-09 09:17:38 +02:00
|
|
|
try:
|
2024-08-21 21:35:57 +02:00
|
|
|
workspace = self.handle.join_workspace(workspace_id).wait()
|
2024-08-09 09:17:38 +02:00
|
|
|
except Exception as e:
|
2024-08-09 19:20:58 +02:00
|
|
|
logger.error(f"Could not join workspace '{workspace_id}'.\n\nerror: {e}")
|
|
|
|
sublime.error_message(f"Could not join workspace '{workspace_id}'")
|
2024-08-21 21:35:57 +02:00
|
|
|
raise
|
2024-08-09 09:17:38 +02:00
|
|
|
|
|
|
|
vws = VirtualWorkspace(workspace)
|
|
|
|
self.workspaces[workspace_id] = vws
|
|
|
|
|
|
|
|
return vws
|
|
|
|
|
|
|
|
def leave_workspace(self, id: str):
|
|
|
|
if self.handle is None:
|
2024-08-21 21:35:57 +02:00
|
|
|
raise
|
|
|
|
|
2024-08-09 14:23:29 +02:00
|
|
|
if self.handle.leave_workspace(id):
|
2024-08-21 21:35:57 +02:00
|
|
|
logger.info(f"Leaving workspace: '{id}'")
|
2024-08-09 14:23:29 +02:00
|
|
|
self.workspaces[id].cleanup()
|
|
|
|
del self.workspaces[id]
|
2024-08-09 09:17:38 +02:00
|
|
|
|
2024-08-04 19:57:59 +02:00
|
|
|
def get_workspace(self, view):
|
|
|
|
tag_id = view.settings().get(g.CODEMP_WORKSPACE_ID)
|
|
|
|
if tag_id is None:
|
|
|
|
return
|
|
|
|
|
|
|
|
ws = self.workspaces.get(tag_id)
|
|
|
|
if ws is None:
|
2024-08-09 19:20:58 +02:00
|
|
|
logging.warning("a tag on the view was found but not a matching workspace.")
|
2024-08-04 19:57:59 +02:00
|
|
|
return
|
|
|
|
|
|
|
|
return ws
|
|
|
|
|
2024-08-09 09:17:38 +02:00
|
|
|
def active_workspaces(self):
|
|
|
|
return self.handle.active_workspaces() if self.handle else []
|
|
|
|
|
|
|
|
def user_id(self):
|
|
|
|
return self.handle.user_id() if self.handle else None
|
|
|
|
|
2024-08-04 19:57:59 +02:00
|
|
|
def get_buffer(self, view):
|
|
|
|
ws = self.get_workspace(view)
|
|
|
|
return None if ws is None else ws.get_by_local(view.buffer_id())
|
|
|
|
|
2024-08-21 21:35:57 +02:00
|
|
|
def make_active(self, ws: Optional[VirtualWorkspace]):
|
2024-08-04 19:57:59 +02:00
|
|
|
if self.active_workspace == ws:
|
|
|
|
return
|
|
|
|
|
2024-02-21 23:59:49 +01:00
|
|
|
if self.active_workspace is not None:
|
2024-08-04 19:57:59 +02:00
|
|
|
self.active_workspace.deactivate()
|
|
|
|
|
|
|
|
if ws is not None:
|
|
|
|
ws.activate()
|
|
|
|
|
2024-08-21 21:35:57 +02:00
|
|
|
self.active_workspace = ws # pyright: ignore
|
2024-02-21 23:59:49 +01:00
|
|
|
|
|
|
|
|
2024-08-04 19:57:59 +02:00
|
|
|
client = VirtualClient()
|