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:
@@ -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