mirror of
https://github.com/openai/codex.git
synced 2026-10-18 17:18:52 +00:00
Make URLs clickable in user verification prompts (#51458)
## What changed Render user verification titles and request details with `HyperlinkText` so URLs carry terminal hyperlinks, including in the waiting-for-verification view. ## Testing Extend the narrow-prompt regression test to verify that wrapped URLs retain their full hyperlink targets before and during verification. Strip OSC 8 annotations when comparing visible text in snapshots. GitOrigin-RevId: 9b2fba963c028eaa2b177220b0487364b44d04bb
This commit is contained in:
@@ -261,7 +261,9 @@ fn user_verification_options(keymap: &ApprovalKeymap) -> Vec<UserVerificationOpt
|
||||
|
||||
pub(crate) fn prompt_header(request: &UserVerificationRequest) -> Box<dyn Renderable> {
|
||||
let mut header = ColumnRenderable::new();
|
||||
header.push(Paragraph::new(request.title.clone().bold()).wrap(Wrap { trim: false }));
|
||||
header.push(crate::terminal_hyperlinks::HyperlinkText::new(vec![
|
||||
request.title.clone().bold().into(),
|
||||
]));
|
||||
header.push(Line::from(""));
|
||||
header.push(request_details(request));
|
||||
Box::new(header)
|
||||
@@ -281,7 +283,7 @@ fn request_details(request: &UserVerificationRequest) -> Box<dyn Renderable> {
|
||||
Line::from(""),
|
||||
Line::from(request.description.clone()),
|
||||
]);
|
||||
Box::new(Paragraph::new(lines).wrap(Wrap { trim: false }))
|
||||
Box::new(crate::terminal_hyperlinks::HyperlinkText::new(lines))
|
||||
}
|
||||
|
||||
fn waiting_view(request: &UserVerificationRequest, keymap: &ListKeymap) -> Box<dyn Renderable> {
|
||||
|
||||
@@ -11,7 +11,7 @@ fn render_view_lines(view: &UserVerificationView, width: u16, height: u16) -> St
|
||||
(0..buf.area.height)
|
||||
.map(|row| {
|
||||
(0..buf.area.width)
|
||||
.map(|col| buf[(col, row)].symbol().to_string())
|
||||
.map(|col| crate::terminal_hyperlinks::strip_osc8(buf[(col, row)].symbol()))
|
||||
.collect::<String>()
|
||||
.trim_end()
|
||||
.to_string()
|
||||
@@ -157,7 +157,7 @@ fn full_screen_request_is_available_before_and_during_verification() {
|
||||
|
||||
#[test]
|
||||
fn long_url_tokens_remain_visible_in_a_narrow_verification_prompt() {
|
||||
let (view, _) = make_view_for_request(UserVerificationRequest {
|
||||
let (mut view, _) = make_view_for_request(UserVerificationRequest {
|
||||
title: "Approve https://example.com/production/release/candidate?".to_string(),
|
||||
description: "Deploy https://example.com/production/critical-release-candidate".to_string(),
|
||||
thread_label: None,
|
||||
@@ -168,6 +168,38 @@ fn long_url_tokens_remain_visible_in_a_narrow_verification_prompt() {
|
||||
"user_verification_long_urls",
|
||||
render_view_lines(&view, /*width*/ 30, view.desired_height(/*width*/ 30))
|
||||
);
|
||||
let urls = [
|
||||
"https://example.com/production/release/candidate?",
|
||||
"https://example.com/production/critical-release-candidate",
|
||||
];
|
||||
for waiting in [false, true] {
|
||||
if waiting {
|
||||
view.handle_key_event(KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE));
|
||||
}
|
||||
let area = Rect::new(0, 0, 30, view.desired_height(/*width*/ 30));
|
||||
let mut buf = Buffer::empty(area);
|
||||
view.render(area, &mut buf);
|
||||
let linked = buf
|
||||
.content
|
||||
.iter()
|
||||
.filter(|cell| cell.symbol().contains("\x1b]8;;"))
|
||||
.map(|cell| {
|
||||
assert!(
|
||||
urls.iter()
|
||||
.any(|url| cell.symbol().starts_with(&format!("\x1b]8;;{url}\x07")))
|
||||
);
|
||||
crate::terminal_hyperlinks::strip_osc8(cell.symbol())
|
||||
})
|
||||
.collect::<String>();
|
||||
assert_eq!(
|
||||
linked,
|
||||
if waiting {
|
||||
urls[1].to_owned()
|
||||
} else {
|
||||
urls.concat()
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
Reference in New Issue
Block a user