fix list split/join & more edge cases in typetermeditor
This commit is contained in:
parent
b386fee6eb
commit
e111a360a9
7 changed files with 486 additions and 336 deletions
|
@ -60,110 +60,101 @@ impl ObjCommander for ListEditor {
|
|||
else if let Some(cmd) = cmd_repr.get_view::<dyn SingletonView<Item = ListCmd>>() {
|
||||
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() {
|
||||
|
|
|
@ -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<isize>,
|
||||
|
@ -34,7 +34,7 @@ impl ListCursor {
|
|||
|
||||
impl Default for ListCursor {
|
||||
fn default() -> Self {
|
||||
ListCursor::none()
|
||||
ListCursor::home()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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::<NestedNode>::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::<NestedNode>::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::<RwLock<ListEditor>>() {
|
||||
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::<RwLock<ListEditor>>().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::<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);
|
||||
}
|
||||
|
||||
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::<RwLock<ListEditor>>() {
|
||||
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();
|
||||
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::<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 {
|
|||
}
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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::<crate::editors::list::ListEditor>().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("'")),
|
||||
]
|
||||
);
|
||||
|
|
|
@ -30,14 +30,17 @@ pub enum State {
|
|||
}
|
||||
|
||||
pub struct TypeTermEditor {
|
||||
|
||||
// shared with NestedNode that contains self
|
||||
ctx: Arc<RwLock<Context>>,
|
||||
data: Arc<RwLock<ReprTree>>,
|
||||
|
||||
// references to Node pointing to TypeTermEditor
|
||||
close_char: SingletonBuffer<Option<char>>,
|
||||
spillbuf: Arc<RwLock<Vec<Arc<RwLock<NestedNode>>>>>,
|
||||
|
||||
// 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::<TypeTermEditor>().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::<TypeTermEditor>().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<RwLock<ReprTree>>) -> 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<TypeTerm> {
|
||||
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::<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 {
|
||||
|
@ -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::<ListEditor>().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::<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
|
||||
}
|
||||
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::<dyn SingletonView<Item = ListCmd>>() {
|
||||
|
||||
}
|
||||
|
||||
match res {
|
||||
TreeNavResult::Exit => {
|
||||
match c {
|
||||
'~' => {
|
||||
// if item at cursor is 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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::<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;
|
||||
|
||||
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::<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.send_child_cmd( co )
|
||||
let res = self.send_child_cmd( co );
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<isize>,
|
||||
|
|
Loading…
Reference in a new issue