From 10cbeb52a3421fe68110fa01daa9641fc6c6738e Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Sat, 10 Aug 2024 13:18:25 +0200
Subject: [PATCH] wip

---
 Cargo.toml                                    |   2 +
 examples/tty-04-posint/src/main.rs            |  32 ++-
 examples/tty-05-dictionary/Cargo.toml         |  19 ++
 examples/tty-05-dictionary/src/main.rs        | 175 +++++++++++++
 examples/tty-06-color/Cargo.toml              |  19 ++
 examples/tty-06-color/src/main.rs             | 232 ++++++++++++++++++
 lib-nested-core/src/edit_tree/cursor.rs       |   8 +
 lib-nested-core/src/editors/char/mod.rs       |  28 ++-
 lib-nested-core/src/editors/integer/ctx.rs    |  45 ++++
 lib-nested-core/src/editors/integer/radix.rs  |  10 +-
 lib-nested-core/src/editors/list/ctx.rs       |  27 +-
 lib-nested-core/src/editors/list/editor.rs    |   3 +-
 .../src/editors/product/segment.rs            |   3 +
 lib-nested-core/src/repr_tree/morphism.rs     | 119 ++++++---
 lib-nested-core/src/repr_tree/node.rs         |   1 +
 lib-nested-tty/src/lib.rs                     |  11 +-
 16 files changed, 675 insertions(+), 59 deletions(-)
 create mode 100644 examples/tty-05-dictionary/Cargo.toml
 create mode 100644 examples/tty-05-dictionary/src/main.rs
 create mode 100644 examples/tty-06-color/Cargo.toml
 create mode 100644 examples/tty-06-color/src/main.rs

diff --git a/Cargo.toml b/Cargo.toml
index 44403c7..0db6274 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,5 +10,7 @@ members = [
     "examples/tty-02-digit",
     "examples/tty-03-string",
     "examples/tty-04-posint",
+    "examples/tty-05-dictionary",
+    "examples/tty-06-color"
 ]
 
diff --git a/examples/tty-04-posint/src/main.rs b/examples/tty-04-posint/src/main.rs
index 906791e..50cfa65 100644
--- a/examples/tty-04-posint/src/main.rs
+++ b/examples/tty-04-posint/src/main.rs
@@ -67,12 +67,26 @@ async fn main() {
         &rt_int,
         &nested::repr_tree::morphism::MorphismType {
             src_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ <Vec Char>"),
-            dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree")
+            dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16>> ~ EditTree")
         });
 
+    return;
+
     /* set Hex-editor to be master
      */
     rt_int.write().unwrap().detach( &ctx );
