use fresh_core::BufferId;
use std::collections::{HashMap, HashSet};
use std::path::PathBuf;
use crate::model::event::LeafId;
use crate::state::EditorState;
use crate::view::split::{SplitManager, SplitViewState};
type Splits = (SplitManager, HashMap<LeafId, SplitViewState>);
pub struct WindowBuffers {
map: HashMap<BufferId, EditorState>,
splits: Option<Splits>,
}
impl WindowBuffers {
pub fn new() -> Self {
Self {
map: HashMap::new(),
splits: None,
}
}
pub fn get(&self, id: &BufferId) -> Option<&EditorState> {
self.map.get(id)
}
pub fn get_mut(&mut self, id: &BufferId) -> Option<&mut EditorState> {
self.map.get_mut(id)
}
pub fn insert(&mut self, id: BufferId, state: EditorState) -> Option<EditorState> {
self.map.insert(id, state)
}
pub fn remove(&mut self, id: &BufferId) -> Option<EditorState> {
self.map.remove(id)
}
pub fn contains_key(&self, id: &BufferId) -> bool {
self.map.contains_key(id)
}
pub fn len(&self) -> usize {
self.map.len()
}
pub fn iter(&self) -> std::collections::hash_map::Iter<'_, BufferId, EditorState> {
self.map.iter()
}
pub fn as_map(&self) -> &HashMap<BufferId, EditorState> {
&self.map
}
pub fn as_map_mut(&mut self) -> &mut HashMap<BufferId, EditorState> {
&mut self.map
}
pub fn ids(&self) -> Vec<BufferId> {
self.map.keys().copied().collect()
}
pub fn find_id<F>(&self, mut predicate: F) -> Option<BufferId>
where
F: FnMut(BufferId, &EditorState) -> bool,
{
self.map
.iter()
.find(|(id, state)| predicate(**id, state))
.map(|(id, _)| *id)
}
pub fn count_where<F>(&self, mut predicate: F) -> usize
where
F: FnMut(BufferId, &EditorState) -> bool,
{
self.map
.iter()
.filter(|(id, state)| predicate(**id, state))
.count()
}
pub fn paths(&self) -> Vec<PathBuf> {
self.map
.values()
.filter_map(|state| state.buffer.file_path().map(PathBuf::from))
.collect()
}
pub fn languages(&self) -> HashSet<String> {
self.map
.values()
.map(|state| state.language.clone())
.collect()
}
pub fn any_needs_semantic_redraw(&self) -> bool {
self.map.values().any(|state| {
state
.reference_highlight_overlay
.needs_redraw()
.is_some_and(|remaining| remaining.is_zero())
})
}
pub fn splits(&self) -> Option<&Splits> {
self.splits.as_ref()
}
pub fn split_manager(&self) -> Option<&SplitManager> {
self.splits.as_ref().map(|(m, _)| m)
}
pub fn split_view_states(&self) -> Option<&HashMap<LeafId, SplitViewState>> {
self.splits.as_ref().map(|(_, vs)| vs)
}
pub fn has_splits(&self) -> bool {
self.splits.is_some()
}
pub fn splits_mut(&mut self) -> Option<&mut Splits> {
self.splits.as_mut()
}
pub fn split_manager_mut(&mut self) -> Option<&mut SplitManager> {
self.splits.as_mut().map(|(m, _)| m)
}
pub fn split_view_states_mut(&mut self) -> Option<&mut HashMap<LeafId, SplitViewState>> {
self.splits.as_mut().map(|(_, vs)| vs)
}
pub fn set_splits(&mut self, splits: Splits) {
self.splits = Some(splits);
}
pub fn clear_splits(&mut self) {
self.splits = None;
}
pub fn with_buffer_and_split<F, R>(&mut self, buf: BufferId, split: LeafId, f: F) -> Option<R>
where
F: FnOnce(&mut EditorState, &mut SplitViewState) -> R,
{
let state = self.map.get_mut(&buf)?;
let (_, vs_map) = self.splits.as_mut()?;
let vs = vs_map.get_mut(&split)?;
Some(f(state, vs))
}
pub fn with_buffer_and_view_states<F, R>(&mut self, buf: BufferId, f: F) -> Option<R>
where
F: FnOnce(&mut EditorState, &mut HashMap<LeafId, SplitViewState>) -> R,
{
let state = self.map.get_mut(&buf)?;
let (_, vs_map) = self.splits.as_mut()?;
Some(f(state, vs_map))
}
pub fn with_all_mut<F, R>(&mut self, f: F) -> Option<R>
where
F: FnOnce(
&mut HashMap<BufferId, EditorState>,
&mut SplitManager,
&mut HashMap<LeafId, SplitViewState>,
) -> R,
{
let buffer_map = &mut self.map;
let (mgr, vs_map) = self.splits.as_mut()?;
Some(f(buffer_map, mgr, vs_map))
}
}
impl Default for WindowBuffers {
fn default() -> Self {
Self::new()
}
}
impl<'a> IntoIterator for &'a WindowBuffers {
type Item = (&'a BufferId, &'a EditorState);
type IntoIter = std::collections::hash_map::Iter<'a, BufferId, EditorState>;
fn into_iter(self) -> Self::IntoIter {
self.map.iter()
}
}
impl<'a> IntoIterator for &'a mut WindowBuffers {
type Item = (&'a BufferId, &'a mut EditorState);
type IntoIter = std::collections::hash_map::IterMut<'a, BufferId, EditorState>;
fn into_iter(self) -> Self::IntoIter {
self.map.iter_mut()
}
}