This commit is contained in:
Michael Sippel 2023-07-03 12:32:03 +02:00
parent 66c6478124
commit 3968baffe1
Signed by: senvas
GPG key ID: F96CF119C34B64A6
7 changed files with 132 additions and 128 deletions

View file

@ -16,7 +16,7 @@ use {
pub struct ListEditor {
pub(super) cursor: SingletonBuffer<ListCursor>,
pub data: VecBuffer<NestedNode>,
pub data: VecBuffer< Arc<RwLock<NestedNode>> >,
pub(super) addr_port: OuterViewPort<dyn SequenceView<Item = isize>>,
pub(super) mode_port: OuterViewPort<dyn SingletonView<Item = ListCursorMode>>,
@ -64,7 +64,7 @@ impl ListEditor {
typ: TypeTerm,
) -> Self {
let cursor = SingletonBuffer::new(ListCursor::default());
let data = VecBuffer::<NestedNode>::new();
let data = VecBuffer::<Arc<RwLock<NestedNode>>>::new();
ListEditor {
mode_port: cursor
@ -77,7 +77,7 @@ impl ListEditor {
ListCursorMode::Insert => ip,
ListCursorMode::Select => {
if let Some(idx) = c.idx {
data.get(idx as usize).get_mode_view()
data.get(idx as usize).read().unwrap().get_mode_view()
} else {
ip
}
@ -99,7 +99,7 @@ impl ListEditor {
if cur.mode == ListCursorMode::Select {
if let Some(idx) = cur.idx {
if idx >= 0 && idx < data.len() as isize {
return data.get(idx as usize).get_addr_view();
return data.get(idx as usize).read().unwrap().get_addr_view();
}
}
}
@ -131,7 +131,7 @@ impl ListEditor {
.set_data(data)
.set_editor(editor.clone())
.set_nav(editor.clone())
//.set_cmd(editor.clone())
//.set_cmd(editor.clone())
.set_diag(e
.get_data_port()
.enumerate()
@ -169,7 +169,9 @@ impl ListEditor {
}
pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = NestedNode>> {
self.data.get_port().to_sequence()
self.data.get_port().to_sequence().map(
|x| x.read().unwrap().clone()
)
}
pub fn get_data(&self) -> Arc<RwLock<ReprTree>> {
@ -184,7 +186,7 @@ impl ListEditor {
if let Some(idx) = self.cursor.get().idx {
let idx = crate::utils::modulo(idx as isize, self.data.len() as isize) as usize;
if idx < self.data.len() {
Some(self.data.get(idx))
Some(self.data.get(idx).read().unwrap().clone())
} else {
None
}
@ -193,7 +195,7 @@ impl ListEditor {
}
}
pub fn get_item_mut(&mut self) -> Option<MutableVecAccess<NestedNode>> {
pub fn get_item_mut(&mut self) -> Option<MutableVecAccess<Arc<RwLock<NestedNode>>>> {
if let Some(idx) = self.cursor.get().idx {
let idx = crate::utils::modulo(idx as isize, self.data.len() as isize) as usize;
if idx < self.data.len() {
@ -208,14 +210,6 @@ impl ListEditor {
pub fn is_listlist(&self) -> bool {
self.ctx.read().unwrap().is_list_type(&self.typ)
/*
match self.typ.clone() {
TypeTerm::Type { id, args } => {
id == self.ctx.read().unwrap().get_typeid("List").unwrap()
},
TypeTerm::Num(_) => false
}
*/
}
/// delete all items
@ -246,10 +240,9 @@ impl ListEditor {
}
/// insert a new element
pub fn insert(&mut self, item: NestedNode) {
pub fn insert(&mut self, item: Arc<RwLock<NestedNode>>) {
let mut cur = self.cursor.get();
if let Some(idx) = cur.idx {
match cur.mode {
ListCursorMode::Insert => {
self.data.insert(idx as usize, item.clone());
@ -276,6 +269,7 @@ impl ListEditor {
/// split the list off at the current cursor position and return the second half
pub fn split(&mut self) -> ListEditor {
eprintln!("split!");
let mut le = ListEditor::new(
Arc::new(RwLock::new(self.ctx.read().unwrap().clone())),
self.typ.clone());
@ -290,12 +284,16 @@ impl ListEditor {
if self.is_listlist() {
if idx > 0 && idx < self.data.len()+1 {
let prev_idx = idx - 1; // we are in insert mode, last element before cursor
let prev_node = self.data.get(prev_idx);
if let Some(prev_editor) = prev_node.editor.clone() {
prev_editor.0.update();
let prev_editor = prev_editor.get_view().unwrap().get().unwrap().downcast::<RwLock<ListEditor>>().unwrap();
eprintln!("try locking prev node");
let prev_node = prev_node.read().unwrap();
eprintln!("locked prev node");
if let Some(prev_editor) = prev_node.editor.get() {
let prev_editor = prev_editor.downcast::<RwLock<ListEditor>>().unwrap();
let prev_editor = prev_editor.write().unwrap();
prev_editor.get_data_port().0.update();
@ -347,24 +345,28 @@ impl ListEditor {
}
}
pub fn listlist_split(&mut self) {
eprintln!("listlist split");
let cur = self.get_cursor();
if let Some(item) = self.get_item_mut() {
eprintln!("cur = {:?}", cur);
if let Some(item) = self.get_item() {
eprintln!("got item");
// let item = item.read().unwrap();
let depth = item.depth;
if let Some(head_editor) = item.editor.clone() {
head_editor.0.update();
let head = head_editor.get_view().unwrap().get().unwrap().downcast::<RwLock<ListEditor>>().unwrap();
if let Some(head_editor) = item.editor.get() {
eprintln!("got head editor");
let head = head_editor.downcast::<RwLock<ListEditor>>().unwrap();
let mut head = head.write().unwrap();
if head.data.len() > 0 {
eprintln!("data len > 0");
if cur.tree_addr.len() > 2 {
head.listlist_split();
}
eprintln!("split head");
let mut tail = head.split();
head.goto(TreeCursor::none());
@ -388,15 +390,16 @@ impl ListEditor {
None
};
let mut tail_node = tail.into_node(depth);
tail_node = tail_node.set_ctx(item.ctx.clone().unwrap());
let mut tail_node = tail.into_node(depth.get());
// if let Some(item_type) = item_type {
tail_node = tail_node.morph(self.typ.clone());
//if let Some(item_type) = item_type {
//eprintln!("morph to {}", self.ctx.read().unwrap().type_term_to_str(&self.typ));
tail_node = tail_node.morph(self.typ.clone());
//}
//eprintln!("insert node");
self.insert(
tail_node
Arc::new(RwLock::new(tail_node))
);
}
}
@ -406,15 +409,14 @@ impl ListEditor {
pub fn listlist_join_pxev(&mut self, idx: isize, item: &NestedNode) {
{
let prev_editor = self.data.get_mut(idx as usize-1);
let prev_editor = prev_editor.editor.clone();
if let Some(prev_editor) = prev_editor {
prev_editor.0.update();
if let Ok(prev_editor) = prev_editor.get_view().unwrap().get().unwrap().downcast::<RwLock<ListEditor>>() {
let prev_editor = prev_editor.read().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 cur_editor = item.editor.clone().unwrap();
cur_editor.0.update();
let cur_editor = cur_editor.get_view().unwrap().get().unwrap().downcast::<RwLock<ListEditor>>().unwrap();
let cur_editor = item.editor.get().unwrap();
let cur_editor = cur_editor.downcast::<RwLock<ListEditor>>().unwrap();
let cur_editor = cur_editor.write().unwrap();
prev_editor.join(&cur_editor);
@ -434,14 +436,13 @@ impl ListEditor {
pub fn listlist_join_nexd(&mut self, next_idx: usize, item: &NestedNode) {
{
let next_editor = self.data.get_mut(next_idx).editor.clone();
if let Some(next_editor) = next_editor {
next_editor.0.update();
if let Ok(next_editor) = next_editor.get_view().unwrap().get().unwrap().downcast::<RwLock<ListEditor>>() {
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 mut next_editor = next_editor.write().unwrap();
let cur_editor = item.editor.clone().unwrap();
cur_editor.0.update();
let cur_editor = cur_editor.get_view().unwrap().get().unwrap().downcast::<RwLock<ListEditor>>().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);

View file

@ -43,7 +43,7 @@ impl TreeNav for ListEditor {
ListCursorMode::Select => {
if let Some(i) = cur.idx {
if i < self.data.len() as isize {
let mut sub_cur = self.data.get(i as usize).get_cursor_warp();
let mut sub_cur = self.data.get(i as usize).read().unwrap().get_cursor_warp();
sub_cur.tree_addr.insert(0, i as isize - self.data.len() as isize);
return sub_cur;
} else {
@ -75,7 +75,7 @@ impl TreeNav for ListEditor {
ListCursorMode::Select => {
if let Some(i) = cur.idx {
if i < self.data.len() as isize {
let mut sub_cur = self.data.get(i as usize).get_cursor();
let mut sub_cur = self.data.get(i as usize).read().unwrap().get_cursor();
if sub_cur.tree_addr.len() > 0 {
sub_cur.tree_addr.insert(0, i as isize);
return sub_cur;
@ -99,7 +99,7 @@ impl TreeNav for ListEditor {
let old_cur = self.cursor.get();
if let Some(i) = old_cur.idx {
if i < self.data.len() as isize {
self.data.get_mut(i as usize).goto(TreeCursor::none());
self.data.get_mut(i as usize).write().unwrap().goto(TreeCursor::none());
}
}
@ -122,6 +122,7 @@ impl TreeNav for ListEditor {
if new_cur.leaf_mode == ListCursorMode::Select && self.data.len() > 0 {
self.data
.get_mut(idx as usize)
.write().unwrap()
.goto(TreeCursor {
leaf_mode: ListCursorMode::Select,
tree_addr: vec![]
@ -141,6 +142,7 @@ impl TreeNav for ListEditor {
self.data
.get_mut(idx as usize)
.write().unwrap()
.goto(TreeCursor {
leaf_mode: new_cur.leaf_mode,
tree_addr: new_cur.tree_addr[1..].iter().cloned().collect(),
@ -189,6 +191,7 @@ impl TreeNav for ListEditor {
if cur.tree_addr[0] < self.data.len() as isize {
if self.data
.get_mut(cur.tree_addr[0] as usize)
.write().unwrap()
.goby(Vector2::new(direction.x, direction.y))
== TreeNavResult::Continue {
self.cursor.set(ListCursor {
@ -224,6 +227,7 @@ impl TreeNav for ListEditor {
if idx < self.data.len() as isize {
self.data
.get_mut(idx as usize)
.write().unwrap()
.goto(TreeCursor {
leaf_mode: cur.leaf_mode,
tree_addr: vec![]
@ -247,6 +251,7 @@ impl TreeNav for ListEditor {
if cur.tree_addr[0] < self.data.len() as isize {
match self.data
.get_mut(cur.tree_addr[0] as usize)
.write().unwrap()
.goby(direction)
{
TreeNavResult::Exit => {

View file

@ -61,7 +61,7 @@ impl PTYListStyle {
pub fn for_node(node: &mut NestedNode, style: (&str, &str, &str)) {
node.view = Some(
Self::new(style, node.depth)
Self::new(style, node.depth.get())
.pty_view(
&node.get_edit::<ListEditor>().unwrap().read().unwrap()
)
@ -115,10 +115,10 @@ impl PTYListController {
}
let editor = node.get_edit::<ListEditor>().unwrap();
let controller = Arc::new(RwLock::new(PTYListController::from_editor( editor, split_char, close_char, node.depth )));
let controller = Arc::new(RwLock::new(PTYListController::from_editor( editor, split_char, close_char, node.depth.get() )));
node.cmd = Some(controller.clone());
node.close_char = close_char;
node.cmd.set(Some(controller.clone()));
node.close_char.set(close_char);
}
pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = NestedNode>> {
@ -136,6 +136,20 @@ impl PTYListController {
pub fn set_depth(&mut self, depth: usize) {
self.depth = depth;
}
/*
pub fn handle_node_event(&mut self, c: &NestedNode) -> TreeNavResult {
}
pub fn handle_char_event(&mut self, c: &char) -> TreeNavResult {
}
pub fn handle_term_event(&mut self, e: &TerminalEvent) -> TreeNavResult {
}
*/
}
use r3vi::view::singleton::SingletonView;
@ -161,10 +175,10 @@ impl ObjCommander for PTYListController {
if let Some(idx) = cur.idx {
match cur.mode {
ListCursorMode::Select => {
*e.data.get_mut(idx as usize) = node_view.get();
*e.data.get_mut(idx as usize) = Arc::new(RwLock::new(node_view.get()));
}
ListCursorMode::Insert => {
e.data.insert(idx as usize, node_view.get());
e.data.insert(idx as usize, Arc::new(RwLock::new(node_view.get())));
}
}
}
@ -212,7 +226,7 @@ impl ObjCommander for PTYListController {
if ! remove {
*/
e.insert(node);
e.insert(Arc::new(RwLock::new(node)));
TreeNavResult::Continue
}
@ -310,7 +324,7 @@ impl ObjCommander for PTYListController {
match new_edit.send_cmd_obj(cmd_obj.clone()) {
TreeNavResult::Continue => {
e.insert(new_edit);
e.insert(Arc::new(RwLock::new(new_edit)));
TreeNavResult::Continue
}
@ -322,7 +336,7 @@ impl ObjCommander for PTYListController {
},
ListCursorMode::Select => {
if let Some(mut item) = e.get_item_mut() {
match item.send_cmd_obj(cmd_obj.clone()) {
match item.write().unwrap().send_cmd_obj(cmd_obj.clone()) {
TreeNavResult::Continue => {
TreeNavResult::Continue
}
@ -337,10 +351,9 @@ impl ObjCommander for PTYListController {
//eprintln!("close char = {:?}", item.close_char);
if Some(c) == self.split_char {
//eprintln!("listlist_split");
e.listlist_split();
TreeNavResult::Continue
} else if Some(c) == item.close_char {
} else if Some(c) == item.read().unwrap().close_char.get() {
//eprintln!("listedit: exit from select (close)");
//item.goto(TreeCursor::none());
e.cursor.set(ListCursor {

View file

@ -16,36 +16,42 @@ use {
};
#[derive(Clone)]
pub struct NestedNode {
/// depth
pub depth: usize,
pub struct NestedNode {
/// context
pub ctx: Option<Arc<RwLock<Context>>>,
/// abstract editor
pub editor: Option<OuterViewPort<dyn SingletonView<Item = Option<Arc<dyn Any + Send + Sync>>>>>,
pub ctx: Option< Arc<RwLock<Context>> >,
/// abstract data view
pub data: Option<Arc<RwLock<ReprTree>>>,
pub data: Option< Arc<RwLock<ReprTree>> >,
/// display view
pub view: Option<OuterViewPort<dyn TerminalView>>,
pub view: Option< OuterViewPort<dyn TerminalView> >,
/// diagnostics
pub diag: Option<OuterViewPort<dyn SequenceView<Item = Message>>>,
pub diag: Option< OuterViewPort<dyn SequenceView<Item = Message>> >,
/// commander
pub close_char: Option<char>,
pub cmd: Option<Arc<RwLock<dyn ObjCommander + Send + Sync>>>,
/// depth
pub depth: SingletonBuffer< usize >,
/// tree navigation
pub tree_nav: Option<Arc<RwLock<dyn TreeNav + Send + Sync>>>,
/// abstract editor
pub editor: SingletonBuffer<
Option< Arc<dyn Any + Send + Sync> >
>,
/// commander & navigation
pub cmd: SingletonBuffer<
Option< Arc<RwLock<dyn ObjCommander + Send + Sync>> >
>,
pub close_char: SingletonBuffer<
Option< char >
>,
pub tree_nav: SingletonBuffer<
Option< Arc<RwLock<dyn TreeNav + Send + Sync>> >
>,
}
impl ObjCommander for NestedNode {
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
if let Some(cmd) = self.cmd.as_ref() {
if let Some(cmd) = self.cmd.get() {
// todo: filter out tree-nav cmds and send them to tree_nav
cmd.write().unwrap().send_cmd_obj(cmd_obj)
} else {
@ -74,7 +80,7 @@ impl TerminalEditor for NestedNode {
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
let buf = SingletonBuffer::new(event.clone());
if let (Some(cmd),Some(ctx)) = (self.cmd.as_ref(),self.ctx.as_ref()) {
if let (Some(cmd),Some(ctx)) = (self.cmd.get(),self.ctx.as_ref()) {
cmd.write().unwrap().send_cmd_obj(
ReprTree::new_leaf(
ctx.read().unwrap().type_term_from_str("( TerminalEvent )").unwrap(),
@ -88,7 +94,7 @@ impl TerminalEditor for NestedNode {
impl TreeNav for NestedNode {
fn get_cursor(&self) -> TreeCursor {
if let Some(tn) = self.tree_nav.as_ref() {
if let Some(tn) = self.tree_nav.get() {
tn.read().unwrap().get_cursor()
} else {
TreeCursor::default()
@ -96,7 +102,7 @@ impl TreeNav for NestedNode {
}
fn get_addr_view(&self) -> OuterViewPort<dyn SequenceView<Item = isize>> {
if let Some(tn) = self.tree_nav.as_ref() {
if let Some(tn) = self.tree_nav.get() {
tn.read().unwrap().get_addr_view()
} else {
OuterViewPort::default()
@ -104,7 +110,7 @@ impl TreeNav for NestedNode {
}
fn get_mode_view(&self) -> OuterViewPort<dyn SingletonView<Item = ListCursorMode>> {
if let Some(tn) = self.tree_nav.as_ref() {
if let Some(tn) = self.tree_nav.get() {
tn.read().unwrap().get_mode_view()
} else {
OuterViewPort::default()
@ -112,7 +118,7 @@ impl TreeNav for NestedNode {
}
fn get_cursor_warp(&self) -> TreeCursor {
if let Some(tn) = self.tree_nav.as_ref() {
if let Some(tn) = self.tree_nav.get() {
tn.read().unwrap().get_cursor_warp()
} else {
TreeCursor::default()
@ -124,7 +130,7 @@ impl TreeNav for NestedNode {
}
fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult {
if let Some(tn) = self.tree_nav.as_ref() {
if let Some(tn) = self.tree_nav.get() {
tn.write().unwrap().goby(direction)
} else {
TreeNavResult::Exit
@ -132,7 +138,7 @@ impl TreeNav for NestedNode {
}
fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult {
if let Some(tn) = self.tree_nav.as_ref() {
if let Some(tn) = self.tree_nav.get() {
tn.write().unwrap().goto(new_cursor)
} else {
TreeNavResult::Exit
@ -149,15 +155,15 @@ impl Diagnostics for NestedNode {
impl NestedNode {
pub fn new(depth: usize) -> Self {
NestedNode {
depth,
ctx: None,
data: None,
editor: None,
view: None,
diag: None,
cmd: None,
close_char: None,
tree_nav: None
depth: SingletonBuffer::new(depth),
editor: SingletonBuffer::new(None),
cmd: SingletonBuffer::new(None),
close_char: SingletonBuffer::new(None),
tree_nav: SingletonBuffer::new(None)
}
}
@ -197,7 +203,7 @@ impl NestedNode {
}
pub fn set_editor(mut self, editor: Arc<dyn Any + Send + Sync>) -> Self {
self.editor = Some(SingletonBuffer::new(Some(editor)).get_port());
self.editor.set(Some(editor));
self
}
@ -207,12 +213,12 @@ impl NestedNode {
}
pub fn set_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self {
self.cmd = Some(cmd);
self.cmd.set(Some(cmd));
self
}
pub fn set_nav(mut self, nav: Arc<RwLock<dyn TreeNav + Send + Sync>>) -> Self {
self.tree_nav = Some(nav);
self.tree_nav.set(Some(nav));
self
}
@ -268,8 +274,8 @@ impl NestedNode {
}
*/
pub fn get_edit<T: Send + Sync + 'static>(&self) -> Option<Arc<RwLock<T>>> {
if let Some(edit) = self.editor.clone() {
if let Ok(edit) = edit.get_view().unwrap().get().unwrap().downcast::<RwLock<T>>() {
if let Some(edit) = self.editor.get() {
if let Ok(edit) = edit.downcast::<RwLock<T>>() {
Some(edit)
} else {
None

View file

@ -189,7 +189,7 @@ impl Context {
self.add_morphism(morphism_pattern, Arc::new(move |node, dst_type| {
let ctx = node.ctx.clone().unwrap();
let depth = node.depth;
mk_editor(ctx, dst_type, depth)
mk_editor(ctx, dst_type, depth.get())
}));
}

View file

@ -33,7 +33,7 @@ pub struct TypeTermEditor {
ctx: Arc<RwLock<Context>>,
state: State,
cur_node: SingletonBuffer<NestedNode>
cur_node: SingletonBuffer< NestedNode >
}
impl TypeTermEditor {
@ -64,17 +64,15 @@ impl TypeTermEditor {
Arc::new(
|mut node, _dst_type:_| {
//eprintln!("morphism to typeterm");
PTYListController::for_node( &mut node, Some(' '), None );
PTYListStyle::for_node( &mut node, ("","","") );
let mut new_node = TypeTermEditor::with_node( node.ctx.clone().unwrap(), node.depth, node.clone(), State::Any );
let mut new_node = TypeTermEditor::with_node( node.ctx.clone().unwrap(), node.depth.get(), node.clone(), State::Any );
let item_nodes = node.get_edit::<ListEditor>().clone().unwrap();
let item_nodes = item_nodes.read().unwrap();
for i in 0..item_nodes.data.len() {
if let Some(x) = item_nodes.data.get(i).data {
if let Some(x) = &item_nodes.data.get(i).read().unwrap().data {
//eprintln!("item with {:?}", x);
//let c = x.read().unwrap().get_view::<dyn SingletonView<Item = NestedNode>>().unwrap().get();
new_node.send_cmd_obj(
@ -99,7 +97,6 @@ impl TypeTermEditor {
let mut node = match new_state {
State::Char => {
let mut node = Context::make_node( &self.ctx, (&self.ctx, "( Char )").into(), 0 ).unwrap();
let mut grid = r3vi::buffer::index_hashmap::IndexBuffer::new();
grid.insert_iter(
@ -110,7 +107,7 @@ impl TypeTermEditor {
]
);
node.close_char = Some('\'');
node.close_char.set(Some('\''));
node.view = Some(
grid.get_port()
.flatten()
@ -153,21 +150,6 @@ impl TypeTermEditor {
cur_node: SingletonBuffer::new(node)
};
let ed_view = editor.cur_node
.get_port()
.map(
|node|
match node.editor {
Some(e) => {
e
},
None => {
r3vi::buffer::singleton::SingletonBuffer::new(None).get_port()
}
}
)
.flatten();
let view = editor.cur_node
.get_port()
.map(
@ -190,12 +172,10 @@ impl TypeTermEditor {
let mut node = NestedNode::new(depth)
.set_ctx(ctx)
.set_view( view )
.set_view(view)
.set_nav(editor.clone())
.set_cmd(editor.clone());
node.editor = Some(ed_view);
//node.editor.unwrap().get_view().unwrap().get().unwrap()
.set_cmd(editor.clone())
.set_editor(editor.clone());
node
}
@ -280,7 +260,7 @@ impl ObjCommander for TypeTermEditor {
}
}
}
State::List => {
match self.cur_node.get_mut().send_cmd_obj( co ) {
TreeNavResult::Continue => {
@ -308,7 +288,6 @@ impl ObjCommander for TypeTermEditor {
TreeNavResult::Exit
}
}
}
}
}

View file

@ -192,8 +192,8 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
ctx.write().unwrap().add_morphism(pattern,
Arc::new(
|mut node, dst_type| {
let depth = node.depth;
let editor = node.editor.clone().unwrap().get_view().unwrap().get().unwrap().downcast::<RwLock<ListEditor>>().unwrap();
let depth = node.depth.get();
let editor = node.editor.get().unwrap().downcast::<RwLock<ListEditor>>().unwrap();
// todo: check src_type parameter to be ( Digit radix )