mirror of
https://github.com/hexedtech/codemp-sublime.git
synced 2024-11-21 14:24:49 +01:00
fix: attach listener upon creation to go around the on_activate event not firing on
a newly spawned view. Former-commit-id: 078a306921278905a50fc97630012a06a00b0cd3
This commit is contained in:
parent
95694dc2ec
commit
a481b79b76
3 changed files with 48 additions and 26 deletions
|
@ -6,7 +6,7 @@ import logging
|
||||||
|
|
||||||
import codemp
|
import codemp
|
||||||
from Codemp.src import globals as g
|
from Codemp.src import globals as g
|
||||||
from Codemp.src.utils import populate_view
|
from Codemp.src.utils import populate_view, safe_listener_attach, safe_listener_detach
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ class VirtualBuffer:
|
||||||
self.tmpfile = os.path.join(rootdir, self.id)
|
self.tmpfile = os.path.join(rootdir, self.id)
|
||||||
open(self.tmpfile, "a").close()
|
open(self.tmpfile, "a").close()
|
||||||
|
|
||||||
# self.view.set_scratch(True)
|
self.view.set_scratch(True)
|
||||||
self.view.set_name(self.id)
|
self.view.set_name(self.id)
|
||||||
self.view.retarget(self.tmpfile)
|
self.view.retarget(self.tmpfile)
|
||||||
|
|
||||||
|
@ -74,13 +74,17 @@ class VirtualBuffer:
|
||||||
self.view.set_status(g.SUBLIME_STATUS_ID, "[Codemp]")
|
self.view.set_status(g.SUBLIME_STATUS_ID, "[Codemp]")
|
||||||
s[g.CODEMP_BUFFER_TAG] = True
|
s[g.CODEMP_BUFFER_TAG] = True
|
||||||
|
|
||||||
self.sync()
|
|
||||||
|
|
||||||
logger.info(f"registering a callback for buffer: {self.id}")
|
logger.info(f"registering a callback for buffer: {self.id}")
|
||||||
self.buffctl.callback(make_bufferchange_cb(self))
|
self.buffctl.callback(make_bufferchange_cb(self))
|
||||||
self.isactive = True
|
self.isactive = True
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
|
logger.debug("__del__ buffer called.")
|
||||||
|
|
||||||
|
def __hash__(self) -> int:
|
||||||
|
return hash(self.id)
|
||||||
|
|
||||||
|
def uninstall(self):
|
||||||
logger.info(f"clearing a callback for buffer: {self.id}")
|
logger.info(f"clearing a callback for buffer: {self.id}")
|
||||||
self.buffctl.clear_callback()
|
self.buffctl.clear_callback()
|
||||||
self.buffctl.stop()
|
self.buffctl.stop()
|
||||||
|
@ -96,15 +100,14 @@ class VirtualBuffer:
|
||||||
|
|
||||||
self.view.close(onclose)
|
self.view.close(onclose)
|
||||||
|
|
||||||
def __hash__(self) -> int:
|
def sync(self, text_listener):
|
||||||
return hash(self.id)
|
|
||||||
|
|
||||||
def sync(self):
|
|
||||||
promise = self.buffctl.content()
|
promise = self.buffctl.content()
|
||||||
|
|
||||||
def defer_sync(promise):
|
def defer_sync(promise):
|
||||||
content = promise.wait()
|
content = promise.wait()
|
||||||
|
safe_listener_detach(text_listener)
|
||||||
populate_view(self.view, content)
|
populate_view(self.view, content)
|
||||||
|
safe_listener_attach(text_listener, self.view.buffer())
|
||||||
|
|
||||||
sublime.set_timeout_async(lambda: defer_sync(promise))
|
sublime.set_timeout_async(lambda: defer_sync(promise))
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,8 @@ logger = logging.getLogger(__name__)
|
||||||
# bidir: VirtualBuffer <-> VirtualWorkspace
|
# bidir: VirtualBuffer <-> VirtualWorkspace
|
||||||
# bidir: VirtualBuffer <-> Sublime.View
|
# bidir: VirtualBuffer <-> Sublime.View
|
||||||
# bidir: VirtualWorkspace <-> Sublime.Window
|
# bidir: VirtualWorkspace <-> Sublime.Window
|
||||||
def log_async(msg):
|
# def log_async(msg):
|
||||||
sublime.set_timeout_async(lambda: logger.log(logger.level, msg))
|
# sublime.set_timeout_async(lambda: logger.log(logger.level, msg))
|
||||||
|
|
||||||
|
|
||||||
class VirtualClient:
|
class VirtualClient:
|
||||||
|
@ -36,11 +36,12 @@ class VirtualClient:
|
||||||
|
|
||||||
self._view2buff: dict[sublime.View, VirtualBuffer] = {}
|
self._view2buff: dict[sublime.View, VirtualBuffer] = {}
|
||||||
self._buff2workspace: bidict[VirtualBuffer, VirtualWorkspace] = bidict()
|
self._buff2workspace: bidict[VirtualBuffer, VirtualWorkspace] = bidict()
|
||||||
# self._workspace2window: bidict[VirtualWorkspace, sublime.Window] = bidict()
|
|
||||||
self._workspace2window: dict[VirtualWorkspace, sublime.Window] = bidict()
|
self._workspace2window: dict[VirtualWorkspace, sublime.Window] = bidict()
|
||||||
|
|
||||||
def dump(self):
|
def dump(self):
|
||||||
logger.debug("CLIENT STATUS:")
|
logger.debug("CLIENT STATUS:")
|
||||||
|
logger.debug(f"codemp: {self.codemp is not None}")
|
||||||
|
logger.debug(f"drived: {self.driver is not None}")
|
||||||
logger.debug("WORKSPACES:")
|
logger.debug("WORKSPACES:")
|
||||||
logger.debug(f"{self._id2workspace}")
|
logger.debug(f"{self._id2workspace}")
|
||||||
logger.debug(f"{self._workspace2window}")
|
logger.debug(f"{self._workspace2window}")
|
||||||
|
@ -103,6 +104,7 @@ class VirtualClient:
|
||||||
logger.info("disconnecting from the current client")
|
logger.info("disconnecting from the current client")
|
||||||
# for each workspace tell it to clean up after itself.
|
# for each workspace tell it to clean up after itself.
|
||||||
for vws in self.all_workspaces():
|
for vws in self.all_workspaces():
|
||||||
|
self.uninstall_workspace(vws)
|
||||||
self.codemp.leave_workspace(vws.id)
|
self.codemp.leave_workspace(vws.id)
|
||||||
|
|
||||||
self._id2workspace.clear()
|
self._id2workspace.clear()
|
||||||
|
@ -110,6 +112,9 @@ class VirtualClient:
|
||||||
self._buff2workspace.clear()
|
self._buff2workspace.clear()
|
||||||
self._view2buff.clear()
|
self._view2buff.clear()
|
||||||
self._workspace2window.clear()
|
self._workspace2window.clear()
|
||||||
|
|
||||||
|
self.driver.stop()
|
||||||
|
self.driver = None
|
||||||
self.codemp = None
|
self.codemp = None
|
||||||
|
|
||||||
def connect(self, host: str, user: str, password: str):
|
def connect(self, host: str, user: str, password: str):
|
||||||
|
@ -119,7 +124,11 @@ class VirtualClient:
|
||||||
|
|
||||||
if self.driver is None:
|
if self.driver is None:
|
||||||
self.driver = codemp.init()
|
self.driver = codemp.init()
|
||||||
codemp.set_logger(log_async, False)
|
logger.debug("registering logger callback...")
|
||||||
|
if not codemp.set_logger(lambda msg: logger.debug(msg), False):
|
||||||
|
logger.debug(
|
||||||
|
"could not register the logger... If reconnecting it's ok, the previous logger is still registered"
|
||||||
|
)
|
||||||
|
|
||||||
self.codemp = codemp.connect(host, user, password).wait()
|
self.codemp = codemp.connect(host, user, password).wait()
|
||||||
id = self.codemp.user_id()
|
id = self.codemp.user_id()
|
||||||
|
@ -140,7 +149,8 @@ class VirtualClient:
|
||||||
del self._id2workspace[vws.id]
|
del self._id2workspace[vws.id]
|
||||||
for vbuff in self.all_buffers(vws):
|
for vbuff in self.all_buffers(vws):
|
||||||
self.unregister_buffer(vbuff)
|
self.unregister_buffer(vbuff)
|
||||||
del vws
|
|
||||||
|
vws.uninstall()
|
||||||
# self._buff2workspace.inverse_del(vws) - if we delete all straight
|
# self._buff2workspace.inverse_del(vws) - if we delete all straight
|
||||||
# keys the last delete will remove also the empty key.
|
# keys the last delete will remove also the empty key.
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import logging
|
||||||
import codemp
|
import codemp
|
||||||
from Codemp.src import globals as g
|
from Codemp.src import globals as g
|
||||||
from Codemp.src.buffers import VirtualBuffer
|
from Codemp.src.buffers import VirtualBuffer
|
||||||
from Codemp.src.utils import draw_cursor_region
|
from Codemp.src.utils import draw_cursor_region, safe_listener_attach, sublime_plugin
|
||||||
from Codemp.src.utils import bidict
|
from Codemp.src.utils import bidict
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,7 +51,6 @@ class VirtualWorkspace:
|
||||||
self.codemp.fetch_buffers()
|
self.codemp.fetch_buffers()
|
||||||
self.codemp.fetch_users()
|
self.codemp.fetch_users()
|
||||||
|
|
||||||
self._buff2view: bidict[VirtualBuffer, sublime.View] = bidict()
|
|
||||||
self._id2buff: dict[str, VirtualBuffer] = {}
|
self._id2buff: dict[str, VirtualBuffer] = {}
|
||||||
|
|
||||||
tmpdir = tempfile.mkdtemp(prefix="codemp_")
|
tmpdir = tempfile.mkdtemp(prefix="codemp_")
|
||||||
|
@ -71,10 +70,25 @@ class VirtualWorkspace:
|
||||||
self.isactive = True
|
self.isactive = True
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
|
logger.debug("workspace destroyed!")
|
||||||
|
|
||||||
|
def __hash__(self) -> int:
|
||||||
|
# so we can use these as dict keys!
|
||||||
|
return hash(self.id)
|
||||||
|
|
||||||
|
def uninstall(self):
|
||||||
self.curctl.clear_callback()
|
self.curctl.clear_callback()
|
||||||
self.isactive = False
|
self.isactive = False
|
||||||
self.curctl.stop()
|
self.curctl.stop()
|
||||||
|
|
||||||
|
for vbuff in self._id2buff.values():
|
||||||
|
vbuff.uninstall()
|
||||||
|
if not self.codemp.detach(vbuff.id):
|
||||||
|
logger.warning(
|
||||||
|
f"could not detach from '{vbuff.id}' for workspace '{self.id}'."
|
||||||
|
)
|
||||||
|
self._id2buff.clear()
|
||||||
|
|
||||||
proj: dict = self.window.project_data() # type:ignore
|
proj: dict = self.window.project_data() # type:ignore
|
||||||
if proj is None:
|
if proj is None:
|
||||||
raise
|
raise
|
||||||
|
@ -91,34 +105,29 @@ class VirtualWorkspace:
|
||||||
logger.info(f"cleaning up virtual workspace '{self.id}'")
|
logger.info(f"cleaning up virtual workspace '{self.id}'")
|
||||||
shutil.rmtree(self.rootdir, ignore_errors=True)
|
shutil.rmtree(self.rootdir, ignore_errors=True)
|
||||||
|
|
||||||
if not all(self.codemp.detach(buff) for buff in self._id2buff.keys()):
|
|
||||||
logger.warning(
|
|
||||||
f"could not detach from all buffers for workspace '{self.id}'."
|
|
||||||
)
|
|
||||||
self._id2buff.clear()
|
|
||||||
|
|
||||||
def __hash__(self) -> int:
|
|
||||||
# so we can use these as dict keys!
|
|
||||||
return hash(self.id)
|
|
||||||
|
|
||||||
def all_buffers(self) -> list[VirtualBuffer]:
|
def all_buffers(self) -> list[VirtualBuffer]:
|
||||||
return list(self._id2buff.values())
|
return list(self._id2buff.values())
|
||||||
|
|
||||||
def buff_by_id(self, id: str) -> Optional[VirtualBuffer]:
|
def buff_by_id(self, id: str) -> Optional[VirtualBuffer]:
|
||||||
return self._id2buff.get(id)
|
return self._id2buff.get(id)
|
||||||
|
|
||||||
def install_buffer(self, buff: codemp.BufferController) -> VirtualBuffer:
|
def install_buffer(
|
||||||
|
self, buff: codemp.BufferController, listener: sublime_plugin.TextChangeListener
|
||||||
|
) -> VirtualBuffer:
|
||||||
logger.debug(f"installing buffer {buff.name()}")
|
logger.debug(f"installing buffer {buff.name()}")
|
||||||
|
|
||||||
view = self.window.new_file()
|
view = self.window.new_file()
|
||||||
vbuff = VirtualBuffer(buff, view, self.rootdir)
|
vbuff = VirtualBuffer(buff, view, self.rootdir)
|
||||||
self._id2buff[vbuff.id] = vbuff
|
self._id2buff[vbuff.id] = vbuff
|
||||||
|
|
||||||
|
vbuff.sync(listener)
|
||||||
|
|
||||||
return vbuff
|
return vbuff
|
||||||
|
|
||||||
def uninstall_buffer(self, vbuff: VirtualBuffer):
|
def uninstall_buffer(self, vbuff: VirtualBuffer):
|
||||||
del self._id2buff[vbuff.id]
|
del self._id2buff[vbuff.id]
|
||||||
self.codemp.detach(vbuff.id)
|
self.codemp.detach(vbuff.id)
|
||||||
|
vbuff.uninstall()
|
||||||
|
|
||||||
def send_cursor(self, id: str, start: Tuple[int, int], end: Tuple[int, int]):
|
def send_cursor(self, id: str, start: Tuple[int, int], end: Tuple[int, int]):
|
||||||
# we can safely ignore the promise, we don't really care if everything
|
# we can safely ignore the promise, we don't really care if everything
|
||||||
|
|
Loading…
Reference in a new issue