mirror of
https://github.com/hexedtech/codemp-sublime.git
synced 2024-11-23 23:34:48 +01:00
switched to more solid (but uglier) way to check for input focus.
Changed how to get from a sublime view to a virtual buffer by means of tags. (maybe slow) added some syntactic sugar Former-commit-id: 2003fe0838af7e47258c6d10d84e2142dfa3da1b
This commit is contained in:
parent
ff883c8e58
commit
fa5f03bd6b
3 changed files with 48 additions and 22 deletions
27
plugin.py
27
plugin.py
|
@ -84,15 +84,17 @@ class EventListener(sublime_plugin.EventListener):
|
||||||
class CodempClientViewEventListener(sublime_plugin.ViewEventListener):
|
class CodempClientViewEventListener(sublime_plugin.ViewEventListener):
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_applicable(cls, settings):
|
def is_applicable(cls, settings):
|
||||||
return settings.get(g.CODEMP_BUFFER_VIEW_TAG, False)
|
return settings.get(g.CODEMP_BUFFER_TAG, False)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def applies_to_primary_view_only(cls):
|
def applies_to_primary_view_only(cls):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def on_selection_modified_async(self):
|
def on_selection_modified_async(self):
|
||||||
|
s = self.view.settings()
|
||||||
|
|
||||||
global CLIENT
|
global CLIENT
|
||||||
vbuff = CLIENT.active_workspace.get_by_local(self.view.buffer_id())
|
vbuff = CLIENT[s[g.CODEMP_WORKSPACE_ID]].get_by_local(self.view.buffer_id())
|
||||||
if vbuff is not None:
|
if vbuff is not None:
|
||||||
CLIENT.send_cursor(vbuff)
|
CLIENT.send_cursor(vbuff)
|
||||||
|
|
||||||
|
@ -101,21 +103,26 @@ class CodempClientViewEventListener(sublime_plugin.ViewEventListener):
|
||||||
# When we defocus, we detach it.
|
# When we defocus, we detach it.
|
||||||
def on_activated(self):
|
def on_activated(self):
|
||||||
global TEXT_LISTENER
|
global TEXT_LISTENER
|
||||||
|
|
||||||
|
g.ACTIVE_CODEMP_VIEW = self.view.id()
|
||||||
print("view {} activated".format(self.view.id()))
|
print("view {} activated".format(self.view.id()))
|
||||||
TEXT_LISTENER.attach(self.view.buffer())
|
TEXT_LISTENER.attach(self.view.buffer())
|
||||||
|
|
||||||
def on_deactivated(self):
|
def on_deactivated(self):
|
||||||
global TEXT_LISTENER
|
global TEXT_LISTENER
|
||||||
|
|
||||||
|
g.ACTIVE_CODEMP_VIEW = None
|
||||||
print("view {} deactivated".format(self.view.id()))
|
print("view {} deactivated".format(self.view.id()))
|
||||||
safe_listener_detach(TEXT_LISTENER)
|
safe_listener_detach(TEXT_LISTENER)
|
||||||
|
|
||||||
def on_pre_close(self):
|
def on_pre_close(self):
|
||||||
global TEXT_LISTENER
|
global TEXT_LISTENER
|
||||||
if is_active(self.view):
|
if self.view.id() == g.ACTIVE_CODEMP_VIEW:
|
||||||
safe_listener_detach(TEXT_LISTENER)
|
safe_listener_detach(TEXT_LISTENER)
|
||||||
|
|
||||||
global CLIENT
|
global CLIENT
|
||||||
vbuff = CLIENT.active_workspace.get_by_local(self.view.buffer_id())
|
wsid = self.view.settings().get(g.CODEMP_WORKSPACE_ID)
|
||||||
|
vbuff = CLIENT[wsid].get_by_local(self.view.buffer_id())
|
||||||
vbuff.cleanup()
|
vbuff.cleanup()
|
||||||
|
|
||||||
CLIENT.tm.stop_and_pop(f"{g.BUFFCTL_TASK_PREFIX}-{vbuff.codemp_id}")
|
CLIENT.tm.stop_and_pop(f"{g.BUFFCTL_TASK_PREFIX}-{vbuff.codemp_id}")
|
||||||
|
@ -132,17 +139,14 @@ class CodempClientTextChangeListener(sublime_plugin.TextChangeListener):
|
||||||
|
|
||||||
# blocking :D
|
# blocking :D
|
||||||
def on_text_changed(self, changes):
|
def on_text_changed(self, changes):
|
||||||
if (
|
s = self.buffer.primary_view().settings()
|
||||||
self.buffer.primary_view()
|
if s.get(g.CODEMP_IGNORE_NEXT_TEXT_CHANGE, None):
|
||||||
.settings()
|
|
||||||
.get(g.CODEMP_IGNORE_NEXT_TEXT_CHANGE, None)
|
|
||||||
):
|
|
||||||
status_log("ignoring echoing back the change.")
|
status_log("ignoring echoing back the change.")
|
||||||
self.view.settings()[g.CODEMP_IGNORE_NEXT_TEXT_CHANGE] = False
|
s[g.CODEMP_IGNORE_NEXT_TEXT_CHANGE] = False
|
||||||
return
|
return
|
||||||
|
|
||||||
global CLIENT
|
global CLIENT
|
||||||
vbuff = CLIENT.active_workspace.get_by_local(self.buffer.id())
|
vbuff = CLIENT[s[g.CODEMP_WORKSPACE_ID]].get_by_local(self.buffer.id())
|
||||||
CLIENT.send_buffer_change(changes, vbuff)
|
CLIENT.send_buffer_change(changes, vbuff)
|
||||||
|
|
||||||
|
|
||||||
|
@ -250,7 +254,6 @@ class ListBufferIdInputHandler(sublime_plugin.ListInputHandler):
|
||||||
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):
|
||||||
# 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
|
||||||
print("running the replace command, launche manually.")
|
|
||||||
region = self.view.transform_region_from(sublime.Region(start, end), 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)
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import asyncio # noqa: F401
|
||||||
import typing # noqa: F401
|
import typing # noqa: F401
|
||||||
import tempfile
|
import tempfile
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
|
||||||
import Codemp.src.globals as g
|
import Codemp.src.globals as g
|
||||||
|
@ -42,13 +43,19 @@ class VirtualBuffer:
|
||||||
self.view.set_scratch(True)
|
self.view.set_scratch(True)
|
||||||
|
|
||||||
# mark the view as a codemp view
|
# mark the view as a codemp view
|
||||||
|
s = self.view.settings()
|
||||||
self.view.set_status(g.SUBLIME_STATUS_ID, "[Codemp]")
|
self.view.set_status(g.SUBLIME_STATUS_ID, "[Codemp]")
|
||||||
self.view.settings()[g.CODEMP_BUFFER_VIEW_TAG] = True
|
s[g.CODEMP_BUFFER_TAG] = True
|
||||||
|
s[g.CODEMP_REMOTE_ID] = self.codemp_id
|
||||||
|
s[g.CODEMP_WORKSPACE_ID] = self.workspace.id
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
os.remove(self.tmpfile)
|
os.remove(self.tmpfile)
|
||||||
# cleanup views
|
# cleanup views
|
||||||
del self.view.settings()[g.CODEMP_BUFFER_VIEW_TAG]
|
s = self.view.settings()
|
||||||
|
del s[g.CODEMP_BUFFER_TAG]
|
||||||
|
del s[g.CODEMP_REMOTE_ID]
|
||||||
|
del s[g.CODEMP_WORKSPACE_ID]
|
||||||
self.view.erase_status(g.SUBLIME_STATUS_ID)
|
self.view.erase_status(g.SUBLIME_STATUS_ID)
|
||||||
# this does nothing for now. figure out a way later
|
# this does nothing for now. figure out a way later
|
||||||
# self.view.erase_regions(g.SUBLIME_REGIONS_PREFIX)
|
# self.view.erase_regions(g.SUBLIME_REGIONS_PREFIX)
|
||||||
|
@ -65,7 +72,7 @@ class VirtualWorkspace:
|
||||||
self.handle = handle
|
self.handle = handle
|
||||||
self.curctl = handle.cursor()
|
self.curctl = handle.cursor()
|
||||||
|
|
||||||
# mapping local buffer ids -> remote ids
|
# mapping remote ids -> local ids
|
||||||
self.id_map: dict[str, str] = {}
|
self.id_map: dict[str, str] = {}
|
||||||
self.active_buffers: dict[str, VirtualBuffer] = {}
|
self.active_buffers: dict[str, VirtualBuffer] = {}
|
||||||
|
|
||||||
|
@ -85,8 +92,8 @@ class VirtualWorkspace:
|
||||||
self.sublime_window.set_project_data(proj_data)
|
self.sublime_window.set_project_data(proj_data)
|
||||||
|
|
||||||
def add_buffer(self, remote_id: str, vbuff: VirtualBuffer):
|
def add_buffer(self, remote_id: str, vbuff: VirtualBuffer):
|
||||||
self.id_map[vbuff.view.buffer_id()] = remote_id
|
self.id_map[remote_id] = vbuff.view.buffer_id()
|
||||||
self.active_buffers[remote_id] = vbuff
|
self.active_buffers[vbuff.view.buffer_id()] = vbuff
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
# the worskpace only cares about closing the various open views on its buffers.
|
# the worskpace only cares about closing the various open views on its buffers.
|
||||||
|
@ -104,13 +111,13 @@ class VirtualWorkspace:
|
||||||
d["folders"] = newf
|
d["folders"] = newf
|
||||||
self.sublime_window.set_project_data(d)
|
self.sublime_window.set_project_data(d)
|
||||||
status_log(f"cleaning up virtual workspace '{self.id}'")
|
status_log(f"cleaning up virtual workspace '{self.id}'")
|
||||||
os.removedirs(self.rootdir)
|
shutil.rmtree(self.rootdir, ignore_errors=True)
|
||||||
|
|
||||||
def get_by_local(self, local_id: str) -> Optional[VirtualBuffer]:
|
def get_by_local(self, local_id: str) -> Optional[VirtualBuffer]:
|
||||||
return self.active_buffers.get(self.id_map.get(local_id))
|
return self.active_buffers.get(local_id)
|
||||||
|
|
||||||
def get_by_remote(self, remote_id: str) -> Optional[VirtualBuffer]:
|
def get_by_remote(self, remote_id: str) -> Optional[VirtualBuffer]:
|
||||||
return self.active_buffers.get(remote_id)
|
return self.active_buffers.get(self.id_map.get(remote_id))
|
||||||
|
|
||||||
async def attach(self, id: str):
|
async def attach(self, id: str):
|
||||||
if id is None:
|
if id is None:
|
||||||
|
@ -149,6 +156,9 @@ class VirtualClient:
|
||||||
self.active_workspace: VirtualWorkspace = None
|
self.active_workspace: VirtualWorkspace = None
|
||||||
self.tm = TaskManager(on_exit)
|
self.tm = TaskManager(on_exit)
|
||||||
|
|
||||||
|
def __getitem__(self, key: str):
|
||||||
|
return self.workspaces.get(key)
|
||||||
|
|
||||||
def make_active(self, ws: VirtualWorkspace):
|
def make_active(self, ws: VirtualWorkspace):
|
||||||
# TODO: Logic to deal with swapping to and from workspaces,
|
# TODO: Logic to deal with swapping to and from workspaces,
|
||||||
# what happens to the cursor tasks etc..
|
# what happens to the cursor tasks etc..
|
||||||
|
@ -157,6 +167,12 @@ class VirtualClient:
|
||||||
self.active_workspace = ws
|
self.active_workspace = ws
|
||||||
self.spawn_cursor_manager(ws)
|
self.spawn_cursor_manager(ws)
|
||||||
|
|
||||||
|
def get_by_local(self, id):
|
||||||
|
for vws in self.workspaces.values():
|
||||||
|
vbuff = vws.get_by_local(id)
|
||||||
|
if vbuff is not None:
|
||||||
|
return
|
||||||
|
|
||||||
async def connect(self, server_host: str):
|
async def connect(self, server_host: str):
|
||||||
status_log(f"Connecting to {server_host}")
|
status_log(f"Connecting to {server_host}")
|
||||||
try:
|
try:
|
||||||
|
@ -248,7 +264,10 @@ class VirtualClient:
|
||||||
# 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 is_active(vb.view):
|
if vb.view.id() == g.ACTIVE_CODEMP_VIEW:
|
||||||
|
status_log(
|
||||||
|
"received a text change with view active, stopping the echo."
|
||||||
|
)
|
||||||
vb.view.settings()[g.CODEMP_IGNORE_NEXT_TEXT_CHANGE] = True
|
vb.view.settings()[g.CODEMP_IGNORE_NEXT_TEXT_CHANGE] = True
|
||||||
|
|
||||||
# we need to go through a sublime text command, since the method,
|
# we need to go through a sublime text command, since the method,
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
BUFFCTL_TASK_PREFIX = "buffer-ctl"
|
BUFFCTL_TASK_PREFIX = "buffer-ctl"
|
||||||
CURCTL_TASK_PREFIX = "cursor-ctl"
|
CURCTL_TASK_PREFIX = "cursor-ctl"
|
||||||
|
CODEMP_BUFFER_TAG = "codemp-buffer"
|
||||||
|
CODEMP_REMOTE_ID = "codemp-buffer-id"
|
||||||
|
CODEMP_WORKSPACE_ID = "codemp-workspace-id"
|
||||||
|
|
||||||
WORKSPACE_FOLDER_PREFIX = "CODEMP::"
|
WORKSPACE_FOLDER_PREFIX = "CODEMP::"
|
||||||
SUBLIME_REGIONS_PREFIX = "codemp-cursors"
|
SUBLIME_REGIONS_PREFIX = "codemp-cursors"
|
||||||
CODEMP_BUFFER_VIEW_TAG = "codemp-buffer"
|
|
||||||
SUBLIME_STATUS_ID = "z_codemp_buffer"
|
SUBLIME_STATUS_ID = "z_codemp_buffer"
|
||||||
CODEMP_IGNORE_NEXT_TEXT_CHANGE = "codemp-skip-change-event"
|
CODEMP_IGNORE_NEXT_TEXT_CHANGE = "codemp-skip-change-event"
|
||||||
|
ACTIVE_CODEMP_VIEW = None
|
||||||
|
|
||||||
PALETTE = [
|
PALETTE = [
|
||||||
"var(--redish)",
|
"var(--redish)",
|
||||||
|
|
Loading…
Reference in a new issue