Skip to content

Commit e7a3f7f

Browse files
committed
fix: clearer creation of virtual workspaces and buffers.
fix: fix messages formatting fix: handle workspaces without buffers when attaching fix: workspave lookupparent feat: initial setup to support local views
1 parent b79e257 commit e7a3f7f

File tree

4 files changed

+110
-93
lines changed

4 files changed

+110
-93
lines changed

plugin/commands/client.py

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,9 @@ def is_enabled(self):
119119
return session.is_active()
120120

121121
def run(self):
122-
cli = session.client
123-
124-
for ws in workspaces.lookup():
125-
if cli.leave_workspace(ws.id):
126-
workspaces.remove(ws)
122+
wslist = session.client.active_workspaces()
123+
for ws in wslist:
124+
workspaces.remove(ws)
127125

128126
session.drop_client()
129127
logger.info(f"disconnected from server '{session.config.host}'!")
@@ -145,19 +143,11 @@ def input(self, args):
145143
)
146144

147145
def run(self, workspace_id): # pyright: ignore[reportIncompatibleMethodOverride]
148-
if workspace_id is None:
146+
if workspace_id in workspaces:
149147
return
150148

151149
logger.info(f"Joining workspace: '{workspace_id}'...")
152-
try:
153-
ws = session.client.attach_workspace(workspace_id).wait()
154-
except Exception as e:
155-
logger.error(f"Could not join workspace '{workspace_id}': {e}")
156-
sublime.error_message(f"Could not join workspace '{workspace_id}'")
157-
raise e
158-
159-
logger.debug("Joined! Adding workspace to registry")
160-
workspaces.register(ws)
150+
workspaces.register(workspace_id)
161151

162152

163153
# Leave Workspace Command
@@ -172,14 +162,13 @@ def input(self, args):
172162
)
173163

174164
def run(self, workspace_id: str): # pyright: ignore[reportIncompatibleMethodOverride]
175-
try:
176-
workspaces.remove(workspace_id)
177-
finally:
178-
if not session.client.leave_workspace(workspace_id):
179-
logger.error(f"could not leave the workspace '{workspace_id}'")
180-
else:
181-
logger.debug(f"successfully left the workspace '{workspace_id}'")
165+
if workspace_id not in workspaces:
166+
sublime.error_message(f"You are not attached to the workspace '{workspace_id}'")
167+
logger.warning(f"You are not attached to the workspace_id '{workspace_id}'")
168+
return
182169

170+
logger.debug("We are about to remove the workspace {}".format(workspace_id))
171+
workspaces.remove(workspace_id)
183172

184173
class CodempInviteToWorkspaceCommand(sublime_plugin.WindowCommand):
185174
def is_enabled(self) -> bool:
@@ -208,10 +197,6 @@ class CodempCreateWorkspaceCommand(sublime_plugin.WindowCommand):
208197
def is_enabled(self):
209198
return session.is_active()
210199

211-
# def input(self, args):
212-
# if "workspace_id" not in args:
213-
# return SimpleTextInput(("workspace_id", "new workspace name"))
214-
215200
def run(self, workspace_id: str): # pyright: ignore[reportIncompatibleMethodOverride]
216201
try:
217202
session.client.create_workspace(workspace_id)
@@ -224,11 +209,6 @@ class CodempDeleteWorkspaceCommand(sublime_plugin.WindowCommand):
224209
def is_enabled(self):
225210
return session.is_active()
226211

227-
# def input(self, args):
228-
# workspaces = session.get_workspaces(owned=True, invited=False) # noqa: F841
229-
# if "workspace_id" not in args:
230-
# return SimpleListInput(("workspace_id", workspaces))
231-
232212
def run(self, workspace_id: str): # pyright: ignore[reportIncompatibleMethodOverride]
233213
if workspace_id in workspaces:
234214
if not sublime.ok_cancel_dialog(

plugin/commands/workspace.py

Lines changed: 22 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import sublime
22
import sublime_plugin
33
import logging
4-
import gc
4+
import os
55

66
from ..core.session import session
77
from ..core.workspace import workspaces
88
from ..core.buffers import buffers
99

1010
from ..text_listener import TEXT_LISTENER
11-
from ..utils import safe_listener_attach, safe_listener_detach, populate_view
11+
from ..utils import some
1212
from ..input_handlers import SimpleListInput, SimpleTextInput
1313

1414
logger = logging.getLogger(__name__)
@@ -37,11 +37,18 @@ def input(self, args):
3737
return None
3838

3939
bflist = ws.handle.fetch_buffers().wait()
40-
return SimpleListInput(
41-
("buffer_id", bflist),
42-
)
40+
if bflist:
41+
return SimpleListInput(
42+
("buffer_id", bflist)
43+
)
44+
else:
45+
sublime.error_message("Workspace does not have any buffers inside.")
46+
return None
4347

4448
def run(self, workspace_id, buffer_id): # pyright: ignore[reportIncompatibleMethodOverride]
49+
if not buffer_id:
50+
return
51+
4552
try: vws = workspaces.lookupId(workspace_id)
4653
except KeyError:
4754
logger.error(f"Can't create buffer: '{workspace_id}' does not exists or is not active.")
@@ -54,25 +61,14 @@ def run(self, workspace_id, buffer_id): # pyright: ignore[reportIncompatibleMeth
5461
except KeyError:
5562
pass
5663

57-
# now we can defer the attaching process
5864
logger.debug(f"attempting to attach to {buffer_id}...")
59-
ctl_promise = vws.handle.attach_buffer(buffer_id)
6065

6166
def _():
62-
try:
63-
buff_ctl = ctl_promise.wait()
64-
logger.debug("attach successfull!")
65-
except Exception as e:
66-
logger.error(f"error when attaching to buffer '{id}':\n\n {e}")
67-
sublime.error_message(f"Could not attach to buffer '{buffer_id}'")
68-
return
69-
70-
vbuff = buffers.register(buff_ctl, vws)
67+
vbuff = some(buffers.register(buffer_id, vws))
7168
vbuff.sync(TEXT_LISTENER)
7269

7370
sublime.set_timeout_async(_)
7471

75-
7672
# Leave Buffer Comand
7773
class CodempLeaveBufferCommand(sublime_plugin.WindowCommand):
7874
def is_enabled(self):
@@ -88,20 +84,13 @@ def input(self, args):
8884
)
8985

