Skip to main content

reovim_driver_session/api/
mod.rs

1//! Session API traits for resolvers and commands.
2//!
3//! This module provides focused traits that resolvers and commands
4//! use to interact with session state. Each trait does ONE thing well
5//! (Unix philosophy).
6//!
7//! # Traits
8//!
9//! | Trait | Purpose |
10//! |-------|---------|
11//! | [`ModeApi`] | Mode stack operations |
12//! | [`BufferApi`] | Buffer content and lifecycle |
13//! | [`WindowApi`] | Window management and focus |
14//! | [`CommandApi`] | Command execution |
15//! | [`UndoApi`] | Undo/redo operations |
16//! | [`ExtensionApi`] | Module per-session state |
17//! | [`ChangeTracker`] | Accumulated change collection |
18//!
19//! # Architecture
20//!
21//! ```text
22//! ┌──────────────────────────────────────────────────────┐
23//! │ MODULES (resolvers, commands)              POLICY    │
24//! │   - Call session.push_mode(), session.move_cursor()  │
25//! │   - Decide WHAT actions to perform                   │
26//! └──────────────────────────────────────────────────────┘
27//!          │ calls methods on
28//!          ↓
29//! ┌──────────────────────────────────────────────────────┐
30//! │ SESSION API (this module)                 MECHANISM  │
31//! │   - Focused traits: ModeApi, BufferApi, etc.         │
32//! │   - SessionRuntime implements all traits             │
33//! │   - Returns: StateChanges (what changed)             │
34//! └──────────────────────────────────────────────────────┘
35//!          │ returns changes to
36//!          ↓
37//! ┌──────────────────────────────────────────────────────┐
38//! │ RUNNER                                    MECHANISM  │
39//! │   - Passes SessionRuntime to resolvers               │
40//! │   - Receives StateChanges                            │
41//! │   - Broadcasts notifications to clients              │
42//! └──────────────────────────────────────────────────────┘
43//! ```
44//!
45//! # Usage
46//!
47//! Resolvers specify which APIs they need via trait bounds:
48//!
49//! ```ignore
50//! fn resolve_with_session<S>(
51//!     &self,
52//!     key: &KeyEvent,
53//!     state: &mut ModeState,
54//!     session: &mut S,
55//! ) -> ResolveResult
56//! where
57//!     S: ModeApi + BufferApi + CommandApi + ExtensionApi,
58//! {
59//!     // Only has access to the traits specified in bounds
60//! }
61//! ```
62
63mod buffer;
64mod changes;
65mod clipboard;
66mod command;
67mod compositor;
68mod extension;
69mod find_char;
70mod mode;
71mod register;
72mod search;
73mod undo;
74mod window;
75
76// Buffer API
77pub use buffer::{BufferApi, BufferError, Selection, SelectionMode};
78
79// Clipboard API (#515)
80pub use clipboard::ClipboardApi;
81
82// Find-char state extension (#563)
83pub use find_char::{FindCharRecord, FindCharState};
84
85// Search state extension
86pub use search::SearchState;
87
88// Compositor API
89pub use compositor::{CompositorApi, CompositorError};
90
91// Register API
92pub use register::{RegisterApi, RegisterContent, YankType};
93
94// Change tracking
95pub use changes::{ChangeTracker, OptionChange, StateChanges};
96
97// Command API
98pub use command::{CommandApi, CommandExecutor, CommandHandle};
99
100// Extension API
101pub use extension::ExtensionApi;
102
103// Mode API
104pub use mode::{ModeApi, ModeError};
105
106// Undo API
107pub use undo::UndoApi;
108
109// Window API
110pub use window::{WindowApi, WindowError};
111
112// ============================================================================
113// SessionApi - Combined trait for resolvers
114// ============================================================================
115
116/// Dyn-compatible session API (without extensions).
117///
118/// This trait bundles the dyn-compatible API traits for use with trait objects.
119/// `ExtensionApi` is excluded because it has generic methods.
120///
121/// # Why Separate from `SessionApi`?
122///
123/// Rust's trait object (`dyn Trait`) requires all methods to be dyn-compatible.
124/// `ExtensionApi` has generic methods (`ext<T>`, `ext_mut<T>`), so it can't be
125/// part of a dyn-compatible trait.
126///
127/// Use `SessionApiDyn` when you need `&mut dyn SessionApiDyn` (e.g., in resolver traits).
128/// Extensions are passed separately as `&mut ExtensionMap`.
129///
130/// # Example
131///
132/// ```ignore
133/// fn resolve_with_session(
134///     &self,
135///     key: &KeyEvent,
136///     state: &mut ModeState,
137///     input: &ResolveInput<'_>,
138///     session: &mut dyn SessionApiDyn,
139///     extensions: &mut ExtensionMap,
140/// ) -> ResolveResult {
141///     session.push_mode(insert_mode, TransitionContext::new());
142///     session.move_cursor(buffer, Position::new(0, 5));
143///     ResolveResult::Completed
144/// }
145/// ```
146pub trait SessionApiDyn:
147    ModeApi + BufferApi + WindowApi + CommandApi + UndoApi + ChangeTracker
148{
149}
150
151// Blanket implementation for SessionApiDyn
152impl<T> SessionApiDyn for T where
153    T: ModeApi + BufferApi + WindowApi + CommandApi + UndoApi + ChangeTracker
154{
155}
156
157/// Full session API for generic bounds (not dyn-compatible).
158///
159/// This trait includes `ExtensionApi` and is used for generic bounds like
160/// `where S: SessionApi`. It cannot be used as `dyn SessionApi` because
161/// `ExtensionApi` has generic methods.
162///
163/// # Example
164///
165/// ```ignore
166/// fn do_something<S: SessionApi>(session: &mut S) {
167///     // Full access including extensions
168///     let ext = session.ext_mut::<MyExtension>();
169/// }
170/// ```
171pub trait SessionApi: SessionApiDyn + ExtensionApi {}
172
173// Blanket implementation for SessionApi
174impl<T> SessionApi for T where T: SessionApiDyn + ExtensionApi {}