sql_cli/
history_manager.rs1use crate::history::{CommandHistory, HistoryMatch};
2
3pub struct HistoryManager {
5 pub search_query: String,
6 pub matches: Vec<HistoryMatch>,
7 pub selected_index: usize,
8}
9
10impl HistoryManager {
11 pub fn new() -> Self {
12 Self {
13 search_query: String::new(),
14 matches: Vec::new(),
15 selected_index: 0,
16 }
17 }
18
19 pub fn update_matches(&mut self, history: &CommandHistory) {
21 if self.search_query.is_empty() {
22 self.matches = history
24 .get_session_entries()
25 .iter()
26 .map(|entry| HistoryMatch {
27 entry: entry.clone(),
28 score: 100,
29 indices: Vec::new(),
30 })
31 .collect();
32 } else {
33 self.matches = history.search(&self.search_query);
35 }
36
37 if self.selected_index >= self.matches.len() && !self.matches.is_empty() {
39 self.selected_index = self.matches.len() - 1;
40 }
41 }
42
43 pub fn next_match(&mut self) {
45 if !self.matches.is_empty() {
46 self.selected_index = (self.selected_index + 1) % self.matches.len();
47 }
48 }
49
50 pub fn previous_match(&mut self) {
52 if !self.matches.is_empty() {
53 if self.selected_index == 0 {
54 self.selected_index = self.matches.len() - 1;
55 } else {
56 self.selected_index -= 1;
57 }
58 }
59 }
60
61 pub fn get_selected(&self) -> Option<&HistoryMatch> {
63 if self.selected_index < self.matches.len() {
64 self.matches.get(self.selected_index)
65 } else {
66 None
67 }
68 }
69
70 pub fn clear(&mut self) {
72 self.search_query.clear();
73 self.matches.clear();
74 self.selected_index = 0;
75 }
76
77 pub fn set_search(&mut self, query: String, history: &CommandHistory) {
79 self.search_query = query;
80 self.update_matches(history);
81 }
82
83 pub fn get_visible_range(&self, height: usize) -> (usize, usize) {
85 if self.matches.is_empty() {
86 return (0, 0);
87 }
88
89 let total = self.matches.len();
90 let half_height = height / 2;
91
92 let start = if self.selected_index <= half_height {
94 0
95 } else if self.selected_index + half_height >= total {
96 total.saturating_sub(height)
97 } else {
98 self.selected_index - half_height
99 };
100
101 let end = (start + height).min(total);
102 (start, end)
103 }
104}
105
106impl Default for HistoryManager {
107 fn default() -> Self {
108 Self::new()
109 }
110}