Skip to main content

ai_agent/utils/
completion_cache.rs

1//! Shell completion cache utilities
2//!
3//! Translated from openclaudecode/src/utils/completionCache.ts
4
5use crate::constants::env::system;
6use std::path::PathBuf;
7
8/// Shell info for completion
9#[derive(Debug, Clone)]
10pub struct ShellInfo {
11    pub name: String,
12    pub rc_file: PathBuf,
13    pub cache_file: PathBuf,
14    pub completion_line: String,
15    pub shell_flag: String,
16}
17
18/// Detect the current shell
19pub fn detect_shell() -> Option<ShellInfo> {
20    let shell = std::env::var(system::SHELL).unwrap_or_default();
21    let home = std::env::var(system::HOME).ok()?;
22    let claude_dir = PathBuf::from(&home).join(".ai");
23
24    if shell.ends_with("/zsh") || shell.ends_with("/zsh.exe") {
25        let cache_file = claude_dir.join("completion.zsh");
26        let cache_file_str = cache_file.display().to_string();
27        return Some(ShellInfo {
28            name: "zsh".to_string(),
29            rc_file: PathBuf::from(&home).join(".zshrc"),
30            cache_file: cache_file.clone(),
31            completion_line: format!(
32                "[[ -f \"{}\" ]] && source \"{}\"",
33                cache_file_str, cache_file_str
34            ),
35            shell_flag: "zsh".to_string(),
36        });
37    }
38
39    if shell.ends_with("/bash") || shell.ends_with("/bash.exe") {
40        let cache_file = claude_dir.join("completion.bash");
41        let cache_file_str = cache_file.display().to_string();
42        return Some(ShellInfo {
43            name: "bash".to_string(),
44            rc_file: PathBuf::from(&home).join(".bashrc"),
45            cache_file: cache_file.clone(),
46            completion_line: format!(
47                "[ -f \"{}\" ] && source \"{}\"",
48                cache_file_str, cache_file_str
49            ),
50            shell_flag: "bash".to_string(),
51        });
52    }
53
54    if shell.ends_with("/fish") || shell.ends_with("/fish.exe") {
55        let xdg_config = std::env::var(system::XDG_CONFIG_HOME)
56            .map(PathBuf::from)
57            .unwrap_or_else(|_| PathBuf::from(&home).join(".config"));
58        let cache_file = claude_dir.join("completion.fish");
59        let cache_file_str = cache_file.display().to_string();
60        return Some(ShellInfo {
61            name: "fish".to_string(),
62            rc_file: xdg_config.join("fish").join("config.fish"),
63            cache_file: cache_file.clone(),
64            completion_line: format!(
65                "[ -f \"{}\" ] && source \"{}\"",
66                cache_file_str, cache_file_str
67            ),
68            shell_flag: "fish".to_string(),
69        });
70    }
71
72    None
73}
74
75/// Get the completion cache directory
76pub fn get_completion_cache_dir() -> Option<PathBuf> {
77    let home = std::env::var(system::HOME).ok()?;
78    Some(PathBuf::from(home).join(".ai"))
79}