mirror of
https://github.com/hexedtech/codemp-sublime.git
synced 2024-11-22 06:44:48 +01:00
Minor fixes in the lib, finished the python objects wrappers. Started working on plugin.py.
Former-commit-id: 3a5e587b1ba019bb9a263478cd2e08b9b532322e
This commit is contained in:
parent
e387b726c8
commit
6fe5effb68
4 changed files with 104 additions and 64 deletions
|
@ -1 +1 @@
|
|||
80ba7b16f0b0647e2f1d8520f3a90c51000bbd2c
|
||||
8114809f135d7ea9f88d0a45a9de8fc93fdbd9ff
|
36
plugin.py
36
plugin.py
|
@ -9,9 +9,9 @@ import time
|
|||
|
||||
# UGLYYYY, find a way to not have global variables laying around.
|
||||
_tasks = []
|
||||
_client = CodempClient()
|
||||
_client = None
|
||||
_cursor_controller = None
|
||||
_op_controller = None
|
||||
_buffer_controller = None
|
||||
_setting_key = "codemp_buffer"
|
||||
|
||||
def store_task(name = None):
|
||||
|
@ -23,6 +23,8 @@ def store_task(name = None):
|
|||
return store_named_task
|
||||
|
||||
def plugin_loaded():
|
||||
global _client
|
||||
_client = CodempClient()
|
||||
sublime_asyncio.acquire() # instantiate and start a global event loop.
|
||||
|
||||
class CodempClientViewEventListener(sublime_plugin.ViewEventListener):
|
||||
|
@ -47,24 +49,24 @@ class CodempClientTextChangeListener(sublime_plugin.TextChangeListener):
|
|||
return False
|
||||
|
||||
def on_text_changed(self, changes):
|
||||
global _op_controller
|
||||
if _op_controller:
|
||||
global _buffer_controller
|
||||
if _buffer_controller:
|
||||
for change in changes:
|
||||
sublime_asyncio.dispatch(apply_changes(change))
|
||||
|
||||
async def apply_changes(change):
|
||||
global _op_controller
|
||||
global _buffer_controller
|
||||
|
||||
text = change.str
|
||||
skip = change.a.pt
|
||||
if change.len_utf8 == 0: # we are inserting new text.
|
||||
tail = len(_op_controller.get_content()) - skip
|
||||
tail = len(_buffer_controller.get_content()) - skip
|
||||
else: # we are changing an existing region of text of length len_utf8
|
||||
tail = len(_op_controller.get_content()) - skip - change.len_utf8
|
||||
tail = len(_buffer_controller.get_content()) - skip - change.len_utf8
|
||||
|
||||
tail_skip = len(_op_controller.get_content()) - tail
|
||||
tail_skip = len(_buffer_controller.get_content()) - tail
|
||||
print("[buff change]", skip, text, tail_skip)
|
||||
await _op_controller.apply(skip, text, tail)
|
||||
await _buffer_controller.apply(skip, text, tail)
|
||||
|
||||
async def make_connection(server_host):
|
||||
global _client
|
||||
|
@ -90,7 +92,7 @@ async def sync_buffer(caller, start, end, txt):
|
|||
async def share_buffer(buffer):
|
||||
global _client
|
||||
global _cursor_controller
|
||||
global _op_controller
|
||||
global _buffer_controller
|
||||
|
||||
if not _client.ready:
|
||||
sublime.error_message("No connected client.")
|
||||
|
@ -106,8 +108,8 @@ async def share_buffer(buffer):
|
|||
sublime.error_message("Could not share buffer.")
|
||||
return
|
||||
|
||||
_op_controller = await _client.attach(buffer)
|
||||
_op_controller.callback(sync_buffer, _client.id)
|
||||
_buffer_controller = await _client.attach(buffer)
|
||||
_buffer_controller.callback(sync_buffer, _client.id)
|
||||
|
||||
_cursor_controller = await _client.listen()
|
||||
_cursor_controller.callback(move_cursor, _client.id)
|
||||
|
@ -115,7 +117,7 @@ async def share_buffer(buffer):
|
|||
if not _cursor_controller:
|
||||
sublime.error_message("Could not subsribe a listener.")
|
||||
return
|
||||
if not _op_controller:
|
||||
if not _buffer_controller:
|
||||
sublime.error_message("Could not attach to the buffer.")
|
||||
return
|
||||
|
||||
|
@ -127,7 +129,7 @@ async def share_buffer(buffer):
|
|||
async def join_buffer(window, buffer):
|
||||
global _client
|
||||
global _cursor_controller
|
||||
global _op_controller
|
||||
global _buffer_controller
|
||||
|
||||
if not _client.ready:
|
||||
sublime.error_message("No connected client.")
|
||||
|
@ -138,8 +140,8 @@ async def join_buffer(window, buffer):
|
|||
sublime.status_message("[codemp] Joining buffer {}".format(buffer))
|
||||
print("[codemp] Joining buffer {}".format(buffer))
|
||||
|
||||
_op_controller = await _client.attach(buffer)
|
||||
content = _op_controller.get_content()
|
||||
_buffer_controller = await _client.attach(buffer)
|
||||
content = _buffer_controller.get_content()
|
||||
view.run_command("codemp_replace_view", {"content": content})
|
||||
|
||||
_cursor_controller = await _client.listen()
|
||||
|
@ -149,7 +151,7 @@ async def join_buffer(window, buffer):
|
|||
if not _cursor_controller:
|
||||
sublime.error_message("Could not subsribe a listener.")
|
||||
return
|
||||
if not _op_controller:
|
||||
if not _buffer_controller:
|
||||
sublime.error_message("Could not attach to the buffer.")
|
||||
return
|
||||
|
||||
|
|
|
@ -4,68 +4,109 @@ import Codemp.bindings.codemp_client as libcodemp
|
|||
class CodempClient():
|
||||
|
||||
def __init__(self):
|
||||
self.handle = None
|
||||
self.id = None
|
||||
self.handle = libcodemp.codemp_init()
|
||||
self.ready = False
|
||||
|
||||
async def connect(self, server_host):
|
||||
self.handle = await libcodemp.connect(server_host)
|
||||
self.id = await self.handle.get_id()
|
||||
async def connect(self, server_host): # -> None
|
||||
await self.handle.connect(server_host)
|
||||
self.ready = True
|
||||
|
||||
def disconnect(self):
|
||||
def disconnect(self): # -> None
|
||||
# disconnect all buffers
|
||||
# stop all callbacks
|
||||
self.handle = None
|
||||
self.id = None
|
||||
self.ready = False
|
||||
# some code that tells the server to unsubscribe stuff as well.
|
||||
|
||||
async def get_id(self):
|
||||
if self.ready and not self.id:
|
||||
self.id = await self.handle.get_id()
|
||||
return self.id
|
||||
elif self.ready:
|
||||
return self.id
|
||||
else:
|
||||
raise RuntimeError("Attemp to get id without an established connection.")
|
||||
|
||||
async def create(self, path, content=None):
|
||||
async def create(self, path, content=None): # -> None
|
||||
if self.ready:
|
||||
return await self.handle.create(path, content)
|
||||
else:
|
||||
raise RuntimeError("Attemp to create a buffer without a connection.")
|
||||
|
||||
async def listen(self):
|
||||
async def join(self, session): # -> CursorController
|
||||
if self.ready:
|
||||
return CursorController(await self.handle.listen())
|
||||
else:
|
||||
raise RuntimeError("Attempt to listen without a connection.")
|
||||
return CursorController(await self.handle.join(session))
|
||||
|
||||
async def attach(self, path):
|
||||
async def attach(self, path): # -> BufferController
|
||||
if self.ready:
|
||||
return ContentController(await self.handle.attach(path))
|
||||
else:
|
||||
raise RuntimeError("Attempt to attach without a connection.")
|
||||
return BufferController(await self.handle.attach(path))
|
||||
|
||||
async def get_cursor(self): # -> CursorController
|
||||
if self.ready:
|
||||
return CursorController(await self.handle.get_cursor())
|
||||
|
||||
async def get_buffer(self, path): # -> BufferController
|
||||
if self.ready:
|
||||
return BufferController(await self.handle.get_buffer())
|
||||
|
||||
async def remove_buffer(self, path): # -> None
|
||||
if self.ready:
|
||||
await self.handle.disconnect_buffer(path)
|
||||
|
||||
class CursorController():
|
||||
def __init__(self, handle):
|
||||
self.handle = handle
|
||||
|
||||
async def send(self, path, start, end):
|
||||
await self.handle.send(path, start, end)
|
||||
def send(self, path, start, end): # -> None
|
||||
self.handle.send(path, start, end)
|
||||
|
||||
def callback(self, coro, id):
|
||||
def try_recv(self): # -> Optional[CursorEvent]
|
||||
return self.handle.try_recv()
|
||||
|
||||
async def recv(self): # -> CursorEvent
|
||||
return await self.handle.recv()
|
||||
|
||||
async def poll(self): # -> None
|
||||
# await until new cursor event, then returns
|
||||
return await self.handle.poll()
|
||||
|
||||
def drop_callback(self): # -> None
|
||||
self.handle.drop_callback()
|
||||
|
||||
def callback(self, coro): # -> None
|
||||
self.handle.callback(coro, id)
|
||||
|
||||
class ContentController():
|
||||
class BufferController():
|
||||
def __init__(self, handle):
|
||||
self.handle = handle
|
||||
|
||||
def get_content(self):
|
||||
def get_content(self): # -> String
|
||||
return self.handle.content()
|
||||
|
||||
async def apply(self, skip, text, tail):
|
||||
return await self.handle.apply(skip, text, tail)
|
||||
def replace(self, txt): # -> None
|
||||
# replace the whole buffer.
|
||||
self.handle.replace(txt)
|
||||
|
||||
def insert(self, txt, pos): # -> None
|
||||
# insert text at buffer position pos
|
||||
self.handle.insert(txt, pos)
|
||||
|
||||
def delta(self, start, txt, end): # -> None
|
||||
# delta in the region start..end with txt new content
|
||||
self.handle.delta(start, txt, end)
|
||||
|
||||
def delete(self, pos, count): # -> None
|
||||
# delete starting from pos, count chars.
|
||||
self.handle.delete(pos, count)
|
||||
|
||||
def cancel(self, pos, count): # -> None
|
||||
# cancel backward `count` elements from pos.
|
||||
self.handle.cancle(pos, count)
|
||||
|
||||
def try_recv(self): # -> Optional[TextChange]
|
||||
return self.handle.try_recv()
|
||||
|
||||
async def recv(self): # -> TextChange
|
||||
return await self.handle.recv()
|
||||
|
||||
async def poll(self): # -> ??
|
||||
return await self.handle.poll()
|
||||
|
||||
def drop_callback(self): # -> None
|
||||
self.handle.drop_callback()
|
||||
|
||||
def callback(self, coro): # -> None
|
||||
self.handle.callback(coro)
|
||||
|
||||
|
||||
|
||||
|
||||
def callback(self, coro, id):
|
||||
self.handle.callback(coro, id)
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ impl From::<CodempInstance> for PyClientHandle {
|
|||
|
||||
#[pymethods]
|
||||
impl PyClientHandle {
|
||||
|
||||
fn connect<'a>(&'a self, py: Python<'a>, addr: String) ->PyResult<&'a PyAny> {
|
||||
let rc = self.0.clone();
|
||||
|
||||
|
@ -232,7 +233,7 @@ impl PyCursorController {
|
|||
}
|
||||
}
|
||||
|
||||
fn send<'a>(&'a self, py: Python<'a>, path: String, start: (i32, i32), end: (i32, i32)) -> PyResult<&'a PyAny> {
|
||||
fn send<'a>(&'a self, path: String, start: (i32, i32), end: (i32, i32)) -> PyResult<()> {
|
||||
let rc = self.handle.clone();
|
||||
let pos = CodempCursorPosition {
|
||||
buffer: path,
|
||||
|
@ -240,12 +241,8 @@ impl PyCursorController {
|
|||
end: Some(end.into())
|
||||
};
|
||||
|
||||
pyo3_asyncio::tokio::future_into_py(py, async move {
|
||||
rc.send(pos)
|
||||
.map_err(PyCodempError::from)?;
|
||||
rc.send(pos).map_err(PyCodempError::from)?;
|
||||
Ok(())
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
fn try_recv(&self, py: Python<'_>) -> PyResult<PyObject> {
|
||||
|
|
Loading…
Reference in a new issue