Source code for simvx.ide.edit_controller
"""Edit command handlers -- undo, redo, clipboard, line operations, folding, bookmarks."""
from __future__ import annotations
import logging
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .app import IDERoot
log = logging.getLogger(__name__)
[docs]
class EditCommandController:
"""Handles all edit-menu actions and bookmark/history navigation.
Methods access the editor panel and IDE state through the ``ide`` reference.
"""
def __init__(self, ide: IDERoot) -> None:
self._ide = ide
# -- Convenience accessors ------------------------------------------------
@property
def _editor_panel(self):
return self._ide._editor_panel
@property
def state(self):
return self._ide.state
# -- Basic edit actions ---------------------------------------------------
[docs]
def on_undo(self):
if self._editor_panel:
self._editor_panel.undo()
[docs]
def on_redo(self):
if self._editor_panel:
self._editor_panel.redo()
[docs]
def on_cut(self):
if self._editor_panel:
self._editor_panel.cut()
[docs]
def on_copy(self):
if self._editor_panel:
self._editor_panel.copy()
[docs]
def on_paste(self):
if self._editor_panel:
self._editor_panel.paste()
[docs]
def on_select_all(self):
if self._editor_panel:
self._editor_panel.select_all()
[docs]
def on_delete_line(self):
if self._editor_panel:
self._editor_panel.delete_line()
[docs]
def on_select_next(self):
if self._editor_panel:
self._editor_panel.select_next_occurrence()
# -- Line operations ------------------------------------------------------
[docs]
def on_duplicate_line(self):
editor = self._editor_panel.get_current_editor() if self._editor_panel else None
if editor and hasattr(editor, "duplicate_line"):
editor.duplicate_line()
[docs]
def on_move_line_up(self):
editor = self._editor_panel.get_current_editor() if self._editor_panel else None
if editor and hasattr(editor, "move_line_up"):
editor.move_line_up()
[docs]
def on_move_line_down(self):
editor = self._editor_panel.get_current_editor() if self._editor_panel else None
if editor and hasattr(editor, "move_line_down"):
editor.move_line_down()
# -- Folding --------------------------------------------------------------
[docs]
def on_fold(self):
editor = self._editor_panel.get_current_editor() if self._editor_panel else None
if editor and hasattr(editor, "fold_at_line"):
editor.fold_at_line(editor._cursor_line)
[docs]
def on_unfold(self):
editor = self._editor_panel.get_current_editor() if self._editor_panel else None
if editor and hasattr(editor, "unfold_at_line"):
editor.unfold_at_line(editor._cursor_line)
# -- Bookmark handlers ----------------------------------------------------
[docs]
def on_toggle_bookmark(self):
path = self.state.active_file
editor = self._editor_panel.get_current_editor() if self._editor_panel else None
if path and editor:
self.state.toggle_bookmark(path, editor._cursor_line)
self._apply_bookmark_markers(path, editor)
[docs]
def on_next_bookmark(self):
path = self.state.active_file
editor = self._editor_panel.get_current_editor() if self._editor_panel else None
if not path or not editor:
return
bookmarks = sorted(self.state.get_bookmarks(path))
if not bookmarks:
return
current = editor._cursor_line
for bm in bookmarks:
if bm > current:
editor._cursor_line = bm
editor._cursor_col = 0
editor._ensure_cursor_visible()
return
# Wrap around
editor._cursor_line = bookmarks[0]
editor._cursor_col = 0
editor._ensure_cursor_visible()
[docs]
def on_prev_bookmark(self):
path = self.state.active_file
editor = self._editor_panel.get_current_editor() if self._editor_panel else None
if not path or not editor:
return
bookmarks = sorted(self.state.get_bookmarks(path), reverse=True)
if not bookmarks:
return
current = editor._cursor_line
for bm in bookmarks:
if bm < current:
editor._cursor_line = bm
editor._cursor_col = 0
editor._ensure_cursor_visible()
return
# Wrap around
editor._cursor_line = bookmarks[0]
editor._cursor_col = 0
editor._ensure_cursor_visible()
def _apply_bookmark_markers(self, path: str, editor):
"""Update bookmark markers on the editor."""
editor.clear_markers("bookmark")
for line in self.state.get_bookmarks(path):
editor.add_marker(line, 0, 999, type="bookmark", tooltip="Bookmark")
# -- History navigation ---------------------------------------------------
[docs]
def on_history_back(self):
result = self.state.history_back()
if result:
path, line, col = result
if self._editor_panel:
self._editor_panel.open_file(path)
self._editor_panel.goto_line(line, col)
[docs]
def on_history_forward(self):
result = self.state.history_forward()
if result:
path, line, col = result
if self._editor_panel:
self._editor_panel.open_file(path)
self._editor_panel.goto_line(line, col)
# -- Find -----------------------------------------------------------------
[docs]
def on_find(self):
if self._editor_panel:
self._editor_panel.show_find()
[docs]
def on_replace(self):
if self._editor_panel:
self._editor_panel.show_replace()
[docs]
def on_find_in_files(self):
self._ide._switch_to_tab("Search")
self._ide._show_bottom_panel()