9086
def run(self, buffer_id): # pyright: ignore[reportIncompatibleMethodOverride]
91-
try:
92-
buff = buffers.lookupId(buffer_id)
93-
vws = buffers.lookupParent(buff)
94-
except KeyError:
95-
sublime.error_message(f"You are not attached to the buffer '{buffer_id}'")
96-
logger.warning(f"You are not attached to the buffer '{buffer_id}'")
97-
return
98-
99-
if not vws.handle.get_buffer(buffer_id):
100-
logger.error("The desired buffer is not managed by the workspace.")
87+
if buffer_id not in buffers:
88+
logger.warning(f"The buffer was already removed: '{buffer_id}'")
10189
return
10290

10391
# The call must happen separately, otherwise it causes sublime to crash...
10492
# no idea why...
93+
sublime.set_timeout(lambda: buffers.remove(buffer_id), 10)
10594
def _():
10695
buffers.remove(buffer_id)
10796
if not vws.handle.detach_buffer(buffer_id):
@@ -113,7 +102,7 @@ def _():
113102
# Leave Buffer Comand
114103
class CodempCreateBufferCommand(sublime_plugin.WindowCommand):
115104
def is_enabled(self):
116-
return len(workspaces.lookup()) > 0
105+
return workspaces.hasactive()
117106

118107
def run(self, workspace_id, buffer_id):# pyright: ignore[reportIncompatibleMethodOverride]
119108
try: vws = workspaces.lookupId(workspace_id)
@@ -122,9 +111,9 @@ def run(self, workspace_id, buffer_id):# pyright: ignore[reportIncompatibleMetho
122111
logger.warning(f"You are not attached to the workspace '{workspace_id}'")
123112
return
124113

125-
vws.handle.create_buffer(buffer_id)
114+
vws.handle.create_buffer(buffer_id).wait()
126115
logger.info(
127-
"created buffer '{buffer_id}' in the workspace '{workspace_id}'.\n\
116+
f"created buffer '{buffer_id}' in the workspace '{workspace_id}'.\n\
128117
To interact with it you need to attach to it with Codemp: Attach."
129118
)
130119

@@ -136,14 +125,14 @@ def run(self, workspace_id, buffer_id):# pyright: ignore[reportIncompatibleMetho
136125

137126
try: vws = workspaces.lookupId(workspace_id)
138127
except KeyError:
139-
sublime.error_message(f"You are not attached to the workspace '{workspace_id}'")
140-
logger.warning(f"You are not attached to the workspace '{workspace_id}'")
128+
sublime.error_message(f"You are not attached to the workspace {workspace_id}")
129+
logger.warning(f"You are not attached to the workspace {workspace_id}")
141130
return
142131

143132
if buffer_id in buffers:
144133

145134
if not sublime.ok_cancel_dialog(
146-
"You are currently attached to '{buffer_id}'.\n\
135+
f"You are currently attached to '{buffer_id}'.\n\
147136
Do you want to detach and delete it?",
148137
ok_title="yes", title="Delete Buffer?",
149138
): return

plugin/core/buffers.py

Lines changed: 52 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,27 @@ def _innercb():
7171
return _callback
7272

7373
class BufferManager():
74-
def __init__(self, handle: codemp.BufferController, v: sublime.View, filename: str):
74+
def __init__(self, handle: codemp.BufferController, v: sublime.View, filename: str, islocal: bool):
7575
self.handle: codemp.BufferController = handle
7676
self.view: sublime.View = v
77+
self.islocal: bool = islocal
7778
self.id = self.handle.path()
7879
self.filename = filename
7980
self.handle.callback(bind_callback(self.view))
8081

