aboutsummaryrefslogtreecommitdiffstats
path: root/crates/atuin-ai/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/atuin-ai/src')
-rw-r--r--crates/atuin-ai/src/commands/init.rs21
-rw-r--r--crates/atuin-ai/src/commands/inline.rs40
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!(),
}
}