From cec7b4a0a01a3b448e463d5a89f7c727762849d9 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Thu, 26 Aug 2021 08:20:51 +0200 Subject: [PATCH] more improvements for ListEditor fix some glitches by refactoring ListCursor: mode is now always present, only idx is optional --- nested/src/list/cursor.rs | 6 +- nested/src/list/editor.rs | 645 +++++++++++++++++--------------------- nested/src/tree_nav.rs | 26 +- shell/src/main.rs | 36 ++- 4 files changed, 343 insertions(+), 370 deletions(-) diff --git a/nested/src/list/cursor.rs b/nested/src/list/cursor.rs index 0eb54ec..51229ea 100644 --- a/nested/src/list/cursor.rs +++ b/nested/src/list/cursor.rs @@ -9,14 +9,14 @@ pub enum ListCursorMode { #[derive(Clone, Copy, Eq, PartialEq)] pub struct ListCursor { pub mode: ListCursorMode, - pub idx: usize + pub idx: Option } impl Default for ListCursor { fn default() -> Self { ListCursor { - mode: ListCursorMode::Insert, - idx: 0 + mode: ListCursorMode::Select, + idx: None } } } diff --git a/nested/src/list/editor.rs b/nested/src/list/editor.rs index c92a4a2..3413a17 100644 --- a/nested/src/list/editor.rs +++ b/nested/src/list/editor.rs @@ -40,7 +40,7 @@ pub struct ListEditor where ItemEditor: TerminalEditor + ?Sized + Send + Sync + 'static, FnMakeItemEditor: Fn() -> Arc> { - cursor: SingletonBuffer>, + cursor: SingletonBuffer, data: VecBuffer>>, data_sequence_port: OuterViewPort>>>, make_item_editor: FnMakeItemEditor, @@ -54,206 +54,213 @@ impl TreeNav for ListEditor Arc> { - fn get_cursor(&self) -> Option { - if let Some(cur) = self.cursor.get() { - match cur.mode { - ListCursorMode::Insert | - ListCursorMode::Select => { - Some(TreeCursor { - leaf_mode: cur.mode, - tree_addr: vec![ cur.idx ] - }) - }, - ListCursorMode::Modify => { - if cur.idx < self.data.len() { - if let Some(mut sub_cur) = self.data.get(cur.idx).read().unwrap().get_cursor() { - sub_cur.tree_addr.insert(0, cur.idx); - Some(sub_cur) - } else { - Some(TreeCursor { - leaf_mode: cur.mode, - tree_addr: vec![ cur.idx ] - }) - } - } else { - None + fn get_cursor(&self) -> TreeCursor { + let cur = self.cursor.get(); + match cur.mode { + ListCursorMode::Insert | + ListCursorMode::Select => { + TreeCursor { + leaf_mode: cur.mode, + tree_addr: if let Some(i) = cur.idx { vec![ i ] } else { vec![] } + } + }, + ListCursorMode::Modify => { + if let Some(i) = cur.idx { + if i < self.data.len() { + let mut sub_cur = self.data.get(i).read().unwrap().get_cursor(); + sub_cur.tree_addr.insert(0, i); + return sub_cur; } } + TreeCursor { + leaf_mode: cur.mode, + tree_addr: vec![] + } } - } else { - None } } - fn goto(&mut self, cursor: Option) -> TreeNavResult { - if let Some(old_cur) = self.cursor.get() { - if old_cur.mode == ListCursorMode::Modify { - let ce = self.data.get_mut(old_cur.idx); + fn goto(&mut self, new_cur: TreeCursor) -> TreeNavResult { + let old_cur = self.cursor.get(); + if old_cur.mode == ListCursorMode::Modify { + if let Some(i) = old_cur.idx { + let ce = self.data.get_mut(i); let mut cur_edit = ce.write().unwrap(); - cur_edit.goto(None); + cur_edit.goto(TreeCursor::default()); } } - if let Some(new_cur) = cursor { - if new_cur.tree_addr.len() == 1 { - self.cursor.set(Some(ListCursor{ - mode: new_cur.leaf_mode, - idx: new_cur.tree_addr[0] - })); - TreeNavResult::Continue - } else if new_cur.tree_addr[0] < self.data.len() { - self.cursor.set(Some(ListCursor { - mode: ListCursorMode::Modify, - idx: new_cur.tree_addr[0] - })); + if new_cur.tree_addr.len() == 1 { + self.cursor.set(ListCursor{ + mode: new_cur.leaf_mode, + idx: Some(new_cur.tree_addr[0]) + }); + TreeNavResult::Continue + } else if new_cur.tree_addr.len() > 1 && new_cur.tree_addr[0] < self.data.len() { + self.cursor.set(ListCursor { + mode: ListCursorMode::Modify, + idx: Some(new_cur.tree_addr[0]) + }); - let ne = self.data.get_mut(new_cur.tree_addr[0]); - let mut nxt_edit = ne.write().unwrap(); + let ne = self.data.get_mut(new_cur.tree_addr[0]); + let mut nxt_edit = ne.write().unwrap(); - nxt_edit.goto( - Some(TreeCursor { - leaf_mode: new_cur.leaf_mode, - tree_addr: new_cur.tree_addr[1..].iter().cloned().collect() - })); + nxt_edit.goto( + TreeCursor { + leaf_mode: new_cur.leaf_mode, + tree_addr: new_cur.tree_addr[1..].iter().cloned().collect() + }); - TreeNavResult::Continue - } else { - self.cursor.set(None); - TreeNavResult::Exit - } + TreeNavResult::Continue } else { - self.cursor.set(None); + self.cursor.set(ListCursor { + mode: new_cur.leaf_mode, + idx: None + }); TreeNavResult::Exit } } fn goto_end(&mut self) -> TreeNavResult { - if let Some(cur) = self.cursor.get() { - if cur.idx < self.data.len() { - match cur.mode { - ListCursorMode::Insert => { - if cur.idx < self.data.len() { - self.cursor.set(Some( - ListCursor { - mode: ListCursorMode::Insert, - idx: self.data.len() - } - )); - TreeNavResult::Continue - } else { - self.cursor.set(None); - TreeNavResult::Exit - } + let mut cur = self.cursor.get(); + let i = cur.idx.unwrap_or(0); + if i < self.data.len() { + match cur.mode { + ListCursorMode::Insert => { + if i < self.data.len() || cur.idx.is_none() { + cur.idx = Some(self.data.len()); + self.cursor.set(cur); + TreeNavResult::Continue + } else { + self.cursor.set(ListCursor::default()); + TreeNavResult::Exit } - ListCursorMode::Select => { - if cur.idx+1 < self.data.len() { - self.cursor.set(Some( - ListCursor { - mode: ListCursorMode::Select, - idx: self.data.len()-1 - } - )); - TreeNavResult::Continue - } else { - self.cursor.set(None); - TreeNavResult::Exit - } + } + ListCursorMode::Select => { + if i+1 < self.data.len() || cur.idx.is_none() { + cur.idx = Some(self.data.len()-1); + self.cursor.set(cur); + TreeNavResult::Continue + } else { + self.cursor.set(ListCursor::default()); + TreeNavResult::Exit } - ListCursorMode::Modify => { - let ce = self.data.get_mut(cur.idx); - let mut cur_edit = ce.write().unwrap(); - let cur_mode = if let Some(c) = cur_edit.get_cursor() { c.leaf_mode } else { ListCursorMode::Select }; + } + ListCursorMode::Modify => { + let ce = self.data.get_mut(i); + let mut cur_edit = ce.write().unwrap(); + let cur_mode = cur_edit.get_cursor().leaf_mode; - match cur_edit.goto_end() { - TreeNavResult::Continue => { - TreeNavResult::Continue - } - TreeNavResult::Exit => { - if cur.idx+1 < self.data.len() { + match cur_edit.goto_end() { + TreeNavResult::Continue => { + TreeNavResult::Continue + } + TreeNavResult::Exit => { + if let Some(i) = cur.idx { + if i+1 < self.data.len() { cur_edit.up(); drop(cur_edit); - self.set_mode(cur_mode); self.nexd(); - self.dn(); - self.goto_end(); + self.set_mode(ListCursorMode::Modify); + + let ne = self.get_item().unwrap(); + let mut nxd_edit = ne.write().unwrap(); + + nxd_edit.goto( + TreeCursor { + leaf_mode: cur_mode, + tree_addr: vec![] + } + ); + nxd_edit.goto_end(); + TreeNavResult::Continue } else { - self.cursor.set(None); + self.cursor.set(ListCursor::default()); TreeNavResult::Exit } + } else { + self.cursor.set(ListCursor::default()); + TreeNavResult::Exit } } } } - } else { - // goto right neighbours end - TreeNavResult::Exit } } else { + self.cursor.set(ListCursor::default()); TreeNavResult::Exit } } fn goto_home(&mut self) -> TreeNavResult { - if let Some(cur) = self.cursor.get() { - match cur.mode { - ListCursorMode::Insert | - ListCursorMode::Select => { - if cur.idx > 0 { - self.cursor.set(Some( - ListCursor { - mode: cur.mode, - idx: 0 - } - )); - TreeNavResult::Continue - } else { - self.cursor.set(None); - TreeNavResult::Exit - } + let cur = self.cursor.get(); + match cur.mode { + ListCursorMode::Insert | + ListCursorMode::Select => { + if cur.idx != Some(0) { + self.cursor.set( + ListCursor { + mode: cur.mode, + idx: Some(0) + } + ); + TreeNavResult::Continue + } else { + self.cursor.set(ListCursor::default()); + TreeNavResult::Exit } - ListCursorMode::Modify => { - let ce = self.get_item().unwrap(); - let mut cur_edit = ce.write().unwrap(); - let cur_mode = if let Some(c) = cur_edit.get_cursor() { c.leaf_mode } else { ListCursorMode::Select }; + } + ListCursorMode::Modify => { + let ce = self.get_item().unwrap(); + let mut cur_edit = ce.write().unwrap(); + let cur_mode = cur_edit.get_cursor().leaf_mode; - match cur_edit.goto_home() { - TreeNavResult::Exit => { - if cur.idx > 0 { + match cur_edit.goto_home() { + TreeNavResult::Exit => { + if let Some(i) = cur.idx { + if i > 0 { cur_edit.up(); drop(cur_edit); - self.set_mode(cur_mode); self.pxev(); - self.dn(); + self.set_mode(ListCursorMode::Modify); + + let pe = self.get_item().unwrap(); + let mut pxv_edit = pe.write().unwrap(); + + pxv_edit.goto( + TreeCursor { + leaf_mode: cur_mode, + tree_addr: vec![] + } + ); + pxv_edit.goto_home(); + TreeNavResult::Continue } else { - self.cursor.set(None); + self.cursor.set(ListCursor::default()); TreeNavResult::Exit } + } else { + self.cursor.set(ListCursor::default()); + TreeNavResult::Exit } - TreeNavResult::Continue => TreeNavResult::Continue } + TreeNavResult::Continue => TreeNavResult::Continue } } - } else { - TreeNavResult::Exit } } fn up(&mut self) -> TreeNavResult { - if let Some(cur) = self.cursor.get() { - if cur.mode == ListCursorMode::Modify { - let ce = self.data.get_mut(cur.idx); + let cur = self.cursor.get(); + if cur.mode == ListCursorMode::Modify { + if let Some(i) = cur.idx { + let ce = self.data.get_mut(i); let mut cur_edit = ce.write().unwrap(); - - let mode = - if let Some(c) = cur_edit.get_cursor() { - c.leaf_mode - } else { - ListCursorMode::Select - }; + let mode = cur_edit.get_cursor().leaf_mode; match cur_edit.up() { TreeNavResult::Exit => { @@ -262,100 +269,85 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, TreeNavResult::Continue => {} } - TreeNavResult::Continue - } else { - self.cursor.set(None); - TreeNavResult::Exit + return TreeNavResult::Continue; } - } else { - TreeNavResult::Exit } + + self.cursor.set(ListCursor { + mode: cur.mode, + idx: None + }); + TreeNavResult::Exit } fn dn(&mut self) -> TreeNavResult { - if let Some(cur) = self.cursor.get() { - match cur.mode { - ListCursorMode::Insert | - ListCursorMode::Select => { - if cur.idx < self.data.len() { - self.cursor.set(Some(ListCursor { - mode: ListCursorMode::Modify, - idx: cur.idx - })); - - self.data.get_mut(cur.idx).write().unwrap().goto( - Some(TreeCursor { + let cur = self.cursor.get(); + match cur.mode { + ListCursorMode::Insert | + ListCursorMode::Select => { + if let Some(i) = cur.idx { + if i < self.data.len() { + self.set_mode(ListCursorMode::Modify); + self.data.get_mut(i).write().unwrap().goto( + TreeCursor { leaf_mode: cur.mode, tree_addr: vec![ 0 ] - }) + } ); } } - ListCursorMode::Modify => { - let ce = self.data.get_mut(cur.idx); - let mut cur_edit = ce.write().unwrap(); - - cur_edit.dn(); - } } - TreeNavResult::Continue - } else { - self.cursor.set(Some(ListCursor { - mode: ListCursorMode::Insert, - idx: 0 // todo: smart prediction - })); - TreeNavResult::Continue + ListCursorMode::Modify => { + self.get_item().unwrap().write().unwrap().dn(); + } } + TreeNavResult::Continue } fn pxev(&mut self) -> TreeNavResult { - if let Some(cur) = self.cursor.get() { + let mut cur = self.cursor.get(); + if let Some(i) = cur.idx { match cur.mode { - ListCursorMode::Insert => { - if cur.idx > 0 { - self.cursor.set(Some(ListCursor { - mode: ListCursorMode::Insert, - idx: cur.idx - 1 - })); - TreeNavResult::Continue - } else { - self.cursor.set(None); - TreeNavResult::Exit - } - } + ListCursorMode::Insert | ListCursorMode::Select => { - if cur.idx > 0 { - self.cursor.set(Some(ListCursor { - mode: ListCursorMode::Select, - idx: cur.idx - 1 - })); + if i > 0 { + cur.idx = Some(i - 1); + self.cursor.set(cur); TreeNavResult::Continue } else { - self.cursor.set(None); + self.cursor.set(ListCursor::default()); TreeNavResult::Exit } } ListCursorMode::Modify => { let ce = self.get_item().unwrap(); let mut cur_edit = ce.write().unwrap(); - let cur_mode = if let Some(c) = cur_edit.get_cursor() { c.leaf_mode } else { ListCursorMode::Select }; + let cur_mode = cur_edit.get_cursor().leaf_mode; match cur_edit.pxev() { TreeNavResult::Exit => { - if cur.idx > 0 { - cur_edit.up(); - drop(cur_edit); - - self.set_mode(cur_mode); + drop(cur_edit); + if i > 0 { + self.up(); self.pxev(); - self.dn(); - self.goto_end(); + self.set_mode(ListCursorMode::Modify); + + let pe = self.get_item().unwrap(); + let mut pxv_edit = pe.write().unwrap(); + pxv_edit.goto( + TreeCursor { + leaf_mode: cur_mode, + tree_addr: vec![] + } + ); + pxv_edit.goto_end(); + TreeNavResult::Continue } else { - self.cursor.set(None); + self.cursor.set(ListCursor::default()); TreeNavResult::Exit } - } + }, TreeNavResult::Continue => TreeNavResult::Continue } } @@ -366,40 +358,37 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, } fn nexd(&mut self) -> TreeNavResult { - if let Some(cur) = self.cursor.get() { + let mut cur = self.cursor.get(); + if let Some(i) = cur.idx { match cur.mode { ListCursorMode::Insert => { - if cur.idx < self.data.len() { - self.cursor.set(Some(ListCursor { - mode: ListCursorMode::Insert, - idx: cur.idx + 1 - })); + if i < self.data.len() { + cur.idx = Some(i + 1); + self.cursor.set(cur); TreeNavResult::Continue } else { - self.cursor.set(None); + self.cursor.set(ListCursor::default()); TreeNavResult::Exit } } ListCursorMode::Select => { - if cur.idx+1 < self.data.len() { - self.cursor.set(Some(ListCursor { - mode: ListCursorMode::Select, - idx: cur.idx + 1 - })); + if i+1 < self.data.len() { + cur.idx = Some(i + 1); + self.cursor.set(cur); TreeNavResult::Continue } else { - self.cursor.set(None); + self.cursor.set(ListCursor::default()); TreeNavResult::Exit } } ListCursorMode::Modify => { - let ce = self.data.get(cur.idx); + let ce = self.data.get(i); let mut cur_edit = ce.write().unwrap(); - let cur_mode = if let Some(c) = cur_edit.get_cursor() { c.leaf_mode } else { ListCursorMode::Select }; + let cur_mode = cur_edit.get_cursor().leaf_mode; match cur_edit.nexd() { TreeNavResult::Exit => { - if cur.idx+1 < self.data.len() { + if i+1 < self.data.len() { cur_edit.up(); drop(cur_edit); drop(ce); @@ -409,7 +398,7 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, self.dn(); TreeNavResult::Continue } else { - self.cursor.set(None); + self.cursor.set(ListCursor::default()); TreeNavResult::Exit } } @@ -432,25 +421,24 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, } fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { - if let Some(cur) = self.cursor.get() { + let mut cur = self.cursor.get(); + if let Some(idx) = cur.idx { match cur.mode { ListCursorMode::Insert => { match event { TerminalEvent::Input(Event::Key(Key::Backspace)) => { - if cur.idx > 0 { - self.data.remove(cur.idx-1); - self.cursor.set(Some(ListCursor { - mode: ListCursorMode::Insert, - idx: cur.idx-1 - })); + if idx > 0 { + self.data.remove(idx-1); + cur.idx = Some(idx-1); + self.cursor.set(cur); TerminalEditorResult::Continue } else { TerminalEditorResult::Exit } } TerminalEvent::Input(Event::Key(Key::Delete)) => { - if cur.idx < self.data.len() { - self.data.remove(cur.idx); + if idx < self.data.len() { + self.data.remove(idx); TerminalEditorResult::Continue } else { TerminalEditorResult::Exit @@ -458,24 +446,20 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, } TerminalEvent::Input(Event::Key(Key::Char('\t'))) | TerminalEvent::Input(Event::Key(Key::Insert)) => { - let l = self.data.len(); self.set_mode(ListCursorMode::Select); TerminalEditorResult::Continue } _ => { let new_edit = (self.make_item_editor)(); - self.data.insert(cur.idx, new_edit.clone()); - self.cursor.set(Some(ListCursor { - mode: ListCursorMode::Modify, - idx: cur.idx - })); + self.data.insert(idx, new_edit.clone()); + self.dn(); match new_edit.write().unwrap().handle_terminal_event(event) { TerminalEditorResult::Exit => { - self.cursor.set(Some(ListCursor { + self.cursor.set(ListCursor { mode: ListCursorMode::Insert, - idx: cur.idx+1 - })); + idx: Some(idx+1) + }); } _ => {} } @@ -487,40 +471,39 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, match event { TerminalEvent::Input(Event::Key(Key::Char('\t'))) | TerminalEvent::Input(Event::Key(Key::Insert)) => { - self.cursor.set(Some(ListCursor { - mode: ListCursorMode::Insert, - idx: cur.idx - })); + self.set_mode(ListCursorMode::Insert); + TerminalEditorResult::Continue } TerminalEvent::Input(Event::Key(Key::Delete)) => { - self.data.remove(cur.idx); + self.data.remove(idx); if self.data.len() == 0 { - self.cursor.set(Some(ListCursor::default())); - } else if cur.idx == self.data.len() { - self.cursor.set(Some(ListCursor { + self.cursor.set(ListCursor::default()); + } else if idx == self.data.len() { + self.cursor.set(ListCursor { mode: ListCursorMode::Select, - idx: cur.idx-1 - })); + idx: Some(idx-1) + }); } + TerminalEditorResult::Continue + } + _ => { + TerminalEditorResult::Continue } - _ => {} } - - TerminalEditorResult::Continue } ListCursorMode::Modify => { - let mut ce = self.data.get_mut(cur.idx); + let mut ce = self.data.get_mut(idx); let mut cur_edit = ce.write().unwrap(); match event { TerminalEvent::Input(Event::Key(Key::Char(' '))) => { // split.. cur_edit.up(); drop(cur_edit); - self.cursor.set(Some(ListCursor { + self.cursor.set(ListCursor { mode: ListCursorMode::Insert, - idx: cur.idx+1 - })); + idx: Some(idx+1) + }); TerminalEditorResult::Continue } TerminalEvent::Input(Event::Key(Key::Backspace)) => { @@ -528,11 +511,11 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, TerminalEditorResult::Exit => { drop(cur_edit); drop(ce); - self.cursor.set(Some(ListCursor { + self.cursor.set(ListCursor { mode: ListCursorMode::Insert, - idx: cur.idx - })); - self.data.remove(cur.idx); // todo: join instead of remove + idx: Some(idx) + }); + self.data.remove(idx); // todo: join instead of remove } TerminalEditorResult::Continue => { } @@ -544,7 +527,7 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, } } } else { - TerminalEditorResult::Continue + TerminalEditorResult::Continue } } } @@ -557,9 +540,9 @@ enum ListEditorViewSegment { } struct ListEditorView { - cursor: Arc>>, + cursor: Arc>, data: Arc>>, - cur_cursor: Option, + cur_cursor: ListCursor, cast: Arc>>>, proj_helper: ProjectionHelper @@ -573,46 +556,42 @@ impl SequenceView for ListEditorView { type Item = ListEditorViewSegment; fn len(&self) -> Option { - if let Some(cur) = self.cur_cursor { - match cur.mode { - ListCursorMode::Insert => Some(self.data.len()? + 1), - _ => self.data.len() - } - } else { - self.data.len() + match self.cursor.get().mode { + ListCursorMode::Insert => Some(self.data.len()? + 1), + _ => self.data.len() } } fn get(&self, idx: &usize) -> Option { Some( - if let Some(cur) = self.cur_cursor { - match cur.mode { + if let Some(cur) = self.cur_cursor.idx { + match self.cur_cursor.mode { ListCursorMode::Select => { - if *idx == cur.idx { - ListEditorViewSegment::Select(self.data.get(idx)?) + if *idx == cur { + ListEditorViewSegment::Select(self.data.get(&idx)?) } else { - ListEditorViewSegment::View(self.data.get(idx)?) + ListEditorViewSegment::View(self.data.get(&idx)?) } } ListCursorMode::Insert => { - if *idx < cur.idx { - ListEditorViewSegment::View(self.data.get(idx)?) - } else if *idx == cur.idx { + if *idx < cur { + ListEditorViewSegment::View(self.data.get(&idx)?) + } else if *idx == cur { ListEditorViewSegment::InsertCursor } else { ListEditorViewSegment::View(self.data.get(&(idx-1))?) - } + } } ListCursorMode::Modify => { - if *idx == cur.idx { - ListEditorViewSegment::Modify(self.data.get(idx)?) + if *idx == cur { + ListEditorViewSegment::Modify(self.data.get(&idx)?) } else { - ListEditorViewSegment::View(self.data.get(idx)?) + ListEditorViewSegment::View(self.data.get(&idx)?) } } } } else { - ListEditorViewSegment::View(self.data.get(idx)?) + ListEditorViewSegment::View(self.data.get(&idx)?) } ) } @@ -620,14 +599,14 @@ impl SequenceView for ListEditorView { impl ListEditorView { fn new( - cursor_port: OuterViewPort>>, + cursor_port: OuterViewPort>, data_port: OuterViewPort>>, out_port: InnerViewPort> ) -> Arc> { let mut proj_helper = ProjectionHelper::new(out_port.0.update_hooks.clone()); let proj = Arc::new(RwLock::new( ListEditorView { - cur_cursor: None, + cur_cursor: ListCursor::default(), cursor: proj_helper.new_singleton_arg( 0, cursor_port, @@ -635,45 +614,7 @@ impl ListEditorView { let old_cursor = s.cur_cursor; let new_cursor = s.cursor.get(); s.cur_cursor = new_cursor; -/* - let mut begin = std::cmp::min( - if let Some(cur) = self.old_cursor { - cur.idx - } else { - usize::MAX - }, - if let Some(cur) = self.new_cursor { - cur.idx - } else { - usize::MAX - } - ); - let mut end = - /* - match (old_cursor, new_cursor) { - (ListEditorCursor::None, ListEditorCursor::None) => usize::MAX, - (ListEditorCursor::Select(old_pos), ListEditorCursor::Select(new_pos)) => max(old_pos, new_pos), - (ListEditorCursor::Edit(old_pos), ListEditorCursor::Edit(new_pos)) => max(old_pos, new_pos), - (ListEditorCursor::Insert(old_pos), ListEditorCursor::Insert(new_pos)) => max(old_pos, new_pos), - (ListEditorCursor::) - }; -*/ - std::cmp::max( - match old_cursor { - ListEditorCursor::None => 0, - ListEditorCursor::Select(c) => c, - ListEditorCursor::Insert(c) => c+1, - ListEditorCursor::Edit(c) => c - }, - match new_cursor { - ListEditorCursor::None => 0, - ListEditorCursor::Select(c) => c, - ListEditorCursor::Insert(c) => c+1, - ListEditorCursor::Edit(c) => c - } - ); -*/ s.cast.notify_each( 0 ..= s.data.len().unwrap_or(0)+1 ); @@ -682,10 +623,10 @@ impl ListEditorView { 1, data_port, |s: &mut Self, idx| { - if let Some(cur) = s.cur_cursor { - match cur.mode { + if let Some(cur_idx) = s.cur_cursor.idx { + match s.cur_cursor.mode { ListCursorMode::Insert => { - if *idx < cur.idx { + if *idx < cur_idx { s.cast.notify(idx); } else { s.cast.notify(&(*idx + 1)); @@ -800,7 +741,7 @@ where ItemEditor: TerminalEditor + ?Sized + Send + Sync + 'static, let cursor_port = ViewPort::new(); let data_port = ViewPort::new(); - let mut cursor = SingletonBuffer::new(Some(ListCursor::default()), cursor_port.inner()); + let mut cursor = SingletonBuffer::new(ListCursor::default(), cursor_port.inner()); let mut data = VecBuffer::>>::new(data_port.inner()); let data_sequence_port = data_port.into_outer().to_sequence(); @@ -842,53 +783,45 @@ where ItemEditor: TerminalEditor + ?Sized + Send + Sync + 'static, } fn get_item(&self) -> Option>> { - if let Some(cur) = self.cursor.get() { - if cur.idx < self.data.len() { - Some(self.data.get(cur.idx)) - } else { - None - } + if let Some(idx) = self.cursor.get().idx { + Some(self.data.get(idx)) } else { None } } - + fn set_idx(&mut self, idx: isize) { - let mode = - if let Some(c) = self.cursor.get() { - c.mode - } else { - ListCursorMode::Insert - }; + let cur = self.cursor.get(); + let mode = cur.mode; if idx < 0 { - self.cursor.set(Some(ListCursor { + self.cursor.set(ListCursor { mode, - idx: (self.data.len() as isize + idx) as usize - })); + idx: Some((self.data.len() as isize + idx) as usize) + }); } else { - self.cursor.set(Some(ListCursor { + self.cursor.set(ListCursor { mode, - idx: idx as usize - })); + idx: Some(idx as usize) + }); } } fn set_mode(&mut self, mode: ListCursorMode) { - if let Some(old_cur) = self.cursor.get() { - let l = self.data.len(); - if old_cur.idx < l { - self.cursor.set(Some(ListCursor { - mode, - idx: old_cur.idx - })); - } else { - self.cursor.set(Some(ListCursor { - mode: ListCursorMode::Select, - idx: l-1 - })); + let mut cur = self.cursor.get(); + + if cur.mode == ListCursorMode::Insert && + mode != ListCursorMode::Insert + { + if let Some(idx) = cur.idx { + if idx == self.data.len() && idx > 0 { + cur.idx = Some(idx-1); + } } } + + cur.mode = mode; + self.cursor.set(cur); } } diff --git a/nested/src/tree_nav.rs b/nested/src/tree_nav.rs index 7a7c87f..58fc86c 100644 --- a/nested/src/tree_nav.rs +++ b/nested/src/tree_nav.rs @@ -6,13 +6,31 @@ pub enum TreeNavResult { Continue, Exit } - +/* +impl From for TerminalEditorResult { + fn from(v: TreeNavResult) -> TerminalEditorResult { + match v { + TreeNavResult::Continue => TerminalEditorResult::Continue, + TreeNavResult::Exit => TerminalEditorResult::Exit + } + } +} +*/ #[derive(Clone, Eq, PartialEq)] pub struct TreeCursor { pub leaf_mode: ListCursorMode, pub tree_addr: Vec } +impl Default for TreeCursor { + fn default() -> Self { + TreeCursor { + leaf_mode: ListCursorMode::Select, + tree_addr: vec![] + } + } +} + pub trait TreeNav { fn up(&mut self) -> TreeNavResult { TreeNavResult::Exit @@ -38,12 +56,12 @@ pub trait TreeNav { TreeNavResult::Exit } - fn goto(&mut self, new_cursor: Option) -> TreeNavResult { + fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult { TreeNavResult::Exit } - fn get_cursor(&self) -> Option { - None + fn get_cursor(&self) -> TreeCursor { + TreeCursor::default() } } diff --git a/shell/src/main.rs b/shell/src/main.rs index 32854db..b775078 100644 --- a/shell/src/main.rs +++ b/shell/src/main.rs @@ -28,7 +28,7 @@ use{ TerminalView, TerminalEditor}, string_editor::{CharEditor}, - tree_nav::{TreeNav, TreeNavResult, TerminalTreeEditor}, + tree_nav::{TreeNav, TreeNavResult, TreeCursor, TerminalTreeEditor}, list::{SExprView, ListCursorMode, ListEditor, ListEditorStyle} } }; @@ -106,9 +106,9 @@ write:: compositor.write().unwrap().push(magic.offset(Vector2::new(40, 4))); //compositor.write().unwrap().push(magic.offset(Vector2::new(40, 20))); - let monstera_port = monstera::make_monstera(); - compositor.write().unwrap().push(monstera_port.clone()); - compositor.write().unwrap().push(monstera_port.offset(Vector2::new(83,0))); + //let monstera_port = monstera::make_monstera(); + //compositor.write().unwrap().push(monstera_port.clone()); + //compositor.write().unwrap().push(monstera_port.offset(Vector2::new(83,0))); } @@ -129,6 +129,13 @@ write:: let mut te = ListEditor::new(make_sub_editor.clone(), ListEditorStyle::Clist); + te.goto( + TreeCursor { + leaf_mode: ListCursorMode::Insert, + tree_addr: vec![ 0 ] + } + ); + compositor.write().unwrap().push( te.get_term_view() .offset(cgmath::Vector2::new(40,y)) @@ -255,13 +262,28 @@ write:: */ }, ev => { - te.handle_terminal_event(&ev); + if te.get_cursor().leaf_mode == ListCursorMode::Select { + match ev { + TerminalEvent::Input(Event::Key(Key::Char('l'))) => { te.up(); }, + TerminalEvent::Input(Event::Key(Key::Char('a'))) => { te.dn(); }, + TerminalEvent::Input(Event::Key(Key::Char('i'))) => { te.pxev(); }, + TerminalEvent::Input(Event::Key(Key::Char('e'))) => { te.nexd(); }, + TerminalEvent::Input(Event::Key(Key::Char('u'))) => { te.goto_home(); }, + TerminalEvent::Input(Event::Key(Key::Char('o'))) => { te.goto_end(); }, + _ => { + te.handle_terminal_event(&ev); + } + } + } else { + te.handle_terminal_event(&ev); + } } - _ => {} } status_chars.clear(); - if let Some(cur) = te.get_cursor() { + let cur = te.get_cursor(); + + if cur.tree_addr.len() > 0 { status_chars.push(TerminalAtom::new('@', TerminalStyle::fg_color((120, 80, 80)).add(TerminalStyle::bold(true)))); for x in cur.tree_addr { for c in format!("{}", x).chars() {