+
+    ctx.read().unwrap().apply_morphism(
+        &rt_int,
+        &laddertypes::MorphismType {
+            src_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ Char> ~ EditTree"),
+            dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16>> ~ <List <Digit 16> ~ EditTree >")
+//            dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char> ~ EditTree")
+        }
+    );
+
+    return;
+/*
     ctx.read().unwrap().apply_morphism(
         &rt_int,
         &laddertypes::MorphismType {
@@ -80,15 +94,15 @@ async fn main() {
             dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char> ~ EditTree")
         }
     );
-
+*/
     let edittree_hex_be_list =
         rt_int
             .descend(Context::parse(&ctx, "
                     <PosInt 16 BigEndian>
-                    ~ <Seq~List <Digit 16>~Char>
+                    ~ <Seq~List <Digit 16>>
                 ")).unwrap()
             .edittree( &ctx );
-
+/*
     let edittree_dec_be_list =
         rt_int
             .descend(Context::parse(&ctx, "
@@ -120,19 +134,19 @@ async fn main() {
         .map(|v| TerminalAtom::from(char::from_digit(*v as u32, 10)))
         .to_sequence()
         .to_grid_horizontal();
-
+*/
     /* list of both editors
      */
     let mut list_editor = nested::editors::list::ListEditor::new(ctx.clone(), Context::parse(&ctx, "<Seq Char>"));
     list_editor.data.push( edittree_hex_be_list.get() );
-    list_editor.data.push( edittree_dec_be_list.get() );
+    //list_editor.data.push( edittree_dec_be_list.get() );
     let mut edittree = list_editor.into_node(SingletonBuffer::new(0).get_port());
 
     /* cursors are a bit screwed initially so fix them up
      * TODO: how to fix this generally?
      */
     edittree_hex_be_list.get().write().unwrap().goto(TreeCursor::none());
-    edittree_dec_be_list.get().write().unwrap().goto(TreeCursor::none());
+    //edittree_dec_be_list.get().write().unwrap().goto(TreeCursor::none());
     edittree.goto(TreeCursor{
         leaf_mode: nested::editors::list::ListCursorMode::Insert,
         tree_addr: vec![0,0]
@@ -210,10 +224,11 @@ async fn main() {
         }
 
         show_edit_tree(&ctx, &mut comp, &rt_int.descend(Context::parse(&ctx, "<PosInt 16 BigEndian> ~ <Seq~List <Digit 16>~Char>")).expect(""), 1);
-        show_edit_tree(&ctx, &mut comp, &rt_int.descend(Context::parse(&ctx, "<PosInt 10 BigEndian> ~ <Seq~List <Digit 10>~Char>")).expect(""), 4);
+        //show_edit_tree(&ctx, &mut comp, &rt_int.descend(Context::parse(&ctx, "<PosInt 10 BigEndian> ~ <Seq~List <Digit 10>~Char>")).expect(""), 4);
 
         /* project the seq of u64 representations to a view
          */
+         /*
         comp.push(nested_tty::make_label("dec: ").offset(Vector2::new(3,7)));
         comp.push(dec_digits_view.offset(Vector2::new(8,7)).map_item(|_,a| {
             a.add_style_back(TerminalStyle::fg_color((30,90,200)))
@@ -223,6 +238,7 @@ async fn main() {
         comp.push(hex_digits_view.offset(Vector2::new(8,8)).map_item(|_,a| {
             a.add_style_back(TerminalStyle::fg_color((200, 200, 30)))
         }));
+        */
     }
 
     /* write the changes in the view of `term_port` to the terminal
diff --git a/examples/tty-05-dictionary/Cargo.toml b/examples/tty-05-dictionary/Cargo.toml
new file mode 100644
index 0000000..fef954f
--- /dev/null
+++ b/examples/tty-05-dictionary/Cargo.toml
@@ -0,0 +1,19 @@
+[package]
+name = "tty-05-dictionary"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+laddertypes = { path = "../../../lib-laddertypes" }
+r3vi = { path = "../../../lib-r3vi" }
+nested = { path = "../../lib-nested-core" }
+nested-tty = { path = "../../lib-nested-tty" }
+termion = "*"
+cgmath = "*"
+
+[dependencies.async-std]
+version = "1.9.0"
+features = ["unstable", "attributes"]
+
diff --git a/examples/tty-05-dictionary/src/main.rs b/examples/tty-05-dictionary/src/main.rs
new file mode 100644
index 0000000..db790b4
--- /dev/null
+++ b/examples/tty-05-dictionary/src/main.rs
@@ -0,0 +1,175 @@
+extern crate cgmath;
+extern crate nested;
+extern crate nested_tty;
+extern crate r3vi;
+extern crate termion;
+
+use {
+    cgmath::Vector2,
+    nested::{
+        editors::{
+            ObjCommander
+        },
+        repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf},
+        edit_tree::{EditTree, TreeNav, TreeCursor}
+    },
+    nested_tty::{
+        DisplaySegment, TTYApplication,
+        TerminalCompositor, TerminalStyle, TerminalView,
+        TerminalAtom, TerminalEvent
+    },
+    r3vi::{
+        buffer::{singleton::*, vec::*},
+        view::{port::UpdateTask, singleton::*, list::*, sequence::*},
+        projection::*
+    },
+    std::sync::{Arc, RwLock},
+};
+
+#[async_std::main]
+async fn main() {
+
+    /* setup context
+     */
+    let ctx = Arc::new(RwLock::new(Context::new()));
+    nested::editors::char::init_ctx( ctx.clone() );
+    nested::editors::digit::init_ctx( ctx.clone() );
+    nested::editors::integer::init_ctx( ctx.clone() );
+    nested::editors::list::init_ctx( ctx.clone() );
+    nested_tty::setup_edittree_hook(&ctx);
+
+    let dict = Arc::new(RwLock::new(std::collections::HashMap::<String, u64>::new()));
+
+    dict.write().unwrap().insert( "red".into(), 0 );
+    dict.write().unwrap().insert( "green".into(), 1 );
+    dict.write().unwrap().insert( "blue".into(), 2 );
+
+    let symbol_morph_str_to_u64 = nested::repr_tree::GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "Symbol ~ <Seq~List~Vec Char>"),
+        Context::parse(&ctx, "Symbol ~ ℕ ~ machine.UInt64"),
+
+        {
+            let ctx = ctx.clone();
+            let dict = dict.clone();
+
+            move |rt, σ| {
+                let str_view = rt
+                    .descend(Context::parse(&ctx, "Symbol ~ <Seq~List~Vec Char>")).unwrap()
+                    .vec_buffer::<char>()
+                    .get_port();
+
+                let u64_view = str_view
+                    .to_singleton()
+                    .map({
+                        let dict = dict.clone();
+                        let old_value = Arc::new(RwLock::new(0));
+                        move |chars| {
+                            let str_val = chars.iter().collect::<String>();
+                            let dict = dict.read().unwrap();
+
+                            let mut old_value = old_value.write().unwrap();
+                            if let Some( new_value ) = dict.get( &str_val ) {
+                                *old_value = new_value.clone();
+                                new_value.clone()
+                            } else {
+                                old_value.clone()
+                            }
+                        }
+                    });
+
+                rt.attach_leaf_to(
+                    Context::parse(&ctx, "ℕ ~ machine.UInt64"),
+                    u64_view
+                );
+            }
+        }
+    );
+    ctx.write().unwrap().morphisms.add_morphism( symbol_morph_str_to_u64 );
+
+    let mut symbol_rt = nested::repr_tree::ReprTree::from_str(Context::parse(&ctx, "
+            Symbol ~ <Seq~List~Vec Char>
+        "),
+        "red"
+    );
+
+
+    // this is required to initialize the <Vec EditTree> representation,
+    // and to take the value from <Vec Char>
+    ctx.read().unwrap().apply_morphism( &symbol_rt,
+        &laddertypes::MorphismType {
+            src_type: Context::parse(&ctx, "Symbol ~ <Seq~List~Vec Char>"),
+            dst_type: Context::parse(&ctx, "Symbol ~ <Seq~List Char> ~ EditTree")
+        });
+    symbol_rt.write().unwrap().detach( &ctx );
+
+    ctx.read().unwrap().apply_morphism( &symbol_rt,
+        &laddertypes::MorphismType {
+            dst_type: Context::parse(&ctx, "Symbol ~ <Seq~List~Vec Char>"),
+            src_type: Context::parse(&ctx, "Symbol ~ <Seq~List Char> ~ EditTree")
+        });
+    ctx.read().unwrap().apply_morphism( &symbol_rt,
+        &laddertypes::MorphismType {
+            src_type: Context::parse(&ctx, "Symbol ~ <Seq~List~Vec Char>"),
+            dst_type: Context::parse(&ctx, "Symbol ~ ℕ ~ <PosInt 10 BigEndian> ~ <Seq~List <Digit 10>~Char> ~ EditTree")
+        });
+
+
+    let symbol1_str_edit = symbol_rt.descend(Context::parse(&ctx, "
+            Symbol ~ <Seq~List Char>
+        ")).unwrap().edittree( &ctx );
+
+    let symbol1_nat_edit = symbol_rt.descend(Context::parse(&ctx, "
+            Symbol ~ ℕ ~ <PosInt 10 BigEndian> ~ <Seq~List <Digit 10>~Char>
+        ")).unwrap().edittree( &ctx );
+
+    symbol1_nat_edit.get().write().unwrap().goto(TreeCursor::none());
+
+    /* setup terminal
+     */
+    let app = TTYApplication::new({
+        /* event handler
+         */
+        let ctx = ctx.clone();
+        let edit = symbol1_str_edit.get().clone();
+
+        edit.write().unwrap().goto(TreeCursor::home());
+        
+        move |ev| {
+            edit.write().unwrap().send_cmd_obj( ev.to_repr_tree(&ctx) );
+        }
+    });
+
+    /* Setup the compositor to serve as root-view
+     * by routing it to the `app.port` Viewport,
+     * so it will be displayed on TTY-output.
+     */
+    let compositor = TerminalCompositor::new(app.port.inner());
+
+    /* Now add some views to our compositor
+     */
+    {
+        let mut comp = compositor.write().unwrap();
+
+        fn show_edit_tree( ctx: &Arc<RwLock<Context>>, comp: &mut TerminalCompositor, rt: &Arc<RwLock<ReprTree>>, y: i16 )
+        {
+            let rt_edittree = rt.descend(Context::parse(&ctx, "EditTree")).expect("descend");
+            let halo_type = rt_edittree.read().unwrap().get_halo_type().clone();
+            let edittree = rt_edittree.read().unwrap().get_view::<dyn r3vi::view::singleton::SingletonView<Item = Arc<RwLock<EditTree>>>>().unwrap().get().read().unwrap().clone();
+
+            comp.push(  nested_tty::make_label( &ctx.read().unwrap().type_term_to_str(&halo_type) ) 
+                .map_item(|_pt, atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90))))
+                .offset(Vector2::new(1,y)));
+
+            comp.push(  edittree.display_view()
+                .offset(Vector2::new(1,y+1)));
+        }
+
+        show_edit_tree( &ctx, &mut comp, &symbol_rt.descend(Context::parse(&ctx, "Symbol ~ <Seq~List Char>")).unwrap(), 1 );
+        show_edit_tree( &ctx, &mut comp, &symbol_rt.descend(Context::parse(&ctx, "Symbol ~ ℕ ~ <PosInt 10 BigEndian> ~ <Seq~List <Digit 10>~Char>")).unwrap(), 3 );
+    }
+
+    /* write the changes in the view of `term_port` to the terminal
+     */
+    app.show().await.expect("output error!");
+}
+
diff --git a/examples/tty-06-color/Cargo.toml b/examples/tty-06-color/Cargo.toml
new file mode 100644
index 0000000..53db651
--- /dev/null
+++ b/examples/tty-06-color/Cargo.toml
@@ -0,0 +1,19 @@
+[package]
+name = "tty-06-color"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+laddertypes = { path = "../../../lib-laddertypes" }
+r3vi = { path = "../../../lib-r3vi" }
+nested = { path = "../../lib-nested-core" }
+nested-tty = { path = "../../lib-nested-tty" }
+termion = "*"
+cgmath = "*"
+
+[dependencies.async-std]
+version = "1.9.0"
+features = ["unstable", "attributes"]
+
diff --git a/examples/tty-06-color/src/main.rs b/examples/tty-06-color/src/main.rs
new file mode 100644
index 0000000..e02ae87
--- /dev/null
+++ b/examples/tty-06-color/src/main.rs
@@ -0,0 +1,232 @@
+extern crate cgmath;
+extern crate nested;
+extern crate nested_tty;
+extern crate r3vi;
+extern crate termion;
+
+use {
+    cgmath::Vector2,
+    nested::{
+        editors::{
+            ObjCommander
+        },
+        repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf},
+        edit_tree::{EditTree, TreeNav, TreeCursor}
+    },
+    nested_tty::{
+        DisplaySegment, TTYApplication,
+        TerminalCompositor, TerminalStyle, TerminalView,
+        TerminalAtom, TerminalEvent
+    },
+    r3vi::{
+        buffer::{singleton::*, vec::*},
+        view::{port::UpdateTask, singleton::*, list::*, sequence::*},
+        projection::*
+    },
+    std::sync::{Arc, RwLock},
+};
+
+#[async_std::main]
+async fn main() {
+
+    /* setup context
+     */
+    let ctx = Arc::new(RwLock::new(Context::new()));
+    nested::editors::char::init_ctx( ctx.clone() );
+    nested::editors::digit::init_ctx( ctx.clone() );
+    nested::editors::integer::init_ctx( ctx.clone() );
+    nested::editors::list::init_ctx( ctx.clone() );
+    nested_tty::setup_edittree_hook(&ctx);
+
+    eprintln!(
+        "Char = {:?}\nu64 = {:?}\nEditTree = {:?}, <Vec EditTree> = {:?}",
+        Context::parse(&ctx, "Char"),
+        Context::parse(&ctx, "machine.UInt64"),
+        Context::parse(&ctx, "EditTree"),
+        Context::parse(&ctx, "<Vec EditTree>")
+    );
+
+    let mut red = nested::repr_tree::ReprTree::from_str(Context::parse(&ctx, "
+            ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char> ~ <Vec Char>
+        "),
+        "221"
+    );
+    ctx.read().unwrap().apply_morphism( &red,
+        &laddertypes::MorphismType {
+            src_type: Context::parse(&ctx, "ℕ ~ <PosInt 10 BigEndian> ~ <Seq~List <Digit 10> ~ Char > ~ <Vec Char>"),
+            dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char > ~ EditTree")
+        });
+    let red_edit = ctx.read().unwrap().setup_edittree(
+        red.descend(Context::parse(&ctx, "
+                ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>~Char>
+            ")).unwrap(),
+        SingletonBuffer::new(0).get_port()
+    ).unwrap();
+
+    let mut green = nested::repr_tree::ReprTree::from_str(Context::parse(&ctx, "
+            ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char> ~ <Vec Char>
+        "),
+        "220"
+    );
+    ctx.read().unwrap().apply_morphism( &green,
+        &laddertypes::MorphismType {
+            src_type: Context::parse(&ctx, "ℕ ~ <PosInt 10 BigEndian> ~ <Seq~List <Digit 10> ~ Char > ~ <Vec Char>"),
+            dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char > ~ EditTree")
+        });
+     let green_edit = ctx.read().unwrap().setup_edittree(green.descend(Context::parse(&ctx, "
+                ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>~Char>
+            ")).unwrap(),
+        SingletonBuffer::new(0).get_port()
+    ).unwrap();
+
+    
+    let mut blue = nested::repr_tree::ReprTree::from_str(Context::parse(&ctx, "
+            ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char> ~ <Vec Char>
+        "),
+        "5"
+    );
+    ctx.read().unwrap().apply_morphism( &blue,
+        &laddertypes::MorphismType {
+            src_type: Context::parse(&ctx, "ℕ ~ <PosInt 10 BigEndian> ~ <Seq~List <Digit 10> ~ Char > ~ <Vec Char>"),
+            dst_type: Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char > ~ EditTree")
+        });
+    let blue_edit = ctx.read().unwrap().setup_edittree(
+        blue.descend(Context::parse(&ctx, "
+                ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>~Char>
+            ")).unwrap(),
+        SingletonBuffer::new(0).get_port()
+    ).unwrap();
+
+
+    eprintln!("======\n   M A K E    L I S T    E D I T O R\n======\n");
+    
+    let mut color = nested::repr_tree::ReprTree::new_arc(
+        Context::parse(&ctx, "<List ℕ>")
+    );
+
+    color.insert_leaf(
+        Context::parse(&ctx, "
+                <List   ℕ
+                      ~ <PosInt 16 BigEndian>
+                      ~ <Seq <Digit 16>>
+                      ~ <List  <Digit 16>
+                              ~ Char >
+                >
+                ~ <List EditTree>
+                ~ <Vec EditTree>
+            "),
+
+        ReprLeaf::from_vec_buffer(VecBuffer::<
+            Arc<RwLock< EditTree >>
+        >::with_data(vec![
+            red_edit.get(),
+            green_edit.get(),
+            blue_edit.get()
+        ]))
+    );
+    ctx.read().unwrap().apply_morphism(
+        &color,
+        &laddertypes::MorphismType {
+            src_type: Context::parse(&ctx, "<List ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char > ~ EditTree > ~ <Vec EditTree>"),
+            dst_type: Context::parse(&ctx, "<List ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char > > ~ EditTree")
+        });
+    let edit = ctx.read().unwrap().setup_edittree(
+        color.descend(Context::parse(&ctx, "
+                <List   ℕ
+                      ~ < PosInt 16 BigEndian >
+                      ~ < Seq~List   <Digit 16>
+                                   ~ Char >
+                >
+            ")).unwrap(),
+        SingletonBuffer::new(0).get_port()
+    ).unwrap();
+
+
+
+eprintln!(" edittree => list list char ");
+     ctx.read().unwrap().apply_morphism(
+        &color,
+        &laddertypes::MorphismType {
+            src_type: Context::parse(&ctx, "<List ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char > > ~ EditTree"),
+            dst_type: Context::parse(&ctx, "<List ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char > >")
+        });
+
+eprintln!("list char ==> list u64");
+    ctx.read().unwrap().apply_morphism(
+        &color,
+        &laddertypes::MorphismType {
+            src_type: Context::parse(&ctx, "<List ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char>>"),
+            dst_type: Context::parse(&ctx, "<List ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>>")
+        });
+return;
+
+    ctx.read().unwrap().apply_morphism(
+        &color,
+        &laddertypes::MorphismType {
+            src_type: Context::parse(&ctx, "<List ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ ℤ_2^64 ~ machine.UInt64 > >"),
+            dst_type: Context::parse(&ctx, "<List ℕ ~ <PosInt 10 BigEndian> ~ <Seq~List <Digit 10> ~ Char > >")
+        });
+    /*
+    let edit2 = ctx.read().unwrap().setup_edittree(
+        color.descend(Context::parse(&ctx, "
+                <List   ℕ
+                      ~ < PosInt 10 BigEndian >
+                      ~ < Seq~List   <Digit 10>
+                                   ~ Char >
+                >
+            ")).unwrap(),
+        SingletonBuffer::new(0).get_port()
+    ).unwrap();
+*/
+
+    return;
+
+    /* setup terminal
+     */
+    let app = TTYApplication::new({
+        /* event handler
+         */
+        let ctx = ctx.clone();
+        let edit = edit.get().clone();
+
+        edit.write().unwrap().goto(TreeCursor::home());
+        
+        move |ev| {
+            edit.write().unwrap().send_cmd_obj( ev.to_repr_tree(&ctx) );
+        }
+    });
+
+    /* Setup the compositor to serve as root-view
+     * by routing it to the `app.port` Viewport,
+     * so it will be displayed on TTY-output.
+     */
+    let compositor = TerminalCompositor::new(app.port.inner());
+
+    /* Now add some views to our compositor
+     */
+    {
+        let mut comp = compositor.write().unwrap();
+
+        fn show_edit_tree( ctx: &Arc<RwLock<Context>>, comp: &mut TerminalCompositor, rt: &Arc<RwLock<ReprTree>>, y: i16 )
+        {
+            let rt_edittree = rt.descend(Context::parse(&ctx, "EditTree")).expect("descend");
+            let halo_type = rt_edittree.read().unwrap().get_halo_type().clone();
+            let edittree = rt_edittree.read().unwrap().get_view::<dyn r3vi::view::singleton::SingletonView<Item = Arc<RwLock<EditTree>>>>().unwrap().get().read().unwrap().clone();
+
+            comp.push(  nested_tty::make_label( &ctx.read().unwrap().type_term_to_str(&halo_type) ) 
+                .map_item(|_pt, atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90))))
+                .offset(Vector2::new(1,y)));
+
+            comp.push(  edittree.display_view()
+                .offset(Vector2::new(1,y+1)));
+        }
+
+        show_edit_tree( &ctx, &mut comp, &color.descend(Context::parse(&ctx, "<List ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>~Char>>")).unwrap(), 1 );        
+        show_edit_tree( &ctx, &mut comp, &color.descend(Context::parse(&ctx, "<List ℕ ~ <PosInt 10 BigEndian> ~ <Seq~List <Digit 10>~Char>>")).unwrap(), 3 );
+    }
+
+    /* write the changes in the view of `term_port` to the terminal
+     */
+    app.show().await.expect("output error!");
+}
+
diff --git a/lib-nested-core/src/edit_tree/cursor.rs b/lib-nested-core/src/edit_tree/cursor.rs
index 9caa659..24e77d2 100644
--- a/lib-nested-core/src/edit_tree/cursor.rs
+++ b/lib-nested-core/src/edit_tree/cursor.rs
@@ -4,6 +4,14 @@ use {
 
 //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
 
+enum GravityMode {
+    // tries to maintain a set distance from bottom
+    Gravity(usize),
+
+    // keeps equal distance from root
+    Floating
+}
+
 #[derive(Clone, Eq, PartialEq, Debug)]
 pub struct TreeCursor {
     pub leaf_mode: ListCursorMode,
diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs
index 3d33efc..efab0c7 100644
--- a/lib-nested-core/src/editors/char/mod.rs
+++ b/lib-nested-core/src/editors/char/mod.rs
@@ -59,15 +59,39 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) {
                     );
 
                     ctx.read().unwrap().setup_edittree(
-                        rt.clone(),
-                        SingletonBuffer::new(0).get_port()
+                        rt
+//                        SingletonBuffer::new(0).get_port()
                     );
                 }
             
         }
     );
 
+    let char_morph_from_edittree = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "Char~EditTree"),
+        Context::parse(&ctx, "Char"),
+        {
+            let ctx = ctx.clone();
+            move |rt, σ|
+            {
+                /*
+                let mut b = rt
+                   .descend(Context::parse(&ctx, "EditTree")).unwrap()
+                   .view_singleton::<Arc<RwLock<EditTree>>>();
+
+                rt.attach_leaf_to(
+                    Context::parse(&ctx, "Char"),
+                    b.map(|x|
+                        x.read().unwrap()
+                            .get_edit::<CharEditor>().unwrap()
+                            .read().unwrap()
+                            .get())
+                );
+                */
+            }
+        });
     ctx.write().unwrap().morphisms.add_morphism( char_morph_to_edittree );
+    ctx.write().unwrap().morphisms.add_morphism( char_morph_from_edittree );
 }
 
 pub struct CharEditor {
diff --git a/lib-nested-core/src/editors/integer/ctx.rs b/lib-nested-core/src/editors/integer/ctx.rs
index dc6aa61..61c1f41 100644
--- a/lib-nested-core/src/editors/integer/ctx.rs
+++ b/lib-nested-core/src/editors/integer/ctx.rs
@@ -170,9 +170,54 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
         }
     );
 
+    let posint_list_morph_from_u64 = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "ℕ ~ machine.UInt64"),
+        Context::parse(&ctx, "ℕ ~ <PosInt 0 LittleEndian> ~ <Seq~List <Digit 0>~ℤ_2^64~machine.UInt64>"),
+        {
+            let ctx = ctx.clone();
+            move |rt, σ| {
+                let digits = rt
+                    .descend(Context::parse(&ctx, "ℕ ~ machine.UInt64")).unwrap()
+                    .view_u64()
+                    .to_sequence()
+                    .to_list();
+
+                rt.attach_leaf_to(
+                    Context::parse(&ctx, "ℕ ~ <PosInt 0 LittleEndian> ~ <Seq~List <Digit 0>~ℤ_2^64~machine.UInt64>"),
+                    digits
+                );
+            }
+        }
+    );
+    let posint_list_morph_to_u64 = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "ℕ ~ <PosInt 0 LittleEndian> ~ <Seq~List <Digit 0>~ℤ_2^64~machine.UInt64>"),
+        Context::parse(&ctx, "ℕ ~ machine.UInt64"),
+        {
+            let ctx = ctx.clone();
+            move |rt, σ| {
+                /*
+                let u64_view = rt
+                    .descend(Context::parse(&ctx, "ℕ ~ <PosInt 2^64 LittleEndian> ~ <Seq~List <Digit 2^64>~ℤ_2^64~machine.UInt64>"),
+                    .view_list()
+                    .to_singleton()
+                    .map(||{
+                        
+                    })
+
+                rt.attach_leaf_to(
+                    Context::parse(&ctx, "ℕ ~ machine.UInt64")).unwrap()
+                    u64_view
+                );
+            */
+            }
+        }
+    );
+
     ctx.write().unwrap().morphisms.add_morphism( posint_seq_morph_big_to_little );
     ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_big_to_little );
     ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_little_to_big );    
     ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_radix );
