Proposal: host hooks for paste interception + timing-based paste-burst detection (Warp/ConPTY)
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 818
- Forks
- 249
- Avg merge
- 4d 14h
- Merged PRs (30d)
- 30
Description
Summary
Two small, optional host hooks that let an application customize how reedline handles pastes. Both are no-ops when not installed, so existing users see zero behavior change. We've been running an implementation of both in a downstream fork and would be glad to upstream them if there's interest — opening this to gauge appetite and design preferences before sending a PR.
1. Paste interception hook
Today a bare Ctrl+V (EditCommand::PasteSystem, system_clipboard feature) reads the OS clipboard and inserts the text verbatim. Some hosts want to intervene — for example, turn a large paste (or an image) into a compact reference token like [Pasted text #N, +M lines] while stashing the real content elsewhere, then expand it back on submit. This keeps a chat-style / REPL composer readable, which is a common pattern in modern terminal CLIs.
Proposed shape: Reedline::with_paste_interceptor(Arc<dyn PasteInterceptor>). On PasteSystem, if an interceptor is installed, reedline calls interceptor.on_paste() -> PasteAction (InsertText(String) or Noop) instead of the default clipboard-read-and-insert. The interceptor reads the clipboard itself, so it can access image bytes the text-only path never exposes. An optional expand_for_display(&buffer) -> Option<String> lets the host expand placeholders for the submitted-line render.
2. Timing-based paste-burst detection (fallback for terminals without bracketed paste)
use_bracketed_paste handles terminals that emit Event::Paste. But some terminals — notably Warp and Windows ConPTY (crossterm#737) — deliver a paste as a rapid stream of individual key events, indistinguishable from fast typing by content alone. Without arrival timing, the read loop can't tell a paste-embedded newline from a settling Enter, so multi-line pastes submit prematurely.
Proposed shape: Reedline::with_paste_burst(Arc<dyn PasteBurstHook>). Chars keep echoing live (no added latency); the read loop feeds each just-read char to hook.on_char(c) at read time (preserving real inter-char timing), keeps draining while hook.is_burst_active() (using hook.poll_timeout() as the idle-flush window), and reclassifies a bare Enter to an inserted newline when hook.enter_is_newline(). All detector state and thresholds live host-side; reedline only drives the hook from the read loop.
Notes
- Both traits are deliberately host-agnostic (no app-specific concepts).
- Both are opt-in and no-op when absent (
Send + Sync, held behind anArc). - #1 is small and self-contained. #2 touches the read loop more deeply — happy to discuss whether a host timing hook is the right layer, or whether this is better addressed at the crossterm level (upstream #737).
References
- Paste-reference UX (found in several chat-style terminal CLIs): a large paste collapses to a
[Pasted text #N]placeholder in the composer and expands to the full text on submit. - crossterm#737 —
Event::Pasteis not emitted on Windows / ConPTY, so bracketed-paste-based detection does not fire there. - Warp terminal delivers pastes as individual key events rather than a bracketed-paste sequence.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the PasteSystem handling and the read loop described in the issue, including the existing use_bracketed_paste path. Review how Reedline currently reads clipboard content and processes individual characters, then clarify the API and behavior for both opt-in hooks. Done should include agreed host hooks that remain no-ops when absent, with coverage for interception and paste-burst behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100