From 4acce3921ded5bddd781687c7f4725bdebdcb31a Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Fri, 24 Feb 2023 19:26:46 +0100
Subject: [PATCH] ObjCommander: return TreeNavResult

---
 nested/src/commander.rs               | 18 ++++----
 nested/src/editors/char/mod.rs        | 23 ++--------
 nested/src/editors/integer/editor.rs  | 32 +++++++-------
 nested/src/editors/list/editor.rs     |  4 +-
 nested/src/editors/list/pty_editor.rs | 60 +++++++++++++++++++++------
 nested/src/editors/product/editor.rs  |  8 +++-
 nested/src/editors/sum/editor.rs      | 12 ++----
 nested/src/tree/node.rs               |  6 ++-
 nested/src/type_system/make_editor.rs |  3 +-
 9 files changed, 91 insertions(+), 75 deletions(-)

diff --git a/nested/src/commander.rs b/nested/src/commander.rs
index 2dee032..88c3065 100644
--- a/nested/src/commander.rs
+++ b/nested/src/commander.rs
@@ -8,25 +8,20 @@ pub trait Commander {
 use std::sync::{Arc, RwLock};
 use crate::{
     type_system::ReprTree,
-    tree::{nav::TreeNavResult, NestedNode}
+    tree::{nav::TreeNavResult}
 };
 
 //use r3vi::view::singleton::*;
 
 pub trait ObjCommander {
-
-    fn send_cmd_node(&mut self, node: NestedNode) -> TreeNavResult {
-        TreeNavResult::Continue
-    }
-
-    fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>);
+    fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult;
 }
-
+/*
 //impl<Cmd: 'static, T: Commander<Cmd>> ObjCommander for T {
 impl<C: Commander> ObjCommander for C
 where C::Cmd: 'static
 {
-    fn send_cmd_obj(&mut self, _cmd_obj: Arc<RwLock<ReprTree>>) {
+    fn send_cmd_obj(&mut self, _cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult{
         /*
         self.send_cmd(
             &cmd_obj.read().unwrap()
@@ -41,8 +36,9 @@ where C::Cmd: 'static
 impl<T: Clone + Send + Sync> Commander for r3vi::buffer::vec::VecBuffer<T> {
     type Cmd = r3vi::buffer::vec::VecDiff<T>;
 
-    fn send_cmd(&mut self, cmd: &Self::Cmd) {
+    fn send_cmd(&mut self, cmd: &Self::Cmd) -> TreeNavResult {
         self.apply_diff(cmd.clone());
+        TreeNavResult::
     }
 }
-
+*/
diff --git a/nested/src/editors/char/mod.rs b/nested/src/editors/char/mod.rs
index a533dd4..23794c3 100644
--- a/nested/src/editors/char/mod.rs
+++ b/nested/src/editors/char/mod.rs
@@ -9,7 +9,7 @@ use {
     crate::{
         type_system::{Context, ReprTree},
         terminal::{TerminalAtom, TerminalStyle},
-        tree::NestedNode,
+        tree::{NestedNode, TreeNavResult},
         commander::{ObjCommander}
     },
     std::sync::Arc,
@@ -22,7 +22,7 @@ pub struct CharEditor {
 }
 
 impl ObjCommander for CharEditor {
-    fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) {
+    fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
         let cmd_obj = cmd_obj.read().unwrap();
         let cmd_type = cmd_obj.get_type().clone();
 
@@ -35,25 +35,8 @@ impl ObjCommander for CharEditor {
                 self.data.set(Some(value));
             }
         }
-/*
-        if cmd_type == term_event_type {
-            if let Some(te_view) = cmd_obj.get_view::<dyn SingletonView<Item = TerminalEvent>>() {
-                let event = te_view.get();
-                match event {
-                    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);
-                        }
-
-                    _ => {}
-                }                
-            }
-    }
-        */
+        TreeNavResult::Continue
     }
 }
 
diff --git a/nested/src/editors/integer/editor.rs b/nested/src/editors/integer/editor.rs
index 5863557..d324017 100644
--- a/nested/src/editors/integer/editor.rs
+++ b/nested/src/editors/integer/editor.rs
@@ -17,8 +17,8 @@ use {
             TerminalAtom, TerminalEvent, TerminalStyle, make_label
         },
         diagnostics::{Message},
-        tree::NestedNode,
-        commander::Commander
+        tree::{NestedNode, TreeNavResult},
+        commander::ObjCommander
     },
     std::sync::Arc,
     std::sync::RwLock,
@@ -35,34 +35,34 @@ pub struct DigitEditor {
     msg: VecBuffer<Message>,
 }
 
-impl Commander for DigitEditor {
-    type Cmd = TerminalEvent;
+impl ObjCommander for DigitEditor {
+    fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
+        let cmd_obj = cmd_obj.read().unwrap();
+        let cmd_type = cmd_obj.get_type().clone();
 
-    fn send_cmd(&mut self, event: &TerminalEvent) {
-        match event {
-            TerminalEvent::Input(Event::Key(Key::Char(c))) => {
-                self.data.set(Some(*c));
+        let char_type = (&self.ctx, "( Char )").into();
+        //let _term_event_type = (&ctx, "( TerminalEvent )").into();
+
+        if cmd_type == char_type {
+            if let Some(cmd_view) = cmd_obj.get_view::<dyn SingletonView<Item = char>>() {
+                let c = cmd_view.get();
+                self.data.set(Some(c));
 
                 self.msg.clear();
                 if c.to_digit(self.radix).is_none() {
                     let mut mb = IndexBuffer::new();
                     mb.insert_iter(vec![
                         (Point2::new(1, 0), make_label("invalid digit '")),
-                        (Point2::new(2, 0), make_label(&format!("{}", *c))
+                        (Point2::new(2, 0), make_label(&format!("{}", c))
                          .map_item(|_p,a| a.add_style_back(TerminalStyle::fg_color((140,140,250))))),
                         (Point2::new(3, 0), make_label("'"))
                     ]);
                     self.msg.push(crate::diagnostics::make_error(mb.get_port().flatten()));
                 }
             }
-            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")));
-                }
-            _ => {}
         }
+
+        TreeNavResult::Continue
     }
 }
 
diff --git a/nested/src/editors/list/editor.rs b/nested/src/editors/list/editor.rs
index f8a0a5f..c96e1e2 100644
--- a/nested/src/editors/list/editor.rs
+++ b/nested/src/editors/list/editor.rs
@@ -255,8 +255,8 @@ impl ListEditor {
                     let prev_node = self.data.get(prev_idx);
 
                     if let Some(prev_editor) = prev_node.editor.clone() {
-                        let mut prev_editor = prev_editor.downcast::<RwLock<ListEditor>>().unwrap();
-                        let mut prev_editor = prev_editor.write().unwrap();
+                        let prev_editor = prev_editor.downcast::<RwLock<ListEditor>>().unwrap();
+                        let prev_editor = prev_editor.write().unwrap();
 
                         if prev_editor.get_data_port().get_view().unwrap().iter()
                             .filter_map(|x| x.get_data_view::<dyn SingletonView<Item = Option<char>>>(vec![].into_iter())?.get()).count() == 0
diff --git a/nested/src/editors/list/pty_editor.rs b/nested/src/editors/list/pty_editor.rs
index 839ae81..2103d4c 100644
--- a/nested/src/editors/list/pty_editor.rs
+++ b/nested/src/editors/list/pty_editor.rs
@@ -7,7 +7,7 @@ use {
         type_system::{Context, TypeTerm, ReprTree},
         editors::list::*,
         terminal::{TerminalEvent, TerminalView, make_label},
-        tree::{TreeCursor, TreeNav},
+        tree::{TreeCursor, TreeNav, TreeNavResult},
         diagnostics::{Diagnostics},
         tree::NestedNode,
         PtySegment
@@ -231,7 +231,7 @@ use r3vi::view::singleton::SingletonView;
 use crate::commander::ObjCommander;
 
 impl ObjCommander for PTYListEditor {
-    fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) {
+    fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
         let mut e = self.editor.write().unwrap();
         let cur = e.cursor.get();
 
@@ -253,6 +253,8 @@ impl ObjCommander for PTYListEditor {
                         | TerminalEvent::Input(Event::Key(Key::Insert)) => {
                             e.toggle_leaf_mode();
                             e.set_leaf_mode(ListCursorMode::Select);
+
+                            TreeNavResult::Continue
                         }
                     _ => {
                         if let Some(idx) = cur.idx {
@@ -261,9 +263,11 @@ impl ObjCommander for PTYListEditor {
                                     match event {
                                         TerminalEvent::Input(Event::Key(Key::Backspace)) => {
                                             e.delete_pxev();
+                                            TreeNavResult::Continue
                                         }
                                         TerminalEvent::Input(Event::Key(Key::Delete)) => {
                                             e.delete_nexd();
+                                            TreeNavResult::Continue
                                         }
                                         _ => {
                                             let mut node = Context::make_node(&e.ctx, e.typ.clone(), self.depth).unwrap();
@@ -281,6 +285,8 @@ impl ObjCommander for PTYListEditor {
                                             if ! remove {
                                             */
                                             e.insert(node);
+
+                                            TreeNavResult::Continue
                                         }
                                     }
                                 },
@@ -306,8 +312,9 @@ impl ObjCommander for PTYListEditor {
                                                         item.handle_terminal_event(event);
                                                         }
                                                          */
+                                                        TreeNavResult::Continue
                                                     } else {
-                                                        item.send_cmd_obj(cmd_obj);
+                                                        item.send_cmd_obj(cmd_obj)
                                                     }
                                                 }
                                                 TerminalEvent::Input(Event::Key(Key::Delete)) => {
@@ -329,31 +336,40 @@ impl ObjCommander for PTYListEditor {
                                                         item.handle_terminal_event(event);
                                                     }
                                                          */
+
+                                                        TreeNavResult::Continue
                                                     } else {
-                                                        item.send_cmd_obj(cmd_obj);
+                                                        item.send_cmd_obj(cmd_obj)
                                                     }
                                                 }
 
                                                 TerminalEvent::Input(Event::Key(Key::Char(c))) => {
                                                     if Some(c) == self.split_char {
                                                         PTYListEditor::split(&mut e);
+                                                        TreeNavResult::Continue
                                                     } else {
-                                                        item.send_cmd_obj(cmd_obj);
+                                                        item.send_cmd_obj(cmd_obj)
                                                     }
                                                 }
                                                 _ => {
-                                                    item.send_cmd_obj(cmd_obj);
+                                                    item.send_cmd_obj(cmd_obj)
                                                 }
                                             }
                                         } else {
-                                            item.send_cmd_obj(cmd_obj);
+                                            item.send_cmd_obj(cmd_obj)
                                         }
+                                    } else {
+                                        TreeNavResult::Exit
                                     }
                                 }
                             }
+                        } else {
+                            TreeNavResult::Exit
                         }
                     }
-                }       
+                }
+            } else {
+                TreeNavResult::Exit
             }
         } else if cmd_type == char_type && cur.mode == ListCursorMode::Select {
             if let Some(cmd_view) = co.get_view::<dyn SingletonView<Item = char>>() {
@@ -362,11 +378,27 @@ impl ObjCommander for PTYListEditor {
 
                 if Some(c) == self.split_char {
                     PTYListEditor::split(&mut e);
+                    TreeNavResult::Continue
                 } else {
                     if let Some(mut item) = e.get_item_mut() {
-                        item.send_cmd_obj(cmd_obj);
+                        match item.send_cmd_obj(cmd_obj) {
+                            TreeNavResult::Continue => TreeNavResult::Continue,
+                            TreeNavResult::Exit => {
+                                item.goto(TreeCursor::none());
+                                e.cursor.set(ListCursor {
+                                    mode: ListCursorMode::Insert,
+                                    idx: Some(cur.idx.unwrap_or(0)+1)
+                                });
+
+                                TreeNavResult::Continue
+                            }
+                        }
+                    } else {
+                        TreeNavResult::Exit
                     }
                 }
+            } else {
+                TreeNavResult::Exit
             }
         } else {
             drop(co);
@@ -377,12 +409,16 @@ impl ObjCommander for PTYListEditor {
                     new_edit.goto(TreeCursor::home());
                     new_edit.send_cmd_obj(cmd_obj);
 
-                    e.insert(new_edit);                    
+                    e.insert(new_edit);
+
+                    TreeNavResult::Continue
                 },
                 ListCursorMode::Select => {
                     if let Some(mut item) = e.get_item_mut() {
-                        item.send_cmd_obj(cmd_obj);
-                    }                    
+                        item.send_cmd_obj(cmd_obj)
+                    } else {
+                        TreeNavResult::Exit
+                    }
                 }
             }
         }
