This commit is contained in:
Michael Sippel 2022-12-19 11:26:07 +01:00
parent 7a24111f08
commit 883cd01f99
Signed by: senvas
GPG key ID: F96CF119C34B64A6
19 changed files with 489 additions and 609 deletions

View file

@ -2,11 +2,7 @@ use {
crate::{ crate::{
core::{OuterViewPort, Context}, core::{OuterViewPort, Context},
singleton::{SingletonBuffer, SingletonView}, singleton::{SingletonBuffer, SingletonView},
terminal::{ terminal::{TerminalAtom, TerminalEvent, TerminalStyle},
TerminalAtom,
TerminalEvent,
TerminalStyle
},
tree::NestedNode, Commander tree::NestedNode, Commander
}, },
std::sync::Arc, std::sync::Arc,
@ -26,10 +22,12 @@ impl Commander for CharEditor {
TerminalEvent::Input(Event::Key(Key::Char(c))) => { TerminalEvent::Input(Event::Key(Key::Char(c))) => {
self.data.set(Some(*c)); self.data.set(Some(*c));
} }
TerminalEvent::Input(Event::Key(Key::Backspace)) TerminalEvent::Input(Event::Key(Key::Backspace))
| TerminalEvent::Input(Event::Key(Key::Delete)) => { | TerminalEvent::Input(Event::Key(Key::Delete)) => {
self.data.set(None); self.data.set(None);
} }
_ => {} _ => {}
} }
} }
@ -65,7 +63,7 @@ impl CharEditor {
}) })
.to_grid() .to_grid()
) )
.with_cmd( .set_cmd(
Arc::new(RwLock::new(CharEditor{ data })) Arc::new(RwLock::new(CharEditor{ data }))
) )
} }

View file

@ -4,7 +4,7 @@ use {
type_term::{TypeDict, TypeTerm, TypeID}, type_term::{TypeDict, TypeTerm, TypeID},
AnyOuterViewPort, OuterViewPort, View, AnyOuterViewPort, OuterViewPort, View,
}, },
Nested tree::NestedNode
}, },
std::{ std::{
collections::HashMap, collections::HashMap,
@ -248,7 +248,7 @@ pub struct Context {
objects: HashMap<String, Arc<RwLock<ReprTree>>>, objects: HashMap<String, Arc<RwLock<ReprTree>>>,
/// editors /// editors
editor_ctors: HashMap<TypeID, Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> + Send + Sync>>, editor_ctors: HashMap<TypeID, Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<NestedNode> + Send + Sync>>,
/// morphisms /// morphisms
default_constructors: HashMap<TypeTerm, Box<dyn Fn() -> Arc<RwLock<ReprTree>> + Send + Sync>>, default_constructors: HashMap<TypeTerm, Box<dyn Fn() -> Arc<RwLock<ReprTree>> + Send + Sync>>,
@ -281,6 +281,10 @@ impl Context {
self.type_dict.write().unwrap().add_typename(tn); self.type_dict.write().unwrap().add_typename(tn);
} }
pub fn get_typeid(&self, tn: &str) -> Option<TypeID> {
self.type_dict.read().unwrap().get_typeid(&tn.into())
}
pub fn type_term_from_str(&self, tn: &str) -> Option<TypeTerm> { pub fn type_term_from_str(&self, tn: &str) -> Option<TypeTerm> {
self.type_dict.read().unwrap().type_term_from_str(&tn) self.type_dict.read().unwrap().type_term_from_str(&tn)
} }
@ -289,13 +293,15 @@ impl Context {
self.type_dict.read().unwrap().type_term_to_str(&t) self.type_dict.read().unwrap().type_term_to_str(&t)
} }
pub fn add_editor_ctor(&mut self, tn: &str, mk_editor: Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> + Send + Sync>) { pub fn add_editor_ctor(&mut self, tn: &str, mk_editor: Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<NestedNode> + Send + Sync>) {
let mut dict = self.type_dict.write().unwrap(); let mut dict = self.type_dict.write().unwrap();
let tyid = dict.get_typeid(&tn.into()).unwrap_or( dict.add_typename(tn.into()) ); let tyid = dict
.get_typeid(&tn.into())
.unwrap_or( dict.add_typename(tn.into()) );
self.editor_ctors.insert(tyid, mk_editor); self.editor_ctors.insert(tyid, mk_editor);
} }
pub fn get_editor_ctor(&self, ty: &TypeTerm) -> Option<Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> + Send + Sync>> { pub fn get_editor_ctor(&self, ty: &TypeTerm) -> Option<Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, usize) -> Option<NestedNode> + Send + Sync>> {
if let TypeTerm::Type{ id, args: _ } = ty.clone() { if let TypeTerm::Type{ id, args: _ } = ty.clone() {
if let Some(m) = self.editor_ctors.get(&id).cloned() { if let Some(m) = self.editor_ctors.get(&id).cloned() {
Some(m) Some(m)
@ -309,9 +315,9 @@ impl Context {
} }
} }
pub fn make_editor(ctx: Arc<RwLock<Self>>, type_term: TypeTerm, depth: usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> { pub fn make_editor(ctx: &Arc<RwLock<Self>>, type_term: TypeTerm, depth: usize) -> Option<NestedNode> {
let mk_editor = ctx.read().unwrap().get_editor_ctor(&type_term)?; let mk_editor = ctx.read().unwrap().get_editor_ctor(&type_term)?;
mk_editor(ctx, type_term, depth) mk_editor(ctx.clone(), type_term, depth)
} }
pub fn add_morphism( pub fn add_morphism(

View file

@ -126,7 +126,7 @@ impl TypeTerm {
pub struct TypeDict { pub struct TypeDict {
typenames: Bimap<String, u64>, typenames: Bimap<String, u64>,
type_id_counter: u64, type_id_counter: TypeID,
} }
impl TypeDict { impl TypeDict {
@ -137,10 +137,10 @@ impl TypeDict {
} }
} }
pub fn add_typename(&mut self, tn: String) -> u64 { pub fn add_typename(&mut self, tn: String) -> TypeID {
let tyid = self.type_id_counter; let tyid = self.type_id_counter;
self.typenames.insert(tn, tyid);
self.type_id_counter += 1; self.type_id_counter += 1;
self.typenames.insert(tn, tyid);
tyid tyid
} }

View file

@ -1,6 +1,6 @@
use { use {
crate::{ crate::{
core::{InnerViewPort, OuterViewPort, ViewPort, View}, core::{InnerViewPort, OuterViewPort, ViewPort, Observer, View},
index::{IndexArea, IndexView}, index::{IndexArea, IndexView},
}, },
std::sync::RwLock, std::sync::RwLock,

View file

@ -1,6 +1,6 @@
use { use {
crate::{ crate::{
core::{OuterViewPort}, core::{OuterViewPort, Context, TypeTerm},
list::{PTYListEditor}, list::{PTYListEditor},
sequence::{SequenceView, SequenceViewExt, decorator::{PTYSeqDecorate, SeqDecorStyle}}, sequence::{SequenceView, SequenceViewExt, decorator::{PTYSeqDecorate, SeqDecorStyle}},
singleton::{SingletonBuffer, SingletonView}, singleton::{SingletonBuffer, SingletonView},
@ -12,7 +12,9 @@ use {
}, },
tree::{TreeCursor, TreeNav, TreeNavResult}, tree::{TreeCursor, TreeNav, TreeNavResult},
diagnostics::{Diagnostics, Message}, diagnostics::{Diagnostics, Message},
Nested tree::NestedNode,
Nested,
Commander
}, },
std::sync::Arc, std::sync::Arc,
std::sync::RwLock, std::sync::RwLock,
@ -23,51 +25,17 @@ use {
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct DigitEditor { pub struct DigitEditor {
ctx: Arc<RwLock<Context>>,
radix: u32, radix: u32,
data: SingletonBuffer<Option<char>>, data: SingletonBuffer<Option<char>>,
msg: VecBuffer<Message>, msg: VecBuffer<Message>,
} }
impl DigitEditor { impl Commander for DigitEditor {
pub fn new(radix: u32) -> Self { type Cmd = TerminalEvent;
DigitEditor {
radix,
data: SingletonBuffer::new(None),
msg: VecBuffer::new(),
}
}
pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Option<u32>>> { fn send_cmd(&mut self, event: &TerminalEvent) {
let radix = self.radix;
self.data.get_port().map(move |c| c?.to_digit(radix))
}
}
impl TreeNav for DigitEditor {}
impl TerminalEditor for DigitEditor {
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
let radix = self.radix;
self.data
.get_port()
.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::bg_color((90, 10, 10))
TerminalStyle::fg_color((200, 40, 40))
},
)
})
.to_grid()
}
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
match event { match event {
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))) => { TerminalEvent::Input(Event::Key(Key::Char(c))) => {
self.data.set(Some(*c)); self.data.set(Some(*c));
@ -82,50 +50,97 @@ impl TerminalEditor for DigitEditor {
]); ]);
self.msg.push(crate::diagnostics::make_error(mb.get_port().flatten())); self.msg.push(crate::diagnostics::make_error(mb.get_port().flatten()));
} }
TerminalEditorResult::Exit
} }
TerminalEvent::Input(Event::Key(Key::Backspace)) TerminalEvent::Input(Event::Key(Key::Backspace))
| TerminalEvent::Input(Event::Key(Key::Delete)) => { | TerminalEvent::Input(Event::Key(Key::Delete)) => {
self.data.set(None); self.data.set(None);
self.msg.clear(); self.msg.clear();
self.msg.push(crate::diagnostics::make_warn(make_label("empty digit"))); self.msg.push(crate::diagnostics::make_warn(make_label("empty digit")));
TerminalEditorResult::Exit
} }
_ => TerminalEditorResult::Continue, _ => {}
} }
} }
} }
impl Nested for DigitEditor {} impl DigitEditor {
pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self {
DigitEditor {
ctx,
radix,
data: SingletonBuffer::new(None),
msg: VecBuffer::new(),
}
}
impl Diagnostics for DigitEditor { pub fn into_node(self) -> NestedNode {
fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = crate::diagnostics::Message>> { let editor = Arc::new(RwLock::new(self));
self.msg.get_port().to_sequence() let ed = editor.read().unwrap();
let r = ed.radix;
NestedNode::new()
.set_ctx(ed.ctx.clone())
.set_cmd(editor.clone())
.set_view(
ed.data
.get_port()
.map(move |c| {
TerminalAtom::new(
c.unwrap_or('?'),
if c.unwrap_or('?').to_digit(r).is_some() {
TerminalStyle::fg_color((100, 140, 100))
} else {
//TerminalStyle::bg_color((90, 10, 10))
TerminalStyle::fg_color((200, 40, 40))
},
)
})
.to_grid()
)
.set_diag(
ed.msg.get_port().to_sequence()
)
}
pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Option<u32>>> {
let radix = self.radix;
self.data.get_port().map(move |c| c?.to_digit(radix))
} }
} }
pub struct PosIntEditor { pub struct PosIntEditor {
radix: u32, radix: u32,
digits_editor: PTYListEditor<DigitEditor> digits: NestedNode
} }
impl PosIntEditor { impl PosIntEditor {
pub fn new(radix: u32) -> Self { pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self {
PosIntEditor { PosIntEditor {
radix, radix,
digits_editor: PTYListEditor::new( digits: PTYListEditor::new(
Box::new(move || Arc::new(RwLock::new(DigitEditor::new(radix)))) as Box<dyn Fn() -> Arc<RwLock<DigitEditor>> + Send + Sync>, ctx.clone(),
SeqDecorStyle::Hex, TypeTerm::Type {
id: ctx.read().unwrap().get_typeid("Digit").unwrap(),
args: vec![
TypeTerm::Num(radix as i64)
]
},
match radix {
16 => SeqDecorStyle::Hex,
_ => SeqDecorStyle::Plain
},
None, None,
0 0
), ).into_node()
} }
} }
pub fn into_node(self) -> NestedNode {
self.digits
}
/*
pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = u32>> { pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = u32>> {
let radix = self.radix; let radix = self.radix;
self.digits_editor.editor self.digits
.get_data_port() .get_data_port()
.filter_map(move |digit_editor| { .filter_map(move |digit_editor| {
digit_editor.read().unwrap().data.get()?.to_digit(radix) digit_editor.read().unwrap().data.get()?.to_digit(radix)
@ -150,63 +165,6 @@ impl PosIntEditor {
value value
} }
*/
} }
impl Diagnostics for PosIntEditor {
fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = crate::diagnostics::Message>> {
self.digits_editor.get_msg_port()
}
}
impl TreeNav for PosIntEditor {
fn get_cursor(&self) -> TreeCursor {
self.digits_editor.get_cursor()
}
fn get_cursor_warp(&self) -> TreeCursor {
self.digits_editor.get_cursor_warp()
}
fn goto(&mut self, cur: TreeCursor) -> TreeNavResult {
self.digits_editor.goto(cur)
}
fn goby(&mut self, cur: Vector2<isize>) -> TreeNavResult {
self.digits_editor.goby(cur)
}
}
impl TerminalEditor for PosIntEditor {
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
match self.radix {
10 => {
self.digits_editor.editor
.get_seg_seq_view()
.pty_decorate(SeqDecorStyle::Plain, 0)
},
16 => {
self.digits_editor.editor
.get_seg_seq_view()
.pty_decorate(SeqDecorStyle::Hex, 0)
}
_ => {
self.digits_editor.editor
.get_seg_seq_view()
.pty_decorate(SeqDecorStyle::Plain, 0)
}
}
}
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
match event {
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
}
event => self.digits_editor.handle_terminal_event(event),
}
}
}
impl Nested for PosIntEditor {}

