mirror of
https://github.com/hexedtech/codemp-sublime.git
synced 2024-11-21 22:34:48 +01:00
feat: added leave buffer command.
feat: new generic input handler for sequence of text inputs with defaults. chore: minor fixes and improvements Former-commit-id: 73ea017903fd717d894092871b7b62f827df4ff2
This commit is contained in:
parent
1e5aeda755
commit
abc976e3e5
4 changed files with 148 additions and 130 deletions
|
@ -28,6 +28,11 @@
|
||||||
// "server_host": "http://[::1]:50051"
|
// "server_host": "http://[::1]:50051"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"caption": "Codemp: Disconnect Client",
|
||||||
|
"command": "codemp_disconnect",
|
||||||
|
"arg": {}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"caption": "Codemp: Join Workspace",
|
"caption": "Codemp: Join Workspace",
|
||||||
"command": "codemp_join_workspace",
|
"command": "codemp_join_workspace",
|
||||||
|
@ -36,6 +41,13 @@
|
||||||
// 'buffer_id': 'test'
|
// 'buffer_id': 'test'
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"caption": "Codemp: Leave Workspace",
|
||||||
|
"command": "codemp_leave_workspace",
|
||||||
|
"arg": {
|
||||||
|
// "id": 'lmaaaao'
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"caption": "Codemp: Join Buffer",
|
"caption": "Codemp: Join Buffer",
|
||||||
"command": "codemp_join_buffer",
|
"command": "codemp_join_buffer",
|
||||||
|
@ -45,23 +57,11 @@
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"caption": "Codemp: Share",
|
"caption": "Codemp: Leave Buffer",
|
||||||
"command": "codemp_share",
|
"command": "codemp_leave_buffer",
|
||||||
"arg": {
|
"arg": {
|
||||||
// 'sublime_buffer' : /path/to/buffer/to/share
|
// 'workspace_id': 'asd'
|
||||||
// 'server_id' : 'how to call the buffer on the server'
|
// 'buffer_id': 'test'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"caption": "Codemp: Leave Workspace",
|
|
||||||
"command": "codemp_leave_workspace",
|
|
||||||
"arg": {
|
|
||||||
// "id": 'lmaaaao'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"caption": "Codemp: Disconnect Client",
|
|
||||||
"command": "codemp_disconnect",
|
|
||||||
"arg": {}
|
|
||||||
},
|
|
||||||
]
|
]
|
238
plugin.py
238
plugin.py
|
@ -3,6 +3,7 @@ import sublime
|
||||||
import sublime_plugin
|
import sublime_plugin
|
||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
|
from typing import List, Tuple
|
||||||
|
|
||||||
import codemp
|
import codemp
|
||||||
from Codemp.src.client import client
|
from Codemp.src.client import client
|
||||||
|
@ -114,7 +115,7 @@ class CodempClientViewEventListener(sublime_plugin.ViewEventListener):
|
||||||
if vws is None or vbuff is None:
|
if vws is None or vbuff is None:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
vws.uninstall_buffer(vbuff.id)
|
vws.uninstall_buffer(vbuff)
|
||||||
|
|
||||||
def on_text_command(self, command_name, args):
|
def on_text_command(self, command_name, args):
|
||||||
if command_name == "codemp_replace_text":
|
if command_name == "codemp_replace_text":
|
||||||
|
@ -146,23 +147,26 @@ class CodempClientTextChangeListener(sublime_plugin.TextChangeListener):
|
||||||
sublime.set_timeout(lambda: vbuff.send_buffer_change(changes))
|
sublime.set_timeout(lambda: vbuff.send_buffer_change(changes))
|
||||||
|
|
||||||
|
|
||||||
# Commands:
|
# Client Commands:
|
||||||
# codemp_connect: connect to a server.
|
# codemp_connect: connect to a server.
|
||||||
# codemp_join: shortcut command if you already know both workspace id
|
|
||||||
# and buffer id
|
|
||||||
# codemp_join_workspace: joins a specific workspace, without joining also a buffer
|
|
||||||
# codemp_join_buffer: joins a specific buffer within the current active workspace
|
|
||||||
|
|
||||||
|
|
||||||
# codemp_share: ??? todo!()
|
|
||||||
# codemp_disconnect: manually call the disconnection, triggering the cleanup and dropping
|
# codemp_disconnect: manually call the disconnection, triggering the cleanup and dropping
|
||||||
# the connection
|
# the connection
|
||||||
#
|
# codemp_join_workspace: joins a specific workspace, without joining also a buffer
|
||||||
|
# codemp_leave_workspace:
|
||||||
|
|
||||||
|
# Workspace Commands:
|
||||||
|
# codemp_join_buffer: joins a specific buffer within the current active workspace
|
||||||
|
# codemp_leave_buffer:
|
||||||
|
# codemp_create_buffer:
|
||||||
|
# codemp_delete_buffer:
|
||||||
|
|
||||||
# Internal commands:
|
# Internal commands:
|
||||||
# replace_text: swaps the content of a view with the given text.
|
# replace_text: swaps the content of a view with the given text.
|
||||||
#
|
|
||||||
# Connect Command
|
|
||||||
|
# Client Commands
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
# Connect Command
|
||||||
class CodempConnectCommand(sublime_plugin.WindowCommand):
|
class CodempConnectCommand(sublime_plugin.WindowCommand):
|
||||||
def is_enabled(self) -> bool:
|
def is_enabled(self) -> bool:
|
||||||
return client.codemp is None
|
return client.codemp is None
|
||||||
|
@ -182,42 +186,27 @@ class CodempConnectCommand(sublime_plugin.WindowCommand):
|
||||||
|
|
||||||
sublime.set_timeout_async(try_connect)
|
sublime.set_timeout_async(try_connect)
|
||||||
|
|
||||||
def input(self, args):
|
|
||||||
if "server_host" not in args:
|
|
||||||
return ConnectServerHost()
|
|
||||||
|
|
||||||
def input_description(self):
|
def input_description(self):
|
||||||
return "Server host:"
|
return "Server host:"
|
||||||
|
|
||||||
|
def input(self, args):
|
||||||
class ConnectServerHost(sublime_plugin.TextInputHandler):
|
if "server_host" not in args:
|
||||||
def name(self):
|
return SimpleTextInput(
|
||||||
return "server_host"
|
("server_host", "http://127.0.0.1:50051"),
|
||||||
|
("user_name", f"user-{random.random()}"),
|
||||||
def initial_text(self):
|
)
|
||||||
return "http://127.0.0.1:50051"
|
|
||||||
|
|
||||||
def next_input(self, args):
|
|
||||||
if "user_name" not in args:
|
|
||||||
return ConnectUserName(args)
|
|
||||||
|
|
||||||
|
|
||||||
class ConnectUserName(sublime_plugin.TextInputHandler):
|
# Disconnect Command
|
||||||
def __init__(self, args):
|
class CodempDisconnectCommand(sublime_plugin.WindowCommand):
|
||||||
self.host = args["server_host"]
|
def is_enabled(self):
|
||||||
|
return client.codemp is not None
|
||||||
|
|
||||||
def name(self):
|
def run(self):
|
||||||
return "user_name"
|
client.disconnect()
|
||||||
|
|
||||||
def initial_text(self):
|
|
||||||
return f"user-{random.random()}"
|
|
||||||
|
|
||||||
|
|
||||||
# Separate the join command into two join workspace and join buffer commands that get called back to back
|
# Join Workspace Command
|
||||||
|
|
||||||
|
|
||||||
# Generic Join Workspace Command
|
|
||||||
#############################################################################
|
|
||||||
class CodempJoinWorkspaceCommand(sublime_plugin.WindowCommand):
|
class CodempJoinWorkspaceCommand(sublime_plugin.WindowCommand):
|
||||||
def is_enabled(self) -> bool:
|
def is_enabled(self) -> bool:
|
||||||
return client.codemp is not None
|
return client.codemp is not None
|
||||||
|
@ -252,11 +241,6 @@ class CodempJoinWorkspaceCommand(sublime_plugin.WindowCommand):
|
||||||
return WorkspaceIdText()
|
return WorkspaceIdText()
|
||||||
|
|
||||||
|
|
||||||
class WorkspaceIdText(sublime_plugin.TextInputHandler):
|
|
||||||
def name(self):
|
|
||||||
return "workspace_id"
|
|
||||||
|
|
||||||
|
|
||||||
# To allow for having a selection and choosing non existing workspaces
|
# To allow for having a selection and choosing non existing workspaces
|
||||||
# we do a little dance: We pass this list input handler to a TextInputHandler
|
# we do a little dance: We pass this list input handler to a TextInputHandler
|
||||||
# when we select "Create New..." which adds his result to the list of possible
|
# when we select "Create New..." which adds his result to the list of possible
|
||||||
|
@ -291,6 +275,25 @@ class WorkspaceIdText(sublime_plugin.TextInputHandler):
|
||||||
# return AddListEntry(self)
|
# return AddListEntry(self)
|
||||||
|
|
||||||
|
|
||||||
|
# Leave Workspace Command
|
||||||
|
class CodempLeaveWorkspaceCommand(sublime_plugin.WindowCommand):
|
||||||
|
def is_enabled(self):
|
||||||
|
return client.codemp is not None and len(client.all_workspaces(self.window)) > 0
|
||||||
|
|
||||||
|
def run(self, workspace_id: str):
|
||||||
|
# client.leave_workspace(id)
|
||||||
|
pass
|
||||||
|
|
||||||
|
def input(self, args):
|
||||||
|
if "id" not in args:
|
||||||
|
return ActiveWorkspacesIdList()
|
||||||
|
|
||||||
|
|
||||||
|
# WORKSPACE COMMANDS
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
# Join Buffer Command
|
||||||
class CodempJoinBufferCommand(sublime_plugin.WindowCommand):
|
class CodempJoinBufferCommand(sublime_plugin.WindowCommand):
|
||||||
def is_enabled(self):
|
def is_enabled(self):
|
||||||
available_workspaces = client.all_workspaces(self.window)
|
available_workspaces = client.all_workspaces(self.window)
|
||||||
|
@ -343,8 +346,6 @@ class CodempJoinBufferCommand(sublime_plugin.WindowCommand):
|
||||||
return "Attach: "
|
return "Attach: "
|
||||||
|
|
||||||
def input(self, args):
|
def input(self, args):
|
||||||
# if we have only a workspace in the window, then
|
|
||||||
# skip to the buffer choice
|
|
||||||
if "workspace_id" not in args:
|
if "workspace_id" not in args:
|
||||||
return ActiveWorkspacesIdList(self.window, get_buffer=True)
|
return ActiveWorkspacesIdList(self.window, get_buffer=True)
|
||||||
|
|
||||||
|
@ -352,6 +353,86 @@ class CodempJoinBufferCommand(sublime_plugin.WindowCommand):
|
||||||
return BufferIdList(args["workspace_id"])
|
return BufferIdList(args["workspace_id"])
|
||||||
|
|
||||||
|
|
||||||
|
# Leave Buffer Comand
|
||||||
|
class CodempLeaveBufferCommand(sublime_plugin.WindowCommand):
|
||||||
|
def is_enabled(self):
|
||||||
|
return len(client.all_buffers()) > 0
|
||||||
|
|
||||||
|
def run(self, workspace_id, buffer_id):
|
||||||
|
vbuff = client.buffer_from_id(buffer_id)
|
||||||
|
vws = client.workspace_from_id(workspace_id)
|
||||||
|
|
||||||
|
if vbuff is None or vws is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
def defer_detach():
|
||||||
|
if vws.codemp.detach(buffer_id):
|
||||||
|
vws.uninstall_buffer(vbuff)
|
||||||
|
|
||||||
|
sublime.set_timeout_async(defer_detach)
|
||||||
|
|
||||||
|
def input_description(self) -> str:
|
||||||
|
return "Leave: "
|
||||||
|
|
||||||
|
def input(self, args):
|
||||||
|
if "workspace_id" not in args:
|
||||||
|
return ActiveWorkspacesIdList(self.window, get_buffer=True)
|
||||||
|
|
||||||
|
if "buffer_id" not in args:
|
||||||
|
return BufferIdList(args["workspace_id"])
|
||||||
|
|
||||||
|
|
||||||
|
# Text Change Command
|
||||||
|
#############################################################################
|
||||||
|
class CodempReplaceTextCommand(sublime_plugin.TextCommand):
|
||||||
|
def run(self, edit, start, end, content, change_id):
|
||||||
|
# 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)
|
||||||
|
self.view.replace(edit, region, content)
|
||||||
|
|
||||||
|
|
||||||
|
# Input handlers
|
||||||
|
############################################################
|
||||||
|
class SimpleTextInput(sublime_plugin.TextInputHandler):
|
||||||
|
def __init__(self, *args: Tuple[str, str]):
|
||||||
|
assert len(args) > 0
|
||||||
|
self.argname = args[0][0]
|
||||||
|
self.default = args[0][1]
|
||||||
|
self.next_inputs = args[1:]
|
||||||
|
|
||||||
|
def initial_text(self):
|
||||||
|
return self.default
|
||||||
|
|
||||||
|
def name(self):
|
||||||
|
return self.argname
|
||||||
|
|
||||||
|
def next_input(self, args):
|
||||||
|
if len(self.next_inputs) > 0:
|
||||||
|
if self.next_inputs[0][0] not in args:
|
||||||
|
return SimpleTextInput(*self.next_inputs)
|
||||||
|
|
||||||
|
|
||||||
|
class WorkspaceIdText(sublime_plugin.TextInputHandler):
|
||||||
|
def name(self):
|
||||||
|
return "workspace_id"
|
||||||
|
|
||||||
|
|
||||||
|
class ActiveWorkspacesIdList(sublime_plugin.ListInputHandler):
|
||||||
|
def __init__(self, window=None, get_buffer=False):
|
||||||
|
self.window = window
|
||||||
|
self.get_buffer = get_buffer
|
||||||
|
|
||||||
|
def name(self):
|
||||||
|
return "workspace_id"
|
||||||
|
|
||||||
|
def list_items(self):
|
||||||
|
return [vws.id for vws in client.all_workspaces(self.window)]
|
||||||
|
|
||||||
|
def next_input(self, args):
|
||||||
|
if self.get_buffer:
|
||||||
|
return BufferIdList(args["workspace_id"])
|
||||||
|
|
||||||
|
|
||||||
class BufferIdList(sublime_plugin.ListInputHandler):
|
class BufferIdList(sublime_plugin.ListInputHandler):
|
||||||
def __init__(self, workspace_id):
|
def __init__(self, workspace_id):
|
||||||
self.add_entry_text = "* create new..."
|
self.add_entry_text = "* create new..."
|
||||||
|
@ -377,69 +458,6 @@ class BufferIdList(sublime_plugin.ListInputHandler):
|
||||||
return AddListEntry(self)
|
return AddListEntry(self)
|
||||||
|
|
||||||
|
|
||||||
# Text Change Command
|
|
||||||
#############################################################################
|
|
||||||
class CodempReplaceTextCommand(sublime_plugin.TextCommand):
|
|
||||||
def run(self, edit, start, end, content, change_id):
|
|
||||||
# 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)
|
|
||||||
self.view.replace(edit, region, content)
|
|
||||||
|
|
||||||
|
|
||||||
# Share Command
|
|
||||||
# #############################################################################
|
|
||||||
# class CodempShareCommand(sublime_plugin.WindowCommand):
|
|
||||||
# def run(self, sublime_buffer_path, server_id):
|
|
||||||
# sublime_asyncio.dispatch(share_buffer_command(sublime_buffer_path, server_id))
|
|
||||||
|
|
||||||
# def input(self, args):
|
|
||||||
# if "sublime_buffer" not in args:
|
|
||||||
# return SublimeBufferPathInputHandler()
|
|
||||||
|
|
||||||
# def input_description(self):
|
|
||||||
# return "Share Buffer:"
|
|
||||||
|
|
||||||
|
|
||||||
# Disconnect Command
|
|
||||||
#############################################################################
|
|
||||||
class CodempDisconnectCommand(sublime_plugin.WindowCommand):
|
|
||||||
def is_enabled(self):
|
|
||||||
return client.codemp is not None
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
client.disconnect()
|
|
||||||
|
|
||||||
|
|
||||||
# Leave Workspace Command
|
|
||||||
class CodempLeaveWorkspaceCommand(sublime_plugin.WindowCommand):
|
|
||||||
def is_enabled(self):
|
|
||||||
return client.codemp is not None and len(client.all_workspaces(self.window)) > 0
|
|
||||||
|
|
||||||
def run(self, workspace_id: str):
|
|
||||||
# client.leave_workspace(id)
|
|
||||||
pass
|
|
||||||
|
|
||||||
def input(self, args):
|
|
||||||
if "id" not in args:
|
|
||||||
return ActiveWorkspacesIdList()
|
|
||||||
|
|
||||||
|
|
||||||
class ActiveWorkspacesIdList(sublime_plugin.ListInputHandler):
|
|
||||||
def __init__(self, window=None, get_buffer=False):
|
|
||||||
self.window = window
|
|
||||||
self.get_buffer = get_buffer
|
|
||||||
|
|
||||||
def name(self):
|
|
||||||
return "workspace_id"
|
|
||||||
|
|
||||||
def list_items(self):
|
|
||||||
return [vws.id for vws in client.all_workspaces(self.window)]
|
|
||||||
|
|
||||||
def next_input(self, args):
|
|
||||||
if self.get_buffer:
|
|
||||||
return BufferIdList(args["workspace_id"])
|
|
||||||
|
|
||||||
|
|
||||||
class AddListEntry(sublime_plugin.TextInputHandler):
|
class AddListEntry(sublime_plugin.TextInputHandler):
|
||||||
# this class works when the list input handler
|
# this class works when the list input handler
|
||||||
# added appended a new element to it's list that will need to be
|
# added appended a new element to it's list that will need to be
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from typing import Optional, Dict
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
import sublime
|
import sublime
|
||||||
|
@ -50,7 +50,7 @@ class VirtualClient:
|
||||||
if window is None:
|
if window is None:
|
||||||
return list(self.__workspace2window.keys())
|
return list(self.__workspace2window.keys())
|
||||||
else:
|
else:
|
||||||
return self.__workspace2window.inverse[window]
|
return self.__workspace2window.inverse.get(window, [])
|
||||||
|
|
||||||
def workspace_from_view(self, view: sublime.View) -> Optional[VirtualWorkspace]:
|
def workspace_from_view(self, view: sublime.View) -> Optional[VirtualWorkspace]:
|
||||||
buff = self.__view2buff.get(view, None)
|
buff = self.__view2buff.get(view, None)
|
||||||
|
@ -70,7 +70,7 @@ class VirtualClient:
|
||||||
else:
|
else:
|
||||||
if isinstance(workspace, str):
|
if isinstance(workspace, str):
|
||||||
workspace = client.__id2workspace[workspace]
|
workspace = client.__id2workspace[workspace]
|
||||||
return self.__buff2workspace.inverse[workspace]
|
return self.__buff2workspace.inverse.get(workspace, [])
|
||||||
|
|
||||||
def buffer_from_view(self, view: sublime.View) -> Optional[VirtualBuffer]:
|
def buffer_from_view(self, view: sublime.View) -> Optional[VirtualBuffer]:
|
||||||
return self.__view2buff.get(view)
|
return self.__view2buff.get(view)
|
||||||
|
|
|
@ -47,7 +47,7 @@ class VirtualWorkspace:
|
||||||
all(id in self.__id2buff for id in attached_buffers)
|
all(id in self.__id2buff for id in attached_buffers)
|
||||||
# TODO!
|
# TODO!
|
||||||
|
|
||||||
def valid_bufffer(self, buff: VirtualBuffer | str):
|
def valid_buffer(self, buff: VirtualBuffer | str):
|
||||||
if isinstance(buff, str):
|
if isinstance(buff, str):
|
||||||
return self.buff_by_id(buff) is not None
|
return self.buff_by_id(buff) is not None
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue