From 8b47a19f2a8f3952b50d2b5081aa2e61fce72f5f Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Mon, 21 Aug 2023 14:12:39 +0200 Subject: [PATCH] list editor: refactor event handling --- nested/src/editors/char/mod.rs | 7 +- nested/src/editors/list/cmd.rs | 52 ++++- nested/src/editors/list/editor.rs | 56 ++--- nested/src/editors/list/pty_editor.rs | 288 +++++++++----------------- 4 files changed, 172 insertions(+), 231 deletions(-) diff --git a/nested/src/editors/char/mod.rs b/nested/src/editors/char/mod.rs index 6297b3c..708424e 100644 --- a/nested/src/editors/char/mod.rs +++ b/nested/src/editors/char/mod.rs @@ -26,10 +26,7 @@ impl ObjCommander for CharEditor { let cmd_obj = cmd_obj.read().unwrap(); let cmd_type = cmd_obj.get_type().clone(); - let char_type = (&self.ctx, "( Char )").into(); - //let _term_event_type = (&ctx, "( TerminalEvent )").into(); - - if cmd_type == char_type { + if cmd_type == (&self.ctx, "( Char )").into() { if let Some(cmd_view) = cmd_obj.get_view::>() { let value = cmd_view.get(); @@ -66,9 +63,7 @@ impl CharEditor { pub fn new_node(ctx0: Arc>) -> NestedNode { let data = SingletonBuffer::new('\0'); - let ctx = ctx0.clone(); - let editor = Arc::new(RwLock::new(CharEditor{ ctx, data: data.clone() })); NestedNode::new( diff --git a/nested/src/editors/list/cmd.rs b/nested/src/editors/list/cmd.rs index 6ac44d5..83d10fd 100644 --- a/nested/src/editors/list/cmd.rs +++ b/nested/src/editors/list/cmd.rs @@ -4,7 +4,7 @@ use { buffer::{singleton::*} }, crate::{ - editors::list::{ListEditor, ListCursorMode}, + editors::list::{ListEditor, ListCursor, ListCursorMode}, type_system::{Context, ReprTree}, tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, commander::{ObjCommander} @@ -36,8 +36,29 @@ impl ListCmd { impl ObjCommander for ListEditor { fn send_cmd_obj(&mut self, cmd_obj: Arc>) -> TreeNavResult { let cmd_repr = cmd_obj.read().unwrap(); + + if let Some(view) = cmd_repr.get_view::>() { + let node = view.get(); + let cur = self.cursor.get(); - if let Some(cmd) = cmd_repr.get_view::>() { + if let Some(idx) = cur.idx { + match cur.mode { + ListCursorMode::Select => { + *self.data.get_mut(idx as usize) = Arc::new(RwLock::new(node)); + TreeNavResult::Exit + } + ListCursorMode::Insert => { + self.insert(Arc::new(RwLock::new(node))); + self.cursor.set(ListCursor{ idx: Some(idx+1), mode: ListCursorMode::Insert }); + TreeNavResult::Continue + } + } + } else { + TreeNavResult::Exit + } + } + + else if let Some(cmd) = cmd_repr.get_view::>() { let cur = self.cursor.get(); drop(cmd_repr); @@ -80,9 +101,30 @@ impl ObjCommander for ListEditor { } } - _ => { + ListCmd::Split => { + self.listlist_split(); TreeNavResult::Continue } + + _ => { + eprintln!("list edit: give cmd to child"); + + match item.send_cmd_obj(cmd_obj) { + TreeNavResult::Continue => TreeNavResult::Continue, + TreeNavResult::Exit => { + TreeNavResult::Continue + /* + match cmd.get() { + ListCmd::Split => { + }, + _ => { + TreeNavResult::Exit + } + } + */ + } + } + } } } else { TreeNavResult::Exit @@ -103,7 +145,11 @@ impl ObjCommander for ListEditor { TreeNavResult::Continue } ListCmd::Split => { +/* + self.split(self.spill_node); + */ self.listlist_split(); + TreeNavResult::Continue } ListCmd::Clear => { diff --git a/nested/src/editors/list/editor.rs b/nested/src/editors/list/editor.rs index 70cda6c..1714415 100644 --- a/nested/src/editors/list/editor.rs +++ b/nested/src/editors/list/editor.rs @@ -354,9 +354,13 @@ impl ListEditor { if let Some(head_editor) = item.editor.get() { + eprintln!("listlistsplit:editor = {:?}", Arc::into_raw(head_editor.clone())); + let head = head_editor.downcast::>().unwrap(); let mut head = head.write().unwrap(); - + + let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), 0).unwrap(); + if head.data.len() > 0 { if cur.tree_addr.len() > 2 { eprintln!("call child head listlist split"); @@ -364,35 +368,33 @@ impl ListEditor { eprintln!("return"); } - eprintln!("got head"); + /* + TODO: replace this by: (does not require ListEditor downcast) + head.send_cmd_obj(ListCmd::Split.into_repr()); + tail_node = head.spill_buf.clone(); + */ - let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), 0).unwrap(); head.split( &mut tail_node ); - - eprintln!("made split"); - - head.goto(TreeCursor::none()); - drop(head); - - eprintln!("done goto"); - - tail_node.goto( - TreeCursor { - tree_addr: vec![0], - leaf_mode: if cur.tree_addr.len() > 2 { - ListCursorMode::Select - } else { - ListCursorMode::Insert - } - } - ); - - self.insert( - Arc::new(RwLock::new(tail_node)) - ); - - eprintln!("made insert"); } + + head.goto(TreeCursor::none()); + drop(head); + + tail_node.goto( + TreeCursor { + tree_addr: vec![0], + leaf_mode: if cur.tree_addr.len() > 2 { + ListCursorMode::Select + } else { + ListCursorMode::Insert + } + } + ); + self.insert( + Arc::new(RwLock::new(tail_node)) + ); + + eprintln!("made insert"); } } } diff --git a/nested/src/editors/list/pty_editor.rs b/nested/src/editors/list/pty_editor.rs index 9ed9719..1d40f37 100644 --- a/nested/src/editors/list/pty_editor.rs +++ b/nested/src/editors/list/pty_editor.rs @@ -137,224 +137,122 @@ impl PTYListController { self.depth = depth; } -/* - pub fn handle_node_event(&mut self, c: &NestedNode) -> TreeNavResult { - + pub fn handle_term_event(&mut self, event: &TerminalEvent, cmd_obj: Arc>) -> TreeNavResult { + let mut e = self.editor.write().unwrap(); + match event { + TerminalEvent::Input(Event::Key(Key::Insert)) => { + e.toggle_leaf_mode(); + TreeNavResult::Continue + } + _ => TreeNavResult::Continue + } } - pub fn handle_char_event(&mut self, c: &char) -> TreeNavResult { + pub fn handle_meta_char(&mut self, c: char, child_close_char: Option) -> TreeNavResult { + eprintln!("handle meta char"); + let mut e = self.editor.write().unwrap(); + let cur = e.cursor.get(); + if Some(c) == self.split_char { + e.listlist_split(); + TreeNavResult::Continue + } else if Some(c) == child_close_char { + e.goto(TreeCursor::none()); + e.cursor.set(ListCursor { + mode: ListCursorMode::Select, + idx: Some(cur.idx.unwrap_or(0)) + }); + TreeNavResult::Continue + } else { + TreeNavResult::Exit + } } - pub fn handle_term_event(&mut self, e: &TerminalEvent) -> TreeNavResult { - -} - */ + pub fn handle_any_event(&mut self, cmd_obj: Arc>) -> TreeNavResult { + let mut e = self.editor.write().unwrap(); + let cur = e.cursor.get(); + let ctx = e.ctx.clone(); + let ctx = ctx.read().unwrap(); + + match cur.mode { + ListCursorMode::Insert => { + let mut new_edit = Context::make_node(&e.ctx, e.typ.clone(), self.depth).unwrap(); + new_edit.goto(TreeCursor::home()); + + match new_edit.send_cmd_obj(cmd_obj.clone()) { + TreeNavResult::Continue => { + e.insert(Arc::new(RwLock::new(new_edit))); + TreeNavResult::Continue + } + TreeNavResult::Exit => TreeNavResult::Exit + } + }, + ListCursorMode::Select => { + if let Some(mut item) = e.get_item_mut() { + + eprintln!("PTYList: forward any cmd to current child item"); + let res = item.write().unwrap().send_cmd_obj(cmd_obj.clone()); + let child_close_char = item.read().unwrap().close_char.get(); + eprintln!("PTYList: returned"); + + match res { + TreeNavResult::Continue => TreeNavResult::Continue, + TreeNavResult::Exit => { + eprintln!("...returned with exit"); + // child editor returned control, probably for meta-char handling.. + + if cmd_obj.read().unwrap().get_type().clone() == ctx.type_term_from_str("( Char )").unwrap() { + let co = cmd_obj.read().unwrap(); + if let Some(cmd_view) = co.get_view::>() { + drop(co); + drop(e); + self.handle_meta_char(cmd_view.get(), child_close_char) + } else { + TreeNavResult::Exit + } + } else { + TreeNavResult::Exit + } + } + } + } else { + // cursor selects non existent item + TreeNavResult::Exit + } + } + } + } } + use r3vi::view::singleton::SingletonView; use crate::commander::ObjCommander; impl ObjCommander for PTYListController { fn send_cmd_obj(&mut self, cmd_obj: Arc>) -> TreeNavResult { let mut e = self.editor.write().unwrap(); - let cur = e.cursor.get(); - let cur_depth = e.get_cursor().tree_addr.len(); + let cmd_type = cmd_obj.read().unwrap().get_type().clone(); - let ctx0 = e.ctx.clone(); - let ctx = e.ctx.clone(); - let ctx = ctx.read().unwrap(); - - let co = cmd_obj.read().unwrap(); - let cmd_type = co.get_type().clone(); - let term_event_type = ctx.type_term_from_str("( TerminalEvent )").unwrap(); - let list_cmd_type = ctx.type_term_from_str("( ListCmd )").unwrap(); - let nested_node_type = ctx.type_term_from_str("( NestedNode )").unwrap(); - let char_type = ctx.type_term_from_str("( Char )").unwrap(); - - if cmd_type == nested_node_type { - eprintln!("got nested node cmd"); - if let Some(node_view) = co.get_view::>() { - if let Some(idx) = cur.idx { - match cur.mode { - ListCursorMode::Select => { - *e.data.get_mut(idx as usize) = Arc::new(RwLock::new(node_view.get())); - TreeNavResult::Exit - } - ListCursorMode::Insert => { - e.insert(Arc::new(RwLock::new(node_view.get()))); - e.cursor.set(ListCursor{ idx: Some(idx+1), mode: ListCursorMode::Insert }); - TreeNavResult::Continue - } - } - } else { - TreeNavResult::Exit - } - } else { - TreeNavResult::Continue - } - } - - else if cmd_type == list_cmd_type { - drop(co); + if cmd_type == (&e.ctx, "( ListCmd )").into() + || cmd_type == (&e.ctx, "( NestedNode )").into() + { e.send_cmd_obj( cmd_obj ) } - else if cmd_type == term_event_type { - if let Some(te_view) = co.get_view::>() { - drop(co); - let event = te_view.get(); - - match event { - TerminalEvent::Input(Event::Key(Key::Char('\t'))) - | TerminalEvent::Input(Event::Key(Key::Insert)) => { - e.toggle_leaf_mode(); - e.set_leaf_mode(ListCursorMode::Select); - - TreeNavResult::Continue - } - _ => { - if let Some(idx) = cur.idx { - match cur.mode { - ListCursorMode::Insert => { - match event { - TerminalEvent::Input(Event::Key(Key::Backspace)) => { - e.send_cmd_obj( ListCmd::DeletePxev.into_repr_tree(&ctx0) ) - } - TerminalEvent::Input(Event::Key(Key::Delete)) => { - e.send_cmd_obj( ListCmd::DeletePxev.into_repr_tree(&ctx0) ) - } - _ => { - let mut node = Context::make_node(&e.ctx, e.typ.clone(), self.depth).unwrap(); - node.goto(TreeCursor::home()); - node.send_cmd_obj(cmd_obj); -/* - if e.is_listlist() { - if let Some(new_edit) = node.get_edit::() { - if new_edit.data.len() == 0 { - remove = true; - } - } - } - - if ! remove { - */ - e.insert(Arc::new(RwLock::new(node))); - - TreeNavResult::Continue - } - } - }, - ListCursorMode::Select => { - if let Some(mut item) = e.get_item().clone() { - if e.is_listlist() { - match event { - TerminalEvent::Input(Event::Key(Key::Backspace)) => { - e.send_cmd_obj( ListCmd::DeletePxev.into_repr_tree(&ctx0) ) - } - TerminalEvent::Input(Event::Key(Key::Delete)) => { - e.send_cmd_obj( ListCmd::DeleteNexd.into_repr_tree(&ctx0) ) - } - - TerminalEvent::Input(Event::Key(Key::Char(c))) => { - if Some(c) == self.split_char { - e.listlist_split(); - TreeNavResult::Continue - } else { - item.send_cmd_obj(cmd_obj) - } - } - _ => { - item.send_cmd_obj(cmd_obj) - } - } - } else { - item.send_cmd_obj(cmd_obj) - } - } else { - TreeNavResult::Exit - } - } - } - } else { - TreeNavResult::Exit - } - } - } + else if cmd_type == (&e.ctx, "( TerminalEvent )").into() { + let co = cmd_obj.read().unwrap(); + if let Some(view) = co.get_view::>() { + drop( co ); + drop( e ); + self.handle_term_event( &view.get(), cmd_obj ) } else { TreeNavResult::Exit } } else { - drop(co); - match cur.mode { - ListCursorMode::Insert => { - let mut new_edit = Context::make_node(&e.ctx, e.typ.clone(), self.depth).unwrap(); - new_edit.goto(TreeCursor::home()); - - match new_edit.send_cmd_obj(cmd_obj.clone()) { - TreeNavResult::Continue => { - e.insert(Arc::new(RwLock::new(new_edit))); - TreeNavResult::Continue - } - - TreeNavResult::Exit => { - //eprintln!("listedit: exit from insert mode"); - TreeNavResult::Exit - } - } - }, - ListCursorMode::Select => { - if let Some(mut item) = e.get_item_mut() { - - let mut i = item.write().unwrap(); - let res = i.send_cmd_obj(cmd_obj.clone()); - - let close_char = i.close_char.get(); - drop(i); - drop(item); - - match res { - TreeNavResult::Continue => { - TreeNavResult::Continue - } - - TreeNavResult::Exit => { - if cmd_type == char_type { - let co = cmd_obj.read().unwrap(); - if let Some(cmd_view) = co.get_view::>() { - drop(co); - let c = cmd_view.get(); - - if Some(c) == self.split_char { - e.listlist_split(); - TreeNavResult::Continue - } else if Some(c) == close_char { - //eprintln!("listedit: exit from select (close)"); - //item.goto(TreeCursor::none()); - e.cursor.set(ListCursor { - mode: ListCursorMode::Insert, - idx: Some(cur.idx.unwrap_or(0)+1) - }); - TreeNavResult::Continue - } else { - //eprintln!("listedit: exit from select mode"); - TreeNavResult::Exit - } - } else { - TreeNavResult::Exit - } - } else { - TreeNavResult::Exit - } - } - } - } else { - TreeNavResult::Exit - } - } - } + drop( e ); + self.handle_any_event( cmd_obj ) } } }