From 603034a06506e027321d5ed672829424afcd5d00 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Sun, 15 Aug 2021 04:27:09 +0200
Subject: [PATCH] TreeNav trait

adapt ListEditor and StringEditor
---
 nested/src/lib.rs           |   2 +
 nested/src/list/editor.rs   | 370 ++++++++++++++++++++++++------------
 nested/src/string_editor.rs | 146 ++++++++------
 nested/src/tree_nav.rs      |  41 ++++
 shell/src/main.rs           |  42 ++--
 5 files changed, 393 insertions(+), 208 deletions(-)
 create mode 100644 nested/src/tree_nav.rs

diff --git a/nested/src/lib.rs b/nested/src/lib.rs
index 67d33e4..7967491 100644
--- a/nested/src/lib.rs
+++ b/nested/src/lib.rs
@@ -12,6 +12,8 @@ pub mod terminal;
 pub mod integer;
 pub mod list;
 
+pub mod tree_nav;
+
 pub mod string_editor;
 pub mod leveled_term_view;
 
diff --git a/nested/src/list/editor.rs b/nested/src/list/editor.rs
index c4af949..f118b17 100644
--- a/nested/src/list/editor.rs
+++ b/nested/src/list/editor.rs
@@ -18,6 +18,7 @@ use {
                 Context
             }
         },
+        tree_nav::{TreeNav, TreeNavResult, TerminalTreeEditor},
         projection::ProjectionHelper,
         singleton::{SingletonView, SingletonBuffer},
         sequence::{SequenceView},
@@ -62,8 +63,221 @@ where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static,
     segment_seq: OuterViewPort<dyn SequenceView<Item = ListEditorViewSegment>>,
 }
 
