assistant: Allow accepting terminal inline assist suggestion without executing command (#17299)
This adds a new button that on click, accepts the suggestion but does not run the generated command. https://github.com/user-attachments/assets/426b0ff3-8e19-435a-aa7f-89e062aefd4c @danilo-leal @iamnbutler Any ideas on how to make both options discoverable without having an extra button? Release Notes: - Added a way to accept terminal inline assist suggestions without executing them --------- Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
This commit is contained in:
parent
3bdc35f1ac
commit
5b0d64890f
2 changed files with 51 additions and 25 deletions
|
@ -1 +1,3 @@
|
||||||
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M3.24182 2.32181C3.3919 2.23132 3.5784 2.22601 3.73338 2.30781L12.7334 7.05781C12.8974 7.14436 13 7.31457 13 7.5C13 7.68543 12.8974 7.85564 12.7334 7.94219L3.73338 12.6922C3.5784 12.774 3.3919 12.7687 3.24182 12.6782C3.09175 12.5877 3 12.4252 3 12.25V2.75C3 2.57476 3.09175 2.4123 3.24182 2.32181ZM4 3.57925V11.4207L11.4288 7.5L4 3.57925Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M5 4L12 8L5 12V4Z" stroke="black" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 518 B After Width: | Height: | Size: 218 B |
|
@ -157,11 +157,11 @@ impl TerminalInlineAssistant {
|
||||||
PromptEditorEvent::StopRequested => {
|
PromptEditorEvent::StopRequested => {
|
||||||
self.stop_assist(assist_id, cx);
|
self.stop_assist(assist_id, cx);
|
||||||
}
|
}
|
||||||
PromptEditorEvent::ConfirmRequested => {
|
PromptEditorEvent::ConfirmRequested { execute } => {
|
||||||
self.finish_assist(assist_id, false, cx);
|
self.finish_assist(assist_id, false, *execute, cx);
|
||||||
}
|
}
|
||||||
PromptEditorEvent::CancelRequested => {
|
PromptEditorEvent::CancelRequested => {
|
||||||
self.finish_assist(assist_id, true, cx);
|
self.finish_assist(assist_id, true, false, cx);
|
||||||
}
|
}
|
||||||
PromptEditorEvent::DismissRequested => {
|
PromptEditorEvent::DismissRequested => {
|
||||||
self.dismiss_assist(assist_id, cx);
|
self.dismiss_assist(assist_id, cx);
|
||||||
|
@ -292,6 +292,7 @@ impl TerminalInlineAssistant {
|
||||||
&mut self,
|
&mut self,
|
||||||
assist_id: TerminalInlineAssistId,
|
assist_id: TerminalInlineAssistId,
|
||||||
undo: bool,
|
undo: bool,
|
||||||
|
execute: bool,
|
||||||
cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
) {
|
) {
|
||||||
self.dismiss_assist(assist_id, cx);
|
self.dismiss_assist(assist_id, cx);
|
||||||
|
@ -307,7 +308,7 @@ impl TerminalInlineAssistant {
|
||||||
assist.codegen.update(cx, |codegen, cx| {
|
assist.codegen.update(cx, |codegen, cx| {
|
||||||
if undo {
|
if undo {
|
||||||
codegen.undo(cx);
|
codegen.undo(cx);
|
||||||
} else {
|
} else if execute {
|
||||||
codegen.complete(cx);
|
codegen.complete(cx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -423,7 +424,7 @@ impl TerminalInlineAssist {
|
||||||
}
|
}
|
||||||
|
|
||||||
if assist.prompt_editor.is_none() {
|
if assist.prompt_editor.is_none() {
|
||||||
this.finish_assist(assist_id, false, cx);
|
this.finish_assist(assist_id, false, false, cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -436,7 +437,7 @@ impl TerminalInlineAssist {
|
||||||
enum PromptEditorEvent {
|
enum PromptEditorEvent {
|
||||||
StartRequested,
|
StartRequested,
|
||||||
StopRequested,
|
StopRequested,
|
||||||
ConfirmRequested,
|
ConfirmRequested { execute: bool },
|
||||||
CancelRequested,
|
CancelRequested,
|
||||||
DismissRequested,
|
DismissRequested,
|
||||||
Resized { height_in_lines: u8 },
|
Resized { height_in_lines: u8 },
|
||||||
|
@ -509,15 +510,15 @@ impl Render for PromptEditor {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
CodegenStatus::Error(_) | CodegenStatus::Done => {
|
CodegenStatus::Error(_) | CodegenStatus::Done => {
|
||||||
vec![
|
let cancel = IconButton::new("cancel", IconName::Close)
|
||||||
IconButton::new("cancel", IconName::Close)
|
.icon_color(Color::Muted)
|
||||||
.icon_color(Color::Muted)
|
.shape(IconButtonShape::Square)
|
||||||
.shape(IconButtonShape::Square)
|
.tooltip(|cx| Tooltip::for_action("Cancel Assist", &menu::Cancel, cx))
|
||||||
.tooltip(|cx| Tooltip::for_action("Cancel Assist", &menu::Cancel, cx))
|
.on_click(cx.listener(|_, _, cx| cx.emit(PromptEditorEvent::CancelRequested)));
|
||||||
.on_click(
|
|
||||||
cx.listener(|_, _, cx| cx.emit(PromptEditorEvent::CancelRequested)),
|
if self.edited_since_done {
|
||||||
),
|
vec![
|
||||||
if self.edited_since_done {
|
cancel,
|
||||||
IconButton::new("restart", IconName::RotateCw)
|
IconButton::new("restart", IconName::RotateCw)
|
||||||
.icon_color(Color::Info)
|
.icon_color(Color::Info)
|
||||||
.shape(IconButtonShape::Square)
|
.shape(IconButtonShape::Square)
|
||||||
|
@ -531,19 +532,35 @@ impl Render for PromptEditor {
|
||||||
})
|
})
|
||||||
.on_click(cx.listener(|_, _, cx| {
|
.on_click(cx.listener(|_, _, cx| {
|
||||||
cx.emit(PromptEditorEvent::StartRequested);
|
cx.emit(PromptEditorEvent::StartRequested);
|
||||||
}))
|
})),
|
||||||
} else {
|
]
|
||||||
|
} else {
|
||||||
|
vec![
|
||||||
|
cancel,
|
||||||
|
IconButton::new("accept", IconName::Check)
|
||||||
|
.icon_color(Color::Info)
|
||||||
|
.shape(IconButtonShape::Square)
|
||||||
|
.tooltip(|cx| {
|
||||||
|
Tooltip::for_action("Accept Generated Command", &menu::Confirm, cx)
|
||||||
|
})
|
||||||
|
.on_click(cx.listener(|_, _, cx| {
|
||||||
|
cx.emit(PromptEditorEvent::ConfirmRequested { execute: false });
|
||||||
|
})),
|
||||||
IconButton::new("confirm", IconName::Play)
|
IconButton::new("confirm", IconName::Play)
|
||||||
.icon_color(Color::Info)
|
.icon_color(Color::Info)
|
||||||
.shape(IconButtonShape::Square)
|
.shape(IconButtonShape::Square)
|
||||||
.tooltip(|cx| {
|
.tooltip(|cx| {
|
||||||
Tooltip::for_action("Execute generated command", &menu::Confirm, cx)
|
Tooltip::for_action(
|
||||||
|
"Execute Generated Command",
|
||||||
|
&menu::SecondaryConfirm,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.on_click(cx.listener(|_, _, cx| {
|
.on_click(cx.listener(|_, _, cx| {
|
||||||
cx.emit(PromptEditorEvent::ConfirmRequested);
|
cx.emit(PromptEditorEvent::ConfirmRequested { execute: true });
|
||||||
}))
|
})),
|
||||||
},
|
]
|
||||||
]
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -555,6 +572,7 @@ impl Render for PromptEditor {
|
||||||
.h_full()
|
.h_full()
|
||||||
.w_full()
|
.w_full()
|
||||||
.on_action(cx.listener(Self::confirm))
|
.on_action(cx.listener(Self::confirm))
|
||||||
|
.on_action(cx.listener(Self::secondary_confirm))
|
||||||
.on_action(cx.listener(Self::cancel))
|
.on_action(cx.listener(Self::cancel))
|
||||||
.on_action(cx.listener(Self::move_up))
|
.on_action(cx.listener(Self::move_up))
|
||||||
.on_action(cx.listener(Self::move_down))
|
.on_action(cx.listener(Self::move_down))
|
||||||
|
@ -605,7 +623,7 @@ impl Render for PromptEditor {
|
||||||
.child(div().flex_1().child(self.render_prompt_editor(cx)))
|
.child(div().flex_1().child(self.render_prompt_editor(cx)))
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.gap_2()
|
.gap_1()
|
||||||
.pr_4()
|
.pr_4()
|
||||||
.children(self.render_token_count(cx))
|
.children(self.render_token_count(cx))
|
||||||
.children(buttons),
|
.children(buttons),
|
||||||
|
@ -809,7 +827,7 @@ impl PromptEditor {
|
||||||
if self.edited_since_done {
|
if self.edited_since_done {
|
||||||
cx.emit(PromptEditorEvent::StartRequested);
|
cx.emit(PromptEditorEvent::StartRequested);
|
||||||
} else {
|
} else {
|
||||||
cx.emit(PromptEditorEvent::ConfirmRequested);
|
cx.emit(PromptEditorEvent::ConfirmRequested { execute: false });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CodegenStatus::Error(_) => {
|
CodegenStatus::Error(_) => {
|
||||||
|
@ -818,6 +836,12 @@ impl PromptEditor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn secondary_confirm(&mut self, _: &menu::SecondaryConfirm, cx: &mut ViewContext<Self>) {
|
||||||
|
if matches!(self.codegen.read(cx).status, CodegenStatus::Done) {
|
||||||
|
cx.emit(PromptEditorEvent::ConfirmRequested { execute: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn move_up(&mut self, _: &MoveUp, cx: &mut ViewContext<Self>) {
|
fn move_up(&mut self, _: &MoveUp, cx: &mut ViewContext<Self>) {
|
||||||
if let Some(ix) = self.prompt_history_ix {
|
if let Some(ix) = self.prompt_history_ix {
|
||||||
if ix > 0 {
|
if ix > 0 {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue