fix(cli): strengthen paste collapse fallback for terminals without bracketed paste (#3625)
The _on_text_changed fallback only detected pastes when all characters arrived in a single event (chars_added > 1). Some terminals (notably VSCode integrated terminal in certain configs) may deliver paste data differently, causing the fallback to miss. Add a second heuristic: if the newline count jumps by 4+ in a single text-change event, treat it as a paste. Alt+Enter only adds 1 newline per event, so this never false-positives on manual multi-line input. Also fixes: the fallback path was missing _paste_just_collapsed flag set before replacing buffer text, which could cause a re-trigger loop.
This commit is contained in:
19
cli.py
19
cli.py
@@ -6656,6 +6656,7 @@ class HermesCLI:
|
||||
# Paste collapsing: detect large pastes and save to temp file
|
||||
_paste_counter = [0]
|
||||
_prev_text_len = [0]
|
||||
_prev_newline_count = [0]
|
||||
_paste_just_collapsed = [False]
|
||||
|
||||
def _on_text_changed(buf):
|
||||
@@ -6664,18 +6665,27 @@ class HermesCLI:
|
||||
When bracketed paste is available, handle_paste collapses
|
||||
large pastes directly. This handler is a fallback for
|
||||
terminals without bracketed paste support.
|
||||
|
||||
Two heuristics (either triggers collapse):
|
||||
1. Many characters added at once (chars_added > 1) — works
|
||||
when the terminal delivers the paste in one event-loop tick.
|
||||
2. Newline count jumped by 4+ in a single text-change event —
|
||||
catches terminals that feed characters individually but
|
||||
still batch newlines. Alt+Enter only adds 1 newline per
|
||||
event so it never triggers this.
|
||||
"""
|
||||
text = buf.text
|
||||
chars_added = len(text) - _prev_text_len[0]
|
||||
_prev_text_len[0] = len(text)
|
||||
if _paste_just_collapsed[0]:
|
||||
_paste_just_collapsed[0] = False
|
||||
_prev_newline_count[0] = text.count('\n')
|
||||
return
|
||||
line_count = text.count('\n')
|
||||
# Heuristic: a real paste adds many characters at once (not just a
|
||||
# single newline from Alt+Enter) AND the result has 5+ lines.
|
||||
# Fallback for terminals without bracketed paste support.
|
||||
if line_count >= 5 and chars_added > 1 and not text.startswith('/'):
|
||||
newlines_added = line_count - _prev_newline_count[0]
|
||||
_prev_newline_count[0] = line_count
|
||||
is_paste = chars_added > 1 or newlines_added >= 4
|
||||
if line_count >= 5 and is_paste and not text.startswith('/'):
|
||||
_paste_counter[0] += 1
|
||||
# Save to temp file
|
||||
paste_dir = _hermes_home / "pastes"
|
||||
@@ -6683,6 +6693,7 @@ class HermesCLI:
|
||||
paste_file = paste_dir / f"paste_{_paste_counter[0]}_{datetime.now().strftime('%H%M%S')}.txt"
|
||||
paste_file.write_text(text, encoding="utf-8")
|
||||
# Replace buffer with compact reference
|
||||
_paste_just_collapsed[0] = True
|
||||
buf.text = f"[Pasted text #{_paste_counter[0]}: {line_count + 1} lines \u2192 {paste_file}]"
|
||||
buf.cursor_position = len(buf.text)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user