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 {}