Refactor source view states to use base class and fix open-files start path

- Add SourceViewsBaseState inheritance to Command, Insert, MultiInsert, and ReadOnly states
- Extract common focus_in_event logic to base class
- Fix open-files command to use current file's directory as file picker start path
- Extract modifier key state logic into reusable get_modkeys_states() method
- Pass modifier keys to command exec_with_args in key_press_event
- Add type hints to key_mapper methods
This commit is contained in:
2026-02-24 23:32:29 -06:00
parent 24bf1e471b
commit 3b205e28e6
12 changed files with 292 additions and 103 deletions

View File

@@ -18,10 +18,14 @@ def execute(
**kwargs
):
logger.debug("Command: Open File(s)")
gfiles = event_system.emit_and_await("open-files")
file = view.command.get_file(view)
start_path = None
if not file.ftype == "buffer":
start_path = file.get_location()
gfiles = event_system.emit_and_await("open-files", (None, None, start_path))
if not gfiles: return
file = view.command.get_file(view)
if file.ftype == "buffer":
gfile = gfiles.pop()
view.command.exec_with_args("load_file", view, gfile, file)

View File

@@ -0,0 +1,80 @@
# Python imports
# Lib imports
# Application imports
from libs.event_factory import Event_Factory, Code_Event_Types
from libs.dto.states import SourceViewStates
class SourceViewsBaseState:
def __init__(self):
super(SourceViewsBaseState, self).__init__()
def focus_in_event(self, source_view, eve, emit):
source_view.command.exec("set_miniview")
source_view.command.exec("set_focus_border")
source_view.command.exec("update_info_bar")
event = Event_Factory.create_event("focused_view", view = source_view)
emit(event)
def insert_text(self, file, text: str):
return True
def move_cursor(self, source_view, step, count, extend_selection, emit):
buffer = source_view.get_buffer()
itr = buffer.get_iter_at_mark( buffer.get_insert() )
line = itr.get_line()
char = itr.get_line_offset()
event = Event_Factory.create_event(
"cursor_moved",
view = source_view,
buffer = buffer,
line = line,
char = char
)
emit(event)
source_view.command.exec("update_info_bar")
def button_press_event(self, source_view, eve):
source_view.command.exec("update_info_bar")
def button_release_event(self, source_view, eve):
source_view.command.exec("update_info_bar")
def key_press_event(self, source_view, eve, key_mapper):
command = key_mapper._key_press_event(eve)
is_future = key_mapper._key_release_event(eve)
char_str = key_mapper.get_char(eve)
modkeys_states = key_mapper.get_modkeys_states(eve)
if is_future: return True
if not command: return False
response = source_view.command.exec_with_args(
command, source_view, char_str, modkeys_states
)
return True if not response else response
def key_release_event(self, source_view, eve, key_mapper):
command = key_mapper._key_release_event(eve)
is_past = key_mapper._key_press_event(eve)
char_str = key_mapper.get_char(eve)
modkeys_states = key_mapper.get_modkeys_states(eve)
if is_past: return True
if not command: return False
response = source_view.command.exec_with_args(
command, source_view, char_str, modkeys_states
)
return True if not response else response

View File

@@ -7,9 +7,11 @@ from libs.event_factory import Event_Factory, Code_Event_Types
from libs.dto.states import SourceViewStates
from .source_view_base_state import SourceViewsBaseState
class SourceViewsCommandState:
class SourceViewsCommandState(SourceViewsBaseState):
def __init__(self):
super(SourceViewsCommandState, self).__init__()
@@ -17,10 +19,10 @@ class SourceViewsCommandState:
def focus_in_event(self, source_view, eve, emit):
return True
def move_cursor(self, source_view, step, count, extend_selection, emit):
def insert_text(self, file, text):
return True
def insert_text(self, file, text):
def move_cursor(self, source_view, step, count, extend_selection, emit):
return True
def button_press_event(self, source_view, eve):

View File

@@ -7,68 +7,10 @@ from libs.event_factory import Event_Factory, Code_Event_Types
from libs.dto.states import SourceViewStates
from .source_view_base_state import SourceViewsBaseState
class SourceViewsInsertState:
class SourceViewsInsertState(SourceViewsBaseState):
def __init__(self):
super(SourceViewsInsertState, self).__init__()
def focus_in_event(self, source_view, eve, emit):
source_view.command.exec("set_miniview")
source_view.command.exec("set_focus_border")
source_view.command.exec("update_info_bar")
event = Event_Factory.create_event("focused_view", view = source_view)
emit(event)
def insert_text(self, file, text: str):
return True
def move_cursor(self, source_view, step, count, extend_selection, emit):
buffer = source_view.get_buffer()
itr = buffer.get_iter_at_mark( buffer.get_insert() )
line = itr.get_line()
char = itr.get_line_offset()
event = Event_Factory.create_event(
"cursor_moved",
view = source_view,
buffer = buffer,
line = line,
char = char
)
emit(event)
source_view.command.exec("update_info_bar")
def button_press_event(self, source_view, eve):
source_view.command.exec("update_info_bar")
def button_release_event(self, source_view, eve):
source_view.command.exec("update_info_bar")
def key_press_event(self, source_view, eve, key_mapper):
command = key_mapper._key_press_event(eve)
is_future = key_mapper._key_release_event(eve)
char_str = key_mapper.get_char(eve)
if is_future: return True
if not command: return False
source_view.command.exec_with_args(command, source_view, char_str)
return True
def key_release_event(self, source_view, eve, key_mapper):
command = key_mapper._key_release_event(eve)
is_past = key_mapper._key_press_event(eve)
char_str = key_mapper.get_char(eve)
if is_past: return True
if not command: return False
source_view.command.exec_with_args(command, source_view, char_str)
return True

