mirror of
https://github.com/hexedtech/codemp-sublime.git
synced 2024-11-21 14:24:49 +01:00
disables using change_id()
as it was introducing complications.
moved view population outside of buffer adding, but it is still broken.
This commit is contained in:
parent
904c27c6d5
commit
017f43a922
6 changed files with 64 additions and 43 deletions
8
main.py
8
main.py
|
@ -94,9 +94,11 @@ class CodempBrowseServerCommand(sublime_plugin.WindowCommand):
|
||||||
|
|
||||||
|
|
||||||
class CodempReplaceTextCommand(sublime_plugin.TextCommand):
|
class CodempReplaceTextCommand(sublime_plugin.TextCommand):
|
||||||
def run(self, edit, start, end, content, change_id):
|
def run(self, edit, start, end, content, change_id = None):
|
||||||
# we modify the region to account for any change that happened in the mean time
|
# we modify the region to account for any change that happened in the mean time
|
||||||
region = self.view.transform_region_from(sublime.Region(start, end), change_id)
|
region = sublime.Region(start, end)
|
||||||
|
if change_id:
|
||||||
|
region = self.view.transform_region_from(sublime.Region(start, end), change_id)
|
||||||
self.view.replace(edit, region, content)
|
self.view.replace(edit, region, content)
|
||||||
|
|
||||||
|
|
||||||
|
@ -155,7 +157,7 @@ class CodempClientViewEventListener(sublime_plugin.ViewEventListener):
|
||||||
return
|
return
|
||||||
|
|
||||||
vws.send_cursor(vbuff.id, start, end)
|
vws.send_cursor(vbuff.id, start, end)
|
||||||
logger.debug(f"selection modified! {vws.id}, {vbuff.id} - {start}, {end}")
|
# logger.debug(f"selection modified! {vws.id}, {vbuff.id} - {start}, {end}")
|
||||||
|
|
||||||
def on_activated(self):
|
def on_activated(self):
|
||||||
logger.debug(f"'{self.view}' view activated!")
|
logger.debug(f"'{self.view}' view activated!")
|
||||||
|
|
|
@ -7,7 +7,7 @@ from ..core.workspace import workspaces
|
||||||
from ..core.buffers import buffers
|
from ..core.buffers import buffers
|
||||||
|
|
||||||
from ..text_listener import TEXT_LISTENER
|
from ..text_listener import TEXT_LISTENER
|
||||||
from ..utils import safe_listener_attach, safe_listener_detach
|
from ..utils import safe_listener_attach, safe_listener_detach, populate_view
|
||||||
from ..input_handlers import SimpleListInput, SimpleTextInput
|
from ..input_handlers import SimpleListInput, SimpleTextInput
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -67,11 +67,11 @@ class CodempJoinBufferCommand(sublime_plugin.WindowCommand):
|
||||||
|
|
||||||
# now we can defer the attaching process
|
# now we can defer the attaching process
|
||||||
logger.debug(f"attempting to attach to {buffer_id}...")
|
logger.debug(f"attempting to attach to {buffer_id}...")
|
||||||
promise = vws.handle.attach_buffer(buffer_id)
|
ctl_promise = vws.handle.attach_buffer(buffer_id)
|
||||||
|
|
||||||
def _():
|
def _():
|
||||||
try:
|
try:
|
||||||
buff_ctl = promise.wait()
|
buff_ctl = ctl_promise.wait()
|
||||||
logger.debug("attach successfull!")
|
logger.debug("attach successfull!")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"error when attaching to buffer '{id}':\n\n {e}")
|
logging.error(f"error when attaching to buffer '{id}':\n\n {e}")
|
||||||
|
@ -79,8 +79,11 @@ class CodempJoinBufferCommand(sublime_plugin.WindowCommand):
|
||||||
return
|
return
|
||||||
|
|
||||||
safe_listener_detach(TEXT_LISTENER)
|
safe_listener_detach(TEXT_LISTENER)
|
||||||
|
content_promise = buff_ctl.content()
|
||||||
vbuff = buffers.add(buff_ctl, vws)
|
vbuff = buffers.add(buff_ctl, vws)
|
||||||
|
|
||||||
|
content = content_promise.wait()
|
||||||
|
populate_view(vbuff.view, content)
|
||||||
if self.window.active_view() == vbuff.view:
|
if self.window.active_view() == vbuff.view:
|
||||||
# if view is already active focusing it won't trigger `on_activate`.
|
# if view is already active focusing it won't trigger `on_activate`.
|
||||||
safe_listener_attach(TEXT_LISTENER, vbuff.view.buffer())
|
safe_listener_attach(TEXT_LISTENER, vbuff.view.buffer())
|
||||||
|
@ -115,8 +118,8 @@ class CodempLeaveBufferCommand(sublime_plugin.WindowCommand):
|
||||||
buffers.lookupId(buffer_id)
|
buffers.lookupId(buffer_id)
|
||||||
vws = workspaces.lookupId(workspace_id)
|
vws = workspaces.lookupId(workspace_id)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
sublime.error_message(f"You are not attached to the buffer '{id}'")
|
sublime.error_message(f"You are not attached to the buffer '{buffer_id}'")
|
||||||
logging.warning(f"You are not attached to the buffer '{id}'")
|
logging.warning(f"You are not attached to the buffer '{buffer_id}'")
|
||||||
return
|
return
|
||||||
|
|
||||||
if not vws.handle.get_buffer(buffer_id):
|
if not vws.handle.get_buffer(buffer_id):
|
||||||
|
|
|
@ -7,10 +7,12 @@ if TYPE_CHECKING:
|
||||||
import sublime
|
import sublime
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
import threading
|
||||||
|
|
||||||
from codemp import TextChange
|
from codemp import TextChange
|
||||||
from .. import globals as g
|
from .. import globals as g
|
||||||
from ..utils import populate_view
|
from ..utils import populate_view
|
||||||
|
from ..utils import get_contents
|
||||||
from ..utils import safe_listener_attach
|
from ..utils import safe_listener_attach
|
||||||
from ..utils import safe_listener_detach
|
from ..utils import safe_listener_detach
|
||||||
from ..utils import bidict
|
from ..utils import bidict
|
||||||
|
@ -18,44 +20,54 @@ from ..utils import bidict
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
def bind_callback(v: sublime.View):
|
def bind_callback(v: sublime.View):
|
||||||
|
# we need this lock to prevent multiple instance of try_recv() to spin up
|
||||||
|
# which would cause out of order insertion of changes.
|
||||||
|
multi_tryrecv_lock = threading.Lock()
|
||||||
|
|
||||||
def _callback(bufctl: codemp.BufferController):
|
def _callback(bufctl: codemp.BufferController):
|
||||||
def _():
|
def _():
|
||||||
change_id = v.change_id()
|
try:
|
||||||
while buffup := bufctl.try_recv().wait():
|
# change_id = v.change_id()
|
||||||
logger.debug("received remote buffer change!")
|
change_id = None
|
||||||
if buffup is None:
|
while buffup := bufctl.try_recv().wait():
|
||||||
break
|
logger.debug("received remote buffer change!")
|
||||||
|
if buffup is None:
|
||||||
|
break
|
||||||
|
|
||||||
if buffup.change.is_empty():
|
if buffup.change.is_empty():
|
||||||
logger.debug("change is empty. skipping.")
|
logger.debug("change is empty. skipping.")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# In case a change arrives to a background buffer, just apply it.
|
# In case a change arrives to a background buffer, just apply it.
|
||||||
# We are not listening on it. Otherwise, interrupt the listening
|
# We are not listening on it. Otherwise, interrupt the listening
|
||||||
# to avoid echoing back the change just received.
|
# to avoid echoing back the change just received.
|
||||||
if v == sublime.active_window().active_view():
|
if v == sublime.active_window().active_view():
|
||||||
v.settings()[g.CODEMP_IGNORE_NEXT_TEXT_CHANGE] = True
|
v.settings()[g.CODEMP_IGNORE_NEXT_TEXT_CHANGE] = True
|
||||||
|
# we need to go through a sublime text command, since the method,
|
||||||
|
# view.replace needs an edit token, that is obtained only when calling
|
||||||
|
# a textcommand associated with a view.
|
||||||
|
|
||||||
|
|
||||||
# we need to go through a sublime text command, since the method,
|
|
||||||
# view.replace needs an edit token, that is obtained only when calling
|
|
||||||
# a textcommand associated with a view.
|
|
||||||
try:
|
|
||||||
change = buffup.change
|
change = buffup.change
|
||||||
v.run_command(
|
v.run_command(
|
||||||
"codemp_replace_text",
|
"codemp_replace_text",
|
||||||
{
|
{
|
||||||
"start": change.start,
|
"start": change.start_idx,
|
||||||
"end": change.end,
|
"end": change.end_idx,
|
||||||
"content": change.content,
|
"content": change.content,
|
||||||
"change_id": change_id,
|
"change_id": change_id,
|
||||||
}, # pyright: ignore
|
}, # pyright: ignore
|
||||||
)
|
)
|
||||||
except Exception as e:
|
|
||||||
raise e
|
|
||||||
|
|
||||||
bufctl.ack(buffup.version)
|
bufctl.ack(buffup.version)
|
||||||
sublime.set_timeout(_)
|
except Exception as e:
|
||||||
|
raise e
|
||||||
|
finally:
|
||||||
|
logger.debug("releasing lock")
|
||||||
|
multi_tryrecv_lock.release()
|
||||||
|
|
||||||
|
if multi_tryrecv_lock.acquire(blocking=False):
|
||||||
|
logger.debug("acquiring lock")
|
||||||
|
sublime.set_timeout(_)
|
||||||
return _callback
|
return _callback
|
||||||
|
|
||||||
class BufferManager():
|
class BufferManager():
|
||||||
|
@ -78,11 +90,11 @@ class BufferManager():
|
||||||
# sequential indexing, assuming the changes are applied in the order they are received.
|
# sequential indexing, assuming the changes are applied in the order they are received.
|
||||||
for change in changes:
|
for change in changes:
|
||||||
region = sublime.Region(change.a.pt, change.b.pt)
|
region = sublime.Region(change.a.pt, change.b.pt)
|
||||||
logger.debug(
|
# logger.debug(
|
||||||
"sending txt change: Reg({} {}) -> '{}'".format(
|
# "sending txt change: Reg({} {}) -> '{}'".format(
|
||||||
region.begin(), region.end(), change.str
|
# region.begin(), region.end(), change.str
|
||||||
)
|
# )
|
||||||
)
|
# )
|
||||||
|
|
||||||
# we must block and wait the send request to make sure the change went through ok
|
# we must block and wait the send request to make sure the change went through ok
|
||||||
self.handle.send(TextChange(start=region.begin(), end=region.end(), content=change.str))
|
self.handle.send(TextChange(start=region.begin(), end=region.end(), content=change.str))
|
||||||
|
@ -91,9 +103,14 @@ class BufferManager():
|
||||||
promise = self.handle.content()
|
promise = self.handle.content()
|
||||||
def _():
|
def _():
|
||||||
content = promise.wait()
|
content = promise.wait()
|
||||||
|
current_contents = get_contents(self.view)
|
||||||
|
if content == current_contents:
|
||||||
|
return
|
||||||
|
|
||||||
safe_listener_detach(text_listener)
|
safe_listener_detach(text_listener)
|
||||||
populate_view(self.view, content)
|
populate_view(self.view, content)
|
||||||
safe_listener_attach(text_listener, self.view.buffer())
|
safe_listener_attach(text_listener, self.view.buffer())
|
||||||
|
sublime.status_message("Syncd contents.")
|
||||||
sublime.set_timeout_async(_)
|
sublime.set_timeout_async(_)
|
||||||
|
|
||||||
class BufferRegistry():
|
class BufferRegistry():
|
||||||
|
@ -120,8 +137,7 @@ class BufferRegistry():
|
||||||
bid = bhandle.path()
|
bid = bhandle.path()
|
||||||
# tmpfile = os.path.join(wsm.rootdir, bid)
|
# tmpfile = os.path.join(wsm.rootdir, bid)
|
||||||
# open(tmpfile, "a").close()
|
# open(tmpfile, "a").close()
|
||||||
content = bhandle.content()
|
|
||||||
|
|
||||||
win = sublime.active_window()
|
win = sublime.active_window()
|
||||||
view = win.open_file(bid)
|
view = win.open_file(bid)
|
||||||
view.set_scratch(True)
|
view.set_scratch(True)
|
||||||
|
@ -129,7 +145,6 @@ class BufferRegistry():
|
||||||
view.settings().set(g.CODEMP_VIEW_TAG, True)
|
view.settings().set(g.CODEMP_VIEW_TAG, True)
|
||||||
view.settings().set(g.CODEMP_BUFFER_ID, bid)
|
view.settings().set(g.CODEMP_BUFFER_ID, bid)
|
||||||
view.set_status(g.SUBLIME_STATUS_ID, "[Codemp]")
|
view.set_status(g.SUBLIME_STATUS_ID, "[Codemp]")
|
||||||
populate_view(view, content.wait())
|
|
||||||
|
|
||||||
tmpfile = "DISABLE"
|
tmpfile = "DISABLE"
|
||||||
bfm = BufferManager(bhandle, view, tmpfile)
|
bfm = BufferManager(bhandle, view, tmpfile)
|
||||||
|
|
|
@ -51,7 +51,7 @@ def cursor_callback(ctl: codemp.CursorController):
|
||||||
def _():
|
def _():
|
||||||
while event := ctl.try_recv().wait():
|
while event := ctl.try_recv().wait():
|
||||||
if event is None: break
|
if event is None: break
|
||||||
|
|
||||||
try: bfm = buffers.lookupId(event.sel.buffer)
|
try: bfm = buffers.lookupId(event.sel.buffer)
|
||||||
except KeyError: continue
|
except KeyError: continue
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import sublime
|
||||||
import sublime_plugin
|
import sublime_plugin
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ def populate_view(view, content):
|
||||||
"start": 0,
|
"start": 0,
|
||||||
"end": view.size(),
|
"end": view.size(),
|
||||||
"content": content,
|
"content": content,
|
||||||
"change_id": view.change_id(),
|
"change_id": None,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ def draw_cursor_region(view, start, end, user):
|
||||||
reg_flags = sublime.RegionFlags.DRAW_EMPTY
|
reg_flags = sublime.RegionFlags.DRAW_EMPTY
|
||||||
|
|
||||||
user_hash = hash(user)
|
user_hash = hash(user)
|
||||||
|
|
||||||
view.add_regions(
|
view.add_regions(
|
||||||
f"{g.SUBLIME_REGIONS_PREFIX}-{user_hash}",
|
f"{g.SUBLIME_REGIONS_PREFIX}-{user_hash}",
|
||||||
[reg],
|
[reg],
|
||||||
|
|
Loading…
Reference in a new issue