Skip to content

Commit 72504f1

Browse files
authored
Add paste summarization to Codex TUI (#1549)
## Summary - introduce `Paste` event to avoid per-character paste handling - collapse large pasted blocks to `[Pasted Content X lines]` - store the real text so submission still includes it - wire paste handling through `App`, `ChatWidget`, `BottomPane`, and `ChatComposer` ## Testing - `cargo test -p codex-tui` ------ https://chatgpt.com/codex/tasks/task_i_6871e24abf80832184d1f3ca0c61a5ee https://github.com/user-attachments/assets/eda7412f-da30-4474-9f7c-96b49d48fbf8
1 parent fa6d507 commit 72504f1

12 files changed

+542
-16
lines changed

codex-rs/Cargo.lock

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

codex-rs/tui/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,5 @@ unicode-segmentation = "1.12.0"
6161
uuid = "1"
6262

6363
[dev-dependencies]
64+
insta = "1.43.1"
6465
pretty_assertions = "1"

codex-rs/tui/src/app.rs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -98,21 +98,7 @@ impl<'a> App<'a> {
9898
scroll_event_helper.scroll_down();
9999
}
100100
crossterm::event::Event::Paste(pasted) => {
101-
use crossterm::event::KeyModifiers;
102-
103-
for ch in pasted.chars() {
104-
let key_event = match ch {
105-
'\n' | '\r' => {
106-
// Represent newline as <Shift+Enter> so that the bottom
107-
// pane treats it as a literal newline instead of a submit
108-
// action (submission is only triggered on Enter *without*
109-
// any modifiers).
110-
KeyEvent::new(KeyCode::Enter, KeyModifiers::SHIFT)
111-
}
112-
_ => KeyEvent::new(KeyCode::Char(ch), KeyModifiers::empty()),
113-
};
114-
app_event_tx.send(AppEvent::KeyEvent(key_event));
115-
}
101+
app_event_tx.send(AppEvent::Paste(pasted));
116102
}
117103
_ => {
118104
// Ignore any other events.
@@ -223,6 +209,9 @@ impl<'a> App<'a> {
223209
AppEvent::Scroll(scroll_delta) => {
224210
self.dispatch_scroll_event(scroll_delta);
225211
}
212+
AppEvent::Paste(text) => {
213+
self.dispatch_paste_event(text);
214+
}
226215
AppEvent::CodexEvent(event) => {
227216
self.dispatch_codex_event(event);
228217
}
@@ -343,6 +332,13 @@ impl<'a> App<'a> {
343332
}
344333
}
345334

335+
fn dispatch_paste_event(&mut self, pasted: String) {
336+
match &mut self.app_state {
337+
AppState::Chat { widget } => widget.handle_paste(pasted),
338+
AppState::Login { .. } | AppState::GitWarning { .. } => {}
339+
}
340+
}
341+
346342
fn dispatch_scroll_event(&mut self, scroll_delta: i32) {
347343
match &mut self.app_state {
348344
AppState::Chat { widget } => widget.handle_scroll_delta(scroll_delta),

codex-rs/tui/src/app_event.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ pub(crate) enum AppEvent {
1212

1313
KeyEvent(KeyEvent),
1414

15+
/// Text pasted from the terminal clipboard.
16+
Paste(String),
17+
1518
/// Scroll event with a value representing the "scroll delta" as the net
1619
/// scroll up/down events within a short time window.
1720
Scroll(i32),

0 commit comments

Comments
 (0)