diff --git a/src/editor/command_line.rs b/src/editor/command_line.rs new file mode 100644 index 0000000..a57280e --- /dev/null +++ b/src/editor/command_line.rs @@ -0,0 +1,27 @@ +use crate::events::{GridLineCell, RedrawEvent, StyledContent}; + +pub struct CommandLine { + visible: bool, + prefix: String, + content: StyledContent, + cursor_position: u64, + special_char: (String, bool), + block: Vec +} + +impl CommandLine { + pub fn handle_command_events(&mut self, event: RedrawEvent) { + match event { + RedrawEvent::CommandLineShow { content, position, first_character, prompt, indent, level } => {}, + RedrawEvent::CommandLinePosition { position, level } => {}, + RedrawEvent::CommandLineSpecialCharacter { character, shift, level } => {}, + RedrawEvent::CommandLineHide => {}, + RedrawEvent::CommandLineBlockShow { lines } => {}, + RedrawEvent::CommandLineBlockAppend { line } => {}, + RedrawEvent::CommandLineBlockHide => {} + _ => {} + } + } + +// fn show() +} diff --git a/src/editor/mod.rs b/src/editor/mod.rs index a49597d..dc32160 100644 --- a/src/editor/mod.rs +++ b/src/editor/mod.rs @@ -5,6 +5,7 @@ use skulpin::winit::window::Window; mod cursor; mod style; +mod command_line; pub use cursor::{Cursor, CursorShape, CursorMode}; pub use style::{Colors, Style}; @@ -173,18 +174,6 @@ impl Editor { } } - fn resize(&mut self, new_size: (u64, u64)) { - self.size = new_size; - self.clear(); - } - - fn clear(&mut self) { - let (width, height) = self.size; - self.grid = vec![vec![None; width as usize]; height as usize]; - self.dirty = vec![vec![true; width as usize]; height as usize]; - self.should_clear = true; - } - fn scroll_region(&mut self, top: u64, bot: u64, left: u64, right: u64, rows: i64, cols: i64) { let (top, bot) = if rows > 0 { (top as i64 + rows, bot as i64) @@ -230,4 +219,16 @@ impl Editor { } } } + + fn resize(&mut self, new_size: (u64, u64)) { + self.size = new_size; + self.clear(); + } + + fn clear(&mut self) { + let (width, height) = self.size; + self.grid = vec![vec![None; width as usize]; height as usize]; + self.dirty = vec![vec![true; width as usize]; height as usize]; + self.should_clear = true; + } } diff --git a/src/events.rs b/src/events.rs index bdc3ac7..b8b8b30 100644 --- a/src/events.rs +++ b/src/events.rs @@ -45,6 +45,9 @@ pub struct GridLineCell { pub repeat: Option } +pub type StyledContent = Vec<(Style, String)>; + +#[derive(Debug)] pub enum MessageKind { Unknown, Confirm, @@ -96,13 +99,19 @@ pub enum RedrawEvent { 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: Vec<(Style, String)>, position: u64, first_character: String, prompt: String, indent: u64, level: u64 }, + 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: Vec<(Style, String)> }, - CommandLineBlockHide + 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 { @@ -169,7 +178,7 @@ fn parse_bool(bool_value: &Value) -> Result { fn parse_set_title(set_title_arguments: Vec) -> Result { if let [title] = set_title_arguments.as_slice() { Ok(RedrawEvent::SetTitle { - title: parse_string(&title)? + title: parse_string(title)? }) } else { Err(EventParseError::InvalidEventFormat) @@ -178,7 +187,7 @@ fn parse_set_title(set_title_arguments: Vec) -> Result { 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 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)?; @@ -336,20 +345,20 @@ fn parse_grid_scroll(grid_scroll_arguments: Vec) -> Result { } } -fn parse_commandline_chunks(line: &Value) -> Result> { +fn parse_styled_content(line: &Value) -> Result { parse_array(line)?.iter().map(|tuple| { if let [attributes, text] = parse_array(tuple)?.as_slice() { Ok((parse_style(attributes)?, parse_string(text)?)) } else { Err(EventParseError::InvalidEventFormat) } - }).collect::>>() + }).collect::>() } fn parse_cmdline_show(cmdline_show_arguments: Vec) -> Result { if let [content, position, first_character, prompt, indent, level] = cmdline_show_arguments.as_slice() { Ok(RedrawEvent::CommandLineShow { - content: parse_commandline_chunks(&content)?, + content: parse_styled_content(&content)?, position: parse_u64(&position)?, first_character: parse_string(&first_character)?, prompt: parse_string(&prompt)?, @@ -387,10 +396,10 @@ fn parse_cmdline_special_char(cmdline_special_char_arguments: Vec) -> Res fn parse_cmdline_block_show(cmdline_block_show_arguments: Vec) -> Result { if let [lines] = cmdline_block_show_arguments.as_slice() { Ok(RedrawEvent::CommandLineBlockShow { - lines: parse_array(&lines)? + lines: parse_array(lines)? .iter() - .map(parse_commandline_chunks) - .collect::>>>()? + .map(parse_styled_content) + .collect::>>()? }) } else { Err(EventParseError::InvalidEventFormat) @@ -400,7 +409,73 @@ fn parse_cmdline_block_show(cmdline_block_show_arguments: Vec) -> Result< fn parse_cmdline_block_append(cmdline_block_append_arguments: Vec) -> Result { if let [line] = cmdline_block_append_arguments.as_slice() { Ok(RedrawEvent::CommandLineBlockAppend { - line: parse_commandline_chunks(&line)? + line: parse_styled_content(line)? + }) + } else { + Err(EventParseError::InvalidEventFormat) + } +} + +fn parse_msg_show(msg_show_arguments: Vec) -> Result { + if let [kind, content, replace_last] = msg_show_arguments.as_slice() { + Ok(RedrawEvent::MessageShow { + kind: MessageKind::parse(&parse_string(&kind)?), + content: parse_styled_content(&content)?, + replace_last: parse_bool(&replace_last)? + }) + } else { + Err(EventParseError::InvalidEventFormat) + } +} + +fn parse_msg_showmode(msg_showmode_arguments: Vec) -> Result { + if let [content] = msg_showmode_arguments.as_slice() { + Ok(RedrawEvent::MessageShowMode { + content: parse_styled_content(&content)?, + }) + } else { + Err(EventParseError::InvalidEventFormat) + } +} + +fn parse_msg_showcmd(msg_showcmd_arguments: Vec) -> Result { + if let [content] = msg_showcmd_arguments.as_slice() { + Ok(RedrawEvent::MessageShowCommand { + content: parse_styled_content(&content)?, + }) + } else { + Err(EventParseError::InvalidEventFormat) + } +} + +fn parse_msg_ruler(msg_ruler_arguments: Vec) -> Result { + if let [content] = msg_ruler_arguments.as_slice() { + Ok(RedrawEvent::MessageRuler { + content: parse_styled_content(&content)?, + }) + } else { + Err(EventParseError::InvalidEventFormat) + } +} + +fn parse_msg_history_entry(entry: &Value) -> Result<(MessageKind, StyledContent)> { + if let [kind, content] = parse_array(entry)?.as_slice() { + Ok(( + MessageKind::parse(&parse_string(kind)?), + parse_styled_content(content)? + )) + } else { + Err(EventParseError::InvalidEventFormat) + } +} + +fn parse_msg_history_show(msg_history_show_arguments: Vec) -> Result { + if let [entries] = msg_history_show_arguments.as_slice() { + Ok(RedrawEvent::MessageHistoryShow { + entries: parse_array(entries)? + .iter() + .map(parse_msg_history_entry) + .collect::>>()? }) } else { Err(EventParseError::InvalidEventFormat) @@ -439,12 +514,12 @@ pub fn parse_redraw_event(event_value: Value) -> Result> { "cmdline_block_show" => Some(parse_cmdline_block_show(event_parameters)?), "cmdline_block_append" => Some(parse_cmdline_block_append(event_parameters)?), "cmdline_block_hide" => Some(RedrawEvent::CommandLineBlockHide), - // "msg_show" => Some(parse_msg_show(event_parameters)?), - // "msg_clear" => Some(parse_msg_clear(event_parameters)?), - // "msg_showmode" => Some(parse_msg_showmode(event_parameters)?), - // "msg_showcmd" => Some(parse_msg_showcmd(event_parameters)?), - // "msg_ruler" => Some(parse_msg_ruler(event_parameters)?), - // "msg_history_show" => Some(parse_msg_history_show(event_parameters)?), + "msg_show" => Some(parse_msg_show(event_parameters)?), + "msg_clear" => Some(RedrawEvent::MessageClear), + "msg_showmode" => Some(parse_msg_showmode(event_parameters)?), + "msg_showcmd" => Some(parse_msg_showcmd(event_parameters)?), + "msg_ruler" => Some(parse_msg_ruler(event_parameters)?), + "msg_history_show" => Some(parse_msg_history_show(event_parameters)?), _ => None };