fresh/app/window/
buffers.rs1use fresh_core::BufferId;
8use std::collections::{HashMap, HashSet};
9use std::path::PathBuf;
10
11use crate::model::event::LeafId;
12use crate::state::EditorState;
13use crate::view::split::{SplitManager, SplitViewState};
14
15type Splits = (SplitManager, HashMap<LeafId, SplitViewState>);
16
17pub struct WindowBuffers {
18 map: HashMap<BufferId, EditorState>,
19 splits: Option<Splits>,
20}
21
22impl WindowBuffers {
23 pub fn new() -> Self {
24 Self {
25 map: HashMap::new(),
26 splits: None,
27 }
28 }
29
30 pub fn get(&self, id: &BufferId) -> Option<&EditorState> {
33 self.map.get(id)
34 }
35
36 pub fn get_mut(&mut self, id: &BufferId) -> Option<&mut EditorState> {
37 self.map.get_mut(id)
38 }
39
40 pub fn insert(&mut self, id: BufferId, state: EditorState) -> Option<EditorState> {
41 self.map.insert(id, state)
42 }
43
44 pub fn remove(&mut self, id: &BufferId) -> Option<EditorState> {
45 self.map.remove(id)
46 }
47
48 pub fn contains_key(&self, id: &BufferId) -> bool {
49 self.map.contains_key(id)
50 }
51
52 pub fn len(&self) -> usize {
53 self.map.len()
54 }
55
56 pub fn iter(&self) -> std::collections::hash_map::Iter<'_, BufferId, EditorState> {
57 self.map.iter()
58 }
59
60 pub fn as_map(&self) -> &HashMap<BufferId, EditorState> {
65 &self.map
66 }
67
68 pub fn as_map_mut(&mut self) -> &mut HashMap<BufferId, EditorState> {
76 &mut self.map
77 }
78
79 pub fn ids(&self) -> Vec<BufferId> {
82 self.map.keys().copied().collect()
83 }
84
85 pub fn find_id<F>(&self, mut predicate: F) -> Option<BufferId>
86 where
87 F: FnMut(BufferId, &EditorState) -> bool,
88 {
89 self.map
90 .iter()
91 .find(|(id, state)| predicate(**id, state))
92 .map(|(id, _)| *id)
93 }
94
95 pub fn count_where<F>(&self, mut predicate: F) -> usize
96 where
97 F: FnMut(BufferId, &EditorState) -> bool,
98 {
99 self.map
100 .iter()
101 .filter(|(id, state)| predicate(**id, state))
102 .count()
103 }
104
105 pub fn paths(&self) -> Vec<PathBuf> {
106 self.map
107 .values()
108 .filter_map(|state| state.buffer.file_path().map(PathBuf::from))
109 .collect()
110 }
111
112 pub fn languages(&self) -> HashSet<String> {
113 self.map
114 .values()
115 .map(|state| state.language.clone())
116 .collect()
117 }
118
119 pub fn any_needs_semantic_redraw(&self) -> bool {
120 self.map.values().any(|state| {
121 state
122 .reference_highlight_overlay
123 .needs_redraw()
124 .is_some_and(|remaining| remaining.is_zero())
125 })
126 }
127
128 pub fn splits(&self) -> Option<&Splits> {
131 self.splits.as_ref()
132 }
133
134 pub fn split_manager(&self) -> Option<&SplitManager> {
135 self.splits.as_ref().map(|(m, _)| m)
136 }
137
138 pub fn split_view_states(&self) -> Option<&HashMap<LeafId, SplitViewState>> {
139 self.splits.as_ref().map(|(_, vs)| vs)
140 }
141
142 pub fn has_splits(&self) -> bool {
143 self.splits.is_some()
144 }
145
146 pub fn splits_mut(&mut self) -> Option<&mut Splits> {
154 self.splits.as_mut()
155 }
156
157 pub fn split_manager_mut(&mut self) -> Option<&mut SplitManager> {
158 self.splits.as_mut().map(|(m, _)| m)
159 }
160
161 pub fn split_view_states_mut(&mut self) -> Option<&mut HashMap<LeafId, SplitViewState>> {
162 self.splits.as_mut().map(|(_, vs)| vs)
163 }
164
165 pub fn set_splits(&mut self, splits: Splits) {
166 self.splits = Some(splits);
167 }
168
169 pub fn clear_splits(&mut self) {
170 self.splits = None;
171 }
172
173 pub fn with_buffer_and_split<F, R>(&mut self, buf: BufferId, split: LeafId, f: F) -> Option<R>
183 where
184 F: FnOnce(&mut EditorState, &mut SplitViewState) -> R,
185 {
186 let state = self.map.get_mut(&buf)?;
187 let (_, vs_map) = self.splits.as_mut()?;
188 let vs = vs_map.get_mut(&split)?;
189 Some(f(state, vs))
190 }
191
192 pub fn with_buffer_and_view_states<F, R>(&mut self, buf: BufferId, f: F) -> Option<R>
196 where
197 F: FnOnce(&mut EditorState, &mut HashMap<LeafId, SplitViewState>) -> R,
198 {
199 let state = self.map.get_mut(&buf)?;
200 let (_, vs_map) = self.splits.as_mut()?;
201 Some(f(state, vs_map))
202 }
203
204 pub fn with_all_mut<F, R>(&mut self, f: F) -> Option<R>
209 where
210 F: FnOnce(
211 &mut HashMap<BufferId, EditorState>,
212 &mut SplitManager,
213 &mut HashMap<LeafId, SplitViewState>,
214 ) -> R,
215 {
216 let buffer_map = &mut self.map;
217 let (mgr, vs_map) = self.splits.as_mut()?;
218 Some(f(buffer_map, mgr, vs_map))
219 }
220}
221
222impl Default for WindowBuffers {
223 fn default() -> Self {
224 Self::new()
225 }
226}
227
228impl<'a> IntoIterator for &'a WindowBuffers {
229 type Item = (&'a BufferId, &'a EditorState);
230 type IntoIter = std::collections::hash_map::Iter<'a, BufferId, EditorState>;
231 fn into_iter(self) -> Self::IntoIter {
232 self.map.iter()
233 }
234}
235
236impl<'a> IntoIterator for &'a mut WindowBuffers {
237 type Item = (&'a BufferId, &'a mut EditorState);
238 type IntoIter = std::collections::hash_map::IterMut<'a, BufferId, EditorState>;
239 fn into_iter(self) -> Self::IntoIter {
240 self.map.iter_mut()
241 }
242}