further refactor pty-list, node morphisms, commander

This commit is contained in:
Michael Sippel 2023-02-18 04:15:47 +01:00
parent 2bdea3e2a3
commit cf313727a6
Signed by: senvas
GPG key ID: F96CF119C34B64A6
15 changed files with 468 additions and 349 deletions

View file

@ -9,7 +9,8 @@ use std::sync::{Arc, RwLock};
use crate::{ use crate::{
type_system::ReprTree type_system::ReprTree
}; };
use r3vi::view::singleton::*;
//use r3vi::view::singleton::*;
pub trait ObjCommander { pub trait ObjCommander {
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>); fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>);
@ -20,12 +21,22 @@ impl<C: Commander> ObjCommander for C
where C::Cmd: 'static where C::Cmd: 'static
{ {
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) { fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) {
/*
self.send_cmd( self.send_cmd(
&cmd_obj.read().unwrap() &cmd_obj.read().unwrap()
.get_port::<dyn SingletonView<Item = C::Cmd>>().unwrap() .get_port::<dyn SingletonView<Item = C::Cmd>>().unwrap()
.get_view().unwrap() .get_view().unwrap()
.get() .get()
); );
*/
}
}
impl<T: Clone + Send + Sync> Commander for r3vi::buffer::vec::VecBuffer<T> {
type Cmd = r3vi::buffer::vec::VecDiff<T>;
fn send_cmd(&mut self, cmd: &Self::Cmd) {
self.apply_diff(cmd.clone());
} }
} }

View file