+    ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_from_u64 );
+    ctx.write().unwrap().morphisms.add_morphism( posint_list_morph_to_u64 );
 }
 
diff --git a/lib-nested-core/src/editors/integer/radix.rs b/lib-nested-core/src/editors/integer/radix.rs
index 36213a9..685452b 100644
--- a/lib-nested-core/src/editors/integer/radix.rs
+++ b/lib-nested-core/src/editors/integer/radix.rs
@@ -116,9 +116,13 @@ impl RadixProjection {
             if val == 0 {
                 self.dst_digits.push(0);
             } else {
-                while val > 0 {
-                    self.dst_digits.push(val % self.dst_radix);
-                    val /= self.dst_radix;
+                if self.dst_radix == 0 {
+                    self.dst_digits.push(val);
+                } else {            
+                    while val > 0 {
+                        self.dst_digits.push(val % self.dst_radix);
+                        val /= self.dst_radix;
+                    }
                 }
             }
         }
diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs
index e4c35fa..887048b 100644
--- a/lib-nested-core/src/editors/list/ctx.rs
+++ b/lib-nested-core/src/editors/list/ctx.rs
@@ -91,8 +91,33 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
                         )
                     )
                 );
+            }           
+         }
+    );
+
+    let list_morph_editsetup3 = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "<List Item> ~ EditTree"),
+        Context::parse(&ctx, "<List Item> ~ <List EditTree>"),
+        {
+            let ctx = ctx.clone();
+            move |src_rt, σ| {
+                let edittree =
+                    src_rt
+                        .descend(
+                            Context::parse(&ctx, "<List Item>~EditTree")
+                                .apply_substitution(&|x| σ.get(x).cloned()).clone()
+                        ).unwrap()
+                        .singleton_buffer::<Arc<RwLock<EditTree>>>();
+
+                let list_edit = edittree.get().read().unwrap().get_edit::< ListEditor >().unwrap();
+                let edittree_items = list_edit.read().unwrap().data.get_port().to_list();
+
+                src_rt.attach_leaf_to(
+                    Context::parse(&ctx, "<List Item> ~ <List EditTree>")
+                        .apply_substitution(&|x| σ.get(x).cloned()).clone(),
+                    edittree_items
+                );
             }
-            
         }
     );
 
diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs
index 64c931f..12cb109 100644
--- a/lib-nested-core/src/editors/list/editor.rs
+++ b/lib-nested-core/src/editors/list/editor.rs
@@ -16,14 +16,13 @@ use {
 
 pub struct ListEditor {
     pub cursor: SingletonBuffer<ListCursor>,
-
-    // todo: (?) remove RwLock<..> around NestedNode ??
     pub data: VecBuffer< Arc<RwLock<EditTree>> >,
 
     pub spillbuf: Arc<RwLock<Vec<Arc<RwLock<EditTree>>>>>,
 
     pub(super) addr_port: OuterViewPort<dyn SequenceView<Item = isize>>,
     pub(super) mode_port: OuterViewPort<dyn SingletonView<Item = ListCursorMode>>,
+//  pub(super) grav_port: OuterViewPort<dyn SingletonView<Item = isize>>,
 
     depth: OuterViewPort<dyn SingletonView<Item = usize>>,
 
diff --git a/lib-nested-core/src/editors/product/segment.rs b/lib-nested-core/src/editors/product/segment.rs
index 0b223f5..a9c9318 100644
--- a/lib-nested-core/src/editors/product/segment.rs
+++ b/lib-nested-core/src/editors/product/segment.rs
@@ -19,7 +19,10 @@ use {
 
 #[derive(Clone)]
 pub enum ProductEditorSegment {
+    /// Terminal Node, i.e. literal, immutable string
     T( String, usize ),
+
+    /// Nonterminal Node, i.e. sub-editor for type t
     N {
         t: TypeTerm,
         editor: Option<NestedNode>,
diff --git a/lib-nested-core/src/repr_tree/morphism.rs b/lib-nested-core/src/repr_tree/morphism.rs
index d8eaf3d..fc641b5 100644
--- a/lib-nested-core/src/repr_tree/morphism.rs
+++ b/lib-nested-core/src/repr_tree/morphism.rs
@@ -1,6 +1,6 @@
 use {
     laddertypes::{TypeTerm, TypeID, morphism::Morphism},
-    r3vi::view::{AnyOuterViewPort, port::UpdateTask},
+    r3vi::view::{AnyOuterViewPort, port::*, list::*},
     crate::{
         repr_tree::{ReprTree, ReprTreeExt, ReprLeaf},
     },
@@ -77,52 +77,68 @@ impl GenericReprTreeMorphism {
                 lst_map_type.src_type.apply_substitution( &|x| subst.get(x).cloned() );
                 lst_map_type.dst_type.apply_substitution( &|x| subst.get(x).cloned() );
 
+                lst_map_type = lst_map_type.normalize();
+
                 eprintln!(
-                    "lst map type :  {:?}", lst_map_type
+                    "lst map type ::\n {:?}\n===>  {:?}\n\n", lst_map_type.src_type, lst_map_type.dst_type
                 );
 
-                let src_port = repr_tree
-                    .descend( lst_map_type.src_type.clone() )
-                    .expect("descend src seq")
-                    .view_list::<SrcItem>();
+                
+                let mut item_ladder = item_morph.morph_type.src_type.clone().get_lnf_vec();
+                let top_type = item_ladder.remove( item_ladder.len() - 1 );
 
-                let subst = subst.clone();
-                let item_morph = item_morph.clone();
+                if let Ok(item_sigma) = laddertypes::unify(
+                    &top_type,
+                    &TypeTerm::App(vec![
+                        TypeTerm::TypeID( list_typeid ),
+                        TypeTerm::TypeID( TypeID::Var( 200 ) )
+                    ])
+                ) {
+                    eprintln!("List OF List...");
+                } else {
+                    let src_port = repr_tree
+                        .descend( lst_map_type.src_type.clone() )
+                        .expect("descend src seq")
+                        .view_list::<SrcItem>();
 
-                let dst_view = src_port.map(
+                    let subst = subst.clone();
+                    let item_morph = item_morph.clone();
+
+                    let dst_view = src_port.map(
                         move |x| {
-                            let mut item_ladder = item_morph.morph_type.src_type.clone().get_lnf_vec();
                             let mut item_rt = ReprTree::from_singleton_buffer(
-                                item_ladder.remove( item_ladder.len() - 1 ),
-                                r3vi::buffer::singleton::SingletonBuffer::new(x.clone())
+                                    top_type.clone(),
+                                    r3vi::buffer::singleton::SingletonBuffer::new(x.clone())
                             );
+                            
 
                             // TODO: required?
-                            while item_ladder.len() > 0 {
-                                let mut n = ReprTree::new_arc( item_ladder.remove( item_ladder.len() - 1) );
+                            for t in item_ladder.iter().rev() {
+                                let mut n = ReprTree::new_arc( t.clone() );
                                 n.insert_branch( item_rt );
                                 item_rt = n;
                             }
 
-                            (item_morph.setup_projection)( &mut item_rt, &subst );
-                            item_rt.descend( item_morph.morph_type.dst_type.clone() ).expect("descend to item rt")
-                                .view_singleton::< DstItem >()
-                                .get_view().unwrap()
-                                .get()
-                        }
-                );
+                                (item_morph.setup_projection)( &mut item_rt, &subst );
+                                item_rt.descend( item_morph.morph_type.dst_type.clone() ).expect("descend to item rt")
+                                    .view_singleton::< DstItem >()
+                                    .get_view().unwrap()
+                                    .get()
+                        });
 
-                repr_tree.attach_leaf_to(
-                    lst_map_type.dst_type.clone(),
-                    dst_view as r3vi::view::OuterViewPort::< dyn r3vi::view::list::ListView<DstItem> >
-                );
+                    repr_tree.attach_leaf_to(
+                        lst_map_type.dst_type.clone(),
+                        dst_view as r3vi::view::OuterViewPort::< dyn r3vi::view::list::ListView<DstItem> >
+                    );
+                }
             })
         }
     }
 
     pub fn into_list_map_dyn(&self, typeid_list: TypeID)
     -> Option< GenericReprTreeMorphism >
-    { 
+    {        
+        let typeid_list = TypeID::Fun(0);
         let typeid_char = TypeID::Fun(1);
         let typeid_u64 = TypeID::Fun(5);
         let typeid_edittree = TypeID::Fun(2);
@@ -131,6 +147,16 @@ impl GenericReprTreeMorphism {
         let dst_item_type_lnf = self.morph_type.dst_type.clone().get_lnf_vec();
 
         if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_char)) &&
+           dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_char))
+        {
+            Some( self.into_list_map::< char, char >(typeid_list) )
+        }
+        else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_u64)) &&
+           dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_u64))
+        {
+            Some( self.into_list_map::< u64, u64 >(typeid_list) )
+        }
+        else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_char)) &&
            dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_u64))
         {
             Some( self.into_list_map::< char, u64 >(typeid_list) )
@@ -145,6 +171,33 @@ impl GenericReprTreeMorphism {
         {
             Some( self.into_list_map::< char, Arc<RwLock<crate::edit_tree::EditTree>> >(typeid_list) )
         }
+        else if src_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_edittree)) &&
+                dst_item_type_lnf.last() == Some(&TypeTerm::TypeID(typeid_char))
+        {
+            Some( self.into_list_map::< Arc<RwLock<crate::edit_tree::EditTree>>, char >(typeid_list) )
+        }
+
+        else if src_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_char) ])) &&
+                dst_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_char) ]))
+        {
+            Some( self.into_list_map::< char, char >(typeid_list) )
+        }
+        else if src_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_u64) ])) &&
+                dst_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_u64) ]))
+        {
+            Some( self.into_list_map::< u64, u64 >(typeid_list) )
+        }
+        else if src_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_char) ])) &&
+                dst_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_u64) ]))
+        {
+            Some( self.into_list_map::< OuterViewPort<dyn ListView<char>>, OuterViewPort<dyn ListView<u64>> >(typeid_list) )
+        }
+        else if src_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_u64) ])) &&
+                dst_item_type_lnf.last() == Some(&TypeTerm::App(vec![ TypeTerm::TypeID(typeid_list), TypeTerm::TypeID(typeid_char) ]))
+        {
+            Some( self.into_list_map::< OuterViewPort<dyn ListView<u64>>, OuterViewPort<dyn ListView<char>> >(typeid_list) )
+        }
+
         else
         {
             eprintln!("no list map type for {:?}", dst_item_type_lnf.last());
@@ -154,16 +207,4 @@ impl GenericReprTreeMorphism {
 }
 
 //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
-/*
-impl MorphismType {
-    pub fn to_str(&self, ctx: &Context) -> String {
-        format!("{:?} -> {:?}",
-                if let Some(t) = self.src_type.as_ref() {
-                    ctx.type_dict.read().unwrap().unparse(t)
-                } else {
-                    "None".into()
-                },
-                ctx.type_dict.read().unwrap().unparse(&self.dst_type))
-    }
-}
-*/
+
diff --git a/lib-nested-core/src/repr_tree/node.rs b/lib-nested-core/src/repr_tree/node.rs
index 6882b7d..c40e5f9 100644
--- a/lib-nested-core/src/repr_tree/node.rs
+++ b/lib-nested-core/src/repr_tree/node.rs
@@ -392,3 +392,4 @@ impl ReprTree {
 
 //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
 
+
diff --git a/lib-nested-tty/src/lib.rs b/lib-nested-tty/src/lib.rs
index 2bc1138..5ea0f11 100644
--- a/lib-nested-tty/src/lib.rs
+++ b/lib-nested-tty/src/lib.rs
@@ -121,7 +121,8 @@ pub fn setup_edittree_hook(ctx: &Arc<RwLock<Context>>) {
     let char_type = Context::parse(&ctx, "Char");
     let digit_type = Context::parse(&ctx, "<Digit Radix>");
     let list_type = Context::parse(&ctx, "<List Item>");
-    let posint_type = Context::parse(&ctx, "<PosInt Radix>");
+    let posint_dec_type = Context::parse(&ctx, "<PosInt 10 BigEndian>");
+    let posint_hex_type = Context::parse(&ctx, "<PosInt 16 BigEndian>");
     let item_tyid = ctx.read().unwrap().get_var_typeid("Item").unwrap();
 
     ctx.write().unwrap().meta_chars.push(',');
@@ -134,18 +135,20 @@ pub fn setup_edittree_hook(ctx: &Arc<RwLock<Context>>) {
     ctx.write().unwrap().set_edittree_hook(
         Arc::new(
             move |et: &mut nested::edit_tree::EditTree, t: laddertypes::TypeTerm| {
-//                let mut et = et.write().unwrap();
-
                 if let Ok(σ) = laddertypes::unify(&t, &char_type.clone()) {
                     *et = crate::editors::edittree_make_char_view(et.clone());
                 }
                 else if let Ok(σ) = laddertypes::unify(&t, &digit_type) {
                     *et = crate::editors::edittree_make_digit_view(et.clone());
                 }
-                else if let Ok(σ) = laddertypes::unify(&t, &posint_type) {
+                else if let Ok(σ) = laddertypes::unify(&t, &posint_dec_type) {
                     crate::editors::list::PTYListStyle::for_node( &mut *et, ("0d", "", ""));
                     crate::editors::list::PTYListController::for_node( &mut *et, None, None );
                 }
+                else if let Ok(σ) = laddertypes::unify(&t, &posint_hex_type) {
+                    crate::editors::list::PTYListStyle::for_node( &mut *et, ("0x", "", ""));
+                    crate::editors::list::PTYListController::for_node( &mut *et, None, None );
+                }
                 else if let Ok(σ) = laddertypes::unify(&t, &list_type) {
                     let item_type = σ.get( &laddertypes::TypeID::Var(item_tyid) ).unwrap();