Hopefully make pty more similar to tested console behavior.
This commit is contained in:
@@ -356,32 +356,37 @@ class ScreenManager:
|
||||
# Not typing - handle as line-by-line content change
|
||||
# This catches: incoming messages, screen updates,
|
||||
# application output, etc.
|
||||
appended_text = self._get_recent_cursor_line_append()
|
||||
if appended_text is not None:
|
||||
diff_list = ["+ " + appended_text]
|
||||
typing = True
|
||||
else:
|
||||
|
||||
# Pre-process screen text for comparison - collapse multiple spaces to single space
|
||||
# This normalization prevents spurious diffs from spacing
|
||||
# inconsistencies
|
||||
old_screen_text = self._space_normalize_regex.sub(
|
||||
" ",
|
||||
self.env["runtime"][
|
||||
"ScreenManager"
|
||||
].get_window_area_in_text(
|
||||
self.env["screen"]["old_content_text"]
|
||||
),
|
||||
)
|
||||
new_screen_text = self._space_normalize_regex.sub(
|
||||
" ",
|
||||
self.env["runtime"][
|
||||
"ScreenManager"
|
||||
].get_window_area_in_text(
|
||||
self.env["screen"]["new_content_text"]
|
||||
),
|
||||
)
|
||||
# Pre-process screen text for comparison - collapse multiple spaces to single space
|
||||
# This normalization prevents spurious diffs from spacing
|
||||
# inconsistencies
|
||||
old_screen_text = self._space_normalize_regex.sub(
|
||||
" ",
|
||||
self.env["runtime"][
|
||||
"ScreenManager"
|
||||
].get_window_area_in_text(
|
||||
self.env["screen"]["old_content_text"]
|
||||
),
|
||||
)
|
||||
new_screen_text = self._space_normalize_regex.sub(
|
||||
" ",
|
||||
self.env["runtime"][
|
||||
"ScreenManager"
|
||||
].get_window_area_in_text(
|
||||
self.env["screen"]["new_content_text"]
|
||||
),
|
||||
)
|
||||
|
||||
diff = self.differ.compare(
|
||||
old_screen_text.split("\n"),
|
||||
new_screen_text.split("\n"),
|
||||
)
|
||||
diff_list = list(diff)
|
||||
diff = self.differ.compare(
|
||||
old_screen_text.split("\n"),
|
||||
new_screen_text.split("\n"),
|
||||
)
|
||||
diff_list = list(diff)
|
||||
|
||||
# Extract added and removed content from diff results
|
||||
# Output format depends on whether this was detected as typing
|
||||
@@ -453,6 +458,44 @@ class ScreenManager:
|
||||
)
|
||||
return screen in ignore_screens
|
||||
|
||||
def _get_recent_cursor_line_append(self):
|
||||
try:
|
||||
if time.time() - self.env["runtime"][
|
||||
"InputManager"
|
||||
].get_last_input_time() > 0.3:
|
||||
return None
|
||||
|
||||
old_lines = self.env["screen"]["old_content_text"].split("\n")
|
||||
new_lines = self.env["screen"]["new_content_text"].split("\n")
|
||||
cursor_y = self.env["screen"]["new_cursor"]["y"]
|
||||
if (
|
||||
len(old_lines) != len(new_lines)
|
||||
or cursor_y < 0
|
||||
or cursor_y >= len(new_lines)
|
||||
):
|
||||
return None
|
||||
|
||||
changed_lines = [
|
||||
index
|
||||
for index, old_line in enumerate(old_lines)
|
||||
if index >= len(new_lines) or old_line != new_lines[index]
|
||||
]
|
||||
if changed_lines != [cursor_y]:
|
||||
return None
|
||||
|
||||
old_line = old_lines[cursor_y]
|
||||
new_line = new_lines[cursor_y]
|
||||
old_line = old_line.rstrip()
|
||||
if not new_line.startswith(old_line):
|
||||
return None
|
||||
|
||||
appended_text = new_line[len(old_line):].strip()
|
||||
if appended_text == "" or len(appended_text) > 4:
|
||||
return None
|
||||
return appended_text
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def is_screen_change(self):
|
||||
if not self.env["screen"]["oldTTY"]:
|
||||
return False
|
||||
|
||||
@@ -88,8 +88,8 @@ class TestIncomingCommand:
|
||||
[
|
||||
"Status old",
|
||||
"Users old",
|
||||
"alice: hi",
|
||||
"bob: hello",
|
||||
"UserA: hi",
|
||||
"UserB: hello",
|
||||
"> ",
|
||||
]
|
||||
)
|
||||
@@ -97,19 +97,19 @@ class TestIncomingCommand:
|
||||
[
|
||||
"Status new",
|
||||
"Users new",
|
||||
"bob: hello",
|
||||
"carol: test",
|
||||
"UserB: hello",
|
||||
"UserC: test",
|
||||
"> ",
|
||||
]
|
||||
)
|
||||
env["screen"]["new_delta"] = "\n".join(
|
||||
["Status new", "Users new", "carol: test"]
|
||||
["Status new", "Users new", "UserC: test"]
|
||||
)
|
||||
|
||||
command.run()
|
||||
|
||||
output_manager.present_text.assert_called_once_with(
|
||||
"carol: test", interrupt=False, flush=False
|
||||
"UserC: test", interrupt=False, flush=False
|
||||
)
|
||||
|
||||
def test_keeps_header_update_when_no_lower_screen_insert_exists(
|
||||
@@ -120,16 +120,16 @@ class TestIncomingCommand:
|
||||
[
|
||||
"Status old",
|
||||
"Users old",
|
||||
"alice: hi",
|
||||
"bob: hello",
|
||||
"UserA: hi",
|
||||
"UserB: hello",
|
||||
]
|
||||
)
|
||||
env["screen"]["new_content_text"] = "\n".join(
|
||||
[
|
||||
"Status new",
|
||||
"Users new",
|
||||
"alice: hi",
|
||||
"bob: hello",
|
||||
"UserA: hi",
|
||||
"UserB: hello",
|
||||
]
|
||||
)
|
||||
env["screen"]["new_delta"] = "\n".join(["Status new", "Users new"])
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import time
|
||||
from unittest.mock import Mock
|
||||
|
||||
import pytest
|
||||
@@ -18,6 +19,7 @@ def _build_screen_manager(old_text, old_cursor):
|
||||
),
|
||||
"CursorManager": Mock(is_application_window_set=Mock(return_value=False)),
|
||||
"DebugManager": Mock(write_debug_out=Mock()),
|
||||
"InputManager": Mock(get_last_input_time=Mock(return_value=0)),
|
||||
"ScreenManager": manager,
|
||||
"SettingsManager": Mock(get_setting_as_bool=Mock(return_value=False)),
|
||||
},
|
||||
@@ -61,3 +63,38 @@ def test_prompt_repaint_during_typing_keeps_only_typed_delta():
|
||||
|
||||
assert env["screen"]["new_delta"] == "h"
|
||||
assert env["screen"]["new_delta_is_typing"] is True
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_tui_input_line_append_is_typing_delta():
|
||||
manager, env = _build_screen_manager(
|
||||
"\n".join(
|
||||
[
|
||||
"<UserA> hi".ljust(20),
|
||||
"[Username] ".ljust(20),
|
||||
]
|
||||
),
|
||||
{"x": 11, "y": 1},
|
||||
)
|
||||
env["runtime"]["InputManager"].get_last_input_time.return_value = time.time()
|
||||
|
||||
manager.update(
|
||||
{
|
||||
"bytes": b"",
|
||||
"lines": 2,
|
||||
"columns": 20,
|
||||
"textCursor": {"x": 12, "y": 1},
|
||||
"screen": "pty",
|
||||
"text": "\n".join(
|
||||
[
|
||||
"<UserA> hi".ljust(20),
|
||||
"[Username] l".ljust(20),
|
||||
]
|
||||
),
|
||||
"attributes": [],
|
||||
},
|
||||
"onScreenUpdate",
|
||||
)
|
||||
|
||||
assert env["screen"]["new_delta"] == "l"
|
||||
assert env["screen"]["new_delta_is_typing"] is True
|
||||
|
||||
Reference in New Issue
Block a user