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>, } + +impl TreeNav for ListEditor +where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, + FnMakeItemEditor: Fn() -> Arc> +{ + 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) -> 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 TerminalEditor for ListEditor -where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static, +where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, FnMakeItemEditor: Fn() -> Arc> { fn get_term_view(&self) -> OuterViewPort { @@ -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 { self.get_seg_seq_view().vertical_sexpr_view(0) } - pub fn path_view(&self) -> OuterViewPort { self.get_seg_seq_view() - .decorate("<", ">", "/", 1) + .decorate("<", ">", "/", 0) + .to_grid_horizontal() + .flatten() + } + pub fn string_view(&self) -> OuterViewPort { + 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) -> 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) -> 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)));