use std::sync::Arc;
use crate::{
AnnotationContext, BufferId, BufferUpdateEvent, ChromePosition, ClientModuleError, ColumnWidth,
GutterCell, Insets, OptionValue, ProbeResult, Rect, RenderBehavior, RenderingModel, Style,
SyntaxToken, TransformedLine, Version, ViewportContext, VirtualLine, WindowId, WindowLayout,
types::{Color, ColorDepth, InlineDecoration},
};
#[allow(unused_variables)]
pub trait ClientModule: Send + Sync + 'static {
fn id(&self) -> &'static str;
fn kind(&self) -> &'static str {
self.id()
}
fn name(&self) -> &'static str;
fn version(&self) -> Version;
fn dependencies(&self) -> &[&str] {
&[]
}
fn optional_dependencies(&self) -> &[&str] {
&[]
}
fn server_kinds(&self) -> Vec<&'static str> {
vec![self.kind()]
}
fn init(&mut self, ctx: &ModuleContext) -> ProbeResult;
fn exit(&mut self) -> Result<(), ClientModuleError>;
fn on_all_loaded(&mut self, ctx: &ModuleContext) {}
fn has_chrome(&self) -> bool {
false
}
fn has_buffer_contrib(&self) -> bool {
false
}
fn has_annotations(&self) -> bool {
false
}
fn on_notification(&mut self, data: &str) {}
fn on_option_changed(&mut self, name: &str, value: &OptionValue) {}
fn on_buffer_update(&mut self, event: &BufferUpdateEvent) {}
fn on_cursor_update(&mut self, buffer_id: BufferId, line: usize, col: usize) {}
fn on_buffer_focus(&mut self, buffer_id: BufferId) {}
fn on_mode_change(&mut self, mode: &str) {}
fn on_capabilities_changed(&mut self, caps: &dyn PlatformCapabilities) {}
fn on_theme_changed(&mut self, theme: &dyn ThemeProvider) {}
fn tick(&mut self) -> bool {
false
}
fn chrome_position(&self) -> ChromePosition {
ChromePosition::Bottom
}
fn chrome_requested_size(&self, caps: &dyn PlatformCapabilities) -> u16 {
1
}
fn chrome_priority(&self) -> u16 {
0
}
fn chrome_z_order(&self) -> u16 {
0
}
#[cfg_attr(coverage_nightly, coverage(off))]
fn chrome_render(
&self,
surface: &mut dyn RenderSurface,
bounds: Rect,
caps: &dyn PlatformCapabilities,
) {
}
fn buffer_contrib_priority(&self) -> u16 {
0
}
fn classify_token(&self, category: &str) -> Option<RenderBehavior> {
None
}
fn transform_line(&self, buf: BufferId, line: usize, text: &str) -> Option<TransformedLine> {
None
}
fn map_cursor_column(&self, buf: BufferId, line: usize, col: usize) -> Option<u16> {
None
}
fn fold_ranges(&self) -> &[(usize, usize)] {
&[]
}
fn virtual_lines(&self) -> &[VirtualLine] {
&[]
}
fn inline_decorations(&self, line: usize) -> &[InlineDecoration] {
&[]
}
fn cursor_position(&self, w: u16, h: u16) -> Option<(u16, u16)> {
None
}
fn annotation_column_width(
&self,
ctx: &AnnotationContext,
caps: &dyn PlatformCapabilities,
) -> ColumnWidth {
ColumnWidth::Fixed(0)
}
fn annotate(&self, line: usize, ctx: &AnnotationContext) -> Option<GutterCell> {
None
}
fn annotation_priority(&self) -> u16 {
0
}
}
pub struct ModuleContext<'a> {
pub capabilities: &'a dyn PlatformCapabilities,
pub server: Arc<dyn ServerHandle>,
pub theme: &'a dyn ThemeProvider,
pub services: Option<&'a crate::services::ClientServiceRegistry>,
pub module_registry: Option<&'a dyn ClientModuleRegistry>,
}
pub trait ClientModuleRegistry: Send + Sync {
fn is_running(&self, kind: &str) -> bool;
fn module_state(&self, kind: &str) -> Option<crate::loader::ClientModuleState>;
fn loaded_kinds(&self) -> Vec<String>;
fn running_count(&self) -> usize;
}
#[allow(unused_variables)]
pub trait PlatformCapabilities: Send + Sync {
fn rendering_model(&self) -> RenderingModel;
fn grid_size(&self) -> Option<(u16, u16)>;
fn color_depth(&self) -> ColorDepth;
fn pixel_size(&self) -> Option<(u32, u32)>;
fn reliable_unicode_width(&self) -> bool;
fn dark_mode(&self) -> bool;
fn smooth_scroll(&self) -> bool;
fn pointer_events(&self) -> bool;
fn touch_input(&self) -> bool;
fn haptic(&self) -> bool;
fn safe_area(&self) -> Insets;
fn has_focus(&self) -> bool;
fn clipboard_available(&self) -> bool;
fn screen_reader_active(&self) -> bool;
}
pub trait RenderSurface {
fn write_styled(&mut self, x: u16, y: u16, text: &str, style: Style) -> u16;
fn apply_style(&mut self, x: u16, y: u16, style: Style);
fn overlay_bg(&mut self, x: u16, y: u16, bg: Color);
fn fill(&mut self, rect: Rect, ch: char, style: Style);
fn clear(&mut self, rect: Rect);
fn size(&self) -> (u16, u16);
}
#[allow(unused_variables)]
pub trait ServerHandle: Send + Sync {
fn get_options(&self, names: &[&str]) -> Vec<(String, OptionValue)>;
fn execute_command(&self, command: &str);
#[cfg_attr(coverage_nightly, coverage(off))]
fn list_commands(&self) -> Vec<String> {
Vec::new()
}
#[cfg_attr(coverage_nightly, coverage(off))]
fn get_option_metadata(&self, name: &str) -> Option<crate::OptionMetadata> {
None
}
}
pub trait ThemeProvider: Send + Sync {
fn highlight(&self, group: &str) -> Style;
fn highlight_with_fallback(&self, groups: &[&str]) -> Style;
fn foreground(&self) -> Style;
fn background(&self) -> Style;
fn is_dark(&self) -> bool;
}
pub trait TokenProvider: Send + Sync {
fn tokens_for_line(&self, buffer_id: BufferId, line: u32) -> Vec<SyntaxToken>;
}
pub trait ViewportRenderer: Send + Sync {
fn gutter_width(
&self,
modules: &[Box<dyn ClientModule>],
caps: &dyn PlatformCapabilities,
) -> u16;
#[allow(clippy::too_many_arguments)]
fn render_viewport(
&self,
surface: &mut dyn RenderSurface,
viewport: Rect,
ctx: &ViewportContext<'_>,
modules: &[Box<dyn ClientModule>],
tokens: &dyn TokenProvider,
theme: &dyn ThemeProvider,
caps: &dyn PlatformCapabilities,
);
}
pub trait LayoutPolicy: Send + Sync {
fn layout(&self, viewport: Rect, windows: &[WindowId], focused: WindowId) -> Vec<WindowLayout>;
}
#[cfg(test)]
mod tests;