Found a vmenu bug in -x. I thought we were close to a new release...
This commit is contained in:
@@ -311,7 +311,10 @@ class FenrirManager:
|
|||||||
self.singleKeyCommand = True
|
self.singleKeyCommand = True
|
||||||
elif (
|
elif (
|
||||||
(
|
(
|
||||||
self.environment["runtime"]["DiffReviewManager"].is_active()
|
self.environment["runtime"]["VmenuManager"].get_active()
|
||||||
|
or self.environment["runtime"][
|
||||||
|
"DiffReviewManager"
|
||||||
|
].is_active()
|
||||||
or self.environment["runtime"][
|
or self.environment["runtime"][
|
||||||
"SpeechHistoryManager"
|
"SpeechHistoryManager"
|
||||||
].is_active()
|
].is_active()
|
||||||
|
|||||||
@@ -333,10 +333,73 @@ class driver(screenDriver):
|
|||||||
def handle_stdin_input(self, msg_bytes, event_queue):
|
def handle_stdin_input(self, msg_bytes, event_queue):
|
||||||
if self.synthesize_backspace_shortcut(msg_bytes, event_queue):
|
if self.synthesize_backspace_shortcut(msg_bytes, event_queue):
|
||||||
return
|
return
|
||||||
|
if self.handle_vmenu_stdin_input(msg_bytes, event_queue):
|
||||||
|
return
|
||||||
self.record_stdin_keypress(msg_bytes)
|
self.record_stdin_keypress(msg_bytes)
|
||||||
self.interrupt_output_on_stdin_input(msg_bytes)
|
self.interrupt_output_on_stdin_input(msg_bytes)
|
||||||
self.inject_text_to_screen(msg_bytes)
|
self.inject_text_to_screen(msg_bytes)
|
||||||
|
|
||||||
|
def handle_vmenu_stdin_input(self, msg_bytes, event_queue):
|
||||||
|
if not self.is_vmenu_active():
|
||||||
|
return False
|
||||||
|
key_name = self.vmenu_stdin_key_name(msg_bytes)
|
||||||
|
if key_name:
|
||||||
|
self.queue_keypress(key_name, event_queue)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def is_vmenu_active(self):
|
||||||
|
try:
|
||||||
|
return self.env["runtime"]["VmenuManager"].get_active()
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def vmenu_stdin_key_name(self, msg_bytes):
|
||||||
|
key_map = {
|
||||||
|
b"\x1b": "KEY_ESC",
|
||||||
|
b"\x1b[A": "KEY_UP",
|
||||||
|
b"\x1b[B": "KEY_DOWN",
|
||||||
|
b"\x1b[C": "KEY_RIGHT",
|
||||||
|
b"\x1b[D": "KEY_LEFT",
|
||||||
|
b"\x1b[5~": "KEY_PAGEUP",
|
||||||
|
b"\x1b[6~": "KEY_PAGEDOWN",
|
||||||
|
b"\r": "KEY_ENTER",
|
||||||
|
b"\n": "KEY_ENTER",
|
||||||
|
b" ": "KEY_SPACE",
|
||||||
|
}
|
||||||
|
if msg_bytes in key_map:
|
||||||
|
return key_map[msg_bytes]
|
||||||
|
if len(msg_bytes) != 1:
|
||||||
|
return None
|
||||||
|
char = chr(msg_bytes[0])
|
||||||
|
if "a" <= char <= "z" or "A" <= char <= "Z":
|
||||||
|
return "KEY_" + char.upper()
|
||||||
|
return None
|
||||||
|
|
||||||
|
def queue_keypress(self, key_name, event_queue):
|
||||||
|
event_time = time.time()
|
||||||
|
for event_state in [1, 0]:
|
||||||
|
try:
|
||||||
|
event_queue.put(
|
||||||
|
{
|
||||||
|
"Type": FenrirEventType.keyboard_input,
|
||||||
|
"data": {
|
||||||
|
"event_name": key_name,
|
||||||
|
"event_value": 0,
|
||||||
|
"event_sec": int(event_time),
|
||||||
|
"event_usec": int((event_time % 1) * 1000000),
|
||||||
|
"event_state": event_state,
|
||||||
|
"event_type": 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
block=False,
|
||||||
|
)
|
||||||
|
except Full:
|
||||||
|
self.env["runtime"]["DebugManager"].write_debug_out(
|
||||||
|
"ptyDriver queue_keypress: Event queue full, dropping "
|
||||||
|
+ key_name,
|
||||||
|
debug.DebugLevel.WARNING,
|
||||||
|
)
|
||||||
|
|
||||||
def record_stdin_keypress(self, msg_bytes):
|
def record_stdin_keypress(self, msg_bytes):
|
||||||
if msg_bytes != b"\t":
|
if msg_bytes != b"\t":
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ def test_speech_history_plain_key_modal_command_is_dispatched():
|
|||||||
)
|
)
|
||||||
speech_history_manager = Mock(is_active=Mock(return_value=True))
|
speech_history_manager = Mock(is_active=Mock(return_value=True))
|
||||||
diff_review_manager = Mock(is_active=Mock(return_value=False))
|
diff_review_manager = Mock(is_active=Mock(return_value=False))
|
||||||
|
vmenu_manager = Mock(get_active=Mock(return_value=False))
|
||||||
|
|
||||||
manager.environment = {
|
manager.environment = {
|
||||||
"input": {
|
"input": {
|
||||||
@@ -32,6 +33,7 @@ def test_speech_history_plain_key_modal_command_is_dispatched():
|
|||||||
"runtime": {
|
"runtime": {
|
||||||
"InputManager": input_manager,
|
"InputManager": input_manager,
|
||||||
"EventManager": event_manager,
|
"EventManager": event_manager,
|
||||||
|
"VmenuManager": vmenu_manager,
|
||||||
"DiffReviewManager": diff_review_manager,
|
"DiffReviewManager": diff_review_manager,
|
||||||
"SpeechHistoryManager": speech_history_manager,
|
"SpeechHistoryManager": speech_history_manager,
|
||||||
},
|
},
|
||||||
@@ -42,3 +44,43 @@ def test_speech_history_plain_key_modal_command_is_dispatched():
|
|||||||
event_manager.put_to_event_queue.assert_called_once_with(
|
event_manager.put_to_event_queue.assert_called_once_with(
|
||||||
FenrirEventType.execute_command, "SPEECH_HISTORY_PREV"
|
FenrirEventType.execute_command, "SPEECH_HISTORY_PREV"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
def test_vmenu_plain_key_modal_command_is_dispatched():
|
||||||
|
manager = FenrirManager.__new__(FenrirManager)
|
||||||
|
manager.modifierInput = False
|
||||||
|
manager.singleKeyCommand = False
|
||||||
|
manager.command = ""
|
||||||
|
|
||||||
|
event_manager = Mock(put_to_event_queue=Mock())
|
||||||
|
input_manager = Mock(
|
||||||
|
is_key_press=Mock(return_value=False),
|
||||||
|
no_key_pressed=Mock(return_value=False),
|
||||||
|
get_curr_shortcut=Mock(return_value=str([1, ["KEY_UP"]])),
|
||||||
|
get_command_for_shortcut=Mock(return_value="PREV_VMENU_ENTRY"),
|
||||||
|
)
|
||||||
|
vmenu_manager = Mock(get_active=Mock(return_value=True))
|
||||||
|
speech_history_manager = Mock(is_active=Mock(return_value=False))
|
||||||
|
diff_review_manager = Mock(is_active=Mock(return_value=False))
|
||||||
|
|
||||||
|
manager.environment = {
|
||||||
|
"input": {
|
||||||
|
"key_forward": 0,
|
||||||
|
"prev_input": ["KEY_UP"],
|
||||||
|
"curr_input": ["KEY_UP"],
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"InputManager": input_manager,
|
||||||
|
"EventManager": event_manager,
|
||||||
|
"VmenuManager": vmenu_manager,
|
||||||
|
"DiffReviewManager": diff_review_manager,
|
||||||
|
"SpeechHistoryManager": speech_history_manager,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
manager.detect_shortcut_command()
|
||||||
|
|
||||||
|
event_manager.put_to_event_queue.assert_called_once_with(
|
||||||
|
FenrirEventType.execute_command, "PREV_VMENU_ENTRY"
|
||||||
|
)
|
||||||
|
|||||||
@@ -160,6 +160,72 @@ def test_pty_plain_stdin_does_not_record_tab_keypress():
|
|||||||
pty_driver.inject_text_to_screen.assert_called_once_with(b"a")
|
pty_driver.inject_text_to_screen.assert_called_once_with(b"a")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("sequence", "key_name"),
|
||||||
|
[
|
||||||
|
(b"\x1b[A", "KEY_UP"),
|
||||||
|
(b"\x1b[B", "KEY_DOWN"),
|
||||||
|
(b"\x1b[C", "KEY_RIGHT"),
|
||||||
|
(b"\x1b[D", "KEY_LEFT"),
|
||||||
|
(b"\x1b[5~", "KEY_PAGEUP"),
|
||||||
|
(b"\x1b[6~", "KEY_PAGEDOWN"),
|
||||||
|
(b"\x1b", "KEY_ESC"),
|
||||||
|
(b"\r", "KEY_ENTER"),
|
||||||
|
(b" ", "KEY_SPACE"),
|
||||||
|
(b"a", "KEY_A"),
|
||||||
|
(b"Z", "KEY_Z"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_pty_vmenu_stdin_is_consumed_and_synthesizes_key_events(
|
||||||
|
sequence,
|
||||||
|
key_name,
|
||||||
|
):
|
||||||
|
pty_driver = PtyDriver()
|
||||||
|
event_queue = Mock()
|
||||||
|
settings_manager = Mock()
|
||||||
|
settings_manager.get_setting_as_bool.return_value = False
|
||||||
|
pty_driver.env = {
|
||||||
|
"input": {"curr_input": []},
|
||||||
|
"runtime": {
|
||||||
|
"DebugManager": Mock(write_debug_out=Mock()),
|
||||||
|
"SettingsManager": settings_manager,
|
||||||
|
"VmenuManager": Mock(get_active=Mock(return_value=True)),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
pty_driver.inject_text_to_screen = Mock()
|
||||||
|
|
||||||
|
pty_driver.handle_stdin_input(sequence, event_queue)
|
||||||
|
|
||||||
|
pty_driver.inject_text_to_screen.assert_not_called()
|
||||||
|
assert event_queue.put.call_count == 2
|
||||||
|
first_event = event_queue.put.call_args_list[0].args[0]
|
||||||
|
second_event = event_queue.put.call_args_list[1].args[0]
|
||||||
|
assert first_event["Type"] == FenrirEventType.keyboard_input
|
||||||
|
assert first_event["data"]["event_name"] == key_name
|
||||||
|
assert first_event["data"]["event_state"] == 1
|
||||||
|
assert second_event["data"]["event_name"] == key_name
|
||||||
|
assert second_event["data"]["event_state"] == 0
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
def test_pty_vmenu_unknown_stdin_is_consumed_without_injection():
|
||||||
|
pty_driver = PtyDriver()
|
||||||
|
event_queue = Mock()
|
||||||
|
pty_driver.env = {
|
||||||
|
"input": {"curr_input": []},
|
||||||
|
"runtime": {
|
||||||
|
"VmenuManager": Mock(get_active=Mock(return_value=True)),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
pty_driver.inject_text_to_screen = Mock()
|
||||||
|
|
||||||
|
pty_driver.handle_stdin_input(b"\x1b[1;5A", event_queue)
|
||||||
|
|
||||||
|
pty_driver.inject_text_to_screen.assert_not_called()
|
||||||
|
event_queue.put.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.unit
|
@pytest.mark.unit
|
||||||
def test_pty_stdin_input_honors_interrupt_disabled():
|
def test_pty_stdin_input_honors_interrupt_disabled():
|
||||||
pty_driver = PtyDriver()
|
pty_driver = PtyDriver()
|
||||||
|
|||||||
Reference in New Issue
Block a user