diff --git a/nested/src/char_editor.rs b/nested/src/char_editor.rs index bb63295..9a6e927 100644 --- a/nested/src/char_editor.rs +++ b/nested/src/char_editor.rs @@ -1,6 +1,6 @@ use { crate::{ - core::{OuterViewPort, ViewPort}, + core::{OuterViewPort, ViewPort, Context}, list::{ListEditor}, sequence::{SequenceView, SequenceViewExt}, singleton::{SingletonBuffer, SingletonView}, @@ -10,7 +10,7 @@ use { }, tree::{TreeCursor, TreeNav, TreeNavResult}, diagnostics::Diagnostics, - Nested + Nested, tree::NestedNode, Commander }, std::sync::Arc, std::sync::RwLock, @@ -22,6 +22,23 @@ pub struct CharEditor { data: SingletonBuffer> } +impl Commander for CharEditor { + type Cmd = TerminalEvent; + + fn send_cmd(&mut self, event: &TerminalEvent) { + 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); + } + _ => {} + } + } +} + impl CharEditor { pub fn new() -> Self { CharEditor { @@ -36,40 +53,32 @@ impl CharEditor { pub fn get(&self) -> char { self.get_port().get_view().unwrap().get().unwrap_or('?') } -} -impl TreeNav for CharEditor {} -impl Diagnostics for CharEditor {} + pub fn new_node(ctx: &Arc>) -> NestedNode { + let data = SingletonBuffer::new(None); -impl TerminalEditor for CharEditor { - fn get_term_view(&self) -> OuterViewPort { - self.data - .get_port() - .map(move |c| { - TerminalAtom::from( - c.unwrap_or('?') - ) - }) - .to_grid() - } - - fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { - match event { - TerminalEvent::Input(Event::Key(Key::Char('\n'))) => TerminalEditorResult::Exit, - 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, - } + NestedNode::new() + .set_ctx(ctx.clone()) + .set_view(data + .get_port() + .map(move |c| { + match c { + Some(c) => TerminalAtom::from(c), + None => TerminalAtom::new('*', TerminalStyle::fg_color((255,0,0))) + } + }) + .to_grid() + ) + .with_cmd( + Arc::new(RwLock::new(CharEditor{ data })) + ) } } -impl Nested for CharEditor {} - +use crate::StringGen; +impl StringGen for CharEditor { + fn get_string(&self) -> String { + String::from(self.get()) + } +} diff --git a/nested/src/core/context.rs b/nested/src/core/context.rs index 07964e4..e5a5f0f 100644 --- a/nested/src/core/context.rs +++ b/nested/src/core/context.rs @@ -36,8 +36,8 @@ impl ReprTree { Arc::new(RwLock::new(tree)) } - pub fn insert_branch(&mut self, type_tag: TypeTerm, repr: Arc>) { - self.branches.insert(type_tag, repr); + pub fn insert_branch(&mut self, repr: Arc>) { + self.branches.insert(repr.clone().read().unwrap().type_tag.clone(), repr.clone()); } pub fn insert_leaf( @@ -51,7 +51,7 @@ impl ReprTree { } else { let mut next_repr = ReprTree::new(type_term.clone()); next_repr.insert_leaf(type_ladder, port); - self.insert_branch(type_term, Arc::new(RwLock::new(next_repr))); + self.insert_branch(Arc::new(RwLock::new(next_repr))); } } else { self.port = Some(port); @@ -73,6 +73,15 @@ impl ReprTree { ) } + pub fn get_view(&self) -> Option> + where + V::Msg: Clone, + { + self.get_port::()? + .get_view() + } + + // descend pub fn downcast(&self, dst_type: &TypeTerm) -> Option>> { self.branches.get(dst_type).cloned() } @@ -84,6 +93,13 @@ impl ReprTree { |s, t| s?.read().unwrap().downcast(&t)) } + // ascend + pub fn upcast(rt: &Arc>, type_term: TypeTerm) -> Arc> { + let mut n = Self::new(type_term); + n.insert_branch(rt.clone()); + Arc::new(RwLock::new(n)) + } + /* pub fn add_iso_repr( &self, @@ -268,6 +284,7 @@ impl Context { pub fn type_term_from_str(&self, tn: &str) -> Option { self.type_dict.read().unwrap().type_term_from_str(&tn) } + pub fn type_term_to_str(&self, t: &TypeTerm) -> String { self.type_dict.read().unwrap().type_term_to_str(&t) } diff --git a/nested/src/grid/flatten.rs b/nested/src/grid/flatten.rs index 8010cac..c934029 100644 --- a/nested/src/grid/flatten.rs +++ b/nested/src/grid/flatten.rs @@ -1,6 +1,6 @@ use { crate::{ - core::{InnerViewPort, Observer, ObserverBroadcast, OuterViewPort, View, ViewPort}, + core::{InnerViewPort, Observer, ObserverBroadcast, OuterViewPort, View, ViewPort, port::UpdateTask}, grid::{GridView, GridWindowIterator}, index::{IndexArea, IndexView}, projection::ProjectionHelper, @@ -113,15 +113,21 @@ where } if let Some(chunk) = s.chunks.get(&chunk_idx) { - s.cast.notify(&area.map(|pt| pt + chunk.offset)); + s.cast.notify(&area.map(|pt| pt + chunk.offset)); } }, ); if let Some(chunk) = self.chunks.get_mut(&chunk_idx) { chunk.view = view; - self.cast - .notify(&chunk.view.area().map(|pt| pt + chunk.offset)); + + let old_limit = chunk.limit; + let new_limit = *chunk.view.area().range().end(); + + self.cast.notify( + &IndexArea::Range( + Point2::new(chunk.offset.x, chunk.offset.y) ..= Point2::new(chunk.offset.x + max(old_limit.x, new_limit.x), chunk.offset.y + max(old_limit.y, new_limit.y) ))); + } else { self.chunks.insert( chunk_idx, @@ -132,7 +138,7 @@ where }, ); } - + self.update_all_offsets(); } else { self.proj_helper.remove_arg(&chunk_idx); @@ -168,15 +174,18 @@ where for chunk_idx in GridWindowIterator::from(top_range.clone()) { if let Some(chunk) = self.chunks.get_mut(&chunk_idx) { - let _old_offset = chunk.offset; - let _old_limit = chunk.limit; + let old_offset = chunk.offset; + let old_limit = chunk.limit; + //chunk.limit = Point2::new( col_widths[chunk_idx.x as usize]-1, row_heights[chunk_idx.y as usize]-1 ); chunk.limit = *chunk.view.area().range().end(); + chunk.offset = Vector2::new( (0..chunk_idx.x as usize).map(|x| col_widths[x]).sum(), (0..chunk_idx.y as usize).map(|y| row_heights[y]).sum(), ); - /* +/* + if old_offset != chunk.offset { self.cast.notify( &IndexArea::Range( @@ -191,7 +200,7 @@ where ) ); } - */ +*/ } } @@ -214,6 +223,7 @@ where max(self.limit.y, old_limit.y), ), )); + } /// given an index in the flattened sequence, diff --git a/nested/src/integer/editor.rs b/nested/src/integer/editor.rs index 003b845..f55c5f3 100644 --- a/nested/src/integer/editor.rs +++ b/nested/src/integer/editor.rs @@ -65,7 +65,8 @@ impl TerminalEditor for DigitEditor { fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { match event { - TerminalEvent::Input(Event::Key(Key::Char(' '))) + TerminalEvent::Input(Event::Key(Key::Ctrl('x'))) + | TerminalEvent::Input(Event::Key(Key::Char(' '))) | TerminalEvent::Input(Event::Key(Key::Char('\n'))) => TerminalEditorResult::Exit, TerminalEvent::Input(Event::Key(Key::Char(c))) => { self.data.set(Some(*c)); @@ -116,7 +117,7 @@ impl PosIntEditor { digits_editor: PTYListEditor::new( Box::new(move || Arc::new(RwLock::new(DigitEditor::new(radix)))) as Box Arc> + Send + Sync>, SeqDecorStyle::Hex, - ' ', + None, 0 ), } @@ -195,7 +196,8 @@ impl TerminalEditor for PosIntEditor { fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { match event { - TerminalEvent::Input(Event::Key(Key::Char(' '))) + TerminalEvent::Input(Event::Key(Key::Ctrl('x'))) + | TerminalEvent::Input(Event::Key(Key::Char(' '))) | TerminalEvent::Input(Event::Key(Key::Char('\n'))) => { self.digits_editor.up(); TerminalEditorResult::Exit diff --git a/nested/src/integer/radix.rs b/nested/src/integer/radix.rs index 8aca421..9d53504 100644 --- a/nested/src/integer/radix.rs +++ b/nested/src/integer/radix.rs @@ -16,10 +16,19 @@ pub struct RadixProjection { impl RadixProjection { pub fn new( + // static parameters + //--- src_radix: usize, dst_radix: usize, + //--- + + // dynamic parameters + //--- + // input src_digits: OuterViewPort>, + // output dst_digits: InnerViewPort>>, + //--- ) -> Arc> { dst_digits.0.add_update_hook(Arc::new(src_digits.0.clone())); let proj = Arc::new(RwLock::new(RadixProjection { diff --git a/nested/src/lib.rs b/nested/src/lib.rs index 0629432..c2b7a82 100644 --- a/nested/src/lib.rs +++ b/nested/src/lib.rs @@ -27,6 +27,7 @@ pub mod diagnostics; pub mod char_editor; pub mod integer; pub mod make_editor; +pub mod type_term_editor; // display pub mod color; @@ -36,16 +37,50 @@ pub fn magic_header() { eprintln!("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>"); } -use crate::terminal::{TerminalEditor}; -use crate::diagnostics::{Diagnostics}; -use crate::tree::{TreeNav, TreeType}; +pub trait Commander { + type Cmd; + + fn send_cmd(&mut self, cmd: &Self::Cmd); +} + +use std::sync::{Arc, RwLock}; +use crate::{ + core::context::ReprTree, + singleton::SingletonView +}; + +pub trait ObjCommander { + fn send_cmd_obj(&mut self, cmd_obj: Arc>); +} + +//impl> ObjCommander for T { +impl ObjCommander for C +where C::Cmd: 'static +{ + fn send_cmd_obj(&mut self, cmd_obj: Arc>) { + self.send_cmd( + &cmd_obj.read().unwrap() + .get_port::>().unwrap() + .get_view().unwrap() + .get() + ); + } +} + +pub trait StringGen { + fn get_string(&self) -> String; +} + +use crate::terminal::TerminalEditor; +use crate::{tree::{TreeNav}, diagnostics::Diagnostics}; pub trait Nested : TerminalEditor + TreeNav -// + TreeType + // + TreeType + Diagnostics + Send + Sync + + std::any::Any {} diff --git a/nested/src/list/editor.rs b/nested/src/list/editor.rs index 799116e..14589e4 100644 --- a/nested/src/list/editor.rs +++ b/nested/src/list/editor.rs @@ -22,12 +22,12 @@ use { }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - + pub struct ListEditor where ItemEditor: Nested + ?Sized + Send + Sync + 'static { pub(super) cursor: SingletonBuffer, - pub(super) data: VecBuffer>>, + pub(crate) data: VecBuffer>>, pub(super) make_item_editor: Box Arc> + Send + Sync>, pub(super) depth: usize, diff --git a/nested/src/list/pty_editor.rs b/nested/src/list/pty_editor.rs index 2b4e51d..26fb5b1 100644 --- a/nested/src/list/pty_editor.rs +++ b/nested/src/list/pty_editor.rs @@ -28,8 +28,8 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static { pub editor: ListEditor, - split_char: char, - + split_char: Option, + style: SeqDecorStyle, depth: usize, @@ -42,7 +42,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static pub fn new( make_item_editor: impl Fn() -> Arc> + Send + Sync + 'static, style: SeqDecorStyle, - split_char: char, + split_char: Option, depth: usize ) -> Self { Self::from_editor(ListEditor::new(make_item_editor, depth), style, split_char, depth) @@ -51,7 +51,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static pub fn from_editor( editor: ListEditor, style: SeqDecorStyle, - split_char: char, + split_char: Option, depth: usize ) -> Self { let port = editor @@ -140,15 +140,15 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static let mut ne = new_edit.write().unwrap(); ne.goto(TreeCursor::home()); - match ne.handle_terminal_event(event) { - TerminalEditorResult::Exit => { - self.editor.cursor.set(ListCursor { - mode: ListCursorMode::Insert, - idx: Some(idx as isize + 1), - }); - } - _ => {} + ne.handle_terminal_event(event); + + if self.split_char.is_none() { + self.editor.cursor.set(ListCursor { + mode: ListCursorMode::Insert, + idx: Some(idx as isize + 1), + }); } + TerminalEditorResult::Continue } }, @@ -161,36 +161,41 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static } TerminalEvent::Input(Event::Key(Key::Char(c))) => { - if *c == self.split_char { + if Some(*c) == self.split_char { let c = self.editor.cursor.get(); self.editor.goto(TreeCursor::none()); self.editor.cursor.set(ListCursor { mode: ListCursorMode::Insert, idx: Some(1 + c.idx.unwrap_or(0)) }); + TerminalEditorResult::Continue } else { if let Some(e) = self.editor.get_item() { - match e.write().unwrap().handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char(*c)))) { - TerminalEditorResult::Exit => { + e.write().unwrap().handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char(*c)))); + //match + if self.split_char.is_none() { + // TerminalEditorResult::Exit => + { self.editor.cursor.set(ListCursor { mode: ListCursorMode::Insert, idx: Some(idx as isize + 1), }); } - TerminalEditorResult::Continue => { - - } + // TerminalEditorResult::Continue => { + // } } } + TerminalEditorResult::Exit } - TerminalEditorResult::Continue } ev => { if let Some(e) = self.editor.get_item() { match e.write().unwrap().handle_terminal_event(ev) { TerminalEditorResult::Exit => { - match ev { + TerminalEvent::Input(Event::Key(Key::Ctrl('x'))) => { + return TerminalEditorResult::Exit + } TerminalEvent::Input(Event::Key(Key::Backspace)) => { self.editor.data.remove(idx as usize); self.editor.cursor.set(ListCursor { @@ -268,18 +273,32 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static } } +/* +impl TreeType for PTYListEditor +where ItemEditor: Nested + TreeType + ?Sized + Send + Sync + 'static +{ + fn get_type(&self, addr: &Vec) -> TypeTerm { + TypeTerm::new(0) + } +} +*/ impl Nested for PTYListEditor where ItemEditor: Nested + ?Sized + Send + Sync + 'static {} use crate::{ char_editor::CharEditor, - sequence::SequenceViewExt + sequence::SequenceViewExt, + StringGen }; -impl PTYListEditor { - pub fn get_string(&self) -> String { - self.get_data_port().map(|ce| ce.read().unwrap().get()).get_view().unwrap().iter().collect::() +impl StringGen for PTYListEditor { + + fn get_string(&self) -> String { + self.get_data_port() + .map(|ce| ce.read().unwrap().get_string()) + .get_view().unwrap() + .iter().collect::() } } diff --git a/nested/src/make_editor.rs b/nested/src/make_editor.rs index b7822a8..5261006 100644 --- a/nested/src/make_editor.rs +++ b/nested/src/make_editor.rs @@ -1,4 +1,3 @@ - use { crate::{ core::{TypeTerm, TypeLadder, Context, OuterViewPort}, @@ -17,38 +16,6 @@ use { std::sync::{Arc, RwLock}, }; -enum RhsNode { - Sum ( - Arc >> - ), - Product ( - Arc >> - ), - String( - Arc >> - ) -} - -impl TreeNav for RhsNode {} - -impl TerminalEditor for RhsNode { - fn get_term_view(&self) -> OuterViewPort { - make_label("todo") - } - - fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { - TerminalEditorResult::Continue - } -} - -impl Diagnostics for RhsNode {} -impl Nested for RhsNode {} - -struct GrammarRuleEditor { - lhs: Arc>>, - rhs: Arc>> -} - pub fn init_editor_ctx(parent: Arc>) -> Arc> { let mut ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent)))); @@ -56,7 +23,7 @@ pub fn init_editor_ctx(parent: Arc>) -> Arc> { "Char", Arc::new( |ctx: Arc>, ty: TypeTerm, _depth: usize| { Some( - Arc::new(RwLock::new(CharEditor::new())) + Arc::new(RwLock::new(CharEditor::new_node(&ctx))) as Arc>) } ) @@ -70,7 +37,7 @@ pub fn init_editor_ctx(parent: Arc>) -> Arc> { id, args } => { if args.len() > 0 { - // todod factor style out of type arGS + // todo: factor style out of type arGS let style = if args.len() > 1 { match args[1] { TypeTerm::Num(0) => SeqDecorStyle::Plain, @@ -82,23 +49,23 @@ pub fn init_editor_ctx(parent: Arc>) -> Arc> { TypeTerm::Num(6) => SeqDecorStyle::Path, _ => SeqDecorStyle::HorizontalSexpr } - }else { + } else { SeqDecorStyle::HorizontalSexpr }; let delim = if args.len() > 1 { match args[1] { - TypeTerm::Num(0) => ' ', - TypeTerm::Num(1) => ' ', - TypeTerm::Num(2) => '\n', - TypeTerm::Num(3) => '"', - TypeTerm::Num(4) => ',', - TypeTerm::Num(5) => ',', - TypeTerm::Num(6) => '/', - _ => '\0' + TypeTerm::Num(0) => Some(' '), + TypeTerm::Num(1) => Some(' '), + TypeTerm::Num(2) => Some('\n'), + TypeTerm::Num(3) => None, + TypeTerm::Num(4) => Some(','), + TypeTerm::Num(5) => Some(','), + TypeTerm::Num(6) => Some('/'), + _ => None } }else { - '\0' + None }; Some( @@ -167,13 +134,16 @@ pub fn init_editor_ctx(parent: Arc>) -> Arc> { } ) ); - + + ctx.write().unwrap().add_typename("TerminalEvent".into()); ctx } pub fn init_math_ctx(parent: Arc>) -> Arc> { let mut ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent)))); + ctx.write().unwrap().add_typename("MachineInt".into()); + ctx.write().unwrap().add_typename("Digit".into()); ctx.write().unwrap().add_typename("BigEndian".into()); ctx.write().unwrap().add_editor_ctor( "PosInt", Arc::new( diff --git a/nested/src/path/mod.rs b/nested/src/path/mod.rs new file mode 100644 index 0000000..a00124b --- /dev/null +++ b/nested/src/path/mod.rs @@ -0,0 +1,10 @@ + +pub struct PathSegmentEditor { + parent: Path, + +} + +pub struct PathEditor { + +} + diff --git a/nested/src/singleton/buffer.rs b/nested/src/singleton/buffer.rs index d7e9596..accfbcf 100644 --- a/nested/src/singleton/buffer.rs +++ b/nested/src/singleton/buffer.rs @@ -64,7 +64,7 @@ where pub fn get_port(&self) -> OuterViewPort> { self.port.0.outer() } - + pub fn get(&self) -> T { self.value.read().unwrap().clone() } diff --git a/nested/src/sum/editor.rs b/nested/src/sum/editor.rs index f4e28f3..ccf5fa3 100644 --- a/nested/src/sum/editor.rs +++ b/nested/src/sum/editor.rs @@ -23,7 +23,7 @@ use { pub struct SumEditor { cur: usize, - editors: Vec< Arc> >, + pub editors: Vec< Arc> >, port: ViewPort< dyn TerminalView >, diag_port: ViewPort< dyn SequenceView > @@ -31,7 +31,7 @@ pub struct SumEditor { impl SumEditor { pub fn new( - editors: Vec< Arc> > + editors: Vec< Arc> > ) -> Self { let port = ViewPort::new(); //let mut diag_buf = VecBuffer::new(); @@ -44,6 +44,10 @@ impl SumEditor { } } + pub fn get(&self) -> Arc> { + self.editors[ self.cur ].clone() + } + pub fn select(&mut self, idx: usize) { self.cur = idx; diff --git a/nested/src/terminal/terminal.rs b/nested/src/terminal/terminal.rs index 8c3e76d..01ef62f 100644 --- a/nested/src/terminal/terminal.rs +++ b/nested/src/terminal/terminal.rs @@ -24,7 +24,7 @@ use { }, }; -#[derive(PartialEq, Eq)] +#[derive(PartialEq, Eq, Clone)] pub enum TerminalEvent { Resize(Vector2), Input(termion::event::Event), diff --git a/nested/src/tree/addr.rs b/nested/src/tree/addr.rs new file mode 100644 index 0000000..62210a1 --- /dev/null +++ b/nested/src/tree/addr.rs @@ -0,0 +1,9 @@ + +pub struct TreeAddr(Vec); + +impl From> for TreeAddr { + fn from(v: Vec) -> TreeAddr { + TreeAddr(v) + } +} + diff --git a/nested/src/tree/mod.rs b/nested/src/tree/mod.rs index d41e2fb..94fbb14 100644 --- a/nested/src/tree/mod.rs +++ b/nested/src/tree/mod.rs @@ -1,18 +1,12 @@ +pub mod addr; pub mod cursor; pub mod nav; -pub mod typeinfo; - -pub struct TreeAddr(Vec); - -impl From> for TreeAddr { - fn from(v: Vec) -> TreeAddr { - TreeAddr(v) - } -} +pub mod node; pub use { + addr::TreeAddr, cursor::TreeCursor, nav::{TreeNav, TreeNavResult}, - typeinfo::TreeType + node::NestedNode }; diff --git a/nested/src/tree/node.rs b/nested/src/tree/node.rs new file mode 100644 index 0000000..9acdac2 --- /dev/null +++ b/nested/src/tree/node.rs @@ -0,0 +1,124 @@ +use { + std::sync::{Arc, RwLock}, + cgmath::Vector2, + crate::{ + core::{ViewPort, OuterViewPort, AnyOuterViewPort, context::ReprTree, Context}, + singleton::{SingletonView, SingletonBuffer}, + sequence::SequenceView, + terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult}, + diagnostics::{Diagnostics, Message}, + tree::{TreeNav, TreeCursor, TreeNavResult}, + Commander, ObjCommander, + Nested + }, +}; + +pub struct NestedNode { + ctx: Option>>, + view: Option>, + diag: Option>>, + cmd: Option>>, + tree_nav: Option>>, +} + +impl ObjCommander for NestedNode { + fn send_cmd_obj(&mut self, cmd_obj: Arc>) { + if let Some(cmd) = self.cmd.as_ref() { + cmd.write().unwrap().send_cmd_obj(cmd_obj); + } + } +} + +impl TerminalEditor for NestedNode { + fn get_term_view(&self) -> OuterViewPort { + self.get_view() + } + + fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { + let buf = SingletonBuffer::new(event.clone()); + + if let (Some(cmd),Some(ctx)) = (self.cmd.as_ref(),self.ctx.as_ref()) { + cmd.write().unwrap().send_cmd_obj( + ReprTree::new_leaf( + ctx.read().unwrap().type_term_from_str("( TerminalEvent )").unwrap(), + AnyOuterViewPort::from(buf.get_port()) + )); + } + + TerminalEditorResult::Continue + } +} + + +impl TreeNav for NestedNode { + fn get_cursor(&self) -> TreeCursor { + if let Some(tn) = self.tree_nav.as_ref() { + tn.read().unwrap().get_cursor() + } else { + TreeCursor::default() + } + } + + fn get_cursor_warp(&self) -> TreeCursor { + if let Some(tn) = self.tree_nav.as_ref() { + tn.read().unwrap().get_cursor_warp() + } else { + TreeCursor::default() + } + } + + fn get_max_depth(&self) -> usize { + 0 + } + + fn goby(&mut self, direction: Vector2) -> TreeNavResult { + if let Some(tn) = self.tree_nav.as_ref() { + tn.write().unwrap().goby(direction) + } else { + TreeNavResult::Exit + } + } + + fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult { + if let Some(tn) = self.tree_nav.as_ref() { + tn.write().unwrap().goto(new_cursor) + } else { + TreeNavResult::Exit + } + } +} + +impl Diagnostics for NestedNode {} +impl Nested for NestedNode {} + +impl NestedNode { + pub fn new() -> Self { + NestedNode { + ctx: None, + view: None, + diag: None, + cmd: None, + tree_nav: None + } + } + + pub fn set_ctx(mut self, ctx: Arc>) -> Self { + self.ctx = Some(ctx); + self + } + + pub fn set_view(mut self, view: OuterViewPort) -> Self { + self.view = Some(view); + self + } + + pub fn with_cmd(mut self, cmd: Arc>) -> Self { + self.cmd = Some(cmd); + self + } + + pub fn get_view(&self) -> OuterViewPort { + self.view.clone().unwrap_or(ViewPort::new().into_outer()) + } +} + diff --git a/nested/src/type_term_editor.rs b/nested/src/type_term_editor.rs new file mode 100644 index 0000000..5503389 --- /dev/null +++ b/nested/src/type_term_editor.rs @@ -0,0 +1,155 @@ +use { + crate::{ + core::{ViewPort, OuterViewPort, TypeLadder, Context}, + terminal::{TerminalEvent, TerminalView, TerminalEditor, TerminalEditorResult}, + sequence::{SequenceView, decorator::SeqDecorStyle}, + list::{PTYListEditor}, + tree::{TreeNav, TreeCursor, TreeNavResult}, + diagnostics::{Diagnostics, Message}, + sum::SumEditor, + char_editor::CharEditor, + integer::PosIntEditor, + Nested + }, + cgmath::{Vector2, Point2}, + termion::event::{Event, Key}, + std::{ + sync::{Arc, RwLock}, + any::Any + } +}; + +#[derive(Clone)] +enum TypeTermVar { + Any, + Symbol, + Num, + List +} + +pub struct TypeTermEditor { + ty: TypeTermVar, + node: SumEditor, +} + +impl TypeTermEditor { + pub fn new(ctx: Arc>, depth: usize) -> Self { + TypeTermEditor { + ty: TypeTermVar::Any, + node: SumEditor::new( + vec![ + Arc::new(RwLock::new(PTYListEditor::new( + Box::new({ + let ctx = ctx.clone(); + move || { + Arc::new(RwLock::new(TypeTermEditor::new(ctx.clone(), depth+1))) + } + }), + SeqDecorStyle::HorizontalSexpr, + Some(' '), + depth + ))), + Arc::new(RwLock::new(PosIntEditor::new(10))), + Arc::new(RwLock::new(PTYListEditor::new( + Box::new({ + let ctx = ctx.clone(); + move || { + Arc::new(RwLock::new(CharEditor::new_node(&ctx))) + } + }), + SeqDecorStyle::Plain, + None, + depth + ))), + ]) + } + } +} + +impl TreeNav for TypeTermEditor { + fn get_cursor(&self) -> TreeCursor { + self.node.get_cursor() + } + + fn get_cursor_warp(&self) -> TreeCursor { + self.node.get_cursor_warp() + } + + fn goby(&mut self, direction: Vector2) -> TreeNavResult { + self.node.goby( direction ) + } + + fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult { + self.node.goto( new_cursor ) + } +} + +impl TerminalEditor for TypeTermEditor { + fn get_term_view(&self) -> OuterViewPort { + self.node.get_term_view() + } + + fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { + match event { + TerminalEvent::Input( termion::event::Event::Key(Key::Char(c)) ) => { + match self.ty { + TypeTermVar::Any => { + self.ty = + if *c == '(' { + self.node.select(0); + self.dn(); + TypeTermVar::List + } else if c.to_digit(10).is_some() { + self.node.select(1); + self.dn(); + self.node.handle_terminal_event( event ); + TypeTermVar::Num + } else { + self.node.select(2); + self.dn(); + self.node.handle_terminal_event( event ); + TypeTermVar::Symbol + }; + TerminalEditorResult::Continue + }, + _ => { + if *c == '(' { + let mut child = Arc::new(RwLock::new(TypeTermEditor { + ty: self.ty.clone(), + node: SumEditor::new( + vec![ + self.node.editors[0].clone(), + self.node.editors[1].clone(), + self.node.editors[2].clone(), + ]) + })); + + self.ty = TypeTermVar::List; + self.node.select(0); +/* + let l = self.node.editors[0].clone(); + let l = l.downcast::>>().unwrap(); + l.write().unwrap().data.push(child); + */ + TerminalEditorResult::Continue + } else { + self.node.handle_terminal_event( event ) + } + } + } + }, + event => { + self.node.handle_terminal_event( event ) + } + } + } +} + +impl Diagnostics for TypeTermEditor { + fn get_msg_port(&self) -> OuterViewPort> { + self.node.get_msg_port() + } +} + +impl Nested for TypeTermEditor {} + diff --git a/shell/src/main.rs b/shell/src/main.rs index ad9737e..302f739 100644 --- a/shell/src/main.rs +++ b/shell/src/main.rs @@ -2,19 +2,19 @@ extern crate portable_pty; mod ascii_box; mod monstera; -mod process; +//mod process; mod pty; -mod command; +//mod command; mod plot; use { crate::{ - process::ProcessLauncher, - command::Commander +// process::ProcessLauncher, +// command::Commander }, cgmath::{Point2, Vector2}, nested::{ - core::{port::UpdateTask, Observer, OuterViewPort, View, ViewPort, Context, TypeTerm}, + core::{port::UpdateTask, Observer, OuterViewPort, AnyOuterViewPort, View, ViewPort, Context, TypeTerm, ReprTree}, index::IndexArea, list::{ListCursorMode, PTYListEditor}, sequence::{SequenceView, decorator::{SeqDecorStyle, Separate}}, @@ -29,6 +29,7 @@ use { product::ProductEditor, sum::SumEditor, diagnostics::{Diagnostics}, + index::{buffer::IndexBuffer}, Nested }, std::sync::{Arc, RwLock}, @@ -43,12 +44,20 @@ async fn main() { let mut term = Terminal::new(term_port.outer()); let term_writer = term.get_writer(); + let mut portmutex = Arc::new(RwLock::new(())); + // Update Loop // let tp = term_port.clone(); - async_std::task::spawn(async move { - loop { - tp.update(); - async_std::task::sleep(std::time::Duration::from_millis(30)).await; + async_std::task::spawn({ + let portmutex = portmutex.clone(); + async move { + loop { + { + let l = portmutex.write().unwrap(); + tp.update(); + } + async_std::task::sleep(std::time::Duration::from_millis(10)).await; + } } }); @@ -58,16 +67,53 @@ async fn main() { let ctx = nested::make_editor::init_math_ctx(ctx); let ctx = nested::make_editor::init_os_ctx(ctx); + let mut vb = VecBuffer::::new(); + let mut rt_char = ReprTree::new_leaf( + ctx.read().unwrap().type_term_from_str("( List Char )").unwrap(), + AnyOuterViewPort::from(vb.get_port()) + ); + let mut rt_digit = ReprTree::upcast(&rt_char, ctx.read().unwrap().type_term_from_str("( List ( Digit 10 ) )").unwrap()); + rt_digit.write().unwrap().insert_branch( + ReprTree::new_leaf( + ctx.read().unwrap().type_term_from_str("( List MachineInt )").unwrap(), + AnyOuterViewPort::from( + vb.get_port().to_sequence().map( + |c: &char| { + c.to_digit(10).unwrap() + } + ) + ) + ) + ); + +/* + ctx.write().unwrap().add_morphism( + MorphismType{ + mode: MorphismMode::Iso, + src_type: + }, + Box::new( + |repr| { + RadixProjection::new( + + ) + } + ) + ); + */ + let c = ctx.clone(); let mut process_list_editor = PTYListEditor::new( Box::new( move || { - Arc::new(RwLock::new(Commander::new(ctx.clone()))) + Arc::new(RwLock::new(nested::type_term_editor::TypeTermEditor::new(c.clone(), 1))) +// Arc::new(RwLock::new(CharEditor::new_node(&c))) + //Context::make_editor( c.clone(), c.read().unwrap().type_term_from_str("( String )").unwrap(), 1 ).unwrap() }), SeqDecorStyle::Plain, - '\0', + Some('\n'), 0 - ); +); async_std::task::spawn(async move { let mut table = nested::index::buffer::IndexBuffer::new(); @@ -84,7 +130,7 @@ async fn main() { let mut cur_size = nested::singleton::SingletonBuffer::new(Vector2::new(10, 10)); let mut status_chars = VecBuffer::new(); - + table.insert_iter(vec![ (Point2::new(0, 0), magic.clone()), ( @@ -96,12 +142,49 @@ async fn main() { (Point2::new(0, 4), process_list_editor.editor .get_seg_seq_view() - .separate( - make_label(" ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~") - .map_item(|p,a| a.add_style_front(TerminalStyle::fg_color((40,40,40)))) + .enumerate() + .map( + |(n, segment)| { + let mut buf = IndexBuffer::new(); + buf.insert_iter(vec![ + (Point2::new(0, 0), + make_label(match n+1 { + 1 => "I) ", + 2 => "II) ", + 3 => "III) ", + 4 => "IV) ", + 5 => "V) ", + 6 => "VI) ", + 7 => "VII) ", + 8 => "IIX) ", + 9 => "IX) ", + 10 => "X) ", + _ => "" + })), + (Point2::new(1, 0), segment.clone()) + ]); + + buf.get_port() + } ) + /* + .separate({ + let mut buf = IndexBuffer::new(); + buf.insert(Point2::new(1,0), + make_label(" ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~") + .map_item( + |p,a| + a.add_style_front(TerminalStyle::fg_color((40,40,40))) + ) + ); + buf.get_port() + } + ) + */ .to_grid_vertical() - .flatten()), + .flatten() + .flatten() + ), (Point2::new(0, 5), make_label(" ")), (Point2::new(0, 6), magic.clone()), @@ -165,62 +248,18 @@ async fn main() { tree_addr: vec![0], }); + loop { - status_chars.clear(); - let cur = process_list_editor.get_cursor(); - - if cur.tree_addr.len() > 0 { - status_chars.push(TerminalAtom::new( - '@', - TerminalStyle::fg_color((150, 80,230)).add(TerminalStyle::bold(true)), - )); - for x in cur.tree_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((150, 80,230)) - )); - } - - status_chars.push(TerminalAtom::new( - ':', - TerminalStyle::fg_color((150, 80,230)).add(TerminalStyle::bold(true)), - )); - for c in match cur.leaf_mode { - ListCursorMode::Insert => "INSERT", - ListCursorMode::Select => "SELECT" - } - .chars() - { - status_chars.push(TerminalAtom::new( - c, - TerminalStyle::fg_color((200, 200, 20)), - )); - } - status_chars.push(TerminalAtom::new( - ':', - TerminalStyle::fg_color((150, 80,230)).add(TerminalStyle::bold(true)), - - )); - } else { - for c in "Press to enter".chars() { - status_chars.push(TerminalAtom::new( - c, - TerminalStyle::fg_color((200, 200, 20)), - )); - } - } - let ev = term.next_event().await; - + let l = portmutex.write().unwrap(); + if let TerminalEvent::Resize(new_size) = ev { cur_size.set(new_size); term_port.inner().get_broadcast().notify(&IndexArea::Full); continue; } + + /* if let Some(process_editor) = process_list_editor.get_item() { let mut pe = process_editor.write().unwrap(); @@ -235,7 +274,7 @@ async fn main() { } */ } -*/ +*/ match ev { TerminalEvent::Input(Event::Key(Key::Ctrl('d'))) => break, TerminalEvent::Input(Event::Key(Key::Ctrl('l'))) => { @@ -284,6 +323,54 @@ async fn main() { } } } + + status_chars.clear(); + let cur = process_list_editor.get_cursor(); + + if cur.tree_addr.len() > 0 { + status_chars.push(TerminalAtom::new( + '@', + TerminalStyle::fg_color((150, 80,230)).add(TerminalStyle::bold(true)), + )); + for x in cur.tree_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((150, 80,230)) + )); + } + + status_chars.push(TerminalAtom::new( + ':', + TerminalStyle::fg_color((150, 80,230)).add(TerminalStyle::bold(true)), + )); + for c in match cur.leaf_mode { + ListCursorMode::Insert => "INSERT", + ListCursorMode::Select => "SELECT" + } + .chars() + { + status_chars.push(TerminalAtom::new( + c, + TerminalStyle::fg_color((200, 200, 20)), + )); + } + status_chars.push(TerminalAtom::new( + ':', + TerminalStyle::fg_color((150, 80,230)).add(TerminalStyle::bold(true)), + + )); + } else { + for c in "Press to enter".chars() { + status_chars.push(TerminalAtom::new( + c, + TerminalStyle::fg_color((200, 200, 20)), + )); + } + } } drop(term); diff --git a/shell/src/process.rs b/shell/src/process.rs index a25f1fc..9f6d3f5 100644 --- a/shell/src/process.rs +++ b/shell/src/process.rs @@ -21,7 +21,7 @@ use { }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - +/* pub struct ProcessArg { editor: PTYListEditor, @@ -274,4 +274,4 @@ impl Diagnostics for ProcessLauncher { } impl Nested for ProcessLauncher {} - +*/