82+
self.view.settings().set(g.CODEMP_VIEW_TAG, True)
83+
self.view.settings().set(g.CODEMP_BUFFER_ID, self.id)
84+
self.view.set_status(g.SUBLIME_STATUS_ID, "[Codemp]")
85+
8186
def __del__(self):
8287
logger.debug(f"dropping buffer {self.id}")
83-
self.view.close()
8488
self.handle.clear_callback()
89+
if self.islocal:
90+
self.view.settings().erase(g.CODEMP_BUFFER_ID)
91+
self.view.settings().erase(g.CODEMP_VIEW_TAG)
92+
self.view.set_status(g.SUBLIME_STATUS_ID, "")
93+
else:
94+
self.view.close()
8595

8696
def __hash__(self):
8797
return hash(self.id)
@@ -103,17 +113,26 @@ def send_change(self, changes):
103113
def sync(self, text_listener):
104114
promise = self.handle.content()
105115
def _():
106-
current_contents = get_contents(self.view)
116+
# current_contents = get_contents(self.view)
107117
content = promise.wait()
108-
if content == current_contents:
109-
return
110118

111119
safe_listener_detach(text_listener)
112120
populate_view(self.view, content)
113121
safe_listener_attach(text_listener, self.view.buffer())
122+
114123
sublime.status_message("Syncd contents.")
115124
sublime.set_timeout_async(_)
116125

126+
def overwrite(self, text_listener):
127+
localcontents = get_contents(self.view)
128+
remotecontents = self.handle.content().wait()
129+
remotelen = len(remotecontents)
130+
self.handle.send(
131+
TextChange(start=0, end=remotelen, content= localcontents)
132+
)
133+
self.sync(text_listener)
134+
135+
117136
class BufferRegistry():
118137
def __init__(self):
119138
self._buffers: bidict[BufferManager, WorkspaceManager] = bidict()
@@ -142,38 +161,49 @@ def lookupId(self, bid: str) -> BufferManager:
142161
if not bfm: raise KeyError
143162
return bfm
144163

145-
def register(self, bhandle: codemp.BufferController, wsm: WorkspaceManager):
146-
bid = bhandle.path()
147-
148-
win = sublime.active_window()
149-
newfileflags = sublime.NewFileFlags.TRANSIENT \
150-
| sublime.NewFileFlags.ADD_TO_SELECTION \
151-
| sublime.NewFileFlags.FORCE_CLONE
152-
view = win.new_file(newfileflags)
164+
def register(self, buff: str, wsm: WorkspaceManager, localview: sublime.View | None = None):
165+
166+
try: buffctl = wsm.handle.attach_buffer(buff).wait()
167+
except Exception as e:
168+
logger.error(f"error when attaching to buffer '{id}':\n\n {e}")
169+
sublime.error_message(f"Could not attach to buffer '{buff}'")
170+
raise e
153171

172+
win = sublime.active_window()
173+
if not localview:
174+
newfileflags = sublime.NewFileFlags.TRANSIENT \
175+
| sublime.NewFileFlags.ADD_TO_SELECTION \
176+
| sublime.NewFileFlags.FORCE_CLONE
177+
view = win.new_file(newfileflags)
154178

155-
view.set_scratch(True)
156-
view.set_name(os.path.basename(bid))
157-
syntax = sublime.find_syntax_for_file(bid)
158-
if syntax:
159-
view.assign_syntax(syntax)
160179

161-
view.settings().set(g.CODEMP_VIEW_TAG, True)
162-
view.settings().set(g.CODEMP_BUFFER_ID, bid)
163-
view.set_status(g.SUBLIME_STATUS_ID, "[Codemp]")
180+
view.set_scratch(True)
181+
view.set_name(os.path.basename(buff))
182+
syntax = sublime.find_syntax_for_file(buff)
183+
if syntax:
184+
view.assign_syntax(syntax)
185+
else:
186+
view = localview
164187

165188
tmpfile = "DISABLE"
166-
bfm = BufferManager(bhandle, view, tmpfile)
189+
bfm = BufferManager(buffctl, view, tmpfile, islocal = localview is not None)
167190
self._buffers[bfm] = wsm
168191

169192
return bfm
170193

171194
def remove(self, bf: BufferManager | str):
172195
if isinstance(bf, str):
173196
bf = self.lookupId(bf)
197+
ws = self.lookupParent(bf)
174198

175199
del self._buffers[bf]
176200

201+
bf = bf.id
202+
if not ws.handle.detach_buffer(bf):
203+
logger.error(f"could not leave the buffer {bf}.")
204+
else:
205+
logger.debug(f"successfully detached from {bf}.")
206+
177207

178208
buffers = BufferRegistry()
179209

0 commit comments

Comments
 (0)