fix list split/join & more edge cases in typetermeditor

This commit is contained in:
Michael Sippel 2023-09-04 01:24:53 +02:00
parent b386fee6eb
commit e111a360a9
Signed by: senvas
GPG key ID: F96CF119C34B64A6
7 changed files with 486 additions and 336 deletions

View file

@ -60,110 +60,101 @@ impl ObjCommander for ListEditor {
else if let Some(cmd) = cmd_repr.get_view::<dyn SingletonView<Item = ListCmd>>() { else if let Some(cmd) = cmd_repr.get_view::<dyn SingletonView<Item = ListCmd>>() {
let cur = self.cursor.get(); let cur = self.cursor.get();
drop(cmd_repr); 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() { match cmd.get() {
ListCmd::DeletePxev => { ListCmd::DeletePxev => {
if idx > 0 self.delete_pxev();
&& 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();
TreeNavResult::Continue TreeNavResult::Continue
} }
ListCmd::DeleteNexd => {
_ => { self.delete_nexd();
eprintln!("list edit: give cmd to child"); TreeNavResult::Continue
}
match item.send_cmd_obj(cmd_obj) { ListCmd::Split => {
TreeNavResult::Continue => TreeNavResult::Continue, self.split();
TreeNavResult::Exit => { TreeNavResult::Exit
TreeNavResult::Continue }
/* ListCmd::Close => {
match cmd.get() { self.goto(TreeCursor::none());
ListCmd::Split => { TreeNavResult::Exit
}, }
_ => { _ =>{
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 { } else {
if let Some(cur_item) = self.get_item_mut() { if let Some(cur_item) = self.get_item_mut() {

View file

@ -1,4 +1,4 @@
#[derive(Clone, Copy, Eq, PartialEq)] #[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub enum ListCursorMode { pub enum ListCursorMode {
Insert, Insert,
Select Select
@ -10,7 +10,7 @@ impl Default for ListCursorMode {
} }
} }
#[derive(Clone, Copy, Eq, PartialEq)] #[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub struct ListCursor { pub struct ListCursor {
pub mode: ListCursorMode, pub mode: ListCursorMode,
pub idx: Option<isize>, pub idx: Option<isize>,
@ -34,7 +34,7 @@ impl ListCursor {
impl Default for ListCursor { impl Default for ListCursor {
fn default() -> Self { fn default() -> Self {
ListCursor::none() ListCursor::home()
} }
} }

View file

@ -52,7 +52,12 @@ impl ListEditor {
ListCursorMode::Insert => ip, ListCursorMode::Insert => ip,
ListCursorMode::Select => { ListCursorMode::Select => {
if let Some(idx) = c.idx { 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 { } else {
ip ip
} }
@ -191,6 +196,12 @@ impl ListEditor {
/// delete all items /// delete all items
pub fn clear(&mut self) { 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.data.clear();
self.cursor.set(ListCursor::home()); self.cursor.set(ListCursor::home());
} }
@ -257,7 +268,8 @@ impl ListEditor {
} }
/* TODO /* TODO
*/
/*
if self.is_listlist() { if self.is_listlist() {
if idx > 0 && idx < self.data.len()+1 { 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) { pub fn listlist_split(&mut self) {
let cur = self.get_cursor(); let cur = self.get_cursor();
eprintln!("listlist_split(): cur = {:?}", cur);
if let Some(mut item) = self.get_item().clone() { 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)); 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(); if cur.tree_addr.len() < 3 {
tail_node.goto(TreeCursor::home()); 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(); let mut b = item.spillbuf.write().unwrap();
for node in b.iter() { for node in b.iter() {
tail_node tail_node
.send_cmd_obj( .send_cmd_obj(
ReprTree::new_leaf( ReprTree::new_leaf(
(&self.ctx, "( NestedNode )"), (&self.ctx, "( NestedNode )"),
SingletonBuffer::<NestedNode>::new( SingletonBuffer::<NestedNode>::new(
node.read().unwrap().clone() node.read().unwrap().clone()
).get_port().into() ).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
}
} }
); b.clear();
drop(b);
drop(item);
self.insert( self.set_leaf_mode(ListCursorMode::Insert);
Arc::new(RwLock::new(tail_node)) 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 cur_editor = self.data.get(idx as usize);
let prev_editor = prev_editor.read().unwrap(); 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() { let oc0 = cur_editor.get_cursor();
if let Ok(prev_editor) = prev_editor.downcast::<RwLock<ListEditor>>() {
let mut prev_editor = prev_editor.write().unwrap();
let cur_editor = item.editor.get().unwrap(); // tell cur_editor move all its elements into its spill-buffer
let cur_editor = cur_editor.downcast::<RwLock<ListEditor>>().unwrap(); cur_editor.goto(TreeCursor::none());
let cur_editor = cur_editor.write().unwrap(); 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( let data = cur_editor.spillbuf.read().unwrap();
ListCursor { for x in data.iter() {
idx: Some(idx - 1), mode: ListCursorMode::Select pxv_editor.send_cmd_obj(
} ReprTree::new_leaf(
); (&self.ctx, "( NestedNode )"),
} SingletonBuffer::<NestedNode>::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); 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 cur_editor = self.data.get(idx);
let next_editor = next_editor.read().unwrap(); let nxd_editor = self.data.get(idx + 1);
if let Some(next_editor) = next_editor.editor.get() { let mut cur_editor = cur_editor.write().unwrap();
if let Ok(next_editor) = next_editor.downcast::<RwLock<ListEditor>>() { let mut nxd_editor = nxd_editor.write().unwrap();
let next_editor = next_editor.write().unwrap();
let cur_editor = item.editor.get().unwrap();
let cur_editor = cur_editor.downcast::<RwLock<ListEditor>>().unwrap();
let mut cur_editor = cur_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::<NestedNode>::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 {
} }
*/ */

View file

@ -152,7 +152,9 @@ impl PTYListController {
let cur = e.cursor.get(); let cur = e.cursor.get();
if Some(c) == self.split_char { if Some(c) == self.split_char {
eprintln!("handle meta char: --> e.listlist_split()");
e.listlist_split(); e.listlist_split();
eprintln!("e.listlist_split() DONE");
TreeNavResult::Continue TreeNavResult::Continue
} else if Some(c) == child_close_char { } else if Some(c) == child_close_char {
e.goto(TreeCursor::none()); e.goto(TreeCursor::none());

View file

@ -4,7 +4,7 @@ use {
}, },
crate::{ crate::{
type_system::{Context, TypeTerm, MorphismTypePattern}, type_system::{Context, TypeTerm, MorphismTypePattern},
terminal::{TerminalStyle}, terminal::{TerminalStyle, TerminalProjections},
editors::{list::{PTYListStyle, PTYListController}, typeterm::{State, TypeTermEditor}} editors::{list::{PTYListStyle, PTYListController}, typeterm::{State, TypeTermEditor}}
}, },
std::{sync::{Arc, RwLock}}, std::{sync::{Arc, RwLock}},
@ -34,11 +34,11 @@ pub fn init_ctx(ctx: &mut Context) {
Arc::new(|mut node, _dst_type: _| { Arc::new(|mut node, _dst_type: _| {
PTYListController::for_node( &mut node, Some('~'), None ); PTYListController::for_node( &mut node, Some('~'), None );
let vertical_view = true; let vertical_view = false;
if vertical_view { if vertical_view {
let editor = node.get_edit::<crate::editors::list::ListEditor>().unwrap(); let editor = node.get_edit::<crate::editors::list::ListEditor>().unwrap();
let mut e = editor.write().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( node = node.set_view(
seg_view.to_grid_vertical().flatten() seg_view.to_grid_vertical().flatten()
@ -95,14 +95,14 @@ pub fn init_ctx(ctx: &mut Context) {
})); }));
ctx.add_morphism( 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:_| { Arc::new(|mut node, _dst_type:_| {
let mut grid = r3vi::buffer::index_hashmap::IndexBuffer::new(); let mut grid = r3vi::buffer::index_hashmap::IndexBuffer::new();
grid.insert_iter( grid.insert_iter(
vec![ vec![
(Point2::new(0,0), crate::terminal::make_label("'")), (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("'")), (Point2::new(2,0), crate::terminal::make_label("'")),
] ]
); );

View file

@ -30,14 +30,17 @@ pub enum State {
} }
pub struct TypeTermEditor { pub struct TypeTermEditor {
// shared with NestedNode that contains self
ctx: Arc<RwLock<Context>>, ctx: Arc<RwLock<Context>>,
data: Arc<RwLock<ReprTree>>, data: Arc<RwLock<ReprTree>>,
// references to Node pointing to TypeTermEditor
close_char: SingletonBuffer<Option<char>>, close_char: SingletonBuffer<Option<char>>,
spillbuf: Arc<RwLock<Vec<Arc<RwLock<NestedNode>>>>>, spillbuf: Arc<RwLock<Vec<Arc<RwLock<NestedNode>>>>>,
// editing/parsing state
state: State, state: State,
// child node
cur_node: SingletonBuffer< NestedNode > cur_node: SingletonBuffer< NestedNode >
} }
@ -55,8 +58,7 @@ impl TypeTermEditor {
}); });
let typename = ctx.read().unwrap().get_typename(&tyid).unwrap_or("UNNAMED TYPE".into()); 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( node.send_cmd_obj(
ReprTree::from_char( &ctx, x ) ReprTree::from_char( &ctx, x )
); );
@ -101,20 +103,21 @@ impl TypeTermEditor {
TypeTerm::Num( n ) => { TypeTerm::Num( n ) => {
let editor = node.get_edit::<TypeTermEditor>().expect("typ term edit"); let editor = node.get_edit::<TypeTermEditor>().expect("typ term edit");
let parent_ctx = editor.read().unwrap().cur_node.get().ctx.clone(); 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 mut editor = editor.write().unwrap();
let node = int_edit.into_node(); editor.cur_node.set(
editor.write().unwrap().cur_node.set(node); crate::editors::integer::PosIntEditor::from_u64(parent_ctx, 10, *n as u64)
editor.write().unwrap().state = State::Num; .into_node()
);
editor.state = State::Num;
} }
TypeTerm::Char( c ) => { TypeTerm::Char( c ) => {
let editor = node.get_edit::<TypeTermEditor>().expect("typ term edit"); let editor = node.get_edit::<TypeTermEditor>().expect("typ term edit");
let mut editor = editor.write().unwrap();
editor.write().unwrap().set_state( State::Char ); editor.set_state( State::Char );
editor.write().unwrap().send_cmd_obj(ReprTree::from_char(&ctx, *c)); editor.send_cmd_obj(ReprTree::from_char(&ctx, *c));
} }
_ => {} _ => {}
@ -196,10 +199,9 @@ impl TypeTermEditor {
let editor = TypeTermEditor { let editor = TypeTermEditor {
ctx: ctx.clone(), ctx: ctx.clone(),
state,
data: data.clone(), data: data.clone(),
state,
cur_node: SingletonBuffer::new(node), cur_node: SingletonBuffer::new(node),
//editor: SingletonBuffer::new(None),
close_char: SingletonBuffer::new(None), close_char: SingletonBuffer::new(None),
spillbuf: Arc::new(RwLock::new(Vec::new())) spillbuf: Arc::new(RwLock::new(Vec::new()))
}; };
@ -227,7 +229,6 @@ impl TypeTermEditor {
} }
fn forward_spill(&mut self) { fn forward_spill(&mut self) {
eprintln!("forward spill");
let node = self.cur_node.get(); let node = self.cur_node.get();
let mut buf = node.spillbuf.write().unwrap(); let mut buf = node.spillbuf.write().unwrap();
for n in buf.iter() { for n in buf.iter() {
@ -237,12 +238,12 @@ impl TypeTermEditor {
} }
fn send_child_cmd(&mut self, cmd: Arc<RwLock<ReprTree>>) -> TreeNavResult { fn send_child_cmd(&mut self, cmd: Arc<RwLock<ReprTree>>) -> TreeNavResult {
eprintln!("typterm forward cmd"); eprintln!("send child cmd");
let res = self.cur_node.get_mut().send_cmd_obj( cmd ); let res = self.cur_node.get_mut().send_cmd_obj( cmd );
self.forward_spill(); self.forward_spill();
res res
} }
fn get_typeterm(&self) -> Option<TypeTerm> { fn get_typeterm(&self) -> Option<TypeTerm> {
match self.state { match self.state {
State::Any => None, State::Any => None,
@ -267,6 +268,7 @@ impl TypeTermEditor {
*/ */
Some(TypeTerm::new(TypeID::Fun(0))) Some(TypeTerm::new(TypeID::Fun(0)))
}, },
State::App => { State::App => {
Some(TypeTerm::new(TypeID::Fun(0))) Some(TypeTerm::new(TypeID::Fun(0)))
}, },
@ -280,6 +282,189 @@ impl TypeTermEditor {
_ => {None} _ => {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::<ListEditor>().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::<TypeTermEditor>().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::<ListEditor>().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::<TypeTermEditor>().unwrap();
if other_tt.write().unwrap().state == State::Ladder {
let other = other_tt.read().unwrap().cur_node.get().get_edit::<ListEditor>().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::<ListEditor>().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::<TypeTermEditor>().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::<NestedNode>::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::<TypeTermEditor>().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 { impl TreeNav for TypeTermEditor {
@ -347,6 +532,7 @@ impl ObjCommander for TypeTermEditor {
} }
} }
} }
State::Char => { State::Char => {
match c { match c {
'\'' => { '\'' => {
@ -360,7 +546,6 @@ impl ObjCommander for TypeTermEditor {
} }
State::Ladder => { State::Ladder => {
eprintln!("have LADDER, send cmd tochild");
let res = self.send_child_cmd( co ); let res = self.send_child_cmd( co );
let cur = self.get_cursor(); let cur = self.get_cursor();
@ -369,96 +554,35 @@ impl ObjCommander for TypeTermEditor {
if cur.tree_addr.len() == 3 { if cur.tree_addr.len() == 3 {
match c { match c {
'~' => { '~' => {
let mut ladder_node = self.cur_node.get().clone(); self.normalize_nested_ladder();
let mut ladder_edit = ladder_node.get_edit::<ListEditor>().unwrap(); self.normalize_singleton();
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::<TypeTermEditor>().unwrap();
let other = other_tt.read().unwrap().cur_node.get().get_edit::<ListEditor>().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
}
} }
_=> res _ => {}
} }
} else { }
TreeNavResult::Continue TreeNavResult::Continue
}
TreeNavResult::Exit => {
match c {
'~' => TreeNavResult::Continue,
_ => TreeNavResult::Exit
} }
} }
res => res,
} }
} }
State::App => { 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::<dyn SingletonView<Item = ListCmd>>() {
}
match res { match res {
TreeNavResult::Exit => { TreeNavResult::Exit => {
match c { match c {
'~' => { '~' => {
// if item at cursor is Ladder self.previous_item_into_ladder();
let app_edit = self.cur_node.get().get_edit::<ListEditor>().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::<TypeTermEditor>().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::<NestedNode>::new( item_node ).get_port().into()
)
);
drop(item_typterm);
*app_edit.get_item_mut().unwrap().write().unwrap() = new_node;
app_edit.dn();
}
}
}
TreeNavResult::Continue TreeNavResult::Continue
}, },
_ => {TreeNavResult::Exit} _ => {TreeNavResult::Exit}
@ -466,53 +590,17 @@ impl ObjCommander for TypeTermEditor {
}, },
res => res res => res
} }
} }
State::AnySymbol | State::FunSymbol | State::VarSymbol | State::App => { State::AnySymbol |
State::FunSymbol |
State::VarSymbol => {
let res = self.send_child_cmd( co ); let res = self.send_child_cmd( co );
match res { match res {
TreeNavResult::Exit => { TreeNavResult::Exit => {
match c { match c {
'~' => { '~' => {
eprintln!("typeterm: ~ "); self.morph_to_ladder();
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::<TypeTermEditor>().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;
TreeNavResult::Continue TreeNavResult::Continue
} }
_ => { _ => {
@ -536,14 +624,32 @@ impl ObjCommander for TypeTermEditor {
} else { } else {
match &self.state { match &self.state {
State::Any => { 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::<dyn SingletonView<Item = NestedNode>>() {
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.cur_node.get_mut().goto(TreeCursor::home());
} }
_ => { _ => {
} }
} }
self.send_child_cmd( co ) let res = self.send_child_cmd( co );
res
} }
} }
} }

View file

@ -4,7 +4,7 @@ use {
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
#[derive(Clone, Eq, PartialEq)] #[derive(Clone, Eq, PartialEq, Debug)]
pub struct TreeCursor { pub struct TreeCursor {
pub leaf_mode: ListCursorMode, pub leaf_mode: ListCursorMode,
pub tree_addr: Vec<isize>, pub tree_addr: Vec<isize>,