+
+impl<SubEditor, FnMakeItemEditor> TreeNav for ListEditor<SubEditor, FnMakeItemEditor>
+where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static,
+      FnMakeItemEditor: Fn() -> Arc<RwLock<SubEditor>>
+{
+    fn up(&mut self) -> TreeNavResult {
+        match self.cursor.get() {
+            ListEditorCursor::Edit(idx) => {
+                let ce = self.data.get_mut(idx);
+                let mut cur_edit = ce.write().unwrap();
+
+                match cur_edit.up() {
+                    TreeNavResult::Exit => {
+                        self.cursor.set(ListEditorCursor::Select(idx));
+                    }
+                    TreeNavResult::Continue => {}
+                }
+                TreeNavResult::Continue
+            }
+            _ => {
+                self.cursor.set(ListEditorCursor::None);
+                TreeNavResult::Exit
+            }
+        }
+    }
+
+    fn goto(&mut self, tree_addr: Vec<usize>) -> TreeNavResult {
+        if tree_addr.len() == 1 {
+            if tree_addr[0] < self.data.len() {
+                match self.cursor.get() {
+                    ListEditorCursor::None |
+                    ListEditorCursor::Select(_) => {
+                        self.cursor.set(ListEditorCursor::Select(tree_addr[0]));
+                    }
+                    ListEditorCursor::Insert(_) => {
+                        self.cursor.set(ListEditorCursor::Insert(tree_addr[0]));
+                    }
+                    ListEditorCursor::Edit(_) => {
+                        self.cursor.set(ListEditorCursor::Edit(tree_addr[0]));
+                    }
+                }
+                TreeNavResult::Continue
+            } else {
+                TreeNavResult::Exit
+            }                    
+        } else if tree_addr.len() > 0 {
+            if tree_addr[0] < self.data.len() {
+                self.cursor.set(ListEditorCursor::Edit(tree_addr[0]));
+
+                let ce = self.data.get_mut(tree_addr[0]);
+                let mut cur_edit = ce.write().unwrap();
+
+                cur_edit.goto(tree_addr[1..].iter().cloned().collect());
+
+                TreeNavResult::Continue
+            } else {
+                TreeNavResult::Exit
+            }
+        } else {
+            self.cursor.set(ListEditorCursor::None);
+            TreeNavResult::Exit
+        }
+    }
+
+    fn goto_end(&mut self) -> TreeNavResult {
+        match self.cursor.get() {
+            ListEditorCursor::None |
+            ListEditorCursor::Insert(_) | 
+            ListEditorCursor::Select(_) =>
+                self.goto(vec![ self.data.len()-1 ]),
+            ListEditorCursor::Edit(idx) => {
+                let ce = self.data.get_mut(idx);
+                let mut cur_edit = ce.write().unwrap();
+
+                match cur_edit.goto_end() {
+                    TreeNavResult::Continue => TreeNavResult::Continue,
+                    TreeNavResult::Exit => {
+                        if idx+1 < self.data.len() {
+                            self.cursor.set(ListEditorCursor::Edit(idx+1));
+                            self.data.get_mut(idx+1).write().unwrap().goto_end();
+                            TreeNavResult::Continue
+                        } else {
+                            self.cursor.set(ListEditorCursor::None);
+                            TreeNavResult::Exit
+                        }
+                    }
+                }                
+            }
+        }
+    }
+
+    fn goto_home(&mut self) -> TreeNavResult {
+        match self.cursor.get() {
+            ListEditorCursor::None |
+            ListEditorCursor::Insert(_) | 
+            ListEditorCursor::Select(_) => self.goto(vec![ 0 ]),
+            ListEditorCursor::Edit(idx) => {
+                let ce = self.data.get_mut(idx);
+                let mut cur_edit = ce.write().unwrap();
+
+                match cur_edit.goto_home() {
+                    TreeNavResult::Continue => TreeNavResult::Continue,
+                    TreeNavResult::Exit => {
+                        if idx > 0 {
+                            self.cursor.set(ListEditorCursor::Edit(idx-1));
+                            self.data.get_mut(idx-1).write().unwrap().goto_home();
+                            TreeNavResult::Continue
+                        } else {
+                            self.cursor.set(ListEditorCursor::None);
+                            TreeNavResult::Exit
+                        }
+                    }
+                }
+            }
+            _ => {
+                self.up();
+                TreeNavResult::Exit
+            }
+        }
+    }
+
+    fn dn(&mut self) -> TreeNavResult {
+        match self.cursor.get() {
+            ListEditorCursor::Select(idx) => {
+                self.data.get_mut(idx).write().unwrap().goto_home();
+                self.cursor.set(ListEditorCursor::Edit(idx));
+            }
+            _ => {}
+        }
+        TreeNavResult::Continue
+    }
+
+    fn pxev(&mut self) -> TreeNavResult {
+        match self.cursor.get() {
+            ListEditorCursor::None => TreeNavResult::Exit,
+            ListEditorCursor::Insert(idx) => {
+                if idx > 0 {
+                    self.cursor.set(ListEditorCursor::Insert(idx-1));
+                    TreeNavResult::Continue
+                } else {
+                    self.cursor.set(ListEditorCursor::None);
+                    TreeNavResult::Exit
+                }
+            }
+            ListEditorCursor::Select(idx) => {
+                if idx > 0 {
+                    self.cursor.set(ListEditorCursor::Select(idx-1));
+                    TreeNavResult::Continue
+                } else {
+                    self.cursor.set(ListEditorCursor::None);
+                    TreeNavResult::Exit
+                }
+            }
+            ListEditorCursor::Edit(idx) => {
+                let ce = self.data.get_mut(idx);
+                let mut cur_edit = ce.write().unwrap();
+
+                match cur_edit.pxev() {
+                    TreeNavResult::Exit => {
+                        if idx > 0 {
+                            self.cursor.set(ListEditorCursor::Edit(idx-1));
+                            self.data.get_mut(idx-1).write().unwrap().goto_end();
+                            TreeNavResult::Continue
+                        } else {
+                            TreeNavResult::Exit
+                        }
+                    }
+                    TreeNavResult::Continue => TreeNavResult::Continue
+                }
+            }
+        }
+    }
+
+    fn nexd(&mut self) -> TreeNavResult {
+        match self.cursor.get() {
+            ListEditorCursor::None => TreeNavResult::Exit,
+            ListEditorCursor::Insert(idx) => {
+                if idx < self.data.len() {
+                    self.cursor.set(ListEditorCursor::Insert(idx+1));
+                    TreeNavResult::Continue
+                } else {
+                    TreeNavResult::Exit
+                }
+            }
+            ListEditorCursor::Select(idx) => {
+                if idx+1 < self.data.len() {
+                    self.cursor.set(ListEditorCursor::Select(idx + 1));
+                    TreeNavResult::Continue
+                } else {
+                    TreeNavResult::Exit
+                }
+            }
+            ListEditorCursor::Edit(idx) => {
+                let ce = self.data.get_mut(idx);
+                let mut cur_edit = ce.write().unwrap();
+
+                match cur_edit.nexd() {
+                    TreeNavResult::Exit => {
+                        if idx+1 < self.data.len() {
+                            self.cursor.set(ListEditorCursor::Edit(idx+1));
+                            self.data.get_mut(idx+1).write().unwrap().goto_home();
+                            TreeNavResult::Continue
+                        } else {//if idx+1 == self.data.len() {
+                            TreeNavResult::Exit
+                        }
+                    }
+                    TreeNavResult::Continue => TreeNavResult::Continue
+                }
+            }
+        }
+    }
+}
+
 impl<SubEditor, FnMakeItemEditor> TerminalEditor for ListEditor<SubEditor, FnMakeItemEditor>
