From fb622c841f99da72d91d1325eceb012de8693f5b Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Tue, 30 Mar 2021 20:03:46 +0200 Subject: [PATCH] refactoring --- editor/src/editor/code_lines.rs | 9 - editor/src/editor/grid_node_map.rs | 35 ---- editor/src/editor/mvc/ed_update.rs | 225 ++++--------------------- editor/src/editor/mvc/mod.rs | 1 + editor/src/editor/mvc/record_update.rs | 104 +++++++++--- editor/src/editor/mvc/string_update.rs | 160 ++++++++++++++++++ 6 files changed, 272 insertions(+), 262 deletions(-) create mode 100644 editor/src/editor/mvc/string_update.rs diff --git a/editor/src/editor/code_lines.rs b/editor/src/editor/code_lines.rs index 8ffbf4c865..d281c81cdd 100644 --- a/editor/src/editor/code_lines.rs +++ b/editor/src/editor/code_lines.rs @@ -19,15 +19,6 @@ impl CodeLines { } } - pub fn add_to_line(&mut self, line_nr: usize, new_str: &str) -> UIResult<()> { - let line_ref = slice_get_mut(line_nr, &mut self.lines)?; - line_ref.push_str(new_str); - - self.nr_of_chars += new_str.len(); - - Ok(()) - } - pub fn insert_between_line( &mut self, line_nr: usize, diff --git a/editor/src/editor/grid_node_map.rs b/editor/src/editor/grid_node_map.rs index 145622f091..9dda436ec4 100644 --- a/editor/src/editor/grid_node_map.rs +++ b/editor/src/editor/grid_node_map.rs @@ -1,4 +1,3 @@ -use crate::editor::code_lines::CodeLines; use crate::editor::ed_error::EdResult; use crate::editor::slow_pool::MarkNodeId; use crate::editor::util::index_of; @@ -73,37 +72,3 @@ impl GridNodeMap { Ok(caret_pos.column - first_node_index) } } - -// perform updates for both GridNodeMap and CodeLines -pub fn add_to_line_both( - grid_node_map: &mut GridNodeMap, - code_lines: &mut CodeLines, - line_nr: usize, - new_str: &str, - node_id: MarkNodeId, -) -> UIResult<()> { - grid_node_map.add_to_line(line_nr, new_str.len(), node_id)?; - code_lines.add_to_line(line_nr, new_str) -} - -pub fn insert_between_line_both( - grid_node_map: &mut GridNodeMap, - code_lines: &mut CodeLines, - line_nr: usize, - index: usize, - new_str: &str, - node_id: MarkNodeId, -) -> UIResult<()> { - grid_node_map.insert_between_line(line_nr, index, new_str.len(), node_id)?; - code_lines.insert_between_line(line_nr, index, new_str) -} - -pub fn del_at_line_both( - grid_node_map: &mut GridNodeMap, - code_lines: &mut CodeLines, - line_nr: usize, - index: usize, -) -> UIResult<()> { - grid_node_map.del_at_line(line_nr, index)?; - code_lines.del_at_line(line_nr, index) -} diff --git a/editor/src/editor/mvc/ed_update.rs b/editor/src/editor/mvc/ed_update.rs index 59a8980dff..bf29c0a2c2 100644 --- a/editor/src/editor/mvc/ed_update.rs +++ b/editor/src/editor/mvc/ed_update.rs @@ -1,23 +1,20 @@ -use crate::editor::ed_error::MissingParent; -use crate::lang::ast::ArrString; -use crate::editor::grid_node_map::del_at_line_both; use crate::editor::code_lines::CodeLines; use crate::editor::ed_error::EdResult; -use crate::editor::grid_node_map::insert_between_line_both; use crate::editor::grid_node_map::GridNodeMap; -use crate::editor::markup::attribute::Attributes; use crate::editor::markup::nodes; use crate::editor::markup::nodes::MarkupNode; use crate::editor::mvc::ed_model::EdModel; use crate::editor::mvc::record_update::start_new_record; +use crate::editor::mvc::record_update::update_new_record; use crate::editor::mvc::record_update::update_record_colon; use crate::editor::mvc::record_update::update_record_field; +use crate::editor::mvc::string_update::start_new_string; +use crate::editor::mvc::string_update::update_small_string; +use crate::editor::mvc::string_update::update_string; use crate::editor::slow_pool::MarkNodeId; use crate::editor::slow_pool::SlowPool; -use crate::editor::syntax_highlight::HighlightStyle; -use crate::editor::util::index_of; use crate::lang::ast::Expr2; -use crate::lang::pool::{NodeId, PoolStr, PoolVec}; +use crate::lang::pool::NodeId; use crate::ui::text::caret_w_select::CaretWSelect; use crate::ui::text::lines::MoveCaretFun; use crate::ui::text::selection::validate_raw_sel; @@ -119,6 +116,25 @@ impl<'a> EdModel<'a> { Ok(()) } + + // updates grid_node_map and code_lines but nothing else. + pub fn insert_between_line( + &mut self, + line_nr: usize, + index: usize, + new_str: &str, + node_id: MarkNodeId, + ) -> UIResult<()> { + self.grid_node_map + .insert_between_line(line_nr, index, new_str.len(), node_id)?; + self.code_lines.insert_between_line(line_nr, index, new_str) + } + + // updates grid_node_map and code_lines but nothing else. + pub fn del_at_line(&mut self, line_nr: usize, index: usize) -> UIResult<()> { + self.grid_node_map.del_at_line(line_nr, index)?; + self.code_lines.del_at_line(line_nr, index) + } } impl<'a> SelectableLines for EdModel<'a> { @@ -312,51 +328,8 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult update_record_colon(ed_model)?; } '"' => { - let old_caret_pos = ed_model.get_caret(); - let curr_mark_node_id = ed_model.grid_node_map.get_id_at_row_col(old_caret_pos)?; - let curr_mark_node = ed_model.markup_node_pool.get(curr_mark_node_id); - let parent_id_opt = curr_mark_node.get_parent_id_opt(); - let ast_node_id = curr_mark_node.get_ast_node_id(); - - if curr_mark_node.is_blank() { - let new_expr2_node = - Expr2::SmallStr( - arraystring::ArrayString::new() - ); - - ed_model.module.env.pool.set(ast_node_id, new_expr2_node); - - let new_string_node = MarkupNode::Text { - content: nodes::STRING_QUOTES.to_owned(), - ast_node_id, - syn_high_style: HighlightStyle::String, - attributes: Attributes::new(), - parent_id_opt, - }; - - ed_model.markup_node_pool.replace_node(curr_mark_node_id, new_string_node); - - // remove data corresponding to Blank node - del_at_line_both( - &mut ed_model.grid_node_map, - &mut ed_model.code_lines, - old_caret_pos.line, - old_caret_pos.column, - )?; - - // update GridNodeMap and CodeLines - insert_between_line_both( - &mut ed_model.grid_node_map, - &mut ed_model.code_lines, - old_caret_pos.line, - old_caret_pos.column, - nodes::STRING_QUOTES, - curr_mark_node_id, - )?; - - ed_model.simple_move_carets_right(); - } + start_new_string(ed_model)?; } '\u{8}' | '\u{7f}' => { // On Linux, '\u{8}' is backspace, @@ -397,84 +370,18 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult None }; - let prev_mark_node_opt = prev_mark_node_id_opt.map( - |prev_mark_node_id| ed_model.markup_node_pool.get(prev_mark_node_id) - ); - - let parent_id_opt = curr_mark_node.get_parent_id_opt(); let ast_node_id = curr_mark_node.get_ast_node_id(); - let sibling_ids = curr_mark_node.get_sibling_ids(&ed_model.markup_node_pool); + let ast_node_ref = ed_model.module.env.pool.get(ast_node_id); match ast_node_ref { Expr2::EmptyRecord => { - if let Some(prev_mark_node) = prev_mark_node_opt { - if prev_mark_node.get_content()? == nodes::LEFT_ACCOLADE { - // update Markup - let record_field_str = &ch.to_string(); - let record_field_node = MarkupNode::Text { - content: record_field_str.to_owned(), - ast_node_id, - syn_high_style: HighlightStyle::RecordField, - attributes: Attributes::new(), - parent_id_opt, - }; + let sibling_ids = curr_mark_node.get_sibling_ids(&ed_model.markup_node_pool); - let record_field_node_id = ed_model.markup_node_pool.add(record_field_node); - - if let Some(parent_id) = parent_id_opt { - let parent = ed_model.markup_node_pool.get_mut(parent_id); - - let new_child_index = index_of(curr_mark_node_id, &sibling_ids)?; - - parent.add_child_at_index(new_child_index, record_field_node_id)?; - } else { - MissingParent { - node_id: curr_mark_node_id - }.fail()? - } - - // update caret - ed_model.simple_move_carets_right(); - - // update GridNodeMap and CodeLines - insert_between_line_both( - &mut ed_model.grid_node_map, - &mut ed_model.code_lines, - old_caret_pos.line, - old_caret_pos.column, - record_field_str, - record_field_node_id, - )?; - - // update AST - let record_var = ed_model.module.env.var_store.fresh(); - let field_name = PoolStr::new(record_field_str, &mut ed_model.module.env.pool); - let field_var = ed_model.module.env.var_store.fresh(); - //TODO actually check if field_str belongs to a previously defined variable - let field_val = Expr2::InvalidLookup( - PoolStr::new(record_field_str, ed_model.module.env.pool) - ); - let field_val_id = ed_model.module.env.pool.add(field_val); - let first_field = (field_name, field_var, field_val_id); - - let fields = PoolVec::new( - vec![first_field].into_iter(), - &mut ed_model.module.env.pool, - ); - - let new_ast_node = - Expr2::Record { - record_var, - fields, - }; - - ed_model.module.env.pool.set(ast_node_id, new_ast_node); - } - } + update_new_record(&ch.to_string(), prev_mark_node_id_opt, sibling_ids, ed_model)?; }, Expr2::Record { record_var:_, fields } => { if let Some(prev_mark_node_id) = prev_mark_node_id_opt { @@ -499,84 +406,12 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult } }, Expr2::SmallStr(array_str) => { - let new_input = &ch.to_string(); - // update markup - let curr_mark_node_mut = ed_model.markup_node_pool.get_mut(curr_mark_node_id); - let content_str_mut = curr_mark_node_mut.get_content_mut()?; - let node_caret_offset = ed_model - .grid_node_map - .get_offset_to_node_id(old_caret_pos, curr_mark_node_id)?; - content_str_mut.insert_str(node_caret_offset, new_input); - - // update GridNodeMap and CodeLines - insert_between_line_both( - &mut ed_model.grid_node_map, - &mut ed_model.code_lines, - old_caret_pos.line, - old_caret_pos.column, - new_input, - curr_mark_node_id, - )?; - - // update ast - let ch_size = std::mem::size_of::(); - - if (ch_size as u8) + array_str.len() <= ArrString::capacity() { - if let Expr2::SmallStr(ref mut mut_array_str) = ed_model.module.env.pool.get_mut(ast_node_id) { - // safe because we checked the length - unsafe { - mut_array_str.push_unchecked(*ch); - } - } else { - unreachable!() - } - } else { - let mut new_str = array_str.as_str().to_owned(); - new_str.push(*ch); - - let new_ast_node = Expr2::Str(PoolStr::new(&new_str, ed_model.module.env.pool)); - - ed_model.module.env.pool.set(ast_node_id, new_ast_node); - } - - // update caret - for _ in 0..new_input.len() { - ed_model.simple_move_carets_right(); - } + update_small_string(ch, array_str, ed_model)?; }, Expr2::Str(old_pool_str) => { - let new_input = &ch.to_string(); - // update markup - let curr_mark_node_mut = ed_model.markup_node_pool.get_mut(curr_mark_node_id); - let content_str_mut = curr_mark_node_mut.get_content_mut()?; - let node_caret_offset = ed_model - .grid_node_map - .get_offset_to_node_id(old_caret_pos, curr_mark_node_id)?; - content_str_mut.insert_str(node_caret_offset, new_input); - - // update GridNodeMap and CodeLines - insert_between_line_both( - &mut ed_model.grid_node_map, - &mut ed_model.code_lines, - old_caret_pos.line, - old_caret_pos.column, - new_input, - curr_mark_node_id, - )?; - - // update ast - let mut new_string = old_pool_str.as_str(ed_model.module.env.pool).to_owned(); - new_string.push(*ch); - - let new_pool_str = PoolStr::new(&new_string, &mut ed_model.module.env.pool); - let new_ast_node = Expr2::Str(new_pool_str); - - ed_model.module.env.pool.set(ast_node_id, new_ast_node); - - // update caret - ed_model.simple_move_carets_right(); + update_string(&ch.to_string(), old_pool_str, ed_model)?; }, other => { unimplemented!("TODO implement updating of Expr2 {:?}.", other) diff --git a/editor/src/editor/mvc/mod.rs b/editor/src/editor/mvc/mod.rs index 672fcdb6cf..69ebe9974e 100644 --- a/editor/src/editor/mvc/mod.rs +++ b/editor/src/editor/mvc/mod.rs @@ -4,3 +4,4 @@ pub mod ed_model; pub mod ed_update; pub mod ed_view; mod record_update; +mod string_update; diff --git a/editor/src/editor/mvc/record_update.rs b/editor/src/editor/mvc/record_update.rs index e4cc2ba65a..00f240544b 100644 --- a/editor/src/editor/mvc/record_update.rs +++ b/editor/src/editor/mvc/record_update.rs @@ -1,8 +1,6 @@ use crate::editor::ed_error::EdResult; use crate::editor::ed_error::MissingParent; use crate::editor::ed_error::RecordWithoutFields; -use crate::editor::grid_node_map::del_at_line_both; -use crate::editor::grid_node_map::insert_between_line_both; use crate::editor::markup::attribute::Attributes; use crate::editor::markup::nodes; use crate::editor::markup::nodes::MarkupNode; @@ -68,30 +66,21 @@ pub fn start_new_record(ed_model: &mut EdModel) -> EdResult<()> { mark_node_pool.replace_node(curr_mark_node_id, nested_node); // remove data corresponding to Blank node - del_at_line_both( - &mut ed_model.grid_node_map, - &mut ed_model.code_lines, - old_caret_pos.line, - old_caret_pos.column, - )?; + ed_model.del_at_line(old_caret_pos.line, old_caret_pos.column)?; for _ in 0..nodes::LEFT_ACCOLADE.len() { ed_model.simple_move_carets_right(); } // update GridNodeMap and CodeLines - insert_between_line_both( - &mut ed_model.grid_node_map, - &mut ed_model.code_lines, + ed_model.insert_between_line( old_caret_pos.line, old_caret_pos.column, nodes::LEFT_ACCOLADE, left_bracket_node_id, )?; - insert_between_line_both( - &mut ed_model.grid_node_map, - &mut ed_model.code_lines, + ed_model.insert_between_line( old_caret_pos.line, old_caret_pos.column + nodes::LEFT_ACCOLADE.len(), nodes::RIGHT_ACCOLADE, @@ -102,6 +91,81 @@ pub fn start_new_record(ed_model: &mut EdModel) -> EdResult<()> { Ok(()) } +pub fn update_new_record( + new_input: &str, + prev_mark_node_id_opt: Option, + sibling_ids: Vec, + ed_model: &mut EdModel, +) -> EdResult<()> { + let prev_mark_node_opt = prev_mark_node_id_opt + .map(|prev_mark_node_id| ed_model.markup_node_pool.get(prev_mark_node_id)); + + if let Some(prev_mark_node) = prev_mark_node_opt { + let NodeContext { + old_caret_pos, + curr_mark_node_id, + curr_mark_node: _, + parent_id_opt, + ast_node_id, + } = get_node_context(&ed_model)?; + + if prev_mark_node.get_content()? == nodes::LEFT_ACCOLADE { + // update Markup + + let record_field_node = MarkupNode::Text { + content: new_input.to_owned(), + ast_node_id, + syn_high_style: HighlightStyle::RecordField, + attributes: Attributes::new(), + parent_id_opt, + }; + + let record_field_node_id = ed_model.markup_node_pool.add(record_field_node); + + if let Some(parent_id) = parent_id_opt { + let parent = ed_model.markup_node_pool.get_mut(parent_id); + + let new_child_index = index_of(curr_mark_node_id, &sibling_ids)?; + + parent.add_child_at_index(new_child_index, record_field_node_id)?; + } else { + MissingParent { + node_id: curr_mark_node_id, + } + .fail()? + } + + // update caret + ed_model.simple_move_carets_right(); + + // update GridNodeMap and CodeLines + ed_model.insert_between_line( + old_caret_pos.line, + old_caret_pos.column, + new_input, + record_field_node_id, + )?; + + // update AST + let record_var = ed_model.module.env.var_store.fresh(); + let field_name = PoolStr::new(new_input, &mut ed_model.module.env.pool); + let field_var = ed_model.module.env.var_store.fresh(); + //TODO actually check if field_str belongs to a previously defined variable + let field_val = Expr2::InvalidLookup(PoolStr::new(new_input, ed_model.module.env.pool)); + let field_val_id = ed_model.module.env.pool.add(field_val); + let first_field = (field_name, field_var, field_val_id); + + let fields = PoolVec::new(vec![first_field].into_iter(), &mut ed_model.module.env.pool); + + let new_ast_node = Expr2::Record { record_var, fields }; + + ed_model.module.env.pool.set(ast_node_id, new_ast_node); + } + } + + Ok(()) +} + pub fn update_record_field( new_input: &str, old_caret_pos: TextPos, @@ -123,9 +187,7 @@ pub fn update_record_field( } // update GridNodeMap and CodeLines - insert_between_line_both( - &mut ed_model.grid_node_map, - &mut ed_model.code_lines, + ed_model.insert_between_line( old_caret_pos.line, old_caret_pos.column, new_input, @@ -213,18 +275,14 @@ pub fn update_record_colon(ed_model: &mut EdModel) -> EdResult<()> { } // update GridNodeMap and CodeLines - insert_between_line_both( - &mut ed_model.grid_node_map, - &mut ed_model.code_lines, + ed_model.insert_between_line( old_caret_pos.line, old_caret_pos.column, nodes::COLON, record_colon_node_id, )?; - insert_between_line_both( - &mut ed_model.grid_node_map, - &mut ed_model.code_lines, + ed_model.insert_between_line( old_caret_pos.line, old_caret_pos.column + nodes::COLON.len(), nodes::BLANK_PLACEHOLDER, diff --git a/editor/src/editor/mvc/string_update.rs b/editor/src/editor/mvc/string_update.rs new file mode 100644 index 0000000000..77d412838e --- /dev/null +++ b/editor/src/editor/mvc/string_update.rs @@ -0,0 +1,160 @@ +use crate::editor::ed_error::EdResult; +use crate::editor::markup::attribute::Attributes; +use crate::editor::markup::nodes; +use crate::editor::markup::nodes::MarkupNode; +use crate::editor::mvc::ed_model::EdModel; +use crate::editor::mvc::ed_update::get_node_context; +use crate::editor::mvc::ed_update::NodeContext; +use crate::editor::syntax_highlight::HighlightStyle; +use crate::lang::ast::ArrString; +use crate::lang::ast::Expr2; +use crate::lang::pool::PoolStr; + +pub fn update_small_string( + new_char: &char, + old_array_str: &ArrString, + ed_model: &mut EdModel, +) -> EdResult<()> { + let NodeContext { + old_caret_pos, + curr_mark_node_id, + curr_mark_node: _, + parent_id_opt: _, + ast_node_id, + } = get_node_context(&ed_model)?; + + let new_input = &new_char.to_string(); + + // update markup + let curr_mark_node_mut = ed_model.markup_node_pool.get_mut(curr_mark_node_id); + let content_str_mut = curr_mark_node_mut.get_content_mut()?; + let node_caret_offset = ed_model + .grid_node_map + .get_offset_to_node_id(old_caret_pos, curr_mark_node_id)?; + content_str_mut.insert_str(node_caret_offset, new_input); + + // update GridNodeMap and CodeLines + ed_model.insert_between_line( + old_caret_pos.line, + old_caret_pos.column, + new_input, + curr_mark_node_id, + )?; + + // update ast + let ch_size = std::mem::size_of::(); + + if (ch_size as u8) + old_array_str.len() <= ArrString::capacity() { + if let Expr2::SmallStr(ref mut mut_array_str) = + ed_model.module.env.pool.get_mut(ast_node_id) + { + // safe because we checked the length + unsafe { + mut_array_str.push_unchecked(*new_char); + } + } else { + unreachable!() + } + } else { + let mut new_str = old_array_str.as_str().to_owned(); + new_str.push(*new_char); + + let new_ast_node = Expr2::Str(PoolStr::new(&new_str, ed_model.module.env.pool)); + + ed_model.module.env.pool.set(ast_node_id, new_ast_node); + } + + // update caret + for _ in 0..new_input.len() { + ed_model.simple_move_carets_right(); + } + + Ok(()) +} + +pub fn update_string( + new_input: &str, + old_pool_str: &PoolStr, + ed_model: &mut EdModel, +) -> EdResult<()> { + let NodeContext { + old_caret_pos, + curr_mark_node_id, + curr_mark_node: _, + parent_id_opt: _, + ast_node_id, + } = get_node_context(&ed_model)?; + + // update markup + let curr_mark_node_mut = ed_model.markup_node_pool.get_mut(curr_mark_node_id); + let content_str_mut = curr_mark_node_mut.get_content_mut()?; + let node_caret_offset = ed_model + .grid_node_map + .get_offset_to_node_id(old_caret_pos, curr_mark_node_id)?; + content_str_mut.insert_str(node_caret_offset, new_input); + + // update GridNodeMap and CodeLines + ed_model.insert_between_line( + old_caret_pos.line, + old_caret_pos.column, + new_input, + curr_mark_node_id, + )?; + + // update ast + let mut new_string = old_pool_str.as_str(ed_model.module.env.pool).to_owned(); + new_string.push_str(new_input); + + let new_pool_str = PoolStr::new(&new_string, &mut ed_model.module.env.pool); + let new_ast_node = Expr2::Str(new_pool_str); + + ed_model.module.env.pool.set(ast_node_id, new_ast_node); + + // update caret + ed_model.simple_move_carets_right(); + + Ok(()) +} + +pub fn start_new_string(ed_model: &mut EdModel) -> EdResult<()> { + let NodeContext { + old_caret_pos, + curr_mark_node_id, + curr_mark_node, + parent_id_opt, + ast_node_id, + } = get_node_context(&ed_model)?; + + if curr_mark_node.is_blank() { + let new_expr2_node = Expr2::SmallStr(arraystring::ArrayString::new()); + + ed_model.module.env.pool.set(ast_node_id, new_expr2_node); + + let new_string_node = MarkupNode::Text { + content: nodes::STRING_QUOTES.to_owned(), + ast_node_id, + syn_high_style: HighlightStyle::String, + attributes: Attributes::new(), + parent_id_opt, + }; + + ed_model + .markup_node_pool + .replace_node(curr_mark_node_id, new_string_node); + + // remove data corresponding to Blank node + ed_model.del_at_line(old_caret_pos.line, old_caret_pos.column)?; + + // update GridNodeMap and CodeLines + ed_model.insert_between_line( + old_caret_pos.line, + old_caret_pos.column, + nodes::STRING_QUOTES, + curr_mark_node_id, + )?; + + ed_model.simple_move_carets_right(); + } + + Ok(()) +}