diff options
| author | Michelle Tilley <michelle@michelletilley.net> | 2026-03-12 14:52:15 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-03-12 14:52:15 -0700 |
| commit | f7431afe2f0b424b6dcd0a76138607857563e008 (patch) | |
| tree | 2557c66400371ba2d353fbf847406c4028c3aafa /crates/atuin-ai/src/commands | |
| parent | chore: update changelog (diff) | |
| download | atuin-f7431afe2f0b424b6dcd0a76138607857563e008.zip | |
feat: Add `atuin setup` (#3257)
Diffstat (limited to 'crates/atuin-ai/src/commands')
| -rw-r--r-- | crates/atuin-ai/src/commands/init.rs | 21 | ||||
| -rw-r--r-- | crates/atuin-ai/src/commands/inline.rs | 40 |
2 files changed, 43 insertions, 18 deletions
diff --git a/crates/atuin-ai/src/commands/init.rs b/crates/atuin-ai/src/commands/init.rs index caf4c8d9..6b23e936 100644 --- a/crates/atuin-ai/src/commands/init.rs +++ b/crates/atuin-ai/src/commands/init.rs @@ -43,7 +43,10 @@ _atuin_ai_question_mark() { # Clean up the inline viewport _atuin_ai_cleanup - if [[ $output == __atuin_ai_cancel__ ]]; then + if [[ $output == __atuin_ai_print__:* ]]; then + zle -I + echo "${output#__atuin_ai_print__:}" + elif [[ $output == __atuin_ai_cancel__ ]]; then zle reset-prompt elif [[ $output == __atuin_ai_execute__:* ]]; then RBUFFER="" @@ -86,8 +89,11 @@ _atuin_ai_question_mark() { local output output=$(atuin ai inline --hook 3>&1 1>&2 2>&3) - if [[ $output == __atuin_ai_cancel__ ]]; then - # User cancelled, do nothing + if [[ $output == __atuin_ai_print__:* ]]; then + echo "${output#__atuin_ai_print__:}" + READLINE_LINE="" + READLINE_POINT=0 + elif [[ $output == __atuin_ai_cancel__ ]]; then READLINE_LINE="" READLINE_POINT=0 elif [[ $output == __atuin_ai_execute__:* ]]; then @@ -145,8 +151,10 @@ function _atuin_ai_question_mark # Run atuin ai inline, swapping stdout and stderr set -l output (atuin ai inline --hook 3>&1 1>&2 2>&3 | string collect) - if test "$output" = "__atuin_ai_cancel__" - # User cancelled, do nothing + if string match --quiet '__atuin_ai_print__:*' "$output" + echo (string replace "__atuin_ai_print__:" "" -- "$output" | string collect) + commandline -f repaint + else if test "$output" = "__atuin_ai_cancel__" commandline -f repaint else if string match --quiet '__atuin_ai_execute__:*' "$output" # Execute the command immediately @@ -188,6 +196,7 @@ mod tests { assert!(result.contains("_atuin_ai_question_mark")); assert!(result.contains("bindkey")); assert!(result.contains("atuin ai inline --hook")); + assert!(result.contains("__atuin_ai_print__")); assert!(result.contains("__atuin_ai_cancel__")); assert!(result.contains("__atuin_ai_execute__")); assert!(result.contains("__atuin_ai_insert__")); @@ -200,6 +209,7 @@ mod tests { assert!(result.contains("bind")); assert!(result.contains("READLINE_LINE")); assert!(result.contains("atuin ai inline --hook")); + assert!(result.contains("__atuin_ai_print__")); assert!(result.contains("__atuin_ai_cancel__")); assert!(result.contains("__atuin_ai_execute__")); assert!(result.contains("__atuin_ai_insert__")); @@ -212,6 +222,7 @@ mod tests { assert!(result.contains("bind")); assert!(result.contains("commandline")); assert!(result.contains("atuin ai inline --hook")); + assert!(result.contains("__atuin_ai_print__")); assert!(result.contains("__atuin_ai_cancel__")); assert!(result.contains("__atuin_ai_execute__")); assert!(result.contains("__atuin_ai_insert__")); diff --git a/crates/atuin-ai/src/commands/inline.rs b/crates/atuin-ai/src/commands/inline.rs index 803c7d72..ce566be1 100644 --- a/crates/atuin-ai/src/commands/inline.rs +++ b/crates/atuin-ai/src/commands/inline.rs @@ -26,6 +26,17 @@ pub async fn run( settings: &atuin_client::settings::Settings, output_for_hook: bool, ) -> Result<()> { + if !settings.ai.enabled { + emit_shell_result( + Action::Print( + "Atuin AI is not enabled. Please enable it in your settings or run `atuin setup`." + .to_string(), + ), + output_for_hook, + ); + return Ok(()); + } + // Install panic hook once at entry point to ensure terminal restoration install_panic_hook(); @@ -62,7 +73,7 @@ pub async fn run( settings, ) .await?; - emit_shell_result(action.0, &action.1, output_for_hook); + emit_shell_result(action, output_for_hook); Ok(()) } @@ -326,10 +337,11 @@ fn detect_os() -> String { } } -#[derive(Clone, Copy)] +#[derive(Clone)] enum Action { - Execute, - Insert, + Execute(String), + Insert(String), + Print(String), Cancel, } @@ -432,7 +444,7 @@ async fn run_inline_tui( keep_output: bool, debug_state_file: Option<String>, settings: &atuin_client::settings::Settings, -) -> Result<(Action, String)> { +) -> Result<Action> { // Detect popup mode (only on Unix where atuin-hex socket is available) #[cfg(unix)] let mut popup_state = crate::tui::popup::try_setup_popup(); @@ -686,9 +698,9 @@ async fn run_inline_tui( // Map exit action to return value let result = match app.state.exit_action { - Some(ExitAction::Execute(cmd)) => (Action::Execute, cmd), - Some(ExitAction::Insert(cmd)) => (Action::Insert, cmd), - _ => (Action::Cancel, String::new()), + Some(ExitAction::Execute(cmd)) => Action::Execute(cmd), + Some(ExitAction::Insert(cmd)) => Action::Insert(cmd), + _ => Action::Cancel, }; Ok(result) @@ -702,17 +714,19 @@ impl Drop for RawModeGuard { } } -fn emit_shell_result(action: Action, command: &str, output_for_hook: bool) { +fn emit_shell_result(action: Action, output_for_hook: bool) { if output_for_hook { match action { - Action::Execute => eprintln!("__atuin_ai_execute__:{command}"), - Action::Insert => eprintln!("__atuin_ai_insert__:{command}"), + Action::Execute(output) => eprintln!("__atuin_ai_execute__:{output}"), + Action::Insert(output) => eprintln!("__atuin_ai_insert__:{output}"), + Action::Print(output) => eprintln!("__atuin_ai_print__:{output}"), Action::Cancel => eprintln!("__atuin_ai_cancel__"), } } else { match action { - Action::Execute => eprintln!("{command}"), - Action::Insert => eprintln!("{command}"), + Action::Execute(output) => eprintln!("{output}"), + Action::Insert(output) => eprintln!("{output}"), + Action::Print(output) => eprintln!("{output}"), Action::Cancel => eprintln!(), } } |
