typeterm editor: improve morphings

This commit is contained in:
Michael Sippel 2023-09-14 13:17:50 +02:00
parent 6c80865229
commit 119105c6a2
Signed by: senvas
GPG key ID: F96CF119C34B64A6
9 changed files with 195 additions and 144 deletions

View file

@ -151,16 +151,16 @@ impl ObjCommander for ListEditor {
} else { } else {
TreeNavResult::Exit TreeNavResult::Exit
} }
} }
} }
} else { } else {
if let Some(cur_item) = self.get_item_mut() { if let Some(cur_item) = self.get_item_mut() {
drop(cmd_repr); drop(cmd_repr);
cur_item.write().unwrap().send_cmd_obj(cmd_obj) cur_item.write().unwrap().send_cmd_obj(cmd_obj);
} else {
TreeNavResult::Continue TreeNavResult::Continue
} else {
TreeNavResult::Exit
} }
} }
} }

View file

@ -10,7 +10,7 @@ use {
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub fn init_ctx(ctx: &mut Context) { 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_list_typename("List".into());
ctx.add_node_ctor( ctx.add_node_ctor(

View file

@ -232,14 +232,15 @@ impl ListEditor {
/// insert a new element /// insert a new element
pub fn insert(&mut self, item: Arc<RwLock<NestedNode>>) { pub fn insert(&mut self, item: Arc<RwLock<NestedNode>>) {
eprintln!("list insert");
item.read().unwrap().depth.0.set_view(
self.depth.map(|d| d+1).get_view()
);
let mut cur = self.cursor.get(); let mut cur = self.cursor.get();
if let Some(idx) = cur.idx { if let Some(idx) = cur.idx {
match cur.mode { match cur.mode {
ListCursorMode::Insert => { 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()); self.data.insert(idx as usize, item.clone());
if self.is_listlist() { if self.is_listlist() {
cur.mode = ListCursorMode::Select; cur.mode = ListCursorMode::Select;
@ -264,6 +265,7 @@ impl ListEditor {
/// split the list off at the current cursor position and return the second half /// 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(); let cur = self.cursor.get();
if let Some(idx) = cur.idx { if let Some(idx) = cur.idx {
let idx = idx as usize; let idx = idx as usize;
@ -277,6 +279,7 @@ impl ListEditor {
} }
pub fn listlist_split(&mut self) { pub fn listlist_split(&mut self) {
eprintln!("listlist split");
let cur = self.get_cursor(); let cur = self.get_cursor();
if let Some(mut item) = self.get_item().clone() { if let Some(mut item) = self.get_item().clone() {
@ -293,6 +296,7 @@ impl ListEditor {
tail_node.goto(TreeCursor::home()); tail_node.goto(TreeCursor::home());
for node in b.iter() { for node in b.iter() {
eprintln!("splid :send to tail node");
tail_node tail_node
.send_cmd_obj( .send_cmd_obj(
ReprTree::new_leaf( ReprTree::new_leaf(

View file

@ -216,10 +216,12 @@ impl TreeNav for ListEditor {
.write().unwrap() .write().unwrap()
.goby(Vector2::new(direction.x, direction.y)) .goby(Vector2::new(direction.x, direction.y))
== TreeNavResult::Continue { == TreeNavResult::Continue {
self.cursor.set(ListCursor { let res = self.cursor.set(ListCursor {
mode: ListCursorMode::Select, mode: ListCursorMode::Select,
idx: Some(cur.tree_addr[0]) idx: Some(cur.tree_addr[0])
}) });
self.set_leaf_mode(cur.leaf_mode);
res
} }
} }

View file

@ -147,6 +147,7 @@ impl PTYListController {
// || Some(c) == child_close_char // || Some(c) == child_close_char
{ {
e.listlist_split(); e.listlist_split();
eprintln!("done listlist split");
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

@ -52,75 +52,138 @@ impl ObjCommander for TypeTermEditor {
} }
State::Char => { State::Char => {
match c { match self.send_child_cmd( co ) {
'\'' => { TreeNavResult::Exit => {
self.cur_node.get_mut().goto(TreeCursor::none()); match c {
'\'' => {
self.cur_node.get_mut().goto(TreeCursor::none());
}
_ => {}
}
TreeNavResult::Exit TreeNavResult::Exit
} },
_ => { TreeNavResult::Continue => TreeNavResult::Continue
self.send_child_cmd( co )
}
} }
} }
State::Ladder => { State::Ladder => {
if c == '~' {
let i0 = self.cur_node.get().get_edit::<ListEditor>().unwrap();
if self.get_cursor().tree_addr.len() > 1 { match self.get_cursor().tree_addr.len() {
let cur_it = i0.clone().read().unwrap().get_item().clone();
if let Some(i) = cur_it {
let tte = i.get_edit::<TypeTermEditor>().unwrap();
if tte.read().unwrap().state != State::App { // entire term is selected
drop(tte); 0 => {
drop(i); match c {
'<' => {
self.morph_to_list(State::App);
TreeNavResult::Continue
}
_ => { TreeNavResult::Exit }
}
}
return self.send_child_cmd( // entire item selected or insert mode
ListCmd::Split.into_repr_tree( &self.ctx ) 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::<ListEditor>().unwrap();
let cur_it = i0.clone().read().unwrap().get_item().clone();
if let Some(i) = cur_it {
let cur_tte = i.get_edit::<TypeTermEditor>().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 => { State::App => {
let res = self.send_child_cmd( co.clone() );
match res { match self.get_cursor().tree_addr.len() {
TreeNavResult::Exit => {
// entire Term is selected
0 => {
match c { 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::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::<ListEditor>().unwrap();
let i = i.read().unwrap();
if let Some(i) = i.get_item() {
let tte = i.get_edit::<TypeTermEditor>().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::<ListEditor>().unwrap();
let i = i.read().unwrap();
if let Some(i) = i.get_item() {
let tte = i.get_edit::<TypeTermEditor>().unwrap();
let mut tte = tte.write().unwrap();
TreeNavResult::Continue if tte.state == State::Ladder {
tte.normalize_singleton();
}
}
},
_ => {}
}
TreeNavResult::Continue
}
}
} }
} }
} }
@ -132,11 +195,19 @@ impl ObjCommander for TypeTermEditor {
match res { match res {
TreeNavResult::Exit => { TreeNavResult::Exit => {
match c { 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( self.send_cmd_obj(
ListCmd::Split.into_repr_tree( &self.ctx ) ListCmd::Split.into_repr_tree( &self.ctx )
) );
TreeNavResult::Continue
} }
_ => { _ => {
TreeNavResult::Exit TreeNavResult::Exit
@ -188,7 +259,6 @@ impl ObjCommander for TypeTermEditor {
let res = self.send_child_cmd( co.clone() ); let res = self.send_child_cmd( co.clone() );
self.normalize_empty(); self.normalize_empty();
if let Some(cmd) = co.read().unwrap().get_view::<dyn SingletonView<Item = ListCmd>>() { if let Some(cmd) = co.read().unwrap().get_view::<dyn SingletonView<Item = ListCmd>>() {
match cmd.get() { match cmd.get() {
ListCmd::Split => { ListCmd::Split => {

View file

@ -41,14 +41,29 @@ 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 = false; let vertical_view = true;
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 seg_view = PTYListStyle::new( ("","~","") ).get_seg_seq_view( &mut e ); let seg_view = PTYListStyle::new( ("","~","") ).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()
.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 { } else {
PTYListStyle::for_node( &mut node, ("","~","") ); PTYListStyle::for_node( &mut node, ("","~","") );
@ -100,6 +115,7 @@ pub fn init_ctx(ctx: &mut Context) {
ctx.add_morphism( ctx.add_morphism(
MorphismTypePattern { src_tyid: ctx.get_typeid("Char"), 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:_| {
node.ctx.write().unwrap().meta_chars = vec![ '\'' ];
let mut grid = r3vi::buffer::index_hashmap::IndexBuffer::new(); let mut grid = r3vi::buffer::index_hashmap::IndexBuffer::new();
grid.insert_iter( grid.insert_iter(

View file

@ -177,6 +177,7 @@ impl TypeTermEditor {
pub fn new_node(ctx: Arc<RwLock<Context>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> NestedNode { pub fn new_node(ctx: Arc<RwLock<Context>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> NestedNode {
let ctx : Arc<RwLock<Context>> = Arc::new(RwLock::new(Context::with_parent(Some(ctx)))); let ctx : Arc<RwLock<Context>> = Arc::new(RwLock::new(Context::with_parent(Some(ctx))));
ctx.write().unwrap().meta_chars.push('~'); 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(); let mut symb_node = Context::make_node( &ctx, (&ctx, "( List Char )").into(), depth ).unwrap();
symb_node = symb_node.morph( (&ctx, "( Type::Sym )").into() ); symb_node = symb_node.morph( (&ctx, "( Type::Sym )").into() );
@ -298,31 +299,28 @@ impl TypeTermEditor {
pub fn normalize_singleton(&mut self) { pub fn normalize_singleton(&mut self) {
eprintln!("normalize singleton"); eprintln!("normalize singleton");
if self.state == State::Ladder{ if self.state == State::Ladder {
let subladder_list_node = self.cur_node.get().clone();
let subladder_list_edit = subladder_list_node.get_edit::<ListEditor>().unwrap();
let subladder_list_node = self.cur_node.get().clone(); let subladder_list_edit = subladder_list_edit.read().unwrap();
let subladder_list_edit = subladder_list_node.get_edit::<ListEditor>().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::<TypeTermEditor>().unwrap();
let subladder_list_edit = subladder_list_edit.read().unwrap(); let mut other_tt = other_tt.write().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::<TypeTermEditor>().unwrap();
let mut other_tt = other_tt.write().unwrap(); other_tt.normalize_singleton();
other_tt.depth.0.set_view( self.depth.map(|x| x).get_view() );
other_tt.normalize_singleton(); self.close_char.set(other_tt.close_char.get());
self.cur_node.set(other_tt.cur_node.get());
other_tt.depth.0.set_view( self.depth.map(|x| x).get_view() ); 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 /* in insert mode, morph the previous element into a ladder and continue there
@ -338,97 +336,58 @@ impl TypeTermEditor {
app_edit.delete_nexd(); app_edit.delete_nexd();
} }
// select previous element
app_edit.goto(TreeCursor{ app_edit.goto(TreeCursor{
tree_addr: vec![ cur.tree_addr[0]-1 ], tree_addr: vec![ cur.tree_addr[0]-1 ],
leaf_mode: ListCursorMode::Select 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::<TypeTermEditor>().expect("typetermedit"); let item_typterm = item_node.get_edit::<TypeTermEditor>().expect("typetermedit");
let mut item_typterm = item_typterm.write().unwrap(); let mut item_typterm = item_typterm.write().unwrap();
match item_typterm.state { if item_typterm.state != State::Ladder {
item_typterm.morph_to_list( State::Ladder );
// 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::<NestedNode>::new( item_node ).get_port().into()
)
);
*app_edit.get_item_mut().unwrap().write().unwrap() = new_node;
app_edit.dn();
}
} }
item_typterm.goto(TreeCursor {
tree_addr: vec![ -1 ],
leaf_mode: ListCursorMode::Insert
});
} }
} }
} }
// TODO: morph_to_app() / morph_to_list(state) /* replace with new list-node (ladder/app) with self as first element
/* replace with new ladder node 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"); 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, /* create a new NestedNode with TerminaltypeEditor,
* that has same state & child-node as current node. * 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)); let old_edit_node = TypeTermEditor::new_node( self.ctx.clone(), SingletonBuffer::new(0).get_port() );
old_node.depth.0.set_view( self.depth.map(|d| d + 1).get_view() ); old_node.depth.0.set_view( old_edit_node.depth.map(|x|x).get_view() );
let old_edit_clone = old_edit_node.get_edit::<TypeTermEditor>().unwrap(); let old_edit_clone = old_edit_node.get_edit::<TypeTermEditor>().unwrap();
old_edit_clone.write().unwrap().set_state( self.state ); 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 ); 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 /* insert old node and split
*/ */
self.goto(TreeCursor::home()); self.goto(TreeCursor::home());
self.send_cmd_obj( self.send_child_cmd(
ReprTree::new_leaf( ReprTree::new_leaf(
(&self.ctx, "( NestedNode )"), (&self.ctx, "( NestedNode )"),
SingletonBuffer::new( old_edit_node ).get_port().into() SingletonBuffer::new( old_edit_node ).get_port().into()
) )
); );
self.set_addr(0);
self.dn();
} }
} }

View file

@ -42,4 +42,3 @@ impl TreeNav for TypeTermEditor {
self.cur_node.get_mut().goto(new_cur) self.cur_node.get_mut().goto(new_cur)
} }
} }