diff --git a/src/events.rs b/src/bridge/events.rs similarity index 97% rename from src/events.rs rename to src/bridge/events.rs index 3710e1e..a515dad 100644 --- a/src/events.rs +++ b/src/bridge/events.rs @@ -1,600 +1,600 @@ -use std::error; -use std::fmt; - -use rmpv::Value; -use skulpin::skia_safe::Color4f; - -use crate::editor::{Colors, Style, CursorMode, CursorShape}; - -#[derive(Debug, Clone)] -pub enum EventParseError { - InvalidArray(Value), - InvalidMap(Value), - InvalidString(Value), - InvalidU64(Value), - InvalidI64(Value), - InvalidBool(Value), - InvalidEventFormat -} -type Result = std::result::Result; - -impl fmt::Display for EventParseError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - EventParseError::InvalidArray(value) => write!(f, "invalid array format {}", value), - EventParseError::InvalidMap(value) => write!(f, "invalid map format {}", value), - EventParseError::InvalidString(value) => write!(f, "invalid string format {}", value), - EventParseError::InvalidU64(value) => write!(f, "invalid u64 format {}", value), - EventParseError::InvalidI64(value) => write!(f, "invalid i64 format {}", value), - EventParseError::InvalidBool(value) => write!(f, "invalid bool format {}", value), - EventParseError::InvalidEventFormat => write!(f, "invalid event format") - } - } -} - -impl error::Error for EventParseError { - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - None - } -} - -#[derive(Debug)] -pub struct GridLineCell { - pub text: String, - pub highlight_id: Option, - pub repeat: Option -} - -pub type StyledContent = Vec<(u64, String)>; - -#[derive(Debug)] -pub enum MessageKind { - Unknown, - Confirm, - ConfirmSubstitute, - Error, - Echo, - EchoMessage, - EchoError, - LuaError, - RpcError, - ReturnPrompt, - QuickFix, - SearchCount, - Warning -} - -impl MessageKind { - pub fn parse(kind: &str) -> MessageKind { - match kind { - "confirm" => MessageKind::Confirm, - "confirm_sub" => MessageKind::ConfirmSubstitute, - "emsg" => MessageKind::Error, - "echo" => MessageKind::Echo, - "echomsg" => MessageKind::EchoMessage, - "echoerr" => MessageKind::EchoError, - "lua_error" => MessageKind::LuaError, - "rpc_error" => MessageKind::RpcError, - "return_prompt" => MessageKind::ReturnPrompt, - "quickfix" => MessageKind::QuickFix, - "search_count" => MessageKind::SearchCount, - "wmsg" => MessageKind::Warning, - _ => MessageKind::Unknown - } - } -} - -#[derive(Debug)] -pub enum GuiOption { - AribicShape(bool), - AmbiWidth(String), - Emoji(bool), - GuiFont(String), - GuiFontSet(String), - GuiFontWide(String), - LineSpace(u64), - Pumblend(u64), - ShowTabLine(u64), - TermGuiColors(bool), - Unknown(String, Value) -} - -#[derive(Debug)] -pub enum RedrawEvent { - SetTitle { title: String }, - ModeInfoSet { cursor_modes: Vec }, - OptionSet { gui_option: GuiOption }, - ModeChange { mode_index: u64 }, - BusyStart, - BusyStop, - Flush, - Resize { grid: u64, width: u64, height: u64 }, - DefaultColorsSet { colors: Colors }, - HighlightAttributesDefine { id: u64, style: Style }, - GridLine { grid: u64, row: u64, column_start: u64, cells: Vec }, - Clear { grid: u64 }, - CursorGoto { grid: u64, row: u64, column: u64 }, - Scroll { grid: u64, top: u64, bottom: u64, left: u64, right: u64, rows: i64, columns: i64 }, - CommandLineShow { content: StyledContent, position: u64, first_character: String, prompt: String, indent: u64, level: u64 }, - CommandLinePosition { position: u64, level: u64 }, - CommandLineSpecialCharacter { character: String, shift: bool, level: u64 }, - CommandLineHide, - CommandLineBlockShow { lines: Vec }, - CommandLineBlockAppend { line: StyledContent }, - CommandLineBlockHide, - MessageShow { kind: MessageKind, content: StyledContent, replace_last: bool }, - MessageClear, - MessageShowMode { content: StyledContent }, - MessageShowCommand { content: StyledContent }, - MessageRuler { content: StyledContent }, - MessageHistoryShow { entries: Vec<(MessageKind, StyledContent)>} -} - -fn unpack_color(packed_color: u64) -> Color4f { - let packed_color = packed_color as u32; - let r = ((packed_color & 0xff0000) >> 16) as f32; - let g = ((packed_color & 0xff00) >> 8) as f32; - let b = (packed_color & 0xff) as f32; - Color4f { - r: r / 255.0, - g: g / 255.0, - b: b / 255.0, - a: 1.0 - } -} - -fn parse_array(array_value: &Value) -> Result> { - if let Value::Array(content) = array_value.clone() { - Ok(content.to_vec()) - } else { - Err(EventParseError::InvalidArray(array_value.clone())) - } -} - -fn parse_map(map_value: &Value) -> Result> { - if let Value::Map(content) = map_value.clone() { - Ok(content) - } else { - Err(EventParseError::InvalidMap(map_value.clone())) - } -} - -fn parse_string(string_value: &Value) -> Result { - if let Value::String(content) = string_value.clone() { - Ok(content.into_str().ok_or(EventParseError::InvalidString(string_value.clone()))?) - } else { - Err(EventParseError::InvalidString(string_value.clone())) - } -} - -fn parse_u64(u64_value: &Value) -> Result { - if let Value::Integer(content) = u64_value.clone() { - Ok(content.as_u64().ok_or(EventParseError::InvalidU64(u64_value.clone()))?) - } else { - Err(EventParseError::InvalidU64(u64_value.clone())) - } -} - -fn parse_i64(i64_value: &Value) -> Result { - if let Value::Integer(content) = i64_value.clone() { - Ok(content.as_i64().ok_or(EventParseError::InvalidI64(i64_value.clone()))?) - } else { - Err(EventParseError::InvalidI64(i64_value.clone())) - } -} - -fn parse_bool(bool_value: &Value) -> Result { - if let Value::Boolean(content) = bool_value.clone() { - Ok(content) - } else { - Err(EventParseError::InvalidBool(bool_value.clone())) - } -} - -fn parse_set_title(set_title_arguments: Vec) -> Result { - if let [title] = set_title_arguments.as_slice() { - Ok(RedrawEvent::SetTitle { - title: parse_string(title)? - }) - } else { - Err(EventParseError::InvalidEventFormat) - } -} - -fn parse_mode_info_set(mode_info_set_arguments: Vec) -> Result { - if let [_cursor_style_enabled, mode_info] = mode_info_set_arguments.as_slice() { - let mode_info_values = parse_array(mode_info)?; - let mut cursor_modes = Vec::new(); - for mode_info_value in mode_info_values { - let info_map = parse_map(&mode_info_value)?; - let mut mode_info = CursorMode::new(); - for (name, value) in info_map { - let name = parse_string(&name)?; - match name.as_ref() { - "cursor_shape" => { - mode_info.shape = CursorShape::from_type_name(&parse_string(&value)?); - }, - "cell_percentage" => { - mode_info.cell_percentage = Some(parse_u64(&value)? as f32 / 100.0); - }, - "blinkwait" => { - mode_info.blinkwait = Some(parse_u64(&value)?); - }, - "blinkon" => { - mode_info.blinkon = Some(parse_u64(&value)?); - }, - "blinkoff" => { - mode_info.blinkoff = Some(parse_u64(&value)?); - } - "attr_id" => { - mode_info.style_id = Some(parse_u64(&value)?); - }, - _ => {} - } - } - cursor_modes.push(mode_info); - } - Ok(RedrawEvent::ModeInfoSet { - cursor_modes - }) - } else { - Err(EventParseError::InvalidEventFormat) - } -} - -fn parse_option_set(option_set_arguments: Vec) -> Result { - if let [name, value] = option_set_arguments.as_slice() { - Ok(RedrawEvent::OptionSet { - gui_option: match parse_string(&name)?.as_ref() { - "arabicshape" => GuiOption::AribicShape(parse_bool(&value)?), - "ambiwidth" => GuiOption::AmbiWidth(parse_string(&value)?), - "emoji" => GuiOption::Emoji(parse_bool(&value)?), - "guifont" => GuiOption::GuiFont(parse_string(&value)?), - "guifontset" => GuiOption::GuiFontSet(parse_string(&value)?), - "guifontwide" => GuiOption::GuiFontWide(parse_string(&value)?), - "linespace" => GuiOption::LineSpace(parse_u64(&value)?), - "pumblend" => GuiOption::Pumblend(parse_u64(&value)?), - "showtabline" => GuiOption::ShowTabLine(parse_u64(&value)?), - "termguicolors" => GuiOption::TermGuiColors(parse_bool(&value)?), - unknown_option => GuiOption::Unknown(unknown_option.to_string(), value.clone()) - } - }) - } else { - Err(EventParseError::InvalidEventFormat) - } -} - -fn parse_mode_change(mode_change_arguments: Vec) -> Result { - if let [_mode, mode_index] = mode_change_arguments.as_slice() { - Ok(RedrawEvent::ModeChange { - mode_index: parse_u64(&mode_index)? - }) - } else { - Err(EventParseError::InvalidEventFormat) - } -} - -fn parse_grid_resize(grid_resize_arguments: Vec) -> Result { - if let [grid_id, width, height] = grid_resize_arguments.as_slice() { - Ok(RedrawEvent::Resize { - grid: parse_u64(&grid_id)?, width: parse_u64(&width)?, height: parse_u64(&height)? - }) - } else { - Err(EventParseError::InvalidEventFormat) - } -} - -fn parse_default_colors(default_colors_arguments: Vec) -> Result { - if let [ - foreground, background, special, _term_foreground, _term_background - ] = default_colors_arguments.as_slice() { - Ok(RedrawEvent::DefaultColorsSet { - colors: Colors { - foreground: Some(unpack_color(parse_u64(&foreground)?)), - background: Some(unpack_color(parse_u64(&background)?)), - special: Some(unpack_color(parse_u64(special)?)), - } - }) - } else { - Err(EventParseError::InvalidEventFormat) - } -} - -fn parse_style(style_map: &Value) -> Result