pub trait Mode:
Copy
+ Clone
+ PartialEq
+ Eq
+ Hash
+ Send
+ Sync
+ 'static {
// Required methods
fn module() -> ModuleId
where Self: Sized;
fn discriminant(&self) -> u16;
fn display_name(&self) -> &'static str;
fn cursor_style(&self) -> CursorStyle;
fn accepts_char_input(&self) -> bool;
// Provided methods
fn id(&self) -> ModeId
where Self: Sized { ... }
fn has_selection(&self) -> bool { ... }
fn inherits_from(&self) -> Option<Self>
where Self: Sized { ... }
fn is_entry(&self) -> bool { ... }
}Expand description
Mode trait for type-safe, compile-time enforced mode ownership.
Policy modules (e.g., vim, emacs) define their own Mode enums and implement this trait. The trait provides both identity and behavior information, allowing the kernel and drivers to query mode properties without knowing the concrete type.
§Type Safety
The trait requires Copy + Clone + PartialEq + Eq + Hash to ensure modes
are lightweight value types that can be efficiently compared and stored.
This also makes the trait not object-safe, which is intentional:
runtime storage uses ModeId, not dyn Mode.
§Blanket Implementation
All Mode types automatically implement From<M> for ModeId, allowing
ergonomic conversion when storing modes in ModeStack or ModeRegistry.
§Example
use reovim_kernel::api::v1::{Mode, ModeId, ModuleId, CursorStyle};
const VIM_MODULE: ModuleId = ModuleId::new("vim");
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u16)]
enum VimMode {
Normal = 0,
Insert = 1,
Visual = 2,
}
impl Mode for VimMode {
fn module() -> ModuleId { VIM_MODULE }
fn discriminant(&self) -> u16 { *self as u16 }
fn display_name(&self) -> &'static str {
match self {
Self::Normal => "NORMAL",
Self::Insert => "INSERT",
Self::Visual => "VISUAL",
}
}
fn cursor_style(&self) -> CursorStyle {
match self {
Self::Insert => CursorStyle::Bar,
_ => CursorStyle::Block,
}
}
fn accepts_char_input(&self) -> bool {
matches!(self, Self::Insert)
}
}Required Methods§
Sourcefn module() -> ModuleIdwhere
Self: Sized,
fn module() -> ModuleIdwhere
Self: Sized,
The module that owns this mode type.
This is a type-level constant, not an instance method.
Sourcefn discriminant(&self) -> u16
fn discriminant(&self) -> u16
Get the unique discriminant for this mode variant.
For #[repr(u16)] enums, this is typically *self as u16.
Discriminants must be stable across versions for serialization.
Sourcefn display_name(&self) -> &'static str
fn display_name(&self) -> &'static str
Get the display name for this mode.
This is shown in the statusline (e.g., “NORMAL”, “INSERT”, “VISUAL”).
Sourcefn cursor_style(&self) -> CursorStyle
fn cursor_style(&self) -> CursorStyle
Get the cursor style for this mode.
Different modes typically use different cursor styles:
- Normal mode: Block cursor
- Insert mode: Bar cursor
- Replace mode: Underline cursor
Sourcefn accepts_char_input(&self) -> bool
fn accepts_char_input(&self) -> bool
Whether this mode accepts direct character input.
Returns true for modes like Insert, CommandLine, Replace.
Returns false for Normal, Visual, OperatorPending.
Provided Methods§
Sourcefn id(&self) -> ModeIdwhere
Self: Sized,
fn id(&self) -> ModeIdwhere
Self: Sized,
Convert to the runtime storage type.
Default implementation creates a ModeId from module, display_name,
and discriminant. Override only if custom behavior is needed.
Sourcefn has_selection(&self) -> bool
fn has_selection(&self) -> bool
Whether this mode has an active selection.
Returns true for Visual, Select modes.
Default is false.
Sourcefn inherits_from(&self) -> Option<Self>where
Self: Sized,
fn inherits_from(&self) -> Option<Self>where
Self: Sized,
Get the parent mode for keybinding inheritance.
For example, VisualLine might inherit from Visual, which inherits
from Normal. Returns None for root modes.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.