-where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static,
+where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static,
       FnMakeItemEditor: Fn() -> Arc<RwLock<SubEditor>>
 {
     fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
@@ -72,144 +286,51 @@ where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static,
 
     fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
         match self.cursor.get() {
-            ListEditorCursor::None => {
-                
-            }
             ListEditorCursor::Insert(idx) => {
+                self.data.insert(idx, (self.make_item_editor)());
+
+                let mut ce = self.data.get_mut(idx);
+                let mut cur_edit = ce.write().unwrap();
+
+                cur_edit.goto_home();
+                self.cursor.set(ListEditorCursor::Edit(idx));
+                cur_edit.handle_terminal_event(event);
+            }
+            ListEditorCursor::Edit(idx) => {
                 match event {
-                    TerminalEvent::Input(Event::Key(Key::Insert)) => {
-                        self.cursor.set(ListEditorCursor::Select(idx));
-                    }
-                    TerminalEvent::Input(Event::Key(Key::Left)) => {
-                        if idx > 0 {
-                            self.cursor.set(ListEditorCursor::Insert(idx-1));
-                        }
-                    }
-                    TerminalEvent::Input(Event::Key(Key::Right)) => {
-                        if idx < self.data.len() {
-                            self.cursor.set(ListEditorCursor::Insert(idx+1));
-                        }
+                    TerminalEvent::Input(Event::Key(Key::Char(' '))) => {
+                        // split..
+                        self.data.insert(idx+1, (self.make_item_editor)());
+                        self.data.get_mut(idx).write().unwrap().goto_end();
+                        self.data.get_mut(idx+1).write().unwrap().goto_home();
+                        self.cursor.set(ListEditorCursor::Edit(idx+1));
                     }
                     event => {
-                        self.data.insert(idx, (self.make_item_editor)());
-                        self.cursor.set(ListEditorCursor::Edit(idx));
-                        self.data.get_mut(idx).write().unwrap().handle_terminal_event(event);
+                        let mut ce = self.data.get_mut(idx);
+                        let mut cur_edit = ce.write().unwrap();
+
+                        cur_edit.handle_terminal_event(event);
                     }
                 }
             }
             ListEditorCursor::Select(idx) => {
                 match event {
                     TerminalEvent::Input(Event::Key(Key::Insert)) => {
-                        self.cursor.set(ListEditorCursor::Insert(idx));
+                        
                     }
                     TerminalEvent::Input(Event::Key(Key::Delete)) => {
                         self.data.remove(idx);
+
                         if self.data.len() == 0 {
                             self.cursor.set(ListEditorCursor::Insert(0));
-                        } else if idx == self.data.len() && idx > 0 {
-                            self.cursor.set(ListEditorCursor::Select(idx-1))
-                        }
-                    }
-                    TerminalEvent::Input(Event::Key(Key::Home)) => {
-                        if self.data.len() > 0 {
-                            self.cursor.set(ListEditorCursor::Select(0))
-                        } else {
-                            self.cursor.set(ListEditorCursor::Insert(0))
-                        }
-                    }
-                    TerminalEvent::Input(Event::Key(Key::End)) => {
-                        if self.data.len() > 0 {
-                            self.cursor.set(ListEditorCursor::Select(self.data.len() - 1))
-                        } else {
-                            self.cursor.set(ListEditorCursor::Insert(0))
-                        }
-                    }
-                    TerminalEvent::Input(Event::Key(Key::Left)) => {
-                        if idx > 0 {
-                            self.cursor.set(ListEditorCursor::Select(idx - 1));
-                        }
-                    }
-                    TerminalEvent::Input(Event::Key(Key::Right)) => {
-                        if idx+1 < self.data.len() {
-                            self.cursor.set(ListEditorCursor::Select(idx + 1));
-                        }
-                    }
-                    event => {
-                        self.cursor.set(ListEditorCursor::Edit(idx));
-                        self.data.get_mut(idx).write().unwrap().handle_terminal_event(event);
-                    }
-                }
-            }
-            ListEditorCursor::Edit(idx) => {
-                match event {
-                    TerminalEvent::Input(Event::Key(Key::Char('\t'))) => {
-                        if idx > 0 {
-                            self.cursor.set(ListEditorCursor::Edit(idx-1));
-                        }
-                    }
-                    TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
-                        if idx+1 < self.data.len() {
-                            self.cursor.set(ListEditorCursor::Edit(idx+1));
-                        }
-                    }
-                    TerminalEvent::Input(Event::Key(Key::Char(' '))) => {
-                        // split..
-                        self.data.insert(idx+1, (self.make_item_editor)());
-                        self.data.get_mut(idx).write().unwrap().handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::End)));
-                        self.data.get_mut(idx+1).write().unwrap().handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Home)));
-                        self.cursor.set(ListEditorCursor::Edit(idx+1));
-                    }
-                    event => {
-                        let ce = self.data.get_mut(idx);
-                        let mut cur_edit = ce.write().unwrap();
-                        match cur_edit.handle_terminal_event(event) {
-                            TerminalEditorResult::Exit => {
-                                match event {
-                                    TerminalEvent::Input(Event::Key(Key::Up)) => {
-                                        self.cursor.set(ListEditorCursor::Select(idx));
-                                    }
-                                    TerminalEvent::Input(Event::Key(Key::Home)) => {
-                                        if idx > 0 {
-                                            self.cursor.set(ListEditorCursor::Edit(idx-1));
-                                            self.data.get_mut(idx-1).write().unwrap().handle_terminal_event(event);
-                                        } else {
-                                            cur_edit.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Home)));
-                                        }
-                                    }
-                                    TerminalEvent::Input(Event::Key(Key::Backspace)) | // -> join
-                                    TerminalEvent::Input(Event::Key(Key::Left)) => {
-                                        if idx > 0 {
-                                            self.cursor.set(ListEditorCursor::Edit(idx-1));
-                                            self.data.get_mut(idx-1).write().unwrap().handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::End)));
-                                        } else {
-                                            cur_edit.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Home)));
-                                        }
-                                    }
-                                    TerminalEvent::Input(Event::Key(Key::End)) => {
-                                        if idx+1 < self.data.len() {
-                                            self.cursor.set(ListEditorCursor::Edit(idx+1));
-                                            self.data.get_mut(idx+1).write().unwrap().handle_terminal_event(event);
-                                        } else if idx+1 == self.data.len() {
-                                            cur_edit.handle_terminal_event(event);
-                                        }
-                                    }
-                                    TerminalEvent::Input(Event::Key(Key::Delete)) |
-                                    TerminalEvent::Input(Event::Key(Key::Right)) => {
-                                        if idx+1 < self.data.len() {
-                                            self.cursor.set(ListEditorCursor::Edit(idx+1));
-                                            self.data.get_mut(idx+1).write().unwrap().handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Home)));
-                                        } else if idx+1 == self.data.len() {
-                                            cur_edit.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::End)));
-                                        }
-                                    }
-                                    _ => {}
-                                }
-                            }
-                            TerminalEditorResult::Continue => {}
+                        } else if idx == self.data.len() {
+                            self.cursor.set(ListEditorCursor::Select(idx-1));
                         }
                     }