View File

@@ -11,9 +11,11 @@ from libs.dto.states import SourceViewStates, MoveDirection, CursorAction
from ....mixins.source_mark_events_mixin import MarkEventsMixin
from .source_view_base_state import SourceViewsBaseState
class SourceViewsMultiInsertState(MarkEventsMixin):
class SourceViewsMultiInsertState(SourceViewsBaseState, MarkEventsMixin):
def __init__(self):
super(SourceViewsMultiInsertState, self).__init__()
@@ -22,14 +24,6 @@ class SourceViewsMultiInsertState(MarkEventsMixin):
self.insert_markers: list = []
def focus_in_event(self, source_view, eve, emit):
source_view.command.exec("set_miniview")
source_view.command.exec("set_focus_border")
source_view.command.exec("update_info_bar")
event = Event_Factory.create_event("focused_view", view = source_view)
emit(event)
def insert_text(self, file, text):
if not self.insert_markers: return False
@@ -86,7 +80,7 @@ class SourceViewsMultiInsertState(MarkEventsMixin):
source_view.command.exec("update_info_bar")
def button_press_event(self, source_view, eve):
source_view.command.exec("update_info_bar")
super().button_press_event(source_view, eve)
return True
def button_release_event(self, source_view, eve):
@@ -129,20 +123,13 @@ class SourceViewsMultiInsertState(MarkEventsMixin):
command = key_mapper._key_press_event(eve)
if not command: return False
source_view.command.exec(command)
char_str = key_mapper.get_char(eve)
modkeys_states = key_mapper.get_modkeys_states(eve)
response = source_view.command.exec_with_args(
command, source_view, char_str, modkeys_states
)
return True
def key_release_event(self, source_view, eve, key_mapper):
command = key_mapper._key_release_event(eve)
is_past = key_mapper._key_press_event(eve)
if is_past: return True
if not command: return False
source_view.command.exec(command)
return True
return True if not response else response
def _signal_cursor_moved(self, source_view, emit):
buffer = source_view.get_buffer()

View File

@@ -7,9 +7,11 @@ from libs.event_factory import Event_Factory, Code_Event_Types
from libs.dto.states import SourceViewStates
from .source_view_base_state import SourceViewsBaseState
class SourceViewsReadOnlyState:
class SourceViewsReadOnlyState(SourceViewsBaseState):
def __init__(self):
super(SourceViewsReadOnlyState, self).__init__()
@@ -17,10 +19,10 @@ class SourceViewsReadOnlyState:
def focus_in_event(self, source_view, eve, emit):
return True
def move_cursor(self, source_view, step, count, extend_selection, emit):
def insert_text(self, file, text):
return True
def insert_text(self, file, text):
def move_cursor(self, source_view, step, count, extend_selection, emit):
return True
def button_press_event(self, source_view, eve):

View File

@@ -119,14 +119,9 @@ class KeyMapper:
return self.states[self.state].released[char_str]
def _set_key_state(self, eve):
modifiers = Gdk.ModifierType(eve.get_state() & ~Gdk.ModifierType.LOCK_MASK)
is_control = modifiers & Gdk.ModifierType.CONTROL_MASK
is_shift = modifiers & Gdk.ModifierType.SHIFT_MASK
try:
is_alt = modifiers & Gdk.ModifierType.ALT_MASK
except:
is_alt = modifiers & Gdk.ModifierType.MOD1_MASK
is_control, \
is_shift, \
is_alt = self.get_modkeys_states(eve)
self.state = NoKeyState
if is_control:
@@ -144,11 +139,23 @@ class KeyMapper:
modifiers = Gdk.ModifierType(eve.get_state() & ~Gdk.ModifierType.LOCK_MASK)
return modifiers & Gdk.ModifierType.SHIFT_MASK
def get_raw_keyname(self, eve):
def get_raw_keyname(self, eve) -> str:
return Gdk.keyval_name(eve.keyval)
def get_keyname(self, eve):
def get_modkeys_states(self, eve) -> tuple:
modifiers = Gdk.ModifierType(eve.get_state() & ~Gdk.ModifierType.LOCK_MASK)
is_control = modifiers & Gdk.ModifierType.CONTROL_MASK
is_shift = modifiers & Gdk.ModifierType.SHIFT_MASK
try:
is_alt = modifiers & Gdk.ModifierType.ALT_MASK
except:
is_alt = modifiers & Gdk.ModifierType.MOD1_MASK
return is_control, is_shift, is_alt
def get_keyname(self, eve) -> str:
return Gdk.keyval_name(eve.keyval).lower()
def get_char(self, eve):
def get_char(self, eve) -> str:
return chr( Gdk.keyval_to_unicode(eve.keyval) )