reovim_driver_session/api/window.rs
1//! Window management and focus operations.
2//!
3//! This module provides the [`WindowApi`] trait for window manipulation.
4//! Resolvers and commands use this to manage window layout and focus.
5//!
6//! # Design
7//!
8//! Following Unix philosophy: this trait does ONE thing well - window management.
9//!
10//! # Example
11//!
12//! ```ignore
13//! use reovim_driver_session::api::WindowApi;
14//!
15//! fn split_window<S: WindowApi + BufferApi>(session: &mut S) {
16//! let buffer = session.active_buffer();
17//! let new_window = session.create_window(buffer);
18//! session.focus_window(new_window).ok();
19//! }
20//! ```
21
22use reovim_kernel::api::v1::{BufferId, Position, WindowId};
23
24use super::Selection;
25
26/// Window management and focus operations.
27///
28/// Provides access to window layout, focus, and buffer association
29/// for resolvers and commands.
30pub trait WindowApi: Send {
31 /// Get the active window ID.
32 fn active_window(&self) -> Option<WindowId>;
33
34 /// Get cursor position from the active window.
35 ///
36 /// Returns `None` if no active window exists.
37 /// Note: This returns cursor for the current client's active window.
38 fn cursor_position(&self) -> Option<Position>;
39
40 /// Get the window count.
41 fn window_count(&self) -> usize;
42
43 /// Get the buffer displayed in a window.
44 fn window_buffer(&self, window: WindowId) -> Option<BufferId>;
45
46 /// Create a new window.
47 ///
48 /// If `buffer` is `None`, the window starts empty.
49 fn create_window(&mut self, buffer: Option<BufferId>) -> WindowId;
50
51 /// Close a window.
52 ///
53 /// # Errors
54 ///
55 /// Returns error if window doesn't exist or is the last window.
56 fn close_window(&mut self, window: WindowId) -> Result<(), WindowError>;
57
58 /// Focus a window.
59 ///
60 /// # Errors
61 ///
62 /// Returns error if window doesn't exist.
63 fn focus_window(&mut self, window: WindowId) -> Result<(), WindowError>;
64
65 /// Set the buffer displayed in a window.
66 ///
67 /// # Errors
68 ///
69 /// Returns error if window or buffer doesn't exist.
70 fn set_window_buffer(&mut self, window: WindowId, buffer: BufferId) -> Result<(), WindowError>;
71
72 /// Set or clear the selection on the active window.
73 ///
74 /// Pass `None` to clear any existing selection.
75 /// Used by snippet navigation and visual mode for programmatic
76 /// selection control through the trait interface.
77 fn set_active_selection(&mut self, selection: Option<Selection>);
78
79 /// Get the selection on the active window, if any.
80 fn active_selection(&self) -> Option<&Selection>;
81}
82
83/// Errors from window operations.
84#[derive(Debug, Clone, PartialEq, Eq)]
85pub enum WindowError {
86 /// Window not found.
87 NotFound(WindowId),
88 /// Cannot close the last window.
89 CannotCloseLastWindow,
90 /// Buffer not found.
91 BufferNotFound(BufferId),
92}
93
94impl std::fmt::Display for WindowError {
95 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
96 match self {
97 Self::NotFound(id) => write!(f, "window not found: {id:?}"),
98 Self::CannotCloseLastWindow => write!(f, "cannot close last window"),
99 Self::BufferNotFound(id) => write!(f, "buffer not found: {id:?}"),
100 }
101 }
102}
103
104impl std::error::Error for WindowError {}
105#[cfg(test)]
106#[path = "tests/window.rs"]
107mod tests;