Compare commits

...

5 Commits

Author SHA1 Message Date
pap-openai
709104a56e Merge branch 'main' into fix/bang-prefixed-prompts-dont-replace-image-path 2026-01-15 20:23:27 +00:00
pap
a6794a1eaa tui2 2026-01-15 17:56:08 +00:00
pap
0de3de185a simplify 2026-01-15 17:51:40 +00:00
pap
ed5f688c87 better comment 2026-01-15 17:50:07 +00:00
pap
8bf607dc81 image path not replaced when prefixed by bang 2026-01-15 17:37:33 +00:00
2 changed files with 68 additions and 2 deletions

View File

@@ -351,7 +351,11 @@ impl ChatComposer {
let placeholder = self.next_large_paste_placeholder(char_count);
self.textarea.insert_element(&placeholder);
self.pending_pastes.push((placeholder, pasted));
} else if char_count > 1 && self.handle_paste_image_path(pasted.clone()) {
} else if char_count > 1
// Keep shell commands like `!open /path/to.png` intact (not replacing with [Image]) so they can be run in shell
&& !self.textarea.text().starts_with('!')
&& self.handle_paste_image_path(pasted.clone())
{
self.textarea.insert_str(" ");
} else {
self.textarea.insert_str(&pasted);
@@ -4132,6 +4136,35 @@ mod tests {
assert_eq!(imgs, vec![tmp_path]);
}
#[test]
fn pasting_filepath_with_shell_prefix_keeps_text() {
let tmp = tempdir().expect("create TempDir");
let tmp_path: PathBuf = tmp.path().join("codex_tui_test_paste_shell.png");
let img: ImageBuffer<Rgba<u8>, Vec<u8>> =
ImageBuffer::from_fn(3, 2, |_x, _y| Rgba([1, 2, 3, 255]));
img.save(&tmp_path).expect("failed to write temp png");
let (tx, _rx) = unbounded_channel::<AppEvent>();
let sender = AppEventSender::new(tx);
let mut composer = ChatComposer::new(
true,
sender,
false,
"Ask Codex to do anything".to_string(),
false,
);
composer.insert_str("!open ");
let pasted = tmp_path.to_string_lossy().to_string();
let needs_redraw = composer.handle_paste(pasted.clone());
assert!(needs_redraw);
assert!(composer.attached_images.is_empty());
assert_eq!(composer.textarea.text(), format!("!open {pasted}"));
let imgs = composer.take_recent_submission_images();
assert!(imgs.is_empty());
}
#[test]
fn selecting_custom_prompt_without_args_submits_content() {
let prompt_text = "Hello from saved prompt";

View File

@@ -362,7 +362,11 @@ impl ChatComposer {
let placeholder = self.next_large_paste_placeholder(char_count);
self.textarea.insert_element(&placeholder);
self.pending_pastes.push((placeholder, pasted));
} else if char_count > 1 && self.handle_paste_image_path(pasted.clone()) {
} else if char_count > 1
// Keep shell commands like `!open /path/to.png` intact (not replacing with [Image]) so they can be run in shell
&& !self.textarea.text().starts_with('!')
&& self.handle_paste_image_path(pasted.clone())
{
self.textarea.insert_str(" ");
} else {
self.textarea.insert_str(&pasted);
@@ -4092,6 +4096,35 @@ mod tests {
assert_eq!(imgs, vec![tmp_path]);
}
#[test]
fn pasting_filepath_with_shell_prefix_keeps_text() {
let tmp = tempdir().expect("create TempDir");
let tmp_path: PathBuf = tmp.path().join("codex_tui_test_paste_shell.png");
let img: ImageBuffer<Rgba<u8>, Vec<u8>> =
ImageBuffer::from_fn(3, 2, |_x, _y| Rgba([1, 2, 3, 255]));
img.save(&tmp_path).expect("failed to write temp png");
let (tx, _rx) = unbounded_channel::<AppEvent>();
let sender = AppEventSender::new(tx);
let mut composer = ChatComposer::new(
true,
sender,
false,
"Ask Codex to do anything".to_string(),
false,
);
composer.insert_str("!open ");
let pasted = tmp_path.to_string_lossy().to_string();
let needs_redraw = composer.handle_paste(pasted.clone());
assert!(needs_redraw);
assert!(composer.attached_images.is_empty());
assert_eq!(composer.textarea.text(), format!("!open {pasted}"));
let imgs = composer.take_recent_submission_images();
assert!(imgs.is_empty());
}
#[test]
fn selecting_custom_prompt_without_args_submits_content() {
let prompt_text = "Hello from saved prompt";