use {
reovim_arch::sync::RwLock,
reovim_driver_input::{ExtensionMap, FallbackContext},
reovim_driver_undo::{UndoKey, UndoProvider, UndoProviderRegistry},
reovim_kernel::api::v1::{
Buffer, BufferId, Edit, KernelContext, ModeId, Position, ServiceRegistry,
},
std::sync::Arc,
};
#[derive(Debug)]
pub struct AppState {
pub kernel: KernelContext,
pub services: Arc<ServiceRegistry>,
pub running: bool,
pub extensions: ExtensionMap,
}
impl AppState {
#[must_use]
pub fn new(kernel: KernelContext) -> Self {
let services = Arc::clone(&kernel.services);
Self {
kernel,
services,
running: true,
extensions: ExtensionMap::new(),
}
}
#[must_use]
pub fn get_undo_provider(&self) -> Option<Arc<dyn UndoProvider>> {
self.services
.get::<UndoProviderRegistry>()
.and_then(|registry| registry.get(&UndoKey::Buffer))
}
#[allow(clippy::missing_const_for_fn)]
pub fn request_quit(&mut self) {
self.running = false;
}
#[allow(clippy::missing_const_for_fn)]
pub fn request_detach(&mut self) {
tracing::info!("Detach requested - clients will be notified");
}
#[must_use]
pub const fn is_running(&self) -> bool {
self.running
}
}
impl FallbackContext for AppState {
fn current_mode(&self) -> &ModeId {
panic!(
"AppState::current_mode() should not be called - use SessionState::current_mode() instead"
);
}
fn active_buffer(&self) -> Option<BufferId> {
panic!(
"AppState::active_buffer() should not be called - use SessionState::session_active_buffer() instead"
);
}
fn cursor_position(&self) -> Option<Position> {
panic!(
"AppState::cursor_position() should not be called - use client-specific window state instead"
);
}
fn set_cursor_position(&mut self, _pos: Position) {
panic!(
"AppState::set_cursor_position() should not be called - use client-specific window state instead"
);
}
fn get_buffer(&self, id: BufferId) -> Option<Arc<RwLock<Buffer>>> {
self.kernel.buffers.get(id)
}
fn record_edit(
&mut self,
buffer_id: BufferId,
edits: Vec<Edit>,
cursor_before: Position,
cursor_after: Position,
) {
if let Some(undo_provider) = self.get_undo_provider() {
undo_provider.record(buffer_id, edits, cursor_before, cursor_after);
}
}
fn accumulate_edit(
&mut self,
buffer_id: BufferId,
edit: Edit,
cursor_before: Position,
cursor_after: Position,
) {
if let Some(undo_provider) = self.get_undo_provider() {
undo_provider.record(buffer_id, vec![edit], cursor_before, cursor_after);
}
}
fn flush_pending_edits(&mut self) {
}
}
#[cfg(test)]
#[path = "app_tests.rs"]
mod tests;