From 883cd01f990ef125064c5a855c83b16dc4372984 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Mon, 19 Dec 2022 11:26:07 +0100
Subject: [PATCH] wip

---
 nested/src/char_editor.rs      |  10 +-
 nested/src/core/context.rs     |  20 ++-
 nested/src/core/type_term.rs   |   6 +-
 nested/src/index/buffer.rs     |   2 +-
 nested/src/integer/editor.rs   | 196 ++++++++++---------------
 nested/src/lib.rs              |   6 +-
 nested/src/list/editor.rs      |  62 ++++----
 nested/src/list/nav.rs         |  78 +++++-----
 nested/src/list/pty_editor.rs  | 252 ++++++++++++---------------------
 nested/src/list/segment.rs     |  57 ++++----
 nested/src/make_editor.rs      |  80 ++++++-----
 nested/src/product/editor.rs   |  24 ++--
 nested/src/product/nav.rs      |  24 ++--
 nested/src/product/segment.rs  |   9 +-
 nested/src/sum/editor.rs       |  62 ++++----
 nested/src/tree/node.rs        |  32 +++--
 nested/src/type_term_editor.rs | 116 ++++++---------
 nested/src/vec/buffer.rs       |   2 +-
 shell/src/main.rs              |  60 ++++----
 19 files changed, 489 insertions(+), 609 deletions(-)

diff --git a/nested/src/char_editor.rs b/nested/src/char_editor.rs
index f160586..89a92e9 100644
--- a/nested/src/char_editor.rs
+++ b/nested/src/char_editor.rs
@@ -2,11 +2,7 @@ use {
     crate::{
         core::{OuterViewPort, Context},
         singleton::{SingletonBuffer, SingletonView},
-        terminal::{
-            TerminalAtom,
-            TerminalEvent,
-            TerminalStyle
-        },
+        terminal::{TerminalAtom, TerminalEvent, TerminalStyle},
         tree::NestedNode, Commander
     },
     std::sync::Arc,
@@ -26,10 +22,12 @@ impl Commander for CharEditor {
             TerminalEvent::Input(Event::Key(Key::Char(c))) => {
                 self.data.set(Some(*c));
             }
+
             TerminalEvent::Input(Event::Key(Key::Backspace))
             | TerminalEvent::Input(Event::Key(Key::Delete)) => {
                 self.data.set(None);
             }
+
             _ => {}
         }
     }
@@ -65,7 +63,7 @@ impl CharEditor {
                       })
                       .to_grid()
             )
-            .with_cmd(
+            .set_cmd(
                 Arc::new(RwLock::new(CharEditor{ data }))
             )
     }
diff --git a/nested/src/core/context.rs b/nested/src/core/context.rs
index 522c24f..3d463e8 100644
--- a/nested/src/core/context.rs
+++ b/nested/src/core/context.rs
@@ -4,7 +4,7 @@ use {
             type_term::{TypeDict, TypeTerm, TypeID},
             AnyOuterViewPort, OuterViewPort, View,
         },
