mirror of
https://github.com/openai/codex.git
synced 2026-11-05 20:10:33 +00:00
Normalize CRLF line endings in pasted text (#38704)
## Why Replacing every carriage return with a line feed turns each CRLF pair into two line breaks when text is pasted into the TUI composer. ## What changed Normalize CRLF pairs before converting remaining bare carriage returns, so each pasted line ending becomes a single line feed while existing line feeds remain unchanged. ## Testing Add a regression test covering mixed CRLF, bare CR, and LF line endings. GitOrigin-RevId: 86c66d2a52fae52c9ae58c2f24a49eed685b60be
This commit is contained in:
committed by
copyberry
parent
e5470f1bce
commit
3685a61dad
@@ -780,11 +780,12 @@ impl App {
|
||||
self.handle_key_event(tui, app_server, key_event).await;
|
||||
}
|
||||
TuiEvent::Paste(pasted) => {
|
||||
// Many terminals convert newlines to \r when pasting (e.g., iTerm2),
|
||||
// but tui-textarea expects \n. Normalize CR to LF.
|
||||
// Pasted text may contain CRLF pairs or bare CRs (e.g., from iTerm2),
|
||||
// but tui-textarea expects LF. Normalize CRLF pairs before bare CRs so
|
||||
// each pasted line break becomes one LF and existing LFs stay unchanged.
|
||||
// [tui-textarea]: https://github.com/rhysd/tui-textarea/blob/4d18622eeac13b309e0ff6a55a46ac6706da68cf/src/textarea.rs#L782-L783
|
||||
// [iTerm2]: https://github.com/gnachman/iTerm2/blob/5d0c0d9f68523cbd0494dad5422998964a2ecd8d/sources/iTermPasteHelper.m#L206-L216
|
||||
let pasted = pasted.replace("\r", "\n");
|
||||
let pasted = pasted.replace("\r\n", "\n").replace('\r', "\n");
|
||||
self.chat_widget.handle_paste(pasted);
|
||||
}
|
||||
TuiEvent::Draw | TuiEvent::Resume | TuiEvent::Resize(_) => {
|
||||
|
||||
@@ -153,6 +153,29 @@ fn test_absolute_path(path: &str) -> AbsolutePathBuf {
|
||||
AbsolutePathBuf::try_from(PathBuf::from(path)).expect("absolute test path")
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn pasted_text_normalizes_mixed_line_endings_at_app_boundary() -> Result<()> {
|
||||
let mut app = make_test_app().await;
|
||||
let mut app_server = start_config_write_test_app_server(&app).await?;
|
||||
let mut tui = crate::tui::test_support::make_test_tui()?;
|
||||
|
||||
app.handle_tui_event(
|
||||
&mut tui,
|
||||
&mut app_server,
|
||||
TuiEvent::Paste("line1\r\nline2\rline3\nline4".to_string()),
|
||||
)
|
||||
.await?;
|
||||
|
||||
assert_snapshot!(app.chat_widget.composer_text_with_pending(), @r"
|
||||
line1
|
||||
line2
|
||||
line3
|
||||
line4
|
||||
");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn chat_widget_frame_reuses_active_cell_height_across_frame_passes() {
|
||||
#[derive(Debug)]
|
||||
|
||||
Reference in New Issue
Block a user