From 119105c6a22567923c25e0e374381da3a2b8dcc4 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Thu, 14 Sep 2023 13:17:50 +0200 Subject: [PATCH] typeterm editor: improve morphings --- nested/src/editors/list/cmd.rs | 6 +- nested/src/editors/list/ctx.rs | 2 +- nested/src/editors/list/editor.rs | 14 ++- nested/src/editors/list/nav.rs | 6 +- nested/src/editors/list/pty_editor.rs | 1 + nested/src/editors/typeterm/cmd.rs | 166 ++++++++++++++++++-------- nested/src/editors/typeterm/ctx.rs | 20 +++- nested/src/editors/typeterm/mod.rs | 123 +++++++------------ nested/src/editors/typeterm/nav.rs | 1 - 9 files changed, 195 insertions(+), 144 deletions(-) diff --git a/nested/src/editors/list/cmd.rs b/nested/src/editors/list/cmd.rs index d7958a5..1cf3c8e 100644 --- a/nested/src/editors/list/cmd.rs +++ b/nested/src/editors/list/cmd.rs @@ -151,16 +151,16 @@ impl ObjCommander for ListEditor { } else { TreeNavResult::Exit } - } } } else { if let Some(cur_item) = self.get_item_mut() { drop(cmd_repr); - cur_item.write().unwrap().send_cmd_obj(cmd_obj) - } else { + cur_item.write().unwrap().send_cmd_obj(cmd_obj); TreeNavResult::Continue + } else { + TreeNavResult::Exit } } } diff --git a/nested/src/editors/list/ctx.rs b/nested/src/editors/list/ctx.rs index f6eb5df..586db0b 100644 --- a/nested/src/editors/list/ctx.rs +++ b/nested/src/editors/list/ctx.rs @@ -10,7 +10,7 @@ use { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub fn init_ctx(ctx: &mut Context) { - ctx.add_list_typename("ListCmd".into()); + ctx.add_typename("ListCmd".into()); ctx.add_list_typename("List".into()); ctx.add_node_ctor( diff --git a/nested/src/editors/list/editor.rs b/nested/src/editors/list/editor.rs index 9b81408..a926605 100644 --- a/nested/src/editors/list/editor.rs +++ b/nested/src/editors/list/editor.rs @@ -232,14 +232,15 @@ impl ListEditor { /// insert a new element pub fn insert(&mut self, item: Arc>) { + eprintln!("list insert"); + item.read().unwrap().depth.0.set_view( + self.depth.map(|d| d+1).get_view() + ); + let mut cur = self.cursor.get(); if let Some(idx) = cur.idx { match cur.mode { ListCursorMode::Insert => { - item.read().unwrap().depth.0.set_view( - self.depth.map(|d| d+1).get_view() - ); - self.data.insert(idx as usize, item.clone()); if self.is_listlist() { cur.mode = ListCursorMode::Select; @@ -263,7 +264,8 @@ impl ListEditor { } /// split the list off at the current cursor position and return the second half - pub fn split(&mut self) { + pub fn split(&mut self) { + eprintln!("split"); let cur = self.cursor.get(); if let Some(idx) = cur.idx { let idx = idx as usize; @@ -277,6 +279,7 @@ impl ListEditor { } pub fn listlist_split(&mut self) { + eprintln!("listlist split"); let cur = self.get_cursor(); if let Some(mut item) = self.get_item().clone() { @@ -293,6 +296,7 @@ impl ListEditor { tail_node.goto(TreeCursor::home()); for node in b.iter() { + eprintln!("splid :send to tail node"); tail_node .send_cmd_obj( ReprTree::new_leaf( diff --git a/nested/src/editors/list/nav.rs b/nested/src/editors/list/nav.rs index 88bac81..9842ef9 100644 --- a/nested/src/editors/list/nav.rs +++ b/nested/src/editors/list/nav.rs @@ -216,10 +216,12 @@ impl TreeNav for ListEditor { .write().unwrap() .goby(Vector2::new(direction.x, direction.y)) == TreeNavResult::Continue { - self.cursor.set(ListCursor { + let res = self.cursor.set(ListCursor { mode: ListCursorMode::Select, idx: Some(cur.tree_addr[0]) - }) + }); + self.set_leaf_mode(cur.leaf_mode); + res } } diff --git a/nested/src/editors/list/pty_editor.rs b/nested/src/editors/list/pty_editor.rs index e14a642..8238a93 100644 --- a/nested/src/editors/list/pty_editor.rs +++ b/nested/src/editors/list/pty_editor.rs @@ -147,6 +147,7 @@ impl PTYListController { // || Some(c) == child_close_char { e.listlist_split(); + eprintln!("done listlist split"); TreeNavResult::Continue } else if Some(c) == child_close_char { e.goto(TreeCursor::none()); diff --git a/nested/src/editors/typeterm/cmd.rs b/nested/src/editors/typeterm/cmd.rs index 56f93d8..57ad081 100644 --- a/nested/src/editors/typeterm/cmd.rs +++ b/nested/src/editors/typeterm/cmd.rs @@ -52,75 +52,138 @@ impl ObjCommander for TypeTermEditor { } State::Char => { - match c { - '\'' => { - self.cur_node.get_mut().goto(TreeCursor::none()); + match self.send_child_cmd( co ) { + TreeNavResult::Exit => { + match c { + '\'' => { + self.cur_node.get_mut().goto(TreeCursor::none()); + } + _ => {} + } TreeNavResult::Exit - } - _ => { - self.send_child_cmd( co ) - } + }, + TreeNavResult::Continue => TreeNavResult::Continue } } State::Ladder => { - if c == '~' { - let i0 = self.cur_node.get().get_edit::().unwrap(); - if self.get_cursor().tree_addr.len() > 1 { - let cur_it = i0.clone().read().unwrap().get_item().clone(); - if let Some(i) = cur_it { - let tte = i.get_edit::().unwrap(); + match self.get_cursor().tree_addr.len() { - if tte.read().unwrap().state != State::App { - drop(tte); - drop(i); + // entire term is selected + 0 => { + match c { + '<' => { + self.morph_to_list(State::App); + TreeNavResult::Continue + } + _ => { TreeNavResult::Exit } + } + } - return self.send_child_cmd( - ListCmd::Split.into_repr_tree( &self.ctx ) - ); + // entire item selected or insert mode + 1 => { + match c { + '~' => { + // ignore '~' since we are already in a ladder + // and cant split current item + TreeNavResult::Continue + } + _ => { + self.send_child_cmd( co.clone() ) + } + } + } + + // some subterm + _ => { + match c { + '~' => { + let i0 = self.cur_node.get().get_edit::().unwrap(); + let cur_it = i0.clone().read().unwrap().get_item().clone(); + if let Some(i) = cur_it { + let cur_tte = i.get_edit::().unwrap(); + if cur_tte.read().unwrap().state == State::App || cur_tte.read().unwrap().get_cursor().tree_addr.len() > 1 { + self.send_child_cmd( co.clone() ) + } else { + drop(cur_tte); + drop(i); + + self.send_child_cmd( + ListCmd::Split.into_repr_tree( &self.ctx ) + ) + } + } else { + self.send_child_cmd( co.clone() ) + } + } + _ => { + self.send_child_cmd( co.clone() ) } } - } else { - return TreeNavResult::Continue; } } - - self.send_child_cmd( co.clone() ) } State::App => { - let res = self.send_child_cmd( co.clone() ); - match res { - TreeNavResult::Exit => { + match self.get_cursor().tree_addr.len() { + + // entire Term is selected + 0 => { + match c { '~' => { - self.previous_item_into_ladder(); + self.morph_to_list(State::Ladder); + self.goto(TreeCursor { + tree_addr: vec![ -1 ], + leaf_mode: ListCursorMode::Insert + }); TreeNavResult::Continue - }, - _ => {TreeNavResult::Exit} + } + '<' => { + self.morph_to_list(State::App); + TreeNavResult::Continue + } + _ => { + TreeNavResult::Exit + } } - }, - TreeNavResult::Continue => { - match c { - '>'| - ' ' => { - let i = self.cur_node.get().get_edit::().unwrap(); - let i = i.read().unwrap(); - if let Some(i) = i.get_item() { - let tte = i.get_edit::().unwrap(); - let mut tte = tte.write().unwrap(); - if tte.state == State::Ladder { - tte.normalize_singleton(); - } + }, + + // some item is selected + _ => { + match self.send_child_cmd( co.clone() ) { + TreeNavResult::Exit => { + match c { + '~' => { + self.previous_item_into_ladder(); + TreeNavResult::Continue + }, + _ => {TreeNavResult::Exit} } }, - _ => {} + TreeNavResult::Continue => { + match c { + '>'| + ' ' => { + let i = self.cur_node.get().get_edit::().unwrap(); + let i = i.read().unwrap(); + if let Some(i) = i.get_item() { + let tte = i.get_edit::().unwrap(); + let mut tte = tte.write().unwrap(); + + if tte.state == State::Ladder { + tte.normalize_singleton(); + } + } + }, + _ => {} + } + TreeNavResult::Continue + } } - - TreeNavResult::Continue } } } @@ -132,11 +195,19 @@ impl ObjCommander for TypeTermEditor { match res { TreeNavResult::Exit => { match c { + '<' => { + self.goto(TreeCursor::none()); + self.morph_to_list(State::App); + TreeNavResult::Continue + } '~' => { - self.morph_to_ladder(); + self.morph_to_list(State::Ladder); + self.set_addr(0); + self.dn(); self.send_cmd_obj( ListCmd::Split.into_repr_tree( &self.ctx ) - ) + ); + TreeNavResult::Continue } _ => { TreeNavResult::Exit @@ -188,7 +259,6 @@ impl ObjCommander for TypeTermEditor { let res = self.send_child_cmd( co.clone() ); self.normalize_empty(); - if let Some(cmd) = co.read().unwrap().get_view::>() { match cmd.get() { ListCmd::Split => { diff --git a/nested/src/editors/typeterm/ctx.rs b/nested/src/editors/typeterm/ctx.rs index 6ee0dbd..6ba6b47 100644 --- a/nested/src/editors/typeterm/ctx.rs +++ b/nested/src/editors/typeterm/ctx.rs @@ -41,14 +41,29 @@ pub fn init_ctx(ctx: &mut Context) { Arc::new(|mut node, _dst_type: _| { PTYListController::for_node( &mut node, Some('~'), None ); - let vertical_view = false; + let vertical_view = true; if vertical_view { let editor = node.get_edit::().unwrap(); let mut e = editor.write().unwrap(); let seg_view = PTYListStyle::new( ("","~","") ).get_seg_seq_view( &mut e ); node = node.set_view( - seg_view.to_grid_vertical().flatten() + seg_view.to_grid_vertical() + .map_item( + |pt,x| + if pt.y > 0 { + r3vi::buffer::vec::VecBuffer::with_data(vec![ + crate::terminal::make_label("~"), + x.clone() + ]) + .get_port() + .to_sequence() + .to_grid_horizontal() + .flatten() + } else { + x.clone() + } + ).flatten() ); } else { PTYListStyle::for_node( &mut node, ("","~","") ); @@ -100,6 +115,7 @@ pub fn init_ctx(ctx: &mut Context) { ctx.add_morphism( MorphismTypePattern { src_tyid: ctx.get_typeid("Char"), dst_tyid: ctx.get_typeid("Type::Lit::Char").unwrap() }, Arc::new(|mut node, _dst_type:_| { + node.ctx.write().unwrap().meta_chars = vec![ '\'' ]; let mut grid = r3vi::buffer::index_hashmap::IndexBuffer::new(); grid.insert_iter( diff --git a/nested/src/editors/typeterm/mod.rs b/nested/src/editors/typeterm/mod.rs index 15f7e99..172cb26 100644 --- a/nested/src/editors/typeterm/mod.rs +++ b/nested/src/editors/typeterm/mod.rs @@ -124,7 +124,7 @@ impl TypeTermEditor { editor.send_cmd_obj(ReprTree::from_char(&ctx, *c)); } } - + node.goto(TreeCursor::none()); node } @@ -177,6 +177,7 @@ impl TypeTermEditor { pub fn new_node(ctx: Arc>, depth: OuterViewPort>) -> NestedNode { let ctx : Arc> = Arc::new(RwLock::new(Context::with_parent(Some(ctx)))); ctx.write().unwrap().meta_chars.push('~'); + ctx.write().unwrap().meta_chars.push('<'); let mut symb_node = Context::make_node( &ctx, (&ctx, "( List Char )").into(), depth ).unwrap(); symb_node = symb_node.morph( (&ctx, "( Type::Sym )").into() ); @@ -298,31 +299,28 @@ impl TypeTermEditor { pub fn normalize_singleton(&mut self) { eprintln!("normalize singleton"); - if self.state == State::Ladder{ - - let subladder_list_node = self.cur_node.get().clone(); - let subladder_list_edit = subladder_list_node.get_edit::().unwrap(); + if self.state == State::Ladder { + let subladder_list_node = self.cur_node.get().clone(); + let subladder_list_edit = subladder_list_node.get_edit::().unwrap(); - let subladder_list_edit = subladder_list_edit.read().unwrap(); - if subladder_list_edit.data.len() == 1 { - let it_node = subladder_list_edit.data.get(0); - let it_node = it_node.read().unwrap(); - if it_node.get_type() == (&self.ctx, "( Type )").into() { - let other_tt = it_node.get_edit::().unwrap(); + let subladder_list_edit = subladder_list_edit.read().unwrap(); + if subladder_list_edit.data.len() == 1 { + let it_node = subladder_list_edit.data.get(0); + let it_node = it_node.read().unwrap(); + if it_node.get_type() == (&self.ctx, "( Type )").into() { + let other_tt = it_node.get_edit::().unwrap(); - let mut other_tt = other_tt.write().unwrap(); + let mut other_tt = other_tt.write().unwrap(); - other_tt.normalize_singleton(); + other_tt.normalize_singleton(); + other_tt.depth.0.set_view( self.depth.map(|x| x).get_view() ); - other_tt.depth.0.set_view( self.depth.map(|x| x).get_view() ); - - self.close_char.set(other_tt.close_char.get()); - self.cur_node.set(other_tt.cur_node.get()); - self.state = other_tt.state; + self.close_char.set(other_tt.close_char.get()); + self.cur_node.set(other_tt.cur_node.get()); + self.state = other_tt.state; + } } } - - } } /* in insert mode, morph the previous element into a ladder and continue there @@ -338,97 +336,58 @@ impl TypeTermEditor { app_edit.delete_nexd(); } + // select previous element app_edit.goto(TreeCursor{ tree_addr: vec![ cur.tree_addr[0]-1 ], leaf_mode: ListCursorMode::Select }); - - if let Some(item_node) = app_edit.get_item() { + + // get selected element + if let Some(item_node) = app_edit.get_item() { let item_typterm = item_node.get_edit::().expect("typetermedit"); let mut item_typterm = item_typterm.write().unwrap(); - match item_typterm.state { - - // if item at cursor is Ladder - State::Ladder => { - drop(item_typterm); - - app_edit.dn(); - app_edit.qnexd(); - } - _ => { - item_typterm.goto(TreeCursor::none()); - drop(item_typterm); - - // else create new ladder - let mut list_node = Context::make_node( &self.ctx, (&self.ctx, "( List Type )").into(), self.depth.map(|d| d+1) ).unwrap(); - list_node = list_node.morph( (&self.ctx, "( Type::Ladder )").into() ); - - let mut new_node = TypeTermEditor::with_node( - self.ctx.clone(), - list_node, - State::Ladder - ); - - // insert old node and split - new_node.goto(TreeCursor::home()); - - new_node.send_cmd_obj( - ReprTree::new_leaf( - (&self.ctx, "( NestedNode )"), - SingletonBuffer::::new( item_node ).get_port().into() - ) - ); - - *app_edit.get_item_mut().unwrap().write().unwrap() = new_node; - app_edit.dn(); - } + if item_typterm.state != State::Ladder { + item_typterm.morph_to_list( State::Ladder ); } + + item_typterm.goto(TreeCursor { + tree_addr: vec![ -1 ], + leaf_mode: ListCursorMode::Insert + }); } } } - - // TODO: morph_to_app() / morph_to_list(state) - /* replace with new ladder node with self as first element + /* replace with new list-node (ladder/app) with self as first element */ - pub fn morph_to_ladder(&mut self) { + pub(super) fn morph_to_list(&mut self, state: State) { eprintln!("morph into ladder"); - - let old_node = self.cur_node.get().clone(); + + let mut old_node = self.cur_node.get().clone(); + + /* reconfigure current node to display new_node list-editor + */ + self.set_state( state ); /* create a new NestedNode with TerminaltypeEditor, * that has same state & child-node as current node. */ - let old_edit_node = TypeTermEditor::new_node( self.ctx.clone(), self.depth.map(|d| d + 1)); - old_node.depth.0.set_view( self.depth.map(|d| d + 1).get_view() ); + let old_edit_node = TypeTermEditor::new_node( self.ctx.clone(), SingletonBuffer::new(0).get_port() ); + old_node.depth.0.set_view( old_edit_node.depth.map(|x|x).get_view() ); + let old_edit_clone = old_edit_node.get_edit::().unwrap(); old_edit_clone.write().unwrap().set_state( self.state ); - old_edit_clone.write().unwrap().close_char.set( old_node.close_char.get() ); old_edit_clone.write().unwrap().cur_node.set( old_node ); - /* create new list-edit node for the ladder - */ - let mut new_node = Context::make_node( &self.ctx, (&self.ctx, "( List Type )").into(), self.depth.map(|x| x) ).unwrap(); - new_node = new_node.morph( (&self.ctx, "( Type::Ladder )").into() ); - - /* reconfigure current node to display new_node list-editor - */ - self.close_char.set(new_node.close_char.get()); - self.cur_node.set(new_node); - self.state = State::Ladder; - /* insert old node and split */ self.goto(TreeCursor::home()); - self.send_cmd_obj( + self.send_child_cmd( ReprTree::new_leaf( (&self.ctx, "( NestedNode )"), SingletonBuffer::new( old_edit_node ).get_port().into() ) ); - - self.set_addr(0); - self.dn(); } } diff --git a/nested/src/editors/typeterm/nav.rs b/nested/src/editors/typeterm/nav.rs index 0d3f970..6fb7bf1 100644 --- a/nested/src/editors/typeterm/nav.rs +++ b/nested/src/editors/typeterm/nav.rs @@ -42,4 +42,3 @@ impl TreeNav for TypeTermEditor { self.cur_node.get_mut().goto(new_cur) } } -