aboutsummaryrefslogtreecommitdiffstats
path: root/crates/atuin-ai/src/commands/init.rs
diff options
context:
space:
mode:
authorMichelle Tilley <michelle@michelletilley.net>2026-02-13 10:54:38 -0800
committerGitHub <noreply@github.com>2026-02-13 18:54:38 +0000
commite6a8bb033434541974262699c12e2805cc054153 (patch)
treeff682af16556266a9777b4d21c84aa66c55d015e /crates/atuin-ai/src/commands/init.rs
parentchore(deps): update to rust 1.93.1 (#3181) (diff)
downloadatuin-e6a8bb033434541974262699c12e2805cc054153.zip
feat: add Atuin AI inline CLI MVP (#3178)
Diffstat (limited to 'crates/atuin-ai/src/commands/init.rs')
-rw-r--r--crates/atuin-ai/src/commands/init.rs70
1 files changed, 70 insertions, 0 deletions
diff --git a/crates/atuin-ai/src/commands/init.rs b/crates/atuin-ai/src/commands/init.rs
new file mode 100644
index 00000000..bf5c6256
--- /dev/null
+++ b/crates/atuin-ai/src/commands/init.rs
@@ -0,0 +1,70 @@
+pub async fn run() -> eyre::Result<()> {
+ let zsh_function = generate_zsh_integration();
+ println!("{}", zsh_function);
+ Ok(())
+}
+
+/// Generate the zsh integration function - pure function for easy testing
+pub fn generate_zsh_integration() -> &'static str {
+ r#"
+# TUI uses an alternate screen, so no explicit cleanup is needed.
+_atuin_ai_cleanup() {
+ true
+}
+
+# Question mark at start of line - natural language mode
+_atuin_ai_question_mark() {
+ # If buffer is empty or just contains '?', trigger natural language mode
+ if [[ -z "$BUFFER" || "$BUFFER" == "?" ]]; then
+ BUFFER=""
+ local output
+ output=$(atuin-ai inline --natural-language 3>&1 1>&2 2>&3)
+
+ # Clean up the inline viewport
+ _atuin_ai_cleanup
+
+ if [[ $output == __atuin_ai_cancel__ ]]; then
+ zle reset-prompt
+ elif [[ $output == __atuin_ai_execute__:* ]]; then
+ RBUFFER=""
+ LBUFFER=${output#__atuin_ai_execute__:}
+ zle reset-prompt
+ zle accept-line
+ elif [[ $output == __atuin_ai_insert__:* ]]; then
+ RBUFFER=""
+ LBUFFER=${output#__atuin_ai_insert__:}
+ zle reset-prompt
+ elif [[ -n $output ]]; then
+ RBUFFER=""
+ LBUFFER=$output
+ zle reset-prompt
+ else
+ zle reset-prompt
+ fi
+ else
+ LBUFFER="${LBUFFER}?"
+ fi
+}
+
+# Set up keybindings
+zle -N _atuin_ai_question_mark
+bindkey '?' _atuin_ai_question_mark # Question mark
+"#
+ .trim()
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_generate_zsh_integration() {
+ let result = generate_zsh_integration();
+ assert!(result.contains("_atuin_ai_question_mark"));
+ assert!(result.contains("bindkey"));
+ assert!(result.contains("atuin-ai inline"));
+ assert!(result.contains("__atuin_ai_cancel__"));
+ assert!(result.contains("__atuin_ai_execute__"));
+ assert!(result.contains("__atuin_ai_insert__"));
+ }
+}