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):
|
def process_update(self):
|
||||||
self._ensure_state()
|
self._ensure_state()
|
||||||
state = self.env["commandBuffer"]["tabCompletion"]
|
state = self.env["commandBuffer"]["tabCompletion"]
|
||||||
|
if self._was_recently_processed(state):
|
||||||
|
return ""
|
||||||
|
|
||||||
pending = state.get("pending")
|
pending = state.get("pending")
|
||||||
if not pending:
|
if not pending:
|
||||||
pending = self._build_pending_from_recent_tab_update()
|
pending = self._build_pending_from_recent_tab_update()
|
||||||
@@ -62,6 +65,14 @@ class TabCompletionManager:
|
|||||||
state["lastProcessedTime"] = time.time()
|
state["lastProcessedTime"] = time.time()
|
||||||
return spoken_text
|
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):
|
def _build_pending_from_recent_tab_update(self):
|
||||||
if not self._recent_tab_input():
|
if not self._recent_tab_input():
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -4,5 +4,5 @@
|
|||||||
# Fenrir TTY screen reader
|
# Fenrir TTY screen reader
|
||||||
# By Chrys, Storm Dragon, and contributors.
|
# By Chrys, Storm Dragon, and contributors.
|
||||||
|
|
||||||
version = "2026.05.08"
|
version = "2026.05.09"
|
||||||
code_name = "testing"
|
code_name = "testing"
|
||||||
|
|||||||
@@ -81,6 +81,43 @@ def test_unique_completion_speaks_inserted_suffix():
|
|||||||
assert state["lastProcessedDelta"] == "cuments/"
|
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
|
@pytest.mark.unit
|
||||||
def test_candidate_list_speaks_visible_list_without_cursor_advance():
|
def test_candidate_list_speaks_visible_list_without_cursor_advance():
|
||||||
old_text = "\n".join(["$ cd Do".ljust(20), "".ljust(20), "".ljust(20)])
|
old_text = "\n".join(["$ cd Do".ljust(20), "".ljust(20), "".ljust(20)])
|
||||||
|
|||||||
Reference in New Issue
Block a user