View file

@ -72,7 +72,11 @@ pub trait StringGen {
} }
use crate::terminal::TerminalEditor; use crate::terminal::TerminalEditor;
use crate::{tree::{TreeNav}, diagnostics::Diagnostics}; use crate::{tree::{TreeNav}, diagnostics::Diagnostics, terminal::TerminalView, core::{OuterViewPort}};
pub trait PtySegment {
fn pty_view(&self) -> OuterViewPort<dyn TerminalView>;
}
pub trait Nested pub trait Nested
: TerminalEditor : TerminalEditor

View file

@ -1,43 +1,44 @@
use { use {
crate::{ crate::{
core::{OuterViewPort, ViewPort}, core::{OuterViewPort, ViewPort, Context, TypeTerm},
list::{ list::{
ListCursor, ListCursor,
ListSegment, ListSegmentSequence, ListSegment,
segment::PTYSegment ListSegmentSequence,
}, },
sequence::{SequenceView}, sequence::{SequenceView},
singleton::{SingletonBuffer, SingletonView}, singleton::{SingletonBuffer, SingletonView},
terminal::{ terminal::{TerminalView},
TerminalView, tree::NestedNode,
}, vec::{VecBuffer, MutableVecAccess},
Nested, PtySegment
vec::VecBuffer
}, },
std::sync::{Arc, RwLock}, std::sync::{Arc, RwLock},
}; };
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct ListEditor<ItemEditor> pub struct ListEditor {
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
{
pub(super) cursor: SingletonBuffer<ListCursor>, pub(super) cursor: SingletonBuffer<ListCursor>,
pub(crate) data: VecBuffer<Arc<RwLock<ItemEditor>>>, pub(crate) data: VecBuffer<NestedNode>,
pub(super) make_item_editor: Box<dyn Fn() -> Arc<RwLock<ItemEditor>> + Send + Sync>,
pub(crate) ctx: Arc<RwLock<Context>>,
pub(super) typ: TypeTerm,
pub(super) depth: usize, pub(super) depth: usize,
pub(super) cur_dist: Arc<RwLock<usize>>, pub(super) cur_dist: Arc<RwLock<usize>>,
} }
impl<ItemEditor> ListEditor<ItemEditor> impl ListEditor {
where ItemEditor: Nested + ?Sized + Send + Sync + 'static pub fn new(
{ ctx: Arc<RwLock<Context>>,
pub fn new(make_item_editor: impl Fn() -> Arc<RwLock<ItemEditor>> + Send + Sync + 'static, depth: usize) -> Self { typ: TypeTerm,
depth: usize
) -> Self {
ListEditor { ListEditor {
cursor: SingletonBuffer::new(ListCursor::default()), cursor: SingletonBuffer::new(ListCursor::default()),
data: VecBuffer::<Arc<RwLock<ItemEditor>>>::new(), data: VecBuffer::<NestedNode>::new(),
make_item_editor: Box::new(make_item_editor), ctx,
typ,
depth, depth,
cur_dist: Arc::new(RwLock::new(0)), cur_dist: Arc::new(RwLock::new(0)),
} }
@ -46,17 +47,16 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
pub fn get_seg_seq_view( pub fn get_seg_seq_view(
&self, &self,
) -> OuterViewPort<dyn SequenceView<Item = OuterViewPort<dyn TerminalView>>> { ) -> OuterViewPort<dyn SequenceView<Item = OuterViewPort<dyn TerminalView>>> {
let segment_view_port = ViewPort::<dyn SequenceView<Item = ListSegment<ItemEditor>>>::new(); let seg_seq = ListSegmentSequence::new(
ListSegmentSequence::new(
self.get_cursor_port(), self.get_cursor_port(),
self.get_data_port(), self.get_data_port(),
segment_view_port.inner(),
self.depth self.depth
); );
segment_view_port.into_outer().map(move |segment| segment.pty_view()) let se = seg_seq.read().unwrap();
se.get_view().map(move |segment| segment.pty_view())
} }
pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = Arc<RwLock<ItemEditor>>>> { pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = NestedNode>> {
self.data.get_port().to_sequence() self.data.get_port().to_sequence()
} }
@ -64,7 +64,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
self.cursor.get_port() self.cursor.get_port()
} }
pub fn get_item(&self) -> Option<Arc<RwLock<ItemEditor>>> { pub fn get_item(&self) -> Option<NestedNode> {
if let Some(idx) = self.cursor.get().idx { if let Some(idx) = self.cursor.get().idx {
let idx = crate::modulo(idx as isize, self.data.len() as isize) as usize; let idx = crate::modulo(idx as isize, self.data.len() as isize) as usize;
if idx < self.data.len() { if idx < self.data.len() {
@ -76,6 +76,18 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
None None
} }
} }
pub fn get_item_mut(&mut self) -> Option<MutableVecAccess<NestedNode>> {
if let Some(idx) = self.cursor.get().idx {
let idx = crate::modulo(idx as isize, self.data.len() as isize) as usize;
if idx < self.data.len() {
Some(self.data.get_mut(idx))
} else {
None
}
} else {
None
}
}
/// split the list off at the current cursor position and return the second half /// split the list off at the current cursor position and return the second half
/* /*

View file

@ -10,9 +10,9 @@ use {
cgmath::Vector2 cgmath::Vector2
}; };
impl<ItemEditor> TreeNav for ListEditor<ItemEditor> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
{ impl TreeNav for ListEditor {
fn get_cursor_warp(&self) -> TreeCursor { fn get_cursor_warp(&self) -> TreeCursor {
let cur = self.cursor.get(); let cur = self.cursor.get();
match cur.mode { match cur.mode {
@ -29,7 +29,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
ListCursorMode::Select => { ListCursorMode::Select => {
if let Some(i) = cur.idx { if let Some(i) = cur.idx {
if i < self.data.len() as isize { if i < self.data.len() as isize {
let mut sub_cur = self.data.get(i as usize).read().unwrap().get_cursor_warp(); let mut sub_cur = self.data.get(i as usize).get_cursor_warp();
sub_cur.tree_addr.insert(0, i as isize - self.data.len() as isize); sub_cur.tree_addr.insert(0, i as isize - self.data.len() as isize);
return sub_cur; return sub_cur;
} else { } else {
@ -61,7 +61,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
ListCursorMode::Select => { ListCursorMode::Select => {
if let Some(i) = cur.idx { if let Some(i) = cur.idx {
if i < self.data.len() as isize { if i < self.data.len() as isize {
let mut sub_cur = self.data.get(i as usize).read().unwrap().get_cursor(); let mut sub_cur = self.data.get(i as usize).get_cursor();
if sub_cur.tree_addr.len() > 0 { if sub_cur.tree_addr.len() > 0 {
sub_cur.tree_addr.insert(0, i as isize); sub_cur.tree_addr.insert(0, i as isize);
return sub_cur; return sub_cur;
@ -85,9 +85,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
let old_cur = self.cursor.get(); let old_cur = self.cursor.get();
if let Some(i) = old_cur.idx { if let Some(i) = old_cur.idx {
if i < self.data.len() as isize { if i < self.data.len() as isize {
let ce = self.data.get_mut(i as usize); self.data.get_mut(i as usize).goto(TreeCursor::none());
let mut cur_edit = ce.write().unwrap();
cur_edit.goto(TreeCursor::none());
} }
} }
@ -108,9 +106,9 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
}); });
if new_cur.leaf_mode == ListCursorMode::Select && self.data.len() > 0 { if new_cur.leaf_mode == ListCursorMode::Select && self.data.len() > 0 {
let item = self.data.get_mut(idx as usize); self.data
let mut item_edit = item.write().unwrap(); .get_mut(idx as usize)
item_edit.goto(TreeCursor { .goto(TreeCursor {
leaf_mode: ListCursorMode::Select, leaf_mode: ListCursorMode::Select,
tree_addr: vec![] tree_addr: vec![]
}); });
@ -127,9 +125,9 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
idx: Some(idx), idx: Some(idx),
}); });
let item = self.data.get_mut(idx as usize); self.data
let mut item_edit = item.write().unwrap(); .get_mut(idx as usize)
item_edit.goto(TreeCursor { .goto(TreeCursor {
leaf_mode: new_cur.leaf_mode, leaf_mode: new_cur.leaf_mode,
tree_addr: new_cur.tree_addr[1..].iter().cloned().collect(), tree_addr: new_cur.tree_addr[1..].iter().cloned().collect(),
}); });
@ -175,10 +173,10 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
if direction.y > 0 { if direction.y > 0 {
// dn // dn
if cur.tree_addr[0] < self.data.len() as isize { if cur.tree_addr[0] < self.data.len() as isize {
let item = self.data.get_mut(cur.tree_addr[0] as usize); if self.data
let mut item_edit = item.write().unwrap(); .get_mut(cur.tree_addr[0] as usize)
.goby(Vector2::new(direction.x, direction.y))
if item_edit.goby(Vector2::new(direction.x, direction.y)) == TreeNavResult::Continue { == TreeNavResult::Continue {
self.cursor.set(ListCursor { self.cursor.set(ListCursor {
mode: ListCursorMode::Select, mode: ListCursorMode::Select,
idx: Some(cur.tree_addr[0]) idx: Some(cur.tree_addr[0])
@ -210,9 +208,9 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
}); });
if idx < self.data.len() as isize { if idx < self.data.len() as isize {
let item = self.data.get_mut(idx as usize); self.data
let mut item_edit = item.write().unwrap(); .get_mut(idx as usize)
item_edit.goto(TreeCursor { .goto(TreeCursor {
leaf_mode: cur.leaf_mode, leaf_mode: cur.leaf_mode,
tree_addr: vec![] tree_addr: vec![]
}); });
@ -233,10 +231,10 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
// nested // nested
if cur.tree_addr[0] < self.data.len() as isize { if cur.tree_addr[0] < self.data.len() as isize {
let item = self.data.get_mut(cur.tree_addr[0] as usize); match self.data
let mut item_edit = item.write().unwrap(); .get_mut(cur.tree_addr[0] as usize)
.goby(direction)
match item_edit.goby(direction) { {
TreeNavResult::Exit => { TreeNavResult::Exit => {
if direction.y < 0 { if direction.y < 0 {
// up // up
@ -252,8 +250,6 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
TreeNavResult::Continue TreeNavResult::Continue
} else { } else {
// horizontal // horizontal
drop(item_edit);
if (cur.tree_addr[0]+direction.x >= 0) && if (cur.tree_addr[0]+direction.x >= 0) &&
(cur.tree_addr[0]+direction.x < self.data.len() as isize) (cur.tree_addr[0]+direction.x < self.data.len() as isize)
{ {

View file

@ -1,6 +1,6 @@
use { use {
crate::{ crate::{
core::{OuterViewPort}, core::{OuterViewPort, Context, TypeTerm},
list::{ list::{
ListCursor, ListCursorMode, ListCursor, ListCursorMode,
ListEditor ListEditor
@ -12,67 +12,99 @@ use {
}, },
tree::{TreeCursor, TreeNav, TreeNavResult}, tree::{TreeCursor, TreeNav, TreeNavResult},
diagnostics::{Diagnostics}, diagnostics::{Diagnostics},
Nested tree::NestedNode, Nested,
Commander
}, },
std::sync::{Arc, RwLock}, std::sync::{Arc, RwLock},
termion::event::{Event, Key}, termion::event::{Event, Key},
cgmath::Vector2 cgmath::Vector2
}; };
pub struct PTYListEditor<ItemEditor> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
{
pub editor: ListEditor<ItemEditor>,
pub struct PTYListEditor {
pub editor: Arc<RwLock<ListEditor>>,
split_char: Option<char>, split_char: Option<char>,
style: SeqDecorStyle, style: SeqDecorStyle,
depth: usize, depth: usize,
port: OuterViewPort<dyn TerminalView> pub diag: OuterViewPort<dyn SequenceView<Item = crate::diagnostics::Message>>,
pub view: OuterViewPort<dyn TerminalView>
} }
impl<ItemEditor> PTYListEditor<ItemEditor> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
{ impl PTYListEditor {
pub fn new( pub fn new(
make_item_editor: impl Fn() -> Arc<RwLock<ItemEditor>> + Send + Sync + 'static, ctx: Arc<RwLock<Context>>,
typ: TypeTerm,
style: SeqDecorStyle, style: SeqDecorStyle,
split_char: Option<char>, split_char: Option<char>,
depth: usize depth: usize
) -> Self { ) -> Self {
Self::from_editor(ListEditor::new(make_item_editor, depth), style, split_char, depth) Self::from_editor(
ListEditor::new(ctx, typ, depth), style, split_char, depth)
} }
pub fn from_editor( pub fn from_editor(
editor: ListEditor<ItemEditor>, editor: ListEditor,
style: SeqDecorStyle, style: SeqDecorStyle,
split_char: Option<char>, split_char: Option<char>,
depth: usize depth: usize
) -> Self { ) -> Self {
let port = editor
.get_seg_seq_view()
.pty_decorate(style, depth);
PTYListEditor { PTYListEditor {
editor,
split_char, split_char,
style, style,
depth, depth,
port
view: editor.get_seg_seq_view().pty_decorate(style, depth),
diag: editor.get_data_port()
.enumerate()
.map(
|(idx, item_editor)| {
let idx = *idx;
item_editor
.get_msg_port()
.map(
move |msg| {
let mut msg = msg.clone();
msg.addr.insert(0, idx);
msg
}
)
}
)
.flatten(),
editor: Arc::new(RwLock::new(editor)),
} }
} }
pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = Arc<RwLock<ItemEditor>>>> { pub fn into_node(self) -> NestedNode {
self.editor.get_data_port() let editor = Arc::new(RwLock::new(self));
let ed = editor.read().unwrap();
let edd = ed.editor.read().unwrap();
NestedNode::new()
.set_cmd(editor.clone())
.set_nav(ed.editor.clone())
.set_ctx(edd.ctx.clone())
.set_diag(ed.diag.clone())
.set_view(ed.view.clone())
}
pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = NestedNode>> {
self.editor.read().unwrap().get_data_port()
} }
pub fn clear(&mut self) { pub fn clear(&mut self) {
self.editor.clear(); self.editor.write().unwrap().clear();
} }
pub fn get_item(&self) -> Option<Arc<RwLock<ItemEditor>>> { pub fn get_item(&self) -> Option<NestedNode> {
self.editor.get_item() self.editor.read().unwrap().get_item()
} }
pub fn set_depth(&mut self, depth: usize) { pub fn set_depth(&mut self, depth: usize) {
@ -84,95 +116,74 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
} }
} }
impl<ItemEditor> TerminalEditor for PTYListEditor<ItemEditor> impl Commander for PTYListEditor {
where ItemEditor: Nested + ?Sized + Send + Sync + 'static type Cmd = TerminalEvent;
{
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
self.port.clone()
}
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { fn send_cmd(&mut self, event: &TerminalEvent) {
let mut cur = self.editor.cursor.get(); let mut e = self.editor.write().unwrap();
let mut cur = e.cursor.get();
if let Some(idx) = cur.idx { if let Some(idx) = cur.idx {
match cur.mode { match cur.mode {
ListCursorMode::Insert => match event { ListCursorMode::Insert => match event {
TerminalEvent::Input(Event::Key(Key::Backspace)) => { TerminalEvent::Input(Event::Key(Key::Backspace)) => {
if idx > 0 && idx <= self.editor.data.len() as isize { if idx > 0 && idx <= e.data.len() as isize {
cur.idx = Some(idx as isize - 1); cur.idx = Some(idx as isize - 1);
self.editor.cursor.set(cur); e.cursor.set(cur);
self.editor.data.remove(idx as usize - 1); e.data.remove(idx as usize - 1);
if self.editor.data.len() > 0 {
TerminalEditorResult::Continue
} else {
TerminalEditorResult::Exit
}
} else {
TerminalEditorResult::Exit
} }
} }
TerminalEvent::Input(Event::Key(Key::Delete)) => { TerminalEvent::Input(Event::Key(Key::Delete)) => {
if idx < self.editor.data.len() as isize { if idx < e.data.len() as isize {
self.editor.data.remove(idx as usize); e.data.remove(idx as usize);
TerminalEditorResult::Continue
} else {
TerminalEditorResult::Exit
} }
} }
TerminalEvent::Input(Event::Key(Key::Char('\t'))) TerminalEvent::Input(Event::Key(Key::Char('\t')))
| TerminalEvent::Input(Event::Key(Key::Insert)) => { | TerminalEvent::Input(Event::Key(Key::Insert)) => {
self.editor.set_leaf_mode(ListCursorMode::Select); e.set_leaf_mode(ListCursorMode::Select);
TerminalEditorResult::Continue
} }
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => { TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
self.editor.goto(TreeCursor::none()); e.goto(TreeCursor::none());
TerminalEditorResult::Exit
} }
_ => { _ => {
let new_edit = (self.editor.make_item_editor)(); let mut new_edit = Context::make_editor(&e.ctx, e.typ.clone(), self.depth+1).unwrap();
self.editor.data.insert(idx as usize, new_edit.clone()); e.data.insert(idx as usize, new_edit.clone());
self.editor.set_leaf_mode(ListCursorMode::Select); e.set_leaf_mode(ListCursorMode::Select);
let mut ne = new_edit.write().unwrap(); new_edit.goto(TreeCursor::home());
ne.goto(TreeCursor::home()); new_edit.handle_terminal_event(event);
ne.handle_terminal_event(event);
if self.split_char.is_none() { if self.split_char.is_none() {
self.editor.cursor.set(ListCursor { e.cursor.set(ListCursor {
mode: ListCursorMode::Insert, mode: ListCursorMode::Insert,
idx: Some(idx as isize + 1), idx: Some(idx as isize + 1),
}); });
} }
TerminalEditorResult::Continue
} }
}, },
ListCursorMode::Select => { ListCursorMode::Select => {
match event { match event {
TerminalEvent::Input(Event::Key(Key::Char('\t'))) TerminalEvent::Input(Event::Key(Key::Char('\t')))
| TerminalEvent::Input(Event::Key(Key::Insert)) => { | TerminalEvent::Input(Event::Key(Key::Insert)) => {
self.editor.set_leaf_mode(ListCursorMode::Insert); e.set_leaf_mode(ListCursorMode::Insert);
TerminalEditorResult::Continue
} }
TerminalEvent::Input(Event::Key(Key::Char(c))) => { TerminalEvent::Input(Event::Key(Key::Char(c))) => {
if Some(*c) == self.split_char { if Some(*c) == self.split_char {
let c = self.editor.cursor.get(); let c = e.cursor.get();
self.editor.goto(TreeCursor::none()); e.goto(TreeCursor::none());
self.editor.cursor.set(ListCursor { e.cursor.set(ListCursor {
mode: ListCursorMode::Insert, mode: ListCursorMode::Insert,
idx: Some(1 + c.idx.unwrap_or(0)) idx: Some(1 + c.idx.unwrap_or(0))
}); });
TerminalEditorResult::Continue
} else { } else {
if let Some(e) = self.editor.get_item() { if let Some(mut ce) = e.get_item_mut() {
e.write().unwrap().handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char(*c)))); ce.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char(*c))));
//match //match
if self.split_char.is_none() { if self.split_char.is_none() {
// TerminalEditorResult::Exit => // TerminalEditorResult::Exit =>
{ {
self.editor.cursor.set(ListCursor { e.cursor.set(ListCursor {
mode: ListCursorMode::Insert, mode: ListCursorMode::Insert,
idx: Some(idx as isize + 1), idx: Some(idx as isize + 1),
}); });
@ -181,26 +192,21 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
// } // }
} }
} }
TerminalEditorResult::Exit
} }
} }
ev => { ev => {
if let Some(e) = self.editor.get_item() { if let Some(mut ce) = e.get_item_mut() {
match e.write().unwrap().handle_terminal_event(ev) { ce.handle_terminal_event(ev);
TerminalEditorResult::Exit => { /*
match ev {
TerminalEvent::Input(Event::Key(Key::Ctrl('x'))) => {
return TerminalEditorResult::Exit
}
TerminalEvent::Input(Event::Key(Key::Backspace)) => { TerminalEvent::Input(Event::Key(Key::Backspace)) => {
self.editor.data.remove(idx as usize); e.data.remove(idx as usize);
self.editor.cursor.set(ListCursor { e.cursor.set(ListCursor {
mode: ListCursorMode::Insert, mode: ListCursorMode::Insert,
idx: Some(idx as isize), idx: Some(idx as isize),
}); });
} }
_ => { _ => {
self.editor.cursor.set(ListCursor { e.cursor.set(ListCursor {
mode: ListCursorMode::Insert, mode: ListCursorMode::Insert,
idx: Some(idx as isize + 1), idx: Some(idx as isize + 1),
}); });
@ -211,89 +217,13 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
} }
} }
}
TerminalEditorResult::Continue
}
}
}
}
} else {
TerminalEditorResult::Continue
}
}
}
impl<ItemEditor> TreeNav for PTYListEditor<ItemEditor>
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
{
fn get_cursor_warp(&self) -> TreeCursor {
self.editor.get_cursor_warp()
}
fn get_cursor(&self) -> TreeCursor {
self.editor.get_cursor()
}
fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult {
self.editor.goby(direction)
}
fn goto(&mut self, cursor: TreeCursor) -> TreeNavResult {
self.editor.goto(cursor)
}
}
impl<ItemEditor> Diagnostics for PTYListEditor<ItemEditor>
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
{
fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = crate::diagnostics::Message>> {
self.editor
.get_data_port()
.enumerate()
.map(
|(idx, item_editor)| {
let idx = *idx;
item_editor.read().unwrap()
.get_msg_port()
.map(
move |msg| {
let mut msg = msg.clone();
msg.addr.insert(0, idx);
msg
}
)
}
)
.flatten()
}
}
/*
impl<ItemEditor> TreeType for PTYListEditor<ItemEditor>
where ItemEditor: Nested + TreeType + ?Sized + Send + Sync + 'static
{
fn get_type(&self, addr: &Vec<usize>) -> TypeTerm {
TypeTerm::new(0)
}
}
*/ */
impl<ItemEditor> Nested for PTYListEditor<ItemEditor> }
where ItemEditor: Nested + ?Sized + Send + Sync + 'static }
{} }
}
use crate::{ }
sequence::SequenceViewExt, }
StringGen
};
impl<ItemEditor: StringGen + Nested + Send + Sync> StringGen for PTYListEditor<ItemEditor> {
fn get_string(&self) -> String {
self.get_data_port()
.map(|ce| ce.read().unwrap().get_string())
.get_view().unwrap()
.iter().collect::<String>()
} }
} }