+                    _=>{}
                 }
             }
+            _ => {}
         }
 
         TerminalEditorResult::Continue
@@ -404,10 +525,15 @@ where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static,
     pub fn vertical_sexpr_view(&self) -> OuterViewPort<dyn TerminalView> {
         self.get_seg_seq_view().vertical_sexpr_view(0)
     }
-
     pub fn path_view(&self) -> OuterViewPort<dyn TerminalView> {
         self.get_seg_seq_view()
-            .decorate("<", ">", "/", 1)
+            .decorate("<", ">", "/", 0)
+            .to_grid_horizontal()
+            .flatten()
+    }
+    pub fn string_view(&self) -> OuterViewPort<dyn TerminalView> {
+        self.get_seg_seq_view()
+            .decorate("\"", "\"", "", 1)
             .to_grid_horizontal()
             .flatten()
     }
diff --git a/nested/src/string_editor.rs b/nested/src/string_editor.rs
index d3ac128..e47fe28 100644
--- a/nested/src/string_editor.rs
+++ b/nested/src/string_editor.rs
@@ -5,7 +5,8 @@ use {
         core::{ViewPort, OuterViewPort},
         singleton::{SingletonView, SingletonBuffer},
         vec::VecBuffer,
-        terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult}
+        terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult},
+        tree_nav::{TreeNav, TreeNavResult}
     }
 };
 