-        Nested
+        tree::NestedNode
     },
     std::{
         collections::HashMap,
@@ -248,7 +248,7 @@ pub struct Context {
     objects: HashMap<String, Arc<RwLock<ReprTree>>>,
 
     /// editors
-    editor_ctors: HashMap<TypeID, Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> + Send + Sync>>,
+    editor_ctors: HashMap<TypeID, Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<NestedNode> + Send + Sync>>,
 
     /// morphisms
     default_constructors: HashMap<TypeTerm, Box<dyn Fn() -> Arc<RwLock<ReprTree>> + Send + Sync>>,
@@ -281,6 +281,10 @@ impl Context {
         self.type_dict.write().unwrap().add_typename(tn);
     }
 
+    pub fn get_typeid(&self, tn: &str) -> Option<TypeID> {
+        self.type_dict.read().unwrap().get_typeid(&tn.into())
+    }
+
     pub fn type_term_from_str(&self, tn: &str) -> Option<TypeTerm> {
         self.type_dict.read().unwrap().type_term_from_str(&tn)
     }
@@ -289,13 +293,15 @@ impl Context {
         self.type_dict.read().unwrap().type_term_to_str(&t)
     }
 
-    pub fn add_editor_ctor(&mut self, tn: &str, mk_editor: Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> + Send + Sync>) {
+    pub fn add_editor_ctor(&mut self, tn: &str, mk_editor: Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<NestedNode> + Send + Sync>) {
         let mut dict = self.type_dict.write().unwrap();
-        let tyid = dict.get_typeid(&tn.into()).unwrap_or( dict.add_typename(tn.into()) );
+        let tyid = dict
+            .get_typeid(&tn.into())
+            .unwrap_or( dict.add_typename(tn.into()) );
         self.editor_ctors.insert(tyid, mk_editor);
     }
 
-    pub fn get_editor_ctor(&self, ty: &TypeTerm) -> Option<Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> + Send + Sync>> {
+    pub fn get_editor_ctor(&self, ty: &TypeTerm) -> Option<Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<NestedNode> + Send + Sync>> {
         if let TypeTerm::Type{ id, args: _ } = ty.clone() {
             if let Some(m) = self.editor_ctors.get(&id).cloned() {
                 Some(m)
@@ -309,9 +315,9 @@ impl Context {
         }
     }
 
-    pub fn make_editor(ctx: Arc<RwLock<Self>>, type_term: TypeTerm, depth: usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> {
+    pub fn make_editor(ctx: &Arc<RwLock<Self>>, type_term: TypeTerm, depth: usize) -> Option<NestedNode> {
         let mk_editor = ctx.read().unwrap().get_editor_ctor(&type_term)?;
-        mk_editor(ctx, type_term, depth)
+        mk_editor(ctx.clone(), type_term, depth)
     }
 
     pub fn add_morphism(
diff --git a/nested/src/core/type_term.rs b/nested/src/core/type_term.rs
index 28de52b..d56a8e3 100644
--- a/nested/src/core/type_term.rs
+++ b/nested/src/core/type_term.rs
@@ -126,7 +126,7 @@ impl TypeTerm {
 
 pub struct TypeDict {
     typenames: Bimap<String, u64>,
-    type_id_counter: u64,
+    type_id_counter: TypeID,
 }
 
 impl TypeDict {
@@ -137,10 +137,10 @@ impl TypeDict {
         }
     }
 
-    pub fn add_typename(&mut self, tn: String) -> u64 {
+    pub fn add_typename(&mut self, tn: String) -> TypeID {
         let tyid = self.type_id_counter;
-        self.typenames.insert(tn, tyid);
         self.type_id_counter += 1;
+        self.typenames.insert(tn, tyid);
         tyid
     }
 
diff --git a/nested/src/index/buffer.rs b/nested/src/index/buffer.rs
index efb2d84..061175d 100644
--- a/nested/src/index/buffer.rs
+++ b/nested/src/index/buffer.rs
@@ -1,6 +1,6 @@
 use {
     crate::{
-        core::{InnerViewPort, OuterViewPort, ViewPort, View},
+        core::{InnerViewPort, OuterViewPort, ViewPort, Observer, View},
         index::{IndexArea, IndexView},
     },
     std::sync::RwLock,
diff --git a/nested/src/integer/editor.rs b/nested/src/integer/editor.rs
index ef0a516..ccc6307 100644
--- a/nested/src/integer/editor.rs
+++ b/nested/src/integer/editor.rs
@@ -1,6 +1,6 @@
 use {
     crate::{
-        core::{OuterViewPort},
+        core::{OuterViewPort, Context, TypeTerm},
         list::{PTYListEditor},
         sequence::{SequenceView, SequenceViewExt, decorator::{PTYSeqDecorate, SeqDecorStyle}},
         singleton::{SingletonBuffer, SingletonView},
@@ -12,7 +12,9 @@ use {
         },
         tree::{TreeCursor, TreeNav, TreeNavResult},
         diagnostics::{Diagnostics, Message},
-        Nested
+        tree::NestedNode,
+        Nested,
+        Commander
     },
     std::sync::Arc,
     std::sync::RwLock,
@@ -23,51 +25,17 @@ use {
 //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
 
 pub struct DigitEditor {
+    ctx: Arc<RwLock<Context>>,
     radix: u32,
     data: SingletonBuffer<Option<char>>,
     msg: VecBuffer<Message>,
 }
 
-impl DigitEditor {
-    pub fn new(radix: u32) -> Self {
-        DigitEditor {
-            radix,
-            data: SingletonBuffer::new(None),
-            msg: VecBuffer::new(),
-        }
-    }
+impl Commander for DigitEditor {
+    type Cmd = TerminalEvent;
 
-    pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Option<u32>>> {
-        let radix = self.radix;
-        self.data.get_port().map(move |c| c?.to_digit(radix))
-    }
-}
-
-impl TreeNav for DigitEditor {}
-impl TerminalEditor for DigitEditor {
-    fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
-        let radix = self.radix;
-        self.data
-            .get_port()
-            .map(move |c| {
-                TerminalAtom::new(
-                    c.unwrap_or('?'),
-                    if c.unwrap_or('?').to_digit(radix).is_some() {
-                        TerminalStyle::fg_color((100, 140, 100))
-                    } else {
-                        //TerminalStyle::bg_color((90, 10, 10))
-                        TerminalStyle::fg_color((200, 40, 40))
-                    },
-                )
-            })
-            .to_grid()
-    }
-
-    fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
+    fn send_cmd(&mut self, event: &TerminalEvent) {
         match event {
-            TerminalEvent::Input(Event::Key(Key::Ctrl('x')))
-            | TerminalEvent::Input(Event::Key(Key::Char(' ')))
-            | TerminalEvent::Input(Event::Key(Key::Char('\n'))) => TerminalEditorResult::Exit,
             TerminalEvent::Input(Event::Key(Key::Char(c))) => {
                 self.data.set(Some(*c));
 
@@ -82,50 +50,97 @@ impl TerminalEditor for DigitEditor {
                     ]);
                     self.msg.push(crate::diagnostics::make_error(mb.get_port().flatten()));
                 }
-
-                TerminalEditorResult::Exit
             }
             TerminalEvent::Input(Event::Key(Key::Backspace))
-            | TerminalEvent::Input(Event::Key(Key::Delete)) => {
-                self.data.set(None);
-                self.msg.clear();
-                self.msg.push(crate::diagnostics::make_warn(make_label("empty digit")));
-                TerminalEditorResult::Exit
-            }
-            _ => TerminalEditorResult::Continue,
+                | TerminalEvent::Input(Event::Key(Key::Delete)) => {
+                    self.data.set(None);
+                    self.msg.clear();
+                    self.msg.push(crate::diagnostics::make_warn(make_label("empty digit")));
+                }
+            _ => {}
         }
     }
 }
 
-impl Nested for DigitEditor {}
+impl DigitEditor {
+    pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self {
+        DigitEditor {
+            ctx,
+            radix,
+            data: SingletonBuffer::new(None),
+            msg: VecBuffer::new(),
+        }
+    }
 
-impl Diagnostics for DigitEditor {
-    fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = crate::diagnostics::Message>> {
-        self.msg.get_port().to_sequence()
+    pub fn into_node(self) -> NestedNode {
+        let editor = Arc::new(RwLock::new(self));
+        let ed = editor.read().unwrap();
+        let r = ed.radix;
+
+        NestedNode::new()
+            .set_ctx(ed.ctx.clone())
+            .set_cmd(editor.clone())
+            .set_view(
+                ed.data
+                    .get_port()
+                    .map(move |c| {
+                        TerminalAtom::new(
+                            c.unwrap_or('?'),
+                            if c.unwrap_or('?').to_digit(r).is_some() {
+                                TerminalStyle::fg_color((100, 140, 100))
+                            } else {
+                                //TerminalStyle::bg_color((90, 10, 10))
+                                TerminalStyle::fg_color((200, 40, 40))
+                            },
+                        )
+                    })
+                    .to_grid()
+            )
+            .set_diag(
+                ed.msg.get_port().to_sequence()
+            )
+    }
+
+    pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Option<u32>>> {
+        let radix = self.radix;
+        self.data.get_port().map(move |c| c?.to_digit(radix))
     }
 }
 
 pub struct PosIntEditor {
     radix: u32,
-    digits_editor: PTYListEditor<DigitEditor>
+    digits: NestedNode
 }
 
 impl PosIntEditor {
-    pub fn new(radix: u32) -> Self {
+    pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self {
         PosIntEditor {
             radix,
-            digits_editor: PTYListEditor::new(
-                Box::new(move || Arc::new(RwLock::new(DigitEditor::new(radix)))) as Box<dyn Fn() -> Arc<RwLock<DigitEditor>> + Send + Sync>,
-                SeqDecorStyle::Hex,
+            digits: PTYListEditor::new(
+                ctx.clone(),
+                TypeTerm::Type {
+                    id: ctx.read().unwrap().get_typeid("Digit").unwrap(),
+                    args: vec![
+                        TypeTerm::Num(radix as i64)
+                    ]
+                },
+                match radix {
+                    16 => SeqDecorStyle::Hex,
+                    _ => SeqDecorStyle::Plain
+                },
                 None,
                 0
-            ),
+            ).into_node()
         }
     }
 
+    pub fn into_node(self) -> NestedNode {
+        self.digits
+    }
+/*
     pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = u32>> {
         let radix = self.radix;
-        self.digits_editor.editor
+        self.digits
             .get_data_port()
             .filter_map(move |digit_editor| {
                 digit_editor.read().unwrap().data.get()?.to_digit(radix)
@@ -149,64 +164,7 @@ impl PosIntEditor {
         }
 
         value
-    }
+}
+*/
 }
 
-impl Diagnostics for PosIntEditor {
-    fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = crate::diagnostics::Message>> {
-        self.digits_editor.get_msg_port()
-    }
-}
-
-impl TreeNav for PosIntEditor {
-    fn get_cursor(&self) -> TreeCursor {
-        self.digits_editor.get_cursor()
-    }
-    fn get_cursor_warp(&self) -> TreeCursor {
-        self.digits_editor.get_cursor_warp()
-    }
-    fn goto(&mut self, cur: TreeCursor) -> TreeNavResult {
-        self.digits_editor.goto(cur)
-    }
-    fn goby(&mut self, cur: Vector2<isize>) -> TreeNavResult {
-        self.digits_editor.goby(cur)
-    }
-}
-
-impl TerminalEditor for PosIntEditor {
-    fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
-        match self.radix {
-            10 => {
-                self.digits_editor.editor
-                    .get_seg_seq_view()
-                    .pty_decorate(SeqDecorStyle::Plain, 0)
-            },
-            16 => {
-                self.digits_editor.editor
-                    .get_seg_seq_view()
-                    .pty_decorate(SeqDecorStyle::Hex, 0)
-            }
-            _ => {
-                self.digits_editor.editor
-                    .get_seg_seq_view()
-                    .pty_decorate(SeqDecorStyle::Plain, 0)
-            }
-        }
-    }
-
-    fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
-        match event {
-            TerminalEvent::Input(Event::Key(Key::Ctrl('x')))
-            | TerminalEvent::Input(Event::Key(Key::Char(' ')))
-            | TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
-                self.digits_editor.up();
-                TerminalEditorResult::Exit
-            }
-
-            event => self.digits_editor.handle_terminal_event(event),
-        }
-    }
-}
-
-impl Nested for PosIntEditor {}
-
diff --git a/nested/src/lib.rs b/nested/src/lib.rs
index c2b7a82..afcd3dc 100644
--- a/nested/src/lib.rs
+++ b/nested/src/lib.rs
@@ -72,7 +72,11 @@ pub trait StringGen {
 }
 
 use crate::terminal::TerminalEditor;
-use crate::{tree::{TreeNav}, diagnostics::Diagnostics};
+use crate::{tree::{TreeNav}, diagnostics::Diagnostics, terminal::TerminalView, core::{OuterViewPort}};
+
+pub trait PtySegment {
+    fn pty_view(&self) -> OuterViewPort<dyn TerminalView>;
+}
 
 pub trait Nested
     : TerminalEditor
diff --git a/nested/src/list/editor.rs b/nested/src/list/editor.rs
index e3101ca..d97e883 100644
--- a/nested/src/list/editor.rs
+++ b/nested/src/list/editor.rs
@@ -1,43 +1,44 @@
 use {
     crate::{
-        core::{OuterViewPort, ViewPort},
+        core::{OuterViewPort, ViewPort, Context, TypeTerm},
         list::{
             ListCursor,
-            ListSegment, ListSegmentSequence,
-            segment::PTYSegment
+            ListSegment,
+            ListSegmentSequence,
         },
         sequence::{SequenceView},
         singleton::{SingletonBuffer, SingletonView},
-        terminal::{
-            TerminalView,
-        },
-        Nested,
-        vec::VecBuffer
+        terminal::{TerminalView},
+        tree::NestedNode,
+        vec::{VecBuffer, MutableVecAccess},
+        PtySegment
     },
     std::sync::{Arc, RwLock},
 };
 
 //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
 
-pub struct ListEditor<ItemEditor>
-where ItemEditor: Nested + ?Sized + Send + Sync + 'static
-{
+pub struct ListEditor {
     pub(super) cursor: SingletonBuffer<ListCursor>,
-    pub(crate) data: VecBuffer<Arc<RwLock<ItemEditor>>>,
-    pub(super) make_item_editor: Box<dyn Fn() -> Arc<RwLock<ItemEditor>> + Send + Sync>,
+    pub(crate) data: VecBuffer<NestedNode>,
 
+    pub(crate) ctx: Arc<RwLock<Context>>,
+    pub(super) typ: TypeTerm,
     pub(super) depth: usize,
     pub(super) cur_dist: Arc<RwLock<usize>>,
 }
 
-impl<ItemEditor> ListEditor<ItemEditor>
-where ItemEditor: Nested + ?Sized + Send + Sync + 'static
-{
-    pub fn new(make_item_editor: impl Fn() -> Arc<RwLock<ItemEditor>> + Send + Sync + 'static, depth: usize) -> Self {
+impl ListEditor {
+    pub fn new(
+        ctx: Arc<RwLock<Context>>,
+        typ: TypeTerm,
+        depth: usize
+    ) -> Self {
         ListEditor {
             cursor: SingletonBuffer::new(ListCursor::default()),
-            data: VecBuffer::<Arc<RwLock<ItemEditor>>>::new(),
-            make_item_editor: Box::new(make_item_editor),
+            data: VecBuffer::<NestedNode>::new(),
+            ctx,
+            typ,
             depth,
             cur_dist: Arc::new(RwLock::new(0)),
         }
@@ -46,17 +47,16 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
     pub fn get_seg_seq_view(
         &self,
     ) -> OuterViewPort<dyn SequenceView<Item = OuterViewPort<dyn TerminalView>>> {
-        let segment_view_port = ViewPort::<dyn SequenceView<Item = ListSegment<ItemEditor>>>::new();
-        ListSegmentSequence::new(
+        let seg_seq = ListSegmentSequence::new(
             self.get_cursor_port(),
             self.get_data_port(),
-            segment_view_port.inner(),
             self.depth
         );
-        segment_view_port.into_outer().map(move |segment| segment.pty_view())
+        let se = seg_seq.read().unwrap();
+        se.get_view().map(move |segment| segment.pty_view())
     }
 
-    pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = Arc<RwLock<ItemEditor>>>> {
+    pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = NestedNode>> {
         self.data.get_port().to_sequence()
     }
 
@@ -64,7 +64,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
         self.cursor.get_port()
     }
 
-    pub fn get_item(&self) -> Option<Arc<RwLock<ItemEditor>>> {
+    pub fn get_item(&self) -> Option<NestedNode> {
         if let Some(idx) = self.cursor.get().idx {
             let idx = crate::modulo(idx as isize, self.data.len() as isize) as usize;
             if idx < self.data.len() {
@@ -76,6 +76,18 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
             None
         }
     }
+    pub fn get_item_mut(&mut self) -> Option<MutableVecAccess<NestedNode>> {
+        if let Some(idx) = self.cursor.get().idx {
+            let idx = crate::modulo(idx as isize, self.data.len() as isize) as usize;
+            if idx < self.data.len() {
+                Some(self.data.get_mut(idx))
+            } else {
+                None
+            }
+        } else {
+            None
+        }
+    }
 
     /// split the list off at the current cursor position and return the second half
     /*
diff --git a/nested/src/list/nav.rs b/nested/src/list/nav.rs
index 7aaf6b4..7926a8c 100644
--- a/nested/src/list/nav.rs
+++ b/nested/src/list/nav.rs
@@ -10,9 +10,9 @@ use {
     cgmath::Vector2
 };
 
-impl<ItemEditor> TreeNav for ListEditor<ItemEditor>
-where ItemEditor: Nested + ?Sized + Send + Sync + 'static
-{
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+impl TreeNav for ListEditor {
     fn get_cursor_warp(&self) -> TreeCursor {
         let cur = self.cursor.get();
         match cur.mode {
@@ -29,7 +29,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
             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.data.get(i as usize).get_cursor_warp();
                         sub_cur.tree_addr.insert(0, i as isize - self.data.len() as isize);
                         return sub_cur;
                     } else {
@@ -61,7 +61,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
             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.data.get(i as usize).get_cursor();
                         if sub_cur.tree_addr.len() > 0 {
                             sub_cur.tree_addr.insert(0, i as isize);
                             return sub_cur;
@@ -85,9 +85,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
         let old_cur = self.cursor.get();
         if let Some(i) = old_cur.idx {
             if i < self.data.len() as isize {
-                let ce = self.data.get_mut(i as usize);
-                let mut cur_edit = ce.write().unwrap();
-                cur_edit.goto(TreeCursor::none());
+                self.data.get_mut(i as usize).goto(TreeCursor::none());
             }
         }
 
@@ -108,12 +106,12 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
                 });
 
                 if new_cur.leaf_mode == ListCursorMode::Select && self.data.len() > 0 {
-                    let item = self.data.get_mut(idx as usize);
-                    let mut item_edit = item.write().unwrap();
-                    item_edit.goto(TreeCursor {
-                        leaf_mode: ListCursorMode::Select,
-                        tree_addr: vec![]
-                    });
+                    self.data
+                        .get_mut(idx as usize)
+                        .goto(TreeCursor {
+                            leaf_mode: ListCursorMode::Select,
+                            tree_addr: vec![]
+                        });
                 }
 
                 TreeNavResult::Continue
@@ -127,12 +125,12 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
                         idx: Some(idx),
                     });
 
-                    let item = self.data.get_mut(idx as usize);
-                    let mut item_edit = item.write().unwrap();
-                    item_edit.goto(TreeCursor {
-                        leaf_mode: new_cur.leaf_mode,
-                        tree_addr: new_cur.tree_addr[1..].iter().cloned().collect(),
-                    });
+                    self.data
+                        .get_mut(idx as usize)
+                        .goto(TreeCursor {
+                            leaf_mode: new_cur.leaf_mode,
+                            tree_addr: new_cur.tree_addr[1..].iter().cloned().collect(),
+                        });
                 } else {
                     self.cursor.set(ListCursor::home());
                 }
@@ -175,15 +173,15 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
                 if direction.y > 0 {
                     // dn
                     if cur.tree_addr[0] < self.data.len() as isize {
-                        let item = self.data.get_mut(cur.tree_addr[0] as usize);
-                        let mut item_edit = item.write().unwrap();
-
-                        if item_edit.goby(Vector2::new(direction.x, direction.y)) == TreeNavResult::Continue {
-                            self.cursor.set(ListCursor {
-                                mode: ListCursorMode::Select,
-                                idx: Some(cur.tree_addr[0])
-                            })
-                        }
+                        if self.data
+                            .get_mut(cur.tree_addr[0] as usize)
+                            .goby(Vector2::new(direction.x, direction.y))
+                            == TreeNavResult::Continue {
+                                self.cursor.set(ListCursor {
+                                    mode: ListCursorMode::Select,
+                                    idx: Some(cur.tree_addr[0])
+                                })
+                            }
                     }
 
                     TreeNavResult::Continue
@@ -210,12 +208,12 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
                         });
 
                         if idx < self.data.len() as isize {
-                            let item = self.data.get_mut(idx as usize);
-                            let mut item_edit = item.write().unwrap();
-                            item_edit.goto(TreeCursor {
-                                leaf_mode: cur.leaf_mode,
-                                tree_addr: vec![]
-                            });
+                            self.data
+                                .get_mut(idx as usize)
+                                .goto(TreeCursor {
+                                    leaf_mode: cur.leaf_mode,
+                                    tree_addr: vec![]
+                                });
                         }
 
                         TreeNavResult::Continue
@@ -233,10 +231,10 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
                 // nested
 
                 if cur.tree_addr[0] < self.data.len() as isize {
-                    let item = self.data.get_mut(cur.tree_addr[0] as usize);
-                    let mut item_edit = item.write().unwrap();
-
-                    match item_edit.goby(direction) {
+                    match self.data
+                        .get_mut(cur.tree_addr[0] as usize)
+                        .goby(direction)
+                    {
                         TreeNavResult::Exit => {
                             if direction.y < 0 {
                                 // up
@@ -252,8 +250,6 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
                                 TreeNavResult::Continue
                             } else {
                                 // horizontal
-                                drop(item_edit);
-
                                 if (cur.tree_addr[0]+direction.x >= 0) &&
                                     (cur.tree_addr[0]+direction.x < self.data.len() as isize)
                                 {
diff --git a/nested/src/list/pty_editor.rs b/nested/src/list/pty_editor.rs
index 0767c5a..c85c43f 100644
--- a/nested/src/list/pty_editor.rs
+++ b/nested/src/list/pty_editor.rs
@@ -1,6 +1,6 @@
 use {
     crate::{
-        core::{OuterViewPort},
+        core::{OuterViewPort, Context, TypeTerm},
         list::{
             ListCursor, ListCursorMode,
             ListEditor
@@ -12,67 +12,99 @@ use {
         },
         tree::{TreeCursor, TreeNav, TreeNavResult},
         diagnostics::{Diagnostics},
-        Nested
+        tree::NestedNode, Nested,
+        Commander
     },
     std::sync::{Arc, RwLock},
     termion::event::{Event, Key},
     cgmath::Vector2
 };
 
-pub struct PTYListEditor<ItemEditor>
-where ItemEditor: Nested + ?Sized + Send + Sync + 'static
-{
-    pub editor: ListEditor<ItemEditor>,
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
 
+pub struct PTYListEditor {
+    pub editor: Arc<RwLock<ListEditor>>,
     split_char: Option<char>,
  
     style: SeqDecorStyle,
     depth: usize,
 
-    port: OuterViewPort<dyn TerminalView>
+    pub diag: OuterViewPort<dyn SequenceView<Item = crate::diagnostics::Message>>,
+    pub view: OuterViewPort<dyn TerminalView>
 }
 
-impl<ItemEditor> PTYListEditor<ItemEditor>
-where ItemEditor: Nested + ?Sized + Send + Sync + 'static
-{
+//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
+
+impl PTYListEditor {
     pub fn new(
-        make_item_editor: impl Fn() -> Arc<RwLock<ItemEditor>> + Send + Sync + 'static,
+        ctx: Arc<RwLock<Context>>,
+        typ: TypeTerm,
         style: SeqDecorStyle,
         split_char: Option<char>,
         depth: usize
     ) -> Self {
-        Self::from_editor(ListEditor::new(make_item_editor, depth), style, split_char, depth)
+        Self::from_editor(
+            ListEditor::new(ctx, typ, depth), style, split_char, depth)
     }
 
     pub fn from_editor(
-        editor: ListEditor<ItemEditor>,
+        editor: ListEditor,
         style: SeqDecorStyle,
         split_char: Option<char>,
         depth: usize
     ) -> Self {
-        let port = editor
-            .get_seg_seq_view()
-            .pty_decorate(style, depth);
-
         PTYListEditor {
-            editor,
             split_char,
             style,
             depth,
-            port
+
+            view: editor.get_seg_seq_view().pty_decorate(style, depth),
+            diag: editor.get_data_port()
+                    .enumerate()
+                    .map(
+                        |(idx, item_editor)| {
+                            let idx = *idx;
+                            item_editor
+                                .get_msg_port()
+                                .map(
+                                    move |msg| {
+                                        let mut msg = msg.clone();
+                                        msg.addr.insert(0, idx);
+                                        msg
+                                    }
+                                )
+                        }
+                    )
+                    .flatten(),
+
+            editor: Arc::new(RwLock::new(editor)),
         } 
     }
 
-    pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = Arc<RwLock<ItemEditor>>>> {
-        self.editor.get_data_port()
+    pub fn into_node(self) -> NestedNode {
+        let editor = Arc::new(RwLock::new(self));
+
+        let ed = editor.read().unwrap();
+        let edd = ed.editor.read().unwrap();
+
+        NestedNode::new()
+            .set_cmd(editor.clone())
+            .set_nav(ed.editor.clone())
+            .set_ctx(edd.ctx.clone())
+            .set_diag(ed.diag.clone())
+            .set_view(ed.view.clone())
+    }
+    
+    pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = NestedNode>> {
+        self.editor.read().unwrap().get_data_port()
     }
     
     pub fn clear(&mut self) {
-        self.editor.clear();
+        self.editor.write().unwrap().clear();
     }
     
-    pub fn get_item(&self) -> Option<Arc<RwLock<ItemEditor>>> {
-        self.editor.get_item()
+    pub fn get_item(&self) -> Option<NestedNode> {
+        self.editor.read().unwrap().get_item()
     }
     
     pub fn set_depth(&mut self, depth: usize) {
@@ -84,95 +116,74 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
     }
 }
 
-impl<ItemEditor> TerminalEditor for PTYListEditor<ItemEditor>
-where ItemEditor: Nested + ?Sized + Send + Sync + 'static
-{
-    fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
-        self.port.clone()
-    }
+impl Commander for PTYListEditor {
+    type Cmd = TerminalEvent;
 
-    fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
-        let mut cur = self.editor.cursor.get();
+    fn send_cmd(&mut self, event: &TerminalEvent) {
+        let mut e = self.editor.write().unwrap();
+
+        let mut cur = e.cursor.get();
         if let Some(idx) = cur.idx {
             match cur.mode {
                 ListCursorMode::Insert => match event {
                     TerminalEvent::Input(Event::Key(Key::Backspace)) => {
-                        if idx > 0 && idx <= self.editor.data.len() as isize {
+                        if idx > 0 && idx <= e.data.len() as isize {
                             cur.idx = Some(idx as isize - 1);
-                            self.editor.cursor.set(cur);
-                            self.editor.data.remove(idx as usize - 1);
-
-                            if self.editor.data.len() > 0 {
-                                TerminalEditorResult::Continue
-                            } else {
-                                TerminalEditorResult::Exit
-                            }
-                        } else {
-                            TerminalEditorResult::Exit
+                            e.cursor.set(cur);
+                            e.data.remove(idx as usize - 1);
                         }
                     }
                     TerminalEvent::Input(Event::Key(Key::Delete)) => {
-                        if idx < self.editor.data.len() as isize {
-                            self.editor.data.remove(idx as usize);
-                            TerminalEditorResult::Continue
-                        } else {
-                            TerminalEditorResult::Exit
+                        if idx < e.data.len() as isize {
+                            e.data.remove(idx as usize);
                         }
                     }
                     TerminalEvent::Input(Event::Key(Key::Char('\t')))
                     | TerminalEvent::Input(Event::Key(Key::Insert)) => {
-                        self.editor.set_leaf_mode(ListCursorMode::Select);
-                        TerminalEditorResult::Continue
+                        e.set_leaf_mode(ListCursorMode::Select);
                     }
                     TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
-                        self.editor.goto(TreeCursor::none());
-                        TerminalEditorResult::Exit
+                        e.goto(TreeCursor::none());
                     }
                     _ => {
-                        let new_edit = (self.editor.make_item_editor)();
-                        self.editor.data.insert(idx as usize, new_edit.clone());
-                        self.editor.set_leaf_mode(ListCursorMode::Select);
+                        let mut new_edit = Context::make_editor(&e.ctx, e.typ.clone(), self.depth+1).unwrap();
+                        e.data.insert(idx as usize, new_edit.clone());
+                        e.set_leaf_mode(ListCursorMode::Select);
 
-                        let mut ne = new_edit.write().unwrap();
-                        ne.goto(TreeCursor::home());
-
-                        ne.handle_terminal_event(event);
+                        new_edit.goto(TreeCursor::home());
+                        new_edit.handle_terminal_event(event);
 
                         if self.split_char.is_none() {
-                            self.editor.cursor.set(ListCursor {
+                            e.cursor.set(ListCursor {
                                 mode: ListCursorMode::Insert,
                                 idx: Some(idx as isize + 1),
                             });
                         }
-
-                        TerminalEditorResult::Continue
                     }
                 },
                 ListCursorMode::Select => {
                     match event {
                         TerminalEvent::Input(Event::Key(Key::Char('\t')))
                             | TerminalEvent::Input(Event::Key(Key::Insert)) => {
-                                self.editor.set_leaf_mode(ListCursorMode::Insert);
-                                TerminalEditorResult::Continue
+                                e.set_leaf_mode(ListCursorMode::Insert);
                             }
 
                         TerminalEvent::Input(Event::Key(Key::Char(c))) => {
                             if Some(*c) == self.split_char {
-                                let c = self.editor.cursor.get();
-                                self.editor.goto(TreeCursor::none());
-                                self.editor.cursor.set(ListCursor {
+                                let c = e.cursor.get();
+                                e.goto(TreeCursor::none());
+                                e.cursor.set(ListCursor {
                                     mode: ListCursorMode::Insert,
                                     idx: Some(1 + c.idx.unwrap_or(0))
                                 });
-                                TerminalEditorResult::Continue
                             } else {
-                                if let Some(e) = self.editor.get_item() {
-                                    e.write().unwrap().handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char(*c))));
+                                if let Some(mut ce) = e.get_item_mut() {
+                                    ce.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char(*c))));
                                     //match 
                                     if self.split_char.is_none() {
                                     //    TerminalEditorResult::Exit =>
                                         {
-                                            self.editor.cursor.set(ListCursor {
+                                            e.cursor.set(ListCursor {
                                                 mode: ListCursorMode::Insert,
                                                 idx: Some(idx as isize + 1),
                                             });
@@ -181,26 +192,21 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
                                       //  }
                                     }
                                 }
-                                TerminalEditorResult::Exit
                             }
                         }
                         ev => {
-                            if let Some(e) = self.editor.get_item() {
-                                match e.write().unwrap().handle_terminal_event(ev) {
-                                    TerminalEditorResult::Exit => {
-                                        match ev {
-                                            TerminalEvent::Input(Event::Key(Key::Ctrl('x'))) => {
-                                                return TerminalEditorResult::Exit
-                                            }
-                                            TerminalEvent::Input(Event::Key(Key::Backspace)) => {
-                                                self.editor.data.remove(idx as usize);
-                                                self.editor.cursor.set(ListCursor {
+                            if let Some(mut ce) = e.get_item_mut() {
+                                ce.handle_terminal_event(ev);
+/*
+                                TerminalEvent::Input(Event::Key(Key::Backspace)) => {
+                                                e.data.remove(idx as usize);
+                                                e.cursor.set(ListCursor {
                                                     mode: ListCursorMode::Insert,
                                                     idx: Some(idx as isize),
                                                 });                             
                                             }
                                             _ => {
-                                                self.editor.cursor.set(ListCursor {
+                                                e.cursor.set(ListCursor {
                                                     mode: ListCursorMode::Insert,
                                                     idx: Some(idx as isize + 1),
                                                 });                                                
@@ -210,90 +216,14 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
                                     TerminalEditorResult::Continue => {
                                         
                                     }
-                                }
                             }
-
-                            TerminalEditorResult::Continue
+                                */
+                            }
                         }
                     }
                 }
             }
-        } else {
-            TerminalEditorResult::Continue
         }
     }
 }
 
-impl<ItemEditor> TreeNav for PTYListEditor<ItemEditor>
-where ItemEditor: Nested + ?Sized + Send + Sync + 'static
-{
-    fn get_cursor_warp(&self) -> TreeCursor {
-        self.editor.get_cursor_warp()
-    }
-
-    fn get_cursor(&self) -> TreeCursor {
-        self.editor.get_cursor()
-    }
-
-    fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult {
-        self.editor.goby(direction)
-    }
-
-    fn goto(&mut self, cursor: TreeCursor) -> TreeNavResult {
-        self.editor.goto(cursor)
-    }
-}
-
-impl<ItemEditor> Diagnostics for PTYListEditor<ItemEditor>
-where ItemEditor: Nested + ?Sized + Send + Sync + 'static
-{
-    fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = crate::diagnostics::Message>> {
-        self.editor
-            .get_data_port()
-            .enumerate()
-            .map(
-                |(idx, item_editor)| {
-                    let idx = *idx;
-                    item_editor.read().unwrap()
-                        .get_msg_port()
-                        .map(
-                            move |msg| {
-                                let mut msg = msg.clone();
-                                msg.addr.insert(0, idx);
-                                msg
-                            }
-                        )
-                }
-            )
-            .flatten()
-    }
-}
-
-/*
-impl<ItemEditor> TreeType for PTYListEditor<ItemEditor>
-where ItemEditor: Nested + TreeType + ?Sized + Send + Sync + 'static
-{
-    fn get_type(&self, addr: &Vec<usize>) -> TypeTerm {
-        TypeTerm::new(0)
-    }
-}
-*/
-impl<ItemEditor> Nested for PTYListEditor<ItemEditor>
-where ItemEditor: Nested + ?Sized + Send + Sync + 'static
-{}
-
-use crate::{
-    sequence::SequenceViewExt,
-    StringGen
-};
-
-impl<ItemEditor: StringGen + Nested + Send + Sync> StringGen for PTYListEditor<ItemEditor> {
-
-   fn get_string(&self) -> String {
-        self.get_data_port()
-            .map(|ce| ce.read().unwrap().get_string())
-            .get_view().unwrap()
-            .iter().collect::<String>()
-    }
-}
-
diff --git a/nested/src/list/segment.rs b/nested/src/list/segment.rs
index 3068455..e400672 100644
--- a/nested/src/list/segment.rs
+++ b/nested/src/list/segment.rs
@@ -1,35 +1,30 @@
 use {
     crate::{
-        core::{InnerViewPort, Observer, ObserverBroadcast, ObserverExt, OuterViewPort, View},
+        core::{InnerViewPort, Observer, ObserverBroadcast, ObserverExt, OuterViewPort, View, ViewPort},
         list::{ListCursor, ListCursorMode},
         projection::ProjectionHelper,
         sequence::SequenceView,
         singleton::SingletonView,
         terminal::{TerminalView, TerminalStyle, make_label},
-        Nested,
-        color::{bg_style_from_depth, fg_style_from_depth}
+        tree::{NestedNode, TreeNav},
+        color::{bg_style_from_depth, fg_style_from_depth},
+        PtySegment
     },
     std::sync::Arc,
     std::sync::RwLock,
 };
 
-pub enum ListSegment<ItemEditor>
-where ItemEditor: Nested + ?Sized + Send + Sync + 'static
+pub enum ListSegment
 {
     InsertCursor,
     Item {
-        editor: Arc<RwLock<ItemEditor>>,
+        editor: NestedNode,
         depth: usize,
         cur_dist: isize,
     }
 }
 
-pub trait PTYSegment {
-    fn pty_view(&self) -> OuterViewPort<dyn TerminalView>;
-}
-
-impl<ItemEditor> PTYSegment for ListSegment<ItemEditor>
-where ItemEditor: Nested + ?Sized + Send + Sync + 'static
+impl PtySegment for ListSegment
 {
     fn pty_view(&self) -> OuterViewPort<dyn TerminalView> {
         match self {
@@ -44,8 +39,8 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
                 let e = editor.clone();
                 let d = *depth;
                 let cur_dist = *cur_dist;
-                editor.read().unwrap().get_term_view().map_item(move |_pt, atom| {
-                    let c = e.read().unwrap().get_cursor();
+                editor.get_view().map_item(move |_pt, atom| {
+                    let c = e.get_cursor();
                     let cur_depth = c.tree_addr.len();
                     let select =
                         if cur_dist == 0 {
@@ -63,29 +58,27 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
     }
 }
 
-pub struct ListSegmentSequence<ItemEditor>
-where ItemEditor: Nested + ?Sized + Send + Sync + 'static
+pub struct ListSegmentSequence
 {
-    data: Arc<dyn SequenceView<Item = Arc<RwLock<ItemEditor>>>>,
+    data: Arc<dyn SequenceView<Item = NestedNode>>,
     cursor: Arc<dyn SingletonView<Item = ListCursor>>,
 
     depth: usize,
     cur_cursor: ListCursor,
 
-    cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = ListSegment<ItemEditor>>>>>,
+    port: ViewPort<dyn SequenceView<Item = ListSegment>>,
+    cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = ListSegment>>>>,
     proj_helper: ProjectionHelper<usize, Self>,
 }
 
-impl<ItemEditor> View for ListSegmentSequence<ItemEditor>
-where ItemEditor: Nested + ?Sized + Send + Sync + 'static
+impl View for ListSegmentSequence
 {
     type Msg = usize;
 }
 
-impl<ItemEditor> SequenceView for ListSegmentSequence<ItemEditor>
-where ItemEditor: Nested + ?Sized + Send + Sync + 'static
+impl SequenceView for ListSegmentSequence
 {
-    type Item = ListSegment<ItemEditor>;
+    type Item = ListSegment;
 
     fn len(&self) -> Option<usize> {
         match self.cur_cursor.mode {
@@ -135,18 +128,18 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
     }
 }
 
-impl<ItemEditor> ListSegmentSequence<ItemEditor>
-where ItemEditor: Nested + ?Sized + Send + Sync + 'static
+impl ListSegmentSequence
 {
     pub fn new(
         cursor_port: OuterViewPort<dyn SingletonView<Item = ListCursor>>,
-        data_port: OuterViewPort<dyn SequenceView<Item = Arc<RwLock<ItemEditor>>>>,
-        out_port: InnerViewPort<dyn SequenceView<Item = ListSegment<ItemEditor>>>,
+        data_port: OuterViewPort<dyn SequenceView<Item = NestedNode>>,
         depth: usize
     ) -> Arc<RwLock<Self>> {
-        let mut proj_helper = ProjectionHelper::new(out_port.0.update_hooks.clone());
+        let out_port = ViewPort::new();
+        let mut proj_helper = ProjectionHelper::new(out_port.update_hooks.clone());
         let proj = Arc::new(RwLock::new(ListSegmentSequence {
             cur_cursor: cursor_port.get_view().get(),
+            port: out_port.clone(),
             depth,
 
             cursor: proj_helper.new_singleton_arg(0, cursor_port, |s: &mut Self, _msg| {
@@ -175,13 +168,17 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
                     s.cast.notify(idx);
                 }
             }),
-            cast: out_port.get_broadcast(),
+            cast: out_port.inner().get_broadcast(),
             proj_helper,
         }));
 
         proj.write().unwrap().proj_helper.set_proj(&proj);
-        out_port.set_view(Some(proj.clone()));
+        out_port.inner().set_view(Some(proj.clone()));
 
         proj
     }
+
+    pub fn get_view(&self) -> OuterViewPort<dyn SequenceView<Item = ListSegment>> {
+        self.port.outer()
+    }
 }
diff --git a/nested/src/make_editor.rs b/nested/src/make_editor.rs
index fa38aa9..1425edb 100644
--- a/nested/src/make_editor.rs
+++ b/nested/src/make_editor.rs
@@ -1,11 +1,12 @@
 use {
     crate::{
         core::{TypeTerm, Context},
-        integer::PosIntEditor,
+        integer::{DigitEditor, PosIntEditor},
         list::{PTYListEditor},
         sequence::{decorator::{SeqDecorStyle}},
         sum::SumEditor,
         char_editor::CharEditor,
+        type_term_editor::TypeTermEditor,
         Nested
     },
     std::sync::{Arc, RwLock},
@@ -17,9 +18,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
     ctx.write().unwrap().add_editor_ctor(
         "Char", Arc::new(
             |ctx: Arc<RwLock<Context>>, _ty: TypeTerm, _depth: usize| {
-                Some(
-                    Arc::new(RwLock::new(CharEditor::new_node(&ctx)))
-                        as Arc<RwLock<dyn Nested + Send + Sync>>)
+                Some(CharEditor::new_node(&ctx))
             }
         )
     );
@@ -50,7 +49,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
 
                             let delim = if args.len() > 1 {
                                 match args[1] {
-                                    TypeTerm::Num(0) => Some(' '),
+                                    TypeTerm::Num(0) => None,
                                     TypeTerm::Num(1) => Some(' '),
                                     TypeTerm::Num(2) => Some('\n'),
                                     TypeTerm::Num(3) => None,
@@ -64,17 +63,13 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
                             };
 
                             Some(
-                                Arc::new(RwLock::new(PTYListEditor::new(
-                                    Box::new({
-                                        move || {
-                                            Context::make_editor(ctx.clone(), args[0].clone(), depth + 1).unwrap()
-                                        }
-                                    }),
+                                PTYListEditor::new(
+                                    ctx.clone(),
+                                    args[0].clone(),
                                     style,
                                     delim,
                                     depth
-                                    )))
-                                    as Arc<RwLock<dyn Nested + Send + Sync>>
+                                ).into_node()
                             )
                         } else {
                             None
@@ -90,7 +85,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
         "Symbol", Arc::new(
             |ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
                 Context::make_editor(
-                    ctx.clone(),
+                    &ctx,
                     ctx.read().unwrap().type_term_from_str("( List Char 0 )").unwrap(),
                     depth
                 )
@@ -102,7 +97,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
         "String", Arc::new(
             |ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
                 Context::make_editor(
-                    ctx.clone(),
+                    &ctx,
                     ctx.read().unwrap().type_term_from_str("( List Char 3 )").unwrap(),
                     depth
                 )
@@ -113,19 +108,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
     ctx.write().unwrap().add_editor_ctor(
         "TypeTerm", Arc::new(
             |ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
-                let mut s = SumEditor::new(
-                    vec![
-                        Context::make_editor(ctx.clone(), ctx.read().unwrap().type_term_from_str("( Symbol )").unwrap(), depth+1).unwrap(),
-                        Context::make_editor(ctx.clone(), ctx.read().unwrap().type_term_from_str("( PosInt 10 )").unwrap(), depth+1).unwrap(),
-                        Context::make_editor(ctx.clone(), ctx.read().unwrap().type_term_from_str("( List TypeTerm )").unwrap(), depth+1).unwrap(),
-                    ]
-                );
-                s.select(0);
-                Some(
-                    Arc::new(RwLock::new(
-                        s
-                    ))
-                )
+                Some(TypeTermEditor::new(ctx, depth).into_node())
             }
         )
     );
@@ -138,11 +121,13 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
     let ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent))));
 
     ctx.write().unwrap().add_typename("MachineInt".into());
-    ctx.write().unwrap().add_typename("Digit".into());
     ctx.write().unwrap().add_typename("BigEndian".into());
+
+    //ctx.write().unwrap().add_typename("Digit".into());
+
     ctx.write().unwrap().add_editor_ctor(
-        "PosInt", Arc::new(
-            |_ctx: Arc<RwLock<Context>>, ty: TypeTerm, _depth: usize| {
+        "Digit", Arc::new(
+            |ctx: Arc<RwLock<Context>>, ty: TypeTerm, _depth: usize| {
                 match ty {
                     TypeTerm::Type {
                         id: _, args
@@ -151,8 +136,33 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
                             match args[0] {
                                 TypeTerm::Num(radix) => {
                                     Some(
-                                        Arc::new(RwLock::new(PosIntEditor::new(radix as u32)))
-                                            as Arc<RwLock<dyn Nested + Send + Sync>>
+                                        DigitEditor::new(ctx.clone(), radix as u32).into_node()
+                                    )
+                                },
+                                _ => None
+                            }
+                        } else {
+                            None
+                        }
+                    }
+                    _ => None
+                }
+            }
+        )
+    );
+    
+    ctx.write().unwrap().add_editor_ctor(
+        "PosInt", Arc::new(
+            |ctx: Arc<RwLock<Context>>, ty: TypeTerm, _depth: usize| {
+                match ty {
+                    TypeTerm::Type {
+                        id: _, args
+                    } => {
+                        if args.len() > 0 {
+                            match args[0] {
+                                TypeTerm::Num(radix) => {
+                                    Some(
+                                        PosIntEditor::new(ctx.clone(), radix as u32).into_node()
                                     )
                                 },
                                 _ => None
@@ -177,7 +187,7 @@ pub fn init_os_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
         "PathSegment", Arc::new(
             |ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
                 Context::make_editor(
-                    ctx.clone(),
+                    &ctx,
                     ctx.read().unwrap().type_term_from_str("( List Char 0 )").unwrap(),
                     depth
                 )
@@ -189,7 +199,7 @@ pub fn init_os_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
         "Path", Arc::new(
             |ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
                 Context::make_editor(
-                    ctx.clone(),
+                    &ctx,
                     ctx.read().unwrap().type_term_from_str("( List PathSegment 6 )").unwrap(),
                     depth+1
                 )
diff --git a/nested/src/product/editor.rs b/nested/src/product/editor.rs
index 9bac1fe..be50901 100644
--- a/nested/src/product/editor.rs
+++ b/nested/src/product/editor.rs
@@ -13,7 +13,7 @@ use {
         tree::{TreeNav, TreeNavResult},
         diagnostics::{Diagnostics},
         terminal::{TerminalStyle},
-        Nested
+        tree::NestedNode
     },
     cgmath::{Point2},
     std::sync::{Arc, RwLock},
@@ -110,7 +110,7 @@ impl ProductEditor {
         Some(self.get_editor_segment_mut(self.cursor?))
     }
 
-    pub fn get_editor(&self, idx: isize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> {
+    pub fn get_editor(&self, idx: isize) -> Option<NestedNode> {
         if let ProductEditorSegment::N{ t: _, editor, ed_depth: _, cur_depth: _, cur_dist: _ } = self.get_editor_segment(idx) {
             editor
         } else {
@@ -118,7 +118,7 @@ impl ProductEditor {
         }
     }
 
-    pub fn get_cur_editor(&self) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> {
+    pub fn get_cur_editor(&self) -> Option<NestedNode> {
         self.get_editor(self.cursor?)
     }
 
@@ -143,7 +143,7 @@ impl ProductEditor {
             };
 
             if let Some(e) = editor {
-                self.msg_buf.update(idx as usize, Some(e.read().unwrap().get_msg_port()));
+                self.msg_buf.update(idx as usize, Some(e.get_msg_port()));
             } else {
                 let mut b = VecBuffer::new();
                 b.push(crate::diagnostics::make_todo(crate::terminal::make_label(&format!("complete {}", self.ctx.read().unwrap().type_term_to_str(&t[0])))));
@@ -192,9 +192,8 @@ impl TerminalEditor for ProductEditor {
             if let Some(ProductEditorSegment::N{ t, editor, ed_depth, cur_depth, cur_dist: _ }) = segment.deref_mut() {
                 *cur_depth = self.get_cursor().tree_addr.len();
 
-                if let Some(e) = editor.clone() {
-                    let mut ce = e.write().unwrap();
-                    match ce.handle_terminal_event(event) {
+                if let Some(mut e) = editor.clone() {
+                    match e.handle_terminal_event(event) {
                         TerminalEditorResult::Exit =>
                             match event {
                                 TerminalEvent::Input(Event::Key(Key::Backspace)) => {
@@ -203,8 +202,7 @@ impl TerminalEditor for ProductEditor {
                                     TerminalEditorResult::Continue
                                 }
                                 _ => {
-                                    *cur_depth = ce.get_cursor().tree_addr.len();
-                                    drop(ce);
+                                    *cur_depth = e.get_cursor().tree_addr.len();
                                     match self.nexd() {
                                         TreeNavResult::Continue => TerminalEditorResult::Continue,
                                         TreeNavResult::Exit => TerminalEditorResult::Exit
@@ -212,17 +210,17 @@ impl TerminalEditor for ProductEditor {
                                 }
                             },
                         TerminalEditorResult::Continue => {
-                            *cur_depth = ce.get_cursor().tree_addr.len();
+                            *cur_depth = e.get_cursor().tree_addr.len();
                             TerminalEditorResult::Continue
                         }
                     }
                 } else {
-                    let e = Context::make_editor(self.ctx.clone(), t[0].clone(), *ed_depth+1).unwrap();
+                    let mut e = Context::make_editor(&self.ctx, t[0].clone(), *ed_depth+1).unwrap();
                     *editor = Some(e.clone());
                     update_segment = true;
 
-                    e.write().unwrap().dn();
-                    let x = e.write().unwrap().handle_terminal_event(event);
+                    e.dn();
+                    let x = e.handle_terminal_event(event);
                     x
                 }
             } else {
diff --git a/nested/src/product/nav.rs b/nested/src/product/nav.rs
index b14d65b..1e8ce9d 100644
--- a/nested/src/product/nav.rs
+++ b/nested/src/product/nav.rs
@@ -14,7 +14,7 @@ impl TreeNav for ProductEditor {
     fn get_cursor(&self) -> TreeCursor {
         if let Some(i) = self.cursor {
             if let Some(e) = self.get_editor(i) {
-                let mut c = e.read().unwrap().get_cursor();
+                let mut c = e.get_cursor();
                 if c.tree_addr.len() == 0 {
                     c.leaf_mode = ListCursorMode::Select;
                 }
@@ -34,7 +34,7 @@ impl TreeNav for ProductEditor {
     fn get_cursor_warp(&self) -> TreeCursor {
         if let Some(i) = self.cursor {
             if let Some(e) = self.get_editor(i) {
-                let mut c = e.read().unwrap().get_cursor_warp();
+                let mut c = e.get_cursor_warp();
                 if c.tree_addr.len() == 0 {
                     c.leaf_mode = ListCursorMode::Select;
                 }
@@ -57,7 +57,6 @@ impl TreeNav for ProductEditor {
         if let Some(mut segment) = self.get_cur_segment_mut() {
             if let Some(ProductEditorSegment::N{ t: _t, editor, ed_depth: _, cur_depth: _, cur_dist:_ }) = segment.deref_mut() {
                 if let Some(e) = editor {
-                    let mut e = e.write().unwrap();
                     e.goto(TreeCursor::none());
                 }
             }
@@ -68,12 +67,11 @@ impl TreeNav for ProductEditor {
             if let Some(mut element) = self.get_cur_segment_mut() {
                 if let Some(ProductEditorSegment::N{ t, editor, ed_depth, cur_depth: _, cur_dist:_ }) = element.deref_mut() {
                     if let Some(e) = editor {
-                        e.write().unwrap().goto(c.clone());
+                        e.goto(c.clone());
                     } else if c.tree_addr.len() > 0 {
                         // create editor
-                        let e = Context::make_editor(self.ctx.clone(), t[0].clone(), *ed_depth+1).unwrap();
+                        let mut e = Context::make_editor(&self.ctx, t[0].clone(), *ed_depth+1).unwrap();
                         *editor = Some(e.clone());
-                        let mut e = e.write().unwrap();
                         e.goto(c.clone());
                     }
                 }
@@ -89,8 +87,8 @@ impl TreeNav for ProductEditor {
 
             TreeNavResult::Continue
         } else {
-            if let Some(ed) = self.get_cur_editor() {
-                ed.write().unwrap().goto(TreeCursor::none());
+            if let Some(mut ed) = self.get_cur_editor() {
+                ed.goto(TreeCursor::none());
             }
 
             self.cursor = None;
@@ -125,14 +123,12 @@ impl TreeNav for ProductEditor {
                     if let Some(mut element) = self.get_cur_segment_mut() {
                         if let Some(ProductEditorSegment::N{ t, editor, ed_depth, cur_depth: _, cur_dist:_ }) = element.deref_mut() {
                             if let Some(e) = editor {
-                                let mut e = e.write().unwrap();
                                 e.goby(direction);
                             } else {
                                 // create editor
 
-                                let e = Context::make_editor(self.ctx.clone(), t[0].clone(), *ed_depth+1).unwrap();
+                                let mut e = Context::make_editor(&self.ctx, t[0].clone(), *ed_depth+1).unwrap();
                                 *editor = Some(e.clone());
-                                let mut e = e.write().unwrap();
                                 e.goby(direction);
                             }
                         }
@@ -175,15 +171,13 @@ impl TreeNav for ProductEditor {
                 let nav_result =
                     if let Some(mut element) = self.get_cur_segment_mut() {
                         if let Some(ProductEditorSegment::N{ t: _, editor, ed_depth: _, cur_depth, cur_dist:_ }) = element.deref_mut() {
-                            if let Some(e) = editor {
-                                let mut ce = e.write().unwrap();
+                            if let Some(mut e) = editor.as_mut() {
                                 //\\//\\//\\//\\
                                 // horizontal //
                                 //\\//\\//\\//\\
-                                match ce.goby(direction) {
+                                match e.goby(direction) {
                                     TreeNavResult::Exit => {
                                        // *cur_depth = 1;
-                                        drop(ce);
                                         drop(e);
 
                                         if direction.y < 0 {
diff --git a/nested/src/product/segment.rs b/nested/src/product/segment.rs
index 2cd0e5b..395755c 100644
--- a/nested/src/product/segment.rs
+++ b/nested/src/product/segment.rs
@@ -6,7 +6,7 @@ use {
             make_label
         },
         color::{bg_style_from_depth, fg_style_from_depth},
-        Nested
+        tree::{NestedNode, TreeNav}
     },
     std::{sync::{Arc, RwLock}},
 };
@@ -16,7 +16,7 @@ pub enum ProductEditorSegment {
     T( String, usize ),
     N {
         t: TypeLadder,
-        editor: Option<Arc<RwLock<dyn Nested + Send + Sync>>>,
+        editor: Option<NestedNode>,
         ed_depth: usize,
         cur_depth: usize,
         cur_dist: isize
@@ -36,15 +36,14 @@ impl ProductEditorSegment {
             ),
 
             ProductEditorSegment::N { t: _, editor: Some(e), ed_depth, cur_depth: _, cur_dist } =>
-                e.read().unwrap()
-                .get_term_view()
+                e.get_view()
                 .map_item({
                     let e = e.clone();
                     let d = *ed_depth;
                     let cur_dist = *cur_dist;
 
                     move |_i, x| {
-                        let c = e.read().unwrap().get_cursor();
+                        let c = e.get_cursor();
                         let cur_depth = c.tree_addr.len();
                         let select =
                             if cur_dist == 0 {
diff --git a/nested/src/sum/editor.rs b/nested/src/sum/editor.rs
index 59946c5..6712e4f 100644
--- a/nested/src/sum/editor.rs
+++ b/nested/src/sum/editor.rs
@@ -8,7 +8,9 @@ use {
         sequence::{SequenceView},
         tree::{TreeNav, TreeCursor, TreeNavResult},
         diagnostics::{Diagnostics, Message},
-        Nested
+        tree::NestedNode,
+        Commander,
+        PtySegment
     },
     cgmath::{Vector2},
     std::sync::{Arc, RwLock},
@@ -17,7 +19,7 @@ use {
 
 pub struct SumEditor {
     cur: usize,
-    pub editors: Vec< Arc<RwLock<dyn Nested + Send + Sync + 'static>> >,
+    pub editors: Vec< NestedNode >,
 
     port: ViewPort< dyn TerminalView >,
     diag_port: ViewPort< dyn SequenceView<Item = Message> >
@@ -25,7 +27,7 @@ pub struct SumEditor {
 
 impl SumEditor {
     pub fn new(
-        editors: Vec< Arc<RwLock<dyn Nested + Send + Sync + 'static>> >
+        editors: Vec< NestedNode >
     ) -> Self {
         let port = ViewPort::new();
         //let mut diag_buf = VecBuffer::new();
@@ -37,21 +39,30 @@ impl SumEditor {
             diag_port: ViewPort::new()//diag_buf.get_port().to_sequence()
         }
     }
-
-    pub fn get(&self) -> Arc<RwLock<dyn Nested + Send + Sync>> {
+/*
+    pub fn into_node(self) -> NestedNode {
+        let editor = Arc::new(RwLock::new(self));
+        NestedNode::new()
+            .set_view()
+            .set_cmd(editor.clone())
+            .set_nav(editor.clone())
+            .set_diag(editor.read().unwrap().diag.clone())
+    }
+*/
+    pub fn get(&self) -> NestedNode {
         self.editors[ self.cur ].clone()
     }
 
     pub fn select(&mut self, idx: usize) {
         self.cur = idx;
 
-        let tv = self.editors[ self.cur ].read().unwrap().get_term_view();
+        let tv = self.editors[ self.cur ].get_term_view();
         tv.add_observer( self.port.get_cast() );
         self.port.update_hooks.write().unwrap().clear();
         self.port.add_update_hook( Arc::new(tv.0.clone()) );
         self.port.set_view( Some(tv.get_view_arc()) );
 
-        let dv = self.editors[ self.cur ].read().unwrap().get_msg_port();
+        let dv = self.editors[ self.cur ].get_msg_port();
         dv.add_observer( self.diag_port.get_cast() );
         self.diag_port.update_hooks.write().unwrap().clear();
         self.diag_port.add_update_hook( Arc::new(dv.0.clone()) );
@@ -61,55 +72,48 @@ impl SumEditor {
 
 impl TreeNav for SumEditor {
     fn get_cursor(&self) -> TreeCursor {
-        self.editors[ self.cur ].write().unwrap().get_cursor()
+        self.editors[ self.cur ].get_cursor()
     }
 
     fn get_cursor_warp(&self) -> TreeCursor {
-        self.editors[ self.cur ].write().unwrap().get_cursor_warp()
+        self.editors[ self.cur ].get_cursor_warp()
     }
 
     fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult {
-        self.editors[ self.cur ].write().unwrap().goby( direction )
+        self.editors[ self.cur ].goby( direction )
     }
 
     fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult {
-        self.editors[ self.cur ].write().unwrap().goto( new_cursor )
+        self.editors[ self.cur ].goto( new_cursor )
     }
 }
 
-impl TerminalEditor for SumEditor {
-    fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
+impl PtySegment for SumEditor {
+    fn pty_view(&self) -> OuterViewPort<dyn TerminalView> {
         self.port.outer()
     }
+}
 
-    fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
+impl Commander for SumEditor {
+    type Cmd = TerminalEvent;
+
+    fn send_cmd(&mut self, event: &TerminalEvent) {
         match event {
             TerminalEvent::Input( termion::event::Event::Key(Key::Ctrl('x')) ) => {
-                let res = self.editors[ self.cur ].write().unwrap().handle_terminal_event( event );
+                let res = self.editors[ self.cur ].handle_terminal_event( event );
                 match res {
                     TerminalEditorResult::Exit => {
                         self.select( (self.cur + 1) % self.editors.len() );
-                        if self.editors[ self.cur ].read().unwrap().get_cursor().tree_addr.len() == 0 {
+                        if self.editors[ self.cur ].get_cursor().tree_addr.len() == 0 {
                             self.dn();
                         }
-                        TerminalEditorResult::Continue
                     },
-                    _ => TerminalEditorResult::Continue
+                    _ => {}
                 }
             },
             event => {
-                self.editors[ self.cur ].write().unwrap().handle_terminal_event( event )
+                self.editors[ self.cur ].handle_terminal_event( event );
             }
         }
     }
 }
-
-impl Diagnostics for SumEditor {
-    fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
-        self.diag_port.outer()
-    }
-}
-
-impl Nested for SumEditor {}
-
-
diff --git a/nested/src/tree/node.rs b/nested/src/tree/node.rs
index 24e5b7e..35652da 100644
--- a/nested/src/tree/node.rs
+++ b/nested/src/tree/node.rs
@@ -7,17 +7,19 @@ use {
         sequence::SequenceView,
         terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult},
         diagnostics::{Diagnostics, Message},
-        tree::{TreeNav, TreeCursor, TreeNavResult}, ObjCommander,
+        tree::{TreeNav, TreeCursor, TreeNavResult},
+        ObjCommander,
         Nested
-    },
+    }
 };
 
+#[derive(Clone)]
 pub struct NestedNode {
-    ctx: Option<Arc<RwLock<Context>>>,
-    view: Option<OuterViewPort<dyn TerminalView>>,
-    diag: Option<OuterViewPort<dyn SequenceView<Item = Message>>>,
-    cmd: Option<Arc<RwLock<dyn ObjCommander + Send + Sync>>>,
-    tree_nav: Option<Arc<RwLock<dyn TreeNav + Send + Sync>>>,
+    pub ctx: Option<Arc<RwLock<Context>>>,
+    pub view: Option<OuterViewPort<dyn TerminalView>>,
+    pub diag: Option<OuterViewPort<dyn SequenceView<Item = Message>>>,
+    pub cmd: Option<Arc<RwLock<dyn ObjCommander + Send + Sync>>>,
+    pub tree_nav: Option<Arc<RwLock<dyn TreeNav + Send + Sync>>>,
 }
 
 impl ObjCommander for NestedNode {
@@ -111,11 +113,25 @@ impl NestedNode {
         self
     }
 
-    pub fn with_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self {
+    pub fn set_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self {
         self.cmd = Some(cmd);
         self
     }
 
+    pub fn set_nav(mut self, nav: Arc<RwLock<dyn TreeNav + Send + Sync>>) -> Self {
+        self.tree_nav = Some(nav);
+        self
+    }
+
+    pub fn set_diag(mut self, diag: OuterViewPort<dyn SequenceView<Item = Message>>) -> Self {
+        self.diag = Some(diag);
+        self
+    }
+
+    pub fn get_diag(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
+        self.diag.clone().unwrap_or(ViewPort::new().into_outer())
+    }
+    
     pub fn get_view(&self) -> OuterViewPort<dyn TerminalView> {
         self.view.clone().unwrap_or(ViewPort::new().into_outer())
     }
diff --git a/nested/src/type_term_editor.rs b/nested/src/type_term_editor.rs
index fc04d7e..19c555a 100644
--- a/nested/src/type_term_editor.rs
+++ b/nested/src/type_term_editor.rs
@@ -9,7 +9,8 @@ use {
         sum::SumEditor,
         char_editor::CharEditor,
         integer::PosIntEditor,
-        Nested
+        tree::NestedNode,
+        Commander, PtySegment
     },
     cgmath::{Vector2},
     termion::event::{Key},
@@ -27,128 +28,93 @@ enum TypeTermVar {
 }
 
 pub struct TypeTermEditor {
+    ctx: Arc<RwLock<Context>>,
     ty: TypeTermVar,
-    node: SumEditor,
+    sum_edit: Arc<RwLock<SumEditor>>
 }
 
 impl TypeTermEditor {
     pub fn new(ctx: Arc<RwLock<Context>>, depth: usize) -> Self {
         TypeTermEditor {
+            ctx: ctx.clone(),
             ty: TypeTermVar::Any,
-            node: SumEditor::new(
+            sum_edit: Arc::new(RwLock::new(SumEditor::new(
                 vec![
-                    Arc::new(RwLock::new(PTYListEditor::new(
-                        Box::new({
-                            let ctx = ctx.clone();
-                            move || {
-                                Arc::new(RwLock::new(TypeTermEditor::new(ctx.clone(), depth+1)))
-                            }
-                        }),
-                        SeqDecorStyle::HorizontalSexpr,
-                        Some(' '),
-                        depth
-                    ))),
-                    Arc::new(RwLock::new(PosIntEditor::new(10))),
-                    Arc::new(RwLock::new(PTYListEditor::new(
-                        Box::new({
-                            let ctx = ctx.clone();
-                            move || {
-                                Arc::new(RwLock::new(CharEditor::new_node(&ctx)))
-                            }
-                        }),
-                        SeqDecorStyle::Plain,
-                        None,
-                        depth
-                    ))),
-                ])
+                    Context::make_editor( &ctx, ctx.read().unwrap().type_term_from_str("( List TypeTerm 1 )").unwrap(), depth + 1).unwrap(),
+                    Context::make_editor( &ctx, ctx.read().unwrap().type_term_from_str("( PosInt 10 )").unwrap(), depth + 1 ).unwrap(),
+                    Context::make_editor( &ctx, ctx.read().unwrap().type_term_from_str("( Symbol )").unwrap(), depth + 1 ).unwrap()
+                ])))
         }
     }
-}
 
-impl TreeNav for TypeTermEditor {
-    fn get_cursor(&self) -> TreeCursor {
-        self.node.get_cursor()
-    }
-
-    fn get_cursor_warp(&self) -> TreeCursor {
-        self.node.get_cursor_warp()
-    }
-
-    fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult {
-        self.node.goby( direction )
-    }
-
-    fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult {
-        self.node.goto( new_cursor )
+    pub fn into_node(self) -> NestedNode {
+        NestedNode::new()
+            .set_ctx(self.ctx.clone())
+            .set_nav(self.sum_edit.clone())
+            .set_cmd(self.sum_edit.clone())
+            .set_view(
+                self.sum_edit.read().unwrap().pty_view()
+            )
     }
 }
 
-impl TerminalEditor for TypeTermEditor {
-    fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
-        self.node.get_term_view()
-    }
+impl Commander for TypeTermEditor {
+    type Cmd = TerminalEvent;
 
-    fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
+    fn send_cmd(&mut self, event: &TerminalEvent) {
         match event {
             TerminalEvent::Input( termion::event::Event::Key(Key::Char(c)) ) => {
                 match self.ty {
                     TypeTermVar::Any => {
                         self.ty =
                             if *c == '(' {
-                                self.node.select(0);
-                                self.dn();
+                                let mut se = self.sum_edit.write().unwrap();
+                                se.select(0);
+                                se.dn();
                                 TypeTermVar::List
                             } else if c.to_digit(10).is_some() {
-                                self.node.select(1);
-                                self.dn();
-                                self.node.handle_terminal_event( event );
+                                let mut se = self.sum_edit.write().unwrap();
+                                se.select(1);
+                                se.dn();
+                                se.send_cmd( event );
                                 TypeTermVar::Num
                             } else {
-                                self.node.select(2);
-                                self.dn();
-                                self.node.handle_terminal_event( event );
+                                let mut se = self.sum_edit.write().unwrap();
+                                se.select(2);
+                                se.dn();
+                                se.send_cmd( event );
                                 TypeTermVar::Symbol
                             };
-                        TerminalEditorResult::Continue
                     },
                     _ => {
                         if *c  == '(' {
                             let _child = Arc::new(RwLock::new(TypeTermEditor {
+                                ctx: self.ctx.clone(),
                                 ty: self.ty.clone(),
-                                node: SumEditor::new(
+                                sum_edit: Arc::new(RwLock::new(SumEditor::new(
                                     vec![
-                                        self.node.editors[0].clone(),
-                                        self.node.editors[1].clone(),
-                                        self.node.editors[2].clone(),
-                                    ])
+                                        self.sum_edit.read().unwrap().editors[0].clone(),
+                                        self.sum_edit.read().unwrap().editors[1].clone(),
+                                        self.sum_edit.read().unwrap().editors[2].clone(),
+                                    ])))
                             }));
-
                             self.ty = TypeTermVar::List;
-                            self.node.select(0);
+                            self.sum_edit.write().unwrap().select(0);
 /*
                             let l = self.node.editors[0].clone();
                             let l = l.downcast::<RwLock<PTYListEditor<TypeTermEditor>>>().unwrap();
                             l.write().unwrap().data.push(child);
                             */
-                            TerminalEditorResult::Continue
                         } else {
-                            self.node.handle_terminal_event( event )
+                            self.sum_edit.write().unwrap().send_cmd( event );
                         }
                     }
                 }
             },
             event => {
-                self.node.handle_terminal_event( event )
+                self.sum_edit.write().unwrap().send_cmd( event );
             }
         }
     }
 }
 
-impl Diagnostics for TypeTermEditor {
-    fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
-        self.node.get_msg_port()
-    }
-}
-
-impl Nested for TypeTermEditor {}
-
diff --git a/nested/src/vec/buffer.rs b/nested/src/vec/buffer.rs
index 9c91009..77116c6 100644
--- a/nested/src/vec/buffer.rs
+++ b/nested/src/vec/buffer.rs
@@ -55,7 +55,7 @@ where
     pub fn new() -> Self {
         VecBuffer::with_port(ViewPort::new().into_inner())
     }
-    
+
     pub fn get_port(&self) -> OuterViewPort<RwLock<Vec<T>>> {
         self.port.0.outer()
     }
diff --git a/shell/src/main.rs b/shell/src/main.rs
index de6bab5..05d9eac 100644
--- a/shell/src/main.rs
+++ b/shell/src/main.rs
@@ -13,7 +13,7 @@ use {
         core::{port::UpdateTask, Observer, AnyOuterViewPort, ViewPort, Context, ReprTree},
         index::IndexArea,
         list::{ListCursorMode, PTYListEditor},
-        sequence::{decorator::{SeqDecorStyle}},
+        sequence::{decorator::{SeqDecorStyle, Separate}},
         terminal::{
             make_label, Terminal, TerminalAtom, TerminalCompositor, TerminalEditor,
             TerminalEditorResult, TerminalEvent, TerminalStyle,
@@ -21,7 +21,8 @@ use {
         tree::{TreeNav, TreeCursor, TreeNavResult},
         vec::VecBuffer,
         diagnostics::{Diagnostics},
-        index::{buffer::IndexBuffer}
+        index::{buffer::IndexBuffer},
+        Commander
     },
     std::sync::{Arc, RwLock},
     termion::event::{Event, Key},
@@ -60,7 +61,7 @@ async fn main() {
 
     let vb = VecBuffer::<char>::new();
     let rt_char = ReprTree::new_leaf(
-        ctx.read().unwrap().type_term_from_str("( List Char )").unwrap(),
+        ctx.read().unwrap().type_term_from_str("( List Char 0 )").unwrap(),
         AnyOuterViewPort::from(vb.get_port())
     );
     let rt_digit = ReprTree::upcast(&rt_char, ctx.read().unwrap().type_term_from_str("( List ( Digit 10 ) )").unwrap());
@@ -96,19 +97,16 @@ async fn main() {
     let c = ctx.clone();
     let mut process_list_editor =
         PTYListEditor::new(
-            Box::new( move || {
-                Arc::new(RwLock::new(nested::type_term_editor::TypeTermEditor::new(c.clone(), 1)))
-//                Arc::new(RwLock::new(CharEditor::new_node(&c)))
-                //Context::make_editor( c.clone(), c.read().unwrap().type_term_from_str("( String )").unwrap(), 1 ).unwrap()
-            }),
+            ctx.clone(),
+            c.read().unwrap().type_term_from_str("( List Path 1 )").unwrap(),
             SeqDecorStyle::Plain,
             Some('\n'),
-            0
-);
+            3
+        );
 
     async_std::task::spawn(async move {
         let mut table = nested::index::buffer::IndexBuffer::new();
-        
+
         let magic =
             make_label("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>")
             .map_item(|pos, atom| {
@@ -131,7 +129,8 @@ async fn main() {
             (Point2::new(0, 2), magic.clone()),
             (Point2::new(0, 3), make_label(" ")),
             (Point2::new(0, 4),
-             process_list_editor.editor
+             process_list_editor
+             .editor.read().unwrap()
              .get_seg_seq_view()
              .enumerate()
              .map(
@@ -158,7 +157,6 @@ async fn main() {
                      buf.get_port()
                  }
              )
-             /*
              .separate({
                  let mut buf = IndexBuffer::new();
                  buf.insert(Point2::new(1,0),
@@ -169,9 +167,7 @@ async fn main() {
                             )
                  );
                  buf.get_port()
-             }
-            )
-             */
+             })
              .to_grid_vertical()
              .flatten()
              .flatten()
@@ -180,7 +176,7 @@ async fn main() {
             (Point2::new(0, 5), make_label(" ")),
             (Point2::new(0, 6), magic.clone()),
 
-            (Point2::new(0, 7), process_list_editor.get_msg_port().map(
+            (Point2::new(0, 7), process_list_editor.diag.map(
                 |entry| {
                     let mut b = VecBuffer::new();
                     b.push(
@@ -234,7 +230,7 @@ async fn main() {
             .unwrap()
             .push(table.get_port().flatten().offset(Vector2::new(3, 0)));
 
-        process_list_editor.goto(TreeCursor {
+        process_list_editor.editor.write().unwrap().goto(TreeCursor {
             leaf_mode: ListCursorMode::Insert,
             tree_addr: vec![0],
         });
@@ -269,54 +265,50 @@ async fn main() {
             match ev {
                 TerminalEvent::Input(Event::Key(Key::Ctrl('d'))) => break,
                 TerminalEvent::Input(Event::Key(Key::Ctrl('l'))) => {
-                    process_list_editor.goto(TreeCursor {
+                    process_list_editor.editor.write().unwrap().goto(TreeCursor {
                         leaf_mode: ListCursorMode::Insert,
                         tree_addr: vec![0],
                     });
                     //process_list_editor.clear();
                 }
                 TerminalEvent::Input(Event::Key(Key::Left)) => {
-                    process_list_editor.pxev();
+                    process_list_editor.editor.write().unwrap().pxev();
                 }
                 TerminalEvent::Input(Event::Key(Key::Right)) => {
-                    process_list_editor.nexd();
+                    process_list_editor.editor.write().unwrap().nexd();
                 }
                 TerminalEvent::Input(Event::Key(Key::Up)) => {
-                    if process_list_editor.up() == TreeNavResult::Exit {
-                        process_list_editor.dn();
+                    if process_list_editor.editor.write().unwrap().up() == TreeNavResult::Exit {
+                        process_list_editor.editor.write().unwrap().dn();
                     }
                 }
                 TerminalEvent::Input(Event::Key(Key::Down)) => {
-                    process_list_editor.dn();
+                    process_list_editor.editor.write().unwrap().dn();
                     // == TreeNavResult::Continue {
                         //process_list_editor.goto_home();
                     //}
                 }
                 TerminalEvent::Input(Event::Key(Key::Home)) => {
-                    process_list_editor.qpxev();
+                    process_list_editor.editor.write().unwrap().qpxev();
                 }
                 TerminalEvent::Input(Event::Key(Key::End)) => {
-                    process_list_editor.qnexd();
+                    process_list_editor.editor.write().unwrap().qnexd();
                 }
                 TerminalEvent::Input(Event::Key(Key::Char('\t'))) => {
-                    let mut c = process_list_editor.get_cursor();
+                    let mut c = process_list_editor.editor.read().unwrap().get_cursor();
                     c.leaf_mode = match c.leaf_mode {
                         ListCursorMode::Select => ListCursorMode::Insert,
                         ListCursorMode::Insert => ListCursorMode::Select
                     };
-                    process_list_editor.goto(c);
+                    process_list_editor.editor.write().unwrap().goto(c);
                 }
                 ev => {
-                    if let TerminalEditorResult::Exit =
-                        process_list_editor.handle_terminal_event(&ev)
-                    {
-                        //process_list_editor.nexd();
-                    }
+                    process_list_editor.send_cmd(&ev);
                 }
             }
 
             status_chars.clear();
-            let cur = process_list_editor.get_cursor();
+            let cur = process_list_editor.editor.read().unwrap().get_cursor();
 
             if cur.tree_addr.len() > 0 {
                 status_chars.push(TerminalAtom::new(