View file

@ -1,35 +1,30 @@
use { use {
crate::{ crate::{
core::{InnerViewPort, Observer, ObserverBroadcast, ObserverExt, OuterViewPort, View}, core::{InnerViewPort, Observer, ObserverBroadcast, ObserverExt, OuterViewPort, View, ViewPort},
list::{ListCursor, ListCursorMode}, list::{ListCursor, ListCursorMode},
projection::ProjectionHelper, projection::ProjectionHelper,
sequence::SequenceView, sequence::SequenceView,
singleton::SingletonView, singleton::SingletonView,
terminal::{TerminalView, TerminalStyle, make_label}, terminal::{TerminalView, TerminalStyle, make_label},
Nested, tree::{NestedNode, TreeNav},
color::{bg_style_from_depth, fg_style_from_depth} color::{bg_style_from_depth, fg_style_from_depth},
PtySegment
}, },
std::sync::Arc, std::sync::Arc,
std::sync::RwLock, std::sync::RwLock,
}; };
pub enum ListSegment<ItemEditor> pub enum ListSegment
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
{ {
InsertCursor, InsertCursor,
Item { Item {
editor: Arc<RwLock<ItemEditor>>, editor: NestedNode,
depth: usize, depth: usize,
cur_dist: isize, cur_dist: isize,
} }
} }
pub trait PTYSegment { impl PtySegment for ListSegment
fn pty_view(&self) -> OuterViewPort<dyn TerminalView>;
}
impl<ItemEditor> PTYSegment for ListSegment<ItemEditor>
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
{ {
fn pty_view(&self) -> OuterViewPort<dyn TerminalView> { fn pty_view(&self) -> OuterViewPort<dyn TerminalView> {
match self { match self {
@ -44,8 +39,8 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
let e = editor.clone(); let e = editor.clone();
let d = *depth; let d = *depth;
let cur_dist = *cur_dist; let cur_dist = *cur_dist;
editor.read().unwrap().get_term_view().map_item(move |_pt, atom| { editor.get_view().map_item(move |_pt, atom| {
let c = e.read().unwrap().get_cursor(); let c = e.get_cursor();
let cur_depth = c.tree_addr.len(); let cur_depth = c.tree_addr.len();
let select = let select =
if cur_dist == 0 { if cur_dist == 0 {
@ -63,29 +58,27 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
} }
} }
pub struct ListSegmentSequence<ItemEditor> pub struct ListSegmentSequence
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
{ {
data: Arc<dyn SequenceView<Item = Arc<RwLock<ItemEditor>>>>, data: Arc<dyn SequenceView<Item = NestedNode>>,
cursor: Arc<dyn SingletonView<Item = ListCursor>>, cursor: Arc<dyn SingletonView<Item = ListCursor>>,
depth: usize, depth: usize,
cur_cursor: ListCursor, cur_cursor: ListCursor,
cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = ListSegment<ItemEditor>>>>>, port: ViewPort<dyn SequenceView<Item = ListSegment>>,
cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = ListSegment>>>>,
proj_helper: ProjectionHelper<usize, Self>, proj_helper: ProjectionHelper<usize, Self>,
} }
impl<ItemEditor> View for ListSegmentSequence<ItemEditor> impl View for ListSegmentSequence
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
{ {
type Msg = usize; type Msg = usize;
} }
impl<ItemEditor> SequenceView for ListSegmentSequence<ItemEditor> impl SequenceView for ListSegmentSequence
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
{ {
type Item = ListSegment<ItemEditor>; type Item = ListSegment;
fn len(&self) -> Option<usize> { fn len(&self) -> Option<usize> {
match self.cur_cursor.mode { match self.cur_cursor.mode {
@ -135,18 +128,18 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
} }
} }
impl<ItemEditor> ListSegmentSequence<ItemEditor> impl ListSegmentSequence
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
{ {
pub fn new( pub fn new(
cursor_port: OuterViewPort<dyn SingletonView<Item = ListCursor>>, cursor_port: OuterViewPort<dyn SingletonView<Item = ListCursor>>,
data_port: OuterViewPort<dyn SequenceView<Item = Arc<RwLock<ItemEditor>>>>, data_port: OuterViewPort<dyn SequenceView<Item = NestedNode>>,
out_port: InnerViewPort<dyn SequenceView<Item = ListSegment<ItemEditor>>>,
depth: usize depth: usize
) -> Arc<RwLock<Self>> { ) -> Arc<RwLock<Self>> {
let mut proj_helper = ProjectionHelper::new(out_port.0.update_hooks.clone()); let out_port = ViewPort::new();
let mut proj_helper = ProjectionHelper::new(out_port.update_hooks.clone());
let proj = Arc::new(RwLock::new(ListSegmentSequence { let proj = Arc::new(RwLock::new(ListSegmentSequence {
cur_cursor: cursor_port.get_view().get(), cur_cursor: cursor_port.get_view().get(),
port: out_port.clone(),
depth, depth,
cursor: proj_helper.new_singleton_arg(0, cursor_port, |s: &mut Self, _msg| { cursor: proj_helper.new_singleton_arg(0, cursor_port, |s: &mut Self, _msg| {
@ -175,13 +168,17 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
s.cast.notify(idx); s.cast.notify(idx);
} }
}), }),
cast: out_port.get_broadcast(), cast: out_port.inner().get_broadcast(),
proj_helper, proj_helper,
})); }));
proj.write().unwrap().proj_helper.set_proj(&proj); proj.write().unwrap().proj_helper.set_proj(&proj);
out_port.set_view(Some(proj.clone())); out_port.inner().set_view(Some(proj.clone()));
proj proj
} }
pub fn get_view(&self) -> OuterViewPort<dyn SequenceView<Item = ListSegment>> {
self.port.outer()
}
} }

View file

@ -1,11 +1,12 @@
use { use {
crate::{ crate::{
core::{TypeTerm, Context}, core::{TypeTerm, Context},
integer::PosIntEditor, integer::{DigitEditor, PosIntEditor},
list::{PTYListEditor}, list::{PTYListEditor},
sequence::{decorator::{SeqDecorStyle}}, sequence::{decorator::{SeqDecorStyle}},
sum::SumEditor, sum::SumEditor,
char_editor::CharEditor, char_editor::CharEditor,
type_term_editor::TypeTermEditor,
Nested Nested
}, },
std::sync::{Arc, RwLock}, std::sync::{Arc, RwLock},
@ -17,9 +18,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
ctx.write().unwrap().add_editor_ctor( ctx.write().unwrap().add_editor_ctor(
"Char", Arc::new( "Char", Arc::new(
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, _depth: usize| { |ctx: Arc<RwLock<Context>>, _ty: TypeTerm, _depth: usize| {
Some( Some(CharEditor::new_node(&ctx))
Arc::new(RwLock::new(CharEditor::new_node(&ctx)))
as Arc<RwLock<dyn Nested + Send + Sync>>)
} }
) )
); );
@ -50,7 +49,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
let delim = if args.len() > 1 { let delim = if args.len() > 1 {
match args[1] { match args[1] {
TypeTerm::Num(0) => Some(' '), TypeTerm::Num(0) => None,
TypeTerm::Num(1) => Some(' '), TypeTerm::Num(1) => Some(' '),
TypeTerm::Num(2) => Some('\n'), TypeTerm::Num(2) => Some('\n'),
TypeTerm::Num(3) => None, TypeTerm::Num(3) => None,
@ -64,17 +63,13 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
}; };
Some( Some(
Arc::new(RwLock::new(PTYListEditor::new( PTYListEditor::new(
Box::new({ ctx.clone(),
move || { args[0].clone(),
Context::make_editor(ctx.clone(), args[0].clone(), depth + 1).unwrap()
}
}),
style, style,
delim, delim,
depth depth
))) ).into_node()
as Arc<RwLock<dyn Nested + Send + Sync>>
) )
} else { } else {
None None
@ -90,7 +85,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
"Symbol", Arc::new( "Symbol", Arc::new(
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| { |ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
Context::make_editor( Context::make_editor(
ctx.clone(), &ctx,
ctx.read().unwrap().type_term_from_str("( List Char 0 )").unwrap(), ctx.read().unwrap().type_term_from_str("( List Char 0 )").unwrap(),
depth depth
) )
@ -102,7 +97,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
"String", Arc::new( "String", Arc::new(
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| { |ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
Context::make_editor( Context::make_editor(
ctx.clone(), &ctx,
ctx.read().unwrap().type_term_from_str("( List Char 3 )").unwrap(), ctx.read().unwrap().type_term_from_str("( List Char 3 )").unwrap(),
depth depth
) )
@ -113,19 +108,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
ctx.write().unwrap().add_editor_ctor( ctx.write().unwrap().add_editor_ctor(
"TypeTerm", Arc::new( "TypeTerm", Arc::new(
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| { |ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
let mut s = SumEditor::new( Some(TypeTermEditor::new(ctx, depth).into_node())
vec![
Context::make_editor(ctx.clone(), ctx.read().unwrap().type_term_from_str("( Symbol )").unwrap(), depth+1).unwrap(),
Context::make_editor(ctx.clone(), ctx.read().unwrap().type_term_from_str("( PosInt 10 )").unwrap(), depth+1).unwrap(),
Context::make_editor(ctx.clone(), ctx.read().unwrap().type_term_from_str("( List TypeTerm )").unwrap(), depth+1).unwrap(),
]
);
s.select(0);
Some(
Arc::new(RwLock::new(
s
))
)
} }
) )
); );
@ -138,11 +121,13 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
let ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent)))); let ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent))));
ctx.write().unwrap().add_typename("MachineInt".into()); 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_typename("BigEndian".into());
//ctx.write().unwrap().add_typename("Digit".into());
ctx.write().unwrap().add_editor_ctor( ctx.write().unwrap().add_editor_ctor(
"PosInt", Arc::new( "Digit", Arc::new(
|_ctx: Arc<RwLock<Context>>, ty: TypeTerm, _depth: usize| { |ctx: Arc<RwLock<Context>>, ty: TypeTerm, _depth: usize| {
match ty { match ty {
TypeTerm::Type { TypeTerm::Type {
id: _, args id: _, args
@ -151,8 +136,33 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
match args[0] { match args[0] {
TypeTerm::Num(radix) => { TypeTerm::Num(radix) => {
Some( Some(
Arc::new(RwLock::new(PosIntEditor::new(radix as u32))) DigitEditor::new(ctx.clone(), radix as u32).into_node()
as Arc<RwLock<dyn Nested + Send + Sync>> )
},
_ => None
}
} else {
None
}
}
_ => None
}
}
)
);
ctx.write().unwrap().add_editor_ctor(
"PosInt", Arc::new(
|ctx: Arc<RwLock<Context>>, ty: TypeTerm, _depth: usize| {
match ty {
TypeTerm::Type {
id: _, args
} => {
if args.len() > 0 {
match args[0] {
TypeTerm::Num(radix) => {
Some(
PosIntEditor::new(ctx.clone(), radix as u32).into_node()
) )
}, },
_ => None _ => None
@ -177,7 +187,7 @@ pub fn init_os_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
"PathSegment", Arc::new( "PathSegment", Arc::new(
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| { |ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
Context::make_editor( Context::make_editor(
ctx.clone(), &ctx,
ctx.read().unwrap().type_term_from_str("( List Char 0 )").unwrap(), ctx.read().unwrap().type_term_from_str("( List Char 0 )").unwrap(),
depth depth
) )
@ -189,7 +199,7 @@ pub fn init_os_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
"Path", Arc::new( "Path", Arc::new(
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| { |ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
Context::make_editor( Context::make_editor(
ctx.clone(), &ctx,
ctx.read().unwrap().type_term_from_str("( List PathSegment 6 )").unwrap(), ctx.read().unwrap().type_term_from_str("( List PathSegment 6 )").unwrap(),
depth+1 depth+1
) )

View file

@ -13,7 +13,7 @@ use {
tree::{TreeNav, TreeNavResult}, tree::{TreeNav, TreeNavResult},
diagnostics::{Diagnostics}, diagnostics::{Diagnostics},
terminal::{TerminalStyle}, terminal::{TerminalStyle},
Nested tree::NestedNode
}, },
cgmath::{Point2}, cgmath::{Point2},
std::sync::{Arc, RwLock}, std::sync::{Arc, RwLock},
@ -110,7 +110,7 @@ impl ProductEditor {
Some(self.get_editor_segment_mut(self.cursor?)) Some(self.get_editor_segment_mut(self.cursor?))
} }
pub fn get_editor(&self, idx: isize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> { pub fn get_editor(&self, idx: isize) -> Option<NestedNode> {
if let ProductEditorSegment::N{ t: _, editor, ed_depth: _, cur_depth: _, cur_dist: _ } = self.get_editor_segment(idx) { if let ProductEditorSegment::N{ t: _, editor, ed_depth: _, cur_depth: _, cur_dist: _ } = self.get_editor_segment(idx) {
editor editor
} else { } else {
@ -118,7 +118,7 @@ impl ProductEditor {
} }
} }
pub fn get_cur_editor(&self) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> { pub fn get_cur_editor(&self) -> Option<NestedNode> {
self.get_editor(self.cursor?) self.get_editor(self.cursor?)
} }
@ -143,7 +143,7 @@ impl ProductEditor {
}; };
if let Some(e) = editor { if let Some(e) = editor {
self.msg_buf.update(idx as usize, Some(e.read().unwrap().get_msg_port())); self.msg_buf.update(idx as usize, Some(e.get_msg_port()));
} else { } else {
let mut b = VecBuffer::new(); let mut b = VecBuffer::new();
b.push(crate::diagnostics::make_todo(crate::terminal::make_label(&format!("complete {}", self.ctx.read().unwrap().type_term_to_str(&t[0]))))); b.push(crate::diagnostics::make_todo(crate::terminal::make_label(&format!("complete {}", self.ctx.read().unwrap().type_term_to_str(&t[0])))));
@ -192,9 +192,8 @@ impl TerminalEditor for ProductEditor {
if let Some(ProductEditorSegment::N{ t, editor, ed_depth, cur_depth, cur_dist: _ }) = segment.deref_mut() { if let Some(ProductEditorSegment::N{ t, editor, ed_depth, cur_depth, cur_dist: _ }) = segment.deref_mut() {
*cur_depth = self.get_cursor().tree_addr.len(); *cur_depth = self.get_cursor().tree_addr.len();
if let Some(e) = editor.clone() { if let Some(mut e) = editor.clone() {
let mut ce = e.write().unwrap(); match e.handle_terminal_event(event) {
match ce.handle_terminal_event(event) {
TerminalEditorResult::Exit => TerminalEditorResult::Exit =>
match event { match event {
TerminalEvent::Input(Event::Key(Key::Backspace)) => { TerminalEvent::Input(Event::Key(Key::Backspace)) => {
@ -203,8 +202,7 @@ impl TerminalEditor for ProductEditor {
TerminalEditorResult::Continue TerminalEditorResult::Continue
} }
_ => { _ => {
*cur_depth = ce.get_cursor().tree_addr.len(); *cur_depth = e.get_cursor().tree_addr.len();
drop(ce);
match self.nexd() { match self.nexd() {
TreeNavResult::Continue => TerminalEditorResult::Continue, TreeNavResult::Continue => TerminalEditorResult::Continue,
TreeNavResult::Exit => TerminalEditorResult::Exit TreeNavResult::Exit => TerminalEditorResult::Exit
@ -212,17 +210,17 @@ impl TerminalEditor for ProductEditor {
} }
}, },
TerminalEditorResult::Continue => { TerminalEditorResult::Continue => {
*cur_depth = ce.get_cursor().tree_addr.len(); *cur_depth = e.get_cursor().tree_addr.len();
TerminalEditorResult::Continue TerminalEditorResult::Continue
} }
} }
} else { } else {
let e = Context::make_editor(self.ctx.clone(), t[0].clone(), *ed_depth+1).unwrap(); let mut e = Context::make_editor(&self.ctx, t[0].clone(), *ed_depth+1).unwrap();
*editor = Some(e.clone()); *editor = Some(e.clone());
update_segment = true; update_segment = true;
e.write().unwrap().dn(); e.dn();
let x = e.write().unwrap().handle_terminal_event(event); let x = e.handle_terminal_event(event);
x x
} }
} else { } else {

View file

@ -14,7 +14,7 @@ impl TreeNav for ProductEditor {
fn get_cursor(&self) -> TreeCursor { fn get_cursor(&self) -> TreeCursor {
if let Some(i) = self.cursor { if let Some(i) = self.cursor {
if let Some(e) = self.get_editor(i) { if let Some(e) = self.get_editor(i) {
let mut c = e.read().unwrap().get_cursor(); let mut c = e.get_cursor();
if c.tree_addr.len() == 0 { if c.tree_addr.len() == 0 {
c.leaf_mode = ListCursorMode::Select; c.leaf_mode = ListCursorMode::Select;
} }
@ -34,7 +34,7 @@ impl TreeNav for ProductEditor {
fn get_cursor_warp(&self) -> TreeCursor { fn get_cursor_warp(&self) -> TreeCursor {
if let Some(i) = self.cursor { if let Some(i) = self.cursor {
if let Some(e) = self.get_editor(i) { if let Some(e) = self.get_editor(i) {
let mut c = e.read().unwrap().get_cursor_warp(); let mut c = e.get_cursor_warp();
if c.tree_addr.len() == 0 { if c.tree_addr.len() == 0 {
c.leaf_mode = ListCursorMode::Select; c.leaf_mode = ListCursorMode::Select;
} }
@ -57,7 +57,6 @@ impl TreeNav for ProductEditor {
if let Some(mut segment) = self.get_cur_segment_mut() { if let Some(mut segment) = self.get_cur_segment_mut() {
if let Some(ProductEditorSegment::N{ t: _t, editor, ed_depth: _, cur_depth: _, cur_dist:_ }) = segment.deref_mut() { if let Some(ProductEditorSegment::N{ t: _t, editor, ed_depth: _, cur_depth: _, cur_dist:_ }) = segment.deref_mut() {
if let Some(e) = editor { if let Some(e) = editor {
let mut e = e.write().unwrap();
e.goto(TreeCursor::none()); e.goto(TreeCursor::none());
} }
} }
@ -68,12 +67,11 @@ impl TreeNav for ProductEditor {
if let Some(mut element) = self.get_cur_segment_mut() { if let Some(mut element) = self.get_cur_segment_mut() {
if let Some(ProductEditorSegment::N{ t, editor, ed_depth, cur_depth: _, cur_dist:_ }) = element.deref_mut() { if let Some(ProductEditorSegment::N{ t, editor, ed_depth, cur_depth: _, cur_dist:_ }) = element.deref_mut() {
if let Some(e) = editor { if let Some(e) = editor {
e.write().unwrap().goto(c.clone()); e.goto(c.clone());
} else if c.tree_addr.len() > 0 { } else if c.tree_addr.len() > 0 {
// create editor // create editor
let e = Context::make_editor(self.ctx.clone(), t[0].clone(), *ed_depth+1).unwrap(); let mut e = Context::make_editor(&self.ctx, t[0].clone(), *ed_depth+1).unwrap();
*editor = Some(e.clone()); *editor = Some(e.clone());
let mut e = e.write().unwrap();
e.goto(c.clone()); e.goto(c.clone());
} }
} }
@ -89,8 +87,8 @@ impl TreeNav for ProductEditor {
TreeNavResult::Continue TreeNavResult::Continue
} else { } else {
if let Some(ed) = self.get_cur_editor() { if let Some(mut ed) = self.get_cur_editor() {
ed.write().unwrap().goto(TreeCursor::none()); ed.goto(TreeCursor::none());
} }
self.cursor = None; self.cursor = None;
@ -125,14 +123,12 @@ impl TreeNav for ProductEditor {
if let Some(mut element) = self.get_cur_segment_mut() { if let Some(mut element) = self.get_cur_segment_mut() {
if let Some(ProductEditorSegment::N{ t, editor, ed_depth, cur_depth: _, cur_dist:_ }) = element.deref_mut() { if let Some(ProductEditorSegment::N{ t, editor, ed_depth, cur_depth: _, cur_dist:_ }) = element.deref_mut() {
if let Some(e) = editor { if let Some(e) = editor {
let mut e = e.write().unwrap();
e.goby(direction); e.goby(direction);
} else { } else {
// create editor // create editor
let e = Context::make_editor(self.ctx.clone(), t[0].clone(), *ed_depth+1).unwrap(); let mut e = Context::make_editor(&self.ctx, t[0].clone(), *ed_depth+1).unwrap();
*editor = Some(e.clone()); *editor = Some(e.clone());
let mut e = e.write().unwrap();
e.goby(direction); e.goby(direction);
} }
} }
@ -175,15 +171,13 @@ impl TreeNav for ProductEditor {
let nav_result = let nav_result =
if let Some(mut element) = self.get_cur_segment_mut() { if let Some(mut element) = self.get_cur_segment_mut() {
if let Some(ProductEditorSegment::N{ t: _, editor, ed_depth: _, cur_depth, cur_dist:_ }) = element.deref_mut() { if let Some(ProductEditorSegment::N{ t: _, editor, ed_depth: _, cur_depth, cur_dist:_ }) = element.deref_mut() {
if let Some(e) = editor { if let Some(mut e) = editor.as_mut() {
let mut ce = e.write().unwrap();
//\\//\\//\\//\\ //\\//\\//\\//\\
// horizontal // // horizontal //
//\\//\\//\\//\\ //\\//\\//\\//\\
match ce.goby(direction) { match e.goby(direction) {
TreeNavResult::Exit => { TreeNavResult::Exit => {
// *cur_depth = 1; // *cur_depth = 1;
drop(ce);
drop(e); drop(e);
if direction.y < 0 { if direction.y < 0 {

View file

@ -6,7 +6,7 @@ use {
make_label make_label
}, },
color::{bg_style_from_depth, fg_style_from_depth}, color::{bg_style_from_depth, fg_style_from_depth},
Nested tree::{NestedNode, TreeNav}
}, },
std::{sync::{Arc, RwLock}}, std::{sync::{Arc, RwLock}},
}; };
@ -16,7 +16,7 @@ pub enum ProductEditorSegment {
T( String, usize ), T( String, usize ),
N { N {
t: TypeLadder, t: TypeLadder,
editor: Option<Arc<RwLock<dyn Nested + Send + Sync>>>, editor: Option<NestedNode>,
ed_depth: usize, ed_depth: usize,
cur_depth: usize, cur_depth: usize,
cur_dist: isize cur_dist: isize
@ -36,15 +36,14 @@ impl ProductEditorSegment {
), ),
ProductEditorSegment::N { t: _, editor: Some(e), ed_depth, cur_depth: _, cur_dist } => ProductEditorSegment::N { t: _, editor: Some(e), ed_depth, cur_depth: _, cur_dist } =>
e.read().unwrap() e.get_view()
.get_term_view()
.map_item({ .map_item({
let e = e.clone(); let e = e.clone();
let d = *ed_depth; let d = *ed_depth;
let cur_dist = *cur_dist; let cur_dist = *cur_dist;
move |_i, x| { move |_i, x| {
let c = e.read().unwrap().get_cursor(); let c = e.get_cursor();
let cur_depth = c.tree_addr.len(); let cur_depth = c.tree_addr.len();
let select = let select =
if cur_dist == 0 { if cur_dist == 0 {

View file

@ -8,7 +8,9 @@ use {
sequence::{SequenceView}, sequence::{SequenceView},
tree::{TreeNav, TreeCursor, TreeNavResult}, tree::{TreeNav, TreeCursor, TreeNavResult},
diagnostics::{Diagnostics, Message}, diagnostics::{Diagnostics, Message},
Nested tree::NestedNode,
Commander,
PtySegment
}, },
cgmath::{Vector2}, cgmath::{Vector2},
std::sync::{Arc, RwLock}, std::sync::{Arc, RwLock},
@ -17,7 +19,7 @@ use {
pub struct SumEditor { pub struct SumEditor {
cur: usize, cur: usize,
pub editors: Vec< Arc<RwLock<dyn Nested + Send + Sync + 'static>> >, pub editors: Vec< NestedNode >,
port: ViewPort< dyn TerminalView >, port: ViewPort< dyn TerminalView >,
diag_port: ViewPort< dyn SequenceView<Item = Message> > diag_port: ViewPort< dyn SequenceView<Item = Message> >
@ -25,7 +27,7 @@ pub struct SumEditor {
impl SumEditor { impl SumEditor {
pub fn new( pub fn new(
editors: Vec< Arc<RwLock<dyn Nested + Send + Sync + 'static>> > editors: Vec< NestedNode >
) -> Self { ) -> Self {
let port = ViewPort::new(); let port = ViewPort::new();
//let mut diag_buf = VecBuffer::new(); //let mut diag_buf = VecBuffer::new();
@ -37,21 +39,30 @@ impl SumEditor {
diag_port: ViewPort::new()//diag_buf.get_port().to_sequence() diag_port: ViewPort::new()//diag_buf.get_port().to_sequence()
} }
} }
/*
pub fn get(&self) -> Arc<RwLock<dyn Nested + Send + Sync>> { pub fn into_node(self) -> NestedNode {
let editor = Arc::new(RwLock::new(self));
NestedNode::new()
.set_view()
.set_cmd(editor.clone())
.set_nav(editor.clone())
.set_diag(editor.read().unwrap().diag.clone())
}
*/
pub fn get(&self) -> NestedNode {
self.editors[ self.cur ].clone() self.editors[ self.cur ].clone()
} }
pub fn select(&mut self, idx: usize) { pub fn select(&mut self, idx: usize) {
self.cur = idx; self.cur = idx;
let tv = self.editors[ self.cur ].read().unwrap().get_term_view(); let tv = self.editors[ self.cur ].get_term_view();
tv.add_observer( self.port.get_cast() ); tv.add_observer( self.port.get_cast() );
self.port.update_hooks.write().unwrap().clear(); self.port.update_hooks.write().unwrap().clear();
self.port.add_update_hook( Arc::new(tv.0.clone()) ); self.port.add_update_hook( Arc::new(tv.0.clone()) );
self.port.set_view( Some(tv.get_view_arc()) ); self.port.set_view( Some(tv.get_view_arc()) );
let dv = self.editors[ self.cur ].read().unwrap().get_msg_port(); let dv = self.editors[ self.cur ].get_msg_port();
dv.add_observer( self.diag_port.get_cast() ); dv.add_observer( self.diag_port.get_cast() );
self.diag_port.update_hooks.write().unwrap().clear(); self.diag_port.update_hooks.write().unwrap().clear();
self.diag_port.add_update_hook( Arc::new(dv.0.clone()) ); self.diag_port.add_update_hook( Arc::new(dv.0.clone()) );
@ -61,55 +72,48 @@ impl SumEditor {
impl TreeNav for SumEditor { impl TreeNav for SumEditor {
fn get_cursor(&self) -> TreeCursor { fn get_cursor(&self) -> TreeCursor {
self.editors[ self.cur ].write().unwrap().get_cursor() self.editors[ self.cur ].get_cursor()
} }
fn get_cursor_warp(&self) -> TreeCursor { fn get_cursor_warp(&self) -> TreeCursor {
self.editors[ self.cur ].write().unwrap().get_cursor_warp() self.editors[ self.cur ].get_cursor_warp()
} }
fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult { fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult {
self.editors[ self.cur ].write().unwrap().goby( direction ) self.editors[ self.cur ].goby( direction )
} }
fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult { fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult {
self.editors[ self.cur ].write().unwrap().goto( new_cursor ) self.editors[ self.cur ].goto( new_cursor )
} }
} }
impl TerminalEditor for SumEditor { impl PtySegment for SumEditor {
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> { fn pty_view(&self) -> OuterViewPort<dyn TerminalView> {
self.port.outer() self.port.outer()
} }
}
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { impl Commander for SumEditor {
type Cmd = TerminalEvent;
fn send_cmd(&mut self, event: &TerminalEvent) {
match event { match event {
TerminalEvent::Input( termion::event::Event::Key(Key::Ctrl('x')) ) => { TerminalEvent::Input( termion::event::Event::Key(Key::Ctrl('x')) ) => {
let res = self.editors[ self.cur ].write().unwrap().handle_terminal_event( event ); let res = self.editors[ self.cur ].handle_terminal_event( event );
match res { match res {
TerminalEditorResult::Exit => { TerminalEditorResult::Exit => {
self.select( (self.cur + 1) % self.editors.len() ); self.select( (self.cur + 1) % self.editors.len() );
if self.editors[ self.cur ].read().unwrap().get_cursor().tree_addr.len() == 0 { if self.editors[ self.cur ].get_cursor().tree_addr.len() == 0 {
self.dn(); self.dn();
} }
TerminalEditorResult::Continue
}, },
_ => TerminalEditorResult::Continue _ => {}
} }
}, },
event => { event => {
self.editors[ self.cur ].write().unwrap().handle_terminal_event( event ) self.editors[ self.cur ].handle_terminal_event( event );
} }
} }
} }
} }
impl Diagnostics for SumEditor {
fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
self.diag_port.outer()
}
}
impl Nested for SumEditor {}

View file

@ -7,17 +7,19 @@ use {
sequence::SequenceView, sequence::SequenceView,
terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult}, terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult},
diagnostics::{Diagnostics, Message}, diagnostics::{Diagnostics, Message},
tree::{TreeNav, TreeCursor, TreeNavResult}, ObjCommander, tree::{TreeNav, TreeCursor, TreeNavResult},
ObjCommander,
Nested Nested
}, }
}; };
#[derive(Clone)]
pub struct NestedNode { pub struct NestedNode {
ctx: Option<Arc<RwLock<Context>>>, pub ctx: Option<Arc<RwLock<Context>>>,
view: Option<OuterViewPort<dyn TerminalView>>, pub view: Option<OuterViewPort<dyn TerminalView>>,
diag: Option<OuterViewPort<dyn SequenceView<Item = Message>>>, pub diag: Option<OuterViewPort<dyn SequenceView<Item = Message>>>,
cmd: Option<Arc<RwLock<dyn ObjCommander + Send + Sync>>>, pub cmd: Option<Arc<RwLock<dyn ObjCommander + Send + Sync>>>,
tree_nav: Option<Arc<RwLock<dyn TreeNav + Send + Sync>>>, pub tree_nav: Option<Arc<RwLock<dyn TreeNav + Send + Sync>>>,
} }
impl ObjCommander for NestedNode { impl ObjCommander for NestedNode {
@ -111,11 +113,25 @@ impl NestedNode {
self self
} }
pub fn with_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self { pub fn set_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self {
self.cmd = Some(cmd); self.cmd = Some(cmd);
self self
} }
pub fn set_nav(mut self, nav: Arc<RwLock<dyn TreeNav + Send + Sync>>) -> Self {
self.tree_nav = Some(nav);
self
}
pub fn set_diag(mut self, diag: OuterViewPort<dyn SequenceView<Item = Message>>) -> Self {
self.diag = Some(diag);
self
}
pub fn get_diag(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
self.diag.clone().unwrap_or(ViewPort::new().into_outer())
}
pub fn get_view(&self) -> OuterViewPort<dyn TerminalView> { pub fn get_view(&self) -> OuterViewPort<dyn TerminalView> {
self.view.clone().unwrap_or(ViewPort::new().into_outer()) self.view.clone().unwrap_or(ViewPort::new().into_outer())
} }

View file

@ -9,7 +9,8 @@ use {
sum::SumEditor, sum::SumEditor,
char_editor::CharEditor, char_editor::CharEditor,
integer::PosIntEditor, integer::PosIntEditor,
Nested tree::NestedNode,
Commander, PtySegment
}, },
cgmath::{Vector2}, cgmath::{Vector2},
termion::event::{Key}, termion::event::{Key},
@ -27,128 +28,93 @@ enum TypeTermVar {
} }
pub struct TypeTermEditor { pub struct TypeTermEditor {
ctx: Arc<RwLock<Context>>,
ty: TypeTermVar, ty: TypeTermVar,
node: SumEditor, sum_edit: Arc<RwLock<SumEditor>>
} }
impl TypeTermEditor { impl TypeTermEditor {
pub fn new(ctx: Arc<RwLock<Context>>, depth: usize) -> Self { pub fn new(ctx: Arc<RwLock<Context>>, depth: usize) -> Self {
TypeTermEditor { TypeTermEditor {
ctx: ctx.clone(),
ty: TypeTermVar::Any, ty: TypeTermVar::Any,
node: SumEditor::new( sum_edit: Arc::new(RwLock::new(SumEditor::new(
vec![ vec![
Arc::new(RwLock::new(PTYListEditor::new( Context::make_editor( &ctx, ctx.read().unwrap().type_term_from_str("( List TypeTerm 1 )").unwrap(), depth + 1).unwrap(),
Box::new({ Context::make_editor( &ctx, ctx.read().unwrap().type_term_from_str("( PosInt 10 )").unwrap(), depth + 1 ).unwrap(),
let ctx = ctx.clone(); Context::make_editor( &ctx, ctx.read().unwrap().type_term_from_str("( Symbol )").unwrap(), depth + 1 ).unwrap()
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<isize>) -> TreeNavResult {
self.node.goby( direction )
}
fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult {
self.node.goto( new_cursor )
} }
} }
impl TerminalEditor for TypeTermEditor { pub fn into_node(self) -> NestedNode {
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> { NestedNode::new()
self.node.get_term_view() .set_ctx(self.ctx.clone())
.set_nav(self.sum_edit.clone())
.set_cmd(self.sum_edit.clone())
.set_view(
self.sum_edit.read().unwrap().pty_view()
)
}
} }
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { impl Commander for TypeTermEditor {
type Cmd = TerminalEvent;
fn send_cmd(&mut self, event: &TerminalEvent) {
match event { match event {
TerminalEvent::Input( termion::event::Event::Key(Key::Char(c)) ) => { TerminalEvent::Input( termion::event::Event::Key(Key::Char(c)) ) => {
match self.ty { match self.ty {
TypeTermVar::Any => { TypeTermVar::Any => {
self.ty = self.ty =
if *c == '(' { if *c == '(' {
self.node.select(0); let mut se = self.sum_edit.write().unwrap();
self.dn(); se.select(0);
se.dn();
TypeTermVar::List TypeTermVar::List
} else if c.to_digit(10).is_some() { } else if c.to_digit(10).is_some() {
self.node.select(1); let mut se = self.sum_edit.write().unwrap();
self.dn(); se.select(1);
self.node.handle_terminal_event( event ); se.dn();
se.send_cmd( event );
TypeTermVar::Num TypeTermVar::Num
} else { } else {
self.node.select(2); let mut se = self.sum_edit.write().unwrap();
self.dn(); se.select(2);
self.node.handle_terminal_event( event ); se.dn();
se.send_cmd( event );
TypeTermVar::Symbol TypeTermVar::Symbol
}; };
TerminalEditorResult::Continue
}, },
_ => { _ => {
if *c == '(' { if *c == '(' {
let _child = Arc::new(RwLock::new(TypeTermEditor { let _child = Arc::new(RwLock::new(TypeTermEditor {
ctx: self.ctx.clone(),
ty: self.ty.clone(), ty: self.ty.clone(),
node: SumEditor::new( sum_edit: Arc::new(RwLock::new(SumEditor::new(
vec![ vec![
self.node.editors[0].clone(), self.sum_edit.read().unwrap().editors[0].clone(),
self.node.editors[1].clone(), self.sum_edit.read().unwrap().editors[1].clone(),
self.node.editors[2].clone(), self.sum_edit.read().unwrap().editors[2].clone(),
]) ])))
})); }));
self.ty = TypeTermVar::List; self.ty = TypeTermVar::List;
self.node.select(0); self.sum_edit.write().unwrap().select(0);
/* /*
let l = self.node.editors[0].clone(); let l = self.node.editors[0].clone();
let l = l.downcast::<RwLock<PTYListEditor<TypeTermEditor>>>().unwrap(); let l = l.downcast::<RwLock<PTYListEditor<TypeTermEditor>>>().unwrap();
l.write().unwrap().data.push(child); l.write().unwrap().data.push(child);
*/ */
TerminalEditorResult::Continue
} else { } else {
self.node.handle_terminal_event( event ) self.sum_edit.write().unwrap().send_cmd( event );
} }
} }
} }
}, },
event => { event => {
self.node.handle_terminal_event( event ) self.sum_edit.write().unwrap().send_cmd( event );
} }
} }
} }
} }
impl Diagnostics for TypeTermEditor {
fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
self.node.get_msg_port()
}
}
impl Nested for TypeTermEditor {}

View file

@ -13,7 +13,7 @@ use {
core::{port::UpdateTask, Observer, AnyOuterViewPort, ViewPort, Context, ReprTree}, core::{port::UpdateTask, Observer, AnyOuterViewPort, ViewPort, Context, ReprTree},
index::IndexArea, index::IndexArea,
list::{ListCursorMode, PTYListEditor}, list::{ListCursorMode, PTYListEditor},
sequence::{decorator::{SeqDecorStyle}}, sequence::{decorator::{SeqDecorStyle, Separate}},
terminal::{ terminal::{
make_label, Terminal, TerminalAtom, TerminalCompositor, TerminalEditor, make_label, Terminal, TerminalAtom, TerminalCompositor, TerminalEditor,
TerminalEditorResult, TerminalEvent, TerminalStyle, TerminalEditorResult, TerminalEvent, TerminalStyle,
@ -21,7 +21,8 @@ use {
tree::{TreeNav, TreeCursor, TreeNavResult}, tree::{TreeNav, TreeCursor, TreeNavResult},
vec::VecBuffer, vec::VecBuffer,
diagnostics::{Diagnostics}, diagnostics::{Diagnostics},
index::{buffer::IndexBuffer} index::{buffer::IndexBuffer},
Commander
}, },
std::sync::{Arc, RwLock}, std::sync::{Arc, RwLock},
termion::event::{Event, Key}, termion::event::{Event, Key},
@ -60,7 +61,7 @@ async fn main() {
let vb = VecBuffer::<char>::new(); let vb = VecBuffer::<char>::new();
let rt_char = ReprTree::new_leaf( let rt_char = ReprTree::new_leaf(
ctx.read().unwrap().type_term_from_str("( List Char )").unwrap(), ctx.read().unwrap().type_term_from_str("( List Char 0 )").unwrap(),
AnyOuterViewPort::from(vb.get_port()) AnyOuterViewPort::from(vb.get_port())
); );
let rt_digit = ReprTree::upcast(&rt_char, ctx.read().unwrap().type_term_from_str("( List ( Digit 10 ) )").unwrap()); let rt_digit = ReprTree::upcast(&rt_char, ctx.read().unwrap().type_term_from_str("( List ( Digit 10 ) )").unwrap());
@ -96,14 +97,11 @@ async fn main() {
let c = ctx.clone(); let c = ctx.clone();
let mut process_list_editor = let mut process_list_editor =
PTYListEditor::new( PTYListEditor::new(
Box::new( move || { ctx.clone(),
Arc::new(RwLock::new(nested::type_term_editor::TypeTermEditor::new(c.clone(), 1))) c.read().unwrap().type_term_from_str("( List Path 1 )").unwrap(),
// 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, SeqDecorStyle::Plain,
Some('\n'), Some('\n'),
0 3
); );
async_std::task::spawn(async move { async_std::task::spawn(async move {
@ -131,7 +129,8 @@ async fn main() {
(Point2::new(0, 2), magic.clone()), (Point2::new(0, 2), magic.clone()),
(Point2::new(0, 3), make_label(" ")), (Point2::new(0, 3), make_label(" ")),
(Point2::new(0, 4), (Point2::new(0, 4),
process_list_editor.editor process_list_editor
.editor.read().unwrap()
.get_seg_seq_view() .get_seg_seq_view()
.enumerate() .enumerate()
.map( .map(
@ -158,7 +157,6 @@ async fn main() {
buf.get_port() buf.get_port()
} }
) )
/*
.separate({ .separate({
let mut buf = IndexBuffer::new(); let mut buf = IndexBuffer::new();
buf.insert(Point2::new(1,0), buf.insert(Point2::new(1,0),
@ -169,9 +167,7 @@ async fn main() {
) )
); );
buf.get_port() buf.get_port()
} })
)
*/
.to_grid_vertical() .to_grid_vertical()
.flatten() .flatten()
.flatten() .flatten()
@ -180,7 +176,7 @@ async fn main() {
(Point2::new(0, 5), make_label(" ")), (Point2::new(0, 5), make_label(" ")),
(Point2::new(0, 6), magic.clone()), (Point2::new(0, 6), magic.clone()),
(Point2::new(0, 7), process_list_editor.get_msg_port().map( (Point2::new(0, 7), process_list_editor.diag.map(
|entry| { |entry| {
let mut b = VecBuffer::new(); let mut b = VecBuffer::new();
b.push( b.push(
@ -234,7 +230,7 @@ async fn main() {
.unwrap() .unwrap()
.push(table.get_port().flatten().offset(Vector2::new(3, 0))); .push(table.get_port().flatten().offset(Vector2::new(3, 0)));
process_list_editor.goto(TreeCursor { process_list_editor.editor.write().unwrap().goto(TreeCursor {
leaf_mode: ListCursorMode::Insert, leaf_mode: ListCursorMode::Insert,
tree_addr: vec![0], tree_addr: vec![0],
}); });
@ -269,54 +265,50 @@ async fn main() {
match ev { match ev {
TerminalEvent::Input(Event::Key(Key::Ctrl('d'))) => break, TerminalEvent::Input(Event::Key(Key::Ctrl('d'))) => break,
TerminalEvent::Input(Event::Key(Key::Ctrl('l'))) => { TerminalEvent::Input(Event::Key(Key::Ctrl('l'))) => {
process_list_editor.goto(TreeCursor { process_list_editor.editor.write().unwrap().goto(TreeCursor {
leaf_mode: ListCursorMode::Insert, leaf_mode: ListCursorMode::Insert,
tree_addr: vec![0], tree_addr: vec![0],
}); });
//process_list_editor.clear(); //process_list_editor.clear();
} }
TerminalEvent::Input(Event::Key(Key::Left)) => { TerminalEvent::Input(Event::Key(Key::Left)) => {
process_list_editor.pxev(); process_list_editor.editor.write().unwrap().pxev();
} }
TerminalEvent::Input(Event::Key(Key::Right)) => { TerminalEvent::Input(Event::Key(Key::Right)) => {
process_list_editor.nexd(); process_list_editor.editor.write().unwrap().nexd();
} }
TerminalEvent::Input(Event::Key(Key::Up)) => { TerminalEvent::Input(Event::Key(Key::Up)) => {
if process_list_editor.up() == TreeNavResult::Exit { if process_list_editor.editor.write().unwrap().up() == TreeNavResult::Exit {
process_list_editor.dn(); process_list_editor.editor.write().unwrap().dn();
} }
} }
TerminalEvent::Input(Event::Key(Key::Down)) => { TerminalEvent::Input(Event::Key(Key::Down)) => {
process_list_editor.dn(); process_list_editor.editor.write().unwrap().dn();
// == TreeNavResult::Continue { // == TreeNavResult::Continue {
//process_list_editor.goto_home(); //process_list_editor.goto_home();
//} //}
} }
TerminalEvent::Input(Event::Key(Key::Home)) => { TerminalEvent::Input(Event::Key(Key::Home)) => {
process_list_editor.qpxev(); process_list_editor.editor.write().unwrap().qpxev();
} }
TerminalEvent::Input(Event::Key(Key::End)) => { TerminalEvent::Input(Event::Key(Key::End)) => {
process_list_editor.qnexd(); process_list_editor.editor.write().unwrap().qnexd();
} }
TerminalEvent::Input(Event::Key(Key::Char('\t'))) => { TerminalEvent::Input(Event::Key(Key::Char('\t'))) => {
let mut c = process_list_editor.get_cursor(); let mut c = process_list_editor.editor.read().unwrap().get_cursor();
c.leaf_mode = match c.leaf_mode { c.leaf_mode = match c.leaf_mode {
ListCursorMode::Select => ListCursorMode::Insert, ListCursorMode::Select => ListCursorMode::Insert,
ListCursorMode::Insert => ListCursorMode::Select ListCursorMode::Insert => ListCursorMode::Select
}; };
process_list_editor.goto(c); process_list_editor.editor.write().unwrap().goto(c);
} }
ev => { ev => {
if let TerminalEditorResult::Exit = process_list_editor.send_cmd(&ev);
process_list_editor.handle_terminal_event(&ev)
{
//process_list_editor.nexd();
}
} }
} }
status_chars.clear(); status_chars.clear();
let cur = process_list_editor.get_cursor(); let cur = process_list_editor.editor.read().unwrap().get_cursor();
if cur.tree_addr.len() > 0 { if cur.tree_addr.len() > 0 {
status_chars.push(TerminalAtom::new( status_chars.push(TerminalAtom::new(