Skip to content

Commit 7c26c8e

Browse files
tui: skip identical consecutive entries in local composer history (#2352)
This PR avoids inserting duplicate consecutive messages into the Chat Composer's local history.
1 parent eda50d8 commit 7c26c8e

File tree

1 file changed

+34
-4
lines changed

1 file changed

+34
-4
lines changed

codex-rs/tui/src/bottom_pane/chat_composer_history.rs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,18 @@ impl ChatComposerHistory {
5555
/// Record a message submitted by the user in the current session so it can
5656
/// be recalled later.
5757
pub fn record_local_submission(&mut self, text: &str) {
58-
if !text.is_empty() {
59-
self.local_history.push(text.to_string());
60-
self.history_cursor = None;
61-
self.last_history_text = None;
58+
if text.is_empty() {
59+
return;
60+
}
61+
62+
// Avoid inserting a duplicate if identical to the previous entry.
63+
if self.local_history.last().is_some_and(|prev| prev == text) {
64+
return;
6265
}
66+
67+
self.local_history.push(text.to_string());
68+
self.history_cursor = None;
69+
self.last_history_text = None;
6370
}
6471

6572
/// Should Up/Down key presses be interpreted as history navigation given
@@ -187,6 +194,29 @@ mod tests {
187194
use codex_core::protocol::Op;
188195
use std::sync::mpsc::channel;
189196

197+
#[test]
198+
fn duplicate_submissions_are_not_recorded() {
199+
let mut history = ChatComposerHistory::new();
200+
201+
// Empty submissions are ignored.
202+
history.record_local_submission("");
203+
assert_eq!(history.local_history.len(), 0);
204+
205+
// First entry is recorded.
206+
history.record_local_submission("hello");
207+
assert_eq!(history.local_history.len(), 1);
208+
assert_eq!(history.local_history.last().unwrap(), "hello");
209+
210+
// Identical consecutive entry is skipped.
211+
history.record_local_submission("hello");
212+
assert_eq!(history.local_history.len(), 1);
213+
214+
// Different entry is recorded.
215+
history.record_local_submission("world");
216+
assert_eq!(history.local_history.len(), 2);
217+
assert_eq!(history.local_history.last().unwrap(), "world");
218+
}
219+
190220
#[test]
191221
fn navigation_with_async_fetch() {
192222
let (tx, rx) = channel::<AppEvent>();

0 commit comments

Comments
 (0)