Hopefully final touches on the new tab completion.
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributors.
|
||||
|
||||
from fenrirscreenreader.core.i18n import _
|
||||
from fenrirscreenreader.core.tabCompletionManager import TabCompletionManager
|
||||
|
||||
|
||||
class command:
|
||||
def __init__(self):
|
||||
self.manager = TabCompletionManager()
|
||||
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.manager.initialize(environment)
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def get_description(self):
|
||||
return _("Announces tab completions on cursor movement")
|
||||
|
||||
def run(self):
|
||||
text = self.manager.process_update()
|
||||
if not text:
|
||||
return
|
||||
|
||||
do_interrupt = True
|
||||
if self.env["runtime"]["SettingsManager"].get_setting_as_bool(
|
||||
"speech", "auto_read_incoming"
|
||||
):
|
||||
do_interrupt = False
|
||||
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
text,
|
||||
interrupt=do_interrupt,
|
||||
announce_capital=True,
|
||||
flush=False,
|
||||
)
|
||||
|
||||
def set_callback(self, callback):
|
||||
pass
|
||||
@@ -39,6 +39,9 @@ class TabCompletionManager:
|
||||
def process_update(self):
|
||||
self._ensure_state()
|
||||
state = self.env["commandBuffer"]["tabCompletion"]
|
||||
if self._was_recently_processed(state):
|
||||
return ""
|
||||
|
||||
pending = state.get("pending")
|
||||
if not pending:
|
||||
pending = self._build_pending_from_recent_tab_update()
|
||||
@@ -62,6 +65,14 @@ class TabCompletionManager:
|
||||
state["lastProcessedTime"] = time.time()
|
||||
return spoken_text
|
||||
|
||||
def _was_recently_processed(self, state):
|
||||
if state.get("lastProcessedDelta") != self.env["screen"]["new_delta"]:
|
||||
return False
|
||||
last_time = state.get("lastProcessedTime")
|
||||
if not last_time:
|
||||
return False
|
||||
return time.time() - last_time <= self.timeout
|
||||
|
||||
def _build_pending_from_recent_tab_update(self):
|
||||
if not self._recent_tab_input():
|
||||
return None
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributors.
|
||||
|
||||
version = "2026.05.08"
|
||||
version = "2026.05.09"
|
||||
code_name = "testing"
|
||||
|
||||
@@ -81,6 +81,43 @@ def test_unique_completion_speaks_inserted_suffix():
|
||||
assert state["lastProcessedDelta"] == "cuments/"
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_small_completion_speaks_inserted_suffix():
|
||||
manager, env, _input_manager = _build_env(
|
||||
"cd gi".ljust(20), {"x": 5, "y": 0}
|
||||
)
|
||||
|
||||
manager.capture_if_tab()
|
||||
_set_screen_update(
|
||||
env,
|
||||
"cd git/".ljust(20),
|
||||
{"x": 7, "y": 0},
|
||||
delta="t/",
|
||||
typing=True,
|
||||
)
|
||||
|
||||
assert manager.process_update() == "t/"
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_completion_processed_once_for_cursor_and_screen_update():
|
||||
manager, env, _input_manager = _build_env(
|
||||
"cd gi".ljust(20), {"x": 5, "y": 0}
|
||||
)
|
||||
|
||||
manager.capture_if_tab()
|
||||
_set_screen_update(
|
||||
env,
|
||||
"cd git/".ljust(20),
|
||||
{"x": 7, "y": 0},
|
||||
delta="t/",
|
||||
typing=True,
|
||||
)
|
||||
|
||||
assert manager.process_update() == "t/"
|
||||
assert manager.process_update() == ""
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_candidate_list_speaks_visible_list_without_cursor_advance():
|
||||
old_text = "\n".join(["$ cd Do".ljust(20), "".ljust(20), "".ljust(20)])
|
||||
|
||||
Reference in New Issue
Block a user