diff --git a/src/engine/doc.rs b/src/engine/doc.rs index b7df195..4dc893b 100644 --- a/src/engine/doc.rs +++ b/src/engine/doc.rs @@ -46,9 +46,9 @@ pub struct Doc { } impl Doc { - pub fn new(node: Node, s: &Storage) -> Self { + pub fn new(s: &Storage, node: Node) -> Self { Doc { - cursor: Location::before(node, s), + cursor: Location::before(s, node), recent: None, undo_stack: Vec::new(), redo_stack: Vec::new(), @@ -65,8 +65,8 @@ impl Doc { } /// Move the cursor to the bookmark's location, if it's in this document. - pub fn goto_bookmark(&mut self, bookmark: Bookmark, s: &Storage) -> Result<(), DocError> { - if let Some(new_loc) = self.cursor.validate_bookmark(bookmark, s) { + pub fn goto_bookmark(&mut self, s: &Storage, bookmark: Bookmark) -> Result<(), DocError> { + if let Some(new_loc) = self.cursor.validate_bookmark(s, bookmark) { self.cursor = new_loc; Ok(()) } else { @@ -76,12 +76,12 @@ impl Doc { /// Executes a single command. Clears the redo stack if it was an editing command (but not if /// it was a navigation command). - pub fn execute(&mut self, cmd: DocCommand, s: &mut Storage) -> Result<(), DocError> { + pub fn execute(&mut self, s: &mut Storage, cmd: DocCommand) -> Result<(), DocError> { match cmd { DocCommand::Ed(cmd) => { self.redo_stack.clear(); let restore_loc = self.cursor; - let undos = execute_ed(cmd, &mut self.cursor, s)?; + let undos = execute_ed(s, cmd, &mut self.cursor)?; if let Some(recent) = &mut self.recent { recent.commands.extend(undos); } else { @@ -89,7 +89,7 @@ impl Doc { } Ok(()) } - DocCommand::Nav(cmd) => execute_nav(cmd, &mut self.cursor, s), + DocCommand::Nav(cmd) => execute_nav(s, cmd, &mut self.cursor), } } @@ -110,7 +110,7 @@ impl Doc { self.end_undo_group(); if let Some(undo_group) = self.undo_stack.pop() { - let redo_group = undo_group.execute(&mut self.cursor, s); + let redo_group = undo_group.execute(s, &mut self.cursor); self.redo_stack.push(redo_group); Ok(()) } else { @@ -126,7 +126,7 @@ impl Doc { self.recent.is_none(), "redo: recent edits should have cleared the redo stack" ); - let undo_group = redo_group.execute(&mut self.cursor, s); + let undo_group = redo_group.execute(s, &mut self.cursor); self.undo_stack.push(undo_group); Ok(()) } else { @@ -144,52 +144,52 @@ impl UndoGroup { } } - fn execute(self, cursor: &mut Location, s: &mut Storage) -> UndoGroup { + fn execute(self, s: &mut Storage, cursor: &mut Location) -> UndoGroup { let mut redo_restore_loc = None; let mut redos = Vec::new(); for (loc, cmd) in self.commands.into_iter().rev() { if redo_restore_loc.is_none() { redo_restore_loc = Some(loc); } - jump_to(cursor, loc, s); - redos.extend(execute_ed(cmd, cursor, s).bug_msg("Failed to undo/redo")); + jump_to(s, cursor, loc); + redos.extend(execute_ed(s, cmd, cursor).bug_msg("Failed to undo/redo")); } - jump_to(cursor, self.restore_loc, s); + jump_to(s, cursor, self.restore_loc); UndoGroup::new(redo_restore_loc.bug(), redos) } } -fn jump_to(cursor: &mut Location, loc: Location, s: &Storage) { +fn jump_to(s: &Storage, cursor: &mut Location, loc: Location) { bug_assert!( - cursor.validate_bookmark(loc.bookmark(), s).is_some(), + cursor.validate_bookmark(s, loc.bookmark()).is_some(), "invalid loc" ); *cursor = loc; } fn execute_ed( + s: &mut Storage, cmd: EdCommand, cursor: &mut Location, - s: &mut Storage, ) -> Result, DocError> { match cmd { - EdCommand::Tree(cmd) => execute_tree_ed(cmd, cursor, s), - EdCommand::Text(cmd) => execute_text_ed(cmd, cursor, s), + EdCommand::Tree(cmd) => execute_tree_ed(s, cmd, cursor), + EdCommand::Text(cmd) => execute_text_ed(s, cmd, cursor), } } -fn execute_nav(cmd: NavCommand, cursor: &mut Location, s: &Storage) -> Result<(), DocError> { +fn execute_nav(s: &Storage, cmd: NavCommand, cursor: &mut Location) -> Result<(), DocError> { match cmd { - NavCommand::Tree(cmd) => execute_tree_nav(cmd, cursor, s), - NavCommand::Text(cmd) => execute_text_nav(cmd, cursor, s), + NavCommand::Tree(cmd) => execute_tree_nav(s, cmd, cursor), + NavCommand::Text(cmd) => execute_text_nav(s, cmd, cursor), } } fn execute_tree_ed( + s: &mut Storage, cmd: TreeEdCommand, cursor: &mut Location, - s: &mut Storage, ) -> Result, DocError> { use TreeEdCommand::*; @@ -198,7 +198,7 @@ fn execute_tree_ed( } match cmd { - Insert(node) => match cursor.insert(node, s) { + Insert(node) => match cursor.insert(s, node) { Ok(None) => Ok(vec![(*cursor, Backspace.into())]), Ok(Some(detached_node)) => { Ok(vec![(cursor.prev(s).bug(), Insert(detached_node).into())]) @@ -206,14 +206,14 @@ fn execute_tree_ed( Err(()) => Err(DocError::CannotInsertNode), }, Backspace => { - if let Some(old_node) = cursor.delete_neighbor(true, s) { + if let Some(old_node) = cursor.delete_neighbor(s, true) { Ok(vec![(*cursor, Insert(old_node).into())]) } else { Err(DocError::CannotDeleteNode) } } Delete => { - if let Some(old_node) = cursor.delete_neighbor(false, s) { + if let Some(old_node) = cursor.delete_neighbor(s, false) { Ok(vec![(*cursor, Insert(old_node).into())]) } else { Err(DocError::CannotDeleteNode) @@ -223,9 +223,9 @@ fn execute_tree_ed( } fn execute_text_ed( + s: &mut Storage, cmd: TextEdCommand, cursor: &mut Location, - s: &mut Storage, ) -> Result, DocError> { use TextEdCommand::{Backspace, Delete, Insert}; @@ -258,9 +258,9 @@ fn execute_text_ed( } fn execute_tree_nav( + s: &Storage, cmd: TreeNavCommand, cursor: &mut Location, - s: &Storage, ) -> Result<(), DocError> { use TreeNavCommand::*; @@ -276,12 +276,12 @@ fn execute_tree_nav( Parent => cursor.after_parent(s), LastChild => cursor .left_node(s) - .and_then(|node| Location::after_children(node, s)), + .and_then(|node| Location::after_children(s, node)), InorderNext => cursor.inorder_next(s), InorderPrev => cursor.inorder_prev(s), EnterText => cursor .left_node(s) - .and_then(|node| Location::end_of_text(node, s)), + .and_then(|node| Location::end_of_text(s, node)), }; if let Some(new_loc) = new_loc { @@ -293,9 +293,9 @@ fn execute_tree_nav( } fn execute_text_nav( + s: &Storage, cmd: TextNavCommand, cursor: &mut Location, - s: &Storage, ) -> Result<(), DocError> { use TextNavCommand::*; diff --git a/src/language/interface.rs b/src/language/interface.rs index 6b87fa0..1ae0497 100644 --- a/src/language/interface.rs +++ b/src/language/interface.rs @@ -134,8 +134,7 @@ impl Language { } } - // TODO: this seems hacky - pub(crate) fn from_id(id: LanguageId) -> Language { + pub(super) fn from_id(id: LanguageId) -> Language { Language { language: id } } } diff --git a/src/tree/location.rs b/src/tree/location.rs index a18876e..913b315 100644 --- a/src/tree/location.rs +++ b/src/tree/location.rs @@ -36,41 +36,41 @@ impl Location { * Constructors * ****************/ - pub fn before(node: Node, s: &Storage) -> Location { + pub fn before(s: &Storage, node: Node) -> Location { Location(LocationInner::BeforeNode(node).normalize(s)) } - pub fn after(node: Node, _s: &Storage) -> Location { + pub fn after(_s: &Storage, node: Node) -> Location { // already normal form Location(LocationInner::AfterNode(node)) } /// Returns the location at the beginning of the child sequence of the given node. - pub fn before_children(node: Node, s: &Storage) -> Option { + pub fn before_children(s: &Storage, node: Node) -> Option { if node.is_texty(s) { return None; } if let Some(first_child) = node.first_child(s) { - Some(Location::before(first_child, s)) + Some(Location::before(s, first_child)) } else { Some(Location(LocationInner::BelowNode(node))) } } /// Returns the location at the end of the child sequence of the given node. - pub fn after_children(node: Node, s: &Storage) -> Option { + pub fn after_children(s: &Storage, node: Node) -> Option { if node.is_texty(s) { return None; } if let Some(last_child) = node.last_child(s) { - Some(Location::after(last_child, s)) + Some(Location::after(s, last_child)) } else { Some(Location(LocationInner::BelowNode(node))) } } /// If the node is texty, returns the location at the start of its text, otherwise returns `None`. - pub fn start_of_text(node: Node, s: &Storage) -> Option { + pub fn start_of_text(s: &Storage, node: Node) -> Option { if node.is_texty(s) { Some(Location(LocationInner::InText(node, 0))) } else { @@ -79,7 +79,7 @@ impl Location { } /// If the node is texty, returns the location at the end of its text, otherwise returns `None`. - pub fn end_of_text(node: Node, s: &Storage) -> Option { + pub fn end_of_text(s: &Storage, node: Node) -> Option { let text_len = node.text(s)?.num_chars(); Some(Location(LocationInner::InText(node, text_len))) } @@ -119,7 +119,7 @@ impl Location { use LocationInner::{AfterNode, BeforeNode, BelowNode, InText}; match self.0 { - AfterNode(node) => Some(Location::before(node, s)), + AfterNode(node) => Some(Location::before(s, node)), InText(_, _) | BeforeNode(_) | BelowNode(_) => None, } } @@ -128,8 +128,8 @@ impl Location { use LocationInner::{AfterNode, BeforeNode, BelowNode, InText}; match self.0 { - AfterNode(node) => Some(Location::after(node.next_sibling(s)?, s)), - BeforeNode(node) => Some(Location::after(node, s)), + AfterNode(node) => Some(Location::after(s, node.next_sibling(s)?)), + BeforeNode(node) => Some(Location::after(s, node)), InText(_, _) | BelowNode(_) => None, } } @@ -139,7 +139,7 @@ impl Location { match self.0 { InText(_, _) => None, - AfterNode(node) => Some(Location::before(node.first_sibling(s), s)), + AfterNode(node) => Some(Location::before(s, node.first_sibling(s))), BeforeNode(_) | BelowNode(_) => Some(self), } } @@ -149,26 +149,26 @@ impl Location { match self.0 { InText(_, _) => None, - BeforeNode(node) | AfterNode(node) => Some(Location::after(node.last_sibling(s), s)), + BeforeNode(node) | AfterNode(node) => Some(Location::after(s, node.last_sibling(s))), BelowNode(_) => Some(self), } } pub fn before_parent(self, s: &Storage) -> Option { - Some(Location::before(self.parent_node(s)?, s)) + Some(Location::before(s, self.parent_node(s)?)) } pub fn after_parent(self, s: &Storage) -> Option { - Some(Location::after(self.parent_node(s)?, s)) + Some(Location::after(s, self.parent_node(s)?)) } /// Returns the next location in an inorder tree traversal. pub fn inorder_next(self, s: &Storage) -> Option { if let Some(right_node) = self.right_node(s) { - if let Some(loc) = Location::before_children(right_node, s) { + if let Some(loc) = Location::before_children(s, right_node) { Some(loc) } else { - Some(Location::after(right_node, s)) + Some(Location::after(s, right_node)) } } else { self.after_parent(s) @@ -178,10 +178,10 @@ impl Location { /// Returns the previous location in an inorder tree traversal. pub fn inorder_prev(self, s: &Storage) -> Option { if let Some(left_node) = self.left_node(s) { - if let Some(loc) = Location::after_children(left_node, s) { + if let Some(loc) = Location::after_children(s, left_node) { Some(loc) } else { - Some(Location::before(left_node, s)) + Some(Location::before(s, left_node)) } } else { self.before_parent(s) @@ -251,7 +251,7 @@ impl Location { /// - This location is after the last node in a fixed sequence. /// - The new node does not match the required sort. #[allow(clippy::result_unit_err)] - pub fn insert(&mut self, new_node: Node, s: &mut Storage) -> Result, ()> { + pub fn insert(&mut self, s: &mut Storage, new_node: Node) -> Result, ()> { use LocationInner::*; let parent = self.parent_node(s).ok_or(())?; @@ -261,7 +261,7 @@ impl Location { Arity::Fixed(_) => { let old_node = self.right_node(s).ok_or(())?; if new_node.swap(s, old_node) { - *self = Location::after(new_node, s); + *self = Location::after(s, new_node); Ok(Some(old_node)) } else { Err(()) @@ -275,7 +275,7 @@ impl Location { BelowNode(_) => parent.insert_last_child(s, new_node), }; if success { - *self = Location::after(new_node, s); + *self = Location::after(s, new_node); Ok(None) } else { Err(()) @@ -288,7 +288,7 @@ impl Location { /// replace the node before (after) the cursor with a hole, and move the cursor before (after) /// it. #[must_use] - pub fn delete_neighbor(&mut self, delete_before: bool, s: &mut Storage) -> Option { + pub fn delete_neighbor(&mut self, s: &mut Storage, delete_before: bool) -> Option { let parent = self.parent_node(s)?; let node = if delete_before { self.left_node(s)? @@ -303,9 +303,9 @@ impl Location { let hole = Node::new_hole(s, node.language(s)); if node.swap(s, hole) { *self = if delete_before { - Location::before(hole, s) + Location::before(s, hole) } else { - Location::after(hole, s) + Location::after(s, hole) }; Some(node) } else { @@ -345,7 +345,7 @@ impl Location { /// created. However, it will return `None` if the bookmark's node /// has since been deleted, or if it is currently located in a /// different tree. - pub fn validate_bookmark(self, mark: Bookmark, s: &Storage) -> Option { + pub fn validate_bookmark(self, s: &Storage, mark: Bookmark) -> Option { let mark_node = mark.0.reference_node(); if mark_node.is_valid(s) && mark_node.root(s) == self.root_node(s) { Some(Location(mark.0.normalize(s))) diff --git a/src/tree/node.rs b/src/tree/node.rs index 0c8332e..5b3af22 100644 --- a/src/tree/node.rs +++ b/src/tree/node.rs @@ -34,8 +34,6 @@ struct NodeData { #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Node(forest::NodeIndex); -// TODO: Put Storage arg always first or always last :-( - impl Storage { fn forest(&self) -> &forest::Forest { &self.node_forest.forest