diff --git a/nested/src/editors/product/editor.rs b/nested/src/editors/product/editor.rs
index ef9d88d..5389330 100644
--- a/nested/src/editors/product/editor.rs
+++ b/nested/src/editors/product/editor.rs
@@ -199,7 +199,7 @@ use r3vi::view::singleton::SingletonView;
 use crate::{commander::ObjCommander, type_system::ReprTree};
 
 impl ObjCommander for ProductEditor {
-    fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) {
+    fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
         let co = cmd_obj.read().unwrap();
         let cmd_type = co.get_type().clone();
         let term_event_type = (&self.ctx, "( TerminalEvent )").into();
@@ -257,10 +257,14 @@ impl ObjCommander for ProductEditor {
                     self.update_cur_segment();
                 }
             }
+
+            TreeNavResult::Continue
         } else {
             drop(co);
             if let Some(mut node) = self.get_cur_editor() {
-                node.send_cmd_obj(cmd_obj);
+                node.send_cmd_obj(cmd_obj)
+            } else {
+                TreeNavResult::Exit
             }
         }
     }
diff --git a/nested/src/editors/sum/editor.rs b/nested/src/editors/sum/editor.rs
index 86f49ac..5000772 100644
--- a/nested/src/editors/sum/editor.rs
+++ b/nested/src/editors/sum/editor.rs
@@ -7,10 +7,7 @@ use {
         }
     },
     crate::{
-        terminal::{
-            TerminalEditor, TerminalEditorResult,
-            TerminalEvent, TerminalView
-        },
+        terminal::TerminalView,
         editors::list::ListCursorMode,
         type_system::{Context, ReprTree},
         tree::{TreeNav, TreeCursor, TreeNavResult},
@@ -20,8 +17,7 @@ use {
         PtySegment
     },
     cgmath::{Vector2},
-    std::sync::{Arc, RwLock},
-    termion::event::{Key}
+    std::sync::{Arc, RwLock}
 };
 
 pub struct SumEditor {
@@ -131,7 +127,7 @@ impl PtySegment for SumEditor {
 }
 
 impl ObjCommander for SumEditor {
-    fn send_cmd_obj(&mut self, obj: Arc<RwLock<ReprTree>>) {
-        self.editors[ self.cur ].send_cmd_obj( obj );
+    fn send_cmd_obj(&mut self, obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
+        self.editors[ self.cur ].send_cmd_obj( obj )
     }
 }
diff --git a/nested/src/tree/node.rs b/nested/src/tree/node.rs
index 3bc3bcc..bcf1f44 100644
--- a/nested/src/tree/node.rs
+++ b/nested/src/tree/node.rs
@@ -43,10 +43,12 @@ pub struct NestedNode {
 }
 
 impl ObjCommander for NestedNode {
-    fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) {
+    fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
         if let Some(cmd) = self.cmd.as_ref() {
             // todo: filter out tree-nav cmds and send them to tree_nav
-            cmd.write().unwrap().send_cmd_obj(cmd_obj);
+            cmd.write().unwrap().send_cmd_obj(cmd_obj)
+        } else {
+            TreeNavResult::Exit
         }
     }
 }
diff --git a/nested/src/type_system/make_editor.rs b/nested/src/type_system/make_editor.rs
index 326ecd7..4dbe1d9 100644
--- a/nested/src/type_system/make_editor.rs
+++ b/nested/src/type_system/make_editor.rs
@@ -7,8 +7,7 @@ use {
             integer::*,
             product::*
         },
-        tree::{NestedNode},        
-        terminal::{TerminalEditor},
+        tree::{NestedNode},
         diagnostics::{Diagnostics},
         type_system::{MorphismTypePattern},
     },