Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,14 @@ After setting up your agent with flyline, you can pass the buffer to your agent

Flyline will syntax highlight the suggested commands and render markdown output.

To fix a failed command, press Alt+Enter on an empty prompt. Flyline sends your previous command and its exit status to your agent.

Alt+Shift+Enter does the same on an empty prompt. On a non-empty buffer it asks the agent to fix what you typed (without an exit status), where Alt+Enter would send it as a regular question. Alt+Shift+Enter needs a terminal that supports extended key codes. If yours doesn't, bind the fix to a single key combination:

```bash
flyline key bind Alt+z always=fixLastCommand
```

# Mouse support

Click to move your cursor, select suggestions, and hover for tooltips.
Expand Down
49 changes: 49 additions & 0 deletions src/app/actions/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ pub enum KeyEventAction {
RunAgentMode,
#[strum(message = "Run the agent mode help command")]
AgentModeRunHelpCommand,
#[strum(
message = "Ask the agent to fix the buffer, or the previous command if the buffer is empty"
)]
FixLastCommand,
#[strum(
message = "Submit the current command or insert a newline if the buffer is an incomplete expression"
)]
Expand Down Expand Up @@ -541,6 +545,38 @@ impl KeyEventAction {
app.show_agent_mode_not_configured_error();
}
}
KeyEventAction::FixLastCommand => {
let last_command = app
.long_lived
.history_manager
.entries()
.last()
.map(|entry| entry.command.clone());
let Some((agent_cmd, buffer)) = app.resolve_agent_command(false) else {
if app.buffer.buffer().trim().is_empty()
&& let Some(last) = last_command
{
app.buffer.replace_buffer(&last);
}
app.show_agent_mode_not_configured_error();
return;
};
let prompt = if buffer.trim().is_empty() {
let Some(last) = last_command else {
return;
};
app.long_lived
.agent_prompt_history_manager
.push_entry(last.clone());
format!(
"This Bash command exited with status {}. Fix it:\n{last}",
crate::shell::backend().last_command_exit_status()
)
} else {
format!("Fix this Bash command:\n{}", buffer.trim())
};
app.start_agent_mode(agent_cmd, &prompt);
}
KeyEventAction::AgentModeRunHelpCommand => {
if let ContentMode::AgentError {
suggested_setup_command,
Expand Down Expand Up @@ -2336,11 +2372,24 @@ pub static DEFAULT_BINDINGS: LazyLock<Vec<Binding>> = LazyLock::new(|| {
ContextVar::BufferHasAgentModePrefix + ContextVar::EditingBufferMode,
&[KeyEventAction::RunAgentMode],
),
Binding::new(
&expand_variations![M::ALT + KC::Enter.into()],
ContextVar::BufferIsEmpty.into(),
&[KeyEventAction::FixLastCommand],
),
Binding::new(
&expand_variations![M::ALT + KC::Enter.into()],
ContextVar::Always.into(),
&[KeyEventAction::RunAgentMode],
),
Binding::new(
&[
(M::ALT | M::SHIFT) + KC::Enter.into(),
(M::META | M::SHIFT) + KC::Enter.into(),
],
ContextVar::Always.into(),
&[KeyEventAction::FixLastCommand],
),
Binding::new(
&expand_variations![KC::Enter.into()],
ContextVar::FuzzyHistorySearchAgentCommands.into(),
Expand Down
1 change: 0 additions & 1 deletion src/history/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,6 @@ impl HistoryManager {
}
}

#[allow(dead_code)]
pub fn entries(&self) -> &[HistoryEntry] {
&self.entries
}
Expand Down
Loading