Skip to main content

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;