That does it, I'm breaking out codex on this one. Take that tab completion!

This commit is contained in:
Storm Dragon
2026-05-08 23:38:59 -04:00
parent 42ba3fdad2
commit 0af7d94014
3 changed files with 245 additions and 1 deletions
@@ -0,0 +1,93 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributors.
import time
from fenrirscreenreader.core.i18n import _
class command:
def __init__(self):
pass
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
def get_description(self):
return _("Announces large text insertions at the cursor")
def run(self):
if self.env["runtime"]["ScreenManager"].is_screen_change():
return
if not self.env["runtime"]["ScreenManager"].is_delta():
return
x_move = (
self.env["screen"]["new_cursor"]["x"]
- self.env["screen"]["old_cursor"]["x"]
)
if x_move < 5:
return
if self._is_recent_tab_input():
return
delta_text = self.env["screen"]["new_delta"]
if not self._matches_cursor_insert(x_move, delta_text):
return
curr_delta = delta_text
if (
len(curr_delta.strip()) != len(curr_delta)
and curr_delta.strip() != ""
):
curr_delta = curr_delta.strip()
if not curr_delta:
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(
curr_delta,
interrupt=do_interrupt,
announce_capital=True,
flush=False,
)
def _is_recent_tab_input(self):
input_manager = self.env["runtime"].get("InputManager")
if not input_manager:
return False
if input_manager.get_last_deepest_input() in [["KEY_TAB"]]:
return True
last_event = input_manager.get_last_event()
if not last_event or last_event.get("event_name") != "KEY_TAB":
return False
try:
return time.time() - input_manager.get_last_input_time() <= 0.5
except Exception:
return False
def _matches_cursor_insert(self, x_move, delta_text):
if not delta_text or "\n" in delta_text:
return False
delta_len = len(delta_text)
if x_move == delta_len:
return True
if abs(x_move - delta_len) <= 2:
return True
return delta_len > 10 and abs(x_move - delta_len) <= (delta_len * 0.2)
def set_callback(self, callback):
pass
@@ -41,7 +41,9 @@ class TabCompletionManager:
state = self.env["commandBuffer"]["tabCompletion"]
pending = state.get("pending")
if not pending:
return ""
pending = self._build_pending_from_recent_tab_update()
if not pending:
return ""
if time.time() - pending["timestamp"] > self.timeout:
state["pending"] = None
@@ -60,6 +62,33 @@ class TabCompletionManager:
state["lastProcessedTime"] = time.time()
return spoken_text
def _build_pending_from_recent_tab_update(self):
if not self._recent_tab_input():
return None
return {
"timestamp": time.time(),
"cursor": self.env["screen"]["old_cursor"].copy(),
"content": self.env["screen"]["old_content_text"],
"screen": self.env["screen"]["newTTY"],
}
def _recent_tab_input(self):
input_manager = self.env["runtime"]["InputManager"]
if input_manager.get_last_deepest_input() in [["KEY_TAB"]]:
return True
last_event = input_manager.get_last_event()
if not last_event or last_event.get("event_name") != "KEY_TAB":
return False
try:
return (
time.time() - input_manager.get_last_input_time()
<= self.timeout
)
except Exception:
return False
def _last_event_is_tab_press(self):
input_manager = self.env["runtime"]["InputManager"]
last_event = input_manager.get_last_event()