Compare commits
6 Commits
2758d6b62b
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
| 890c6cdfcc | |||
| b13d9c2397 | |||
| e367e31890 | |||
| bd277c0214 | |||
| 12a5e4935e | |||
| 01ede1ac49 |
@@ -25,7 +25,7 @@ class Plugin(PluginCode):
|
|||||||
if len(history) == history_size:
|
if len(history) == history_size:
|
||||||
history.pop(0)
|
history.pop(0)
|
||||||
|
|
||||||
history.append(event.file)
|
history.append(event.file.fpath)
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
self._manage_signals("register_command")
|
self._manage_signals("register_command")
|
||||||
@@ -60,6 +60,6 @@ class Handler:
|
|||||||
|
|
||||||
view._on_uri_data_received(
|
view._on_uri_data_received(
|
||||||
[
|
[
|
||||||
history.pop().replace("file://", "")
|
f"file://{history.pop()}"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class Plugin(PluginCode):
|
|||||||
def load(self):
|
def load(self):
|
||||||
self._manage_signals("register_command")
|
self._manage_signals("register_command")
|
||||||
|
|
||||||
def load(self):
|
def unload(self):
|
||||||
self._manage_signals("unregister_command")
|
self._manage_signals("unregister_command")
|
||||||
|
|
||||||
def _manage_signals(self, action: str):
|
def _manage_signals(self, action: str):
|
||||||
|
|||||||
3
plugins/code/commands/split_pane_manager/__init__.py
Normal file
3
plugins/code/commands/split_pane_manager/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
"""
|
||||||
|
Pligin Module
|
||||||
|
"""
|
||||||
3
plugins/code/commands/split_pane_manager/__main__.py
Normal file
3
plugins/code/commands/split_pane_manager/__main__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
"""
|
||||||
|
Pligin Package
|
||||||
|
"""
|
||||||
64
plugins/code/commands/split_pane_manager/close_split_view.py
Normal file
64
plugins/code/commands/split_pane_manager/close_split_view.py
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
# Python imports
|
||||||
|
|
||||||
|
# Lib imports
|
||||||
|
import gi
|
||||||
|
|
||||||
|
gi.require_version('Gtk', '3.0')
|
||||||
|
gi.require_version('GtkSource', '4')
|
||||||
|
|
||||||
|
from gi.repository import Gtk
|
||||||
|
from gi.repository import GtkSource
|
||||||
|
|
||||||
|
# Application imports
|
||||||
|
from libs.event_factory import Event_Factory, Code_Event_Types
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
emit_to: callable = None
|
||||||
|
|
||||||
|
def execute(
|
||||||
|
source_view,
|
||||||
|
char_str,
|
||||||
|
modkeys_states
|
||||||
|
):
|
||||||
|
logger.debug("Command: Close Split Pane")
|
||||||
|
|
||||||
|
scrolled_win = source_view.get_parent()
|
||||||
|
pane = scrolled_win.get_parent()
|
||||||
|
|
||||||
|
if not isinstance(pane, Gtk.Paned): return
|
||||||
|
|
||||||
|
container = pane.get_parent()
|
||||||
|
source_view1 = pane.get_child1()
|
||||||
|
source_view2 = pane.get_child2()
|
||||||
|
|
||||||
|
if scrolled_win == source_view1:
|
||||||
|
remaining = source_view2
|
||||||
|
closing_view = source_view
|
||||||
|
else:
|
||||||
|
remaining = source_view1
|
||||||
|
closing_view = source_view
|
||||||
|
|
||||||
|
remaining_view = remaining.get_child()
|
||||||
|
left = closing_view.sibling_left
|
||||||
|
right = closing_view.sibling_right
|
||||||
|
|
||||||
|
if left:
|
||||||
|
left.sibling_right = right
|
||||||
|
|
||||||
|
if right:
|
||||||
|
right.sibling_left = left
|
||||||
|
|
||||||
|
pane.remove(source_view1)
|
||||||
|
pane.remove(source_view2)
|
||||||
|
|
||||||
|
container.remove(pane)
|
||||||
|
container.add(remaining)
|
||||||
|
|
||||||
|
event = Event_Factory.create_event(
|
||||||
|
"remove_source_view",
|
||||||
|
view = closing_view
|
||||||
|
)
|
||||||
|
emit_to("source_views", event)
|
||||||
|
|
||||||
|
remaining_view.grab_focus()
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
# Python imports
|
||||||
|
|
||||||
|
# Lib imports
|
||||||
|
import gi
|
||||||
|
|
||||||
|
gi.require_version("Gtk", "3.0")
|
||||||
|
|
||||||
|
from gi.repository import Gtk
|
||||||
|
|
||||||
|
# Application imports
|
||||||
|
from libs.event_factory import Event_Factory, Code_Event_Types
|
||||||
|
from libs.dto.states import SourceViewStates
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
emit_to: callable = None
|
||||||
|
|
||||||
|
def execute(
|
||||||
|
source_view1,
|
||||||
|
char_str,
|
||||||
|
modkeys_states
|
||||||
|
):
|
||||||
|
logger.debug("Command: Split Pane")
|
||||||
|
|
||||||
|
scrolled_win1 = source_view1.get_parent()
|
||||||
|
container = scrolled_win1.get_parent()
|
||||||
|
pane = Gtk.Paned()
|
||||||
|
event = Event_Factory.create_event(
|
||||||
|
"create_source_view",
|
||||||
|
state = SourceViewStates.INSERT
|
||||||
|
)
|
||||||
|
emit_to("source_views", event)
|
||||||
|
|
||||||
|
scrolled_win2, \
|
||||||
|
source_view2 = event.response
|
||||||
|
old_sibling_right = None
|
||||||
|
|
||||||
|
if source_view1.sibling_right:
|
||||||
|
old_sibling_right = source_view1.sibling_right
|
||||||
|
|
||||||
|
source_view1.sibling_right = source_view2
|
||||||
|
if old_sibling_right:
|
||||||
|
old_sibling_right.sibling_left = source_view2
|
||||||
|
source_view2.sibling_right = old_sibling_right
|
||||||
|
|
||||||
|
source_view2.sibling_left = source_view1
|
||||||
|
|
||||||
|
pane.set_hexpand(True)
|
||||||
|
pane.set_vexpand(True)
|
||||||
|
pane.set_wide_handle(True)
|
||||||
|
|
||||||
|
container.remove(scrolled_win1)
|
||||||
|
pane.pack1( scrolled_win1, True, True )
|
||||||
|
pane.pack2( scrolled_win2, True, True )
|
||||||
|
container.add(pane)
|
||||||
|
|
||||||
|
pane.show_all()
|
||||||
|
|
||||||
|
is_control, is_shift, is_alt = modkeys_states
|
||||||
|
if is_control and is_shift:
|
||||||
|
pane.set_orientation(Gtk.Orientation.VERTICAL)
|
||||||
|
elif is_control:
|
||||||
|
pane.set_orientation(Gtk.Orientation.HORIZONTAL)
|
||||||
|
|
||||||
|
source_view2.grab_focus()
|
||||||
|
source_view2.command.exec("new_file")
|
||||||
@@ -7,6 +7,7 @@ gi.require_version('GtkSource', '4')
|
|||||||
|
|
||||||
from gi.repository import GtkSource
|
from gi.repository import GtkSource
|
||||||
|
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
|
|
||||||
|
|
||||||
@@ -18,5 +19,4 @@ def execute(
|
|||||||
):
|
):
|
||||||
logger.debug("Command: Focus Left Sibling")
|
logger.debug("Command: Focus Left Sibling")
|
||||||
if not view.sibling_left: return
|
if not view.sibling_left: return
|
||||||
view.sibling_left.get_parent().show()
|
|
||||||
view.sibling_left.grab_focus()
|
view.sibling_left.grab_focus()
|
||||||
@@ -18,5 +18,4 @@ def execute(
|
|||||||
):
|
):
|
||||||
logger.debug("Command: Focus Right Sibling")
|
logger.debug("Command: Focus Right Sibling")
|
||||||
if not view.sibling_right: return
|
if not view.sibling_right: return
|
||||||
view.sibling_right.get_parent().show()
|
|
||||||
view.sibling_right.grab_focus()
|
view.sibling_right.grab_focus()
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "Toggle Source View",
|
"name": "Split Pane Manager",
|
||||||
"author": "ITDominator",
|
"author": "ITDominator",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"support": "",
|
"support": "",
|
||||||
100
plugins/code/commands/split_pane_manager/plugin.py
Normal file
100
plugins/code/commands/split_pane_manager/plugin.py
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
# Python imports
|
||||||
|
|
||||||
|
# Lib imports
|
||||||
|
import gi
|
||||||
|
|
||||||
|
gi.require_version("Gtk", "3.0")
|
||||||
|
|
||||||
|
from gi.repository import Gtk
|
||||||
|
|
||||||
|
# Application imports
|
||||||
|
from plugins.plugin_types import PluginCode
|
||||||
|
|
||||||
|
from libs.event_factory import Event_Factory, Code_Event_Types
|
||||||
|
|
||||||
|
from . import create_split_view, \
|
||||||
|
close_split_view, \
|
||||||
|
focus_left_sibling, \
|
||||||
|
focus_right_sibling, \
|
||||||
|
move_to_left_sibling, \
|
||||||
|
move_to_right_sibling
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Plugin(PluginCode):
|
||||||
|
def __init__(self):
|
||||||
|
super(Plugin, self).__init__()
|
||||||
|
|
||||||
|
|
||||||
|
def _controller_message(self, event: Code_Event_Types.CodeEvent):
|
||||||
|
...
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
gemit_to = self.emit_to
|
||||||
|
self._manage_signals("register_command")
|
||||||
|
|
||||||
|
def unload(self):
|
||||||
|
self._manage_signals("unregister_command")
|
||||||
|
|
||||||
|
def _manage_signals(self, action: str):
|
||||||
|
_create_split_view = create_split_view
|
||||||
|
_close_split_view = close_split_view
|
||||||
|
_create_split_view.emit_to = self.emit_to
|
||||||
|
_close_split_view.emit_to = self.emit_to
|
||||||
|
|
||||||
|
event = Event_Factory.create_event(action,
|
||||||
|
command_name = "create_split_view",
|
||||||
|
command = _create_split_view,
|
||||||
|
binding_mode = "released",
|
||||||
|
binding = ["<Control>\\", "<Shift><Control>|"]
|
||||||
|
)
|
||||||
|
|
||||||
|
self.emit_to("source_views", event)
|
||||||
|
|
||||||
|
event = Event_Factory.create_event(action,
|
||||||
|
command_name = "close_split_view",
|
||||||
|
command = _close_split_view,
|
||||||
|
binding_mode = "released",
|
||||||
|
binding = "<Shift><Control>w"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.emit_to("source_views", event)
|
||||||
|
|
||||||
|
event = Event_Factory.create_event(action,
|
||||||
|
command_name = "focus_left_sibling",
|
||||||
|
command = focus_left_sibling,
|
||||||
|
binding_mode = "released",
|
||||||
|
binding = "<Control>Page_Up"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.emit_to("source_views", event)
|
||||||
|
|
||||||
|
event = Event_Factory.create_event(action,
|
||||||
|
command_name = "focus_right_sibling",
|
||||||
|
command = focus_right_sibling,
|
||||||
|
binding_mode = "released",
|
||||||
|
binding = "<Control>Page_Down"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.emit_to("source_views", event)
|
||||||
|
|
||||||
|
event = Event_Factory.create_event(action,
|
||||||
|
command_name = "move_to_left_sibling",
|
||||||
|
command = move_to_left_sibling,
|
||||||
|
binding_mode = "released",
|
||||||
|
binding = "<Control><Shift>Up"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.emit_to("source_views", event)
|
||||||
|
|
||||||
|
event = Event_Factory.create_event(action,
|
||||||
|
command_name = "move_to_right_sibling",
|
||||||
|
command = move_to_right_sibling,
|
||||||
|
binding_mode = "released",
|
||||||
|
binding = "<Control><Shift>Down"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.emit_to("source_views", event)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
...
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
"""
|
|
||||||
Plugin Module
|
|
||||||
"""
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
"""
|
|
||||||
Plugin Package
|
|
||||||
"""
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
# Python imports
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
from libs.event_factory import Event_Factory, Code_Event_Types
|
|
||||||
|
|
||||||
from plugins.plugin_types import PluginCode
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Plugin(PluginCode):
|
|
||||||
def __init__(self):
|
|
||||||
super(Plugin, self).__init__()
|
|
||||||
|
|
||||||
def _controller_message(self, event: Code_Event_Types.CodeEvent):
|
|
||||||
...
|
|
||||||
|
|
||||||
def load(self):
|
|
||||||
event = Event_Factory.create_event("register_command",
|
|
||||||
command_name = "toggle_source_view",
|
|
||||||
command = Handler,
|
|
||||||
binding_mode = "released",
|
|
||||||
binding = "<Shift><Control>h"
|
|
||||||
)
|
|
||||||
|
|
||||||
self.emit_to("source_views", event)
|
|
||||||
|
|
||||||
def unload(self):
|
|
||||||
event = Event_Factory.create_event("unregister_command",
|
|
||||||
command_name = "toggle_source_view",
|
|
||||||
command = Handler,
|
|
||||||
binding_mode = "released",
|
|
||||||
binding = "<Shift><Control>h"
|
|
||||||
)
|
|
||||||
|
|
||||||
self.emit_to("source_views", event)
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
class Handler:
|
|
||||||
@staticmethod
|
|
||||||
def execute(
|
|
||||||
view: any,
|
|
||||||
char_str: str,
|
|
||||||
*args,
|
|
||||||
**kwargs
|
|
||||||
):
|
|
||||||
logger.debug("Command: Toggle Source View")
|
|
||||||
target = view.get_parent()
|
|
||||||
target.hide() if target.is_visible() else target.show()
|
|
||||||
|
|
||||||
if view.sibling_left:
|
|
||||||
target = view.sibling_left.get_parent()
|
|
||||||
target.show()
|
|
||||||
view.sibling_left.grab_focus()
|
|
||||||
|
|
||||||
if view.sibling_right:
|
|
||||||
target = view.sibling_right.get_parent()
|
|
||||||
target.show()
|
|
||||||
view.sibling_right.grab_focus()
|
|
||||||
|
|
||||||
@@ -24,6 +24,7 @@ class Plugin(PluginCode):
|
|||||||
self.emit_to("files", event)
|
self.emit_to("files", event)
|
||||||
|
|
||||||
file = event.response
|
file = event.response
|
||||||
|
if not file: return
|
||||||
if file.ftype == "buffer": return
|
if file.ftype == "buffer": return
|
||||||
|
|
||||||
file.check_file_on_disk()
|
file.check_file_on_disk()
|
||||||
|
|||||||
@@ -19,13 +19,10 @@ class LSPClient(LSPClientWebsocket):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(LSPClient, self).__init__()
|
super(LSPClient, self).__init__()
|
||||||
|
|
||||||
# https://github.com/microsoft/multilspy/tree/main/src/multilspy/language_servers
|
|
||||||
# initialize-params-slim.json was created off of jedi_language_server one
|
|
||||||
# self._init_params = settings_manager.get_lsp_init_data()
|
|
||||||
|
|
||||||
self._language: str = ""
|
self._language: str = ""
|
||||||
|
self._workspace_path: str = ""
|
||||||
self._init_params: dict = {}
|
self._init_params: dict = {}
|
||||||
self._event_history: dict[int, str] = {}
|
self._init_opts: dict = {}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
_USER_HOME = path.expanduser('~')
|
_USER_HOME = path.expanduser('~')
|
||||||
@@ -33,19 +30,29 @@ class LSPClient(LSPClientWebsocket):
|
|||||||
_LSP_INIT_CONFIG = f"{_SCRIPT_PTH}/../configs/initialize-params-slim.json"
|
_LSP_INIT_CONFIG = f"{_SCRIPT_PTH}/../configs/initialize-params-slim.json"
|
||||||
|
|
||||||
with open(_LSP_INIT_CONFIG) as file:
|
with open(_LSP_INIT_CONFIG) as file:
|
||||||
data = file.read().replace("{user.home}", _USER_HOME)
|
data = file.read()
|
||||||
self._init_params = json.loads(data)
|
self._init_params = json.loads(data)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error( f"LSP Controller: {_LSP_INIT_CONFIG}\n\t\t{repr(e)}" )
|
logger.error( f"LSP Controller: {_LSP_INIT_CONFIG}\n\t\t{repr(e)}" )
|
||||||
|
|
||||||
self._message_id: int = -1
|
|
||||||
self._socket = None
|
self._socket = None
|
||||||
|
self._message_id: int = -1
|
||||||
|
self._event_history: dict[int, str] = {}
|
||||||
|
|
||||||
self.read_lock = threading.Lock()
|
self.read_lock = threading.Lock()
|
||||||
self.write_lock = threading.Lock()
|
self.write_lock = threading.Lock()
|
||||||
|
|
||||||
|
|
||||||
def set_language(self, language: str):
|
def set_language(self, language: str):
|
||||||
self._language = language
|
self._language = language
|
||||||
|
|
||||||
|
def set_workspace_path(self, workspace_path: str):
|
||||||
|
self._workspace_path = workspace_path
|
||||||
|
|
||||||
|
def set_init_opts(self, init_opts: dict[str, str]):
|
||||||
|
self._init_opts = init_opts
|
||||||
|
|
||||||
def set_socket(self, socket: str):
|
def set_socket(self, socket: str):
|
||||||
self._socket = socket
|
self._socket = socket
|
||||||
|
|
||||||
|
|||||||
@@ -17,11 +17,12 @@ from ..dto.code.lsp.lsp_messages import symbols_request
|
|||||||
|
|
||||||
|
|
||||||
class LSPClientEvents:
|
class LSPClientEvents:
|
||||||
def send_initialize_message(self, init_ops: dict, workspace_file: str, workspace_uri: str):
|
def send_initialize_message(self):
|
||||||
folder_name = os.path.basename(workspace_file)
|
folder_name = os.path.basename(self._workspace_path)
|
||||||
|
workspace_uri = f"file://{self._workspace_path}"
|
||||||
|
|
||||||
self._init_params["processId"] = None
|
self._init_params["processId"] = None
|
||||||
self._init_params["rootPath"] = workspace_file
|
self._init_params["rootPath"] = self._workspace_path
|
||||||
self._init_params["rootUri"] = workspace_uri
|
self._init_params["rootUri"] = workspace_uri
|
||||||
self._init_params["workspaceFolders"] = [
|
self._init_params["workspaceFolders"] = [
|
||||||
{
|
{
|
||||||
@@ -30,7 +31,7 @@ class LSPClientEvents:
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
self._init_params["initializationOptions"] = init_ops
|
self._init_params["initializationOptions"] = self._init_opts
|
||||||
self.send_request("initialize", self._init_params)
|
self.send_request("initialize", self._init_params)
|
||||||
|
|
||||||
def send_initialized_message(self):
|
def send_initialized_message(self):
|
||||||
|
|||||||
@@ -54,17 +54,21 @@ class LSPManager(ControllerBase):
|
|||||||
self.response_registry.unregister_handler(event.lang_id)
|
self.response_registry.unregister_handler(event.lang_id)
|
||||||
self.lsp_manager_ui.remove_client_listing(event.lang_id)
|
self.lsp_manager_ui.remove_client_listing(event.lang_id)
|
||||||
|
|
||||||
def _on_create_client(self, ui, lang_id: str, workspace_uri: str) -> bool:
|
def _on_create_client(self, ui, lang_id: str, workspace_path: str) -> bool:
|
||||||
init_opts = ui.get_init_opts(lang_id)
|
init_opts = ui.get_init_opts(lang_id)
|
||||||
result = self.create_client(lang_id, workspace_uri, init_opts)
|
result = self.create_client(lang_id, workspace_path, init_opts)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
ui.toggle_client_buttons(show_close=True)
|
ui.toggle_client_buttons(show_close = True)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _on_close_client(self, ui, lang_id: str) -> bool:
|
def _on_close_client(self, ui, lang_id: str) -> bool:
|
||||||
result = self.close_client(lang_id)
|
result = self.close_client(lang_id)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
ui.toggle_client_buttons(show_close=False)
|
ui.toggle_client_buttons(show_close = False)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def handle_destroy(self):
|
def handle_destroy(self):
|
||||||
@@ -73,12 +77,12 @@ class LSPManager(ControllerBase):
|
|||||||
|
|
||||||
def create_client(
|
def create_client(
|
||||||
self,
|
self,
|
||||||
lang_id: str = "python",
|
lang_id: str,
|
||||||
workspace_uri: str = "",
|
workspace_path: str,
|
||||||
init_opts: dict = {}
|
init_opts: dict[str, str]
|
||||||
) -> bool:
|
) -> bool:
|
||||||
client = self.lsp_manager_client.create_client(
|
client = self.lsp_manager_client.create_client(
|
||||||
lang_id, workspace_uri, init_opts
|
lang_id, workspace_path, init_opts
|
||||||
)
|
)
|
||||||
handler = self.response_registry.get_handler(lang_id)
|
handler = self.response_registry.get_handler(lang_id)
|
||||||
self.lsp_manager_client.active_language_id = lang_id
|
self.lsp_manager_client.active_language_id = lang_id
|
||||||
@@ -92,7 +96,7 @@ class LSPManager(ControllerBase):
|
|||||||
handler.set_response_cache(self.response_cache)
|
handler.set_response_cache(self.response_cache)
|
||||||
|
|
||||||
client.handle_lsp_response = self.server_response
|
client.handle_lsp_response = self.server_response
|
||||||
client.send_initialize_message(init_opts, "", f"file://{workspace_uri}")
|
client.send_initialize_message()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ class LSPManagerClient(LSPClientEventsMixin):
|
|||||||
|
|
||||||
def create_client(
|
def create_client(
|
||||||
self,
|
self,
|
||||||
lang_id: str = "python",
|
lang_id: str,
|
||||||
workspace_uri: str = "",
|
workspace_path: str,
|
||||||
init_opts: dict = {}
|
init_opts: dict[str, str]
|
||||||
) -> LSPClient:
|
) -> LSPClient:
|
||||||
if lang_id in self.clients: return None
|
if lang_id in self.clients: return None
|
||||||
|
|
||||||
@@ -33,8 +33,10 @@ class LSPManagerClient(LSPClientEventsMixin):
|
|||||||
uri = f"ws://{address}:{port}/{lang_id}"
|
uri = f"ws://{address}:{port}/{lang_id}"
|
||||||
client = LSPClient()
|
client = LSPClient()
|
||||||
|
|
||||||
client.set_language(lang_id)
|
|
||||||
client.set_socket(uri)
|
client.set_socket(uri)
|
||||||
|
client.set_language(lang_id)
|
||||||
|
client.set_workspace_path(workspace_path)
|
||||||
|
client.set_init_opts(init_opts)
|
||||||
client.start_client()
|
client.start_client()
|
||||||
|
|
||||||
if not client.ws_client.wait_for_connection(timeout = 5.0):
|
if not client.ws_client.wait_for_connection(timeout = 5.0):
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
# Python imports
|
# Python imports
|
||||||
|
from os import path
|
||||||
import json
|
import json
|
||||||
|
|
||||||
# Lib imports
|
# Lib imports
|
||||||
@@ -24,6 +25,8 @@ class LSPManagerUI(Gtk.Dialog):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(LSPManagerUI, self).__init__()
|
super(LSPManagerUI, self).__init__()
|
||||||
|
|
||||||
|
self._USER_HOME = path.expanduser('~')
|
||||||
|
|
||||||
self.client_configs: dict[str, str] = {}
|
self.client_configs: dict[str, str] = {}
|
||||||
|
|
||||||
self.source_view = None
|
self.source_view = None
|
||||||
@@ -167,9 +170,11 @@ class LSPManagerUI(Gtk.Dialog):
|
|||||||
lang_id = self.combo_box.get_active_text()
|
lang_id = self.combo_box.get_active_text()
|
||||||
if not lang_id: return
|
if not lang_id: return
|
||||||
|
|
||||||
json_str = self.client_configs[lang_id].replace("{workspace.folder}", workspace_dir)
|
json_str = self.client_configs[lang_id] \
|
||||||
buffer = self.source_view.get_buffer()
|
.replace("{workspace.folder}", workspace_dir) \
|
||||||
|
.replace("{user.home}", self._USER_HOME)
|
||||||
|
|
||||||
|
buffer = self.source_view.get_buffer()
|
||||||
buffer.set_text(json_str, -1)
|
buffer.set_text(json_str, -1)
|
||||||
|
|
||||||
def map_parent_resize_event(self, parent):
|
def map_parent_resize_event(self, parent):
|
||||||
@@ -204,7 +209,7 @@ class LSPManagerUI(Gtk.Dialog):
|
|||||||
model = self.combo_box.get_model()
|
model = self.combo_box.get_model()
|
||||||
|
|
||||||
for i, row in enumerate(model):
|
for i, row in enumerate(model):
|
||||||
if row[0] == lang_id: # assuming text is in column 0
|
if row[0] == lang_id:
|
||||||
self.combo_box.remove(i)
|
self.combo_box.remove(i)
|
||||||
break
|
break
|
||||||
|
|
||||||
@@ -215,7 +220,9 @@ class LSPManagerUI(Gtk.Dialog):
|
|||||||
if not lang_id or lang_id not in self.client_configs: return {}
|
if not lang_id or lang_id not in self.client_configs: return {}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
lang_config = json.loads(self.client_configs[lang_id])
|
buffer = self.source_view.get_buffer()
|
||||||
|
json_str = buffer.get_text(*buffer.get_bounds(), -1)
|
||||||
|
lang_config = json.loads(json_str)
|
||||||
except json.JSONDecodeError as e:
|
except json.JSONDecodeError as e:
|
||||||
logger.error(f"Invalid JSON for {lang_id}: {e}")
|
logger.error(f"Invalid JSON for {lang_id}: {e}")
|
||||||
return {}
|
return {}
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
{
|
||||||
|
"info": "https://github.com/python-lsp/python-lsp-server",
|
||||||
|
"command": "lsp-ws-proxy -- pylsp",
|
||||||
|
"alt-command": "pylsp",
|
||||||
|
"alt-command2": "lsp-ws-proxy --listen 4114 -- pylsp",
|
||||||
|
"alt-command3": "pylsp --ws --port 4114",
|
||||||
|
"socket": "ws://127.0.0.1:9999/python",
|
||||||
|
"socket-two": "ws://127.0.0.1:9999/?name=pylsp",
|
||||||
|
"initialization-options": {
|
||||||
|
"pylsp": {
|
||||||
|
"rope": {
|
||||||
|
"ropeFolder": "{user.home}/.config/newton/lsps/ropeproject"
|
||||||
|
},
|
||||||
|
"plugins": {
|
||||||
|
"ruff": {
|
||||||
|
"enabled": true,
|
||||||
|
"extendSelect": ["I"],
|
||||||
|
"lineLength": 80
|
||||||
|
},
|
||||||
|
"pycodestyle": {
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"pyflakes": {
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"pylint": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
"mccabe": {
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"pylsp_rope": {
|
||||||
|
"rename": false
|
||||||
|
},
|
||||||
|
"rope_rename": {
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"rope_autoimport": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
"rope_completion": {
|
||||||
|
"enabled": false,
|
||||||
|
"eager": false
|
||||||
|
},
|
||||||
|
"jedi_rename": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
"jedi_completion": {
|
||||||
|
"enabled": true,
|
||||||
|
"include_class_objects": true,
|
||||||
|
"include_function_objects": true,
|
||||||
|
"fuzzy": false
|
||||||
|
},
|
||||||
|
"jedi": {
|
||||||
|
"root_dir": "file://{workspace.folder}",
|
||||||
|
"extra_paths": [
|
||||||
|
"{user.home}/Portable_Apps/py-venvs/pylsp-venv/venv/lib/python3.10/site-packages"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"python - jedi-language-server": {
|
||||||
|
"hidden": true,
|
||||||
|
"info": "https://pypi.org/project/jedi-language-server/",
|
||||||
|
"command": "jedi-language-server",
|
||||||
|
"alt-command": "lsp-ws-proxy --listen 3030 -- jedi-language-server",
|
||||||
|
"socket": "ws://127.0.0.1:9999/python",
|
||||||
|
"socket-two": "ws://127.0.0.1:9999/?name=jedi-language-server",
|
||||||
|
"initialization-options": {
|
||||||
|
"jediSettings": {
|
||||||
|
"autoImportModules": [],
|
||||||
|
"caseInsensitiveCompletion": true,
|
||||||
|
"debug": false
|
||||||
|
},
|
||||||
|
"completion": {
|
||||||
|
"disableSnippets": false,
|
||||||
|
"resolveEagerly": false,
|
||||||
|
"ignorePatterns": []
|
||||||
|
},
|
||||||
|
"markupKindPreferred": "markdown",
|
||||||
|
"workspace": {
|
||||||
|
"extraPaths": [
|
||||||
|
"{user.home}/Portable_Apps/py-venvs/pylsp-venv/venv/lib/python3.10/site-packages"
|
||||||
|
],
|
||||||
|
"environmentPath": "{user.home}/Portable_Apps/py-venvs/gtk-apps-venv/venv/bin/python",
|
||||||
|
"symbols": {
|
||||||
|
"ignoreFolders": [
|
||||||
|
".nox",
|
||||||
|
".tox",
|
||||||
|
".venv",
|
||||||
|
"__pycache__",
|
||||||
|
"venv"
|
||||||
|
],
|
||||||
|
"maxSymbols": 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -60,41 +60,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"python - jedi-language-server": {
|
|
||||||
"hidden": true,
|
|
||||||
"info": "https://pypi.org/project/jedi-language-server/",
|
|
||||||
"command": "jedi-language-server",
|
|
||||||
"alt-command": "lsp-ws-proxy --listen 3030 -- jedi-language-server",
|
|
||||||
"socket": "ws://127.0.0.1:9999/python",
|
|
||||||
"socket-two": "ws://127.0.0.1:9999/?name=jedi-language-server",
|
|
||||||
"initialization-options": {
|
|
||||||
"jediSettings": {
|
|
||||||
"autoImportModules": [],
|
|
||||||
"caseInsensitiveCompletion": true,
|
|
||||||
"debug": false
|
|
||||||
},
|
|
||||||
"completion": {
|
|
||||||
"disableSnippets": false,
|
|
||||||
"resolveEagerly": false,
|
|
||||||
"ignorePatterns": []
|
|
||||||
},
|
|
||||||
"markupKindPreferred": "markdown",
|
|
||||||
"workspace": {
|
|
||||||
"extraPaths": [
|
|
||||||
"{user.home}/Portable_Apps/py-venvs/pylsp-venv/venv/lib/python3.10/site-packages"
|
|
||||||
],
|
|
||||||
"environmentPath": "{user.home}/Portable_Apps/py-venvs/gtk-apps-venv/venv/bin/python",
|
|
||||||
"symbols": {
|
|
||||||
"ignoreFolders": [
|
|
||||||
".nox",
|
|
||||||
".tox",
|
|
||||||
".venv",
|
|
||||||
"__pycache__",
|
|
||||||
"venv"
|
|
||||||
],
|
|
||||||
"maxSymbols": 20
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
# Python imports
|
# Python imports
|
||||||
|
|
||||||
# Lib imports
|
# Lib imports
|
||||||
|
import gi
|
||||||
|
|
||||||
|
from gi.repository import Gtk
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from libs.event_factory import Event_Factory, Code_Event_Types
|
from libs.event_factory import Event_Factory, Code_Event_Types
|
||||||
@@ -25,8 +28,19 @@ class Plugin(PluginCode):
|
|||||||
|
|
||||||
self.register_controller("tabs", self.tabs_controller)
|
self.register_controller("tabs", self.tabs_controller)
|
||||||
|
|
||||||
code_container.add( self.tabs_controller.tabs_widget )
|
scrolled_win = Gtk.ScrolledWindow()
|
||||||
code_container.reorder_child(self.tabs_controller.tabs_widget, 0)
|
viewport = Gtk.Viewport()
|
||||||
|
|
||||||
|
scrolled_win.set_overlay_scrolling(False)
|
||||||
|
scrolled_win.set_size_request(-1, 50)
|
||||||
|
|
||||||
|
viewport.add( self.tabs_controller.tabs_widget )
|
||||||
|
scrolled_win.add( viewport )
|
||||||
|
code_container.add( scrolled_win )
|
||||||
|
code_container.reorder_child(scrolled_win, 0)
|
||||||
|
|
||||||
|
viewport.show()
|
||||||
|
scrolled_win.show()
|
||||||
|
|
||||||
event = Event_Factory.create_event("get_files")
|
event = Event_Factory.create_event("get_files")
|
||||||
self.emit_to("files", event)
|
self.emit_to("files", event)
|
||||||
@@ -36,7 +50,14 @@ class Plugin(PluginCode):
|
|||||||
def unload(self):
|
def unload(self):
|
||||||
self.unregister_controller("tabs")
|
self.unregister_controller("tabs")
|
||||||
self.tabs_controller.unload_tabs()
|
self.tabs_controller.unload_tabs()
|
||||||
self.tabs_controller.tabs_widget.destroy()
|
|
||||||
|
tabs_widget = self.tabs_controller.tabs_widget
|
||||||
|
viewport = tabs_widget.get_parent()
|
||||||
|
scrolled_win = viewport.get_parent()
|
||||||
|
|
||||||
|
tabs_widget.destroy()
|
||||||
|
viewport.destroy()
|
||||||
|
scrolled_win.destroy()
|
||||||
|
|
||||||
self.tabs_controller.tabs_widget = None
|
self.tabs_controller.tabs_widget = None
|
||||||
self.tabs_controller = None
|
self.tabs_controller = None
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class TabsWidget(Gtk.Notebook):
|
|||||||
|
|
||||||
|
|
||||||
def _setup_styling(self):
|
def _setup_styling(self):
|
||||||
self.set_scrollable(True)
|
...
|
||||||
|
|
||||||
def _setup_signals(self):
|
def _setup_signals(self):
|
||||||
self.connect("page-added", self._page_added)
|
self.connect("page-added", self._page_added)
|
||||||
@@ -67,6 +67,7 @@ class TabsWidget(Gtk.Notebook):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.emit(event)
|
self.emit(event)
|
||||||
|
self._scroll_to_center(tab)
|
||||||
|
|
||||||
def _bind_tab_menu(self, tab, page_widget):
|
def _bind_tab_menu(self, tab, page_widget):
|
||||||
def do_context_menu(tab, eve, page_widget):
|
def do_context_menu(tab, eve, page_widget):
|
||||||
@@ -81,6 +82,21 @@ class TabsWidget(Gtk.Notebook):
|
|||||||
page_widget
|
page_widget
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _scroll_to_center(self, tab):
|
||||||
|
scrolled_win = self.get_parent().get_parent()
|
||||||
|
alloc = tab.get_allocation()
|
||||||
|
tab_x = alloc.x
|
||||||
|
tab_width = alloc.width
|
||||||
|
view_width = scrolled_win.get_allocated_width()
|
||||||
|
target = tab_x + tab_width / 2 - view_width / 2
|
||||||
|
adj = scrolled_win.get_hadjustment()
|
||||||
|
lower = adj.get_lower()
|
||||||
|
upper = adj.get_upper()
|
||||||
|
page_size = adj.get_page_size()
|
||||||
|
target = max(lower, min(target, upper - page_size))
|
||||||
|
|
||||||
|
adj.set_value(target)
|
||||||
|
|
||||||
def create_menu(self, page_widget) -> Gtk.Menu:
|
def create_menu(self, page_widget) -> Gtk.Menu:
|
||||||
context_menu = Gtk.Menu()
|
context_menu = Gtk.Menu()
|
||||||
close_submenu = Gtk.Menu()
|
close_submenu = Gtk.Menu()
|
||||||
@@ -130,6 +146,7 @@ class TabsWidget(Gtk.Notebook):
|
|||||||
self.page_num(page_widget)
|
self.page_num(page_widget)
|
||||||
)
|
)
|
||||||
self.handler_unblock(self.switch_page_id)
|
self.handler_unblock(self.switch_page_id)
|
||||||
|
self._scroll_to_center(tab)
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ gi.require_version('Gtk', '3.0')
|
|||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from ..widgets.webkit.webkit_ui import WebkitUI
|
from core.widgets.webkit.webkit_ui import WebkitUI
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -28,6 +28,7 @@ class CenterContainer(Gtk.Box):
|
|||||||
self.set_orientation(Gtk.Orientation.VERTICAL)
|
self.set_orientation(Gtk.Orientation.VERTICAL)
|
||||||
self.set_hexpand(True)
|
self.set_hexpand(True)
|
||||||
self.set_vexpand(True)
|
self.set_vexpand(True)
|
||||||
|
self.set_size_request(320, -1)
|
||||||
|
|
||||||
def _setup_signals(self):
|
def _setup_signals(self):
|
||||||
self.connect("show", self._handle_show)
|
self.connect("show", self._handle_show)
|
||||||
|
|||||||
@@ -6,10 +6,6 @@ gi.require_version('Gtk', '3.0')
|
|||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from ...widgets.code.code_base import CodeBase
|
|
||||||
|
|
||||||
from ...widgets.separator_widget import Separator
|
|
||||||
|
|
||||||
from .editors_container import EditorsContainer
|
from .editors_container import EditorsContainer
|
||||||
|
|
||||||
|
|
||||||
@@ -27,6 +23,9 @@ class CodeContainer(Gtk.Box):
|
|||||||
|
|
||||||
|
|
||||||
def _setup_styling(self):
|
def _setup_styling(self):
|
||||||
|
self.ctx = self.get_style_context()
|
||||||
|
self.ctx.add_class("code-container")
|
||||||
|
|
||||||
self.set_orientation(Gtk.Orientation.VERTICAL)
|
self.set_orientation(Gtk.Orientation.VERTICAL)
|
||||||
|
|
||||||
def _setup_signals(self):
|
def _setup_signals(self):
|
||||||
@@ -37,18 +36,4 @@ class CodeContainer(Gtk.Box):
|
|||||||
|
|
||||||
def _load_widgets(self):
|
def _load_widgets(self):
|
||||||
widget_registery.expose_object("code-container", self)
|
widget_registery.expose_object("code-container", self)
|
||||||
|
self.add( EditorsContainer() )
|
||||||
code_base = CodeBase()
|
|
||||||
|
|
||||||
self.add( self._create_editor_widget(code_base) )
|
|
||||||
|
|
||||||
def _create_editor_widget(self, code_base: CodeBase):
|
|
||||||
editors_container = Gtk.Box()
|
|
||||||
|
|
||||||
widget_registery.expose_object("editors-container", editors_container)
|
|
||||||
|
|
||||||
editors_container.add( Separator("separator_left") )
|
|
||||||
editors_container.add( EditorsContainer(code_base) )
|
|
||||||
editors_container.add( Separator("separator_right") )
|
|
||||||
|
|
||||||
return editors_container
|
|
||||||
|
|||||||
@@ -4,18 +4,17 @@
|
|||||||
import gi
|
import gi
|
||||||
gi.require_version('Gtk', '3.0')
|
gi.require_version('Gtk', '3.0')
|
||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
#from gi.repository import GLib
|
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
|
from core.widgets.code.code_base import CodeBase
|
||||||
|
from core.widgets.separator_widget import Separator
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class EditorsContainer(Gtk.Paned):
|
class EditorsContainer(Gtk.Box):
|
||||||
def __init__(self, code_base: any):
|
def __init__(self):
|
||||||
super(EditorsContainer, self).__init__()
|
super(EditorsContainer, self).__init__()
|
||||||
|
|
||||||
self.code_base = code_base
|
|
||||||
|
|
||||||
self._setup_styling()
|
self._setup_styling()
|
||||||
self._setup_signals()
|
self._setup_signals()
|
||||||
self._subscribe_to_events()
|
self._subscribe_to_events()
|
||||||
@@ -24,11 +23,11 @@ class EditorsContainer(Gtk.Paned):
|
|||||||
|
|
||||||
def _setup_styling(self):
|
def _setup_styling(self):
|
||||||
self.ctx = self.get_style_context()
|
self.ctx = self.get_style_context()
|
||||||
self.ctx.add_class("paned-editors-container")
|
self.ctx.add_class("editors-container")
|
||||||
|
|
||||||
self.set_hexpand(True)
|
self.set_hexpand(True)
|
||||||
self.set_vexpand(True)
|
self.set_vexpand(True)
|
||||||
self.set_wide_handle(True)
|
self.set_size_request(320, -1)
|
||||||
|
|
||||||
def _setup_signals(self):
|
def _setup_signals(self):
|
||||||
self.connect("map", self._init_map)
|
self.connect("map", self._init_map)
|
||||||
@@ -37,26 +36,16 @@ class EditorsContainer(Gtk.Paned):
|
|||||||
...
|
...
|
||||||
|
|
||||||
def _load_widgets(self):
|
def _load_widgets(self):
|
||||||
self.scrolled_win1, \
|
box = Gtk.Box()
|
||||||
self.scrolled_win2 = self._create_views()
|
widget_registery.expose_object("editors-container", self)
|
||||||
|
self.code_base = CodeBase()
|
||||||
|
scrolled_win, \
|
||||||
|
source_view = self.code_base.create_source_view()
|
||||||
|
|
||||||
self.pack1( self.scrolled_win1, True, True )
|
box.add( scrolled_win )
|
||||||
self.pack2( self.scrolled_win2, True, True )
|
self.add( Separator("separator_left") )
|
||||||
|
self.add( box )
|
||||||
def _create_views(self):
|
self.add( Separator("separator_right") )
|
||||||
scrolled_win1 = Gtk.ScrolledWindow()
|
|
||||||
scrolled_win2 = Gtk.ScrolledWindow()
|
|
||||||
|
|
||||||
source_view1 = self.code_base.create_source_view()
|
|
||||||
source_view2 = self.code_base.create_source_view()
|
|
||||||
|
|
||||||
source_view1.sibling_right = source_view2
|
|
||||||
source_view2.sibling_left = source_view1
|
|
||||||
|
|
||||||
scrolled_win1.add( source_view1 )
|
|
||||||
scrolled_win2.add( source_view2 )
|
|
||||||
|
|
||||||
return scrolled_win1, scrolled_win2
|
|
||||||
|
|
||||||
def _init_map(self, view):
|
def _init_map(self, view):
|
||||||
self.disconnect_by_func( self._init_map )
|
self.disconnect_by_func( self._init_map )
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ gi.require_version('Gtk', '3.0')
|
|||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from ..widgets.separator_widget import Separator
|
from core.widgets.separator_widget import Separator
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ gi.require_version('Gtk', '3.0')
|
|||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from ..widgets.separator_widget import Separator
|
from core.widgets.separator_widget import Separator
|
||||||
from ..widgets.controls.open_files_button import OpenFilesButton
|
from core.widgets.controls.open_files_button import OpenFilesButton
|
||||||
from ..widgets.controls.transparency_scale import TransparencyScale
|
from core.widgets.controls.transparency_scale import TransparencyScale
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ gi.require_version('Gtk', '3.0')
|
|||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from ..widgets.separator_widget import Separator
|
from core.widgets.separator_widget import Separator
|
||||||
|
|
||||||
from .code.code_container import CodeContainer
|
from .code.code_container import CodeContainer
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ gi.require_version('Gtk', '3.0')
|
|||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from ..widgets.separator_widget import Separator
|
from core.widgets.separator_widget import Separator
|
||||||
from ..widgets.vte_widget import VteWidget
|
from core.widgets.vte_widget import VteWidget
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,16 +18,12 @@ class BaseControllerMixin:
|
|||||||
files = []
|
files = []
|
||||||
|
|
||||||
for arg in unknownargs + [args.new_tab,]:
|
for arg in unknownargs + [args.new_tab,]:
|
||||||
if os.path.isdir( arg.replace("file://", "") ):
|
if os.path.isfile(arg):
|
||||||
files.append( f"DIR|{arg.replace('file://', '')}" )
|
files.append(f"{arg}")
|
||||||
continue
|
|
||||||
|
|
||||||
# NOTE: If passing line number with file split against :
|
if os.path.isdir(arg):
|
||||||
if os.path.isfile( arg.replace("file://", "").split(":")[0] ):
|
message = f"DIR|{arg}"
|
||||||
files.append( f"FILE|{arg.replace('file://', '')}" )
|
ipc_server.send_ipc_message(message)
|
||||||
continue
|
|
||||||
|
|
||||||
logger.info(f"Not a File: {arg}")
|
|
||||||
|
|
||||||
if not files: return
|
if not files: return
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ class CodeBase:
|
|||||||
completion_controller = CompletionController()
|
completion_controller = CompletionController()
|
||||||
source_views_controller = SourceViewsController()
|
source_views_controller = SourceViewsController()
|
||||||
|
|
||||||
# self.controller_manager.register_controller("base", self)
|
|
||||||
self.controller_manager.register_controller("files", files_controller)
|
self.controller_manager.register_controller("files", files_controller)
|
||||||
self.controller_manager.register_controller("commands", commands_controller)
|
self.controller_manager.register_controller("commands", commands_controller)
|
||||||
self.controller_manager.register_controller("completion", completion_controller)
|
self.controller_manager.register_controller("completion", completion_controller)
|
||||||
@@ -43,12 +42,13 @@ class CodeBase:
|
|||||||
self.controller_manager.register_controller("widgets", widget_registery)
|
self.controller_manager.register_controller("widgets", widget_registery)
|
||||||
|
|
||||||
def create_source_view(self):
|
def create_source_view(self):
|
||||||
|
scrolled_win, \
|
||||||
source_view = self.controller_manager["source_views"].create_source_view()
|
source_view = self.controller_manager["source_views"].create_source_view()
|
||||||
self.controller_manager["completion"].register_completer(
|
self.controller_manager["completion"].register_completer(
|
||||||
source_view.get_completion()
|
source_view.get_completion()
|
||||||
)
|
)
|
||||||
|
|
||||||
return source_view
|
return scrolled_win, source_view
|
||||||
|
|
||||||
def first_map_load(self):
|
def first_map_load(self):
|
||||||
self.controller_manager["source_views"].first_map_load()
|
self.controller_manager["source_views"].first_map_load()
|
||||||
|
|||||||
@@ -2,4 +2,4 @@
|
|||||||
Code Command System Package
|
Code Command System Package
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from .command_system import CommandSystem
|
from .source_view_command_system import SourceViewCommandSystem
|
||||||
|
|||||||
@@ -1,120 +0,0 @@
|
|||||||
# Python imports
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
from libs.event_factory import Event_Factory, Code_Event_Types
|
|
||||||
|
|
||||||
from ..mixins.command_system_mixin import CommandSystemMixin
|
|
||||||
from ..source_view import SourceView
|
|
||||||
|
|
||||||
from . import commands
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CommandSystem(CommandSystemMixin):
|
|
||||||
def __init__(self):
|
|
||||||
super(CommandSystem, self).__init__()
|
|
||||||
|
|
||||||
self.data: list = ()
|
|
||||||
|
|
||||||
|
|
||||||
def set_data(self, *args, **kwargs):
|
|
||||||
self.data = (args, kwargs)
|
|
||||||
|
|
||||||
def exec(self, command: str) -> any:
|
|
||||||
if not hasattr(commands, command): return
|
|
||||||
method = getattr(commands, command)
|
|
||||||
|
|
||||||
args, kwargs = self.data
|
|
||||||
return method.execute(*args, **kwargs)
|
|
||||||
|
|
||||||
def exec_with_args(self, command: str, *args, **kwargs) -> any:
|
|
||||||
if not hasattr(commands, command): return
|
|
||||||
|
|
||||||
method = getattr(commands, command)
|
|
||||||
return method.execute(*args, **kwargs)
|
|
||||||
|
|
||||||
def add_command(self, command_name: str, command: callable):
|
|
||||||
setattr(commands, command_name, command)
|
|
||||||
|
|
||||||
def remove_command(self, command_name: str, command: callable):
|
|
||||||
if hasattr(commands, command_name):
|
|
||||||
delattr(commands, command_name)
|
|
||||||
|
|
||||||
|
|
||||||
def emit(self, event: Code_Event_Types.CodeEvent):
|
|
||||||
""" Monkey patch 'emit' from command controller... """
|
|
||||||
...
|
|
||||||
|
|
||||||
def emit_to(self, controller: str, event: Code_Event_Types.CodeEvent):
|
|
||||||
""" Monkey patch 'emit_to' from command controller... """
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
# def filter_out_loaded_files(self, uris: list[str]):
|
|
||||||
# event = Event_Factory.create_event(
|
|
||||||
# "filter_out_loaded_files",
|
|
||||||
# uris = uris
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# self.emit_to("files", event)
|
|
||||||
#
|
|
||||||
# return event.response
|
|
||||||
#
|
|
||||||
# def set_info_labels(self, data: tuple[str]):
|
|
||||||
# event = Event_Factory.create_event(
|
|
||||||
# "set_info_labels",
|
|
||||||
# info = data
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# self.emit_to("plugins", event)
|
|
||||||
#
|
|
||||||
# def get_file(self, view: SourceView):
|
|
||||||
# event = Event_Factory.create_event(
|
|
||||||
# "get_file",
|
|
||||||
# view = view,
|
|
||||||
# buffer = view.get_buffer()
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# self.emit_to("files", event)
|
|
||||||
#
|
|
||||||
# return event.response
|
|
||||||
#
|
|
||||||
# def get_swap_file(self, view: SourceView):
|
|
||||||
# event = Event_Factory.create_event(
|
|
||||||
# "get_swap_file",
|
|
||||||
# view = view,
|
|
||||||
# buffer = view.get_buffer()
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# self.emit_to("files", event)
|
|
||||||
#
|
|
||||||
# return event.response
|
|
||||||
#
|
|
||||||
# def new_file(self, view: SourceView):
|
|
||||||
# event = Event_Factory.create_event("add_new_file", view = view)
|
|
||||||
#
|
|
||||||
# self.emit_to("files", event)
|
|
||||||
#
|
|
||||||
# return event.response
|
|
||||||
#
|
|
||||||
# def remove_file(self, view: SourceView):
|
|
||||||
# event = Event_Factory.create_event(
|
|
||||||
# "remove_file",
|
|
||||||
# view = view,
|
|
||||||
# buffer = view.get_buffer()
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# self.emit_to("files", event)
|
|
||||||
#
|
|
||||||
# return event.response
|
|
||||||
#
|
|
||||||
# def request_completion(self, view: SourceView):
|
|
||||||
# event = Event_Factory.create_event(
|
|
||||||
# "request_completion",
|
|
||||||
# view = view,
|
|
||||||
# buffer = view.get_buffer()
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# self.emit_to("completion", event)
|
|
||||||
@@ -20,9 +20,14 @@ def execute(
|
|||||||
ctx = view.get_parent().get_style_context()
|
ctx = view.get_parent().get_style_context()
|
||||||
ctx.add_class("source-view-focused")
|
ctx.add_class("source-view-focused")
|
||||||
|
|
||||||
if view.sibling_right:
|
lview = view.sibling_left
|
||||||
ctx = view.sibling_right.get_parent().get_style_context()
|
while lview is not None:
|
||||||
elif view.sibling_left:
|
ctx = lview.get_parent().get_style_context()
|
||||||
ctx = view.sibling_left.get_parent().get_style_context()
|
|
||||||
|
|
||||||
ctx.remove_class("source-view-focused")
|
ctx.remove_class("source-view-focused")
|
||||||
|
lview = lview.sibling_left
|
||||||
|
|
||||||
|
rview = view.sibling_right
|
||||||
|
while rview is not None:
|
||||||
|
ctx = rview.get_parent().get_style_context()
|
||||||
|
ctx.remove_class("source-view-focused")
|
||||||
|
rview = rview.sibling_right
|
||||||
|
|||||||
@@ -4,12 +4,19 @@
|
|||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from libs.event_factory import Event_Factory, Code_Event_Types
|
from libs.event_factory import Event_Factory, Code_Event_Types
|
||||||
|
from libs.command_system import CommandSystem
|
||||||
|
|
||||||
from ..source_view import SourceView
|
from ..source_view import SourceView
|
||||||
|
|
||||||
|
|
||||||
|
from . import commands
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class SourceViewCommandSystem(CommandSystem):
|
||||||
|
def __init__(self):
|
||||||
|
super(SourceViewCommandSystem, self).__init__(commands)
|
||||||
|
|
||||||
class CommandSystemMixin:
|
|
||||||
def toggle_plugins_ui(self):
|
def toggle_plugins_ui(self):
|
||||||
event = Event_Factory.create_event( "toggle_plugins_ui" )
|
event = Event_Factory.create_event( "toggle_plugins_ui" )
|
||||||
|
|
||||||
@@ -81,3 +88,11 @@ class CommandSystemMixin:
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.emit_to("completion", event)
|
self.emit_to("completion", event)
|
||||||
|
|
||||||
|
def emit(self, event: Code_Event_Types.CodeEvent):
|
||||||
|
""" Monkey patch 'emit' from command controller... """
|
||||||
|
...
|
||||||
|
|
||||||
|
def emit_to(self, controller: str, event: Code_Event_Types.CodeEvent):
|
||||||
|
""" Monkey patch 'emit_to' from command controller... """
|
||||||
|
...
|
||||||
@@ -7,7 +7,7 @@ from libs.controllers.controller_base import ControllerBase
|
|||||||
|
|
||||||
from libs.event_factory import Code_Event_Types
|
from libs.event_factory import Code_Event_Types
|
||||||
|
|
||||||
from ..command_system import CommandSystem
|
from ..command_system import SourceViewCommandSystem
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -17,14 +17,19 @@ class CommandsController(ControllerBase, list):
|
|||||||
|
|
||||||
|
|
||||||
def _controller_message(self, event: Code_Event_Types.CodeEvent):
|
def _controller_message(self, event: Code_Event_Types.CodeEvent):
|
||||||
if isinstance(event, Code_Event_Types.GetNewCommandSystemEvent):
|
if isinstance(event, Code_Event_Types.CreateCommandSystemEvent):
|
||||||
event.response = self.get_new_command_system()
|
event.response = self.create_command_system()
|
||||||
|
elif isinstance(event, Code_Event_Types.RemovedSourceViewEvent):
|
||||||
|
self.remove_command_system(event)
|
||||||
|
|
||||||
def get_new_command_system(self):
|
def create_command_system(self):
|
||||||
command_system = CommandSystem()
|
command_system = SourceViewCommandSystem()
|
||||||
command_system.emit = self.emit
|
command_system.emit = self.emit
|
||||||
command_system.emit_to = self.emit_to
|
command_system.emit_to = self.emit_to
|
||||||
|
|
||||||
self.append(command_system)
|
self.append(command_system)
|
||||||
|
|
||||||
return command_system
|
return command_system
|
||||||
|
|
||||||
|
def remove_command_system(self, event: Code_Event_Types.RemovedSourceViewEvent):
|
||||||
|
self.remove(event.view.command)
|
||||||
|
|||||||
@@ -46,14 +46,24 @@ class MarkerManager(MarkSupportMixin):
|
|||||||
start_itr = buffer.get_iter_at_mark(start_mark)
|
start_itr = buffer.get_iter_at_mark(start_mark)
|
||||||
end_itr = buffer.get_iter_at_mark(end_mark)
|
end_itr = buffer.get_iter_at_mark(end_mark)
|
||||||
|
|
||||||
|
self._proc_move(
|
||||||
|
buffer, is_forward, is_selection, mode, mark_hash,
|
||||||
|
start_mark, end_mark, has_selection, start_itr, end_itr
|
||||||
|
)
|
||||||
|
|
||||||
|
def _proc_move(
|
||||||
|
self, buffer, is_forward: bool, is_selection: bool, mode: str,
|
||||||
|
mark_hash, start_mark, end_mark, has_selection, start_itr, end_itr
|
||||||
|
):
|
||||||
if is_selection:
|
if is_selection:
|
||||||
|
if mark_hash:
|
||||||
self.buffer_markers[mark_hash]["is_selection"] = True
|
self.buffer_markers[mark_hash]["is_selection"] = True
|
||||||
|
|
||||||
self._move_iter(buffer, end_itr, mode, is_forward)
|
self._move_iter(buffer, end_itr, mode, is_forward)
|
||||||
buffer.move_mark(end_mark, end_itr)
|
buffer.move_mark(end_mark, end_itr)
|
||||||
|
|
||||||
self._apply_selection(buffer, start_itr, end_itr)
|
self._apply_selection(buffer, start_itr, end_itr)
|
||||||
continue
|
return
|
||||||
|
|
||||||
if has_selection:
|
if has_selection:
|
||||||
caret_itr = buffer.get_iter_at_mark(end_mark)
|
caret_itr = buffer.get_iter_at_mark(end_mark)
|
||||||
@@ -67,15 +77,14 @@ class MarkerManager(MarkSupportMixin):
|
|||||||
|
|
||||||
self.collapse_selection(buffer, mark_hash, start_mark, end_mark, is_forward)
|
self.collapse_selection(buffer, mark_hash, start_mark, end_mark, is_forward)
|
||||||
if mode == "word":
|
if mode == "word":
|
||||||
if not can_move: continue
|
if not can_move: return
|
||||||
|
|
||||||
itr = caret_itr
|
itr = caret_itr
|
||||||
self._move_iter(buffer, itr, mode, is_forward)
|
self._move_iter(buffer, itr, mode, is_forward)
|
||||||
buffer.move_mark(start_mark, itr)
|
buffer.move_mark(start_mark, itr)
|
||||||
buffer.move_mark(end_mark, itr)
|
buffer.move_mark(end_mark, itr)
|
||||||
|
|
||||||
continue
|
return
|
||||||
|
|
||||||
|
|
||||||
# No selection - move both anchor and caret together
|
# No selection - move both anchor and caret together
|
||||||
self._move_iter(buffer, end_itr, mode, is_forward)
|
self._move_iter(buffer, end_itr, mode, is_forward)
|
||||||
@@ -86,6 +95,7 @@ class MarkerManager(MarkSupportMixin):
|
|||||||
def collapse_selection(self,
|
def collapse_selection(self,
|
||||||
buffer, mark_hash, start_mark, end_mark, is_forward: bool
|
buffer, mark_hash, start_mark, end_mark, is_forward: bool
|
||||||
):
|
):
|
||||||
|
if mark_hash:
|
||||||
self.buffer_markers[mark_hash]["is_selection"] = False
|
self.buffer_markers[mark_hash]["is_selection"] = False
|
||||||
|
|
||||||
start_itr = buffer.get_iter_at_mark(start_mark)
|
start_itr = buffer.get_iter_at_mark(start_mark)
|
||||||
@@ -105,19 +115,28 @@ class MarkerManager(MarkSupportMixin):
|
|||||||
buffer.move_mark(start_mark, collapse_itr)
|
buffer.move_mark(start_mark, collapse_itr)
|
||||||
buffer.move_mark(end_mark, collapse_itr)
|
buffer.move_mark(end_mark, collapse_itr)
|
||||||
|
|
||||||
def move_word_snake_case(self, itr: Gtk.TextIter, count: int):
|
def move_along_word(self, itr: Gtk.TextIter, count: int):
|
||||||
def is_word(ch):
|
def not_is_word(ch: str):
|
||||||
|
return not is_word(ch)
|
||||||
|
|
||||||
|
def is_word(ch: str):
|
||||||
return ch and (ch.isalnum() or ch == "_")
|
return ch and (ch.isalnum() or ch == "_")
|
||||||
|
|
||||||
def step(fwd):
|
def is_special(ch: str):
|
||||||
|
return ch in "-"
|
||||||
|
|
||||||
|
def is_punct(ch: str):
|
||||||
|
return ch in ".;?!"
|
||||||
|
|
||||||
|
def step(fwd: bool):
|
||||||
return itr.forward_cursor_position() if fwd else itr.backward_cursor_position()
|
return itr.forward_cursor_position() if fwd else itr.backward_cursor_position()
|
||||||
|
|
||||||
def peek(fwd):
|
def peek(fwd: bool):
|
||||||
if fwd: return itr.get_char()
|
if fwd: return itr.get_char()
|
||||||
tmp = itr.copy()
|
tmp = itr.copy()
|
||||||
return tmp.backward_cursor_position() and tmp.get_char()
|
return tmp.backward_cursor_position() and tmp.get_char()
|
||||||
|
|
||||||
def walk(fwd, cond):
|
def walk(fwd, cond: callable):
|
||||||
while True:
|
while True:
|
||||||
ch = peek(fwd)
|
ch = peek(fwd)
|
||||||
if not cond(ch): break
|
if not cond(ch): break
|
||||||
@@ -126,23 +145,22 @@ class MarkerManager(MarkSupportMixin):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
fwd = count > 0
|
fwd = count > 0
|
||||||
|
for _ in range( abs(count) ):
|
||||||
|
ch = peek(fwd)
|
||||||
|
|
||||||
for _ in range(abs(count)):
|
if is_special(ch) or is_punct(ch):
|
||||||
ch = itr.get_char() if fwd else peek(False)
|
step(fwd)
|
||||||
|
elif is_word(ch):
|
||||||
if is_word(ch):
|
|
||||||
# inside word
|
|
||||||
if not walk(fwd, is_word): return
|
if not walk(fwd, is_word): return
|
||||||
else:
|
else:
|
||||||
# in separators -> skip them, then the word
|
if not walk(fwd, not_is_word): return
|
||||||
if not walk(fwd, lambda c: not is_word(c)): return
|
|
||||||
if not walk(fwd, is_word): return
|
if not walk(fwd, is_word): return
|
||||||
|
|
||||||
def _move_iter(self, buffer, itr_, mode: str, is_forward: bool):
|
def _move_iter(self, buffer, itr_, mode: str, is_forward: bool):
|
||||||
if mode == "char":
|
if mode == "char":
|
||||||
itr_.forward_char() if is_forward else itr_.backward_char()
|
itr_.forward_char() if is_forward else itr_.backward_char()
|
||||||
elif mode == "word":
|
elif mode == "word":
|
||||||
self.move_word_snake_case(itr_, 1 if is_forward else -1)
|
self.move_along_word(itr_, 1 if is_forward else -1)
|
||||||
elif mode == "line":
|
elif mode == "line":
|
||||||
line = itr_.get_line()
|
line = itr_.get_line()
|
||||||
offset = itr_.get_line_offset()
|
offset = itr_.get_line_offset()
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
# Python imports
|
# Python imports
|
||||||
|
|
||||||
# Lib imports
|
# Lib imports
|
||||||
|
import gi
|
||||||
|
gi.require_version('Gtk', '3.0')
|
||||||
|
from gi.repository import Gtk
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from libs.controllers.controller_base import ControllerBase
|
from libs.controllers.controller_base import ControllerBase
|
||||||
@@ -29,6 +32,8 @@ class SourceViewsController(ControllerBase, list):
|
|||||||
def _controller_message(self, event: Code_Event_Types.CodeEvent):
|
def _controller_message(self, event: Code_Event_Types.CodeEvent):
|
||||||
if isinstance(event, Code_Event_Types.CreateSourceViewEvent):
|
if isinstance(event, Code_Event_Types.CreateSourceViewEvent):
|
||||||
event.response = self.create_source_view(event.state)
|
event.response = self.create_source_view(event.state)
|
||||||
|
elif isinstance(event, Code_Event_Types.RemoveSourceViewEvent):
|
||||||
|
self._remove_source_view(event)
|
||||||
elif isinstance(event, Code_Event_Types.RemovedFileEvent):
|
elif isinstance(event, Code_Event_Types.RemovedFileEvent):
|
||||||
self._remove_file(event)
|
self._remove_file(event)
|
||||||
elif isinstance(event, Code_Event_Types.RegisterCommandEvent):
|
elif isinstance(event, Code_Event_Types.RegisterCommandEvent):
|
||||||
@@ -86,7 +91,7 @@ class SourceViewsController(ControllerBase, list):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def _get_command_system(self):
|
def _get_command_system(self):
|
||||||
event = Event_Factory.create_event("get_new_command_system")
|
event = Event_Factory.create_event("create_command_system")
|
||||||
self.message_to("commands", event)
|
self.message_to("commands", event)
|
||||||
command = event.response
|
command = event.response
|
||||||
|
|
||||||
@@ -103,15 +108,33 @@ class SourceViewsController(ControllerBase, list):
|
|||||||
|
|
||||||
source_view.set_buffer(event.next_file.buffer)
|
source_view.set_buffer(event.next_file.buffer)
|
||||||
|
|
||||||
|
def _remove_source_view(self, event: Code_Event_Types.RemovedFileEvent):
|
||||||
|
event = Event_Factory.create_event("removed_source_view", view = event.view)
|
||||||
|
self.message(event)
|
||||||
|
|
||||||
|
self.remove(event.view)
|
||||||
|
self.signal_mapper.disconnect_signals(event.view)
|
||||||
|
|
||||||
def create_source_view(self, state: SourceViewStates = SourceViewStates.INSERT):
|
def create_source_view(self, state: SourceViewStates = SourceViewStates.INSERT):
|
||||||
|
scrolled_win: Gtk.ScrolledWindow = Gtk.ScrolledWindow()
|
||||||
source_view: SourceView = SourceView(state)
|
source_view: SourceView = SourceView(state)
|
||||||
source_view.command = self._get_command_system()
|
source_view.command = self._get_command_system()
|
||||||
source_view.command.set_data(source_view)
|
|
||||||
|
|
||||||
|
scrolled_win.set_hexpand(True)
|
||||||
|
scrolled_win.set_vexpand(True)
|
||||||
|
|
||||||
|
source_view.command.set_data(source_view)
|
||||||
self.signal_mapper.connect_signals(source_view)
|
self.signal_mapper.connect_signals(source_view)
|
||||||
|
|
||||||
self.append(source_view)
|
self.append(source_view)
|
||||||
return source_view
|
scrolled_win.add(source_view)
|
||||||
|
|
||||||
|
event = Event_Factory.create_event(
|
||||||
|
"created_source_view", view = source_view
|
||||||
|
)
|
||||||
|
self.emit(event)
|
||||||
|
|
||||||
|
return scrolled_win, source_view
|
||||||
|
|
||||||
def first_map_load(self):
|
def first_map_load(self):
|
||||||
for source_view in self:
|
for source_view in self:
|
||||||
|
|||||||
@@ -59,30 +59,56 @@ class SourceViewsMultiInsertState(SourceViewsBaseState):
|
|||||||
buffer.insert(start_itr, text, -1)
|
buffer.insert(start_itr, text, -1)
|
||||||
|
|
||||||
self.marker_manager.apply_to_marks(buffer, replace_word)
|
self.marker_manager.apply_to_marks(buffer, replace_word)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def move_cursor(self, source_view, step, count, is_selection, emit):
|
def move_cursor(
|
||||||
|
self, source_view, step, count, is_selection,
|
||||||
|
emit = None, ignore_leader: bool = False
|
||||||
|
):
|
||||||
is_forward = count > 0
|
is_forward = count > 0
|
||||||
buffer = source_view.get_buffer()
|
buffer = source_view.get_buffer()
|
||||||
|
|
||||||
if step in [
|
start_mark = buffer.get_insert()
|
||||||
Gtk.MovementStep.LOGICAL_POSITIONS,
|
end_mark = buffer.get_selection_bound()
|
||||||
Gtk.MovementStep.VISUAL_POSITIONS
|
start_itr = buffer.get_iter_at_mark(start_mark)
|
||||||
]:
|
end_itr = buffer.get_iter_at_mark(end_mark)
|
||||||
self.marker_manager.move_by_char(buffer, is_forward, is_selection)
|
has_selection = not start_itr.equal(end_itr)
|
||||||
elif step == Gtk.MovementStep.WORDS:
|
|
||||||
self.marker_manager.move_by_word(buffer, is_forward, is_selection)
|
|
||||||
elif step == Gtk.MovementStep.DISPLAY_LINES:
|
|
||||||
self.marker_manager.move_by_line(buffer, is_forward, is_selection)
|
|
||||||
|
|
||||||
self._signal_cursor_moved(source_view, emit)
|
step_map = {
|
||||||
|
Gtk.MovementStep.LOGICAL_POSITIONS: ("char", self.marker_manager.move_by_char),
|
||||||
|
Gtk.MovementStep.VISUAL_POSITIONS: ("char", self.marker_manager.move_by_char),
|
||||||
|
Gtk.MovementStep.WORDS: ("word", self.marker_manager.move_by_word),
|
||||||
|
Gtk.MovementStep.DISPLAY_LINES: ("line", self.marker_manager.move_by_line),
|
||||||
|
}
|
||||||
|
|
||||||
return False
|
kind, move_fn = step_map[step]
|
||||||
|
move_fn(buffer, is_forward, is_selection)
|
||||||
|
|
||||||
|
if ignore_leader: return True
|
||||||
|
|
||||||
|
self.marker_manager._proc_move(
|
||||||
|
buffer,
|
||||||
|
is_forward,
|
||||||
|
is_selection,
|
||||||
|
kind,
|
||||||
|
None,
|
||||||
|
start_mark,
|
||||||
|
end_mark,
|
||||||
|
has_selection,
|
||||||
|
start_itr,
|
||||||
|
end_itr,
|
||||||
|
)
|
||||||
|
|
||||||
|
# self._signal_cursor_moved(source_view, emit)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
def key_press_event(self, source_view, event, key_mapper):
|
def key_press_event(self, source_view, event, key_mapper):
|
||||||
char = key_mapper.get_raw_keyname(event).upper()
|
char = key_mapper.get_raw_keyname(event).upper()
|
||||||
self.is_control = key_mapper.is_control(event)
|
self.is_control = key_mapper.is_control(event)
|
||||||
self.is_shift = key_mapper.is_shift(event)
|
self.is_shift = key_mapper.is_shift(event)
|
||||||
|
self.is_super = key_mapper.is_super(event)
|
||||||
|
|
||||||
if char.upper() in ["BACKSPACE", "DELETE", "ENTER"]:
|
if char.upper() in ["BACKSPACE", "DELETE", "ENTER"]:
|
||||||
self.marker_manager.process_cursor_action(
|
self.marker_manager.process_cursor_action(
|
||||||
@@ -91,6 +117,9 @@ class SourceViewsMultiInsertState(SourceViewsBaseState):
|
|||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if self._do_cursor_moved(source_view, char):
|
||||||
|
return True
|
||||||
|
|
||||||
return super().key_press_event(source_view, event, key_mapper)
|
return super().key_press_event(source_view, event, key_mapper)
|
||||||
|
|
||||||
def button_press_event(self, source_view, event):
|
def button_press_event(self, source_view, event):
|
||||||
@@ -99,6 +128,56 @@ class SourceViewsMultiInsertState(SourceViewsBaseState):
|
|||||||
def button_release_event(self, source_view, event):
|
def button_release_event(self, source_view, event):
|
||||||
self.marker_manager.button_release_event(source_view, event)
|
self.marker_manager.button_release_event(source_view, event)
|
||||||
|
|
||||||
|
def _do_cursor_moved(self, source_view, char: str):
|
||||||
|
key = char.upper()
|
||||||
|
if key not in {"LEFT", "RIGHT", "UP", "DOWN"}: return False
|
||||||
|
|
||||||
|
direction = {
|
||||||
|
"LEFT": -1,
|
||||||
|
"RIGHT": 1,
|
||||||
|
"UP": -1,
|
||||||
|
"DOWN": 1,
|
||||||
|
}[key]
|
||||||
|
|
||||||
|
is_horizontal = key in {"LEFT", "RIGHT"}
|
||||||
|
|
||||||
|
step = \
|
||||||
|
Gtk.MovementStep.VISUAL_POSITIONS if is_horizontal else Gtk.MovementStep.DISPLAY_LINES
|
||||||
|
count = direction
|
||||||
|
is_selection = self.is_shift
|
||||||
|
|
||||||
|
if is_horizontal:
|
||||||
|
if self.is_control:
|
||||||
|
step = Gtk.MovementStep.WORDS
|
||||||
|
if self.is_control and self.is_shift:
|
||||||
|
is_selection = True
|
||||||
|
if self.is_super:
|
||||||
|
return self.move_cursor(
|
||||||
|
source_view,
|
||||||
|
step,
|
||||||
|
count,
|
||||||
|
is_selection = False,
|
||||||
|
emit = None,
|
||||||
|
ignore_leader = True,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if self.is_super:
|
||||||
|
return self.move_cursor(
|
||||||
|
source_view,
|
||||||
|
step,
|
||||||
|
count,
|
||||||
|
is_selection,
|
||||||
|
emit = None,
|
||||||
|
ignore_leader = True,
|
||||||
|
)
|
||||||
|
|
||||||
|
return self.move_cursor(
|
||||||
|
source_view,
|
||||||
|
step = step,
|
||||||
|
count = count,
|
||||||
|
is_selection = is_selection,
|
||||||
|
)
|
||||||
|
|
||||||
def _signal_cursor_moved(self, source_view, emit):
|
def _signal_cursor_moved(self, source_view, emit):
|
||||||
buffer = source_view.get_buffer()
|
buffer = source_view.get_buffer()
|
||||||
itr = buffer.get_iter_at_mark( buffer.get_insert() )
|
itr = buffer.get_iter_at_mark( buffer.get_insert() )
|
||||||
|
|||||||
@@ -161,6 +161,10 @@ class KeyMapper:
|
|||||||
modifiers = Gdk.ModifierType(eve.get_state() & ~Gdk.ModifierType.LOCK_MASK)
|
modifiers = Gdk.ModifierType(eve.get_state() & ~Gdk.ModifierType.LOCK_MASK)
|
||||||
return modifiers & Gdk.ModifierType.SHIFT_MASK
|
return modifiers & Gdk.ModifierType.SHIFT_MASK
|
||||||
|
|
||||||
|
def is_super(self, eve):
|
||||||
|
modifiers = Gdk.ModifierType(eve.get_state() & ~Gdk.ModifierType.LOCK_MASK)
|
||||||
|
return modifiers & Gdk.ModifierType.SUPER_MASK
|
||||||
|
|
||||||
def get_raw_keyname(self, eve) -> str:
|
def get_raw_keyname(self, eve) -> str:
|
||||||
return Gdk.keyval_name(eve.keyval)
|
return Gdk.keyval_name(eve.keyval)
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,10 @@
|
|||||||
# Lib imports
|
# Lib imports
|
||||||
import gi
|
import gi
|
||||||
gi.require_version('Gtk', '3.0')
|
gi.require_version('Gtk', '3.0')
|
||||||
|
#gi.require_version('Gdk', '3.0')
|
||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
|
#from gi.repository import Gdk
|
||||||
|
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
|
|
||||||
@@ -12,25 +15,41 @@ from gi.repository import Gtk
|
|||||||
class SourceViewDnDMixin:
|
class SourceViewDnDMixin:
|
||||||
|
|
||||||
def _set_up_dnd(self):
|
def _set_up_dnd(self):
|
||||||
PLAIN_TEXT_TARGET_TYPE = 70
|
URI_TARGET_TYPE = 10
|
||||||
URI_TARGET_TYPE = 80
|
PLAIN_TEXT_TARGET_TYPE = 50
|
||||||
text_target = Gtk.TargetEntry.new('text/plain', Gtk.TargetFlags(0), PLAIN_TEXT_TARGET_TYPE)
|
|
||||||
uri_target = Gtk.TargetEntry.new('text/uri-list', Gtk.TargetFlags(0), URI_TARGET_TYPE)
|
uri_target = Gtk.TargetEntry.new(
|
||||||
targets = [ text_target, uri_target ]
|
'text/uri-list', Gtk.TargetFlags(0), URI_TARGET_TYPE
|
||||||
|
)
|
||||||
|
text_target = Gtk.TargetEntry.new(
|
||||||
|
'text/plain', Gtk.TargetFlags(0), PLAIN_TEXT_TARGET_TYPE
|
||||||
|
)
|
||||||
|
targets = Gtk.TargetList.new([ uri_target, text_target ])
|
||||||
|
|
||||||
self.drag_dest_set_target_list(targets)
|
self.drag_dest_set_target_list(targets)
|
||||||
|
|
||||||
def _on_drag_data_received(self, widget, drag_context, x, y, data, info, time):
|
def _on_drag_data_received(
|
||||||
if info == 70: return
|
self, widget, drag_context, x, y, data, info, time
|
||||||
|
):
|
||||||
|
target = data.get_target().name()
|
||||||
|
|
||||||
if info == 80:
|
if (info == 10) or (target == "text/uri-list"):
|
||||||
uris = data.get_uris()
|
uris = data.get_uris()
|
||||||
|
|
||||||
if not uris:
|
if not uris:
|
||||||
uris = data.get_text().split("\n")
|
uris = data.get_text().split("\n")
|
||||||
|
|
||||||
self._on_uri_data_received(uris)
|
self._on_uri_data_received(uris)
|
||||||
|
|
||||||
|
drag_context.finish(True, False, time)
|
||||||
|
|
||||||
|
return
|
||||||
|
elif (info == 50) or (target == "text/plain"):
|
||||||
|
...
|
||||||
|
else:
|
||||||
|
logger.info(f"DnD Dropped File Type: {target}")
|
||||||
|
|
||||||
|
drag_context.finish(False, False, time)
|
||||||
|
|
||||||
def _on_uri_data_received(self, uris: list[str]):
|
def _on_uri_data_received(self, uris: list[str]):
|
||||||
uris = self.command.filter_out_loaded_files(uris)
|
uris = self.command.filter_out_loaded_files(uris)
|
||||||
if not uris: return
|
if not uris: return
|
||||||
|
|||||||
@@ -155,9 +155,10 @@ class SourceFile(GtkSource.File):
|
|||||||
self.buffer.unblock_modified_changed_signal()
|
self.buffer.unblock_modified_changed_signal()
|
||||||
|
|
||||||
def is_externally_modified(self) -> bool:
|
def is_externally_modified(self) -> bool:
|
||||||
|
if self.fname == "buffer": return
|
||||||
|
|
||||||
stat = os.stat(self.fpath)
|
stat = os.stat(self.fpath)
|
||||||
current = (stat.st_mtime_ns, stat.st_size)
|
current = (stat.st_mtime_ns, stat.st_size)
|
||||||
|
|
||||||
is_modified = \
|
is_modified = \
|
||||||
hasattr(self, "last_state") and not current == self.last_state
|
hasattr(self, "last_state") and not current == self.last_state
|
||||||
|
|
||||||
@@ -169,7 +170,12 @@ class SourceFile(GtkSource.File):
|
|||||||
loaded, contents, etag_out = gfile.load_contents()
|
loaded, contents, etag_out = gfile.load_contents()
|
||||||
if not loaded: raise Exception("File couldn't be loaded...'")
|
if not loaded: raise Exception("File couldn't be loaded...'")
|
||||||
|
|
||||||
text = contents.decode("UTF-8")
|
# Note:
|
||||||
|
# "strict" (default) -> raises an error on invalid bytes
|
||||||
|
# "ignore" -> skips invalid bytes entirely
|
||||||
|
# "replace" -> replaces invalid bytes with <20>
|
||||||
|
# "backslashreplace" -> uses escape sequences like \xFF
|
||||||
|
text = contents.decode("UTF-8", errors = "replace")
|
||||||
info = gfile.query_info('standard::content-type', Gio.FileQueryInfoFlags.NONE, None)
|
info = gfile.query_info('standard::content-type', Gio.FileQueryInfoFlags.NONE, None)
|
||||||
content_type = info.get_content_type()
|
content_type = info.get_content_type()
|
||||||
self.ftype = Gio.content_type_get_mime_type(content_type) \
|
self.ftype = Gio.content_type_get_mime_type(content_type) \
|
||||||
@@ -177,6 +183,7 @@ class SourceFile(GtkSource.File):
|
|||||||
.replace("text/", "") \
|
.replace("text/", "") \
|
||||||
.replace("x-", "")
|
.replace("x-", "")
|
||||||
|
|
||||||
|
del contents
|
||||||
self.set_path(gfile)
|
self.set_path(gfile)
|
||||||
logger.debug(f"File content type: {self.ftype}")
|
logger.debug(f"File content type: {self.ftype}")
|
||||||
self._load_data(text)
|
self._load_data(text)
|
||||||
|
|||||||
50
src/libs/command_system.py
Normal file
50
src/libs/command_system.py
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# Python imports
|
||||||
|
import types
|
||||||
|
|
||||||
|
# Lib imports
|
||||||
|
|
||||||
|
# Application imports
|
||||||
|
from .event_factory import Event_Factory, Code_Event_Types
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class CommandSystem:
|
||||||
|
def __init__(self, commands: dict | types.ModuleType):
|
||||||
|
super(CommandSystem, self).__init__()
|
||||||
|
|
||||||
|
self.commands: dict | types.ModuleType = commands
|
||||||
|
self.data: tuple = ()
|
||||||
|
|
||||||
|
|
||||||
|
def set_data(self, *args, **kwargs):
|
||||||
|
self.data = (args, kwargs)
|
||||||
|
|
||||||
|
def exec(self, command: str) -> any:
|
||||||
|
"""
|
||||||
|
The 'exec' method passes the default 'self.data' to commands where custom args are not needed.
|
||||||
|
Ex: The 'code' widget has many internally created commands that
|
||||||
|
only need 'source_view' and so 'set_data' is called to set that.
|
||||||
|
"""
|
||||||
|
if not hasattr(self.commands, command): return
|
||||||
|
method = getattr(self.commands, command)
|
||||||
|
|
||||||
|
args, kwargs = self.data
|
||||||
|
return method.execute(*args, **kwargs)
|
||||||
|
|
||||||
|
def exec_with_args(self, command: str, *args, **kwargs) -> any:
|
||||||
|
"""
|
||||||
|
The 'exec_with_args' method passes custom args with the understanding
|
||||||
|
that the recipient has proper method signature to accept it- whether
|
||||||
|
*args or **kwargs or something else entirely.
|
||||||
|
"""
|
||||||
|
if not hasattr(self.commands, command): return
|
||||||
|
|
||||||
|
method = getattr(self.commands, command)
|
||||||
|
return method.execute(*args, **kwargs)
|
||||||
|
|
||||||
|
def add_command(self, command_name: str, command: callable):
|
||||||
|
setattr(self.commands, command_name, command)
|
||||||
|
|
||||||
|
def remove_command(self, command_name: str, command: callable):
|
||||||
|
if hasattr(self.commands, command_name):
|
||||||
|
delattr(self.commands, command_name)
|
||||||
@@ -6,6 +6,9 @@
|
|||||||
from .code_event import CodeEvent
|
from .code_event import CodeEvent
|
||||||
from .toggle_plugins_ui_event import TogglePluginsUiEvent
|
from .toggle_plugins_ui_event import TogglePluginsUiEvent
|
||||||
from .create_source_view_event import CreateSourceViewEvent
|
from .create_source_view_event import CreateSourceViewEvent
|
||||||
|
from .created_source_view_event import CreatedSourceViewEvent
|
||||||
|
from .remove_source_view_event import RemoveSourceViewEvent
|
||||||
|
from .removed_source_view_event import RemovedSourceViewEvent
|
||||||
from .register_completer_event import RegisterCompleterEvent
|
from .register_completer_event import RegisterCompleterEvent
|
||||||
from .unregister_completer_event import UnregisterCompleterEvent
|
from .unregister_completer_event import UnregisterCompleterEvent
|
||||||
from .register_provider_event import RegisterProviderEvent
|
from .register_provider_event import RegisterProviderEvent
|
||||||
@@ -20,7 +23,7 @@ from .filter_out_loaded_files_event import FilterOutLoadedFilesEvent
|
|||||||
from .get_active_view_event import GetActiveViewEvent
|
from .get_active_view_event import GetActiveViewEvent
|
||||||
from .get_source_views_event import GetSourceViewsEvent
|
from .get_source_views_event import GetSourceViewsEvent
|
||||||
|
|
||||||
from .get_new_command_system_event import GetNewCommandSystemEvent
|
from .create_command_system_event import CreateCommandSystemEvent
|
||||||
from .request_completion_event import RequestCompletionEvent
|
from .request_completion_event import RequestCompletionEvent
|
||||||
from .cursor_moved_event import CursorMovedEvent
|
from .cursor_moved_event import CursorMovedEvent
|
||||||
from .modified_changed_event import ModifiedChangedEvent
|
from .modified_changed_event import ModifiedChangedEvent
|
||||||
|
|||||||
@@ -9,5 +9,5 @@ from .code_event import CodeEvent
|
|||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class GetNewCommandSystemEvent(CodeEvent):
|
class CreateCommandSystemEvent(CodeEvent):
|
||||||
...
|
...
|
||||||
14
src/libs/dto/code/events/created_source_view_event.py
Normal file
14
src/libs/dto/code/events/created_source_view_event.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Python imports
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
# Lib imports
|
||||||
|
|
||||||
|
# Application imports
|
||||||
|
from .code_event import CodeEvent
|
||||||
|
from libs.dto.states.source_view_states import SourceViewStates
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class CreatedSourceViewEvent(CodeEvent):
|
||||||
|
...
|
||||||
14
src/libs/dto/code/events/remove_source_view_event.py
Normal file
14
src/libs/dto/code/events/remove_source_view_event.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Python imports
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
# Lib imports
|
||||||
|
|
||||||
|
# Application imports
|
||||||
|
from .code_event import CodeEvent
|
||||||
|
from libs.dto.states.source_view_states import SourceViewStates
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class RemoveSourceViewEvent(CodeEvent):
|
||||||
|
...
|
||||||
14
src/libs/dto/code/events/removed_source_view_event.py
Normal file
14
src/libs/dto/code/events/removed_source_view_event.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Python imports
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
# Lib imports
|
||||||
|
|
||||||
|
# Application imports
|
||||||
|
from .code_event import CodeEvent
|
||||||
|
from libs.dto.states.source_view_states import SourceViewStates
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class RemovedSourceViewEvent(CodeEvent):
|
||||||
|
...
|
||||||
@@ -13,9 +13,11 @@ from .requests import Requests
|
|||||||
class Manifest:
|
class Manifest:
|
||||||
name: str = ""
|
name: str = ""
|
||||||
author: str = ""
|
author: str = ""
|
||||||
credit: str = ""
|
description: str = ""
|
||||||
version: str = "0.0.1"
|
version: str = "0.0.1"
|
||||||
support: str = "support@mail.com"
|
support: str = "support@mail.com"
|
||||||
|
credit: str = ""
|
||||||
|
copyright: str = "GPLv2"
|
||||||
pre_launch: bool = False
|
pre_launch: bool = False
|
||||||
autoload: bool = True
|
autoload: bool = True
|
||||||
requests: Requests = field(default_factory = lambda: Requests())
|
requests: Requests = field(default_factory = lambda: Requests())
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class ManifestManager:
|
|||||||
|
|
||||||
if not manifest.autoload:
|
if not manifest.autoload:
|
||||||
self.manual_launch_manifests.append(manifest_meta)
|
self.manual_launch_manifests.append(manifest_meta)
|
||||||
return
|
return manifest_meta
|
||||||
|
|
||||||
if manifest.pre_launch:
|
if manifest.pre_launch:
|
||||||
self.pre_launch_manifests.append(manifest_meta)
|
self.pre_launch_manifests.append(manifest_meta)
|
||||||
|
|||||||
@@ -48,13 +48,13 @@ class PluginReloadMixin:
|
|||||||
|
|
||||||
def remove_plugin(self, file: str) -> None:
|
def remove_plugin(self, file: str) -> None:
|
||||||
logger.info(f"Removing plugin: {file.get_uri()}")
|
logger.info(f"Removing plugin: {file.get_uri()}")
|
||||||
for manifest_meta in self._plugin_collection[:]:
|
|
||||||
if not manifest_meta.folder in file.get_uri(): continue
|
|
||||||
|
|
||||||
manifest_meta.instance.unload()
|
manifests = self._manifest_manager.pre_launch_manifests \
|
||||||
manifest_meta.instance = None
|
+ self._manifest_manager.post_launch_manifests \
|
||||||
self._plugin_collection.remove(manifest_meta)
|
+ self._manifest_manager.manual_launch_manifests
|
||||||
self.plugins_ui.remove_row(manifest_meta)
|
|
||||||
|
for manifest_meta in manifests:
|
||||||
|
if not manifest_meta.folder in file.get_uri(): continue
|
||||||
|
|
||||||
if manifest_meta in self._manifest_manager.pre_launch_manifests:
|
if manifest_meta in self._manifest_manager.pre_launch_manifests:
|
||||||
self._manifest_manager.pre_launch_manifests.remove(manifest_meta)
|
self._manifest_manager.pre_launch_manifests.remove(manifest_meta)
|
||||||
@@ -63,4 +63,15 @@ class PluginReloadMixin:
|
|||||||
elif manifest_meta in self._manifest_manager.manual_launch_manifests:
|
elif manifest_meta in self._manifest_manager.manual_launch_manifests:
|
||||||
self._manifest_manager.manual_launch_manifests.remove(manifest_meta)
|
self._manifest_manager.manual_launch_manifests.remove(manifest_meta)
|
||||||
|
|
||||||
|
self.plugins_ui.remove_row(manifest_meta)
|
||||||
|
break
|
||||||
|
|
||||||
|
del manifests
|
||||||
|
for manifest_meta in self._plugin_collection[:]:
|
||||||
|
if not manifest_meta.folder in file.get_uri(): continue
|
||||||
|
|
||||||
|
manifest_meta.instance.unload()
|
||||||
|
manifest_meta.instance = None
|
||||||
|
self._plugin_collection.remove(manifest_meta)
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ class PluginsUI(Gtk.Dialog):
|
|||||||
|
|
||||||
toggle_bttn.toggle_id = \
|
toggle_bttn.toggle_id = \
|
||||||
toggle_bttn.connect("toggled", callback, manifest_meta)
|
toggle_bttn.connect("toggled", callback, manifest_meta)
|
||||||
|
box.toggle_bttn = toggle_bttn
|
||||||
|
|
||||||
box.add(plugin_lbl)
|
box.add(plugin_lbl)
|
||||||
box.add(author_lbl)
|
box.add(author_lbl)
|
||||||
@@ -96,5 +97,5 @@ class PluginsUI(Gtk.Dialog):
|
|||||||
toggle_bttn.disconnect(toggle_bttn.toggle_id)
|
toggle_bttn.disconnect(toggle_bttn.toggle_id)
|
||||||
|
|
||||||
self.list_box.remove(row)
|
self.list_box.remove(row)
|
||||||
box.destroy()
|
child.destroy()
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -42,17 +42,8 @@
|
|||||||
"save_file_as": {
|
"save_file_as": {
|
||||||
"released": "<Control><Shift>s"
|
"released": "<Control><Shift>s"
|
||||||
},
|
},
|
||||||
"focus_left_sibling": {
|
"toggle_plugins_ui": {
|
||||||
"released": "<Control>Page_Up"
|
"released": "<Control><Shift>p"
|
||||||
},
|
|
||||||
"focus_right_sibling": {
|
|
||||||
"released": "<Control>Page_Down"
|
|
||||||
},
|
|
||||||
"move_to_left_sibling": {
|
|
||||||
"released": "<Control><Shift>Up"
|
|
||||||
},
|
|
||||||
"move_to_right_sibling": {
|
|
||||||
"released": "<Control><Shift>Down"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user