Skip to main content

codetether_agent/tui/app/state/
slash_suggest.rs

1//! Slash autocomplete suggestion methods.
2//!
3//! Refreshing, navigating, and applying slash command completions.
4
5use crate::tui::models::InputMode;
6
7impl super::AppState {
8    pub fn refresh_slash_suggestions(&mut self) {
9        if !self.input.starts_with('/') {
10            self.slash_suggestions.clear();
11            self.selected_slash_suggestion = 0;
12            return;
13        }
14        let raw_query = self.input.split_whitespace().next().unwrap_or("");
15        let query = crate::tui::app::text::normalize_slash_command(raw_query).to_lowercase();
16        self.slash_suggestions = super::slash_commands::SLASH_COMMANDS
17            .iter()
18            .filter(|cmd| cmd.starts_with(&query))
19            .map(|cmd| (*cmd).to_string())
20            .collect();
21        if self.slash_suggestions.is_empty() && query == "/" {
22            self.slash_suggestions = super::slash_commands::SLASH_COMMANDS
23                .iter()
24                .map(|cmd| (*cmd).to_string())
25                .collect();
26        }
27        if self.selected_slash_suggestion >= self.slash_suggestions.len() {
28            self.selected_slash_suggestion = self.slash_suggestions.len().saturating_sub(1);
29        }
30    }
31
32    pub fn slash_suggestions_visible(&self) -> bool {
33        self.view_mode == crate::tui::models::ViewMode::Chat
34            && !self.processing
35            && self.input.starts_with('/')
36            && !self.input.trim().chars().any(char::is_whitespace)
37            && !self.slash_suggestions.is_empty()
38    }
39
40    pub fn select_prev_slash_suggestion(&mut self) {
41        if !self.slash_suggestions.is_empty() {
42            self.selected_slash_suggestion = self.selected_slash_suggestion.saturating_sub(1);
43        }
44    }
45
46    pub fn select_next_slash_suggestion(&mut self) {
47        if !self.slash_suggestions.is_empty() {
48            self.selected_slash_suggestion =
49                (self.selected_slash_suggestion + 1).min(self.slash_suggestions.len() - 1);
50        }
51    }
52
53    pub fn selected_slash_suggestion(&self) -> Option<&str> {
54        self.slash_suggestions
55            .get(self.selected_slash_suggestion)
56            .map(String::as_str)
57    }
58
59    pub fn apply_selected_slash_suggestion(&mut self) -> bool {
60        if let Some(selected) = self.selected_slash_suggestion() {
61            self.input = selected.to_string();
62            self.input_cursor = self.input_char_count();
63            self.input_mode = InputMode::Command;
64            self.refresh_slash_suggestions();
65            return true;
66        }
67        false
68    }
69}