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
|
@ -61,110 +61,101 @@ impl ObjCommander for ListEditor {
|
||||||
let cur = self.cursor.get();
|
let cur = self.cursor.get();
|
||||||
drop(cmd_repr);
|
drop(cmd_repr);
|
||||||
|
|
||||||
if let Some(idx) = cur.idx {
|
match cmd.get() {
|
||||||
match cur.mode {
|
ListCmd::Clear => {
|
||||||
ListCursorMode::Select => {
|
self.clear();
|
||||||
if let Some(mut item) = self.get_item().clone() {
|
TreeNavResult::Continue
|
||||||
if self.is_listlist() {
|
}
|
||||||
let item_cur = item.get_cursor();
|
_ => {
|
||||||
|
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() {
|
||||||
drop(cmd_repr);
|
drop(cmd_repr);
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 )
|
||||||
|
);
|
||||||
|
|
||||||
prev_editor.join(&cur_editor);
|
pxv_editor.goto(TreeCursor {
|
||||||
|
tree_addr: vec![-1],
|
||||||
|
leaf_mode: ListCursorMode::Insert
|
||||||
|
});
|
||||||
|
|
||||||
self.cursor.set(
|
let old_cur = pxv_editor.get_cursor();
|
||||||
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);
|
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 {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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("'")),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
|
@ -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,7 +238,7 @@ 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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
Loading…
Reference in a new issue