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::{
type_system::ReprTree
};
use r3vi::view::singleton::*;
//use r3vi::view::singleton::*;
pub trait ObjCommander {
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
{
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) {
/*
self.send_cmd(
&cmd_obj.read().unwrap()
.get_port::<dyn SingletonView<Item = C::Cmd>>().unwrap()
.get_view().unwrap()
.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::*
},
crate::{
type_system::{Context},
type_system::{Context, ReprTree},
terminal::{TerminalAtom, TerminalEvent, TerminalStyle},
tree::NestedNode,
commander::Commander
commander::{ObjCommander}
},
std::sync::Arc,
std::sync::RwLock,
@ -18,31 +18,52 @@ use {
};
pub struct CharEditor {
ctx: Arc<RwLock<Context>>,
data: SingletonBuffer<Option<char>>
}
impl Commander for CharEditor {
type Cmd = TerminalEvent;
impl ObjCommander for CharEditor {
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) {
let ctx = self.ctx.read().unwrap();
fn send_cmd(&mut self, event: &TerminalEvent) {
match event {
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
self.data.set(Some(*c));
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));
}
TerminalEvent::Input(Event::Key(Key::Backspace))
| TerminalEvent::Input(Event::Key(Key::Delete)) => {
self.data.set(None);
}
_ => {}
}
/*
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 {
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
self.data.set(Some(c));
}
TerminalEvent::Input(Event::Key(Key::Backspace))
| TerminalEvent::Input(Event::Key(Key::Delete)) => {
self.data.set(None);
}
_ => {}
}
}
}
*/
}
}
impl CharEditor {
pub fn new() -> Self {
pub fn new(ctx: Arc<RwLock<Context>>) -> Self {
CharEditor {
ctx,
data: SingletonBuffer::new(None)
}
}
@ -55,11 +76,19 @@ impl CharEditor {
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);
NestedNode::new()
.set_ctx(ctx.clone())
let ctx = ctx0.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
.get_port()
.map(move |c| {
@ -71,7 +100,7 @@ impl CharEditor {
.to_grid()
)
.set_cmd(
Arc::new(RwLock::new(CharEditor{ data }))
Arc::new(RwLock::new(CharEditor{ ctx, data }))
)
}
}

View file

@ -12,7 +12,7 @@ use {
},
crate::{
type_system::{Context, TypeTerm, ReprTree},
editors::list::{PTYListEditor, ListStyle},
editors::list::{PTYListEditor},
terminal::{
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 editor = Arc::new(RwLock::new(self));
let mut ed = editor.write().unwrap();
let r = ed.radix;
NestedNode::new()
NestedNode::new(depth)
.set_ctx(ed.ctx.clone())
.set_cmd(editor.clone())
.set_data(data)
@ -140,7 +140,7 @@ pub struct PosIntEditor {
impl PosIntEditor {
pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self {
let mut node = PTYListEditor::new(
let mut editor = PTYListEditor::new(
ctx.clone(),
TypeTerm::Type {
id: ctx.read().unwrap().get_typeid("Digit").unwrap(),
@ -148,12 +148,19 @@ impl PosIntEditor {
TypeTerm::Num(radix as i64)
]
},
match radix {
16 => ListStyle::Hex,
_ => ListStyle::Plain
},
None,
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
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 {
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>> {
self.cursor.get_port()
}

View file

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

View file

@ -14,14 +14,13 @@ use {
editor::ListEditor
},
terminal::{
TerminalEditor, TerminalEvent,
TerminalEvent,
TerminalView,
make_label
},
tree::{TreeCursor, TreeNav},
diagnostics::{Diagnostics},
tree::NestedNode,
commander::Commander,
PtySegment
},
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 editor: Arc<RwLock<ListEditor>>,
style: ListStyle,
split_char: Option<char>,
depth: usize
}
@ -125,20 +41,23 @@ impl PTYListEditor {
pub fn new(
ctx: Arc<RwLock<Context>>,
typ: TypeTerm,
style: ListStyle,
split_char: Option<char>,
depth: usize
) -> Self {
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(
editor: Arc<RwLock<ListEditor>>,
style: ListStyle,
split_char: Option<char>,
depth: usize
) -> Self {
PTYListEditor {
style,
split_char,
depth,
editor,
}
@ -154,7 +73,10 @@ impl PTYListEditor {
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 seg_seq = ListSegmentSequence::new(
@ -167,26 +89,25 @@ impl PTYListEditor {
seg_seq
.get_view()
.map(move |segment| segment.pty_view())
.separate(make_label(&if let Some(c) = self.style.get_split_char() { format!("{}", c) } else { "".to_string() } ))
.wrap(make_label(self.style.get_wrapper().0), make_label(self.style.get_wrapper().1))
.separate(make_label(display_style.1))
.wrap(make_label(display_style.0), make_label(display_style.2))
.to_grid_horizontal()
.flatten()
}
pub fn into_node(self) -> NestedNode {
let view = self.pty_view();
let depth = self.depth;
let editor = Arc::new(RwLock::new(self));
let ed = editor.read().unwrap();
let edd = ed.editor.read().unwrap();
NestedNode::new()
NestedNode::new(depth)
.set_data(edd.get_data())
.set_cmd(editor.clone())
.set_editor(ed.editor.clone())
.set_nav(ed.editor.clone())
.set_ctx(edd.ctx.clone())
.set_view(view)
.set_diag(
edd.get_data_port()
.enumerate()
@ -224,16 +145,18 @@ impl PTYListEditor {
self.depth = depth;
}
pub fn split(e: &mut ListEditor, depth: usize) {
pub fn split(e: &mut ListEditor) {
let cur = e.get_cursor();
if let Some(item) = e.get_item_mut() {
let depth = item.depth;
if let Some(head_editor) = item.editor.clone() {
let head = head_editor.downcast::<RwLock<ListEditor>>().unwrap();
let mut head = head.write().unwrap();
if cur.tree_addr.len() > 2 {
PTYListEditor::split(&mut head, depth+1);
PTYListEditor::split(&mut head);
}
let mut tail = head.split();
@ -259,27 +182,11 @@ impl PTYListEditor {
None
};
let style =
if let Some(item_type) = &item_type {
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();
let mut tail_node = tail.into_node(depth);
tail_node = tail_node.set_ctx(item.ctx.clone().unwrap());
if let Some(item_type) = item_type {
tail_node.data = Some(ReprTree::ascend(
&tail_node.data.unwrap(),
item_type.clone()
));
tail_node = tail_node.morph(item_type);
}
e.insert(
@ -328,104 +235,154 @@ impl PTYListEditor {
}
}
impl Commander for PTYListEditor {
type Cmd = TerminalEvent;
use r3vi::view::singleton::SingletonView;
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 cur = e.cursor.get();
match event {
TerminalEvent::Input(Event::Key(Key::Char('\t')))
| TerminalEvent::Input(Event::Key(Key::Insert)) => {
e.toggle_leaf_mode();
e.set_leaf_mode(ListCursorMode::Select);
}
_ => {
let cur = e.cursor.get();
if let Some(idx) = cur.idx {
match cur.mode {
ListCursorMode::Insert => {
match event {
TerminalEvent::Input(Event::Key(Key::Backspace)) => {
e.delete_pxev();
}
TerminalEvent::Input(Event::Key(Key::Delete)) => {
e.delete_nexd();
}
_ => {
let mut new_edit = Context::make_node(&e.ctx, e.typ.clone(), self.depth).unwrap();
new_edit.goto(TreeCursor::home());
new_edit.handle_terminal_event(event);
let ctx = e.ctx.clone();
let ctx = ctx.read().unwrap();
e.insert(new_edit);
}
}
},
ListCursorMode::Select => {
if let Some(mut item) = e.get_item().clone() {
if e.is_listlist() {
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 {
TerminalEvent::Input(Event::Key(Key::Char('\t')))
| TerminalEvent::Input(Event::Key(Key::Insert)) => {
e.toggle_leaf_mode();
e.set_leaf_mode(ListCursorMode::Select);
}
_ => {
if let Some(idx) = cur.idx {
match cur.mode {
ListCursorMode::Insert => {
match event {
TerminalEvent::Input(Event::Key(Key::Backspace)) => {
let item_cur = item.get_cursor();
if idx > 0
&& item_cur.tree_addr.iter().fold(
true,
|is_zero, x| is_zero && (*x == 0)
)
{
PTYListEditor::join_pxev(&mut e, idx, &item);
/*
if item_cur.tree_addr.len() > 1 {
let mut item = e.get_item_mut().unwrap();
item.handle_terminal_event(event);
}
*/
} else {
item.handle_terminal_event(event);
}
e.delete_pxev();
}
TerminalEvent::Input(Event::Key(Key::Delete)) => {
let item_cur = item.get_cursor_warp();
let next_idx = idx as usize + 1;
if next_idx < e.data.len()
&& item_cur.tree_addr.iter().fold(
true,
|is_end, x| is_end && (*x == -1)
)
{
PTYListEditor::join_nexd(&mut e, next_idx, &item);
/*
if item_cur.tree_addr.len() > 1 {
let mut item = e.get_item_mut().unwrap();
item.handle_terminal_event(event);
}
*/
} else {
item.handle_terminal_event(event);
}
}
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
if Some(*c) == self.style.get_split_char() {
PTYListEditor::split(&mut e, self.depth);
} else {
item.handle_terminal_event(event);
}
e.delete_nexd();
}
_ => {
item.handle_terminal_event(event);
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().clone() {
if e.is_listlist() {
match event {
TerminalEvent::Input(Event::Key(Key::Backspace)) => {
let item_cur = item.get_cursor();
if idx > 0
&& item_cur.tree_addr.iter().fold(
true,
|is_zero, x| is_zero && (*x == 0)
)
{
PTYListEditor::join_pxev(&mut e, idx, &item);
/* Optional: recursive joining
if item_cur.tree_addr.len() > 1 {
let mut item = e.get_item_mut().unwrap();
item.handle_terminal_event(event);
}
*/
} else {
item.send_cmd_obj(cmd_obj);
}
}
TerminalEvent::Input(Event::Key(Key::Delete)) => {
let item_cur = item.get_cursor_warp();
let next_idx = idx as usize + 1;
if next_idx < e.data.len()
&& item_cur.tree_addr.iter().fold(
true,
|is_end, x| is_end && (*x == -1)
)
{
PTYListEditor::join_nexd(&mut e, next_idx, &item);
/* Optional: recursive joining
if item_cur.tree_addr.len() > 1 {
let mut item = e.get_item_mut().unwrap();
item.handle_terminal_event(event);
}
*/
} else {
item.send_cmd_obj(cmd_obj);
}
}
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
if Some(c) == self.split_char {
PTYListEditor::split(&mut e);
} else {
item.send_cmd_obj(cmd_obj);
}
}
_ => {
item.send_cmd_obj(cmd_obj);
}
}
} else {
item.send_cmd_obj(cmd_obj);
}
}
} else {
item.handle_terminal_event(event);
}
}
}
}
}
}
} 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 {
let view = self.pty_view();
let editor = Arc::new(RwLock::new(self));
NestedNode::new()
NestedNode::new(0)
.set_ctx(ctx)
.set_view(view)
.set_cmd(editor.clone())

View file

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

View file

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

View file

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

View file

@ -10,7 +10,7 @@ use {
buffer::{singleton::*}
},
crate::{
type_system::{ReprTree, Context},
type_system::{ReprTree, Context, TypeTerm},
terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult},
diagnostics::{Diagnostics, Message},
tree::{TreeNav, TreeCursor, TreeNavResult},
@ -21,6 +21,9 @@ use {
#[derive(Clone)]
pub struct NestedNode {
/// depth
pub depth: usize,
/// context
pub ctx: Option<Arc<RwLock<Context>>>,
@ -145,8 +148,9 @@ impl Diagnostics for NestedNode {
}
impl NestedNode {
pub fn new() -> Self {
pub fn new(depth: usize) -> Self {
NestedNode {
depth,
ctx: None,
data: None,
editor: None,
@ -199,5 +203,9 @@ impl NestedNode {
pub fn get_view(&self) -> OuterViewPort<dyn TerminalView> {
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<
MorphismTypePattern,
Arc<
dyn Fn( NestedNode, TypeTerm, usize ) -> Option<NestedNode>
dyn Fn( NestedNode, TypeTerm ) -> Option<NestedNode>
+ Send + Sync
>
>,
@ -158,8 +158,9 @@ impl Context {
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 depth = node.depth;
mk_editor(ctx, dst_type, depth)
}));
}
@ -168,15 +169,14 @@ impl Context {
&mut self,
morph_type_pattern: MorphismTypePattern,
morph_fn: Arc<
dyn Fn( NestedNode, TypeTerm, usize ) -> Option<NestedNode>
dyn Fn( NestedNode, TypeTerm ) -> Option<NestedNode>
+ Send + Sync
>
) {
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());
if let Some(morphism) = self.morphisms.get( &pattern ) {
Some(morphism.clone())
@ -193,10 +193,11 @@ impl Context {
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;
if let Some(data) = node.data.clone() {
@ -210,8 +211,9 @@ impl Context {
}
let pattern = MorphismType { src_type, dst_type: dst_type.clone() }.into();
if let Some(transform) = ctx.read().unwrap().get_morphism(pattern) {
if let Some(new_node) = transform(node.clone(), dst_type, 0) {
let ctx = ctx.read().unwrap();
if let Some(transform) = ctx.get_morphism(pattern) {
if let Some(new_node) = transform(node.clone(), dst_type) {
new_node
} else {
node.clone()

View file

@ -20,7 +20,35 @@ use {
pub fn init_mem_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
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
}
@ -31,7 +59,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
ctx.write().unwrap().add_node_ctor(
"Char", Arc::new(
|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
} => {
if args.len() > 0 {
Some(
PTYListEditor::new(
ctx,
args[0].clone(),
ListStyle::HorizontalSexpr,
depth + 1
).into_node()
)
let editor = PTYListEditor::new(
ctx,
args[0].clone(),
Some(','),
depth + 1
);
let view = editor.pty_view(
(
"{".into(),
", ".into(),
"}".into()
)
);
Some(editor
.into_node()
.set_view(view))
} else {
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());
let pattern = MorphismTypePattern {
src_type: ctx.read().unwrap().type_term_from_str("( List Char )"),
dst_tyid: ctx.read().unwrap().get_typeid("Symbol").unwrap()
};
ctx.write().unwrap().add_morphism(pattern,
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 pty_editor = PTYListEditor::from_editor(
editor,
ListStyle::Plain,
None,
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)));
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())
]
},
depth
depth+1
).unwrap();
node = Context::morph_node(ctx, node, dst_typ);
node = node.morph(dst_typ);
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());
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(
"String", 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::DoubleQuote,
depth + 1
).into_node();
|ctx: Arc<RwLock<Context>>, dst_typ: TypeTerm, depth: usize| {
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("Char").unwrap())
]
},
depth+1
).unwrap();
node.data = Some(ReprTree::ascend(
&node.data.unwrap(),
ctx.read().unwrap().type_term_from_str("( String )").unwrap()
));
node = node.morph(dst_typ);
Some(node)
}
@ -134,7 +201,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
ctx.write().unwrap().add_node_ctor(
"TypeTerm", Arc::new(
|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(
"Digit", Arc::new(
|ctx: Arc<RwLock<Context>>, ty: TypeTerm, _depth: usize| {
|ctx: Arc<RwLock<Context>>, ty: TypeTerm, depth: usize| {
match ty {
TypeTerm::Type {
id: _, args
@ -160,7 +227,7 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
if args.len() > 0 {
match args[0] {
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(
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_node_ctor(
"PosInt", Arc::new(
|ctx: Arc<RwLock<Context>>, ty: TypeTerm, _depth: usize| {
match ty {
let pattern = MorphismTypePattern {
src_type: ctx.read().unwrap().type_term_from_str("( List ( Digit 10 ) )"),
dst_tyid: ctx.read().unwrap().get_typeid("PosInt").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();
match dst_type {
TypeTerm::Type {
id: _, args
} => {
if args.len() > 0 {
match args[0] {
TypeTerm::Num(radix) => {
Some(
PosIntEditor::new(ctx.clone(), radix as u32).into_node()
)
let pty_editor = PTYListEditor::from_editor(
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
}
@ -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_node_ctor(
"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 editor = Arc::new(RwLock::new(editor));
let node = NestedNode::new()
let node = NestedNode::new(depth)
.set_ctx(ctx)
.set_cmd(editor.clone())
.set_nav(editor.clone())
@ -245,52 +372,3 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
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>>,
) {
// 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 sum_edit = self.sum_edit.clone();
let view = sum_edit.read().unwrap().pty_view();
let editor = Arc::new(RwLock::new(self));
NestedNode::new()
NestedNode::new(depth)
.set_ctx(ctx)
.set_nav(sum_edit)
.set_cmd(editor.clone())