mirror of
https://github.com/openai/codex.git
synced 2026-02-08 18:03:37 +00:00
Compare commits
1 Commits
patch-squa
...
codex/make
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b69f2982a |
@@ -1,12 +1,14 @@
|
||||
---
|
||||
source: tui/src/chatwidget/tests.rs
|
||||
assertion_line: 728
|
||||
expression: terminal.backend()
|
||||
---
|
||||
" "
|
||||
"this is a test reason such as one that would be produced by the model "
|
||||
" "
|
||||
"▌Allow command? "
|
||||
"▌ Yes Always No, provide feedback "
|
||||
"▌> 1. Yes "
|
||||
"▌ 2. Always "
|
||||
"▌ 3. No, provide feedback "
|
||||
"▌ "
|
||||
"▌ Approve and run the command "
|
||||
" "
|
||||
|
||||
@@ -4,6 +4,9 @@ expression: terminal.backend()
|
||||
---
|
||||
" "
|
||||
"▌Allow command? "
|
||||
"▌ Yes Always No, provide feedback "
|
||||
"▌> 1. Yes "
|
||||
"▌ 2. Always "
|
||||
"▌ 3. No, provide feedback "
|
||||
"▌ "
|
||||
"▌ Approve and run the command "
|
||||
" "
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
source: tui/src/chatwidget/tests.rs
|
||||
assertion_line: 794
|
||||
expression: terminal.backend()
|
||||
---
|
||||
" "
|
||||
@@ -9,6 +8,8 @@ expression: terminal.backend()
|
||||
"This will grant write access to /tmp for the remainder of this session. "
|
||||
" "
|
||||
"▌Apply changes? "
|
||||
"▌ Yes No, provide feedback "
|
||||
"▌> 1. Yes "
|
||||
"▌ 2. No, provide feedback "
|
||||
"▌ "
|
||||
"▌ Approve and apply the changes "
|
||||
" "
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
---
|
||||
source: tui/src/chatwidget/tests.rs
|
||||
assertion_line: 921
|
||||
expression: terminal.backend()
|
||||
---
|
||||
" "
|
||||
"this is a test reason such as one that would be produced by the model "
|
||||
" "
|
||||
"▌Allow command? "
|
||||
"▌ Yes Always No, provide feedback "
|
||||
"▌> 1. Yes "
|
||||
"▌ 2. Always "
|
||||
"▌ 3. No, provide feedback "
|
||||
"▌ "
|
||||
"▌ Approve and run the command "
|
||||
" "
|
||||
|
||||
@@ -191,12 +191,11 @@ impl UserApprovalWidget {
|
||||
|
||||
fn handle_select_key(&mut self, key_event: KeyEvent) {
|
||||
match key_event.code {
|
||||
KeyCode::Left => {
|
||||
self.selected_option = (self.selected_option + self.select_options.len() - 1)
|
||||
% self.select_options.len();
|
||||
KeyCode::Up | KeyCode::Char('k') | KeyCode::Left => {
|
||||
self.select_previous_option();
|
||||
}
|
||||
KeyCode::Right => {
|
||||
self.selected_option = (self.selected_option + 1) % self.select_options.len();
|
||||
KeyCode::Down | KeyCode::Char('j') | KeyCode::Right => {
|
||||
self.select_next_option();
|
||||
}
|
||||
KeyCode::Enter => {
|
||||
let opt = &self.select_options[self.selected_option];
|
||||
@@ -205,6 +204,13 @@ impl UserApprovalWidget {
|
||||
KeyCode::Esc => {
|
||||
self.send_decision(ReviewDecision::Abort);
|
||||
}
|
||||
KeyCode::Char(c @ '1'..='9') => {
|
||||
let idx = c as usize - '1' as usize;
|
||||
if idx < self.select_options.len() {
|
||||
let opt = &self.select_options[idx];
|
||||
self.send_decision(opt.decision);
|
||||
}
|
||||
}
|
||||
other => {
|
||||
let normalized = Self::normalize_keycode(other);
|
||||
if let Some(opt) = self
|
||||
@@ -218,6 +224,21 @@ impl UserApprovalWidget {
|
||||
}
|
||||
}
|
||||
|
||||
fn select_previous_option(&mut self) {
|
||||
if self.select_options.is_empty() {
|
||||
return;
|
||||
}
|
||||
self.selected_option =
|
||||
(self.selected_option + self.select_options.len() - 1) % self.select_options.len();
|
||||
}
|
||||
|
||||
fn select_next_option(&mut self) {
|
||||
if self.select_options.is_empty() {
|
||||
return;
|
||||
}
|
||||
self.selected_option = (self.selected_option + 1) % self.select_options.len();
|
||||
}
|
||||
|
||||
fn send_decision(&mut self, decision: ReviewDecision) {
|
||||
self.send_decision_with_feedback(decision, String::new())
|
||||
}
|
||||
@@ -320,9 +341,10 @@ impl UserApprovalWidget {
|
||||
pub(crate) fn desired_height(&self, width: u16) -> u16 {
|
||||
// Reserve space for:
|
||||
// - 1 title line ("Allow command?" or "Apply changes?")
|
||||
// - 1 buttons line (options rendered horizontally on a single row)
|
||||
// - N option lines (one per choice rendered vertically)
|
||||
// - 1 spacer line between the options and description
|
||||
// - 1 description line (context for the currently selected option)
|
||||
self.get_confirmation_prompt_height(width) + 3
|
||||
self.get_confirmation_prompt_height(width) + self.select_options.len() as u16 + 3
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,24 +356,37 @@ impl WidgetRef for &UserApprovalWidget {
|
||||
.constraints([Constraint::Length(prompt_height), Constraint::Min(0)])
|
||||
.areas(area);
|
||||
|
||||
let lines: Vec<Line> = self
|
||||
.select_options
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, opt)| {
|
||||
let style = if idx == self.selected_option {
|
||||
Style::new().bg(Color::Cyan).fg(Color::Black)
|
||||
} else {
|
||||
Style::new().add_modifier(Modifier::DIM)
|
||||
};
|
||||
opt.label.clone().alignment(Alignment::Center).style(style)
|
||||
})
|
||||
.collect();
|
||||
let mut option_lines: Vec<Line<'static>> = Vec::new();
|
||||
for (idx, opt) in self.select_options.iter().enumerate() {
|
||||
let is_selected = idx == self.selected_option;
|
||||
let prefix = if is_selected {
|
||||
format!("> {}. ", idx + 1).cyan().dim()
|
||||
} else {
|
||||
format!(" {}. ", idx + 1).dim()
|
||||
};
|
||||
|
||||
let [title_area, button_area, description_area] = Layout::vertical([
|
||||
let mut label_spans = opt.label.clone().spans;
|
||||
let label_style = if is_selected {
|
||||
Style::new().fg(Color::Cyan)
|
||||
} else {
|
||||
Style::new().add_modifier(Modifier::DIM)
|
||||
};
|
||||
for span in &mut label_spans {
|
||||
span.style = span.style.patch(label_style);
|
||||
}
|
||||
|
||||
let mut spans = Vec::with_capacity(label_spans.len() + 1);
|
||||
spans.push(prefix);
|
||||
spans.append(&mut label_spans);
|
||||
option_lines.push(Line::from(spans));
|
||||
}
|
||||
|
||||
let options_height = option_lines.len().max(1) as u16;
|
||||
let [title_area, options_area, _spacer_area, description_area] = Layout::vertical([
|
||||
Constraint::Length(1),
|
||||
Constraint::Length(options_height),
|
||||
Constraint::Length(1),
|
||||
Constraint::Length(1),
|
||||
Constraint::Min(0),
|
||||
])
|
||||
.areas(response_chunk.inner(Margin::new(1, 0)));
|
||||
let title = match &self.approval_request {
|
||||
@@ -361,17 +396,7 @@ impl WidgetRef for &UserApprovalWidget {
|
||||
Line::from(title).render(title_area, buf);
|
||||
|
||||
self.confirmation_prompt.clone().render(prompt_chunk, buf);
|
||||
let areas = Layout::horizontal(
|
||||
lines
|
||||
.iter()
|
||||
.map(|l| Constraint::Length(l.width() as u16 + 2)),
|
||||
)
|
||||
.spacing(1)
|
||||
.split(button_area);
|
||||
for (idx, area) in areas.iter().enumerate() {
|
||||
let line = &lines[idx];
|
||||
line.render(*area, buf);
|
||||
}
|
||||
Paragraph::new(option_lines).render(options_area, buf);
|
||||
|
||||
Line::from(self.select_options[self.selected_option].description)
|
||||
.style(Style::new().italic().add_modifier(Modifier::DIM))
|
||||
|
||||
Reference in New Issue
Block a user