@@ -53,56 +54,89 @@ impl StringEditor {
         self.cursor_port.outer()
     }
 
-    pub fn goto(&mut self, new_pos: usize) -> TerminalEditorResult {
-        if new_pos <= self.data.len() {
-            self.cursor.set(Some(new_pos));
-            TerminalEditorResult::Continue
-        } else {
-            self.cursor.set(None);
-            TerminalEditorResult::Exit
-        }
-    }
-
-    pub fn goto_end(&mut self) -> TerminalEditorResult {
-        self.goto(self.data.len())
-    }
-
-    pub fn prev(&mut self) -> TerminalEditorResult {
-        let cur = self.cursor.get().unwrap_or(usize::MAX);
-        if cur > 0 {
-            self.cursor.set(Some(cur - 1));
-            TerminalEditorResult::Continue
-        } else {
-            self.cursor.set(None);
-            TerminalEditorResult::Exit
-        }
-    }
-
-    pub fn next(&mut self) -> TerminalEditorResult {
-        self.goto(self.cursor.get().unwrap_or(0) + 1)
-    }
-
-    pub fn insert(&mut self, c: char) -> TerminalEditorResult {
+    pub fn insert(&mut self, c: char) -> TreeNavResult {
         self.data.insert(self.cursor.get().unwrap_or(0), c);
-        self.next()
+        self.nexd()
     }
 
-    pub fn delete_prev(&mut self) -> TerminalEditorResult {
+    pub fn delete_prev(&mut self) -> TreeNavResult {
         let cur = self.cursor.get().unwrap_or(0);
         if cur <= self.data.len() && cur > 0 {
             self.data.remove(cur-1);
         }
-        self.prev()
+        self.pxev()
     }
 
-    pub fn delete(&mut self) -> TerminalEditorResult {
+    pub fn delete(&mut self) -> TreeNavResult {
         let cur = self.cursor.get().unwrap_or(0);
         if cur < self.data.len() {
             self.data.remove(cur);
-            TerminalEditorResult::Continue
+            TreeNavResult::Continue
         } else {
             self.cursor.set(None);
-            TerminalEditorResult::Exit
+            TreeNavResult::Exit
+        }
+    }
+}
+
+impl TreeNav for  StringEditor {
+    fn goto(&mut self, tree_pos: Vec<usize>) -> TreeNavResult {
+        if tree_pos.len() == 1 {
+            let new_pos = tree_pos[0];
+            if new_pos <= self.data.len() {
+                self.cursor.set(Some(new_pos));
+                TreeNavResult::Continue
+            } else {
+                self.cursor.set(None);
+                TreeNavResult::Exit
+            }
+        } else {
+            self.cursor.set(None);            
+            TreeNavResult::Exit
+        }
+    }
+
+    fn pxev(&mut self) -> TreeNavResult {
+        let cur = self.cursor.get().unwrap_or(usize::MAX);
+        if cur > 0 {
+            self.cursor.set(Some(cur - 1));
+            TreeNavResult::Continue
+        } else {
+            self.cursor.set(None);
+            TreeNavResult::Exit
+        }        
+    }
+
+    fn nexd(&mut self) -> TreeNavResult {
+        self.goto(vec![ self.cursor.get().unwrap_or(0) + 1 ])
+    }
+
+    fn goto_end(&mut self) -> TreeNavResult {
+        if self.cursor.get() == Some(self.data.len()) {
+            self.up()
+        } else {
+            self.goto(vec![ self.data.len() ])
+        }
+    }
+
+    fn goto_home(&mut self) -> TreeNavResult {
+        if self.cursor.get() == Some(0) {
+            self.up()
+        } else {
+            self.goto(vec![ 0 ])
+        }
+    }
+
+    fn up(&mut self) -> TreeNavResult {
+        self.cursor.set(None);
+        TreeNavResult::Exit
+    }
+
+    fn dn(&mut self) -> TreeNavResult {
+        if self.cursor.get() == Some(0) {
+            self.up()
+        } else {
+            self.goto(vec![0])
         }
     }
 }
@@ -114,33 +148,19 @@ impl TerminalEditor for StringEditor {
 
     fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
         match event {
-            TerminalEvent::Input(Event::Key(Key::Left)) => self.prev(),
-            TerminalEvent::Input(Event::Key(Key::Right)) => self.next(),
-
-            TerminalEvent::Input(Event::Key(Key::Up)) => {
-                self.cursor.set(None);
-                TerminalEditorResult::Exit
-            }
-            
-            TerminalEvent::Input(Event::Key(Key::Down)) |
-            TerminalEvent::Input(Event::Key(Key::Home)) =>
-                if self.cursor.get() == Some(0) {
-                    self.cursor.set(None);
-                    TerminalEditorResult::Exit
-                } else {
-                    self.goto(0)
-                },
-            TerminalEvent::Input(Event::Key(Key::End)) =>
-                if self.cursor.get() == Some(self.data.len()) {
-                    self.cursor.set(None);
-                    TerminalEditorResult::Exit
-                } else {
-                    self.goto_end()
-                },
             TerminalEvent::Input(Event::Key(Key::Char('\n'))) => TerminalEditorResult::Continue,
-            TerminalEvent::Input(Event::Key(Key::Char(c))) => self.insert(*c),
-            TerminalEvent::Input(Event::Key(Key::Delete)) => self.delete(),
-            TerminalEvent::Input(Event::Key(Key::Backspace)) => self.delete_prev(),
+            TerminalEvent::Input(Event::Key(Key::Char(c))) => match self.insert(*c) {
+                TreeNavResult::Exit => TerminalEditorResult::Exit,
+                TreeNavResult::Continue => TerminalEditorResult::Continue
+            }
+            TerminalEvent::Input(Event::Key(Key::Delete)) => match self.delete()  {
+                TreeNavResult::Exit => TerminalEditorResult::Exit,
+                TreeNavResult::Continue => TerminalEditorResult::Continue
+            }
+            TerminalEvent::Input(Event::Key(Key::Backspace)) => match self.delete_prev() {
+                TreeNavResult::Exit => TerminalEditorResult::Exit,
+                TreeNavResult::Continue => TerminalEditorResult::Continue
+            }
             _ => TerminalEditorResult::Continue
         }
     }
diff --git a/nested/src/tree_nav.rs b/nested/src/tree_nav.rs
new file mode 100644
index 0000000..a9174a0
--- /dev/null
+++ b/nested/src/tree_nav.rs
@@ -0,0 +1,41 @@
+
+#[derive(Eq, PartialEq)]
+pub enum TreeNavResult {
+    Continue,
+    Exit
+}
+
+pub trait TreeNav {
+    fn up(&mut self) -> TreeNavResult {
+        TreeNavResult::Exit
+    }
+
+    fn dn(&mut self) -> TreeNavResult {
+        TreeNavResult::Exit
+    }
+
+    fn pxev(&mut self) -> TreeNavResult {
+        TreeNavResult::Exit
+    }
+
+    fn nexd(&mut self) -> TreeNavResult {
+        TreeNavResult::Exit
+    }
+
+    fn goto_home(&mut self) -> TreeNavResult {
+        TreeNavResult::Exit        
+    }
+
+    fn goto_end(&mut self) -> TreeNavResult {
+        TreeNavResult::Exit        
+    }
+    
+    fn goto(&mut self, tree_addr: Vec<usize>)  -> TreeNavResult {
+        TreeNavResult::Exit
+    }
+}
+
+use crate::terminal::{TerminalView, TerminalEditor};
+
+pub trait TerminalTreeEditor = TerminalEditor + TreeNav;
+
diff --git a/shell/src/main.rs b/shell/src/main.rs
index b75a377..a7d3cbf 100644
--- a/shell/src/main.rs
+++ b/shell/src/main.rs
@@ -28,6 +28,7 @@ use{
             TerminalView,
             TerminalEditor},
         string_editor::StringEditor,
+        tree_nav::{TreeNav, TreeNavResult, TerminalTreeEditor},
         list::{SExprView, ListEditor}
     }
 };