@ -7,10 +7,10 @@ use {
buffer::singleton::* buffer::singleton::*
}, },
crate::{ crate::{
type_system::{Context}, type_system::{Context, ReprTree},
terminal::{TerminalAtom, TerminalEvent, TerminalStyle}, terminal::{TerminalAtom, TerminalEvent, TerminalStyle},
tree::NestedNode, tree::NestedNode,
commander::Commander commander::{ObjCommander}
}, },
std::sync::Arc, std::sync::Arc,
std::sync::RwLock, std::sync::RwLock,
@ -18,16 +18,33 @@ use {
}; };
pub struct CharEditor { pub struct CharEditor {
ctx: Arc<RwLock<Context>>,
data: SingletonBuffer<Option<char>> data: SingletonBuffer<Option<char>>
} }
impl Commander for CharEditor { impl ObjCommander for CharEditor {
type Cmd = TerminalEvent; fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) {
let ctx = self.ctx.read().unwrap();
fn send_cmd(&mut self, event: &TerminalEvent) { let cmd_obj = cmd_obj.read().unwrap();
let cmd_type = cmd_obj.get_type().clone();
let char_type = ctx.type_term_from_str("( Char )").unwrap();
let term_event_type = ctx.type_term_from_str("( TerminalEvent )").unwrap();
if cmd_type == char_type {
if let Some(cmd_view) = cmd_obj.get_view::<dyn SingletonView<Item = char>>() {
let value = cmd_view.get();
self.data.set(Some(value));
}
}
/*
if cmd_type == term_event_type {
if let Some(te_view) = cmd_obj.get_view::<dyn SingletonView<Item = TerminalEvent>>() {
let event = te_view.get();
match event { match event {
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))
@ -39,10 +56,14 @@ impl Commander for CharEditor {
} }
} }
} }
*/
}
}
impl CharEditor { impl CharEditor {
pub fn new() -> Self { pub fn new(ctx: Arc<RwLock<Context>>) -> Self {
CharEditor { CharEditor {
ctx,
data: SingletonBuffer::new(None) data: SingletonBuffer::new(None)
} }
} }
@ -55,11 +76,19 @@ impl CharEditor {
self.get_port().get_view().unwrap().get().unwrap_or('?') self.get_port().get_view().unwrap().get().unwrap_or('?')
} }
pub fn new_node(ctx: &Arc<RwLock<Context>>) -> NestedNode { pub fn new_node(ctx0: Arc<RwLock<Context>>) -> NestedNode {
let data = SingletonBuffer::new(None); let data = SingletonBuffer::new(None);
NestedNode::new() let ctx = ctx0.clone();
.set_ctx(ctx.clone())
NestedNode::new(0)
.set_ctx(ctx0.clone())
.set_data(
ReprTree::new_leaf(
ctx0.read().unwrap().type_term_from_str("( Char )").unwrap(),
data.get_port().into()
)
)
.set_view(data .set_view(data
.get_port() .get_port()
.map(move |c| { .map(move |c| {
@ -71,7 +100,7 @@ impl CharEditor {
.to_grid() .to_grid()
) )
.set_cmd( .set_cmd(
Arc::new(RwLock::new(CharEditor{ data })) Arc::new(RwLock::new(CharEditor{ ctx, data }))
) )
} }
} }

View file

@ -12,7 +12,7 @@ use {
}, },
crate::{ crate::{
type_system::{Context, TypeTerm, ReprTree}, type_system::{Context, TypeTerm, ReprTree},
editors::list::{PTYListEditor, ListStyle}, editors::list::{PTYListEditor},
terminal::{ terminal::{
TerminalAtom, TerminalEvent, TerminalStyle, make_label TerminalAtom, TerminalEvent, TerminalStyle, make_label
}, },
@ -76,13 +76,13 @@ impl DigitEditor {
} }
} }
pub fn into_node(self) -> NestedNode { pub fn into_node(self, depth: usize) -> NestedNode {
let data = self.get_data(); let data = self.get_data();
let editor = Arc::new(RwLock::new(self)); let editor = Arc::new(RwLock::new(self));
let mut ed = editor.write().unwrap(); let mut ed = editor.write().unwrap();
let r = ed.radix; let r = ed.radix;
NestedNode::new() NestedNode::new(depth)
.set_ctx(ed.ctx.clone()) .set_ctx(ed.ctx.clone())
.set_cmd(editor.clone()) .set_cmd(editor.clone())
.set_data(data) .set_data(data)
@ -140,7 +140,7 @@ pub struct PosIntEditor {
impl PosIntEditor { impl PosIntEditor {
pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self { pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self {
let mut node = PTYListEditor::new( let mut editor = PTYListEditor::new(
ctx.clone(), ctx.clone(),
TypeTerm::Type { TypeTerm::Type {
id: ctx.read().unwrap().get_typeid("Digit").unwrap(), id: ctx.read().unwrap().get_typeid("Digit").unwrap(),
@ -148,12 +148,19 @@ impl PosIntEditor {
TypeTerm::Num(radix as i64) TypeTerm::Num(radix as i64)
] ]
}, },
match radix { None,
16 => ListStyle::Hex,
_ => ListStyle::Plain
},
0 0
).into_node(); );
let view = editor.pty_view((
match radix {
2 => "0d".into(),
16 => "0x".into(),
_ => "".into()
},
"".into(),
"".into()));
let mut node = editor.into_node().set_view(view);
// Set Type // Set Type
let data = node.data.clone().unwrap(); let data = node.data.clone().unwrap();

View file

@ -97,6 +97,37 @@ impl ListEditor {
} }
} }
pub fn into_node(self, depth: usize) -> NestedNode {
let data = self.get_data();
let ctx = self.ctx.clone();
let editor = Arc::new(RwLock::new(self));
NestedNode::new(depth)
.set_ctx(ctx)
.set_data(data)
.set_editor(editor.clone())
.set_nav(editor.clone())
// .set_cmd(editor.clone())
}
pub fn new_node(
node: NestedNode,
item_type: TypeTerm
) -> NestedNode {
let ctx = node.ctx.clone().unwrap();
let editor = ListEditor::new(
ctx.clone(),
item_type,
);
let data = editor.get_data();
let editor = Arc::new(RwLock::new(editor));
node.set_data(data)
.set_editor(editor.clone())
.set_nav(editor.clone())
}
pub fn get_item_type(&self) -> TypeTerm { pub fn get_item_type(&self) -> TypeTerm {
self.typ.clone() self.typ.clone()
} }
@ -108,17 +139,6 @@ impl ListEditor {
} }
} }
pub fn into_node(self) -> NestedNode {
let data = self.get_data();
let editor = Arc::new(RwLock::new(self));
NestedNode::new()
.set_data(data)
.set_editor(editor.clone())
.set_nav(editor.clone())
// .set_cmd(editor.clone())
}
pub fn get_cursor_port(&self) -> OuterViewPort<dyn SingletonView<Item = ListCursor>> { pub fn get_cursor_port(&self) -> OuterViewPort<dyn SingletonView<Item = ListCursor>> {
self.cursor.get_port() self.cursor.get_port()
} }

View file

@ -10,6 +10,6 @@ pub use {
cursor::{ListCursor, ListCursorMode}, cursor::{ListCursor, ListCursorMode},
editor::ListEditor, editor::ListEditor,
segment::{ListSegment, ListSegmentSequence}, segment::{ListSegment, ListSegmentSequence},
pty_editor::{ListStyle, PTYListEditor} pty_editor::{PTYListEditor}
}; };

View file

@ -14,14 +14,13 @@ use {
editor::ListEditor editor::ListEditor
}, },
terminal::{ terminal::{
TerminalEditor, TerminalEvent, TerminalEvent,
TerminalView, TerminalView,
make_label make_label
}, },
tree::{TreeCursor, TreeNav}, tree::{TreeCursor, TreeNav},
diagnostics::{Diagnostics}, diagnostics::{Diagnostics},
tree::NestedNode, tree::NestedNode,
commander::Commander,
PtySegment PtySegment
}, },
std::sync::{Arc, RwLock}, std::sync::{Arc, RwLock},
@ -30,92 +29,9 @@ use {
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
#[derive(Clone, Copy)]
pub enum ListStyle {
Plain,
HorizontalSexpr,
VerticalSexpr,
DoubleQuote,
Tuple,
EnumSet,
Path,
Hex
}
pub fn list_style_from_type(
ctx: &Arc<RwLock<Context>>,
typ: &TypeTerm
) -> Option<ListStyle> {
let ctx = ctx.read().unwrap();
match typ {
TypeTerm::Type {
id, args
} => {
if *id == ctx.get_typeid("List").unwrap() {
Some(ListStyle::HorizontalSexpr)
} else if *id == ctx.get_typeid("String").unwrap() {
Some(ListStyle::DoubleQuote)
} else if *id == ctx.get_typeid("Symbol").unwrap() {
Some(ListStyle::Plain)
} else if *id == ctx.get_typeid("PathSegment").unwrap() {
Some(ListStyle::Plain)
} else if *id == ctx.get_typeid("Path").unwrap() {
Some(ListStyle::Path)
} else if *id == ctx.get_typeid("PosInt").unwrap() {
if args.len() > 0 {
match args[0] {
TypeTerm::Num(radix) => {
match radix {
16 => Some(ListStyle::Hex),
_ => Some(ListStyle::Plain)
}
}
_ => None
}
} else {
None
}
} else {
None
}
}
_ => None
}
}
impl ListStyle {
fn get_split_char(&self) -> Option<char> {
match self {
ListStyle::Plain => None,
ListStyle::DoubleQuote => None,
ListStyle::HorizontalSexpr => Some(' '),
ListStyle::VerticalSexpr => Some('\n'),
ListStyle::Tuple => Some(','),
ListStyle::EnumSet => Some(','),
ListStyle::Path => Some('/'),
ListStyle::Hex => None
}
}
fn get_wrapper(&self) -> (&str, &str) {
match self {
ListStyle::Plain => ("", ""),
ListStyle::HorizontalSexpr => ("(", ")"),
ListStyle::VerticalSexpr => ("(", ")"),
ListStyle::DoubleQuote => ("\"", "\""),
ListStyle::Tuple => ("(", ")"),
ListStyle::EnumSet => ("{", "}"),
ListStyle::Path => ("<", ">"),
ListStyle::Hex => ("0x", "")
}
}
}
pub struct PTYListEditor { pub struct PTYListEditor {
pub editor: Arc<RwLock<ListEditor>>, pub editor: Arc<RwLock<ListEditor>>,
style: ListStyle, split_char: Option<char>,
depth: usize depth: usize
} }
@ -125,20 +41,23 @@ impl PTYListEditor {
pub fn new( pub fn new(
ctx: Arc<RwLock<Context>>, ctx: Arc<RwLock<Context>>,
typ: TypeTerm, typ: TypeTerm,
style: ListStyle, split_char: Option<char>,
depth: usize depth: usize
) -> Self { ) -> Self {
Self::from_editor( Self::from_editor(
Arc::new(RwLock::new(ListEditor::new(ctx, typ))), style, depth) Arc::new(RwLock::new(ListEditor::new(ctx, typ))),
split_char,
depth
)
} }
pub fn from_editor( pub fn from_editor(
editor: Arc<RwLock<ListEditor>>, editor: Arc<RwLock<ListEditor>>,
style: ListStyle, split_char: Option<char>,
depth: usize depth: usize
) -> Self { ) -> Self {
PTYListEditor { PTYListEditor {
style, split_char,
depth, depth,
editor, editor,
} }
@ -154,7 +73,10 @@ impl PTYListEditor {
se.get_view().map(move |segment| segment.pty_view()) se.get_view().map(move |segment| segment.pty_view())
} }
pub fn pty_view(&self) -> OuterViewPort<dyn TerminalView> { pub fn pty_view(
&self,
display_style: (&str, &str, &str),
) -> OuterViewPort<dyn TerminalView> {
let editor = self.editor.read().unwrap(); let editor = self.editor.read().unwrap();
let seg_seq = ListSegmentSequence::new( let seg_seq = ListSegmentSequence::new(
@ -167,26 +89,25 @@ impl PTYListEditor {
seg_seq seg_seq
.get_view() .get_view()
.map(move |segment| segment.pty_view()) .map(move |segment| segment.pty_view())
.separate(make_label(&if let Some(c) = self.style.get_split_char() { format!("{}", c) } else { "".to_string() } )) .separate(make_label(display_style.1))
.wrap(make_label(self.style.get_wrapper().0), make_label(self.style.get_wrapper().1)) .wrap(make_label(display_style.0), make_label(display_style.2))
.to_grid_horizontal() .to_grid_horizontal()
.flatten() .flatten()
} }
pub fn into_node(self) -> NestedNode { pub fn into_node(self) -> NestedNode {
let view = self.pty_view(); let depth = self.depth;
let editor = Arc::new(RwLock::new(self)); let editor = Arc::new(RwLock::new(self));
let ed = editor.read().unwrap(); let ed = editor.read().unwrap();
let edd = ed.editor.read().unwrap(); let edd = ed.editor.read().unwrap();
NestedNode::new() NestedNode::new(depth)
.set_data(edd.get_data()) .set_data(edd.get_data())
.set_cmd(editor.clone()) .set_cmd(editor.clone())
.set_editor(ed.editor.clone()) .set_editor(ed.editor.clone())
.set_nav(ed.editor.clone()) .set_nav(ed.editor.clone())
.set_ctx(edd.ctx.clone()) .set_ctx(edd.ctx.clone())
.set_view(view)
.set_diag( .set_diag(
edd.get_data_port() edd.get_data_port()
.enumerate() .enumerate()
@ -224,16 +145,18 @@ impl PTYListEditor {
self.depth = depth; self.depth = depth;
} }
pub fn split(e: &mut ListEditor, depth: usize) { pub fn split(e: &mut ListEditor) {
let cur = e.get_cursor(); let cur = e.get_cursor();
if let Some(item) = e.get_item_mut() { if let Some(item) = e.get_item_mut() {
let depth = item.depth;
if let Some(head_editor) = item.editor.clone() { if let Some(head_editor) = item.editor.clone() {
let head = head_editor.downcast::<RwLock<ListEditor>>().unwrap(); let head = head_editor.downcast::<RwLock<ListEditor>>().unwrap();
let mut head = head.write().unwrap(); let mut head = head.write().unwrap();
if cur.tree_addr.len() > 2 { if cur.tree_addr.len() > 2 {
PTYListEditor::split(&mut head, depth+1); PTYListEditor::split(&mut head);
} }
let mut tail = head.split(); let mut tail = head.split();
@ -259,27 +182,11 @@ impl PTYListEditor {
None None
}; };
let style = let mut tail_node = tail.into_node(depth);
if let Some(item_type) = &item_type { tail_node = tail_node.set_ctx(item.ctx.clone().unwrap());
list_style_from_type(&tail.ctx, item_type)
.unwrap_or(
ListStyle::HorizontalSexpr
)
} else {
ListStyle::HorizontalSexpr
};
let mut tail_node = PTYListEditor::from_editor(
Arc::new(RwLock::new(tail)),
style,
depth+1
).into_node();
if let Some(item_type) = item_type { if let Some(item_type) = item_type {
tail_node.data = Some(ReprTree::ascend( tail_node = tail_node.morph(item_type);
&tail_node.data.unwrap(),
item_type.clone()
));
} }
e.insert( e.insert(
@ -328,11 +235,26 @@ impl PTYListEditor {
} }
} }
impl Commander for PTYListEditor { use r3vi::view::singleton::SingletonView;
type Cmd = TerminalEvent; use crate::commander::ObjCommander;
fn send_cmd(&mut self, event: &TerminalEvent) { impl ObjCommander for PTYListEditor {
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) {
let mut e = self.editor.write().unwrap(); let mut e = self.editor.write().unwrap();
let cur = e.cursor.get();
let ctx = e.ctx.clone();
let ctx = ctx.read().unwrap();
let co = cmd_obj.read().unwrap();
let cmd_type = co.get_type().clone();
let term_event_type = ctx.type_term_from_str("( TerminalEvent )").unwrap();
let char_type = ctx.type_term_from_str("( Char )").unwrap();
if cmd_type == term_event_type {
if let Some(te_view) = co.get_view::<dyn SingletonView<Item = TerminalEvent>>() {
drop(co);
let event = te_view.get();
match event { match event {
TerminalEvent::Input(Event::Key(Key::Char('\t'))) TerminalEvent::Input(Event::Key(Key::Char('\t')))
@ -341,7 +263,6 @@ impl Commander for PTYListEditor {
e.set_leaf_mode(ListCursorMode::Select); e.set_leaf_mode(ListCursorMode::Select);
} }
_ => { _ => {
let cur = e.cursor.get();
if let Some(idx) = cur.idx { if let Some(idx) = cur.idx {
match cur.mode { match cur.mode {
ListCursorMode::Insert => { ListCursorMode::Insert => {
@ -355,7 +276,7 @@ impl Commander for PTYListEditor {
_ => { _ => {
let mut new_edit = Context::make_node(&e.ctx, e.typ.clone(), self.depth).unwrap(); let mut new_edit = Context::make_node(&e.ctx, e.typ.clone(), self.depth).unwrap();
new_edit.goto(TreeCursor::home()); new_edit.goto(TreeCursor::home());
new_edit.handle_terminal_event(event); new_edit.send_cmd_obj(cmd_obj);
e.insert(new_edit); e.insert(new_edit);
} }
@ -375,14 +296,16 @@ impl Commander for PTYListEditor {
) )
{ {
PTYListEditor::join_pxev(&mut e, idx, &item); PTYListEditor::join_pxev(&mut e, idx, &item);
/*
/* Optional: recursive joining
if item_cur.tree_addr.len() > 1 { if item_cur.tree_addr.len() > 1 {
let mut item = e.get_item_mut().unwrap(); let mut item = e.get_item_mut().unwrap();
item.handle_terminal_event(event); item.handle_terminal_event(event);
} }
*/ */
} else { } else {
item.handle_terminal_event(event); item.send_cmd_obj(cmd_obj);
} }
} }
TerminalEvent::Input(Event::Key(Key::Delete)) => { TerminalEvent::Input(Event::Key(Key::Delete)) => {
@ -396,30 +319,32 @@ impl Commander for PTYListEditor {
) )
{ {
PTYListEditor::join_nexd(&mut e, next_idx, &item); PTYListEditor::join_nexd(&mut e, next_idx, &item);
/*
/* Optional: recursive joining
if item_cur.tree_addr.len() > 1 { if item_cur.tree_addr.len() > 1 {
let mut item = e.get_item_mut().unwrap(); let mut item = e.get_item_mut().unwrap();
item.handle_terminal_event(event); item.handle_terminal_event(event);
} }
*/ */
} else { } else {
item.handle_terminal_event(event); item.send_cmd_obj(cmd_obj);
} }
} }
TerminalEvent::Input(Event::Key(Key::Char(c))) => { TerminalEvent::Input(Event::Key(Key::Char(c))) => {
if Some(*c) == self.style.get_split_char() { if Some(c) == self.split_char {
PTYListEditor::split(&mut e, self.depth); PTYListEditor::split(&mut e);
} else { } else {
item.handle_terminal_event(event); item.send_cmd_obj(cmd_obj);
} }
} }
_ => { _ => {
item.handle_terminal_event(event); item.send_cmd_obj(cmd_obj);
} }
} }
} else { } else {
item.handle_terminal_event(event); item.send_cmd_obj(cmd_obj);
} }
} }
} }
@ -428,4 +353,36 @@ impl Commander for PTYListEditor {
} }
} }
} }
} else if cmd_type == char_type && cur.mode == ListCursorMode::Select {
if let Some(cmd_view) = co.get_view::<dyn SingletonView<Item = char>>() {
drop(co);
let c = cmd_view.get();
if Some(c) == self.split_char {
PTYListEditor::split(&mut e);
} else {
if let Some(mut item) = e.get_item_mut() {
item.send_cmd_obj(cmd_obj);
}
}
}
} else {
drop(co);
match cur.mode {
ListCursorMode::Insert => {
let mut new_edit = Context::make_node(&e.ctx, e.typ.clone(), self.depth).unwrap();
new_edit.goto(TreeCursor::home());
new_edit.send_cmd_obj(cmd_obj);
e.insert(new_edit);
},
ListCursorMode::Select => {
if let Some(mut item) = e.get_item_mut() {
item.send_cmd_obj(cmd_obj);
}
}
}
}
}
} }

View file

@ -47,7 +47,7 @@ impl SumEditor {
pub fn into_node(self, ctx: Arc<RwLock<Context>>) -> NestedNode { pub fn into_node(self, ctx: Arc<RwLock<Context>>) -> NestedNode {
let view = self.pty_view(); let view = self.pty_view();
let editor = Arc::new(RwLock::new(self)); let editor = Arc::new(RwLock::new(self));
NestedNode::new() NestedNode::new(0)
.set_ctx(ctx) .set_ctx(ctx)
.set_view(view) .set_view(view)
.set_cmd(editor.clone()) .set_cmd(editor.clone())

View file

@ -3,6 +3,7 @@ pub mod atom;
pub mod compositor; pub mod compositor;
pub mod style; pub mod style;
pub mod terminal; pub mod terminal;
pub mod widgets;
pub use { pub use {
atom::TerminalAtom, atom::TerminalAtom,

View file

@ -1,8 +1,12 @@
use { use {
cgmath::{Point2, Vector2}, cgmath::{Point2, Vector2},
nested::{ r3vi::{
core::{InnerViewPort, Observer, ObserverBroadcast, OuterViewPort, View}, view::{
index::{IndexArea, IndexView}, InnerViewPort, Observer, ObserverBroadcast, OuterViewPort, View,
index::*
},
},
crate::{
terminal::{TerminalAtom, TerminalView}, terminal::{TerminalAtom, TerminalView},
}, },
std::sync::{Arc, RwLock}, std::sync::{Arc, RwLock},

View file

@ -0,0 +1,3 @@
pub mod ascii_box;

View file

@ -10,7 +10,7 @@ use {
buffer::{singleton::*} buffer::{singleton::*}
}, },
crate::{ crate::{
type_system::{ReprTree, Context}, type_system::{ReprTree, Context, TypeTerm},
terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult}, terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult},
diagnostics::{Diagnostics, Message}, diagnostics::{Diagnostics, Message},
tree::{TreeNav, TreeCursor, TreeNavResult}, tree::{TreeNav, TreeCursor, TreeNavResult},
@ -21,6 +21,9 @@ use {
#[derive(Clone)] #[derive(Clone)]
pub struct NestedNode { pub struct NestedNode {
/// depth
pub depth: usize,
/// context /// context
pub ctx: Option<Arc<RwLock<Context>>>, pub ctx: Option<Arc<RwLock<Context>>>,
@ -145,8 +148,9 @@ impl Diagnostics for NestedNode {
} }
impl NestedNode { impl NestedNode {
pub fn new() -> Self { pub fn new(depth: usize) -> Self {
NestedNode { NestedNode {
depth,
ctx: None, ctx: None,
data: None, data: None,
editor: None, editor: None,
@ -199,5 +203,9 @@ impl NestedNode {
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())
} }
pub fn morph(self, ty: TypeTerm) -> NestedNode {
Context::morph_node(self, ty)
}
} }

View file

@ -75,7 +75,7 @@ pub struct Context {
morphisms: HashMap< morphisms: HashMap<
MorphismTypePattern, MorphismTypePattern,
Arc< Arc<
dyn Fn( NestedNode, TypeTerm, usize ) -> Option<NestedNode> dyn Fn( NestedNode, TypeTerm ) -> Option<NestedNode>
+ Send + Sync + Send + Sync
> >
>, >,
@ -158,8 +158,9 @@ impl Context {
dst_tyid: tyid dst_tyid: tyid
}; };
self.add_morphism(morphism_pattern, Arc::new(move |node, dst_type, depth| { self.add_morphism(morphism_pattern, Arc::new(move |node, dst_type| {
let ctx = node.ctx.clone().unwrap(); let ctx = node.ctx.clone().unwrap();
let depth = node.depth;
mk_editor(ctx, dst_type, depth) mk_editor(ctx, dst_type, depth)
})); }));
} }
@ -168,15 +169,14 @@ impl Context {
&mut self, &mut self,
morph_type_pattern: MorphismTypePattern, morph_type_pattern: MorphismTypePattern,
morph_fn: Arc< morph_fn: Arc<
dyn Fn( NestedNode, TypeTerm, usize ) -> Option<NestedNode> dyn Fn( NestedNode, TypeTerm ) -> Option<NestedNode>
+ Send + Sync + Send + Sync
> >
) { ) {
self.morphisms.insert(morph_type_pattern, morph_fn); self.morphisms.insert(morph_type_pattern, morph_fn);
} }
pub fn get_morphism(&self, ty: MorphismType) -> Option<Arc<dyn Fn(NestedNode, TypeTerm, usize) -> Option<NestedNode> + Send + Sync>> { pub fn get_morphism(&self, ty: MorphismType) -> Option<Arc<dyn Fn(NestedNode, TypeTerm) -> Option<NestedNode> + Send + Sync>> {
let pattern = MorphismTypePattern::from(ty.clone()); let pattern = MorphismTypePattern::from(ty.clone());
if let Some(morphism) = self.morphisms.get( &pattern ) { if let Some(morphism) = self.morphisms.get( &pattern ) {
Some(morphism.clone()) Some(morphism.clone())
@ -193,10 +193,11 @@ impl Context {
dst_type: type_term.clone() dst_type: type_term.clone()
})?; })?;
mk_node(NestedNode::new().set_ctx(ctx.clone()), type_term, depth) mk_node(NestedNode::new(depth).set_ctx(ctx.clone()), type_term)
} }
pub fn morph_node(ctx: Arc<RwLock<Self>>, mut node: NestedNode, dst_type: TypeTerm) -> NestedNode { pub fn morph_node(mut node: NestedNode, dst_type: TypeTerm) -> NestedNode {
let ctx = node.ctx.clone().unwrap();
let mut src_type = None; let mut src_type = None;
if let Some(data) = node.data.clone() { if let Some(data) = node.data.clone() {
@ -210,8 +211,9 @@ impl Context {
} }
let pattern = MorphismType { src_type, dst_type: dst_type.clone() }.into(); let pattern = MorphismType { src_type, dst_type: dst_type.clone() }.into();
if let Some(transform) = ctx.read().unwrap().get_morphism(pattern) { let ctx = ctx.read().unwrap();
if let Some(new_node) = transform(node.clone(), dst_type, 0) { if let Some(transform) = ctx.get_morphism(pattern) {
if let Some(new_node) = transform(node.clone(), dst_type) {
new_node new_node
} else { } else {
node.clone() node.clone()

View file

@ -20,7 +20,35 @@ use {
pub fn init_mem_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> { pub fn init_mem_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("Vec".into()); ctx.write().unwrap().add_node_ctor(
"Vec", Arc::new(
|ctx: Arc<RwLock<Context>>, ty: TypeTerm, depth: usize| {
match ty {
TypeTerm::Type {
id: _, args
} => {
if args.len() > 0 {
let mut buf = r3vi::buffer::vec::VecBuffer::<char>::new();
let data = ReprTree::new_leaf(
ctx.read().unwrap().type_term_from_str("( Char )").unwrap(),
buf.get_port().into()
);
Some(
NestedNode::new(depth)
.set_ctx(ctx)
.set_data(data)
.set_editor(Arc::new(RwLock::new(buf)))
)
} else {
None
}
}
_ => None
}
}
)
);
ctx ctx
} }
@ -31,7 +59,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
ctx.write().unwrap().add_node_ctor( ctx.write().unwrap().add_node_ctor(
"Char", Arc::new( "Char", Arc::new(
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, _depth: usize| { |ctx: Arc<RwLock<Context>>, _ty: TypeTerm, _depth: usize| {
Some(CharEditor::new_node(&ctx)) Some(CharEditor::new_node(ctx))
} }
) )
); );
@ -46,14 +74,25 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
id: _, args id: _, args
} => { } => {
if args.len() > 0 { if args.len() > 0 {
Some(
PTYListEditor::new( let editor = PTYListEditor::new(
ctx, ctx,
args[0].clone(), args[0].clone(),
ListStyle::HorizontalSexpr, Some(','),
depth + 1 depth + 1
).into_node() );
let view = editor.pty_view(
(
"{".into(),
", ".into(),
"}".into()
) )
);
Some(editor
.into_node()
.set_view(view))
} else { } else {
None None
} }
@ -65,23 +104,24 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
); );
ctx.write().unwrap().add_list_typename("Symbol".into()); ctx.write().unwrap().add_list_typename("Symbol".into());
let pattern = MorphismTypePattern { let pattern = MorphismTypePattern {
src_type: ctx.read().unwrap().type_term_from_str("( List Char )"), src_type: ctx.read().unwrap().type_term_from_str("( List Char )"),
dst_tyid: ctx.read().unwrap().get_typeid("Symbol").unwrap() dst_tyid: ctx.read().unwrap().get_typeid("Symbol").unwrap()
}; };
ctx.write().unwrap().add_morphism(pattern, ctx.write().unwrap().add_morphism(pattern,
Arc::new( Arc::new(
|mut node, dst_type:_, depth| { |mut node, _dst_type:_| {
let depth = node.depth;
let editor = node.editor.clone().unwrap().downcast::<RwLock<ListEditor>>().unwrap(); let editor = node.editor.clone().unwrap().downcast::<RwLock<ListEditor>>().unwrap();
let pty_editor = PTYListEditor::from_editor( let pty_editor = PTYListEditor::from_editor(
editor, editor,
ListStyle::Plain, None,
depth depth
); );
node.view = Some(pty_editor.pty_view()); node.view = Some(pty_editor.pty_view(
("".into(), "".into(), "".into())
));
node.cmd = Some(Arc::new(RwLock::new(pty_editor))); node.cmd = Some(Arc::new(RwLock::new(pty_editor)));
Some(node) Some(node)
} }
@ -99,10 +139,10 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
TypeTerm::new(ctx.read().unwrap().get_typeid("Char").unwrap()) TypeTerm::new(ctx.read().unwrap().get_typeid("Char").unwrap())
] ]
}, },
depth depth+1
).unwrap(); ).unwrap();
node = Context::morph_node(ctx, node, dst_typ); node = node.morph(dst_typ);
Some(node) Some(node)
} }
@ -110,20 +150,47 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
); );
ctx.write().unwrap().add_list_typename("String".into()); ctx.write().unwrap().add_list_typename("String".into());
let pattern = MorphismTypePattern {
src_type: ctx.read().unwrap().type_term_from_str("( List Char )"),
dst_tyid: ctx.read().unwrap().get_typeid("String").unwrap()
};
ctx.write().unwrap().add_morphism(pattern,
Arc::new(
|mut node, _dst_type:_| {
let depth = node.depth;
let editor = node.editor.clone().unwrap().downcast::<RwLock<ListEditor>>().unwrap();
let pty_editor = PTYListEditor::from_editor(
editor,
None,
depth
);
node.view = Some(pty_editor.pty_view((
"\"".into(),
"".into(),
"\"".into()
)));
node.cmd = Some(Arc::new(RwLock::new(pty_editor)));
Some(node)
}
)
);
ctx.write().unwrap().add_node_ctor( ctx.write().unwrap().add_node_ctor(
"String", Arc::new( "String", Arc::new(
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| { |ctx: Arc<RwLock<Context>>, dst_typ: TypeTerm, depth: usize| {
let mut node = PTYListEditor::new( let mut node = Context::make_node(
ctx.clone(), &ctx,
ctx.read().unwrap().type_term_from_str("( Char )").unwrap(), TypeTerm::Type {
ListStyle::DoubleQuote, id: ctx.read().unwrap().get_typeid("List").unwrap(),
args: vec![
TypeTerm::new(ctx.read().unwrap().get_typeid("Char").unwrap())
]
},
depth+1 depth+1
).into_node(); ).unwrap();
node.data = Some(ReprTree::ascend( node = node.morph(dst_typ);
&node.data.unwrap(),
ctx.read().unwrap().type_term_from_str("( String )").unwrap()
));
Some(node) Some(node)
} }
@ -134,7 +201,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
ctx.write().unwrap().add_node_ctor( ctx.write().unwrap().add_node_ctor(
"TypeTerm", Arc::new( "TypeTerm", Arc::new(
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| { |ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
Some(TypeTermEditor::new(ctx, depth).into_node()) Some(TypeTermEditor::new(ctx, depth).into_node(depth))
} }
) )
); );
@ -152,7 +219,7 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
ctx.write().unwrap().add_node_ctor( ctx.write().unwrap().add_node_ctor(
"Digit", 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
@ -160,7 +227,7 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
if args.len() > 0 { if args.len() > 0 {
match args[0] { match args[0] {
TypeTerm::Num(radix) => { TypeTerm::Num(radix) => {
let node = DigitEditor::new(ctx.clone(), radix as u32).into_node(); let node = DigitEditor::new(ctx.clone(), radix as u32).into_node(depth);
Some( Some(
node node
) )
@ -178,19 +245,39 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
); );
ctx.write().unwrap().add_list_typename("PosInt".into()); ctx.write().unwrap().add_list_typename("PosInt".into());
ctx.write().unwrap().add_node_ctor( let pattern = MorphismTypePattern {
"PosInt", Arc::new( src_type: ctx.read().unwrap().type_term_from_str("( List ( Digit 10 ) )"),
|ctx: Arc<RwLock<Context>>, ty: TypeTerm, _depth: usize| { dst_tyid: ctx.read().unwrap().get_typeid("PosInt").unwrap()
match ty { };
ctx.write().unwrap().add_morphism(pattern,
Arc::new(
|mut node, dst_type| {
let depth = node.depth;
let editor = node.editor.clone().unwrap().downcast::<RwLock<ListEditor>>().unwrap();
match dst_type {
TypeTerm::Type { TypeTerm::Type {
id: _, args id: _, args
} => { } => {
if args.len() > 0 { if args.len() > 0 {
match args[0] { match args[0] {
TypeTerm::Num(radix) => { TypeTerm::Num(radix) => {
Some( let pty_editor = PTYListEditor::from_editor(
PosIntEditor::new(ctx.clone(), radix as u32).into_node() editor,
Some(','),
depth
);
// todo: set data view
node.view = Some(pty_editor.pty_view(
(
"{".into(),
", ".into(),
"}".into()
) )
));
node.cmd = Some(Arc::new(RwLock::new(pty_editor)));
Some(node)
}, },
_ => None _ => None
} }
@ -204,6 +291,46 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
) )
); );
ctx.write().unwrap().add_node_ctor(
"PosInt", Arc::new(
|ctx: Arc<RwLock<Context>>, dst_typ: TypeTerm, depth: usize| {
match dst_typ.clone() {
TypeTerm::Type {
id: _, args
} => {
if args.len() > 0 {
match args[0] {
TypeTerm::Num(radix) => {
let mut node = Context::make_node(
&ctx,
TypeTerm::Type {
id: ctx.read().unwrap().get_typeid("List").unwrap(),
args: vec![
TypeTerm::new(ctx.read().unwrap().get_typeid("Digit").unwrap())
.num_arg(radix)
.clone()
]
},
depth+1
).unwrap();
node = node.morph(dst_typ);
Some(node)
}
_ => None
}
} else {
None
}
}
_ => None
}
}
)
);
ctx.write().unwrap().add_list_typename("RGB".into()); ctx.write().unwrap().add_list_typename("RGB".into());
ctx.write().unwrap().add_node_ctor( ctx.write().unwrap().add_node_ctor(
"RGB", Arc::new( "RGB", Arc::new(
@ -230,7 +357,7 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
let diag = editor.get_msg_port(); let diag = editor.get_msg_port();
let editor = Arc::new(RwLock::new(editor)); let editor = Arc::new(RwLock::new(editor));
let node = NestedNode::new() let node = NestedNode::new(depth)
.set_ctx(ctx) .set_ctx(ctx)
.set_cmd(editor.clone()) .set_cmd(editor.clone())
.set_nav(editor.clone()) .set_nav(editor.clone())
@ -245,52 +372,3 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
ctx ctx
} }
pub fn init_os_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
let ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent))));
ctx.write().unwrap().add_list_typename("PathSegment".into());
ctx.write().unwrap().add_node_ctor(
"PathSegment", Arc::new(
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
let mut node = PTYListEditor::new(
ctx.clone(),
ctx.read().unwrap().type_term_from_str("( Char )").unwrap(),
ListStyle::Plain,
depth + 1
).into_node();
node.data = Some(ReprTree::ascend(
&node.data.unwrap(),
ctx.read().unwrap().type_term_from_str("( PathSegment )").unwrap()
));
Some(node)
}
)
);
ctx.write().unwrap().add_list_typename("Path".into());
ctx.write().unwrap().add_node_ctor(
"Path", Arc::new(
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
let mut node = PTYListEditor::new(
ctx.clone(),
ctx.read().unwrap().type_term_from_str("( PathSegment )").unwrap(),
ListStyle::Path,
depth + 1
).into_node();
node.data = Some(ReprTree::ascend(
&node.data.unwrap(),
ctx.read().unwrap().type_term_from_str("( Path )").unwrap()
));
Some(node)
}
)
);
ctx
}

View file

@ -201,7 +201,6 @@ impl ReprTree {
_morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>, _morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>,
) { ) {
// todo // todo
} }
*/ */
} }

View file

@ -44,13 +44,13 @@ impl TypeTermEditor {
} }
} }
pub fn into_node(self) -> NestedNode { pub fn into_node(self, depth: usize) -> NestedNode {
let ctx = self.ctx.clone(); let ctx = self.ctx.clone();
let sum_edit = self.sum_edit.clone(); let sum_edit = self.sum_edit.clone();
let view = sum_edit.read().unwrap().pty_view(); let view = sum_edit.read().unwrap().pty_view();
let editor = Arc::new(RwLock::new(self)); let editor = Arc::new(RwLock::new(self));
NestedNode::new() NestedNode::new(depth)
.set_ctx(ctx) .set_ctx(ctx)
.set_nav(sum_edit) .set_nav(sum_edit)
.set_cmd(editor.clone()) .set_cmd(editor.clone())