mirror of
https://github.com/hexedtech/codemp-sublime.git
synced 2024-11-21 22:34:48 +01:00
fix: fixed the logger, spawning multiple instances.
Former-commit-id: 926b222cad75a036095ab23e5d11c439e0810b21
This commit is contained in:
parent
73e8e9c061
commit
e334323304
3 changed files with 134 additions and 93 deletions
222
plugin.py
222
plugin.py
|
@ -9,8 +9,7 @@ import random
|
||||||
# import importlib.util
|
# import importlib.util
|
||||||
|
|
||||||
from .src.TaskManager import tm
|
from .src.TaskManager import tm
|
||||||
from .src.client import client, VirtualClient
|
from .src.client import logger, client, VirtualClient
|
||||||
from .src.client import CodempLogger
|
|
||||||
from .src.utils import status_log
|
from .src.utils import status_log
|
||||||
from .src.utils import safe_listener_detach
|
from .src.utils import safe_listener_detach
|
||||||
from .src.utils import safe_listener_attach
|
from .src.utils import safe_listener_attach
|
||||||
|
@ -29,9 +28,6 @@ def plugin_loaded():
|
||||||
# instantiate and start a global asyncio event loop.
|
# instantiate and start a global asyncio event loop.
|
||||||
# pass in the exit_handler coroutine that will be called upon relasing the event loop.
|
# pass in the exit_handler coroutine that will be called upon relasing the event loop.
|
||||||
tm.acquire(disconnect_client)
|
tm.acquire(disconnect_client)
|
||||||
|
|
||||||
logger = CodempLogger()
|
|
||||||
|
|
||||||
tm.dispatch(logger.log(), "codemp-logger")
|
tm.dispatch(logger.log(), "codemp-logger")
|
||||||
|
|
||||||
TEXT_LISTENER = CodempClientTextChangeListener()
|
TEXT_LISTENER = CodempClientTextChangeListener()
|
||||||
|
@ -50,6 +46,8 @@ async def disconnect_client():
|
||||||
for vws in client.workspaces.values():
|
for vws in client.workspaces.values():
|
||||||
vws.cleanup()
|
vws.cleanup()
|
||||||
|
|
||||||
|
client.handle = None # drop
|
||||||
|
|
||||||
|
|
||||||
def plugin_unloaded():
|
def plugin_unloaded():
|
||||||
# releasing the runtime, runs the disconnect callback defined when acquiring the event loop.
|
# releasing the runtime, runs the disconnect callback defined when acquiring the event loop.
|
||||||
|
@ -67,6 +65,7 @@ class EventListener(sublime_plugin.EventListener):
|
||||||
if client.active_workspace is None:
|
if client.active_workspace is None:
|
||||||
return # nothing to do
|
return # nothing to do
|
||||||
|
|
||||||
|
# deactivate all workspaces
|
||||||
client.make_active(None)
|
client.make_active(None)
|
||||||
|
|
||||||
s = window.settings()
|
s = window.settings()
|
||||||
|
@ -172,6 +171,9 @@ class CodempConnectCommand(sublime_plugin.WindowCommand):
|
||||||
def run(self, server_host, user_name, password="lmaodefaultpassword"):
|
def run(self, server_host, user_name, password="lmaodefaultpassword"):
|
||||||
client.connect(server_host, user_name, password)
|
client.connect(server_host, user_name, password)
|
||||||
|
|
||||||
|
def is_enabled(self) -> bool:
|
||||||
|
return client.handle is None
|
||||||
|
|
||||||
def input(self, args):
|
def input(self, args):
|
||||||
if "server_host" not in args:
|
if "server_host" not in args:
|
||||||
return ConnectServerHost()
|
return ConnectServerHost()
|
||||||
|
@ -189,10 +191,13 @@ class ConnectServerHost(sublime_plugin.TextInputHandler):
|
||||||
|
|
||||||
def next_input(self, args):
|
def next_input(self, args):
|
||||||
if "user_name" not in args:
|
if "user_name" not in args:
|
||||||
return ConnectUserName()
|
return ConnectUserName(args)
|
||||||
|
|
||||||
|
|
||||||
class ConnectUserName(sublime_plugin.TextInputHandler):
|
class ConnectUserName(sublime_plugin.TextInputHandler):
|
||||||
|
def __init__(self, args):
|
||||||
|
self.host = args["server_host"]
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return "user_name"
|
return "user_name"
|
||||||
|
|
||||||
|
@ -200,49 +205,95 @@ class ConnectUserName(sublime_plugin.TextInputHandler):
|
||||||
return f"user-{random.random()}"
|
return f"user-{random.random()}"
|
||||||
|
|
||||||
|
|
||||||
|
# Separate the join command into two join workspace and join buffer commands that get called back to back
|
||||||
|
|
||||||
|
|
||||||
# Generic Join Command
|
# Generic Join Command
|
||||||
#############################################################################
|
#############################################################################
|
||||||
async def JoinCommand(client: VirtualClient, workspace_id: str, buffer_id: str):
|
async def JoinCommand(client: VirtualClient, workspace_id: str, buffer_id: str):
|
||||||
if workspace_id is None:
|
if workspace_id == "":
|
||||||
return
|
return
|
||||||
|
|
||||||
|
vws = client.workspaces.get(workspace_id)
|
||||||
|
if vws is None:
|
||||||
vws = await client.join_workspace(workspace_id)
|
vws = await client.join_workspace(workspace_id)
|
||||||
|
|
||||||
if buffer_id is None:
|
vws.materialize()
|
||||||
return
|
|
||||||
|
|
||||||
if vws is not None:
|
if buffer_id != "":
|
||||||
await vws.attach(buffer_id)
|
await vws.attach(buffer_id)
|
||||||
|
|
||||||
|
|
||||||
class CodempJoinCommand(sublime_plugin.WindowCommand):
|
class CodempJoinCommand(sublime_plugin.WindowCommand):
|
||||||
def run(self, workspace_id, buffer_id):
|
def run(self, workspace_id, buffer_id):
|
||||||
|
print(workspace_id, buffer_id)
|
||||||
|
if buffer_id == "* Don't Join Any":
|
||||||
|
buffer_id = ""
|
||||||
tm.dispatch(JoinCommand(client, workspace_id, buffer_id))
|
tm.dispatch(JoinCommand(client, workspace_id, buffer_id))
|
||||||
|
|
||||||
|
def is_enabled(self) -> bool:
|
||||||
|
return client.handle is not None
|
||||||
|
|
||||||
def input_description(self):
|
def input_description(self):
|
||||||
return "Join:"
|
return "Join:"
|
||||||
|
|
||||||
def input(self, args):
|
def input(self, args):
|
||||||
if "workspace_id" not in args:
|
if "workspace_id" not in args:
|
||||||
return WorkspaceIdAndFollowup()
|
return JoinWorkspaceIdList()
|
||||||
|
|
||||||
|
|
||||||
class WorkspaceIdAndFollowup(sublime_plugin.ListInputHandler):
|
class JoinWorkspaceIdList(sublime_plugin.ListInputHandler):
|
||||||
|
# To allow for having a selection and choosing non existing workspaces
|
||||||
|
# we do a little dance: We pass this list input handler to a TextInputHandler
|
||||||
|
# when we select "Create New..." which adds his result to the list of possible
|
||||||
|
# workspaces and pop itself off the stack to go back to the list handler.
|
||||||
|
def __init__(self):
|
||||||
|
self.list = client.active_workspaces()
|
||||||
|
self.list.sort()
|
||||||
|
self.list.append("* Create New...")
|
||||||
|
self.preselected = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return "workspace_id"
|
return "workspace_id"
|
||||||
|
|
||||||
def placeholder(self):
|
def placeholder(self):
|
||||||
return "Workspace Id"
|
return "Workspace"
|
||||||
|
|
||||||
def list_items(self):
|
def list_items(self):
|
||||||
return client.active_workspaces()
|
if self.preselected is not None:
|
||||||
|
return (self.list, self.preselected)
|
||||||
|
else:
|
||||||
|
return self.list
|
||||||
|
|
||||||
def next_input(self, args):
|
def next_input(self, args):
|
||||||
if "buffer_id" not in args:
|
if args["workspace_id"] == "* Create New...":
|
||||||
return ListBufferId()
|
return AddListEntryName(self)
|
||||||
|
|
||||||
|
wid = args["workspace_id"]
|
||||||
|
if wid != "":
|
||||||
|
vws = tm.sync(client.join_workspace(wid))
|
||||||
|
else:
|
||||||
|
vws = None
|
||||||
|
try:
|
||||||
|
return ListBufferId(vws)
|
||||||
|
except Exception:
|
||||||
|
return TextBufferId()
|
||||||
|
|
||||||
|
|
||||||
|
class TextBufferId(sublime_plugin.TextInputHandler):
|
||||||
|
def name(self):
|
||||||
|
return "buffer_id"
|
||||||
|
|
||||||
|
|
||||||
class ListBufferId(sublime_plugin.ListInputHandler):
|
class ListBufferId(sublime_plugin.ListInputHandler):
|
||||||
|
def __init__(self, vws):
|
||||||
|
self.ws = vws
|
||||||
|
self.list = vws.handle.filetree()
|
||||||
|
self.list.sort()
|
||||||
|
self.list.append("* Create New...")
|
||||||
|
self.list.append("* Don't Join Any")
|
||||||
|
self.preselected = None
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return "buffer_id"
|
return "buffer_id"
|
||||||
|
|
||||||
|
@ -250,54 +301,39 @@ class ListBufferId(sublime_plugin.ListInputHandler):
|
||||||
return "Buffer Id"
|
return "Buffer Id"
|
||||||
|
|
||||||
def list_items(self):
|
def list_items(self):
|
||||||
return client.active_workspace.handle.filetree()
|
if self.preselected is not None:
|
||||||
|
return (self.list, self.preselected)
|
||||||
|
|
||||||
# Join Workspace Command
|
|
||||||
#############################################################################
|
|
||||||
class CodempJoinWorkspaceCommand(sublime_plugin.WindowCommand):
|
|
||||||
def run(self, workspace_id): # pyright: ignore
|
|
||||||
tm.dispatch(client.join_workspace(workspace_id))
|
|
||||||
|
|
||||||
def input_description(self):
|
|
||||||
return "Join specific workspace"
|
|
||||||
|
|
||||||
def input(self, args):
|
|
||||||
if "workspace_id" not in args:
|
|
||||||
return RawWorkspaceId()
|
|
||||||
|
|
||||||
|
|
||||||
# Join Buffer Command
|
|
||||||
#############################################################################
|
|
||||||
class CodempJoinBufferCommand(sublime_plugin.WindowCommand):
|
|
||||||
def run(self, buffer_id): # pyright: ignore
|
|
||||||
if client.active_workspace is None:
|
|
||||||
sublime.error_message(
|
|
||||||
"You haven't joined any worksapce yet. \
|
|
||||||
use `Codemp: Join Workspace` or `Codemp: Join`"
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
tm.dispatch(client.active_workspace.attach(buffer_id))
|
|
||||||
|
|
||||||
def input_description(self):
|
|
||||||
return "Join buffer in the active workspace"
|
|
||||||
|
|
||||||
# This is awful, fix it
|
|
||||||
def input(self, args):
|
|
||||||
if client.active_workspace is None:
|
|
||||||
sublime.error_message(
|
|
||||||
"You haven't joined any worksapce yet. \
|
|
||||||
use `Codemp: Join Workspace` or `Codemp: Join`"
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
if "buffer_id" not in args:
|
|
||||||
existing_buffers = client.active_workspace.handle.filetree()
|
|
||||||
if len(existing_buffers) == 0:
|
|
||||||
return RawBufferId()
|
|
||||||
else:
|
else:
|
||||||
return ListBufferId2()
|
return self.list
|
||||||
|
|
||||||
|
def cancel(self):
|
||||||
|
client.leave_workspace(self.ws.id)
|
||||||
|
|
||||||
|
def next_input(self, args):
|
||||||
|
if args["buffer_id"] == "* Create New...":
|
||||||
|
return AddListEntryName(self)
|
||||||
|
|
||||||
|
if args["buffer_id"] == "* Dont' Join Any":
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class AddListEntryName(sublime_plugin.TextInputHandler):
|
||||||
|
def __init__(self, list_handler):
|
||||||
|
self.parent = list_handler
|
||||||
|
|
||||||
|
def name(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def validate(self, text: str) -> bool:
|
||||||
|
return not len(text) == 0
|
||||||
|
|
||||||
|
def confirm(self, text: str):
|
||||||
|
self.parent.list.pop() # removes the "Create New..."
|
||||||
|
self.parent.list.insert(0, text)
|
||||||
|
self.parent.preselected = 0
|
||||||
|
|
||||||
|
def next_input(self, args):
|
||||||
|
return sublime_plugin.BackInputHandler()
|
||||||
|
|
||||||
|
|
||||||
# Text Change Command
|
# Text Change Command
|
||||||
|
@ -309,39 +345,6 @@ class CodempReplaceTextCommand(sublime_plugin.TextCommand):
|
||||||
self.view.replace(edit, region, content)
|
self.view.replace(edit, region, content)
|
||||||
|
|
||||||
|
|
||||||
# Input Handlers
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
|
|
||||||
class ListBufferId2(sublime_plugin.ListInputHandler):
|
|
||||||
def name(self):
|
|
||||||
return "buffer_id"
|
|
||||||
|
|
||||||
def list_items(self):
|
|
||||||
assert client.active_workspace is not None
|
|
||||||
return client.active_workspace
|
|
||||||
|
|
||||||
def next_input(self, args):
|
|
||||||
if "buffer_id" not in args:
|
|
||||||
return RawBufferId()
|
|
||||||
|
|
||||||
|
|
||||||
class RawWorkspaceId(sublime_plugin.TextInputHandler):
|
|
||||||
def name(self):
|
|
||||||
return "workspace_id"
|
|
||||||
|
|
||||||
def placeholder(self):
|
|
||||||
return "Workspace Id"
|
|
||||||
|
|
||||||
|
|
||||||
class RawBufferId(sublime_plugin.TextInputHandler):
|
|
||||||
def name(self):
|
|
||||||
return "buffer_id"
|
|
||||||
|
|
||||||
def placeholder(self):
|
|
||||||
return "Buffer Id"
|
|
||||||
|
|
||||||
|
|
||||||
# Share Command
|
# Share Command
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
# class CodempShareCommand(sublime_plugin.WindowCommand):
|
# class CodempShareCommand(sublime_plugin.WindowCommand):
|
||||||
|
@ -359,10 +362,37 @@ class RawBufferId(sublime_plugin.TextInputHandler):
|
||||||
# Disconnect Command
|
# Disconnect Command
|
||||||
#############################################################################
|
#############################################################################
|
||||||
class CodempDisconnectCommand(sublime_plugin.WindowCommand):
|
class CodempDisconnectCommand(sublime_plugin.WindowCommand):
|
||||||
|
def is_enabled(self) -> bool:
|
||||||
|
if client.handle is not None:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
tm.sync(disconnect_client())
|
tm.sync(disconnect_client())
|
||||||
|
|
||||||
|
|
||||||
|
# Leave Workspace Command
|
||||||
|
class CodempLeaveWorkspaceCommand(sublime_plugin.WindowCommand):
|
||||||
|
def is_enabled(self) -> bool:
|
||||||
|
return client.handle is not None and len(client.workspaces.keys()) > 0
|
||||||
|
|
||||||
|
def run(self, id: str):
|
||||||
|
client.leave_workspace(id)
|
||||||
|
|
||||||
|
def input(self, args):
|
||||||
|
if "id" not in args:
|
||||||
|
return LeaveWorkspaceIdList()
|
||||||
|
|
||||||
|
|
||||||
|
class LeaveWorkspaceIdList(sublime_plugin.ListInputHandler):
|
||||||
|
def name(self):
|
||||||
|
return "id"
|
||||||
|
|
||||||
|
def list_items(self):
|
||||||
|
return client.active_workspaces()
|
||||||
|
|
||||||
|
|
||||||
# Proxy Commands ( NOT USED, left just in case we need it again. )
|
# Proxy Commands ( NOT USED, left just in case we need it again. )
|
||||||
#############################################################################
|
#############################################################################
|
||||||
# class ProxyCodempShareCommand(sublime_plugin.WindowCommand):
|
# class ProxyCodempShareCommand(sublime_plugin.WindowCommand):
|
||||||
|
|
|
@ -18,12 +18,13 @@ class TaskManager:
|
||||||
|
|
||||||
def release(self, at_exit):
|
def release(self, at_exit):
|
||||||
self.runtime.release(at_exit=at_exit, exit_handler_id=self.exit_handler_id)
|
self.runtime.release(at_exit=at_exit, exit_handler_id=self.exit_handler_id)
|
||||||
|
self.exit_handler_id = None
|
||||||
|
|
||||||
def dispatch(self, coro, name=None):
|
def dispatch(self, coro, name=None):
|
||||||
self.runtime.dispatch(coro, self.store_named_lambda(name))
|
self.runtime.dispatch(coro, self.store_named_lambda(name))
|
||||||
|
|
||||||
def sync(self, coro):
|
def sync(self, coro):
|
||||||
self.runtime.sync(coro)
|
return self.runtime.sync(coro)
|
||||||
|
|
||||||
def remove_stopped(self):
|
def remove_stopped(self):
|
||||||
self.tasks = list(filter(lambda T: not T.cancelled(), self.tasks))
|
self.tasks = list(filter(lambda T: not T.cancelled(), self.tasks))
|
||||||
|
|
|
@ -22,18 +22,25 @@ from ..src.utils import status_log, rowcol_to_region
|
||||||
|
|
||||||
class CodempLogger:
|
class CodempLogger:
|
||||||
def __init__(self, debug: bool = False):
|
def __init__(self, debug: bool = False):
|
||||||
|
self.handle = None
|
||||||
|
self.started = False
|
||||||
try:
|
try:
|
||||||
self.handle = PyLogger(debug)
|
self.handle = PyLogger(debug)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def log(self):
|
async def log(self):
|
||||||
|
if self.started:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.started = True
|
||||||
status_log("spinning up the logger...")
|
status_log("spinning up the logger...")
|
||||||
try:
|
try:
|
||||||
while msg := await self.handle.listen():
|
while msg := await self.handle.listen():
|
||||||
print(msg)
|
print(msg)
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
status_log("stopping logger")
|
status_log("stopping logger")
|
||||||
|
self.started = False
|
||||||
raise
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
status_log(f"logger crashed unexpectedly:\n{e}")
|
status_log(f"logger crashed unexpectedly:\n{e}")
|
||||||
|
@ -460,4 +467,7 @@ class VirtualClient:
|
||||||
self.active_workspace = ws
|
self.active_workspace = ws
|
||||||
|
|
||||||
|
|
||||||
|
DEBUG = False
|
||||||
|
logger = CodempLogger(DEBUG)
|
||||||
|
logger.log()
|
||||||
client = VirtualClient()
|
client = VirtualClient()
|
||||||
|
|
Loading…
Reference in a new issue