@@ -297,25 +298,8 @@ write::
             let cur_size_port = ViewPort::new();
             let mut cur_size = nested::singleton::SingletonBuffer::new(Vector2::new(10, 10), cur_size_port.inner());
 
-            {
-//                let history_port = ViewPort::new();
-//                let mut history = VecBuffer::new(history_port.inner());
-/*
-                compositor.write().unwrap().push(
-                    history_port.into_outer()
-                        .to_sequence()
-                        .map(
-                            |
-                        )
-                        .to_grid_vertical()
-                        .flatten()
-                        .offset(Vector2::new(45, 5))
-                );
-*/
-            };
             let mut y = 5;
 
-
             // TypeEditor
 
             let make_sub_editor = || {
@@ -346,6 +330,22 @@ write::
                     TerminalEvent::Input(Event::Key(Key::Ctrl('c'))) |
                     TerminalEvent::Input(Event::Key(Key::Ctrl('g'))) |
                     TerminalEvent::Input(Event::Key(Key::Ctrl('d'))) => break,
+
+                    TerminalEvent::Input(Event::Key(Key::Left)) => {
+                        if te.pxev() == TreeNavResult::Exit {
+                            te.goto_home();
+                        }
+                    }
+                    TerminalEvent::Input(Event::Key(Key::Right)) => {
+                        if te.nexd() == TreeNavResult::Exit {
+                            te.goto_end();
+                        }
+                    }
+                    TerminalEvent::Input(Event::Key(Key::Up)) => { te.up(); }
+                    TerminalEvent::Input(Event::Key(Key::Down)) => { te.dn(); }
+                    TerminalEvent::Input(Event::Key(Key::Home)) => { te.goto_home(); }
+                    TerminalEvent::Input(Event::Key(Key::End)) => { te.goto_end(); }
+
                     TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
                         let mut strings = Vec::new();
 
@@ -398,12 +398,8 @@ write::
                             y+=1;
                         }
 
-                        te.handle_terminal_event(
-                            &TerminalEvent::Input(Event::Key(Key::Up))
-                        );
-                        te.handle_terminal_event(
-                            &TerminalEvent::Input(Event::Key(Key::Home))
-                        );
+                        te.up();
+                        te.goto_home();
                         te = ListEditor::new(make_sub_editor.clone());
 
                         compositor.write().unwrap().push(magic.offset(Vector2::new(40, y)));