diff --git a/nested/src/integer/digit.rs b/nested/src/integer/digit.rs new file mode 100644 index 0000000..27d2973 --- /dev/null +++ b/nested/src/integer/digit.rs @@ -0,0 +1,76 @@ +use { + std::sync::RwLock, + termion::event::{Key, Event}, + crate::{ + core::{ViewPort, OuterViewPort}, + singleton::{SingletonView, SingletonBuffer}, + vec::VecBuffer, + terminal::{TerminalAtom, TerminalStyle, TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult}, + tree_nav::{TreeNav, TreeNavResult} + } +}; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +pub struct DigitEditor { + radix: u32, + data: SingletonBuffer>, + data_port: ViewPort>> +} + +impl DigitEditor { + pub fn new(radix: u32) -> Self { + let mut data_port = ViewPort::new(); + DigitEditor { + radix, + data: SingletonBuffer::new(None, data_port.inner()), + data_port + } + } + + pub fn get_data_port(&self) -> OuterViewPort>> { + let radix = self.radix; + self.data_port.outer().map( + move |c| c.unwrap_or('?').to_digit(radix) + ) + } +} + +impl TreeNav for DigitEditor {} +impl TerminalEditor for DigitEditor { + fn get_term_view(&self) -> OuterViewPort { + let radix = self.radix; + self.data_port.outer().map( + move |c| TerminalAtom::new( + c.unwrap_or('?'), + if c.unwrap_or('?').to_digit(radix).is_some() { + TerminalStyle::fg_color((100, 140, 100)) + } else { + TerminalStyle::fg_color((200, 0, 0)) + } + ) + ).to_grid() + } + + fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { + match event { + TerminalEvent::Input(Event::Key(Key::Char('\n'))) => + TerminalEditorResult::Continue, + TerminalEvent::Input(Event::Key(Key::Char(c))) => { + self.data.set(Some(*c)); + TerminalEditorResult::Exit + } + TerminalEvent::Input(Event::Key(Key::Backspace)) | + TerminalEvent::Input(Event::Key(Key::Delete)) => { + self.data.set(None); + TerminalEditorResult::Exit + } + _ => TerminalEditorResult::Continue + } + } +} + +struct PosIntEditor { + +} + diff --git a/nested/src/integer/mod.rs b/nested/src/integer/mod.rs index 1c122f8..6544679 100644 --- a/nested/src/integer/mod.rs +++ b/nested/src/integer/mod.rs @@ -1,9 +1,11 @@ pub mod radix; pub mod add; +pub mod digit; pub use { radix::RadixProjection, - add::Add + add::Add, + digit::DigitEditor }; diff --git a/nested/src/list/editor.rs b/nested/src/list/editor.rs index 7b2f98a..fcb69b8 100644 --- a/nested/src/list/editor.rs +++ b/nested/src/list/editor.rs @@ -31,7 +31,6 @@ use { TerminalEditorResult, make_label }, - string_editor::StringEditor, leveled_term_view::LeveledTermView, list::{SExprView, ListDecoration} } @@ -145,10 +144,29 @@ where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, fn goto_end(&mut self) -> TreeNavResult { match self.cursor.get() { - ListEditorCursor::None | - ListEditorCursor::Insert(_) | - ListEditorCursor::Select(_) => - self.goto(vec![ self.data.len()-1 ]), + ListEditorCursor::None => { self.goto(vec![ self.data.len() - 1 ])} + ListEditorCursor::Insert(idx) => { + if idx < self.data.len() { + self.goto(vec![ self.data.len() ]) + } else { + self.up(); + self.nexd(); + self.dn(); + self.goto_end(); + TreeNavResult::Continue + } + } + ListEditorCursor::Select(idx) => { + if idx < self.data.len()-1 { + self.goto(vec![ self.data.len()-1 ]) + } else { + self.up(); + self.nexd(); + self.dn(); + self.goto_end(); + TreeNavResult::Continue + } + } ListEditorCursor::Edit(idx) => { let ce = self.data.get_mut(idx); let mut cur_edit = ce.write().unwrap(); @@ -157,15 +175,18 @@ where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, 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(); + drop(cur_edit); + self.up(); + self.nexd(); + self.dn(); + self.goto_end(); TreeNavResult::Continue } else { self.cursor.set(ListEditorCursor::None); TreeNavResult::Exit } } - } + } } } } @@ -183,8 +204,11 @@ where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, 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(); + drop(cur_edit); + self.up(); + self.pxev(); + self.dn(); + self.goto_home(); TreeNavResult::Continue } else { self.cursor.set(ListEditorCursor::None); @@ -206,6 +230,12 @@ where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, self.data.get_mut(idx).write().unwrap().goto_home(); self.cursor.set(ListEditorCursor::Edit(idx)); } + ListEditorCursor::Edit(idx) => { + let ce = self.data.get_mut(idx); + let mut cur_edit = ce.write().unwrap(); + + cur_edit.dn(); + } _ => {} } TreeNavResult::Continue @@ -239,8 +269,11 @@ where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, 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(); + drop(cur_edit); + self.up(); + self.pxev(); + self.dn(); + self.goto_end(); TreeNavResult::Continue } else { TreeNavResult::Exit @@ -268,6 +301,7 @@ where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, self.cursor.set(ListEditorCursor::Select(idx + 1)); TreeNavResult::Continue } else { + self.cursor.set(ListEditorCursor::None); TreeNavResult::Exit } } @@ -278,8 +312,10 @@ where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, 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(); + drop(cur_edit); + self.up(); + self.nexd(); + self.dn(); TreeNavResult::Continue } else {//if idx+1 == self.data.len() { TreeNavResult::Exit @@ -297,42 +333,74 @@ where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, FnMakeItemEditor: Fn() -> Arc> { fn get_term_view(&self) -> OuterViewPort { - self.horizontal_sexpr_view() + self.terminal_view.clone() } fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { match self.cursor.get() { ListEditorCursor::Insert(idx) => { - self.data.insert(idx, (self.make_item_editor)()); + match event { + TerminalEvent::Input(Event::Key(Key::Backspace)) => { + if idx > 0 { + self.data.remove(idx-1); + self.cursor.set(ListEditorCursor::Insert(idx-1)); + TerminalEditorResult::Continue + } else { + TerminalEditorResult::Exit + } + } + TerminalEvent::Input(Event::Key(Key::Delete)) => { + if idx < self.data.len() { + self.data.remove(idx); + self.cursor.set(ListEditorCursor::Insert(idx)); + TerminalEditorResult::Continue + } else { + TerminalEditorResult::Exit + } + } + TerminalEvent::Input(Event::Key(Key::Insert)) => { + let l = self.data.len(); + if idx < l { + self.cursor.set(ListEditorCursor::Select(idx)); + } else { + self.cursor.set(ListEditorCursor::Select(l-1)) + } + TerminalEditorResult::Continue + } + _ => { + + let new_edit = (self.make_item_editor)(); + self.data.insert(idx, new_edit.clone()); - 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); + new_edit.write().unwrap().goto_home(); + self.cursor.set(ListEditorCursor::Edit(idx)); + match new_edit.write().unwrap().handle_terminal_event(event) { + TerminalEditorResult::Exit => { + self.cursor.set(ListEditorCursor::Insert(idx+1)); + } + _ => {} + } + TerminalEditorResult::Continue + } + } } ListEditorCursor::Edit(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.. - 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 => { - let mut ce = self.data.get_mut(idx); - let mut cur_edit = ce.write().unwrap(); - - cur_edit.handle_terminal_event(event); + cur_edit.up(); + self.cursor.set(ListEditorCursor::Insert(idx+1)); + TerminalEditorResult::Continue } + _ => 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); @@ -345,11 +413,10 @@ where SubEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, } _=>{} } + TerminalEditorResult::Continue } - _ => {} + _ => TerminalEditorResult::Continue } - - TerminalEditorResult::Continue } } @@ -472,7 +539,7 @@ impl ListEditorView { ); s.cast.notify_each( - begin ..= end + 0 ..= s.data.len().unwrap_or(0)+1 ); }), data: proj_helper.new_sequence_arg( @@ -502,11 +569,19 @@ impl ListEditorView { } } +pub enum ListEditorStyle { + HorizontalSexpr, + VerticalSexpr, + Path, + String, + Clist, + Hex +} + impl ListEditor where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static, FnMakeItemEditor: Fn() -> Arc> { - pub fn get_seg_seq_view(&self) -> OuterViewPort>> { self.segment_seq .map( @@ -538,9 +613,11 @@ where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static, pub fn horizontal_sexpr_view(&self) -> OuterViewPort { self.get_seg_seq_view().horizontal_sexpr_view(0) } + 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("<", ">", "/", 0) @@ -553,8 +630,21 @@ where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static, .to_grid_horizontal() .flatten() } + pub fn clist_view(&self) -> OuterViewPort { + self.get_seg_seq_view() + .decorate("{", "}", ", ", 1) + .to_grid_horizontal() + .flatten() + } - pub fn new(make_item_editor: FnMakeItemEditor) -> Self { + pub fn hex_view(&self) -> OuterViewPort { + self.get_seg_seq_view() + .decorate("0x", "", "", 0) + .to_grid_horizontal() + .flatten() + } + + pub fn new(make_item_editor: FnMakeItemEditor, style: ListEditorStyle) -> Self { let cursor_port = ViewPort::new(); let data_port = ViewPort::new(); @@ -570,16 +660,30 @@ where SubEditor: TerminalEditor + ?Sized + Send + Sync + 'static, segment_view_port.inner() ); - ListEditor { + let mut le = ListEditor { data, data_sequence_port, cursor, make_item_editor, level: 0, - segment_seq: segment_view_port.outer() - } + segment_seq: segment_view_port.outer(), + terminal_view: make_label("lol"), + }; + le.set_style(style); + le } + pub fn set_style(&mut self, style: ListEditorStyle) { + self.terminal_view = match style { + ListEditorStyle::HorizontalSexpr => self.horizontal_sexpr_view(), + ListEditorStyle::VerticalSexpr => self.vertical_sexpr_view(), + ListEditorStyle::Path => self.path_view(), + ListEditorStyle::String => self.string_view(), + ListEditorStyle::Clist => self.clist_view(), + ListEditorStyle::Hex => self.hex_view() + } + } + pub fn get_data_port(&self) -> OuterViewPort>>> { self.data_sequence_port.clone() } diff --git a/nested/src/list/mod.rs b/nested/src/list/mod.rs index eaed748..3f15b3d 100644 --- a/nested/src/list/mod.rs +++ b/nested/src/list/mod.rs @@ -2,6 +2,6 @@ pub mod editor; pub mod sexpr; -pub use editor::ListEditor; +pub use editor::{ListEditor, ListEditorStyle}; pub use sexpr::{SExprView, ListDecoration}; diff --git a/nested/src/list/sexpr.rs b/nested/src/list/sexpr.rs index 810a576..f6cae55 100644 --- a/nested/src/list/sexpr.rs +++ b/nested/src/list/sexpr.rs @@ -34,7 +34,7 @@ impl SequenceView for ListDecorator { fn len(&self) -> Option { let l = self.items.len()?; - Some(if l == 0 { 2 } else { 2 * l + 2 }) + Some(if l == 0 { 2 } else { 2 * l + 1 }) } fn get(&self, idx: &usize) -> Option { diff --git a/nested/src/string_editor.rs b/nested/src/string_editor.rs index e47fe28..db7a44d 100644 --- a/nested/src/string_editor.rs +++ b/nested/src/string_editor.rs @@ -12,271 +12,52 @@ use { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -#[derive(Clone)] -pub struct StringEditor { - data: VecBuffer, - cursor: SingletonBuffer>, - - data_port: ViewPort>>, - cursor_port: ViewPort>> +pub struct CharEditor { + data: SingletonBuffer>, + data_port: ViewPort>> } -impl StringEditor { +impl CharEditor { pub fn new() -> Self { - let data_port = ViewPort::new(); - let cursor_port = ViewPort::new(); - - StringEditor { - data: VecBuffer::new(data_port.inner()), - cursor: SingletonBuffer::new(None, cursor_port.inner()), - - data_port, - cursor_port + let mut data_port = ViewPort::new(); + CharEditor { + data: SingletonBuffer::new(None, data_port.inner()), + data_port } } - - pub fn insert_view(&self) -> OuterViewPort { - let port = ViewPort::new(); - insert_view::StringInsertView::new( - self.get_cursor_port(), - self.get_data_port().to_sequence(), - port.inner() - ); - port.into_outer() - } - - pub fn get_data_port(&self) -> OuterViewPort>> { + pub fn get_data_port(&self) -> OuterViewPort>> { self.data_port.outer() } - - pub fn get_cursor_port(&self) -> OuterViewPort>> { - self.cursor_port.outer() - } - - pub fn insert(&mut self, c: char) -> TreeNavResult { - self.data.insert(self.cursor.get().unwrap_or(0), c); - self.nexd() - } - - 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.pxev() - } - - pub fn delete(&mut self) -> TreeNavResult { - let cur = self.cursor.get().unwrap_or(0); - if cur < self.data.len() { - self.data.remove(cur); - TreeNavResult::Continue - } else { - self.cursor.set(None); - 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]) - } - } -} - -impl TerminalEditor for StringEditor { +impl TreeNav for CharEditor {} +impl TerminalEditor for CharEditor { fn get_term_view(&self) -> OuterViewPort { - self.insert_view() + crate::terminal::make_label( + &if let Some(c) = self.data.get() { + c.to_string() + } else { + "".to_string() + }) } fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { match event { - TerminalEvent::Input(Event::Key(Key::Char('\n'))) => TerminalEditorResult::Continue, - TerminalEvent::Input(Event::Key(Key::Char(c))) => match self.insert(*c) { - TreeNavResult::Exit => TerminalEditorResult::Exit, - TreeNavResult::Continue => TerminalEditorResult::Continue + TerminalEvent::Input(Event::Key(Key::Char('\n'))) => + TerminalEditorResult::Continue, + TerminalEvent::Input(Event::Key(Key::Char(c))) => { + self.data.set(Some(*c)); + TerminalEditorResult::Exit } - 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 + TerminalEvent::Input(Event::Key(Key::Backspace)) | + TerminalEvent::Input(Event::Key(Key::Delete)) => { + self.data.set(None); + TerminalEditorResult::Exit } _ => TerminalEditorResult::Continue } } } -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub mod insert_view { - use { - std::{ - sync::Arc, - cmp::{min, max} - }, - cgmath::Point2, - std::sync::RwLock, - crate::{ - core::{View, Observer, ObserverExt, ObserverBroadcast, OuterViewPort, InnerViewPort}, - terminal::{TerminalAtom, TerminalStyle, TerminalView}, - grid::{GridWindowIterator}, - singleton::{SingletonView}, - sequence::{SequenceView}, - index::{IndexView}, - projection::{ProjectionHelper}, - } - }; - - pub struct StringInsertView { - cursor: Arc>>, - data: Arc>>, - cur_pos: Option, - - cast: Arc>>, - proj_helper: ProjectionHelper - } - - impl View for StringInsertView { - type Msg = Point2; - } - - impl IndexView> for StringInsertView { - type Item = TerminalAtom; - - fn get(&self, pos: &Point2) -> Option { - if pos.y == 0 && pos.x >= 0 { - let i = pos.x as usize; - let data = self.data.read().unwrap(); - let len = data.len().unwrap_or(0); - - if i < len+1 { - return Some( - if i < self.cur_pos.unwrap_or(usize::MAX) { - TerminalAtom::from(data.get(&i)?) - } else if i == self.cur_pos.unwrap_or(usize::MAX) { - TerminalAtom::new('|', TerminalStyle::fg_color((90, 60, 200))) - } else { - TerminalAtom::from(data.get(&(i - 1))?) - } - ); - } - } - - None - } - - fn area(&self) -> Option>> { - Some(GridWindowIterator::from( - Point2::new(0, 0) .. Point2::new(self.data.len()? as i16 + if self.cursor.get().is_some() { 1 } else { 0 }, 1) - ).collect()) - } - } - - impl StringInsertView { - pub fn new( - 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( - StringInsertView { - cursor: proj_helper.new_singleton_arg( - cursor_port, - |s: &mut Self, _msg| { - let old_pos = s.cur_pos.unwrap_or(0); - s.cur_pos = s.cursor.get(); - let new_pos = s.cur_pos.unwrap_or(0); - s.cast.notify_each(GridWindowIterator::from(Point2::new(min(old_pos, new_pos) as i16,0) ..= Point2::new(max(old_pos, new_pos) as i16, 0))) - }), - - data: proj_helper.new_sequence_arg( - data_port, - |s: &mut Self, idx| { - s.cast.notify(&Point2::new( - if *idx < s.cur_pos.unwrap_or(0) { - *idx as i16 - } else { - *idx as i16 + 1 - }, - 0 - )); - }), - - cur_pos: None, - cast: out_port.get_broadcast(), - - proj_helper - } - )); - - proj.write().unwrap().proj_helper.set_proj(&proj); - out_port.set_view(Some(proj.clone())); - - proj - } - } -} - diff --git a/shell/src/main.rs b/shell/src/main.rs index a7d3cbf..21b0354 100644 --- a/shell/src/main.rs +++ b/shell/src/main.rs @@ -17,7 +17,7 @@ use{ index::{IndexView}, sequence::{SequenceView}, vec::{VecBuffer}, - integer::{RadixProjection}, + integer::{RadixProjection, DigitEditor}, terminal::{ Terminal, TerminalStyle, @@ -27,9 +27,9 @@ use{ make_label, TerminalView, TerminalEditor}, - string_editor::StringEditor, + string_editor::{CharEditor}, tree_nav::{TreeNav, TreeNavResult, TerminalTreeEditor}, - list::{SExprView, ListEditor} + list::{SExprView, ListEditor, ListEditorStyle} } }; @@ -81,197 +81,14 @@ write:: */ - let mut args = std::env::args(); -/* - let arg0_port = ViewPort::new(); - let _arg0 = VecBuffer::::with_data( - args.next().expect("Arg $0 missing!") - .chars().collect::>(), - arg0_port.inner() - ); -*/ - let arg1_vec_port = ViewPort::new(); - let mut arg1 = VecBuffer::::with_data( - vec!['1'], -/* - args.next().expect("Arg $1 missing!") - .chars().collect::>(), -*/ - arg1_vec_port.inner() - ); -/* - let _arg1_vec = args.next().expect("Arg $1 missing!") - .chars().collect::>(); -*/ let term_port = ViewPort::new(); let compositor = TerminalCompositor::new(term_port.inner()); - let mut ed = StringEditor::new(); - let mut term = Terminal::new(term_port.outer()); let term_writer = term.get_writer(); async_std::task::spawn( async move { - let mut ctx = Context::new(); - for tn in vec![ - "MachineWord", "MachineInt", "MachineSyllab", "Bits", - "Vec", "Stream", "Json", - "Sequence", "UTF-8-String", "UnicodeChar", - "PositionalInt", "Digit", "LittleEndian", "BigEndian", - "DiffStream", "ℕ" - ] { ctx.add_typename(tn.into()); } - - let src_type = - ctx.type_term_from_str("( Vec UnicodeChar )").unwrap(); - - let dst_type = - ctx.type_term_from_str("( Sequence UnicodeChar )").unwrap(); - - ctx.add_morphism( - MorphismType { - mode: MorphismMode::Epi, - src_type: src_type.clone(), - dst_type: dst_type.clone() - }, - Box::new(move |src| { - assert!(src.type_tag == src_type); - Object { - type_tag: dst_type.clone(), - repr: ReprTree::new_leaf( - src.get_port::>>().unwrap() - .to_sequence() - .into() - ) - } - }) - ); - - let src_type = ctx.type_term_from_str("( Sequence UnicodeChar )").unwrap(); - let dst_type = ctx.type_term_from_str("( Sequence ( Bits 32 ) )").unwrap(); - ctx.add_morphism( - MorphismType { - mode: MorphismMode::Mono, - src_type: src_type.clone(), - dst_type: dst_type.clone() - }, - Box::new({ - move |src| { - assert!(src.type_tag == src_type); - Object { - type_tag: dst_type.clone(), - repr: ReprTree::new_leaf( - src.get_port::>().unwrap() - .map( - |c| *c as u32 - ) - .into() - ) - } - } - }) - ); - -/* - let src_type = vec![ - ctx.type_term_from_str("( PositionalInteger )").unwrap(), - ]; - let dst_type = ctx.type_term_from_str("( Sequence MachineInt )").unwrap(); - ctx.add_morphism( - MorphismType { - mode: MorphismMode::Epi, - src_type: src_type.clone(), - dst_type: dst_type.clone() - }, - Box::new({ - move |src| { - assert!(src.type_tag == src_type); - Object { - type_tag: dst_type.clone(), - repr: ReprTree::new_leaf( - vec![ dst_type.clone() ].into_iter(), - src.get_port::>>().unwrap().to_sequence().into() - ) - } - } - }) - ); - */ - - let arg1_vec_port = ed.get_data_port(); - - ctx.add_obj("$1".into(), "( Vec UnicodeChar )"); - ctx.insert_repr( - "$1", - vec![].into_iter(), - arg1_vec_port.clone().into() - ); - - ctx.epi_cast("$1", "( Sequence UnicodeChar )"); - ctx.epi_cast("$1", "( Sequence ( Digit 10 ) )"); - ctx.epi_cast("$1", "( PositionalInt 10 LittleEndian )"); - ctx.epi_cast("$1", "( ℕ )"); - - let arg1_dec_unic_port: OuterViewPort> = - ctx.mono_view( - "$1", - vec![ - "( PositionalInt 10 LittleEndian )", - "( Sequence ( Digit 10 ) )", - "( Sequence UnicodeChar )" - ].into_iter() - ).unwrap(); - - let arg1_dec_mint_port: OuterViewPort> = - arg1_dec_unic_port - .map(|c| c.to_digit(10).map(|x| x as usize)) - .filter(|d| d.is_some()) - .map(|d| d.unwrap()); - - ctx.insert_repr( - "$1", - vec![ - "( PositionalInt 10 LittleEndian )", - "( Sequence ( Digit 10 ) )", - "( Sequence MachineInt )" - ].into_iter(), - arg1_dec_mint_port.clone().into() - ); - - let arg1_hex_mint_port: ViewPort>> - = ViewPort::new(); - let _radix_proj = RadixProjection::new( - 10, - 16, - arg1_dec_mint_port.clone(), - arg1_hex_mint_port.inner() - ); - - ctx.insert_repr( - "$1", - vec![ - "( PositionalInt 16 LittleEndian )", - "( Sequence ( Digit 16 ) )", - "( Sequence MachineInt )" - ].into_iter(), - arg1_hex_mint_port.outer().to_sequence().into() - ); - - let arg1_hex_unic_port: OuterViewPort> = - arg1_hex_mint_port.outer().to_sequence() - .map( - |d| char::from_digit(*d as u32, 16).unwrap() - ); - - ctx.insert_repr( - "$1", - vec![ - "( PositionalInt 16 LittleEndian )", - "( Sequence ( Digit 16 ) )", - "( Sequence UnicodeChar )" - ].into_iter(), - arg1_hex_unic_port.clone().into() - ); let magic = make_label("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>") .map_item( @@ -302,19 +119,33 @@ write:: // TypeEditor - let make_sub_editor = || { - std::sync::Arc::new(std::sync::RwLock::new(StringEditor::new())) + let make_char_editor = || { + std::sync::Arc::new(std::sync::RwLock::new(DigitEditor::new(16))) }; - let mut te = ListEditor::new(make_sub_editor.clone()); + let make_sub_editor = move || { + std::sync::Arc::new(std::sync::RwLock::new(ListEditor::new(make_char_editor.clone(), ListEditorStyle::Hex))) + }; + + let mut te = ListEditor::new(make_sub_editor.clone(), ListEditorStyle::Clist); compositor.write().unwrap().push( - te.path_view() + te.get_term_view() .offset(cgmath::Vector2::new(40,y)) ); y += 1; - let mut p = te.get_data_port().map(|string_editor| string_editor.read().unwrap().get_data_port()); + let mut p = te.get_data_port().map(|sub_editor| sub_editor.read().unwrap().get_data_port()); + + let status_chars_port = ViewPort::new(); + let mut status_chars = VecBuffer::new(status_chars_port.inner()); + + compositor.write().unwrap().push( + status_chars_port.outer() + .to_sequence() + .to_grid_horizontal() + .offset(cgmath::Vector2::new(40, 2)) + ); loop { term_port.update(); @@ -343,10 +174,19 @@ write:: } 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::Home)) => { + if te.goto_home() == TreeNavResult::Exit { + te.goto_home(); + } + } + TerminalEvent::Input(Event::Key(Key::End)) => { + if te.goto_end() == TreeNavResult::Exit { + te.goto_end(); + } + } TerminalEvent::Input(Event::Key(Key::Char('\n'))) => { + /* let mut strings = Vec::new(); let v = p.get_view().unwrap(); @@ -412,12 +252,27 @@ write:: y += 1; p = te.get_data_port().map(|string_editor| string_editor.read().unwrap().get_data_port()); +*/ }, ev => { te.handle_terminal_event(&ev); } _ => {} } + + status_chars.clear(); + match te.get_cursor() { + Some(addr) => { + status_chars.push(TerminalAtom::new('@', TerminalStyle::fg_color((120, 80, 80)).add(TerminalStyle::bold(true)))); + for x in addr { + for c in format!("{}", x).chars() { + status_chars.push(TerminalAtom::new(c, TerminalStyle::fg_color((0, 100, 20)))); + } + status_chars.push(TerminalAtom::new('.', TerminalStyle::fg_color((120, 80, 80)))); + } + } + None => {} + } } //drop(term);