feat: Complete plugin lifecycle management with lazy loading and runtime reload
Major changes: - Add unload() method to all plugins for proper cleanup (unregister commands/providers/LSP clients, destroy widgets, clear state) - Implement lazy widget loading via "show" signal across all containers - Add autoload: false manifest option for manual/conditional plugin loading - Add Plugins UI with runtime load/unload toggle via Ctrl+Shift+p - Implement controller unregistration system with proper signal disconnection - Add new events: UnregisterCommandEvent, GetFilesEvent, GetSourceViewsEvent, TogglePluginsUiEvent - Fix signal leaks by tracking and disconnecting handlers in widgets (search/replace, LSP manager, tabs, telescope, markdown preview) - Add Save/Save As to tabs context menu - Improve search/replace behavior (selection handling, focus management) - Add telescope file initialization from existing loaded files - Refactor plugin reload watcher to dynamically add/remove plugins on filesystem changes - Add new plugins: file_history, extend_source_view_menu, godot_lsp_client - Fix bug in prettify_json (undefined variable reference
This commit is contained in:
@@ -39,6 +39,24 @@ class Plugin(PluginCode):
|
||||
|
||||
self.emit_to("source_views", event)
|
||||
|
||||
def unload(self):
|
||||
event = Event_Factory.create_event("unregister_command",
|
||||
command_name = "autopairs",
|
||||
command = Handler,
|
||||
binding_mode = "held",
|
||||
binding = [
|
||||
"'", "`", "[", "]",
|
||||
'<Shift>"',
|
||||
'<Shift>(',
|
||||
'<Shift>)',
|
||||
'<Shift>{',
|
||||
'<Shift>}'
|
||||
]
|
||||
)
|
||||
|
||||
self.emit_to("source_views", event)
|
||||
autopairs = None
|
||||
|
||||
def run(self):
|
||||
...
|
||||
|
||||
|
||||
3
plugins/code/commands/file_history/__init__.py
Normal file
3
plugins/code/commands/file_history/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
"""
|
||||
Plugin Module
|
||||
"""
|
||||
3
plugins/code/commands/file_history/__main__.py
Normal file
3
plugins/code/commands/file_history/__main__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
"""
|
||||
Plugin Package
|
||||
"""
|
||||
97
plugins/code/commands/file_history/autopairs.py
Normal file
97
plugins/code/commands/file_history/autopairs.py
Normal file
@@ -0,0 +1,97 @@
|
||||
# Python imports
|
||||
|
||||
# Lib imports
|
||||
|
||||
# Application imports
|
||||
|
||||
|
||||
|
||||
class Autopairs:
|
||||
def __init__(self):
|
||||
...
|
||||
|
||||
def handle_word_wrap(self, buffer, char_str: str):
|
||||
wrap_block = self.get_wrap_block(char_str)
|
||||
if not wrap_block: return
|
||||
|
||||
selection = buffer.get_selection_bounds()
|
||||
if not selection:
|
||||
self.insert_pair(buffer, char_str, wrap_block)
|
||||
return True
|
||||
|
||||
self.wrap_selection(buffer, char_str, wrap_block, selection)
|
||||
|
||||
return True
|
||||
|
||||
def insert_pair(
|
||||
self, buffer, char_str: str, wrap_block: tuple
|
||||
):
|
||||
buffer.begin_user_action()
|
||||
|
||||
left_block, right_block = wrap_block
|
||||
insert_mark = buffer.get_insert()
|
||||
|
||||
insert_itr = buffer.get_iter_at_mark(insert_mark)
|
||||
buffer.insert(insert_itr, f"{left_block}{right_block}")
|
||||
insert_itr = buffer.get_iter_at_mark( insert_mark )
|
||||
insert_itr.backward_char()
|
||||
|
||||
buffer.place_cursor(insert_itr)
|
||||
|
||||
buffer.end_user_action()
|
||||
|
||||
def wrap_selection(
|
||||
self, buffer, char_str: str, wrap_block: tuple, selection
|
||||
):
|
||||
left_block, \
|
||||
right_block = wrap_block
|
||||
start_itr, \
|
||||
end_itr = selection
|
||||
data = buffer.get_text(
|
||||
start_itr, end_itr, include_hidden_chars = False
|
||||
)
|
||||
start_mark = buffer.create_mark("startclose", start_itr, False)
|
||||
end_mark = buffer.create_mark("endclose", end_itr, True)
|
||||
|
||||
buffer.begin_user_action()
|
||||
|
||||
buffer.insert(start_itr, left_block)
|
||||
end_itr = buffer.get_iter_at_mark(end_mark)
|
||||
buffer.insert(end_itr, right_block)
|
||||
|
||||
start = buffer.get_iter_at_mark(start_mark)
|
||||
end = buffer.get_iter_at_mark(end_mark)
|
||||
|
||||
buffer.select_range(start, end)
|
||||
buffer.delete_mark_by_name("startclose")
|
||||
buffer.delete_mark_by_name("endclose")
|
||||
|
||||
buffer.end_user_action()
|
||||
|
||||
def get_wrap_block(self, char_str) -> tuple:
|
||||
left_block = ""
|
||||
right_block = ""
|
||||
|
||||
match char_str:
|
||||
case "(" | ")":
|
||||
left_block = "("
|
||||
right_block = ")"
|
||||
case "[" | "]":
|
||||
left_block = "["
|
||||
right_block = "]"
|
||||
case "{" | "}":
|
||||
left_block = "{"
|
||||
right_block = "}"
|
||||
case '"':
|
||||
left_block = '"'
|
||||
right_block = '"'
|
||||
case "'":
|
||||
left_block = "'"
|
||||
right_block = "'"
|
||||
case "`":
|
||||
left_block = "`"
|
||||
right_block = "`"
|
||||
case _:
|
||||
return ()
|
||||
|
||||
return left_block, right_block
|
||||
7
plugins/code/commands/file_history/manifest.json
Normal file
7
plugins/code/commands/file_history/manifest.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "File History",
|
||||
"author": "ITDominator",
|
||||
"version": "0.0.1",
|
||||
"support": "",
|
||||
"requests": {}
|
||||
}
|
||||
65
plugins/code/commands/file_history/plugin.py
Normal file
65
plugins/code/commands/file_history/plugin.py
Normal file
@@ -0,0 +1,65 @@
|
||||
# Python imports
|
||||
|
||||
# Lib imports
|
||||
|
||||
# Application imports
|
||||
from libs.event_factory import Event_Factory, Code_Event_Types
|
||||
|
||||
from plugins.plugin_types import PluginCode
|
||||
|
||||
|
||||
|
||||
history: list = []
|
||||
history_size: int = 30
|
||||
|
||||
|
||||
class Plugin(PluginCode):
|
||||
def __init__(self):
|
||||
super(Plugin, self).__init__()
|
||||
|
||||
|
||||
def _controller_message(self, event: Code_Event_Types.CodeEvent):
|
||||
if isinstance(event, Code_Event_Types.RemovedFileEvent):
|
||||
if event.file.ftype == "buffer": return
|
||||
|
||||
if len(history) == history_size:
|
||||
history.pop(0)
|
||||
|
||||
history.append(event.file)
|
||||
|
||||
def load(self):
|
||||
self._manage_signals("register_command")
|
||||
|
||||
def unload(self):
|
||||
self._manage_signals("unregister_command")
|
||||
|
||||
def _manage_signals(self, action: str):
|
||||
event = Event_Factory.create_event(action,
|
||||
command_name = "file_history_pop",
|
||||
command = Handler,
|
||||
binding_mode = "released",
|
||||
binding = "<Shift><Control>t"
|
||||
)
|
||||
|
||||
self.emit_to("source_views", event)
|
||||
|
||||
def run(self):
|
||||
...
|
||||
|
||||
|
||||
class Handler:
|
||||
@staticmethod
|
||||
def execute(
|
||||
view: any,
|
||||
char_str: str,
|
||||
*args,
|
||||
**kwargs
|
||||
):
|
||||
logger.debug("Command: File History")
|
||||
if len(history) == 0: return
|
||||
|
||||
view._on_uri_data_received(
|
||||
[
|
||||
history.pop().replace("file://", "")
|
||||
]
|
||||
)
|
||||
@@ -21,7 +21,13 @@ class Plugin(PluginCode):
|
||||
...
|
||||
|
||||
def load(self):
|
||||
event = Event_Factory.create_event("register_command",
|
||||
self._manage_signals("register_command")
|
||||
|
||||
def load(self):
|
||||
self._manage_signals("unregister_command")
|
||||
|
||||
def _manage_signals(self, action: str):
|
||||
event = Event_Factory.create_event(action,
|
||||
command_name = "cut_to_temp_buffer",
|
||||
command = Handler,
|
||||
binding_mode = "held",
|
||||
@@ -30,7 +36,7 @@ class Plugin(PluginCode):
|
||||
|
||||
self.emit_to("source_views", event)
|
||||
|
||||
event = Event_Factory.create_event("register_command",
|
||||
event = Event_Factory.create_event(action,
|
||||
command_name = "paste_temp_buffer",
|
||||
command = Handler2,
|
||||
binding_mode = "held",
|
||||
|
||||
@@ -26,6 +26,16 @@ class Plugin(PluginCode):
|
||||
|
||||
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):
|
||||
...
|
||||
|
||||
|
||||
@@ -35,5 +35,15 @@ class Plugin(PluginCode):
|
||||
)
|
||||
self.emit_to("completion", event)
|
||||
|
||||
def unload(self):
|
||||
event = Event_Factory.create_event(
|
||||
"unregister_provider",
|
||||
provider_name = "Example Completer"
|
||||
)
|
||||
self.emit_to("completion", event)
|
||||
|
||||
self.provider = None
|
||||
del self.provider
|
||||
|
||||
def run(self):
|
||||
...
|
||||
|
||||
@@ -35,5 +35,15 @@ class Plugin(PluginCode):
|
||||
)
|
||||
self.emit_to("completion", event)
|
||||
|
||||
def unload(self):
|
||||
event = Event_Factory.create_event(
|
||||
"unregister_provider",
|
||||
provider_name = "Snippets Completer"
|
||||
)
|
||||
self.emit_to("completion", event)
|
||||
|
||||
self.provider = None
|
||||
del self.provider
|
||||
|
||||
def run(self):
|
||||
...
|
||||
|
||||
@@ -35,5 +35,15 @@ class Plugin(PluginCode):
|
||||
)
|
||||
self.emit_to("completion", event)
|
||||
|
||||
def unload(self):
|
||||
event = Event_Factory.create_event(
|
||||
"unregister_provider",
|
||||
provider_name = "Words Completer"
|
||||
)
|
||||
self.emit_to("completion", event)
|
||||
|
||||
self.provider = None
|
||||
del self.provider
|
||||
|
||||
def run(self):
|
||||
...
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
"""
|
||||
Plugin Module
|
||||
"""
|
||||
@@ -0,0 +1,3 @@
|
||||
"""
|
||||
Plugin Package
|
||||
"""
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "Extend Source View Menu",
|
||||
"author": "ITDominator",
|
||||
"version": "0.0.1",
|
||||
"support": "",
|
||||
"requests": {}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
# Python imports
|
||||
|
||||
# Lib imports
|
||||
|
||||
# Application imports
|
||||
from libs.event_factory import Event_Factory, Code_Event_Types
|
||||
|
||||
from plugins.plugin_types import PluginCode
|
||||
|
||||
from .source_view_menu import extend_source_view_menu
|
||||
|
||||
|
||||
|
||||
class Plugin(PluginCode):
|
||||
def __init__(self):
|
||||
super(Plugin, self).__init__()
|
||||
|
||||
def _controller_message(self, event: Code_Event_Types.CodeEvent):
|
||||
if isinstance(event, Code_Event_Types.PopulateSourceViewPopupEvent):
|
||||
extend_source_view_menu(event.buffer, event.menu)
|
||||
|
||||
def load(self):
|
||||
...
|
||||
|
||||
def unload(self):
|
||||
...
|
||||
|
||||
def run(self):
|
||||
...
|
||||
@@ -0,0 +1,68 @@
|
||||
# Python imports
|
||||
import json
|
||||
|
||||
# Lib imports
|
||||
import gi
|
||||
|
||||
gi.require_version('Gtk', '3.0')
|
||||
|
||||
from gi.repository import Gtk
|
||||
|
||||
# Application imports
|
||||
|
||||
|
||||
|
||||
def on_case_handle(menuitem, buffer, action):
|
||||
start_itr, \
|
||||
end_itr = buffer.get_selection_bounds()
|
||||
data = buffer.get_text(start_itr, end_itr, False)
|
||||
text = data
|
||||
|
||||
if action == "on_all_upper":
|
||||
text = data.upper()
|
||||
elif action == "on_all_lower":
|
||||
text = data.lower()
|
||||
elif action == "on_invert":
|
||||
text = data.swapcase()
|
||||
elif action == "on_title":
|
||||
text = data.title()
|
||||
elif action == "on_title_strip":
|
||||
text = data.title().replace("-", "").replace("_", "").replace(" ", "")
|
||||
|
||||
buffer.begin_user_action()
|
||||
buffer.delete(start_itr, end_itr)
|
||||
buffer.insert(start_itr, text)
|
||||
buffer.end_user_action()
|
||||
|
||||
|
||||
|
||||
def extend_source_view_menu(buffer, menu):
|
||||
if not buffer.get_selection_bounds(): return
|
||||
|
||||
for child in menu.get_children():
|
||||
if not child.get_label() == "C_hange Case": continue
|
||||
menu.remove(child)
|
||||
|
||||
change_case_item = Gtk.MenuItem(label = "Change Case")
|
||||
|
||||
case_menu = Gtk.Menu()
|
||||
au_case_item = Gtk.MenuItem(label = "All Upper Case")
|
||||
al_case_item = Gtk.MenuItem(label = "All Lower Case")
|
||||
inver_case_item = Gtk.MenuItem(label = "Invert Case")
|
||||
title_case_item = Gtk.MenuItem(label = "Title Case")
|
||||
title_strip_case_item = Gtk.MenuItem(label = "Title Strip Case")
|
||||
|
||||
au_case_item.connect("activate", on_case_handle, buffer, "on_all_upper")
|
||||
al_case_item.connect("activate", on_case_handle, buffer, "on_all_lower")
|
||||
inver_case_item.connect("activate", on_case_handle, buffer, "on_invert")
|
||||
title_case_item.connect("activate", on_case_handle, buffer, "on_title")
|
||||
title_strip_case_item.connect("activate", on_case_handle, buffer, "on_title_strip")
|
||||
|
||||
case_menu.append(au_case_item)
|
||||
case_menu.append(al_case_item)
|
||||
case_menu.append(inver_case_item)
|
||||
case_menu.append(title_case_item)
|
||||
case_menu.append(title_strip_case_item)
|
||||
change_case_item.set_submenu(case_menu)
|
||||
|
||||
menu.append(change_case_item)
|
||||
@@ -21,12 +21,15 @@ class Plugin(PluginCode):
|
||||
event.file.check_file_on_disk()
|
||||
|
||||
if event.file.is_deleted():
|
||||
file_is_deleted(event)
|
||||
file_is_deleted(event, self.emit)
|
||||
elif event.file.is_externally_modified():
|
||||
file_is_externally_modified(event)
|
||||
file_is_externally_modified(event, self.emit)
|
||||
|
||||
def load(self):
|
||||
...
|
||||
|
||||
def unload(self):
|
||||
...
|
||||
|
||||
def run(self):
|
||||
...
|
||||
|
||||
@@ -10,23 +10,23 @@ from libs.event_factory import Event_Factory, Code_Event_Types
|
||||
|
||||
|
||||
|
||||
def file_is_deleted(event):
|
||||
def file_is_deleted(event, emit):
|
||||
event.file.was_deleted = True
|
||||
event = Event_Factory.create_event(
|
||||
"file_externally_deleted",
|
||||
file = event.file,
|
||||
buffer = event.buffer
|
||||
)
|
||||
self.emit(event)
|
||||
emit(event)
|
||||
|
||||
|
||||
def file_is_externally_modified(event):
|
||||
def file_is_externally_modified(event, emit):
|
||||
# event = Event_Factory.create_event(
|
||||
# "file_externally_modified",
|
||||
# file = event.file,
|
||||
# buffer = event.buffer
|
||||
# )
|
||||
# self.emit(event)
|
||||
# emit(event)
|
||||
|
||||
...
|
||||
|
||||
|
||||
@@ -32,5 +32,8 @@ class Plugin(PluginCode):
|
||||
def load(self):
|
||||
...
|
||||
|
||||
def unload(self):
|
||||
...
|
||||
|
||||
def run(self):
|
||||
...
|
||||
|
||||
@@ -13,7 +13,7 @@ from gi.repository import Gtk
|
||||
|
||||
|
||||
def add_prettify_json(buffer, menu):
|
||||
menu.append( Gtk.SeparatorMenuItem() )
|
||||
menu.append(separator)
|
||||
|
||||
def on_prettify_json(menuitem, buffer):
|
||||
start_itr, \
|
||||
|
||||
@@ -3,5 +3,6 @@
|
||||
"author": "ITDominator",
|
||||
"version": "0.0.1",
|
||||
"support": "",
|
||||
"autoload": false,
|
||||
"requests": {}
|
||||
}
|
||||
|
||||
@@ -33,5 +33,11 @@ class Plugin(PluginCode):
|
||||
)
|
||||
self.emit_to("lsp_manager", event)
|
||||
|
||||
def unload(self):
|
||||
event = Event_Factory.create_event("unregister_lsp_client",
|
||||
lang_id = "java"
|
||||
)
|
||||
self.emit_to("lsp_manager", event)
|
||||
|
||||
def run(self):
|
||||
...
|
||||
|
||||
@@ -40,7 +40,7 @@ class LSPManager(ControllerBase):
|
||||
self.lsp_manager_ui.connect('close-client', self._on_close_client)
|
||||
|
||||
def _do_bind_mapping(self):
|
||||
self.response_cache.set_lsp_client(self.lsp_manager_client)
|
||||
self.response_cache.set_lsp_manager_client(self.lsp_manager_client)
|
||||
self.provider.response_cache = self.response_cache
|
||||
self.response_registry.set_event_hub(
|
||||
self.emit, self.emit_to, self.provider
|
||||
@@ -52,6 +52,7 @@ class LSPManager(ControllerBase):
|
||||
self.lsp_manager_ui.add_client_listing(event.lang_id, event.lang_config)
|
||||
elif isinstance(event, Code_Event_Types.UnregisterLspClientEvent):
|
||||
self.response_registry.unregister_handler(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:
|
||||
init_opts = ui.get_init_opts(lang_id)
|
||||
@@ -66,6 +67,10 @@ class LSPManager(ControllerBase):
|
||||
ui.toggle_client_buttons(show_close=False)
|
||||
return result
|
||||
|
||||
def handle_destroy(self):
|
||||
self.lsp_manager_ui.disconnect_by_func(self._on_create_client)
|
||||
self.lsp_manager_ui.disconnect_by_func(self._on_close_client)
|
||||
|
||||
def create_client(
|
||||
self,
|
||||
lang_id: str = "python",
|
||||
|
||||
@@ -41,7 +41,8 @@ class LSPManagerUI(Gtk.Dialog):
|
||||
self.set_hexpand(True)
|
||||
|
||||
def _setup_signals(self):
|
||||
self.connect("show", self._show)
|
||||
self.connect("show", self._handle_show)
|
||||
self.connect("destroy", self._handle_destroy)
|
||||
|
||||
def _subscribe_to_events(self):
|
||||
...
|
||||
@@ -68,7 +69,7 @@ class LSPManagerUI(Gtk.Dialog):
|
||||
|
||||
self.path_bttn.connect("file-set", self._file_set)
|
||||
self.combo_box.connect("changed", self._on_combo_changed)
|
||||
self.hide_bttn.connect("clicked", lambda widget: self.hide())
|
||||
self.hide_bttn_id = self.hide_bttn.connect("clicked", lambda widget: self.hide())
|
||||
self.create_client_bttn.connect("clicked", self._create_client, self.close_client_bttn)
|
||||
self.close_client_bttn.connect("clicked", self._close_client, self.create_client_bttn)
|
||||
|
||||
@@ -92,9 +93,18 @@ class LSPManagerUI(Gtk.Dialog):
|
||||
self.close_client_bttn.hide()
|
||||
bttn_box.hide()
|
||||
|
||||
def _show(self, widget):
|
||||
def _handle_show(self, widget):
|
||||
GLib.idle_add(self.path_entry.grab_focus)
|
||||
|
||||
def _handle_destroy(self, widget):
|
||||
self.disconnect_by_func(self._show)
|
||||
self.disconnect_by_func(self._handle_destroy)
|
||||
self.path_bttn.disconnect_by_func(self._file_set)
|
||||
self.combo_box.disconnect_by_func(self._on_combo_changed)
|
||||
self.hide_bttn.disconnect(self.hide_bttn_id)
|
||||
self.create_client_bttn.disconnect_by_func(self._create_client)
|
||||
self.close_client_bttn.disconnect_by_func(self._close_client)
|
||||
|
||||
def _map_resize(self, widget, parent):
|
||||
parent_x, parent_y = parent.get_position()
|
||||
parent_width, parent_height = parent.get_size()
|
||||
@@ -163,7 +173,10 @@ class LSPManagerUI(Gtk.Dialog):
|
||||
buffer.set_text(json_str, -1)
|
||||
|
||||
def map_parent_resize_event(self, parent):
|
||||
parent.connect("size-allocate", lambda w, r: self._map_resize(self, parent))
|
||||
self.size_allocate_id = parent.connect("size-allocate", lambda w, r: self._map_resize(self, parent))
|
||||
|
||||
def unmap_parent_resize_event(self, parent):
|
||||
parent.disconnect(self.size_allocate_id)
|
||||
|
||||
def set_source_view(self, source_view):
|
||||
scrolled_win = Gtk.ScrolledWindow()
|
||||
@@ -187,6 +200,17 @@ class LSPManagerUI(Gtk.Dialog):
|
||||
self.combo_box.append_text(lang_id)
|
||||
self.client_configs[lang_id] = lang_config
|
||||
|
||||
def remove_client_listing(self, lang_id: str):
|
||||
model = self.combo_box.get_model()
|
||||
|
||||
for i, row in enumerate(model):
|
||||
if row[0] == lang_id: # assuming text is in column 0
|
||||
self.combo_box.remove(i)
|
||||
break
|
||||
|
||||
if lang_id in self.client_configs:
|
||||
del self.client_configs[lang_id]
|
||||
|
||||
def get_init_opts(self, lang_id: str) -> dict:
|
||||
if not lang_id or lang_id not in self.client_configs: return {}
|
||||
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
"author": "ITDominator",
|
||||
"version": "0.0.1",
|
||||
"support": "",
|
||||
"pre_launch": true,
|
||||
"autoload": false,
|
||||
"requests": {}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,31 @@ class Plugin(PluginCode):
|
||||
source_view = event.response
|
||||
lsp_manager.lsp_manager_ui.set_source_view(source_view)
|
||||
|
||||
def unload(self):
|
||||
Event_Factory.unregister_events( lsp_events.__dict__.items() )
|
||||
|
||||
self.unregister_controller("lsp_manager")
|
||||
|
||||
window = self.request_ui_element("main-window")
|
||||
|
||||
lsp_manager.lsp_manager_ui.unmap_parent_resize_event(window)
|
||||
|
||||
event = Event_Factory.create_event("unregister_command",
|
||||
command_name = "LSP Manager",
|
||||
command = Handler,
|
||||
binding_mode = "released",
|
||||
binding = ["<Shift><Control>l", "<Control>g", "<Control>i"]
|
||||
)
|
||||
self.emit_to("source_views", event)
|
||||
|
||||
event = Event_Factory.create_event(
|
||||
"unregister_provider",
|
||||
provider_name = "LSP Completer"
|
||||
)
|
||||
self.emit_to("completion", event)
|
||||
|
||||
lsp_manager.handle_destroy()
|
||||
|
||||
def run(self):
|
||||
...
|
||||
|
||||
|
||||
@@ -15,27 +15,27 @@ class ProviderResponseCache(ProviderResponseCacheBase):
|
||||
def __init__(self):
|
||||
super(ProviderResponseCache, self).__init__()
|
||||
|
||||
self.matchers: dict = {}
|
||||
self._lsp_client = None
|
||||
self.matchers: dict = {}
|
||||
self.lsp_manager_client = None
|
||||
|
||||
def set_lsp_client(self, lsp_client):
|
||||
self._lsp_client = lsp_client
|
||||
def set_lsp_manager_client(self, lsp_client):
|
||||
self.lsp_manager_client = lsp_client
|
||||
|
||||
def process_file_load(self, event):
|
||||
if self._lsp_client:
|
||||
self._lsp_client.process_file_load(event)
|
||||
if self.lsp_manager_client:
|
||||
self.lsp_manager_client.process_file_load(event)
|
||||
|
||||
def process_file_close(self, event):
|
||||
if self._lsp_client:
|
||||
self._lsp_client.process_file_close(event)
|
||||
if self.lsp_manager_client:
|
||||
self.lsp_manager_client.process_file_close(event)
|
||||
|
||||
def process_file_save(self, event):
|
||||
if self._lsp_client:
|
||||
self._lsp_client.process_file_save(event)
|
||||
if self.lsp_manager_client:
|
||||
self.lsp_manager_client.process_file_save(event)
|
||||
|
||||
def process_file_change(self, event):
|
||||
if self._lsp_client:
|
||||
self._lsp_client.process_file_change(event)
|
||||
if self.lsp_manager_client:
|
||||
self.lsp_manager_client.process_file_change(event)
|
||||
|
||||
def filter(self, word: str) -> list[dict]:
|
||||
return []
|
||||
|
||||
@@ -33,7 +33,7 @@ class ResponseRegistry:
|
||||
def register_handler(self, lang_id: str, handler_cls: type[BaseHandler]):
|
||||
self._lang_handlers[lang_id] = handler_cls
|
||||
|
||||
def unregister_handler(self, lang_id: str, handler_cls: type[BaseHandler]):
|
||||
def unregister_handler(self, lang_id: str):
|
||||
del self._lang_handlers[lang_id]
|
||||
|
||||
def get_handler(self, lang_id: str = "", method: str = ""):
|
||||
|
||||
@@ -3,5 +3,6 @@
|
||||
"author": "ITDominator",
|
||||
"version": "0.0.1",
|
||||
"support": "",
|
||||
"autoload": false,
|
||||
"requests": {}
|
||||
}
|
||||
|
||||
@@ -33,5 +33,11 @@ class Plugin(PluginCode):
|
||||
)
|
||||
self.emit_to("lsp_manager", event)
|
||||
|
||||
def unload(self):
|
||||
event = Event_Factory.create_event("unregister_lsp_client",
|
||||
lang_id = "python"
|
||||
)
|
||||
self.emit_to("lsp_manager", event)
|
||||
|
||||
def run(self):
|
||||
...
|
||||
|
||||
@@ -28,5 +28,12 @@ class Plugin(PluginCode):
|
||||
editors_container = self.request_ui_element("editors-container")
|
||||
editors_container.add( code_minimap )
|
||||
|
||||
event = Event_Factory.create_event("get_active_view")
|
||||
self.emit_to("source_views", event)
|
||||
code_minimap.set_smini_view(event.response)
|
||||
|
||||
def unload(self):
|
||||
code_minimap.destroy()
|
||||
|
||||
def run(self):
|
||||
...
|
||||
|
||||
@@ -35,7 +35,6 @@ class InfoBarWidget(Gtk.Box):
|
||||
def _subscribe_to_events(self):
|
||||
...
|
||||
|
||||
|
||||
def _load_widgets(self):
|
||||
self.path_label = Gtk.Label(label = "...")
|
||||
self.line_char_label = Gtk.Label(label = "1:0")
|
||||
@@ -92,5 +91,3 @@ class InfoBarWidget(Gtk.Box):
|
||||
encoding_type = "utf-8" if not encoding_type else encoding_type
|
||||
|
||||
self.encoding_label.set_text(encoding_type)
|
||||
|
||||
|
||||
|
||||
@@ -28,5 +28,8 @@ class Plugin(PluginCode):
|
||||
header = self.request_ui_element("header-container")
|
||||
header.add( info_bar_widget )
|
||||
|
||||
def unload(self):
|
||||
info_bar_widget.destroy()
|
||||
|
||||
def run(self):
|
||||
...
|
||||
|
||||
@@ -20,13 +20,27 @@ class Plugin(PluginCode):
|
||||
...
|
||||
|
||||
def load(self):
|
||||
tabs_controller = TabsController()
|
||||
self.tabs_controller = TabsController()
|
||||
code_container = self.request_ui_element("code-container")
|
||||
|
||||
self.register_controller("tabs", tabs_controller)
|
||||
self.register_controller("tabs", self.tabs_controller)
|
||||
|
||||
code_container.add( tabs_controller.tabs_widget )
|
||||
code_container.reorder_child(tabs_controller.tabs_widget, 0)
|
||||
code_container.add( self.tabs_controller.tabs_widget )
|
||||
code_container.reorder_child(self.tabs_controller.tabs_widget, 0)
|
||||
|
||||
event = Event_Factory.create_event("get_files")
|
||||
self.emit_to("files", event)
|
||||
for file in event.response:
|
||||
self.tabs_controller.add_tab(file)
|
||||
|
||||
def unload(self):
|
||||
self.unregister_controller("tabs")
|
||||
self.tabs_controller.unload_tabs()
|
||||
self.tabs_controller.tabs_widget.destroy()
|
||||
|
||||
self.tabs_controller.tabs_widget = None
|
||||
self.tabs_controller = None
|
||||
del self.tabs_controller
|
||||
|
||||
def run(self):
|
||||
...
|
||||
|
||||
@@ -32,7 +32,6 @@ class TabWidget(Gtk.Box):
|
||||
self.set_orientation(0)
|
||||
self.set_hexpand(False)
|
||||
self.set_vexpand(False)
|
||||
self.set_can_focus(False)
|
||||
self.set_size_request(-1, 12)
|
||||
|
||||
def _setup_signals(self):
|
||||
@@ -44,10 +43,6 @@ class TabWidget(Gtk.Box):
|
||||
self.close_bttn = Gtk.Button()
|
||||
icon = Gtk.Image(stock = Gtk.STOCK_CLOSE)
|
||||
|
||||
self.event_box.set_can_focus(False)
|
||||
self.label.set_can_focus(False)
|
||||
self.close_bttn.set_can_focus(False)
|
||||
|
||||
self.event_box.set_above_child(True)
|
||||
ctx = self.label.get_style_context()
|
||||
ctx.add_class("tab-label")
|
||||
|
||||
@@ -16,7 +16,6 @@ from .tab_widget import TabWidget
|
||||
|
||||
|
||||
|
||||
|
||||
class TabsController(ControllerBase):
|
||||
def __init__(self):
|
||||
super(TabsController, self).__init__()
|
||||
@@ -35,7 +34,7 @@ class TabsController(ControllerBase):
|
||||
elif isinstance(event, Code_Event_Types.FileExternallyDeletedEvent):
|
||||
self.tabs_widget.externally_deleted( event.buffer )
|
||||
elif isinstance(event, Code_Event_Types.AddedNewFileEvent):
|
||||
self.add_tab(event)
|
||||
self.add_tab(event.file)
|
||||
elif isinstance(event, Code_Event_Types.PoppedFileEvent):
|
||||
...
|
||||
elif isinstance(event, Code_Event_Types.RemovedFileEvent):
|
||||
@@ -53,11 +52,11 @@ class TabsController(ControllerBase):
|
||||
|
||||
break
|
||||
|
||||
def add_tab(self, event: Code_Event_Types.AddedNewFileEvent):
|
||||
def add_tab(self, file):
|
||||
tab = TabWidget()
|
||||
tab.file = event.file
|
||||
tab.file = file
|
||||
|
||||
tab.label.set_label(event.file.fname)
|
||||
tab.label.set_label(file.fname)
|
||||
|
||||
self.tabs_widget.append_page(Gtk.Separator(), tab)
|
||||
tab.show_all()
|
||||
@@ -73,3 +72,13 @@ class TabsController(ControllerBase):
|
||||
)
|
||||
|
||||
break
|
||||
|
||||
def unload_tabs(self):
|
||||
for page_widget in self.tabs_widget.get_children():
|
||||
tab = self.tabs_widget.get_tab_label(page_widget)
|
||||
|
||||
tab.clear_signals_and_data()
|
||||
self.tabs_widget.remove_page(
|
||||
self.tabs_widget.page_num(page_widget)
|
||||
)
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ class TabsWidget(Gtk.Notebook):
|
||||
self.connect("page-added", self._page_added)
|
||||
self.switch_page_id = \
|
||||
self.connect_after("switch-page", self._switch_page)
|
||||
self.connect("destroy", self._handle_destroy)
|
||||
|
||||
def _subscribe_to_events(self):
|
||||
...
|
||||
@@ -81,25 +82,38 @@ class TabsWidget(Gtk.Notebook):
|
||||
)
|
||||
|
||||
def create_menu(self, page_widget) -> Gtk.Menu:
|
||||
context_menu = Gtk.Menu()
|
||||
context_menu = Gtk.Menu()
|
||||
close_submenu = Gtk.Menu()
|
||||
save_item = Gtk.MenuItem(label = "Save")
|
||||
save_as_item = Gtk.MenuItem(label = "Save As")
|
||||
|
||||
close_item = Gtk.MenuItem(label = "Close Tab")
|
||||
close_left_item = Gtk.MenuItem(label = "Close Tabs Left")
|
||||
close_right_item = Gtk.MenuItem(label = "Close Tabs Right")
|
||||
close_other_item = Gtk.MenuItem(label = "Close Other Tabs")
|
||||
close_all_item = Gtk.MenuItem(label = "Close All Tabs")
|
||||
close_actions_menu = Gtk.MenuItem(label = "Close Actions")
|
||||
close_item = Gtk.MenuItem(label = "Close Tab")
|
||||
close_left_item = Gtk.MenuItem(label = "Close Tabs Left")
|
||||
close_right_item = Gtk.MenuItem(label = "Close Tabs Right")
|
||||
close_other_item = Gtk.MenuItem(label = "Close Other Tabs")
|
||||
close_all_item = Gtk.MenuItem(label = "Close All Tabs")
|
||||
|
||||
close_item.connect("activate", self.close_item, page_widget)
|
||||
close_left_item.connect("activate", self.close_left_items, page_widget)
|
||||
save_item.connect("activate", self.save_item, page_widget)
|
||||
save_as_item.connect("activate", self.save_as_item, page_widget)
|
||||
|
||||
close_item.connect("activate", self.close_item, page_widget)
|
||||
close_left_item.connect("activate", self.close_left_items, page_widget)
|
||||
close_right_item.connect("activate", self.close_right_items, page_widget)
|
||||
close_other_item.connect("activate", self.close_other_items, page_widget)
|
||||
close_all_item.connect("activate", self.close_all_items, page_widget)
|
||||
close_all_item.connect("activate", self.close_all_items, page_widget)
|
||||
|
||||
context_menu.append(close_item)
|
||||
context_menu.append(close_left_item)
|
||||
context_menu.append(close_right_item)
|
||||
context_menu.append(close_other_item)
|
||||
context_menu.append(close_all_item)
|
||||
close_submenu.append(close_item)
|
||||
close_submenu.append(close_left_item)
|
||||
close_submenu.append(close_right_item)
|
||||
close_submenu.append(close_other_item)
|
||||
close_submenu.append(close_all_item)
|
||||
|
||||
close_actions_menu.set_submenu(close_submenu)
|
||||
|
||||
context_menu.append(save_item)
|
||||
context_menu.append(save_as_item)
|
||||
context_menu.append(close_actions_menu)
|
||||
|
||||
context_menu.show_all()
|
||||
|
||||
@@ -115,7 +129,6 @@ class TabsWidget(Gtk.Notebook):
|
||||
self.set_current_page(
|
||||
self.page_num(page_widget)
|
||||
)
|
||||
|
||||
self.handler_unblock(self.switch_page_id)
|
||||
|
||||
break
|
||||
@@ -143,6 +156,14 @@ class TabsWidget(Gtk.Notebook):
|
||||
break
|
||||
|
||||
|
||||
def save_item(self, menu_item, page_widget):
|
||||
tab = self.get_tab_label(page_widget)
|
||||
tab.file.save()
|
||||
|
||||
def save_as_item(self, menu_item, page_widget):
|
||||
tab = self.get_tab_label(page_widget)
|
||||
tab.file.save_as()
|
||||
|
||||
def close_item(self, menu_item, page_widget):
|
||||
tab = self.get_tab_label(page_widget)
|
||||
tab.close_bttn.clicked()
|
||||
@@ -177,3 +198,9 @@ class TabsWidget(Gtk.Notebook):
|
||||
for widget in children[ : ]:
|
||||
tab = self.get_tab_label(widget)
|
||||
tab.close_bttn.clicked()
|
||||
|
||||
def _handle_destroy(self, widget):
|
||||
self.disconnect_by_func(self._page_added)
|
||||
self.disconnect_by_func(self._switch_page)
|
||||
self.disconnect_by_func(self._handle_destroy)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user