From 26186b3375f886b18ae5332ee053781f5befe81b Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Tue, 24 Dec 2024 12:50:02 +0100
Subject: [PATCH] wip: Refactor ReprTree; add ReprTreeBuilder

---
 examples/tty-02-digit/src/main.rs          |  49 +----
 examples/tty-03-string/src/main.rs         |  77 +++----
 examples/tty-04-posint/src/main.rs         |  92 +++-----
 examples/tty-05-dictionary/src/main.rs     |  73 ++-----
 examples/tty-06-lines/src/main.rs          | 127 ++++++-----
 examples/tty-07-color/Cargo.toml           |  19 ++
 examples/tty-07-color/src/main.rs          | 232 +++++++++++++++++++++
 lib-nested-core/src/edit_tree/node.rs      |  11 +-
 lib-nested-core/src/editors/list/cmd.rs    |  58 +++---
 lib-nested-core/src/editors/list/ctx.rs    |  96 ++++++---
 lib-nested-core/src/editors/list/editor.rs | 206 ++++++++++--------
 lib-nested-core/src/editors/list/nav.rs    |  62 +++---
 lib-nested-core/src/repr_tree/builder.rs   | 108 ++++++++++
 lib-nested-core/src/repr_tree/context.rs   |  33 ---
 lib-nested-core/src/repr_tree/leaf.rs      |   5 +-
 lib-nested-core/src/repr_tree/mod.rs       |  22 +-
 lib-nested-core/src/repr_tree/morphism.rs  |  68 +++---
 lib-nested-core/src/repr_tree/node.rs      | 124 ++++++-----
 lib-nested-tty/src/editors/list.rs         |  18 +-
 lib-nested-tty/src/lib.rs                  |   7 +-
 20 files changed, 924 insertions(+), 563 deletions(-)
 create mode 100644 examples/tty-07-color/Cargo.toml
 create mode 100644 examples/tty-07-color/src/main.rs
 create mode 100644 lib-nested-core/src/repr_tree/builder.rs

