feat: improve LSP lifecycle, terminal widget, and code folding support

- LSP:
  - Add shutdown and exit request/notification handling
  - Send initialized notification after initialize response
  - Gracefully close clients with delayed shutdown via GLib timeout
  - Fix LSP WS server ↔ Godot LSP communication flow

- Terminal (VteWidget):
  - Switch to async spawn with full environment inheritance
  - Add PROMPT_COMMAND OSC7 support for cwd tracking
  - Improve UX: scrollback, no audible bell, auto scroll
  - Implement clipboard shortcuts, selection copy, middle-click paste
  - Track cwd changes and update UI label
  - Add proper signal wiring and cleanup on destroy

- Code folding:
  - Add fold support for JS, HTML, CSS, JSON, C, C++, Go
  - Reset fold state safely when AST or filetype is unavailable

- UI (Plugins dialog):
  - Improve dialog behavior (non-modal, centered, transient)
  - Add focus-out auto-hide and Ctrl+Shift+P shortcut

- Misc:
  - Add type hints in VTE widget
  - Update TODOs (remove completed items, add LSP comm fix)
  - Add terminal plugin scaffolding
This commit is contained in:
2026-04-13 00:50:42 -05:00
parent d8e0185d1c
commit 12b5fe7304
15 changed files with 585 additions and 34 deletions

View File

@@ -0,0 +1,60 @@
# Python imports
# Lib imports
# Application imports
from libs.event_factory import Event_Factory, Code_Event_Types
from plugins.plugin_types import PluginCode
from .terminals_view import TerminalsView
terminals_view = TerminalsView()
class Plugin(PluginCode):
def __init__(self):
super(Plugin, self).__init__()
def _controller_message(self, event: Code_Event_Types.CodeEvent):
...
def load(self):
footer = self.request_ui_element("footer-container")
footer.add( terminals_view )
self._manage_signals("register_command")
def unload(self):
self._manage_signals("unregister_command")
terminals_view.destroy()
def _manage_signals(self, action: str):
event = Event_Factory.create_event(action,
command_name = "terminals",
command = Handler,
binding_mode = "released",
binding = "<Control>."
)
self.emit_to("source_views", event)
def run(self):
...
class Handler:
@staticmethod
def execute(
view: any,
*args,
**kwargs
):
logger.debug("Command: Terminal")
terminals_view.set_code_view(view)
terminals_view.hide() if terminals_view.is_visible() else terminals_view.show()