From e111a360a974ea7d6b7a13bce7b9961e59a6398c Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Mon, 4 Sep 2023 01:24:53 +0200 Subject: [PATCH] fix list split/join & more edge cases in typetermeditor --- nested/src/editors/list/cmd.rs | 175 ++++++------ nested/src/editors/list/cursor.rs | 6 +- nested/src/editors/list/editor.rs | 245 ++++++++++------- nested/src/editors/list/pty_editor.rs | 2 + nested/src/editors/typeterm/ctx.rs | 10 +- nested/src/editors/typeterm/mod.rs | 382 ++++++++++++++++---------- nested/src/tree/cursor.rs | 2 +- 7 files changed, 486 insertions(+), 336 deletions(-) diff --git a/nested/src/editors/list/cmd.rs b/nested/src/editors/list/cmd.rs index f74c753..a03efe9 100644 --- a/nested/src/editors/list/cmd.rs +++ b/nested/src/editors/list/cmd.rs @@ -60,110 +60,101 @@ impl ObjCommander for ListEditor { else if let Some(cmd) = cmd_repr.get_view::>() { let cur = self.cursor.get(); drop(cmd_repr); - - if let Some(idx) = cur.idx { - match cur.mode { - ListCursorMode::Select => { - if let Some(mut item) = self.get_item().clone() { - if self.is_listlist() { - let item_cur = item.get_cursor(); + match cmd.get() { + ListCmd::Clear => { + self.clear(); + TreeNavResult::Continue + } + _ => { + if let Some(idx) = cur.idx { + match cur.mode { + ListCursorMode::Select => { + if let Some(mut item) = self.get_item().clone() { + if self.is_listlist() { + let item_cur = item.get_cursor(); + + match cmd.get() { + ListCmd::DeletePxev => { + if idx > 0 + && item_cur.tree_addr.iter().fold( + true, + |is_zero, x| is_zero && (*x == 0) + ) + { + self.listlist_join_pxev(idx); + TreeNavResult::Continue + } else { + item.send_cmd_obj(cmd_obj) + } + } + + ListCmd::DeleteNexd => { + let item_cur = item.get_cursor_warp(); + let next_idx = idx as usize + 1; + + if next_idx < self.data.len() + && item_cur.tree_addr.iter().fold( + true, + |is_end, x| is_end && (*x == -1) + ) + { + self.listlist_join_nexd(idx as usize); + TreeNavResult::Continue + } else { + item.send_cmd_obj(cmd_obj) + } + } + + ListCmd::Split => { + self.listlist_split(); + TreeNavResult::Continue + } + + _ => { + item.send_cmd_obj(cmd_obj); + TreeNavResult::Continue + } + } + } else { + TreeNavResult::Exit + } + } else { + TreeNavResult::Exit + } + }, + + ListCursorMode::Insert => { match cmd.get() { ListCmd::DeletePxev => { - if idx > 0 - && item_cur.tree_addr.iter().fold( - true, - |is_zero, x| is_zero && (*x == 0) - ) - { - self.listlist_join_pxev(idx, &item); - TreeNavResult::Continue - } else { - item.send_cmd_obj(cmd_obj) - } - } - - ListCmd::DeleteNexd => { - let item_cur = item.get_cursor_warp(); - let next_idx = idx as usize + 1; - - if next_idx < self.data.len() - && item_cur.tree_addr.iter().fold( - true, - |is_end, x| is_end && (*x == -1) - ) - { - self.listlist_join_nexd(next_idx, &item); - TreeNavResult::Continue - } else { - item.send_cmd_obj(cmd_obj) - } - } - - ListCmd::Split => { - self.listlist_split(); + self.delete_pxev(); TreeNavResult::Continue } - - _ => { - eprintln!("list edit: give cmd to child"); - - match item.send_cmd_obj(cmd_obj) { - TreeNavResult::Continue => TreeNavResult::Continue, - TreeNavResult::Exit => { - TreeNavResult::Continue - /* - match cmd.get() { - ListCmd::Split => { - }, - _ => { - TreeNavResult::Exit - } - } - */ - } - } + ListCmd::DeleteNexd => { + self.delete_nexd(); + TreeNavResult::Continue + } + ListCmd::Split => { + self.split(); + TreeNavResult::Exit + } + ListCmd::Close => { + self.goto(TreeCursor::none()); + TreeNavResult::Exit + } + _ =>{ + TreeNavResult::Continue } } - } else { - TreeNavResult::Exit - } - } else { - TreeNavResult::Exit - } - }, - - ListCursorMode::Insert => { - match cmd.get() { - ListCmd::DeletePxev => { - self.delete_pxev(); - TreeNavResult::Continue - } - ListCmd::DeleteNexd => { - self.delete_nexd(); - TreeNavResult::Continue - } - ListCmd::Split => { - self.split(); - TreeNavResult::Exit - } - ListCmd::Clear => { - self.clear(); - TreeNavResult::Continue - } - ListCmd::Close => { - self.goto(TreeCursor::none()); - TreeNavResult::Exit - } - _ =>{ - TreeNavResult::Continue } } + } else { + TreeNavResult::Exit } + } - } else { - TreeNavResult::Exit } + } else { if let Some(cur_item) = self.get_item_mut() { diff --git a/nested/src/editors/list/cursor.rs b/nested/src/editors/list/cursor.rs index de21c01..e995b10 100644 --- a/nested/src/editors/list/cursor.rs +++ b/nested/src/editors/list/cursor.rs @@ -1,4 +1,4 @@ -#[derive(Clone, Copy, Eq, PartialEq)] +#[derive(Clone, Copy, Eq, PartialEq, Debug)] pub enum ListCursorMode { Insert, Select @@ -10,7 +10,7 @@ impl Default for ListCursorMode { } } -#[derive(Clone, Copy, Eq, PartialEq)] +#[derive(Clone, Copy, Eq, PartialEq, Debug)] pub struct ListCursor { pub mode: ListCursorMode, pub idx: Option, @@ -34,7 +34,7 @@ impl ListCursor { impl Default for ListCursor { fn default() -> Self { - ListCursor::none() + ListCursor::home() } } diff --git a/nested/src/editors/list/editor.rs b/nested/src/editors/list/editor.rs index 95c9287..1da2e58 100644 --- a/nested/src/editors/list/editor.rs +++ b/nested/src/editors/list/editor.rs @@ -52,7 +52,12 @@ impl ListEditor { ListCursorMode::Insert => ip, ListCursorMode::Select => { if let Some(idx) = c.idx { - data.get(idx as usize).read().unwrap().get_mode_view() + if idx > 0 && idx < data.len() as isize { + data.get(idx as usize).read().unwrap().get_mode_view() + } else { + eprintln!("ListEditor::mode_port invalid cursor idx"); + ip + } } else { ip } @@ -191,6 +196,12 @@ impl ListEditor { /// delete all items pub fn clear(&mut self) { + eprintln!("list editor: clear"); + let mut b = self.spillbuf.write().unwrap(); + for i in 0..self.data.len() { + b.push( self.data.get(i) ); + } + self.data.clear(); self.cursor.set(ListCursor::home()); } @@ -257,7 +268,8 @@ impl ListEditor { } /* TODO - + */ + /* if self.is_listlist() { if idx > 0 && idx < self.data.len()+1 { @@ -283,127 +295,165 @@ impl ListEditor { } } - /// append data of other editor at the end and set cursor accordingly - pub fn join(&mut self, other: &ListEditor) { - let selfcur = self.cursor.get(); - let othercur = other.cursor.get(); - - let is_bottom = self.get_cursor().tree_addr.len() == 1 || - other.get_cursor().tree_addr.len() == 1; - - let is_insert = - selfcur.mode == ListCursorMode::Insert - || othercur.mode == ListCursorMode::Insert; - - let is_primary = self.get_cursor().tree_addr.len() > 1; - - self.cursor.set(ListCursor { - mode: if is_insert && is_bottom { - ListCursorMode::Insert - } else { - ListCursorMode::Select - }, - idx: Some(self.data.len() as isize - - if is_primary { - 1 - } else { - 0 - } - ) - }); - - for i in 0 .. other.data.len() { - self.data.push(other.data.get(i)); - } - } - pub fn listlist_split(&mut self) { let cur = self.get_cursor(); - + eprintln!("listlist_split(): cur = {:?}", cur); if let Some(mut item) = self.get_item().clone() { + eprintln!("listlist_split(): split child item"); item.send_cmd_obj(ListCmd::Split.into_repr_tree(&self.ctx)); + eprintln!("listlist_split(): done child split"); - let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), 0).unwrap(); - tail_node.goto(TreeCursor::home()); + if cur.tree_addr.len() < 3 { + item.goto(TreeCursor::none()); + let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), 0).unwrap(); + //tail_node = tail_node.morph( ); + tail_node.goto(TreeCursor::home()); - let mut b = item.spillbuf.write().unwrap(); - for node in b.iter() { - tail_node - .send_cmd_obj( - ReprTree::new_leaf( - (&self.ctx, "( NestedNode )"), - SingletonBuffer::::new( - node.read().unwrap().clone() - ).get_port().into() - ) - ); - } - b.clear(); - drop(b); - - item.goto(TreeCursor::none()); - drop(item); - - tail_node.goto( - TreeCursor { - tree_addr: vec![0], - leaf_mode: if cur.tree_addr.len() > 2 { - ListCursorMode::Select - } else { - ListCursorMode::Insert - } + let mut b = item.spillbuf.write().unwrap(); + for node in b.iter() { + tail_node + .send_cmd_obj( + ReprTree::new_leaf( + (&self.ctx, "( NestedNode )"), + SingletonBuffer::::new( + node.read().unwrap().clone() + ).get_port().into() + ) + ); } - ); + b.clear(); + drop(b); + drop(item); - self.insert( - Arc::new(RwLock::new(tail_node)) - ); + self.set_leaf_mode(ListCursorMode::Insert); + self.nexd(); + + tail_node.goto(TreeCursor::home()); + if cur.tree_addr.len() > 2 { + tail_node.dn(); + } + + eprintln!("insert tail node"); + self.insert( + Arc::new(RwLock::new(tail_node)) + ); + } else { + self.up(); + self.listlist_split(); + self.dn(); + eprintln!("tree depth >= 3"); + } } } - pub fn listlist_join_pxev(&mut self, idx: isize, item: &NestedNode) { + pub fn listlist_join_pxev(&mut self, idx: isize) { { - let prev_editor = self.data.get_mut(idx as usize-1); - let prev_editor = prev_editor.read().unwrap(); + let cur_editor = self.data.get(idx as usize); + let pxv_editor = self.data.get(idx as usize-1); + let mut cur_editor = cur_editor.write().unwrap(); + let mut pxv_editor = pxv_editor.write().unwrap(); - if let Some(prev_editor) = prev_editor.editor.get() { - if let Ok(prev_editor) = prev_editor.downcast::>() { - let mut prev_editor = prev_editor.write().unwrap(); + let oc0 = cur_editor.get_cursor(); - let cur_editor = item.editor.get().unwrap(); - let cur_editor = cur_editor.downcast::>().unwrap(); - let cur_editor = cur_editor.write().unwrap(); + // tell cur_editor move all its elements into its spill-buffer + cur_editor.goto(TreeCursor::none()); + cur_editor.send_cmd_obj( + ListCmd::Clear.into_repr_tree( &self.ctx ) + ); + + pxv_editor.goto(TreeCursor { + tree_addr: vec![-1], + leaf_mode: ListCursorMode::Insert + }); - prev_editor.join(&cur_editor); + let old_cur = pxv_editor.get_cursor(); - self.cursor.set( - ListCursor { - idx: Some(idx - 1), mode: ListCursorMode::Select - } - ); - } + let data = cur_editor.spillbuf.read().unwrap(); + for x in data.iter() { + pxv_editor.send_cmd_obj( + ReprTree::new_leaf( + (&self.ctx, "( NestedNode )"), + SingletonBuffer::::new( + x.read().unwrap().clone() + ).get_port().into() + ) + ); + } + + if oc0.tree_addr.len() > 1 { + pxv_editor.goto(TreeCursor { + tree_addr: vec![ old_cur.tree_addr[0], 0 ], + leaf_mode: ListCursorMode::Insert + }); + pxv_editor.send_cmd_obj(ListCmd::DeletePxev.into_repr_tree( &self.ctx )); + } else { + pxv_editor.goto(TreeCursor { + tree_addr: vec![ old_cur.tree_addr[0] ], + leaf_mode: ListCursorMode::Insert + }); } } + self.cursor.set(ListCursor { + idx: Some(idx as isize - 1), + mode: ListCursorMode::Select + }); + + // remove cur_editor from top list, its elements are now in pxv_editor self.data.remove(idx as usize); } - pub fn listlist_join_nexd(&mut self, next_idx: usize, item: &NestedNode) { + pub fn listlist_join_nexd(&mut self, idx: usize) { + eprintln!("listilst_join_nexd"); { - let next_editor = self.data.get(next_idx); - let next_editor = next_editor.read().unwrap(); - if let Some(next_editor) = next_editor.editor.get() { - if let Ok(next_editor) = next_editor.downcast::>() { - let next_editor = next_editor.write().unwrap(); - let cur_editor = item.editor.get().unwrap(); - let cur_editor = cur_editor.downcast::>().unwrap(); - let mut cur_editor = cur_editor.write().unwrap(); + let cur_editor = self.data.get(idx); + let nxd_editor = self.data.get(idx + 1); + let mut cur_editor = cur_editor.write().unwrap(); + let mut nxd_editor = nxd_editor.write().unwrap(); - cur_editor.join(&next_editor); - } + let oc0 = cur_editor.get_cursor(); + + // tell next_editor move all its elements into its spill-buffer + nxd_editor.goto(TreeCursor::none()); + nxd_editor.send_cmd_obj( + ListCmd::Clear.into_repr_tree( &self.ctx ) + ); + + let old_cur = cur_editor.get_cursor(); + cur_editor.goto(TreeCursor { + tree_addr: vec![-1], + leaf_mode: ListCursorMode::Insert + }); + + let data = nxd_editor.spillbuf.read().unwrap(); + eprintln!("spillbuf of next : {} elements", data.len()); + for x in data.iter() { + cur_editor.send_cmd_obj( + ReprTree::new_leaf( + (&self.ctx, "( NestedNode )"), + SingletonBuffer::::new( + x.read().unwrap().clone() + ).get_port().into() + ) + ); + } + + if oc0.tree_addr.len() > 1 { + cur_editor.goto(TreeCursor { + tree_addr: vec![ old_cur.tree_addr[0], -1 ], + leaf_mode: ListCursorMode::Insert + }); + cur_editor.send_cmd_obj(ListCmd::DeleteNexd.into_repr_tree( &self.ctx )); + } else { + cur_editor.goto(TreeCursor { + tree_addr: vec![ old_cur.tree_addr[0] ], + leaf_mode: ListCursorMode::Insert + }); } } - self.data.remove(next_idx); + + // remove next_editor from top list, its elements are now in cur_editor + self.data.remove(idx+1); } } @@ -429,3 +479,4 @@ impl TreeType for ListEditor { } */ + diff --git a/nested/src/editors/list/pty_editor.rs b/nested/src/editors/list/pty_editor.rs index 3f3cbe7..b6f237e 100644 --- a/nested/src/editors/list/pty_editor.rs +++ b/nested/src/editors/list/pty_editor.rs @@ -152,7 +152,9 @@ impl PTYListController { let cur = e.cursor.get(); if Some(c) == self.split_char { + eprintln!("handle meta char: --> e.listlist_split()"); e.listlist_split(); + eprintln!("e.listlist_split() DONE"); TreeNavResult::Continue } else if Some(c) == child_close_char { e.goto(TreeCursor::none()); diff --git a/nested/src/editors/typeterm/ctx.rs b/nested/src/editors/typeterm/ctx.rs index 2f842f5..d7236e0 100644 --- a/nested/src/editors/typeterm/ctx.rs +++ b/nested/src/editors/typeterm/ctx.rs @@ -4,7 +4,7 @@ use { }, crate::{ type_system::{Context, TypeTerm, MorphismTypePattern}, - terminal::{TerminalStyle}, + terminal::{TerminalStyle, TerminalProjections}, editors::{list::{PTYListStyle, PTYListController}, typeterm::{State, TypeTermEditor}} }, std::{sync::{Arc, RwLock}}, @@ -34,11 +34,11 @@ pub fn init_ctx(ctx: &mut Context) { Arc::new(|mut node, _dst_type: _| { PTYListController::for_node( &mut node, Some('~'), None ); - let vertical_view = true; + let vertical_view = false; if vertical_view { let editor = node.get_edit::().unwrap(); let mut e = editor.write().unwrap(); - let mut seg_view = PTYListStyle::new( ("","~",""), 0 ).get_seg_seq_view( &mut e ); + let mut seg_view = PTYListStyle::new( ("","~",""), node.depth.get() ).get_seg_seq_view( &mut e ); node = node.set_view( seg_view.to_grid_vertical().flatten() @@ -95,14 +95,14 @@ pub fn init_ctx(ctx: &mut Context) { })); ctx.add_morphism( - MorphismTypePattern { src_tyid: ctx.get_typeid("List"), dst_tyid: ctx.get_typeid("Type::Lit::Char").unwrap() }, + MorphismTypePattern { src_tyid: ctx.get_typeid("Char"), dst_tyid: ctx.get_typeid("Type::Lit::Char").unwrap() }, Arc::new(|mut node, _dst_type:_| { let mut grid = r3vi::buffer::index_hashmap::IndexBuffer::new(); grid.insert_iter( vec![ (Point2::new(0,0), crate::terminal::make_label("'")), - (Point2::new(1,0), node.view.clone().unwrap()), + (Point2::new(1,0), node.view.clone().unwrap_or( crate::terminal::make_label(".").with_fg_color((220,200,20))) ), (Point2::new(2,0), crate::terminal::make_label("'")), ] ); diff --git a/nested/src/editors/typeterm/mod.rs b/nested/src/editors/typeterm/mod.rs index 9a646f5..d213987 100644 --- a/nested/src/editors/typeterm/mod.rs +++ b/nested/src/editors/typeterm/mod.rs @@ -30,14 +30,17 @@ pub enum State { } pub struct TypeTermEditor { + + // shared with NestedNode that contains self ctx: Arc>, data: Arc>, - - // references to Node pointing to TypeTermEditor close_char: SingletonBuffer>, spillbuf: Arc>>>>, + // editing/parsing state state: State, + + // child node cur_node: SingletonBuffer< NestedNode > } @@ -55,8 +58,7 @@ impl TypeTermEditor { }); let typename = ctx.read().unwrap().get_typename(&tyid).unwrap_or("UNNAMED TYPE".into()); - for x in typename.chars() - { + for x in typename.chars() { node.send_cmd_obj( ReprTree::from_char( &ctx, x ) ); @@ -101,20 +103,21 @@ impl TypeTermEditor { TypeTerm::Num( n ) => { let editor = node.get_edit::().expect("typ term edit"); - let parent_ctx = editor.read().unwrap().cur_node.get().ctx.clone(); - let int_edit = crate::editors::integer::PosIntEditor::from_u64(parent_ctx, 10, *n as u64); - let node = int_edit.into_node(); - editor.write().unwrap().cur_node.set(node); - editor.write().unwrap().state = State::Num; + let mut editor = editor.write().unwrap(); + editor.cur_node.set( + crate::editors::integer::PosIntEditor::from_u64(parent_ctx, 10, *n as u64) + .into_node() + ); + editor.state = State::Num; } TypeTerm::Char( c ) => { let editor = node.get_edit::().expect("typ term edit"); - - editor.write().unwrap().set_state( State::Char ); - editor.write().unwrap().send_cmd_obj(ReprTree::from_char(&ctx, *c)); + let mut editor = editor.write().unwrap(); + editor.set_state( State::Char ); + editor.send_cmd_obj(ReprTree::from_char(&ctx, *c)); } _ => {} @@ -196,10 +199,9 @@ impl TypeTermEditor { let editor = TypeTermEditor { ctx: ctx.clone(), - state, data: data.clone(), + state, cur_node: SingletonBuffer::new(node), - //editor: SingletonBuffer::new(None), close_char: SingletonBuffer::new(None), spillbuf: Arc::new(RwLock::new(Vec::new())) }; @@ -227,7 +229,6 @@ impl TypeTermEditor { } fn forward_spill(&mut self) { - eprintln!("forward spill"); let node = self.cur_node.get(); let mut buf = node.spillbuf.write().unwrap(); for n in buf.iter() { @@ -237,12 +238,12 @@ impl TypeTermEditor { } fn send_child_cmd(&mut self, cmd: Arc>) -> TreeNavResult { - eprintln!("typterm forward cmd"); + eprintln!("send child cmd"); let res = self.cur_node.get_mut().send_cmd_obj( cmd ); self.forward_spill(); res } - + fn get_typeterm(&self) -> Option { match self.state { State::Any => None, @@ -267,6 +268,7 @@ impl TypeTermEditor { */ Some(TypeTerm::new(TypeID::Fun(0))) }, + State::App => { Some(TypeTerm::new(TypeID::Fun(0))) }, @@ -280,6 +282,189 @@ impl TypeTermEditor { _ => {None} } } + + /* unwrap a ladder if it only contains one element + */ + pub fn normalize_singleton(&mut self) { + eprintln!("normalize singleton ladder!"); + let mut subladder_list_node = self.cur_node.get().clone(); + let mut 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 { + eprintln!("-> is singleton ladder"); + 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(); + + other_tt.normalize_singleton(); + + eprintln!(">>>==>>> reset curent editor!!"); + self.close_char.set(other_tt.close_char.get()); + self.cur_node.set(other_tt.cur_node.get()); + self.state = other_tt.state; + } + } else { + eprintln!("-> is empty ladder"); + } + } + + /* flatten ladder of ladders into one ladder editor + */ + pub fn normalize_nested_ladder(&mut self) { + let mut subladder_list_node = self.cur_node.get().clone(); + let mut subladder_list_edit = subladder_list_node.get_edit::().unwrap(); + + let item = subladder_list_edit.write().unwrap().get_item().clone(); + + if let Some(mut it_node) = item { + if it_node.get_type() == (&self.ctx, "( Type )").into() { + let other_tt = it_node.get_edit::().unwrap(); + + if other_tt.write().unwrap().state == State::Ladder { + let other = other_tt.read().unwrap().cur_node.get().get_edit::().unwrap(); + let buf = other.read().unwrap().data.clone(); + + subladder_list_edit.write().unwrap().up(); + subladder_list_edit.write().unwrap().up(); + subladder_list_node.send_cmd_obj( + ListCmd::DeleteNexd.into_repr_tree( &self.ctx ) + ); + + if subladder_list_edit.read().unwrap().get_cursor_warp().tree_addr.len() > 0 { + if subladder_list_edit.read().unwrap().get_cursor_warp().tree_addr[0] == -1 { + subladder_list_edit.write().unwrap().delete_nexd(); + } + } + + let l = buf.len(); + for i in 0..l { + subladder_list_edit.write().unwrap().insert( buf.get(i) ); + } + subladder_list_node.dn(); + } + } + } + } + + /* in insert mode, morph the previous element into a ladder and continue there + */ + pub fn previous_item_into_ladder(&mut self) { + eprintln!("previous_item_into_ladder()"); + let app_edit = self.cur_node.get().get_edit::().expect("editor"); + let mut app_edit = app_edit.write().unwrap(); + + let cur = app_edit.get_cursor(); + + if cur.tree_addr.len() <= 2 && cur.tree_addr.len() > 0 { + if cur.tree_addr.len() == 2 { + app_edit.delete_nexd(); + } + + 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() { + 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 => { + eprintln!("current item is already ladder"); + drop(item_typterm); + + app_edit.dn(); + app_edit.qnexd(); + } + _ => { + eprintln!("create new ladder"); + 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(), 0 ).unwrap(); + list_node = list_node.morph( (&self.ctx, "( Type::Ladder )").into() ); + + let mut new_node = TypeTermEditor::with_node( + self.ctx.clone(), + 0, + 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; + /* + let mut c = app_edit.cursor.get(); + c.mode = ListCursorMode::Select; + app_edit.goto( c ); + */ + app_edit.dn(); + } + } + } + } + } + + /* split up current + */ + pub fn morph_to_ladder(&mut self) { + let old_node = self.cur_node.get().clone(); + + /* create a new NestedNode with TerminaltypeEditor, + * that has same state & child-node as current node. + */ + let mut old_edit_node = TypeTermEditor::new_node( self.ctx.clone(), 0 ); + let mut 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(), 0 ).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( + ReprTree::new_leaf( + (&self.ctx, "( NestedNode )"), + SingletonBuffer::new( old_edit_node ).get_port().into() + ) + ); + + self.set_addr(0); + self.dn(); + + let res = self.send_cmd_obj( + ListCmd::Split.into_repr_tree( &self.ctx ) + ); + } } impl TreeNav for TypeTermEditor { @@ -347,6 +532,7 @@ impl ObjCommander for TypeTermEditor { } } } + State::Char => { match c { '\'' => { @@ -360,7 +546,6 @@ impl ObjCommander for TypeTermEditor { } State::Ladder => { - eprintln!("have LADDER, send cmd tochild"); let res = self.send_child_cmd( co ); let cur = self.get_cursor(); @@ -369,96 +554,35 @@ impl ObjCommander for TypeTermEditor { if cur.tree_addr.len() == 3 { match c { '~' => { - let mut ladder_node = self.cur_node.get().clone(); - let mut ladder_edit = ladder_node.get_edit::().unwrap(); - - let item = ladder_edit.write().unwrap().get_item().clone(); - - if let Some(mut it_node) = item { - if it_node.get_type() == (&self.ctx, "( Type )").into() { - let other_tt = it_node.get_edit::().unwrap(); - let other = other_tt.read().unwrap().cur_node.get().get_edit::().unwrap(); - let buf = other.read().unwrap().data.clone(); - - ladder_edit.write().unwrap().up(); - ladder_edit.write().unwrap().up(); - - ladder_node.send_cmd_obj( - ListCmd::DeleteNexd.into_repr_tree( &self.ctx ) - ); - //ladder_edit.write().unwrap().delete_nexd(); - - let l = buf.len(); - for i in 0..l { - ladder_edit.write().unwrap().insert( buf.get(i) ); - } - ladder_node.dn(); - - TreeNavResult::Continue - } else { - TreeNavResult::Continue - } - } else { - TreeNavResult::Continue - } + self.normalize_nested_ladder(); + self.normalize_singleton(); } - _=> res + _ => {} } - } else { - TreeNavResult::Continue + } + TreeNavResult::Continue + } + TreeNavResult::Exit => { + match c { + '~' => TreeNavResult::Continue, + _ => TreeNavResult::Exit } } - res => res, } } State::App => { - let res = self.send_child_cmd( co ); + let res = self.send_child_cmd( co.clone() ); + + if let Some(cmd) = co.read().unwrap().get_view::>() { + + } match res { TreeNavResult::Exit => { match c { '~' => { - // if item at cursor is Ladder - let app_edit = self.cur_node.get().get_edit::().expect("editor"); - let mut app_edit = app_edit.write().unwrap(); - app_edit.delete_nexd(); - app_edit.pxev(); - - 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 { - State::Ladder => { - drop(item_typterm); - - app_edit.dn(); - app_edit.qnexd(); - } - _ => { - eprintln!("create new ladder"); - - // else create enw ladder - let mut new_node = Context::make_node( &self.ctx, (&self.ctx, "( List Type )").into(), 0 ).unwrap(); - new_node = new_node.morph( (&self.ctx, "( Type::Ladder )").into() ); - // 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() - ) - ); - - drop(item_typterm); - *app_edit.get_item_mut().unwrap().write().unwrap() = new_node; - app_edit.dn(); - } - } - } - + self.previous_item_into_ladder(); TreeNavResult::Continue }, _ => {TreeNavResult::Exit} @@ -466,53 +590,17 @@ impl ObjCommander for TypeTermEditor { }, res => res } - } + } - State::AnySymbol | State::FunSymbol | State::VarSymbol | State::App => { + State::AnySymbol | + State::FunSymbol | + State::VarSymbol => { let res = self.send_child_cmd( co ); match res { TreeNavResult::Exit => { match c { '~' => { - eprintln!("typeterm: ~ "); - - let old_node = self.cur_node.get().clone(); - - // create a new NestedNode with TerminaltypeEditor, - // that has same data as current node. - let mut old_edit_node = TypeTermEditor::new_node( self.ctx.clone(), 0 ); - let mut 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(), 0 ).unwrap(); - new_node = new_node.morph( (&self.ctx, "( Type::Ladder )").into() ); - - eprintln!("insert old node into new node"); - - // insert old node and split - new_node.goto(TreeCursor::home()); - new_node.send_cmd_obj( - ReprTree::new_leaf( - (&self.ctx, "( NestedNode )"), - SingletonBuffer::new( old_edit_node ).get_port().into() - ) - ); - - new_node.set_addr(0); - new_node.dn(); - - let res = new_node.send_cmd_obj( - ListCmd::Split.into_repr_tree( &self.ctx ) - ); - - // reconfigure current node to display new_node - self.close_char.set(new_node.close_char.get()); - self.cur_node.set(new_node); - self.state = State::Ladder; - + self.morph_to_ladder(); TreeNavResult::Continue } _ => { @@ -536,14 +624,32 @@ impl ObjCommander for TypeTermEditor { } else { match &self.state { State::Any => { - self.set_state( State::AnySymbol ); + let cmd_repr = co.read().unwrap(); + if cmd_repr.get_type().clone() == (&self.ctx, "( NestedNode )").into() { + if let Some(view) = cmd_repr.get_view::>() { + let node = view.get(); + + if node.data.read().unwrap().get_type().clone() == (&self.ctx, "( Char )").into() { + self.set_state( State::AnySymbol ); + } else { + self.set_state( State::Ladder ); + } + } else { + eprintln!("ERROR"); + } + } else { + self.set_state( State::AnySymbol ); + } + self.cur_node.get_mut().goto(TreeCursor::home()); } _ => { } } - self.send_child_cmd( co ) + let res = self.send_child_cmd( co ); + + res } } } diff --git a/nested/src/tree/cursor.rs b/nested/src/tree/cursor.rs index bd0a4fb..98c0984 100644 --- a/nested/src/tree/cursor.rs +++ b/nested/src/tree/cursor.rs @@ -4,7 +4,7 @@ use { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -#[derive(Clone, Eq, PartialEq)] +#[derive(Clone, Eq, PartialEq, Debug)] pub struct TreeCursor { pub leaf_mode: ListCursorMode, pub tree_addr: Vec,