diff --git a/examples/tty-02-digit/src/main.rs b/examples/tty-02-digit/src/main.rs
index 9279cc5..93a1b8e 100644
--- a/examples/tty-02-digit/src/main.rs
+++ b/examples/tty-02-digit/src/main.rs
@@ -11,7 +11,7 @@ use {
     cgmath::Vector2,
     nested::{
         editors::ObjCommander,
-        repr_tree::{Context, ReprTree, ReprTreeExt},
+        repr_tree::{Context, ReprTree, ReprTreeExt, ReprTreeBuilder},
         edit_tree::{EditTree}
     },
     nested_tty::{
@@ -39,50 +39,23 @@ async fn main() {
 
     nested_tty::setup_edittree_hook(&ctx);
 
-    /* structure of Repr-Tree
-     *
-     *   === Repr-Tree ===
-     *
-     *        <Digit 10>
-     *         /   |     \
-     *        /    |        \
-     *       /     |          \
-     *     u64   EditTree     Char
-     *           - Editor         \
-     *           - Display        EditTree
-     *         /     |    \      - Editor
-     *        /      |     \     - Display
-     *      TTY  PixelBuf  SDF  /    |     \
-     *                         /     |      \
-     *                       TTY  PixelBuf  SDF
-     */
-    let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") );
+    let digit_builder = ReprTreeBuilder::new( ctx.clone() )
+        .require(Context::parse(&ctx, "<Digit 16> ~ ℤ_2^64 ~ machine.UInt64"))
+        .require(Context::parse(&ctx, "<Digit 16> ~ EditTree"))
+    ;
 
     /* add initial representation
      *  <Digit 16> ~ Char
      */
-    rt_digit.insert_leaf(
+    let mut rt_digit = ReprTree::from_singleton_buffer(
         Context::parse(&ctx, "Char"),
-        nested::repr_tree::ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') )
+        SingletonBuffer::new('5')
     );
-
-    /* furthermore, setup projections to and from u8 value,
-     * this synchronizes the buffers 
-     */
-    ctx.read().unwrap().apply_morphism(
-        &rt_digit,
-        &laddertypes::MorphismType {
-            src_type: Context::parse(&ctx, "<Digit 16>~Char"),
-            dst_type: Context::parse(&ctx, "<Digit 16>~ℤ_2^64~machine.UInt64")
-        }
-    );
-    ctx.read().unwrap().apply_morphism(
-        &rt_digit,
-        &laddertypes::MorphismType {
-            src_type: Context::parse(&ctx, "<Digit 16>~Char"),
-            dst_type: Context::parse(&ctx, "<Digit 16>~EditTree")
-        }
+    rt_digit.write().unwrap().set_halo(
+        Context::parse(&ctx, "<Digit 16>")
     );
+    rt_digit = digit_builder.build_from(rt_digit)
+        .expect("failed to build repr tree");
 
     /* setup terminal
      */
diff --git a/examples/tty-03-string/src/main.rs b/examples/tty-03-string/src/main.rs
index d5f8ff9..c3fa53e 100644
--- a/examples/tty-03-string/src/main.rs
+++ b/examples/tty-03-string/src/main.rs
@@ -15,7 +15,7 @@ use {
     cgmath::Vector2,
     nested::{
         editors::ObjCommander,
-        repr_tree::{Context, ReprTree, ReprTreeExt},
+        repr_tree::{Context, ReprTree, ReprTreeExt, ReprTreeBuilder},
         edit_tree::{EditTree}
     },
     nested_tty::{
@@ -43,35 +43,45 @@ async fn main() {
 
     /* Create a Representation-Tree of type <List Char>
      */
-    let mut rt_string = ReprTree::from_str(
-        Context::parse(&ctx, "<List Char>~<Vec Char>"),
-        "hello world"
+    let mut ldata = VecBuffer::new();
+    for c in "Hello World!".chars() {
+        let rt = ReprTree::from_singleton_buffer(
+            Context::parse(&ctx, "Char"),
+            SingletonBuffer::new(c));
+
+        ldata.push(rt);
+    }
+
+    let mut ldata_rt = ReprTree::from_vec_buffer(
+        Context::parse(&ctx, "<Vec ReprTree>"),
+        ldata.clone()
     );
 
-    /* create EditTree
-     */
-    ctx.read().unwrap().apply_morphism(
-        &rt_string,
-        &laddertypes::MorphismType {
-            src_type: Context::parse(&ctx, "<List~Vec Char>"),
-            dst_type: Context::parse(&ctx, "<List Char> ~ EditTree")
-        }
+    ldata_rt.write().unwrap().set_halo(
+        Context::parse(&ctx, "<List Char>~<List ReprTree>")
     );
 
-    // .. avoid cycle of projections..
-    rt_string.write().unwrap().detach(&ctx);
-
-    /* In order to get access to the values that are modified by the Editor,
-     * we apply a morphism that, given the List of Edit-Trees, extracts
-     * the value from each EditTree and shows them in a ListView.
-     */
-    ctx.read().unwrap().apply_morphism(
-        &rt_string,
-        &laddertypes::MorphismType {
-            src_type: Context::parse(&ctx, "<List Char>~EditTree"),
-            dst_type: Context::parse(&ctx, "<List Char>")
-        }
+    let mut ledit = nested::editors::list::ListEditor::with_data(
+        ctx.clone(),
+        Context::parse(&ctx, "Char"),
+        ldata
     );
+    ledit.update_item_reprtrees(&Context::parse(&ctx, "Char"));
+    ledit.update_item_reprtrees(&Context::parse(&ctx, "Char~EditTree"));
+    let mut ledit = ledit.into_node(SingletonBuffer::new(0).get_port());
+
+    nested_tty::editors::list::PTYListStyle::for_node(&mut ledit, ("<", "", ">"));
+    nested_tty::editors::list::PTYListController::for_node(&mut ledit, None, None);
+    let ledittree = SingletonBuffer::new(Arc::new(RwLock::new(ledit)));
+
+    let rt_string_builder = ReprTreeBuilder::new( ctx.clone() )
+        .require(Context::parse(&ctx, "<List Char>~<Vec Char>"))
+        .require(Context::parse(&ctx, "<List Char>"))
+        .require(Context::parse(&ctx, "<List Char>~EditTree"))
+    ;
+
+    let rt_string = rt_string_builder.build_from(ldata_rt).expect("could not build rt_string");
+    eprintln!("rt_string = \n{}", rt_string.read().unwrap().fmt(&ctx, 0));
 
     /* Now, get the ListView that serves our char-values.
      * This view is a projection created by the morphism that was called above.
@@ -81,17 +91,6 @@ async fn main() {
         .get_port::<dyn ListView<char>>()
         .unwrap();
 
-    /* Lets add another morphism which will store the values
-     * of the character-list in a `Vec<char>`
-     */
-    ctx.read().unwrap().apply_morphism(
-        &rt_string,
-        &laddertypes::MorphismType {
-            src_type: Context::parse(&ctx, "<List Char>"),
-            dst_type: Context::parse(&ctx, "<List Char>~<Vec Char>")
-        }
-    );
-
     /* Access the Vec<char> object (wrapped behind a VecBuffer<char>)
      * from the ReprTree.
      */
@@ -109,7 +108,7 @@ async fn main() {
     /* setup terminal
      */
     let app = TTYApplication::new({
-        let edittree_list = rt_string.edittree(&ctx).clone();
+        let edittree_list = ledittree.clone();//rt_string.edittree(&ctx).clone();
 
         /* event handler
          */
@@ -137,7 +136,8 @@ async fn main() {
                 .offset(Vector2::new(1,1)));
 
         comp.push(
-            rt_string.edittree(&ctx).get()
+            //rt_string.edittree(&ctx).get()
+            ledittree.get()
                 .read().unwrap()
                 .display_view()
                 .offset(Vector2::new(3,2)));
@@ -145,6 +145,7 @@ async fn main() {
         comp.push(
             string_view_tty
                 .offset(Vector2::new(5,3)));
+
     }
 
     /* write the changes in the view of `term_port` to the terminal
diff --git a/examples/tty-04-posint/src/main.rs b/examples/tty-04-posint/src/main.rs
index 4c91ee5..7ffbc87 100644
--- a/examples/tty-04-posint/src/main.rs
+++ b/examples/tty-04-posint/src/main.rs
@@ -16,7 +16,7 @@ use {
         editors::{
             ObjCommander
         },
-        repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf},
+        repr_tree::{Context, ReprTreeBuilder, ReprTree, ReprTreeExt, ReprLeaf},
         edit_tree::{EditTree, TreeNav, TreeCursor}
     },
     nested_tty::{
@@ -46,76 +46,49 @@ async fn main() {
     /* Create a Representation-Tree of type `ℕ`
      * with a specific representation-path (big-endian hexadecimal string)
      */
-    let mut rt_int = nested::repr_tree::ReprTree::from_str(
-        /* TYPE */
+    let int_builder = ReprTreeBuilder::new( ctx.clone() )
+            .require(Context::parse(&ctx,
+                "ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>~Char> ~ EditTree"))
+            /*
+            .require(Context::parse(&ctx,
+                "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq~List <Digit 16>> ~ EditTree"))
+            .require(Context::parse(&ctx,
+                "ℕ ~ <PosInt 16 BigEndian> ~ EditTree"))
+            .require(Context::parse(&ctx,
+                "ℕ ~ <PosInt 8 BigEndian> ~ EditTree"))
+            .require(Context::parse(&ctx,
+                "ℕ ~ <PosInt 2 BigEndian> ~ EditTree"))
+                */
+                ;
+
+    let mut rt_int = nested::repr_tree::ReprTree::from_str("cff");
+    rt_int.write().unwrap().set_halo(
+        /* HALO TYPE */
         Context::parse(&ctx, "
               ℕ
             ~ <PosInt 16 BigEndian>
             ~ <Seq <Digit 16>>
             ~ <List <Digit 16>>
             ~ <List Char>
-            ~ <Vec Char>
-        "),
-
-        /* VALUE */
-        "cff"
+        ")
     );
 
-    /* initially copy values from Vec to EditTree...
-     */
-    ctx.read().unwrap().build_repr_tree(
-        &rt_int,
-        Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>~Char> ~ <Vec Char>"),
-        vec![
-            Context::parse(&ctx, "ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>> ~ EditTree"),
-            Context::parse(&ctx, "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq~List <Digit 16>> ~ EditTree"),
-        ]);
+    eprintln!("rt_int = \n{}\n", rt_int.read().unwrap().fmt(&ctx, 0));
 
-    fn set_master(
-        ctx: &Arc<RwLock<Context>>,
-        rt: &Arc<RwLock<ReprTree>>,
-        mut leaves: Vec< laddertypes::TypeTerm >,
-        master_idx: usize
-    ) {
-        eprintln!("set master to {}", master_idx);
-        if master_idx < leaves.len() {
-            let master = leaves.remove( master_idx );
-            rt.write().unwrap().detach( &ctx );
-            ctx.read().unwrap().build_repr_tree(
-                rt,
-                master,
-                leaves
-            );
-        }
-    }
+    rt_int = int_builder.build_from( rt_int ).expect("cant build initial repr tree");
 
-    let editor_types = vec![
-         Context::parse(&ctx,
-             "ℕ ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>> ~ EditTree"),
-         Context::parse(&ctx,
-             "ℕ ~ <PosInt 16 LittleEndian> ~ <Seq~List <Digit 16>> ~ EditTree"),
-         Context::parse(&ctx,
-             "ℕ ~ <PosInt 16 BigEndian> ~ EditTree"),
-         Context::parse(&ctx,
-             "ℕ ~ <PosInt 8 BigEndian> ~ EditTree"),
-         Context::parse(&ctx,
-             "ℕ ~ <PosInt 2 BigEndian> ~ EditTree"),
-    ];
+    eprintln!("rt_int = \n{}\n", rt_int.read().unwrap().fmt(&ctx, 0));
 
-    set_master(&ctx, &rt_int, editor_types.clone(), 0);
+    return;
 
     /* list of editors
      */
     let mut list_editor = nested::editors::list::ListEditor::new(ctx.clone(), Context::parse(&ctx, "<Seq Char>"));
 
     // add all desired editors to the list
-    for leaf in editor_types.iter() {
-        let et =  
-            rt_int
-                .descend(leaf.clone()).unwrap()
-                .edittree(&ctx).get();
-        et.write().unwrap().goto(TreeCursor::none());
-        list_editor.data.push(et);
+    for edit_leaf in int_builder.required_leaves {
+        let leaf_rt = rt_int.descend(edit_leaf.clone()).unwrap();
+        list_editor.data.push(leaf_rt);
     }
 
     let mut edittree = list_editor.into_node(SingletonBuffer::new(0).get_port());
@@ -128,7 +101,7 @@ async fn main() {
         tree_addr: vec![0,0]
     });
     let edittree = Arc::new(RwLock::new(edittree));
- 
+
     /* setup terminal
      */
     let app = TTYApplication::new({
@@ -137,7 +110,6 @@ async fn main() {
         let ctx = ctx.clone();
         let rt_int = rt_int.clone();
         let last_idx = RwLock::new(0);
-        let editor_types = editor_types.clone();
         move |ev| {
             let cur = edittree.read().unwrap().get_cursor();
             if cur.tree_addr.len() > 0 {
@@ -145,6 +117,7 @@ async fn main() {
                 let ci = cur.tree_addr[0];
 
                 if *li != ci {
+                    /*
                     eprintln!("----------------------------------");
                     set_master(
                         &ctx,
@@ -152,6 +125,8 @@ async fn main() {
                         editor_types.clone(),
                         ci as usize
                     );
+                    */
+                    int_builder.update( &rt_int, int_builder.required_leaves[ci as usize].clone() );
                     *li = ci;
                 }
             }
@@ -177,7 +152,7 @@ async fn main() {
             let halo_type = rt_edittree.read().unwrap().get_halo_type().clone();
             let edittree = rt_edittree.edittree( &ctx );
 
-            comp.push(  nested_tty::make_label( &ctx.read().unwrap().type_term_to_str(&halo_type) ) 
+            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)));
 
@@ -186,7 +161,7 @@ async fn main() {
         }
 
         let mut y = 1;
-        for t in editor_types.iter() {
+        for t in int_builder.required_leaves.iter() {
             show_edit_tree(&ctx, &mut comp, &rt_int.descend(t.clone()).expect(""), y);
             y += 3;
         }
@@ -196,4 +171,3 @@ async fn main() {
      */
     app.show().await.expect("output error!");
 }
-
diff --git a/examples/tty-05-dictionary/src/main.rs b/examples/tty-05-dictionary/src/main.rs
index d6daefc..f5b4478 100644
--- a/examples/tty-05-dictionary/src/main.rs
+++ b/examples/tty-05-dictionary/src/main.rs
@@ -10,7 +10,7 @@ use {
         editors::{
             ObjCommander
         },
-        repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf},
+        repr_tree::{Context, ReprTreeBuilder, ReprTree, ReprTreeExt, ReprLeaf},
         edit_tree::{EditTree, TreeNav, TreeCursor}
     },
     laddertypes::{
@@ -160,62 +160,24 @@ async fn main() {
     ctx.write().unwrap().morphisms.add_morphism( symbol_morph_u64_to_str );
     ctx.write().unwrap().morphisms.add_morphism( symbol_morph_str_to_u64 );
 
-    let mut symbol_rt = nested::repr_tree::ReprTree::from_str(Context::parse(&ctx, "
-            Instruction ~ Mnemonic ~ <Seq~List~Vec Char>
-        "),
-        "Call"
-    );
+    let mut symbol_rt = nested::repr_tree::ReprTree::from_str("Call");
+    symbol_rt.write().unwrap().set_halo(Context::parse(&ctx, "
+        Instruction ~ Mnemonic ~ <Seq~List Char>
+    "));
 
-    // this is required to initialize the <Vec EditTree> representation,
-    // and to take the value from <Vec Char>
-    ctx.read().unwrap().build_repr_tree(
-        &symbol_rt,
-        Context::parse(&ctx, "Instruction ~ Mnemonic ~ <Seq~List~Vec Char>"),
-        vec![
-            Context::parse(&ctx, "Instruction ~ Opcode ~ ℕ ~ <PosInt 10 BigEndian> ~ EditTree"),
-            Context::parse(&ctx, "Instruction ~ Mnemonic ~ <Seq~List Char> ~ EditTree"),
-        ]);
+    let symbol_builder = ReprTreeBuilder::new( ctx.clone() )
+        //.require(Context::parse(&ctx, "Instruction ~ Opcode ~ ℕ ~ <PosInt 10 BigEndian> ~ EditTree"))
+        .require(Context::parse(&ctx, "Instruction ~ Mnemonic ~ <Seq~List Char> ~ EditTree"))
+    ;
 
-    symbol_rt.write().unwrap().detach( &ctx );
+    symbol_rt = symbol_builder.build_from(symbol_rt).expect("failed to build symbol repr-tree");
 
-    fn set_master(
-        ctx: &Arc<RwLock<Context>>,
-        rt: &Arc<RwLock<ReprTree>>,
-        mut leaves: Vec< laddertypes::TypeTerm >,
-        master_idx: usize
-    ) {
-        eprintln!("set master to {}", master_idx);
-        if master_idx < leaves.len() {
-            let master = leaves.remove( master_idx );
-            rt.write().unwrap().detach( &ctx );
-            ctx.read().unwrap().build_repr_tree(
-                rt,
-                master,
-                leaves
-            );
-        }
-    }
-
-    let editor_types = vec![
-         Context::parse(&ctx,
-             "Instruction ~ Mnemonic ~ <Seq~List Char> ~ EditTree"),
-         Context::parse(&ctx,
-             "Instruction ~ Opcode ~ ℕ ~ <PosInt 10 BigEndian> ~ EditTree"),
-         Context::parse(&ctx,
-             "Instruction ~ Opcode ~ ℕ ~ <PosInt 16 BigEndian> ~ EditTree"),
-    ];
-
-    set_master(&ctx, &symbol_rt, editor_types.clone(), 0);
     let mut list_editor = nested::editors::list::ListEditor::new(ctx.clone(), Context::parse(&ctx, "<Seq Char>"));
 
     // add all desired editors to the list
-    for leaf in editor_types.iter() {
-        let et =
-            symbol_rt
-                .descend(leaf.clone()).unwrap()
-                .edittree(&ctx).get();
-        et.write().unwrap().goto(TreeCursor::none());
-        list_editor.data.push(et);
+    for edit_leaf in symbol_builder.required_leaves {
+        let leaf_rt = symbol_rt.descend(edit_leaf.clone()).unwrap();
+        list_editor.data.push(leaf_rt);
     }
 
     let mut edittree = list_editor.into_node(SingletonBuffer::new(0).get_port());
@@ -233,7 +195,6 @@ async fn main() {
         let ctx = ctx.clone();
         let symbol_rt = symbol_rt.clone();
         let last_idx = RwLock::new(0);
-        let editor_types = editor_types.clone();
         move |ev| {
             let cur = edittree.read().unwrap().get_cursor();
             if cur.tree_addr.len() > 0 {
@@ -241,13 +202,7 @@ async fn main() {
                 let ci = cur.tree_addr[0];
 
                 if *li != ci {
-                    eprintln!("----------------------------------");
-                    set_master(
-                        &ctx,
-                        &symbol_rt,
-                        editor_types.clone(),
-                        ci as usize
-                    );
+                    // symbol_builder.update()
                     *li = ci;
                 }
             }
diff --git a/examples/tty-06-lines/src/main.rs b/examples/tty-06-lines/src/main.rs
index 701c26c..33a956e 100644
--- a/examples/tty-06-lines/src/main.rs
+++ b/examples/tty-06-lines/src/main.rs
@@ -32,16 +32,20 @@ struct LineDiagnostic {
     msg: String
 }
 
+struct LineEditor {
+    num_buf: SingletonBuffer< u64 >,
+    diag_buf: VecBuffer< LineDiagnostic >,
+    chars_edit: Arc<RwLock<ListEditor>>,
+    out_port: ViewPort< dyn TerminalView >,
+    view: Arc<RwLock< LineView >>,
+    cast: Arc<RwLock<ObserverBroadcast<dyn TerminalView>>>,
+}
+
 struct LineView {
     line_num: Arc< dyn SingletonView<Item = u64> >,
     segments: Arc< dyn SequenceView<Item = ListSegment> >,
     diagnostics: Arc< dyn SequenceView<Item = LineDiagnostic> >,
-
-    diag_buf: VecBuffer< LineDiagnostic >,
-
-    cast: Arc<RwLock<ObserverBroadcast<dyn TerminalView>>>,
-    out_port: OuterViewPort<dyn TerminalView>,
-    proj_helper: ProjectionHelper<usize, Self>
+    proj_helper: ProjectionHelper<usize, LineEditor>
 }
 
 impl View for LineView {
@@ -121,10 +125,9 @@ impl IndexView<Point2<i16>> for LineView {
         while n > 0 { n_digits += 1; n /= 10; }
         let diag_len = self.diagnostics.iter().map(|d| d.msg.chars().count() as i16).max().unwrap_or(0);
         IndexArea::Range(
-            Point2::new( xoff -1-n_digits , 0) ..=
+            Point2::new( xoff - n_digits - 1 , 0) ..=
             Point2::new(
-                xoff+
-                i16::max(
+                xoff + i16::max(
                     self.segments.len().unwrap_or(i16::MAX as usize) as i16,
                     diag_len
                 ),
@@ -134,57 +137,72 @@ impl IndexView<Point2<i16>> for LineView {
     }
 }
 
-impl LineView {
+impl LineEditor {
     pub fn new(
+        ctx: &Arc<RwLock<Context>>,
         n: u64,
-        le: &ListEditor,
     ) -> Arc<RwLock<Self>> {
-        let line_num_buf = SingletonBuffer::new(n);
+        let num_buf = SingletonBuffer::new(n);
         let diag_buf = VecBuffer::new();
-        let seg_seq = ListSegmentSequence::new(le.get_cursor_port(), le.get_data_port())
+        let chars_edit = ListEditor::new(
+            ctx.clone(),
+            Context::parse(&ctx, "<List Char>")
+        );
+        let chars_seg_seq = ListSegmentSequence::new(chars_edit.get_cursor_port(), chars_edit.get_data_port())
             .read().unwrap().get_view();
 
         let out_port = ViewPort::new();
-        let mut proj_helper = ProjectionHelper::new(out_port.update_hooks.clone());
 
-        let lv = Arc::new(RwLock::new(LineView{
-            line_num: proj_helper.new_singleton_arg(0, line_num_buf.get_port(),
-                |s: &mut LineView, _msg|{
-                    s.cast.write().unwrap()
+        let mut proj_helper = ProjectionHelper::new(out_port.update_hooks.clone());
+        let line_view = Arc::new(RwLock::new(LineView {
+            line_num: proj_helper.new_singleton_arg(0, num_buf.get_port(),
+                |e: &mut LineEditor, _msg|{
+                    e.cast.write().unwrap()
                         .notify(&IndexArea::Range(
                             (Point2::new(-100, 0) ..= Point2::new(0, 0))
                         ));
                 }),
-            segments: proj_helper.new_sequence_arg(1, seg_seq,
-                |s: &mut LineView, idx| {
-                    s.cast.write().unwrap()
+            segments: proj_helper.new_sequence_arg(1, chars_seg_seq,
+                |e: &mut LineEditor, idx| {
+                    e.cast.write().unwrap()
                         .notify(&IndexArea::Range(
-                            (Point2::new(0, *idx as i16 - 1) ..= Point2::new(100, *idx as i16))
+                            (Point2::new(*idx as i16, 0) ..= Point2::new(*idx as i16, 0))
                         ));
                 }),
             diagnostics: proj_helper.new_sequence_arg(2, diag_buf.get_port().to_sequence(),
-                |s: &mut LineView, idx| {
-                    s.cast.write().unwrap()
+                |e: &mut LineEditor, idx| {
+                    e.cast.write().unwrap()
                         .notify(&IndexArea::Range(
                             (Point2::new(-100, 1+*idx as i16) ..= Point2::new(100, 1+*idx as i16))
                         ));
                 }),
 
-            diag_buf,
-
-            cast: out_port.inner().get_broadcast(),
             proj_helper,
-            out_port: out_port.outer()
         }));
 
-        lv.write().unwrap().proj_helper.set_proj(&lv);
-        out_port.inner().set_view(Some(lv.clone()));
+        let line_edit = Arc::new(RwLock::new(LineEditor {
+            num_buf,
+            diag_buf,
+            chars_edit: Arc::new(RwLock::new(chars_edit)),
+            cast: out_port.inner().get_broadcast(),
+            view: line_view.clone(),
+            out_port,
+        }));
 
-        lv
+        line_view.write().unwrap().proj_helper.set_proj(&line_edit);
+        line_edit
+    }
+
+    pub fn set_linum(&mut self, n: u64) {
+        self.num_buf.set(n);
+    }
+
+    pub fn add_diag(&mut self, diag: LineDiagnostic) {
+        self.diag_buf.push(diag);
     }
 
     pub fn get_port(&self) -> OuterViewPort<dyn TerminalView> {
-        self.out_port.clone()
+        self.out_port.outer()
     }
 }
 
@@ -205,6 +223,11 @@ impl LinesEditor {
             Context::parse(&ctx, "Line ~ EditTree"),
             |rt, σ| {
                 eprintln!("LINE EDITOR CONSTRUCT");
+/*
+                rt.insert_branch(
+                    Context::parse(&ctx, "EditTree"),
+
+                )*/
             }
         );
         ctx.write().unwrap().morphisms.add_morphism( line_to_edittree );
@@ -238,12 +261,11 @@ impl LinesEditor {
 
         let mut list_edit = list_edit.into_node( depth_port );
         nested_tty::editors::list::PTYListController::for_node( &mut list_edit, Some('\n'), None );
-        list_edit.disp.view
-                .write().unwrap()
-                .insert_branch(ReprTree::from_view(
-                    Context::parse(&ctx, "TerminalView"),
-                    lines_view
-                ));
+        list_edit.disp.view.write().unwrap()
+            .insert_branch(ReprTree::from_view(
+                Context::parse(&ctx, "TerminalView"),
+                lines_view
+            ));
 
         LinesEditor {
            // lines,
@@ -258,26 +280,34 @@ impl LinesEditor {
             .read().unwrap()
             .data.len() as u64;
 
-        let line =
-            self.make_line(line_value)
-                .descend(Context::parse(&self.ctx, "EditTree")).unwrap()
-                .edittree(&self.ctx).get();
+        let depth = SingletonBuffer::new(0).get_port();
 
-        let le = line.read().unwrap().get_edit::<ListEditor>().unwrap();
-        le.write().unwrap().goto(TreeCursor::none());
+        let chars_rt = self.make_line(line_value);
+        let chars_edittree = chars_rt
+            .descend(Context::parse(&self.ctx, "EditTree")).unwrap()
+            .edittree(&self.ctx).get()
+            .read().unwrap().clone();
 
-        let lvport = LineView::new( n, &*le.read().unwrap() ).read().unwrap().get_port();
-        line.write().unwrap().disp.view
+        let line = LineEditor::new(&self.ctx, n);
+        line.write().unwrap().chars_edit = chars_edittree.get_edit::<ListEditor>().unwrap();
+        let line_port = line.read().unwrap().get_port();
+
+        let mut line_edittree = EditTree::new(self.ctx.clone(), depth)
+            .set_nav( line.read().unwrap().chars_edit.clone() )
+            .set_cmd( line.read().unwrap().chars_edit.clone() )
+            .set_editor( line.clone() );
+
+        line_edittree.disp.view
             .insert_leaf(
                 Context::parse(&self.ctx, "TerminalView"),
-                ReprLeaf::from_view( lvport )
+                ReprLeaf::from_view( line_port )
             );
 
         self.edit.write().unwrap()
             .get_edit::< ListEditor >().unwrap()
             .write().unwrap()
             .data
-            .push(line);
+            .push( Arc::new(RwLock::new(line_edittree)) );
     }
 
     pub fn make_line(&self, line_value: &str) -> Arc<RwLock<ReprTree>> {
@@ -287,6 +317,7 @@ impl LinesEditor {
             line_value
         );
 
+        // create Editor & transfer data to Editor
         ctx.read().unwrap().apply_morphism(
             &rt_line,
             &laddertypes::MorphismType {
diff --git a/examples/tty-07-color/Cargo.toml b/examples/tty-07-color/Cargo.toml
new file mode 100644
index 0000000..53db651
--- /dev/null
+++ b/examples/tty-07-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-07-color/src/main.rs b/examples/tty-07-color/src/main.rs
new file mode 100644
index 0000000..e02ae87
--- /dev/null
+++ b/examples/tty-07-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/node.rs b/lib-nested-core/src/edit_tree/node.rs
index 8b5a8a6..53d1c4b 100644
--- a/lib-nested-core/src/edit_tree/node.rs
+++ b/lib-nested-core/src/edit_tree/node.rs
@@ -7,7 +7,7 @@ use {
     },
     laddertypes::{TypeTerm},
     crate::{
-        repr_tree::{ReprTree, Context},
+        repr_tree::{ReprTree, ReprTreeArc, Context},
         edit_tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp, diagnostics::{Diagnostics, Message}},
         editors::{list::{ListCursorMode}, ObjCommander}
     }
@@ -32,9 +32,7 @@ pub struct EdittreeControl {
                     Option< Arc<dyn Any + Send + Sync> >
                 >,
 
-    pub spillbuf: Arc<RwLock<
-                    Vec< Arc<RwLock< EditTree >> >
-                  >>,
+    pub spillbuf: Arc<RwLock< Vec< ReprTreeArc > >>,
 
     /// commander & navigation
     pub cmd: SingletonBuffer<
@@ -46,7 +44,7 @@ pub struct EdittreeControl {
     // could be replaced by cmd when TreeNav -CmdObjects are used
     pub tree_nav: SingletonBuffer<
                       Option< Arc<RwLock<dyn TreeNav + Send + Sync>> >
-                  >,    
+                  >,
 }
 
 #[derive(Clone)]
@@ -153,7 +151,7 @@ impl TreeNav for EditTree {
             tn.read().unwrap().get_mode_view()
         } else {
             OuterViewPort::default()
-        }        
+        }
     }
 
     fn get_cursor_warp(&self) -> TreeCursor {
@@ -225,4 +223,3 @@ impl Diagnostics for EditTree {
         self.get_diag()
     }
 }
-
diff --git a/lib-nested-core/src/editors/list/cmd.rs b/lib-nested-core/src/editors/list/cmd.rs
index bbdd19c..03b3e96 100644
--- a/lib-nested-core/src/editors/list/cmd.rs
+++ b/lib-nested-core/src/editors/list/cmd.rs
@@ -25,7 +25,7 @@ impl ListCmd {
     // note: cant use Into becaue of ctx (maybe global typedict?)
     pub fn into_repr_tree(self, ctx: &Arc<RwLock<Context>>) -> Arc<RwLock<ReprTree>> {
         ReprTree::from_singleton_buffer(
-            Context::parse(ctx, "ListCmd"),            
+            Context::parse(ctx, "ListCmd"),
             r3vi::buffer::singleton::SingletonBuffer::new(self)
         )
     }
@@ -35,28 +35,7 @@ impl ObjCommander for ListEditor {
     fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
         let cmd_repr = cmd_obj.read().unwrap();
 
-        if let Some(view) = cmd_repr.get_view::<dyn SingletonView<Item = EditTree>>() {
-            let node = view.get();
-            let cur = self.cursor.get();
-
-            if let Some(idx) = cur.idx {
-                match cur.mode {
-                    ListCursorMode::Select => {
-                        *self.data.get_mut(idx as usize) = Arc::new(RwLock::new(node));
-                        TreeNavResult::Exit
-                    }
-                    ListCursorMode::Insert => {
-                        self.insert(Arc::new(RwLock::new(node)));
-                        self.cursor.set(ListCursor{ idx: Some(idx+1),  mode: ListCursorMode::Insert });
-                        TreeNavResult::Continue
-                    }
-                }
-            } else {
-                TreeNavResult::Exit
-            }
-        }
-
-        else if let Some(cmd) = cmd_repr.get_view::<dyn SingletonView<Item = ListCmd>>() {
+        if let Some(cmd) = cmd_repr.get_view::<dyn SingletonView<Item = ListCmd>>() {
 
             let cur = self.cursor.get();
             drop(cmd_repr);
@@ -69,10 +48,11 @@ impl ObjCommander for ListEditor {
                 _ => {
                     if let Some(idx) = cur.idx {
                         match cur.mode {
-                            ListCursorMode::Select => {                        
-                                if let Some(mut item) = self.get_item().clone() {
+                            ListCursorMode::Select => {
+                                if let Some(mut item) = self.get_cur_edittree() {
+                                    let mut item = item.write().unwrap();
                                     let item_cur = item.get_cursor();
-                                    
+
                                     match cmd.get() {
                                         ListCmd::DeletePxev => {
                                             if idx > 0
@@ -151,14 +131,30 @@ impl ObjCommander for ListEditor {
             }
 
         } else {
-            if let Some(cur_item) = self.get_item_mut() {
-                drop(cmd_repr);
-                cur_item.write().unwrap().send_cmd_obj(cmd_obj);
-                TreeNavResult::Continue
+            let cur = self.cursor.get();
+
+            if let Some(idx) = cur.idx {
+                match cur.mode {
+                    ListCursorMode::Select => {
+                        // what ??
+                        //*self.data.get_mut(idx as usize) = Arc::new(RwLock::new(node));
+
+
+
+                        TreeNavResult::Exit
+                    }
+                    ListCursorMode::Insert => {
+                        self.insert( cmd_obj.clone() );
+
+                        // todo: setup edittree
+
+                        self.cursor.set(ListCursor{ idx: Some(idx+1),  mode: ListCursorMode::Insert });
+                        TreeNavResult::Continue
+                    }
+                }
             } else {
                 TreeNavResult::Exit
             }
         }
     }
 }
-
diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs
index 0107124..fd9656b 100644
--- a/lib-nested-core/src/editors/list/ctx.rs
+++ b/lib-nested-core/src/editors/list/ctx.rs
@@ -1,23 +1,14 @@
 use {
-    r3vi::{
-        view::{
-            ViewPort, port::UpdateTask,
-            OuterViewPort, Observer,
-            singleton::*,
-            list::*
-        },
-        buffer::{singleton::*, vec::*}
-    },
-    laddertypes::{TypeTerm},
     crate::{
-        repr_tree::{Context, ReprTree, ReprLeaf, ReprTreeExt, GenericReprTreeMorphism},
-        edit_tree::{EditTree},
-        editors::{
-            char::{CharEditor},
-            list::{ListEditor}
+        edit_tree::EditTree, editors::{
+            char::CharEditor,
+            list::ListEditor
+        }, repr_tree::{context::TYPEID_char, Context, GenericReprTreeMorphism, ReprLeaf, ReprTree, ReprTreeArc, ReprTreeExt}
+    }, laddertypes::TypeTerm, r3vi::{
+        buffer::{singleton::*, vec::*}, view::{
+            list::*, port::UpdateTask, singleton::*, Observer, OuterViewPort, ViewPort
         }
-    },
-    std::sync::{Arc, RwLock}
+    }, std::sync::{Arc, RwLock}
 };
 
 //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
@@ -26,21 +17,21 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
     ctx.write().unwrap().add_varname("Item");
 
     let list_morph_editsetup1 = GenericReprTreeMorphism::new(
-        Context::parse(&ctx, "<List Item>~<List EditTree>~<Vec EditTree>"),
+        Context::parse(&ctx, "<List Item>~<List ReprTree>~<Vec ReprTree>"),
         Context::parse(&ctx, "<List Item>~EditTree"),
         {
             let ctx = ctx.clone();
             move |src_rt, σ| {
-                let item_id = laddertypes::TypeID::Var( ctx.read().unwrap().get_var_typeid("Item").unwrap() );
+                let item_id = laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Item").unwrap());
                 if let Some( item_type ) = σ.get( &item_id ) {
                     let mut item_vec_rt = src_rt
                         .descend(
-                            Context::parse(&ctx, "<List Item~EditTree>~<Vec EditTree>")
+                            Context::parse(&ctx, "<List ReprTree>~<Vec ReprTree>")
                                 .apply_substitution(&|id| σ.get(id).cloned()).clone()
                         )
                         .expect("cant descend src repr");
 
-                    let item_vec_buffer = item_vec_rt.vec_buffer::< Arc<RwLock<EditTree>> >();
+                    let item_vec_buffer = item_vec_rt.vec_buffer::< ReprTreeArc >();
 
                     let mut list_editor = ListEditor::with_data(ctx.clone(), item_type.clone(), item_vec_buffer);
                     let edittree_list = list_editor.into_node(
@@ -62,7 +53,7 @@ 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>"),
@@ -83,6 +74,46 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
             }
         }
     );
+*/
+
+    let list_morph_rt_to_char = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "<List Char> ~ <List ReprTree>"),
+        Context::parse(&ctx, "<List Char>"),
+        {
+            let ctx = ctx.clone();
+            move |src_rt, σ| {
+                src_rt.attach_leaf_to(
+                    Context::parse(&ctx, "<List Char>"),
+                    src_rt.descend(Context::parse(&ctx, "<List ReprTree>")).expect("cant descend")
+                        .view_list::<ReprTreeArc>()
+                        .map(|rt| {
+                            rt.view_singleton::<char>().get_view().get()
+                        })
+                );
+            }
+        }
+    );
+
+    let list_morph_rt_from_char = GenericReprTreeMorphism::new(
+            Context::parse(&ctx, "<List Char>"),
+            Context::parse(&ctx, "<List Char> ~ <List ReprTree>"),
+            {
+                let ctx = ctx.clone();
+                move |src_rt, σ| {
+                    src_rt.attach_leaf_to(
+                        Context::parse(&ctx, "<List Char>~<List ReprTree>"),
+                        src_rt.view_list::<char>()
+                            .map({|c| {
+                                ReprTree::from_singleton_buffer(
+                                    TypeTerm::TypeID(TYPEID_char),
+                                    SingletonBuffer::<char>::new( *c )
+                                )
+                            }})
+                    );
+                }
+            }
+        );
+
 
     let seq_morph_to_list_char = GenericReprTreeMorphism::new(
         Context::parse(&ctx, "<Seq Char>"),
@@ -154,6 +185,22 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
         }
     );
 
+    let list_morph_from_vec_rt = GenericReprTreeMorphism::new(
+        Context::parse(&ctx, "<List ReprTree>~<Vec ReprTree>"),
+        Context::parse(&ctx, "<List ReprTree>"),
+        {
+            let ctx = ctx.clone();
+            move |src_rt, σ| {
+                let src_port = src_rt.descend(Context::parse(&ctx, "<List ReprTree>~<Vec ReprTree>")).expect("descend")
+                    .get_port::<RwLock<Vec<ReprTreeArc>>>().unwrap();
+
+                src_rt.attach_leaf_to( Context::parse(&ctx, "<List ReprTree>"), src_port.to_list() );
+            }
+        }
+    );
+
+
+
 
     let list_morph_to_vec_edittree = GenericReprTreeMorphism::new(
         Context::parse(&ctx, "<List EditTree>"),
@@ -169,12 +216,13 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
     );
 
     ctx.write().unwrap().morphisms.add_morphism( list_morph_editsetup1 );
-    ctx.write().unwrap().morphisms.add_morphism( list_morph_editsetup3 );
+    ctx.write().unwrap().morphisms.add_morphism( list_morph_rt_to_char );
+    ctx.write().unwrap().morphisms.add_morphism( list_morph_rt_from_char );
     ctx.write().unwrap().morphisms.add_morphism( list_morph_from_vec_char );
+    ctx.write().unwrap().morphisms.add_morphism( list_morph_from_vec_rt );
     ctx.write().unwrap().morphisms.add_morphism( seq_morph_to_list_char );
     ctx.write().unwrap().morphisms.add_morphism( seq_morph_to_list_u64 );
     ctx.write().unwrap().morphisms.add_morphism( list_morph_to_vec_char );
     ctx.write().unwrap().morphisms.add_morphism( list_morph_to_vec_u64 );
     ctx.write().unwrap().morphisms.add_morphism( list_morph_to_vec_edittree );
 }
-
diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs
index 6773891..1afa517 100644
--- a/lib-nested-core/src/editors/list/editor.rs
+++ b/lib-nested-core/src/editors/list/editor.rs
@@ -1,14 +1,14 @@
 use {
-    r3vi::{
-        view::{OuterViewPort, singleton::*, sequence::*},
-        buffer::{singleton::*, vec::*},
-        projection::*
-    },
-    laddertypes::{TypeTerm},
     crate::{
-        repr_tree::{Context, ReprTree},
-        edit_tree::{EditTree, TreeNav, TreeCursor, diagnostics::Diagnostics},
-        editors::{list::{ListCursor, ListCursorMode, ListCmd}, ObjCommander},
+        edit_tree::{diagnostics::Diagnostics, EditTree, TreeCursor, TreeNav},
+        editors::{list::{ListCmd, ListCursor, ListCursorMode}, ObjCommander},
+        repr_tree::{ReprTreeBuilder, context::TYPEID_edittree, node::ReprTreeArc, Context, ReprTree, ReprTreeExt}
+    },
+    laddertypes::TypeTerm,
+    r3vi::{
+        buffer::{singleton::*, vec::*},
+        projection::*,
+        view::{list::*, sequence::*, singleton::*, OuterViewPort}
     },
     std::sync::{Arc, RwLock}
 };
@@ -17,17 +17,15 @@ 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 data: VecBuffer< ReprTreeArc >,
+    pub spillbuf: Arc<RwLock< Vec< ReprTreeArc > >>,
 
     pub(super) addr_port: OuterViewPort<dyn SequenceView<Item = isize>>,
     pub(super) mode_port: OuterViewPort<dyn SingletonView<Item = ListCursorMode>>,
 
     depth: OuterViewPort<dyn SingletonView<Item = usize>>,
 
+    pub item_builder: ReprTreeBuilder,
     pub ctx: Arc<RwLock<Context>>,
 
     /// item type
@@ -37,7 +35,7 @@ pub struct ListEditor {
 impl ListEditor {
     pub fn new(
        ctx: Arc<RwLock<Context>>,
-       typ: TypeTerm 
+       typ: TypeTerm
     ) -> Self {
         Self::with_data(
             ctx,
@@ -49,7 +47,7 @@ impl ListEditor {
     pub fn with_data(
         ctx: Arc<RwLock<Context>>,
         typ: TypeTerm,
-        data: VecBuffer<Arc<RwLock<EditTree>>>
+        data: VecBuffer< ReprTreeArc >
     ) -> Self {
         let cursor = SingletonBuffer::new(ListCursor::default());
 
@@ -58,6 +56,7 @@ impl ListEditor {
                 .get_port()
                 .map({
                     let data = data.clone();
+                    let ctx = ctx.clone();
                     move |c| {
                         let ip = SingletonBuffer::new(c.mode).get_port();
                         match c.mode {
@@ -65,7 +64,10 @@ impl ListEditor {
                             ListCursorMode::Select => {
                                 if let Some(idx) = c.idx {
                                     if idx >= 0 && idx < data.len() as isize {
-                                        data.get(idx as usize).read().unwrap().get_mode_view()
+                                        data.get(idx as usize)
+                                            .edittree(&ctx).get()
+                                            .read().unwrap()
+                                            .get_mode_view()
                                     } else {
                                         ip
                                     }
@@ -86,11 +88,15 @@ impl ListEditor {
                     cursor.get_port()
                         .map({
                             let data = data.clone();
+                            let ctx = ctx.clone();
                             move |cur| {
                                 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).read().unwrap().get_addr_view();
+                                            return data.get(idx as usize)
+                                                .edittree(&ctx).get()
+                                                .read().unwrap()
+                                                .get_addr_view();
                                         }
                                     }
                                 }
@@ -98,7 +104,7 @@ impl ListEditor {
                             }
                         })
                         .to_sequence()
-                        .flatten()                
+                        .flatten()
                 ])
                 .get_port()
                 .to_sequence()
@@ -106,8 +112,15 @@ impl ListEditor {
             cursor,
             data,
             spillbuf: Arc::new(RwLock::new(Vec::new())),
-            ctx,
+            item_builder: ReprTreeBuilder::new(ctx.clone())
+                .require( typ.clone() )
+                .require( TypeTerm::Ladder(vec![
+                    typ.clone(),
+                    TypeTerm::TypeID(TYPEID_edittree)
+                ]))
+                .clone(),
             typ,
+            ctx,
             depth: SingletonBuffer::new(0).get_port()
         }
     }
@@ -124,7 +137,7 @@ impl ListEditor {
             .set_editor(editor.clone())
             .set_nav(editor.clone())
             .set_cmd(editor.clone())
-            .set_diag(e.get_data_port()
+            .set_diag(e.get_edittree_seq()
                       .enumerate()
                       .map(|(idx, item_editor)| {
                           let idx = *idx;
@@ -141,11 +154,17 @@ impl ListEditor {
         node
     }
 
+    pub fn update_item_reprtrees(&self, master_repr: &TypeTerm) {
+        for i in 0..self.data.len() {
+            self.item_builder.update( &self.data.get(i), master_repr.clone() );
+        }
+    }
+
     pub fn get_item_type(&self) -> TypeTerm {
         self.typ.clone()
     }
 
-    pub fn get_seq_type(&self) -> TypeTerm {
+    pub fn get_list_type(&self) -> TypeTerm {
         TypeTerm::App(vec![
             TypeTerm::TypeID(self.ctx.read().unwrap().get_typeid("List").unwrap()),
             self.get_item_type().into()
@@ -156,10 +175,21 @@ impl ListEditor {
         self.cursor.get_port()
     }
 
-    pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = EditTree>> {
-        self.data.get_port().to_list().map(
-            |x| x.read().unwrap().clone()
-        ).to_sequence()
+    pub fn get_reprtree_list(&self) -> OuterViewPort<dyn ListView<ReprTreeArc>> {
+        self.data.get_port().to_list()
+    }
+
+    pub fn get_edittree_list(&self) -> OuterViewPort<dyn ListView<EditTree>> {
+        self.get_reprtree_list().map({
+            let ctx = self.ctx.clone();
+            move|rt| {
+                rt.edittree(&ctx).get().read().unwrap().clone()
+            }
+        })
+    }
+
+    pub fn get_edittree_seq(&self) -> OuterViewPort<dyn SequenceView<Item = EditTree>> {
+        self.get_edittree_list().to_sequence()
     }
 /*
     pub fn get_data(&self) -> Arc<RwLock<ReprTree>> {
@@ -170,11 +200,11 @@ impl ListEditor {
         )
     }
 */
-    pub fn get_item(&self) -> Option<EditTree> {
+    pub fn get_item(&self) -> Option< ReprTreeArc > {
         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).read().unwrap().clone())
+                Some( self.data.get(idx).clone() )
             } else {
                 None
             }
@@ -183,7 +213,7 @@ impl ListEditor {
         }
     }
 
-    pub fn get_item_mut(&mut self) -> Option<MutableVecAccess<Arc<RwLock<EditTree>>>> {
+    pub fn get_item_mut(&mut self) -> Option<MutableVecAccess< ReprTreeArc >> {
         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() {
@@ -196,6 +226,23 @@ impl ListEditor {
         }
     }
 
+    pub fn get_edittree(&self, idx: usize) -> Arc<RwLock<EditTree>> {
+        self.data.get(idx).edittree(&self.ctx).get()
+    }
+
+    pub fn get_cur_edittree(&self) -> Option< Arc<RwLock<EditTree>> > {
+        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.get_edittree(idx))
+            } else {
+                None
+            }
+        } else {
+            None
+        }
+    }
+
     /// is the element-type also a list-like editor (i.e. impls TreeNav)
     pub fn is_listlist(&self) -> bool {
         self.ctx.read().unwrap().is_list_type(&self.typ)
@@ -207,7 +254,7 @@ impl ListEditor {
         for i in 0..self.data.len() {
             b.push( self.data.get(i) );
         }
-        
+
         self.data.clear();
         self.cursor.set(ListCursor::home());
     }
@@ -234,8 +281,9 @@ impl ListEditor {
     }
 
     /// insert a new element
-    pub fn insert(&mut self, item: Arc<RwLock<EditTree>>) {
-        item.read().unwrap().disp.depth.0.set_view(
+    pub fn insert(&mut self, item: ReprTreeArc) {
+        let item_edit = item.edittree(&self.ctx).get();
+        item_edit.read().unwrap().disp.depth.0.set_view(
             self.depth.map(|d| d+1).get_view()
         );
 
@@ -247,13 +295,13 @@ impl ListEditor {
                     if self.is_listlist() {
                         cur.mode = ListCursorMode::Select;
                     } else {
-                        item.write().unwrap().goto(TreeCursor::none());
+                        item_edit.write().unwrap().goto(TreeCursor::none());
                         cur.idx = Some(idx + 1);
                     }
                 }
 
                 ListCursorMode::Select => {
-                    self.data.insert(1 + idx as usize, item.clone());                    
+                    self.data.insert(1 + idx as usize, item.clone());
                     if self.is_listlist() {
                         cur.idx = Some(idx + 1);
                     }
@@ -304,51 +352,41 @@ impl ListEditor {
         let cur = self.get_cursor();
 
         if let Some(mut item) = self.get_item().clone() {
-            item.send_cmd_obj(ListCmd::Split.into_repr_tree(&self.ctx));
+            let item_edit = item.edittree(&self.ctx).get();
+            let mut ie = item_edit.write().unwrap();
+            ie.send_cmd_obj(ListCmd::Split.into_repr_tree(&self.ctx));
 
             if cur.tree_addr.len() < 3 {
-                item.goto(TreeCursor::none());
+                ie.goto(TreeCursor::none());
 
                 self.set_leaf_mode(ListCursorMode::Insert);
                 self.nexd();
 
-                let mut b = item.ctrl.spillbuf.write().unwrap();
+                let mut b = ie.ctrl.spillbuf.write().unwrap();
 
                 let rt = ReprTree::new_arc(self.typ.clone());
                 let mut et = self.ctx.read().unwrap().setup_edittree(&rt);
 
                 if let Some(edittree) = et.as_mut(){
+                    let mut tail_node = edittree.get();
+                    let mut tail_node = tail_node.write().unwrap();
+                    tail_node.goto(TreeCursor::home());
 
-                let mut tail_node = edittree.get();
-                let mut tail_node = tail_node.write().unwrap();
-                tail_node.goto(TreeCursor::home());
+                    for n in b.iter() {
+                        tail_node.send_cmd_obj(n.clone());
+                    }
 
-                for node in b.iter() {
-                    tail_node
-                        .send_cmd_obj(
-                            ReprTree::from_singleton_buffer(
-                                Context::parse(&self.ctx, "EditTree"),
-                                SingletonBuffer::<EditTree>::new(
-                                    node.read().unwrap().clone()
-                                )
-                            )
-                        );
-                }
+                    b.clear();
+                    drop(b);
+                    drop(item);
 
-                b.clear();
-                drop(b);
-                drop(item);
-
-                tail_node.goto(TreeCursor::home());
-                if cur.tree_addr.len() > 1 {
-                    tail_node.dn();
-                }
-                drop(tail_node);
-
-                self.insert(
-                    edittree.value.read().unwrap().clone()
-                );
+                    tail_node.goto(TreeCursor::home());
+                    if cur.tree_addr.len() > 1 {
+                        tail_node.dn();
+                    }
+                    drop(tail_node);
 
+                    self.insert(rt);
                 }
 
             } else {
@@ -361,8 +399,8 @@ impl ListEditor {
 
     pub fn listlist_join_pxev(&mut self, idx: isize) {
         {
-            let cur_editor = self.data.get(idx as usize);
-            let pxv_editor = self.data.get(idx as usize-1);
+            let cur_editor = self.data.get(idx as usize).edittree(&self.ctx).get();
+            let pxv_editor = self.data.get(idx as usize-1).edittree(&self.ctx).get();
             let mut cur_editor = cur_editor.write().unwrap();
             let mut pxv_editor = pxv_editor.write().unwrap();
 
@@ -373,7 +411,7 @@ impl ListEditor {
             cur_editor.send_cmd_obj(
                 ListCmd::Clear.into_repr_tree( &self.ctx )
             );
-            
+
             pxv_editor.goto(TreeCursor {
                 tree_addr: vec![-1],
                 leaf_mode: ListCursorMode::Insert
@@ -383,14 +421,7 @@ impl ListEditor {
 
             let data = cur_editor.ctrl.spillbuf.read().unwrap();
             for x in data.iter() {
-                pxv_editor.send_cmd_obj(
-                    ReprTree::from_singleton_buffer(
-                        Context::parse(&self.ctx, "EditTree"),
-                        SingletonBuffer::<EditTree>::new(
-                            x.read().unwrap().clone()
-                        )
-                    )
-                );
+                pxv_editor.send_cmd_obj(x.clone());
             }
 
 
@@ -398,13 +429,13 @@ impl ListEditor {
             if oc0.tree_addr.len() > 1 {
                 pxv_editor.goto(TreeCursor {
                     tree_addr: vec![ old_cur.tree_addr[0], 0 ],
-                    leaf_mode: ListCursorMode::Insert                
+                    leaf_mode: ListCursorMode::Insert
                 });
                 pxv_editor.send_cmd_obj(ListCmd::DeletePxev.into_repr_tree( &self.ctx ));
             } else if oc0.tree_addr.len() > 0 {
                 pxv_editor.goto(TreeCursor {
                     tree_addr: vec![ old_cur.tree_addr[0] ],
-                    leaf_mode: ListCursorMode::Insert                
+                    leaf_mode: ListCursorMode::Insert
                 });
             }
         }
@@ -420,8 +451,8 @@ impl ListEditor {
 
     pub fn listlist_join_nexd(&mut self, idx: usize) {
         {
-            let cur_editor = self.data.get(idx);
-            let nxd_editor = self.data.get(idx + 1);
+            let cur_editor = self.data.get(idx).edittree(&self.ctx).get();
+            let nxd_editor = self.data.get(idx + 1).edittree(&self.ctx).get();
             let mut cur_editor = cur_editor.write().unwrap();
             let mut nxd_editor = nxd_editor.write().unwrap();
 
@@ -438,25 +469,18 @@ impl ListEditor {
                 tree_addr: vec![-1],
                 leaf_mode: ListCursorMode::Insert
             });
- 
+
             let data = nxd_editor.ctrl.spillbuf.read().unwrap();
 
             for x in data.iter() {
-                cur_editor.send_cmd_obj(
-                    ReprTree::from_singleton_buffer(
-                        Context::parse(&self.ctx, "EditTree"),
-                        SingletonBuffer::<EditTree>::new(
-                            x.read().unwrap().clone()
-                        )
-                    )
-                );
+                cur_editor.send_cmd_obj(x.clone());
             }
 
             // fixme: is it oc0 or old_cur ??
             if oc0.tree_addr.len() > 1 {
                 cur_editor.goto(TreeCursor {
                     tree_addr: vec![ old_cur.tree_addr[0], -1 ],
-                    leaf_mode: ListCursorMode::Insert                
+                    leaf_mode: ListCursorMode::Insert
                 });
                 cur_editor.send_cmd_obj(ListCmd::DeleteNexd.into_repr_tree( &self.ctx ));
             } else if oc0.tree_addr.len() > 0 {
@@ -485,7 +509,7 @@ impl TreeType for ListEditor {
         let idx = crate::utils::modulo::modulo(addr.0[0] as isize, self.data.len() as isize) as usize;
 
         let mut addr = addr.clone();
-        
+
         if self.data.len() > 0 {
             addr.0.remove(0);
             self.data.get(idx).get_type(addr)
@@ -495,5 +519,3 @@ impl TreeType for ListEditor {
     }
 }
  */
-
-
diff --git a/lib-nested-core/src/editors/list/nav.rs b/lib-nested-core/src/editors/list/nav.rs
index b92cc8f..bbef859 100644
--- a/lib-nested-core/src/editors/list/nav.rs
+++ b/lib-nested-core/src/editors/list/nav.rs
@@ -11,6 +11,7 @@ use {
             ListCursor, ListCursorMode,
             editor::ListEditor
         },
+        repr_tree::{ReprTreeExt},
         edit_tree::{TreeCursor, TreeNav, TreeNavResult, TreeHeightOp}
     },
     cgmath::Vector2
@@ -26,7 +27,7 @@ impl TreeNav for ListEditor {
     fn get_mode_view(&self) -> OuterViewPort<dyn SingletonView<Item = ListCursorMode>> {
         self.mode_port.clone()
     }
-    
+
     fn get_height(&self, op: &TreeHeightOp) -> usize {
         match op {
             TreeHeightOp::P | TreeHeightOp::Q => {
@@ -35,7 +36,10 @@ impl TreeNav for ListEditor {
                         TreeHeightOp::P => 0,
                         TreeHeightOp::Q => self.data.len() - 1,
                         _ => 0
-                    }).read().unwrap().get_height(op)
+                    })
+                    .edittree(&self.ctx).get()
+                    .read().unwrap()
+                    .get_height(op)
                 } else {
                     1
                 }
@@ -43,7 +47,9 @@ impl TreeNav for ListEditor {
             TreeHeightOp::Max => {
                 1 + (0..self.data.len() as usize)
                     .map(|i| self.data
-                         .get(i).read().unwrap()
+                         .get(i)
+                         .edittree(&self.ctx).get()
+                         .read().unwrap()
                          .get_height(&TreeHeightOp::Max)
                     )
                     .max()
@@ -68,7 +74,9 @@ 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).read().unwrap().get_cursor_warp();
+                        let mut sub_cur = self.get_edittree(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 {
@@ -100,11 +108,11 @@ 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).read().unwrap().get_cursor();
+                        let mut sub_cur = self.get_edittree(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;
-                        } else {                            
+                        } else {
                             return TreeCursor {
                                 leaf_mode: ListCursorMode::Select,
                                 tree_addr: vec![ i ],
@@ -124,7 +132,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).write().unwrap().goto(TreeCursor::none());
+                self.get_edittree(i as usize).write().unwrap().goto(TreeCursor::none());
             }
         }
 
@@ -145,8 +153,7 @@ impl TreeNav for ListEditor {
                 });
 
                 if new_cur.leaf_mode == ListCursorMode::Select && self.data.len() > 0 {
-                    self.data
-                        .get_mut(idx as usize)
+                    self.get_edittree(idx as usize)
                         .write().unwrap()
                         .goto(TreeCursor {
                             leaf_mode: ListCursorMode::Select,
@@ -165,8 +172,7 @@ impl TreeNav for ListEditor {
                         idx: Some(idx),
                     });
 
-                    self.data
-                        .get_mut(idx as usize)
+                    self.get_edittree(idx as usize)
                         .write().unwrap()
                         .goto(TreeCursor {
                             leaf_mode: new_cur.leaf_mode,
@@ -176,7 +182,7 @@ impl TreeNav for ListEditor {
                     self.cursor.set(ListCursor::home());
                 }
 
-                TreeNavResult::Continue                
+                TreeNavResult::Continue
             }
         }
     }
@@ -212,8 +218,7 @@ impl TreeNav for ListEditor {
                     // dn
 
                     if cur.tree_addr[0] < self.data.len() as isize {
-                        if self.data
-                            .get_mut(cur.tree_addr[0] as usize)
+                        if self.get_edittree(cur.tree_addr[0] as usize)
                             .write().unwrap()
                             .goby(Vector2::new(direction.x, direction.y))
                             == TreeNavResult::Continue {
@@ -247,11 +252,10 @@ impl TreeNav for ListEditor {
 
                         match cur.leaf_mode {
                             ListCursorMode::Select => {
-                                let cur_item = self.data.get(cur.tree_addr[0] as usize);
+                                let cur_item = self.get_edittree(cur.tree_addr[0] as usize);
                                 let cur_height = cur_item.read().unwrap().get_height(&TreeHeightOp::Max);
 
-                                let new_item = self.data
-                                    .get_mut(idx as usize);
+                                let new_item = self.get_edittree(idx as usize);
 
                                 let height = new_item.read().unwrap().get_height(
                                     if direction.x < 0 {
@@ -277,28 +281,28 @@ impl TreeNav for ListEditor {
                                 if direction.x > 0
                                 {
                                     if (cur.tree_addr[0] as usize) < self.data.len() {
-                                        let cur_item = self.data.get(cur.tree_addr[0] as usize);
+                                        let cur_item = self.get_edittree(cur.tree_addr[0] as usize);
                                         let cur_height = cur_item.read().unwrap().get_height(&TreeHeightOp::P);
 
                                         if gravity && cur_height > 1 {
                                             new_addr.push( cur.tree_addr[0] );
                                             new_addr.push(0);
                                         } else {
-                                            new_addr.push( idx );           
+                                            new_addr.push( idx );
                                         }
                                     }
                                 } else {
                                     if (idx as usize) < self.data.len() {
-                                        let pxv_item = self.data.get(idx as usize);
+                                        let pxv_item = self.get_edittree(idx as usize);
                                         let pxv_height = pxv_item.read().unwrap().get_height(&TreeHeightOp::P);
 
                                         if gravity && pxv_height > 1 {
                                             new_addr.push( idx );
                                             new_addr.push( -1 );
                                         } else {
-                                            new_addr.push( idx );           
+                                            new_addr.push( idx );
                                         }
-                                    }                                    
+                                    }
                                 }
                             }
                         }
@@ -324,10 +328,7 @@ impl TreeNav for ListEditor {
                 // nested
 
                 if cur.tree_addr[0] < self.data.len() as isize {
-
-                    let cur_item = self.data
-                        .get_mut(cur.tree_addr[0] as usize);
-
+                    let cur_item = self.get_edittree(cur.tree_addr[0] as usize);
                     let result = cur_item.write().unwrap().goby(direction);
 
                     match result
@@ -353,8 +354,7 @@ impl TreeNav for ListEditor {
                                     let mut new_addr = Vec::new();
 
                                     if direction.x < 0 {
-                                        let pxv_item = self.data
-                                            .get_mut(cur.tree_addr[0] as usize - 1);
+                                        let pxv_item = self.get_edittree(cur.tree_addr[0] as usize - 1);
 
                                         let pxv_height = pxv_item.read().unwrap().get_height(&TreeHeightOp::Q) as isize;
                                         let cur_height = cur_item.read().unwrap().get_height(&TreeHeightOp::P) as isize;
@@ -370,10 +370,9 @@ impl TreeNav for ListEditor {
                                         for _i in 0..n_steps_down {
                                             new_addr.push( -1 );
                                         }
-                                        
+
                                     } else {
-                                        let nxd_item = self.data
-                                            .get_mut(cur.tree_addr[0] as usize + 1);
+                                        let nxd_item = self.get_edittree(cur.tree_addr[0] as usize + 1);
 
                                         let cur_height = cur_item.read().unwrap().get_height(&TreeHeightOp::Q) as isize;
                                         let nxd_height = nxd_item.read().unwrap().get_height(&TreeHeightOp::P) as isize;
@@ -422,4 +421,3 @@ impl TreeNav for ListEditor {
         }
     }
 }
-
diff --git a/lib-nested-core/src/repr_tree/builder.rs b/lib-nested-core/src/repr_tree/builder.rs
new file mode 100644
index 0000000..af76b31
--- /dev/null
+++ b/lib-nested-core/src/repr_tree/builder.rs
@@ -0,0 +1,108 @@
+use {
+    r3vi::{
+        view::{
+            ViewPort, OuterViewPort,
+            AnyViewPort, AnyInnerViewPort, AnyOuterViewPort,
+            port::UpdateTask,
+            View, Observer,
+            singleton::*,
+            sequence::*,
+            list::*
+        },
+        buffer::{singleton::*, vec::*}
+    },
+    laddertypes::{TypeTerm, TypeID},
+    std::{
+        collections::HashMap,
+        sync::{Arc, RwLock},
+        any::Any
+    },
+    super::{Context, ReprLeaf, ReprTree, ReprTreeExt, context::{TYPEID_list, TYPEID_vec, TYPEID_char, TYPEID_u64, TYPEID_edittree}}
+};
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+#[derive(Clone)]
+pub struct ReprTreeBuilder {
+    ctx: Arc<RwLock<Context>>,
+    pub required_leaves: Vec<TypeTerm>,
+}
+
+#[derive(Debug)]
+pub enum ReprTreeError {
+    MissingMorphism
+}
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+impl ReprTreeBuilder {
+    pub fn new(ctx: Arc<RwLock<Context>>) -> Self {
+        ReprTreeBuilder {
+            ctx,
+            required_leaves: Vec::new()
+        }
+    }
+
+    /// Add a type to the set of required representations.
+    pub fn require(mut self, t: TypeTerm) -> Self {
+        self.required_leaves.push(t);
+        self
+    }
+
+    /// (re)build steiner tree with `required_leaves`,
+    /// and apply it to the projections in the ReprTree.
+    /// Updating and keeping existing nodes, while
+    /// adding new ones if required.
+    pub fn update(
+        &self,
+        rt: &Arc<RwLock<ReprTree>>,
+        master_leaf_type: impl Into<TypeTerm>
+    ) -> Result< Arc<RwLock<ReprTree>>, ReprTreeError > {
+        rt.write().unwrap().detach( &self.ctx );
+
+        let morphism_base = &self.ctx.read().unwrap().morphisms;
+
+        let mt = master_leaf_type.into();
+        let mut leaves = self.required_leaves.clone();
+        leaves.retain(|t| t != &mt);
+
+        let mut st_problem = laddertypes::steiner_tree::PathApproxSteinerTreeSolver::new(
+            mt,
+            leaves
+        );
+
+        if let Some( steiner_tree ) = st_problem.solve( &morphism_base ) {
+            for morphism_type in steiner_tree.into_edges() {
+                eprintln!("--> morph {} to {}",
+                    self.ctx.read().unwrap().type_term_to_str(&morphism_type.src_type),
+                    self.ctx.read().unwrap().type_term_to_str(&morphism_type.dst_type));
+
+                if let Some(( morphism, mut τ, σ )) =
+                    morphism_base.find_morphism_with_subtyping( &morphism_type )
+                {
+                    let mut rt = rt.descend_create( τ ).expect("descend src repr");
+                    (morphism.setup_projection)( &mut rt, &σ );
+                } else {
+                    eprintln!("failed to get morphism");
+                    //return Err(ReprTreeError::MissingMorphism);
+                }
+            }
+
+            Ok( rt.clone() )
+        } else {
+            eprintln!("could not find steiner tree to build the requested repr tree");
+            Err(ReprTreeError::MissingMorphism)
+        }
+    }
+
+    /// Build fresh ReprTree from a master representation.
+    pub fn build_from(
+        &self,
+        mut master_rt: Arc<RwLock<ReprTree>>
+    ) -> Result< Arc<RwLock<ReprTree>>, ReprTreeError > {
+        let master_leaf_type = master_rt.get_full_type();
+        self.update( &ReprTree::rise( master_rt ), master_leaf_type )
+    }
+}
+
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs
index 37f16ae..4ff1f75 100644
--- a/lib-nested-core/src/repr_tree/context.rs
+++ b/lib-nested-core/src/repr_tree/context.rs
@@ -123,41 +123,9 @@ impl Context {
             }
         } else {
             eprintln!("no path found");
-        }    
-    }
-
-    pub fn build_repr_tree(
-        &self,
-        rt: &Arc<RwLock<ReprTree>>,
-        root: TypeTerm,
-        leaves: Vec< TypeTerm >
-    ) {
-        let mut st_problem = laddertypes::steiner_tree::PathApproxSteinerTreeSolver::new(
-            root,
-            leaves
-        );
-
-        if let Some( steiner_tree ) = st_problem.solve( &self.morphisms ) {
-            for morphism_type in steiner_tree.into_edges() {
-                eprintln!("--> apply morph to {}", self.type_term_to_str(&morphism_type.dst_type));
-                if let Some(( morphism, mut τ, σ )) =
-                    self.morphisms.find_morphism_with_subtyping( &morphism_type )
-                {
-                    let mut rt = rt.descend( τ ).expect("descend src repr");
-                    (morphism.setup_projection)( &mut rt, &σ );
-                }
-            }
-        } else {
-            eprintln!("could not find steiner tree to build the requested repr tree");
         }
     }
 
-    pub fn make_repr(ctx: &Arc<RwLock<Self>>, t: &TypeTerm) -> ReprTreeArc {
-        let rt = Arc::new(RwLock::new(ReprTree::new( TypeTerm::unit() )));
-        ctx.read().unwrap().apply_morphism( &rt, &MorphismType{ src_type: TypeTerm::unit(), dst_type: t.clone() } );
-        rt
-    }
-
     pub fn parse(ctx: &Arc<RwLock<Self>>, s: &str) -> TypeTerm {
         ctx.read().unwrap().type_term_from_str(s).expect("could not parse type term")
     }
@@ -277,4 +245,3 @@ impl Context {
 }
 
 //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
-
diff --git a/lib-nested-core/src/repr_tree/leaf.rs b/lib-nested-core/src/repr_tree/leaf.rs
index 6a12440..a23e65e 100644
--- a/lib-nested-core/src/repr_tree/leaf.rs
+++ b/lib-nested-core/src/repr_tree/leaf.rs
@@ -50,13 +50,13 @@ impl ReprLeaf {
             in_keepalive: Some(in_keepalive),
             in_port: in_port.inner().into(),
             out_port: out_port.into(),
-            data: None, 
+            data: None,
         }
     }
 
     pub fn detach<V>(&mut self)
     where V: View + ?Sized + 'static,
-         V::Msg: Clone
+        V::Msg: Clone
     {
         self.keepalive = None;
         self.in_keepalive = None;
@@ -213,4 +213,3 @@ impl ReprLeaf {
 }
 
 //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
-
diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs
index e77774f..d4a3b52 100644
--- a/lib-nested-core/src/repr_tree/mod.rs
+++ b/lib-nested-core/src/repr_tree/mod.rs
@@ -1,5 +1,6 @@
 pub mod node;
 pub mod leaf;
+pub mod builder;
 pub mod context;
 pub mod morphism;
 
@@ -10,6 +11,7 @@ pub use {
     context::{Context},
     leaf::ReprLeaf,
     node::{ReprTree, ReprTreeArc},
+    builder::{ReprTreeBuilder, ReprTreeError},
     morphism::{GenericReprTreeMorphism}
 };
 
@@ -34,15 +36,15 @@ use {
     },
 };
 
-//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
-
 pub trait ReprTreeExt {
     fn get_type(&self) -> TypeTerm;
+    fn get_full_type(&self) -> TypeTerm;
 
     fn insert_leaf(&mut self, type_ladder: impl Into<TypeTerm>, leaf: ReprLeaf);
     fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>);
     fn create_branch(&mut self, rung: impl Into<TypeTerm>);
     fn descend(&self, target_type: impl Into<TypeTerm>) -> Option< ReprTreeArc >;
+    fn descend_create(&self, target_type: impl Into<TypeTerm>) -> Option< ReprTreeArc >;
 
     fn attach_leaf_to<V: View + ?Sized + 'static>(&self, t: impl Into<TypeTerm>, v: OuterViewPort<V>) where V::Msg: Clone;
     fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>> where V::Msg: Clone;
@@ -60,7 +62,8 @@ pub trait ReprTreeExt {
     fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> VecBuffer<T>;
 
     fn edittree(&self, ctx: &Arc<RwLock<Context>>) -> SingletonBuffer< Arc<RwLock<crate::edit_tree::EditTree>> > {
-        self.descend(Context::parse(&ctx, "EditTree")).unwrap()
+        self.descend_create(Context::parse(&ctx, "EditTree"))
+            .expect("failed to get EditTree")
             .singleton_buffer()
     }
 }
@@ -70,6 +73,10 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> {
         self.read().unwrap().get_type().clone()
     }
 
+    fn get_full_type(&self) -> TypeTerm {
+        self.read().unwrap().get_full_type().clone()
+    }
+
     fn insert_leaf(&mut self, type_ladder: impl Into<TypeTerm>, leaf: ReprLeaf) {
         self.write().unwrap().insert_leaf(type_ladder.into().get_lnf_vec().into_iter(), leaf)
     }
@@ -78,8 +85,8 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> {
         self.write().unwrap().insert_branch(repr)
     }
 
-    fn create_branch(&mut self, rung: impl Into<TypeTerm>) {
-        let mut lnf = rung.into().get_lnf_vec().into_iter();
+    fn create_branch(&mut self, branch: impl Into<TypeTerm>) {
+        let mut lnf = branch.into().get_lnf_vec().into_iter();
         if let Some(rung) = lnf.next() {
             let mut parent = ReprTree::new_arc( rung );
             self.insert_branch( parent.clone() );
@@ -104,6 +111,10 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> {
         ReprTree::descend( self, target_type )
     }
 
+    fn descend_create(&self, target_type: impl Into<TypeTerm>)-> Option< ReprTreeArc > {
+        ReprTree::descend_create( self, target_type )
+    }
+
     fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>> {
         self.read().unwrap().view_char()
     }
@@ -142,4 +153,3 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> {
 }
 
 //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
-
diff --git a/lib-nested-core/src/repr_tree/morphism.rs b/lib-nested-core/src/repr_tree/morphism.rs
index fe59b6f..c5e5e8a 100644
--- a/lib-nested-core/src/repr_tree/morphism.rs
+++ b/lib-nested-core/src/repr_tree/morphism.rs
@@ -80,29 +80,44 @@ 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;
                             }
@@ -112,13 +127,14 @@ impl GenericReprTreeMorphism {
                                 .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> >
+                    );
+                }
             })
         }
     }
@@ -192,16 +208,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 bef682b..c0b34c5 100644
--- a/lib-nested-core/src/repr_tree/node.rs
+++ b/lib-nested-core/src/repr_tree/node.rs
@@ -1,5 +1,3 @@
-
-
 use {
     r3vi::{
         view::{
@@ -11,7 +9,7 @@ use {
             sequence::*,
             list::*
         },
-        buffer::{singleton::*, vec::*}
+        buffer::{singleton::*, vec::*},
     },
     laddertypes::{TypeTerm, TypeID},
     std::{
@@ -19,7 +17,12 @@ use {
         sync::{Arc, RwLock},
         any::Any
     },
-    super::{Context, ReprLeaf, ReprTreeExt, context::{TYPEID_list, TYPEID_vec, TYPEID_char, TYPEID_u64, TYPEID_edittree}}
+    super::{
+        Context,
+        ReprLeaf,
+        ReprTreeExt,
+        context::{TYPEID_list, TYPEID_vec, TYPEID_char, TYPEID_u64, TYPEID_edittree}
+    }
 };
 
 //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
@@ -29,28 +32,13 @@ pub struct ReprTree {
     halo: TypeTerm,
     type_tag: TypeTerm,
     branches: HashMap<TypeTerm, ReprTreeArc>,
-    leaf: Option< ReprLeaf >
+    leaf: Option< ReprLeaf >,
 }
 
 pub type ReprTreeArc = Arc<RwLock<ReprTree>>;
 
 //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
 
-impl std::fmt::Debug for ReprTree {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        writeln!(f, "| type: {:?}", self.type_tag)?;
-
-        for (_k,x) in self.branches.iter() {
-            writeln!(f, "|--> child: {:?}", x)?;
-        }
-        writeln!(f, "");
-
-        Ok(())
-    }
-}
-
-//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
-
 impl ReprTree {
     pub fn new(typ: impl Into<TypeTerm>) -> Self {
         let mut lnf = typ.into().get_lnf_vec();
@@ -69,10 +57,33 @@ impl ReprTree {
         }
     }
 
+    pub fn fmt(&self, ctx: &Arc<RwLock<Context>>, depth: u32) -> String {
+        let mut s = String::new();
+        if( depth == 0 ) {
+            s.push_str(&format!("{}", ctx.read().unwrap().type_term_to_str(self.get_halo_type())))
+        }
+        s.push_str(&format!("+ {}\n", ctx.read().unwrap().type_term_to_str(&self.type_tag)));
+
+        for (_k,x) in self.branches.iter() {
+            for _ in 0..depth {
+                s.push_str("   ");
+            }
+            s.push_str(&format!("|--{}", x.read().unwrap().fmt(ctx, depth+1)));
+        }
+        s
+    }
+
     pub fn new_arc(type_tag: impl Into<TypeTerm>) -> ReprTreeArc {
         Arc::new(RwLock::new(Self::new(type_tag)))
     }
 
+    pub fn get_full_type(&self) -> TypeTerm {
+        TypeTerm::Ladder(vec![
+            self.halo.clone(),
+            self.type_tag.clone()
+        ]).normalize()
+    }
+
     pub fn get_type(&self) -> &TypeTerm {
         &self.type_tag
     }
@@ -128,7 +139,10 @@ impl ReprTree {
         )
     }
 
-    pub fn from_view<V>( type_tag: impl Into<TypeTerm>, view: OuterViewPort<V> ) -> ReprTreeArc
+    pub fn from_view<V>(
+        type_tag: impl Into<TypeTerm>,
+        view: OuterViewPort<V>
+    ) -> ReprTreeArc
     where V: View + ?Sized + 'static,
         V::Msg: Clone
     {
@@ -137,7 +151,10 @@ impl ReprTree {
         Arc::new(RwLock::new(rt))
     }
 
-    pub fn from_singleton_buffer<T>( type_tag: impl Into<TypeTerm>, buf: SingletonBuffer<T> ) -> ReprTreeArc
+    pub fn from_singleton_buffer<T>(
+        type_tag: impl Into<TypeTerm>,
+        buf: SingletonBuffer<T>
+    ) -> ReprTreeArc
     where T: Clone + Send + Sync + 'static
     {
         let mut rt = ReprTree::new(type_tag);
@@ -145,23 +162,20 @@ impl ReprTree {
         Arc::new(RwLock::new(rt))
     }
 
-    pub fn from_str(
-        type_tag: impl Into<TypeTerm>,
-        val: &str
-    ) -> ReprTreeArc {
-        let mut lnf = type_tag.into().get_lnf_vec();
-
-        let mut rt = ReprTree::from_vec_buffer(
-            lnf.pop().unwrap(),
+    pub fn from_str(val: &str) -> ReprTreeArc {
+        ReprTree::from_vec_buffer(
+            TypeTerm::App(vec![ TypeTerm::TypeID(TYPEID_vec), TypeTerm::TypeID(TYPEID_char) ]),
             VecBuffer::with_data( val.chars().collect() )
-        );
+        )
+    }
 
+    pub fn rise( mut rt: Arc<RwLock<ReprTree>> ) -> Arc<RwLock<ReprTree>> {
+        let mut lnf = rt.read().unwrap().get_halo_type().clone().get_lnf_vec();
         while let Some(t) = lnf.pop() {
             let mut new_rt = ReprTree::new_arc(t);
             new_rt.insert_branch(rt);
-            rt = new_rt;
+            rt = new_rt
         }
-
         rt
     }
 
@@ -198,7 +212,7 @@ impl ReprTree {
         V::Msg: Clone
     {
         while let Some(rung_type) = type_ladder.next() {
-            if &rung_type != self.get_type() { 
+            if &rung_type != self.get_type() {
                 if let Some(next_repr) = self.branches.get(&rung_type) {
                     next_repr.write().unwrap().attach_leaf_to(type_ladder, src_port);
                 } else {
@@ -225,7 +239,7 @@ impl ReprTree {
 
                 leaf.attach_to(src_port);
                 self.leaf = Some(leaf);
-            }           
+            }
             else if self.type_tag == TypeTerm::App(vec![
                 TypeTerm::TypeID(TYPEID_vec),
                 TypeTerm::TypeID(TYPEID_char)
@@ -342,7 +356,7 @@ impl ReprTree {
 
     //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
 
-    pub fn descend_one(&self, dst_type: impl Into<TypeTerm>) -> Option< ReprTreeArc > {
+    pub fn descend_rung(&self, dst_type: impl Into<TypeTerm>) -> Option< ReprTreeArc > {
         let dst_type = dst_type.into();
         assert!( dst_type.is_flat() );
         self.branches.get(&dst_type).cloned()
@@ -352,7 +366,7 @@ impl ReprTree {
         if let Some(first) = repr_ladder.next() {
             let rt = rt.read().unwrap();
             repr_ladder.fold(
-                rt.descend_one(first),
+                rt.descend_rung(first),
                 |s, t| s?.descend(t))
         } else {
             Some(rt.clone())
@@ -371,25 +385,36 @@ impl ReprTree {
         }
     }
 
-    pub fn ascend(rt: &Arc<RwLock<Self>>, type_term: impl Into<TypeTerm>) -> Arc<RwLock<ReprTree>> {
+    pub fn descend_create(
+        rt: &Arc<RwLock<Self>>,
+        dst_type: impl Into<TypeTerm>
+    ) -> Option< ReprTreeArc > {
+        let dst_type = dst_type.into();
+        if let Some(branch) = ReprTree::descend(rt, dst_type.clone()) {
+            Some(branch)
+        } else {
+            let branch = ReprTree::new_arc(dst_type);
+            rt.write().unwrap().insert_branch(branch.clone());
+            Some(branch)
+        }
+    }
+
+    pub fn ascend(rt: &Arc<RwLock<Self>>, type_term: impl Into<TypeTerm>) -> ReprTreeArc {
         let mut n = Self::new(type_term);
         n.insert_branch(rt.clone());
         Arc::new(RwLock::new(n))
     }
 
-    //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+
+    //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
+    //               Buffer Access               \\
+    //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
 
     pub fn singleton_buffer<T: Clone + Send + Sync + 'static>(&mut self) -> Option<SingletonBuffer<T>> {
         if let Some(leaf) = self.leaf.as_mut() {
             leaf.as_singleton_buffer::<T>()
         } else {
-            // create new singleton buffer
-            /*
-            // default value??
-            let buf = SingletonBuffer::<T>::default();
-            self.leaf = Some(ReprLeaf::from_singleton_buffer(buf.clone()));
-            Some(buf)
-            */
             None
         }
     }
@@ -402,7 +427,10 @@ impl ReprTree {
         }
     }
 
-    //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+    //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
+    //                 View Access               \\
+    //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
 
     pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>>
     where
@@ -455,5 +483,3 @@ impl ReprTree {
 }
 
 //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
-
-
diff --git a/lib-nested-tty/src/editors/list.rs b/lib-nested-tty/src/editors/list.rs
index e55172c..cee4284 100644
--- a/lib-nested-tty/src/editors/list.rs
+++ b/lib-nested-tty/src/editors/list.rs
@@ -43,7 +43,7 @@ impl DisplaySegment for ListSegment {
                         } else {
                             usize::MAX
                         };
-                    
+
                     atom
                         .add_style_back(bg_style_from_depth(select))
                         .add_style_back(TerminalStyle::bold(select==1))
@@ -70,7 +70,7 @@ impl PTYListStyle {
     pub fn get_seg_seq_view(&self, editor: &ListEditor) -> OuterViewPort<dyn SequenceView<Item = OuterViewPort<dyn TerminalView>>> {
         let seg_seq = ListSegmentSequence::new(
             editor.get_cursor_port(),
-            editor.get_data_port()
+            editor.get_edittree_seq()
         );
         let se = seg_seq.read().unwrap();
         se.get_view().map(move |segment| segment.display_view())
@@ -79,7 +79,7 @@ impl PTYListStyle {
     pub fn pty_view(&self, editor: &ListEditor) -> OuterViewPort<dyn TerminalView> {
         let seg_seq = ListSegmentSequence::new(
             editor.get_cursor_port(),
-            editor.get_data_port()
+            editor.get_edittree_seq()
         );
 
         let seg_seq0 = seg_seq.read().unwrap();
@@ -133,7 +133,7 @@ impl PTYListController {
             split_char,
             close_char,
             depth
-        } 
+        }
     }
 
     pub fn for_node(
@@ -162,17 +162,17 @@ impl PTYListController {
     }
 
     pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = EditTree>> {
-        self.editor.read().unwrap().get_data_port()
+        self.editor.read().unwrap().get_edittree_seq()
     }
 
     pub fn clear(&mut self) {
         self.editor.write().unwrap().clear();
     }
-
+/*
     pub fn get_item(&self) -> Option<EditTree> {
         self.editor.read().unwrap().get_item()
     }
-
+*/
     pub fn handle_term_event(&mut self, event: &TerminalEvent, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
         let mut e = self.editor.write().unwrap();
         match event {
@@ -247,7 +247,7 @@ impl PTYListController {
                     match ne.send_cmd_obj(cmd_obj.clone()) {
                         TreeNavResult::Continue => {
                             drop(ne);
-                            e.insert(new_edittree.value.read().unwrap().clone());
+                            e.insert(rt);
                             TreeNavResult::Continue
                         }
                         TreeNavResult::Exit => {
@@ -260,7 +260,7 @@ impl PTYListController {
                 }
             },
             ListCursorMode::Select => {
-                if let Some(item) = e.get_item_mut() {
+                if let Some(item) = e.get_cur_edittree() {
                     let res = item.write().unwrap().send_cmd_obj(cmd_obj.clone());
                     let child_close_char = item.read().unwrap().ctrl.close_char.get();
 
diff --git a/lib-nested-tty/src/lib.rs b/lib-nested-tty/src/lib.rs
index 0e12095..022e8f9 100644
--- a/lib-nested-tty/src/lib.rs
+++ b/lib-nested-tty/src/lib.rs
@@ -127,9 +127,10 @@ pub fn setup_edittree_hook(ctx: &Arc<RwLock<Context>>) {
     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(',');
-    ctx.write().unwrap().meta_chars.push('\"');
-    ctx.write().unwrap().meta_chars.push('}');
+    ctx.write().unwrap().meta_chars.push('\n');
+    //ctx.write().unwrap().meta_chars.push(',');
+    //ctx.write().unwrap().meta_chars.push('\"');
+    //ctx.write().unwrap().meta_chars.push('}');
 
     // Define a hook which is executed when a new editTree of type `t` is created.
     // this will setup the display and navigation elements of the editor.