That does it, I'm breaking out codex on this one. Take that tab completion!
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user